diff --git a/INSTALL.md b/INSTALL.md index 893f5551e4..b92739a0db 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -10,7 +10,7 @@ Refer to the [wiki](http://cwiki.apache.org/confluence/display/CLOUDSTACK/Index) for the latest information, especially: - [Setting up development environment](https://cwiki.apache.org/confluence/display/CLOUDSTACK/Setting+up+CloudStack+Development+Environment) for Apache CloudStack. - - [Building](https://cwiki.apache.org/confluence/display/CLOUDSTACK/How+to+build+on+master+branch) Apache CloudStack. + - [Building](https://cwiki.apache.org/confluence/display/CLOUDSTACK/How+to+build+CloudStack) Apache CloudStack. ## Setting up Development Environment @@ -18,7 +18,7 @@ for the latest information, especially: Install tools and dependencies used for development: - $ yum install git ant ant-devel java-1.6.0-openjdk java-1.6.0-openjdk-devel + $ yum install git ant ant-devel java-1.7.0-openjdk java-1.7.0-openjdk-devel mysql mysql-server tomcat6 mkisofs gcc python MySQL-python openssh-clients wget Set up Maven (3.0.5): diff --git a/README.md b/README.md index c9f5733d5f..23f5004cd9 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -Apache CloudStack Version 4.2.0 +Apache CloudStack Version 4.4.0 # About Apache CloudStack diff --git a/agent-simulator/tomcatconf/commands-simulator.properties.in b/agent-simulator/tomcatconf/commands-simulator.properties.in index ba19e33dc5..4350bb788b 100644 --- a/agent-simulator/tomcatconf/commands-simulator.properties.in +++ b/agent-simulator/tomcatconf/commands-simulator.properties.in @@ -17,3 +17,5 @@ configureSimulator=com.cloud.api.commands.ConfigureSimulatorCmd;1 +querySimulatorMock=com.cloud.api.commands.QuerySimulatorMockCmd;1 +cleanupSimulatorMock=com.cloud.api.commands.CleanupSimulatorMockCmd;1 diff --git a/api/src/com/cloud/agent/api/VgpuTypesInfo.java b/api/src/com/cloud/agent/api/VgpuTypesInfo.java new file mode 100644 index 0000000000..85ffc18982 --- /dev/null +++ b/api/src/com/cloud/agent/api/VgpuTypesInfo.java @@ -0,0 +1,86 @@ +// 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 VgpuTypesInfo { + + private String modelName; + private String groupName; + private Long maxHeads; + private Long videoRam; + private Long maxResolutionX; + private Long maxResolutionY; + private Long maxVgpuPerGpu; + private Long remainingCapacity; + private Long maxCapacity; + + public String getModelName() { + return modelName; + } + + public String getGroupName() { + return groupName; + } + + public Long getVideoRam() { + return videoRam; + } + + public Long getMaxHeads() { + return maxHeads; + } + + public Long getMaxResolutionX() { + return maxResolutionX; + } + + public Long getMaxResolutionY() { + return maxResolutionY; + } + + public Long getMaxVpuPerGpu() { + return maxVgpuPerGpu; + } + + public Long getRemainingCapacity() { + return remainingCapacity; + } + + public void setRemainingCapacity(Long remainingCapacity) { + this.remainingCapacity = remainingCapacity; + } + + public Long getMaxCapacity() { + return maxCapacity; + } + + public void setMaxVmCapacity(Long maxCapacity) { + this.maxCapacity = maxCapacity; + } + + public VgpuTypesInfo(String groupName, String modelName, Long videoRam, Long maxHeads, Long maxResolutionX, Long maxResolutionY, Long maxVgpuPerGpu, + Long remainingCapacity, Long maxCapacity) { + this.groupName = groupName; + this.modelName = modelName; + this.videoRam = videoRam; + this.maxHeads = maxHeads; + this.maxResolutionX = maxResolutionX; + this.maxResolutionY = maxResolutionY; + this.maxVgpuPerGpu = maxVgpuPerGpu; + this.remainingCapacity = remainingCapacity; + this.maxCapacity = maxCapacity; + } +} diff --git a/api/src/com/cloud/agent/api/to/GPUDeviceTO.java b/api/src/com/cloud/agent/api/to/GPUDeviceTO.java index 8bc9e5229d..4afe080477 100644 --- a/api/src/com/cloud/agent/api/to/GPUDeviceTO.java +++ b/api/src/com/cloud/agent/api/to/GPUDeviceTO.java @@ -18,13 +18,15 @@ import java.util.HashMap; +import com.cloud.agent.api.VgpuTypesInfo; + public class GPUDeviceTO { private String gpuGroup; private String vgpuType; - private HashMap> groupDetails = new HashMap>(); + private HashMap> groupDetails = new HashMap>(); - public GPUDeviceTO( String gpuGroup, String vgpuType, HashMap> groupDetails) { + public GPUDeviceTO( String gpuGroup, String vgpuType, HashMap> groupDetails) { this.gpuGroup = gpuGroup; this.vgpuType = vgpuType; this.groupDetails = groupDetails; @@ -46,11 +48,12 @@ public void setVgpuType(String vgpuType) { this.vgpuType = vgpuType; } - public HashMap> getGroupDetails() { + public HashMap> getGroupDetails() { return groupDetails; } - public void setGroupDetails(HashMap> groupDetails) { + public void setGroupDetails(HashMap> groupDetails) { this.groupDetails = groupDetails; } + } diff --git a/api/src/com/cloud/agent/api/to/VirtualMachineTO.java b/api/src/com/cloud/agent/api/to/VirtualMachineTO.java index bbd83852ab..45bad79f98 100644 --- a/api/src/com/cloud/agent/api/to/VirtualMachineTO.java +++ b/api/src/com/cloud/agent/api/to/VirtualMachineTO.java @@ -47,6 +47,7 @@ public class VirtualMachineTO { String hostName; String arch; String os; + String platformEmulator; String bootArgs; String[] bootupScripts; boolean rebootOnCrash; @@ -236,7 +237,7 @@ public void setNics(NicTO[] nics) { } public String getVncPassword() { - return this.vncPassword; + return vncPassword; } public void setVncPassword(String vncPassword) { @@ -244,7 +245,7 @@ public void setVncPassword(String vncPassword) { } public String getVncAddr() { - return this.vncAddr; + return vncAddr; } public void setVncAddr(String vncAddr) { @@ -275,4 +276,12 @@ public void setGpuDevice(GPUDeviceTO gpuDevice) { this.gpuDevice = gpuDevice; } + public String getPlatformEmulator() { + return platformEmulator; + } + + public void setPlatformEmulator(String platformEmulator) { + this.platformEmulator = platformEmulator; + } + } diff --git a/api/src/com/cloud/capacity/Capacity.java b/api/src/com/cloud/capacity/Capacity.java index c1c5d8fa9b..2fbc1d6eef 100755 --- a/api/src/com/cloud/capacity/Capacity.java +++ b/api/src/com/cloud/capacity/Capacity.java @@ -30,6 +30,7 @@ public interface Capacity extends InternalIdentity, Identity { public static final short CAPACITY_TYPE_VLAN = 7; public static final short CAPACITY_TYPE_DIRECT_ATTACHED_PUBLIC_IP = 8; public static final short CAPACITY_TYPE_LOCAL_STORAGE = 9; + public static final short CAPACITY_TYPE_GPU = 19; public Long getHostOrPoolId(); diff --git a/api/src/com/cloud/dc/Vlan.java b/api/src/com/cloud/dc/Vlan.java index ac9acda741..dd12128a25 100644 --- a/api/src/com/cloud/dc/Vlan.java +++ b/api/src/com/cloud/dc/Vlan.java @@ -20,6 +20,8 @@ import org.apache.cloudstack.api.Identity; import org.apache.cloudstack.api.InternalIdentity; +import java.util.Date; + public interface Vlan extends InfrastructureEntity, InternalIdentity, Identity { public enum VlanType { DirectAttached, VirtualNetwork @@ -41,6 +43,10 @@ public enum VlanType { public Long getNetworkId(); + public Date getRemoved(); + + public Date getCreated(); + public Long getPhysicalNetworkId(); public String getIp6Gateway(); diff --git a/api/src/com/cloud/event/EventTypes.java b/api/src/com/cloud/event/EventTypes.java index 39ef710f8a..5b9ea5c1a9 100755 --- a/api/src/com/cloud/event/EventTypes.java +++ b/api/src/com/cloud/event/EventTypes.java @@ -19,6 +19,19 @@ import java.util.HashMap; import java.util.Map; +import com.cloud.network.IpAddress; +import com.cloud.network.Site2SiteCustomerGateway; +import com.cloud.network.Site2SiteVpnGateway; +import com.cloud.network.rules.FirewallRule; +import com.cloud.network.rules.HealthCheckPolicy; +import com.cloud.network.rules.StickinessPolicy; +import com.cloud.network.vpc.NetworkACL; +import com.cloud.network.vpc.NetworkACLItem; +import com.cloud.network.Site2SiteVpnConnection; +import com.cloud.server.ResourceTag; +import com.cloud.storage.snapshot.SnapshotPolicy; +import com.cloud.vm.ConsoleProxy; +import com.cloud.vm.SecondaryStorageVm; import org.apache.cloudstack.config.Configuration; import com.cloud.dc.DataCenter; @@ -32,7 +45,6 @@ import com.cloud.network.PhysicalNetwork; import com.cloud.network.PhysicalNetworkServiceProvider; import com.cloud.network.PhysicalNetworkTrafficType; -import com.cloud.network.PublicIpAddress; import com.cloud.network.RemoteAccessVpn; import com.cloud.network.as.AutoScaleCounter; import com.cloud.network.as.AutoScalePolicy; @@ -62,7 +74,7 @@ public class EventTypes { //map of Event and corresponding entity for which Event is applicable - private static Map entityEventDetails = null; + private static Map entityEventDetails = null; // VM Events public static final String EVENT_VM_CREATE = "VM.CREATE"; @@ -117,6 +129,10 @@ public class EventTypes { public static final String EVENT_FIREWALL_CLOSE = "FIREWALL.CLOSE"; public static final String EVENT_FIREWALL_UPDATE = "FIREWALL.UPDATE"; + public static final String EVENT_FIREWALL_EGRESS_OPEN = "FIREWALL.EGRESS.OPEN"; + public static final String EVENT_FIREWALL_EGRESS_CLOSE = "FIREWALL.EGRESS.CLOSE"; + public static final String EVENT_FIREWALL_EGRESS_UPDATE = "FIREWALL.EGRESS.UPDATE"; + //NIC Events public static final String EVENT_NIC_CREATE = "NIC.CREATE"; public static final String EVENT_NIC_DELETE = "NIC.DELETE"; @@ -131,9 +147,11 @@ public class EventTypes { public static final String EVENT_LOAD_BALANCER_CREATE = "LB.CREATE"; public static final String EVENT_LOAD_BALANCER_DELETE = "LB.DELETE"; public static final String EVENT_LB_STICKINESSPOLICY_CREATE = "LB.STICKINESSPOLICY.CREATE"; + public static final String EVENT_LB_STICKINESSPOLICY_UPDATE = "LB.STICKINESSPOLICY.UPDATE"; public static final String EVENT_LB_STICKINESSPOLICY_DELETE = "LB.STICKINESSPOLICY.DELETE"; public static final String EVENT_LB_HEALTHCHECKPOLICY_CREATE = "LB.HEALTHCHECKPOLICY.CREATE"; public static final String EVENT_LB_HEALTHCHECKPOLICY_DELETE = "LB.HEALTHCHECKPOLICY.DELETE"; + public static final String EVENT_LB_HEALTHCHECKPOLICY_UPDATE = "LB.HEALTHCHECKPOLICY.UPDATE"; public static final String EVENT_LOAD_BALANCER_UPDATE = "LB.UPDATE"; public static final String EVENT_LB_CERT_UPLOAD = "LB.CERT.UPLOAD"; public static final String EVENT_LB_CERT_DELETE = "LB.CERT.DELETE"; @@ -492,122 +510,130 @@ public class EventTypes { static { // TODO: need a way to force author adding event types to declare the entity details as well, with out braking - // current ActionEvent annotation semantics - // TODO #2 - The map should be from event type to class. - - entityEventDetails = new HashMap(); - - entityEventDetails.put(EVENT_VM_CREATE, VirtualMachine.class.getName()); - entityEventDetails.put(EVENT_VM_DESTROY, VirtualMachine.class.getName()); - entityEventDetails.put(EVENT_VM_START, VirtualMachine.class.getName()); - entityEventDetails.put(EVENT_VM_STOP, VirtualMachine.class.getName()); - entityEventDetails.put(EVENT_VM_REBOOT, VirtualMachine.class.getName()); - entityEventDetails.put(EVENT_VM_UPDATE, VirtualMachine.class.getName()); - entityEventDetails.put(EVENT_VM_UPGRADE, VirtualMachine.class.getName()); - entityEventDetails.put(EVENT_VM_DYNAMIC_SCALE, VirtualMachine.class.getName()); - entityEventDetails.put(EVENT_VM_RESETPASSWORD, VirtualMachine.class.getName()); - entityEventDetails.put(EVENT_VM_RESETSSHKEY, VirtualMachine.class.getName()); - entityEventDetails.put(EVENT_VM_MIGRATE, VirtualMachine.class.getName()); - entityEventDetails.put(EVENT_VM_MOVE, VirtualMachine.class.getName()); - entityEventDetails.put(EVENT_VM_RESTORE, VirtualMachine.class.getName()); - entityEventDetails.put(EVENT_VM_EXPUNGE, VirtualMachine.class.getName()); - - entityEventDetails.put(EVENT_ROUTER_CREATE, VirtualRouter.class.getName()); - entityEventDetails.put(EVENT_ROUTER_DESTROY, VirtualRouter.class.getName()); - entityEventDetails.put(EVENT_ROUTER_START, VirtualRouter.class.getName()); - entityEventDetails.put(EVENT_ROUTER_STOP, VirtualRouter.class.getName()); - entityEventDetails.put(EVENT_ROUTER_REBOOT, VirtualRouter.class.getName()); - entityEventDetails.put(EVENT_ROUTER_HA, VirtualRouter.class.getName()); - entityEventDetails.put(EVENT_ROUTER_UPGRADE, VirtualRouter.class.getName()); - - entityEventDetails.put(EVENT_PROXY_CREATE, "ConsoleProxy"); - entityEventDetails.put(EVENT_PROXY_DESTROY, "ConsoleProxy"); - entityEventDetails.put(EVENT_PROXY_START, "ConsoleProxy"); - entityEventDetails.put(EVENT_PROXY_STOP, "ConsoleProxy"); - entityEventDetails.put(EVENT_PROXY_REBOOT, "ConsoleProxy"); - entityEventDetails.put(EVENT_ROUTER_HA, "ConsoleProxy"); - entityEventDetails.put(EVENT_PROXY_HA, "ConsoleProxy"); + + entityEventDetails = new HashMap(); + + entityEventDetails.put(EVENT_VM_CREATE, VirtualMachine.class); + entityEventDetails.put(EVENT_VM_DESTROY, VirtualMachine.class); + entityEventDetails.put(EVENT_VM_START, VirtualMachine.class); + entityEventDetails.put(EVENT_VM_STOP, VirtualMachine.class); + entityEventDetails.put(EVENT_VM_REBOOT, VirtualMachine.class); + entityEventDetails.put(EVENT_VM_UPDATE, VirtualMachine.class); + entityEventDetails.put(EVENT_VM_UPGRADE, VirtualMachine.class); + entityEventDetails.put(EVENT_VM_DYNAMIC_SCALE, VirtualMachine.class); + entityEventDetails.put(EVENT_VM_RESETPASSWORD, VirtualMachine.class); + entityEventDetails.put(EVENT_VM_RESETSSHKEY, VirtualMachine.class); + entityEventDetails.put(EVENT_VM_MIGRATE, VirtualMachine.class); + entityEventDetails.put(EVENT_VM_MOVE, VirtualMachine.class); + entityEventDetails.put(EVENT_VM_RESTORE, VirtualMachine.class); + entityEventDetails.put(EVENT_VM_EXPUNGE, VirtualMachine.class); + + entityEventDetails.put(EVENT_ROUTER_CREATE, VirtualRouter.class); + entityEventDetails.put(EVENT_ROUTER_DESTROY, VirtualRouter.class); + entityEventDetails.put(EVENT_ROUTER_START, VirtualRouter.class); + entityEventDetails.put(EVENT_ROUTER_STOP, VirtualRouter.class); + entityEventDetails.put(EVENT_ROUTER_REBOOT, VirtualRouter.class); + entityEventDetails.put(EVENT_ROUTER_HA, VirtualRouter.class); + entityEventDetails.put(EVENT_ROUTER_UPGRADE, VirtualRouter.class); + + entityEventDetails.put(EVENT_PROXY_CREATE, ConsoleProxy.class); + entityEventDetails.put(EVENT_PROXY_DESTROY, ConsoleProxy.class); + entityEventDetails.put(EVENT_PROXY_START, ConsoleProxy.class); + entityEventDetails.put(EVENT_PROXY_STOP, ConsoleProxy.class); + entityEventDetails.put(EVENT_PROXY_REBOOT, ConsoleProxy.class); + entityEventDetails.put(EVENT_ROUTER_HA, ConsoleProxy.class); + entityEventDetails.put(EVENT_PROXY_HA, ConsoleProxy.class); entityEventDetails.put(EVENT_VNC_CONNECT, "VNC"); entityEventDetails.put(EVENT_VNC_DISCONNECT, "VNC"); // Network Events - entityEventDetails.put(EVENT_NETWORK_CREATE, Network.class.getName()); - entityEventDetails.put(EVENT_NETWORK_DELETE, Network.class.getName()); - entityEventDetails.put(EVENT_NETWORK_UPDATE, Network.class.getName()); - entityEventDetails.put(EVENT_NETWORK_RESTART, Network.class.getName()); - entityEventDetails.put(EVENT_NET_IP_ASSIGN, PublicIpAddress.class.getName()); - entityEventDetails.put(EVENT_NET_IP_RELEASE, PublicIpAddress.class.getName()); - entityEventDetails.put(EVENT_NET_RULE_ADD, Network.class.getName()); - entityEventDetails.put(EVENT_NET_RULE_DELETE, Network.class.getName()); - entityEventDetails.put(EVENT_NET_RULE_MODIFY, Network.class.getName()); - entityEventDetails.put(EVENT_FIREWALL_OPEN, Network.class.getName()); - entityEventDetails.put(EVENT_FIREWALL_CLOSE, Network.class.getName()); + entityEventDetails.put(EVENT_NETWORK_CREATE, Network.class); + entityEventDetails.put(EVENT_NETWORK_DELETE, Network.class); + entityEventDetails.put(EVENT_NETWORK_UPDATE, Network.class); + entityEventDetails.put(EVENT_NETWORK_RESTART, Network.class); + entityEventDetails.put(EVENT_NET_IP_ASSIGN, IpAddress.class); + entityEventDetails.put(EVENT_PORTABLE_IP_ASSIGN, IpAddress.class); + entityEventDetails.put(EVENT_PORTABLE_IP_RELEASE, IpAddress.class); + entityEventDetails.put(EVENT_NET_IP_RELEASE, IpAddress.class); + entityEventDetails.put(EVENT_NET_RULE_ADD, FirewallRule.class); + entityEventDetails.put(EVENT_NET_RULE_DELETE, FirewallRule.class); + entityEventDetails.put(EVENT_NET_RULE_MODIFY, FirewallRule.class); + entityEventDetails.put(EVENT_FIREWALL_OPEN, FirewallRule.class); + entityEventDetails.put(EVENT_FIREWALL_CLOSE, FirewallRule.class); + entityEventDetails.put(EVENT_FIREWALL_EGRESS_OPEN, FirewallRule.class); + entityEventDetails.put(EVENT_FIREWALL_EGRESS_CLOSE, FirewallRule.class); + entityEventDetails.put(EVENT_FIREWALL_EGRESS_UPDATE, FirewallRule.class); + // Load Balancers - entityEventDetails.put(EVENT_ASSIGN_TO_LOAD_BALANCER_RULE, LoadBalancer.class.getName()); - entityEventDetails.put(EVENT_REMOVE_FROM_LOAD_BALANCER_RULE, LoadBalancer.class.getName()); - entityEventDetails.put(EVENT_LOAD_BALANCER_CREATE, LoadBalancer.class.getName()); - entityEventDetails.put(EVENT_LOAD_BALANCER_DELETE, LoadBalancer.class.getName()); - entityEventDetails.put(EVENT_LB_STICKINESSPOLICY_CREATE, LoadBalancer.class.getName()); - entityEventDetails.put(EVENT_LB_STICKINESSPOLICY_DELETE, LoadBalancer.class.getName()); - entityEventDetails.put(EVENT_LOAD_BALANCER_UPDATE, LoadBalancer.class.getName()); - entityEventDetails.put(EVENT_LB_CERT_UPLOAD, LoadBalancer.class.getName()); - entityEventDetails.put(EVENT_LB_CERT_DELETE, LoadBalancer.class.getName()); - entityEventDetails.put(EVENT_LB_CERT_ASSIGN, LoadBalancer.class.getName()); - entityEventDetails.put(EVENT_LB_CERT_REMOVE, LoadBalancer.class.getName()); + entityEventDetails.put(EVENT_ASSIGN_TO_LOAD_BALANCER_RULE, FirewallRule.class); + entityEventDetails.put(EVENT_REMOVE_FROM_LOAD_BALANCER_RULE, FirewallRule.class); + entityEventDetails.put(EVENT_LOAD_BALANCER_CREATE, LoadBalancer.class); + entityEventDetails.put(EVENT_LOAD_BALANCER_DELETE, FirewallRule.class); + entityEventDetails.put(EVENT_LB_STICKINESSPOLICY_CREATE, StickinessPolicy.class); + entityEventDetails.put(EVENT_LB_STICKINESSPOLICY_UPDATE, StickinessPolicy.class); + entityEventDetails.put(EVENT_LB_STICKINESSPOLICY_DELETE, StickinessPolicy.class); + entityEventDetails.put(EVENT_LB_HEALTHCHECKPOLICY_CREATE, HealthCheckPolicy.class); + entityEventDetails.put(EVENT_LB_HEALTHCHECKPOLICY_UPDATE, HealthCheckPolicy.class); + entityEventDetails.put(EVENT_LB_HEALTHCHECKPOLICY_DELETE, HealthCheckPolicy.class); + entityEventDetails.put(EVENT_LOAD_BALANCER_UPDATE, LoadBalancer.class); + entityEventDetails.put(EVENT_LB_CERT_UPLOAD, LoadBalancer.class); + entityEventDetails.put(EVENT_LB_CERT_DELETE, LoadBalancer.class); + entityEventDetails.put(EVENT_LB_CERT_ASSIGN, LoadBalancer.class); + entityEventDetails.put(EVENT_LB_CERT_REMOVE, LoadBalancer.class); // Account events - entityEventDetails.put(EVENT_ACCOUNT_ENABLE, Account.class.getName()); - entityEventDetails.put(EVENT_ACCOUNT_DISABLE, Account.class.getName()); - entityEventDetails.put(EVENT_ACCOUNT_CREATE, Account.class.getName()); - entityEventDetails.put(EVENT_ACCOUNT_DELETE, Account.class.getName()); - entityEventDetails.put(EVENT_ACCOUNT_UPDATE, Account.class.getName()); - entityEventDetails.put(EVENT_ACCOUNT_MARK_DEFAULT_ZONE, Account.class.getName()); + entityEventDetails.put(EVENT_ACCOUNT_ENABLE, Account.class); + entityEventDetails.put(EVENT_ACCOUNT_DISABLE, Account.class); + entityEventDetails.put(EVENT_ACCOUNT_CREATE, Account.class); + entityEventDetails.put(EVENT_ACCOUNT_DELETE, Account.class); + entityEventDetails.put(EVENT_ACCOUNT_UPDATE, Account.class); + entityEventDetails.put(EVENT_ACCOUNT_MARK_DEFAULT_ZONE, Account.class); // UserVO Events - entityEventDetails.put(EVENT_USER_LOGIN, User.class.getName()); - entityEventDetails.put(EVENT_USER_LOGOUT, User.class.getName()); - entityEventDetails.put(EVENT_USER_CREATE, User.class.getName()); - entityEventDetails.put(EVENT_USER_DELETE, User.class.getName()); - entityEventDetails.put(EVENT_USER_DISABLE, User.class.getName()); - entityEventDetails.put(EVENT_USER_UPDATE, User.class.getName()); - entityEventDetails.put(EVENT_USER_ENABLE, User.class.getName()); - entityEventDetails.put(EVENT_USER_LOCK, User.class.getName()); + entityEventDetails.put(EVENT_USER_LOGIN, User.class); + entityEventDetails.put(EVENT_USER_LOGOUT, User.class); + entityEventDetails.put(EVENT_USER_CREATE, User.class); + entityEventDetails.put(EVENT_USER_DELETE, User.class); + entityEventDetails.put(EVENT_USER_DISABLE, User.class); + entityEventDetails.put(EVENT_USER_UPDATE, User.class); + entityEventDetails.put(EVENT_USER_ENABLE, User.class); + entityEventDetails.put(EVENT_USER_LOCK, User.class); // Template Events - entityEventDetails.put(EVENT_TEMPLATE_CREATE, VirtualMachineTemplate.class.getName()); - entityEventDetails.put(EVENT_TEMPLATE_DELETE, VirtualMachineTemplate.class.getName()); - entityEventDetails.put(EVENT_TEMPLATE_UPDATE, VirtualMachineTemplate.class.getName()); - entityEventDetails.put(EVENT_TEMPLATE_DOWNLOAD_START, VirtualMachineTemplate.class.getName()); - entityEventDetails.put(EVENT_TEMPLATE_DOWNLOAD_SUCCESS, VirtualMachineTemplate.class.getName()); - entityEventDetails.put(EVENT_TEMPLATE_DOWNLOAD_FAILED, VirtualMachineTemplate.class.getName()); - entityEventDetails.put(EVENT_TEMPLATE_COPY, VirtualMachineTemplate.class.getName()); - entityEventDetails.put(EVENT_TEMPLATE_EXTRACT, VirtualMachineTemplate.class.getName()); - entityEventDetails.put(EVENT_TEMPLATE_UPLOAD, VirtualMachineTemplate.class.getName()); - entityEventDetails.put(EVENT_TEMPLATE_CLEANUP, VirtualMachineTemplate.class.getName()); + entityEventDetails.put(EVENT_TEMPLATE_CREATE, VirtualMachineTemplate.class); + entityEventDetails.put(EVENT_TEMPLATE_DELETE, VirtualMachineTemplate.class); + entityEventDetails.put(EVENT_TEMPLATE_UPDATE, VirtualMachineTemplate.class); + entityEventDetails.put(EVENT_TEMPLATE_DOWNLOAD_START, VirtualMachineTemplate.class); + entityEventDetails.put(EVENT_TEMPLATE_DOWNLOAD_SUCCESS, VirtualMachineTemplate.class); + entityEventDetails.put(EVENT_TEMPLATE_DOWNLOAD_FAILED, VirtualMachineTemplate.class); + entityEventDetails.put(EVENT_TEMPLATE_COPY, VirtualMachineTemplate.class); + entityEventDetails.put(EVENT_TEMPLATE_EXTRACT, VirtualMachineTemplate.class); + entityEventDetails.put(EVENT_TEMPLATE_UPLOAD, VirtualMachineTemplate.class); + entityEventDetails.put(EVENT_TEMPLATE_CLEANUP, VirtualMachineTemplate.class); // Volume Events - entityEventDetails.put(EVENT_VOLUME_CREATE, Volume.class.getName()); - entityEventDetails.put(EVENT_VOLUME_DELETE, Volume.class.getName()); - entityEventDetails.put(EVENT_VOLUME_ATTACH, Volume.class.getName()); - entityEventDetails.put(EVENT_VOLUME_DETACH, Volume.class.getName()); - entityEventDetails.put(EVENT_VOLUME_EXTRACT, Volume.class.getName()); - entityEventDetails.put(EVENT_VOLUME_UPLOAD, Volume.class.getName()); - entityEventDetails.put(EVENT_VOLUME_MIGRATE, Volume.class.getName()); - entityEventDetails.put(EVENT_VOLUME_RESIZE, Volume.class.getName()); + entityEventDetails.put(EVENT_VOLUME_CREATE, Volume.class); + entityEventDetails.put(EVENT_VOLUME_DELETE, Volume.class); + entityEventDetails.put(EVENT_VOLUME_ATTACH, Volume.class); + entityEventDetails.put(EVENT_VOLUME_DETACH, Volume.class); + entityEventDetails.put(EVENT_VOLUME_EXTRACT, Volume.class); + entityEventDetails.put(EVENT_VOLUME_UPLOAD, Volume.class); + entityEventDetails.put(EVENT_VOLUME_MIGRATE, Volume.class); + entityEventDetails.put(EVENT_VOLUME_RESIZE, Volume.class); // Domains - entityEventDetails.put(EVENT_DOMAIN_CREATE, Domain.class.getName()); - entityEventDetails.put(EVENT_DOMAIN_DELETE, Domain.class.getName()); - entityEventDetails.put(EVENT_DOMAIN_UPDATE, Domain.class.getName()); + entityEventDetails.put(EVENT_DOMAIN_CREATE, Domain.class); + entityEventDetails.put(EVENT_DOMAIN_DELETE, Domain.class); + entityEventDetails.put(EVENT_DOMAIN_UPDATE, Domain.class); // Snapshots - entityEventDetails.put(EVENT_SNAPSHOT_CREATE, Snapshot.class.getName()); - entityEventDetails.put(EVENT_SNAPSHOT_DELETE, Snapshot.class.getName()); - entityEventDetails.put(EVENT_SNAPSHOT_POLICY_CREATE, Snapshot.class.getName()); - entityEventDetails.put(EVENT_SNAPSHOT_POLICY_UPDATE, Snapshot.class.getName()); - entityEventDetails.put(EVENT_SNAPSHOT_POLICY_DELETE, Snapshot.class.getName()); + entityEventDetails.put(EVENT_SNAPSHOT_CREATE, Snapshot.class); + entityEventDetails.put(EVENT_SNAPSHOT_DELETE, Snapshot.class); + entityEventDetails.put(EVENT_SNAPSHOT_POLICY_CREATE, SnapshotPolicy.class); + entityEventDetails.put(EVENT_SNAPSHOT_POLICY_UPDATE, SnapshotPolicy.class); + entityEventDetails.put(EVENT_SNAPSHOT_POLICY_DELETE, SnapshotPolicy.class); // ISO entityEventDetails.put(EVENT_ISO_CREATE, "Iso"); @@ -619,129 +645,129 @@ public class EventTypes { entityEventDetails.put(EVENT_ISO_UPLOAD, "Iso"); // SSVM - entityEventDetails.put(EVENT_SSVM_CREATE, "SecondaryStorageVm"); - entityEventDetails.put(EVENT_SSVM_DESTROY, "SecondaryStorageVm"); - entityEventDetails.put(EVENT_SSVM_START, "SecondaryStorageVm"); - entityEventDetails.put(EVENT_SSVM_STOP, "SecondaryStorageVm"); - entityEventDetails.put(EVENT_SSVM_REBOOT, "SecondaryStorageVm"); - entityEventDetails.put(EVENT_SSVM_HA, "SecondaryStorageVm"); + entityEventDetails.put(EVENT_SSVM_CREATE, SecondaryStorageVm.class); + entityEventDetails.put(EVENT_SSVM_DESTROY, SecondaryStorageVm.class); + entityEventDetails.put(EVENT_SSVM_START, SecondaryStorageVm.class); + entityEventDetails.put(EVENT_SSVM_STOP, SecondaryStorageVm.class); + entityEventDetails.put(EVENT_SSVM_REBOOT, SecondaryStorageVm.class); + entityEventDetails.put(EVENT_SSVM_HA, SecondaryStorageVm.class); // Service Offerings - entityEventDetails.put(EVENT_SERVICE_OFFERING_CREATE, ServiceOffering.class.getName()); - entityEventDetails.put(EVENT_SERVICE_OFFERING_EDIT, ServiceOffering.class.getName()); - entityEventDetails.put(EVENT_SERVICE_OFFERING_DELETE, ServiceOffering.class.getName()); + entityEventDetails.put(EVENT_SERVICE_OFFERING_CREATE, ServiceOffering.class); + entityEventDetails.put(EVENT_SERVICE_OFFERING_EDIT, ServiceOffering.class); + entityEventDetails.put(EVENT_SERVICE_OFFERING_DELETE, ServiceOffering.class); // Disk Offerings - entityEventDetails.put(EVENT_DISK_OFFERING_CREATE, DiskOffering.class.getName()); - entityEventDetails.put(EVENT_DISK_OFFERING_EDIT, DiskOffering.class.getName()); - entityEventDetails.put(EVENT_DISK_OFFERING_DELETE, DiskOffering.class.getName()); + entityEventDetails.put(EVENT_DISK_OFFERING_CREATE, DiskOffering.class); + entityEventDetails.put(EVENT_DISK_OFFERING_EDIT, DiskOffering.class); + entityEventDetails.put(EVENT_DISK_OFFERING_DELETE, DiskOffering.class); // Network offerings - entityEventDetails.put(EVENT_NETWORK_OFFERING_CREATE, NetworkOffering.class.getName()); - entityEventDetails.put(EVENT_NETWORK_OFFERING_ASSIGN, NetworkOffering.class.getName()); - entityEventDetails.put(EVENT_NETWORK_OFFERING_EDIT, NetworkOffering.class.getName()); - entityEventDetails.put(EVENT_NETWORK_OFFERING_REMOVE, NetworkOffering.class.getName()); - entityEventDetails.put(EVENT_NETWORK_OFFERING_DELETE, NetworkOffering.class.getName()); + entityEventDetails.put(EVENT_NETWORK_OFFERING_CREATE, NetworkOffering.class); + entityEventDetails.put(EVENT_NETWORK_OFFERING_ASSIGN, NetworkOffering.class); + entityEventDetails.put(EVENT_NETWORK_OFFERING_EDIT, NetworkOffering.class); + entityEventDetails.put(EVENT_NETWORK_OFFERING_REMOVE, NetworkOffering.class); + entityEventDetails.put(EVENT_NETWORK_OFFERING_DELETE, NetworkOffering.class); // Pods - entityEventDetails.put(EVENT_POD_CREATE, Pod.class.getName()); - entityEventDetails.put(EVENT_POD_EDIT, Pod.class.getName()); - entityEventDetails.put(EVENT_POD_DELETE, Pod.class.getName()); + entityEventDetails.put(EVENT_POD_CREATE, Pod.class); + entityEventDetails.put(EVENT_POD_EDIT, Pod.class); + entityEventDetails.put(EVENT_POD_DELETE, Pod.class); // Zones - entityEventDetails.put(EVENT_ZONE_CREATE, DataCenter.class.getName()); - entityEventDetails.put(EVENT_ZONE_EDIT, DataCenter.class.getName()); - entityEventDetails.put(EVENT_ZONE_DELETE, DataCenter.class.getName()); + entityEventDetails.put(EVENT_ZONE_CREATE, DataCenter.class); + entityEventDetails.put(EVENT_ZONE_EDIT, DataCenter.class); + entityEventDetails.put(EVENT_ZONE_DELETE, DataCenter.class); // VLANs/IP ranges - entityEventDetails.put(EVENT_VLAN_IP_RANGE_CREATE, Vlan.class.getName()); - entityEventDetails.put(EVENT_VLAN_IP_RANGE_DELETE, Vlan.class.getName()); - entityEventDetails.put(EVENT_VLAN_IP_RANGE_DEDICATE, Vlan.class.getName()); - entityEventDetails.put(EVENT_VLAN_IP_RANGE_RELEASE, Vlan.class.getName()); + entityEventDetails.put(EVENT_VLAN_IP_RANGE_CREATE, Vlan.class); + entityEventDetails.put(EVENT_VLAN_IP_RANGE_DELETE, Vlan.class); + entityEventDetails.put(EVENT_VLAN_IP_RANGE_DEDICATE, Vlan.class); + entityEventDetails.put(EVENT_VLAN_IP_RANGE_RELEASE, Vlan.class); - entityEventDetails.put(EVENT_STORAGE_IP_RANGE_CREATE, StorageNetworkIpRange.class.getName()); - entityEventDetails.put(EVENT_STORAGE_IP_RANGE_DELETE, StorageNetworkIpRange.class.getName()); - entityEventDetails.put(EVENT_STORAGE_IP_RANGE_UPDATE, StorageNetworkIpRange.class.getName()); + entityEventDetails.put(EVENT_STORAGE_IP_RANGE_CREATE, StorageNetworkIpRange.class); + entityEventDetails.put(EVENT_STORAGE_IP_RANGE_DELETE, StorageNetworkIpRange.class); + entityEventDetails.put(EVENT_STORAGE_IP_RANGE_UPDATE, StorageNetworkIpRange.class); // Configuration Table - entityEventDetails.put(EVENT_CONFIGURATION_VALUE_EDIT, Configuration.class.getName()); + entityEventDetails.put(EVENT_CONFIGURATION_VALUE_EDIT, Configuration.class); // Security Groups - entityEventDetails.put(EVENT_SECURITY_GROUP_AUTHORIZE_INGRESS, SecurityGroup.class.getName()); - entityEventDetails.put(EVENT_SECURITY_GROUP_REVOKE_INGRESS, SecurityGroup.class.getName()); - entityEventDetails.put(EVENT_SECURITY_GROUP_AUTHORIZE_EGRESS, SecurityGroup.class.getName()); - entityEventDetails.put(EVENT_SECURITY_GROUP_REVOKE_EGRESS, SecurityGroup.class.getName()); - entityEventDetails.put(EVENT_SECURITY_GROUP_CREATE, SecurityGroup.class.getName()); - entityEventDetails.put(EVENT_SECURITY_GROUP_DELETE, SecurityGroup.class.getName()); - entityEventDetails.put(EVENT_SECURITY_GROUP_ASSIGN, SecurityGroup.class.getName()); - entityEventDetails.put(EVENT_SECURITY_GROUP_REMOVE, SecurityGroup.class.getName()); + entityEventDetails.put(EVENT_SECURITY_GROUP_AUTHORIZE_INGRESS, SecurityGroup.class); + entityEventDetails.put(EVENT_SECURITY_GROUP_REVOKE_INGRESS, SecurityGroup.class); + entityEventDetails.put(EVENT_SECURITY_GROUP_AUTHORIZE_EGRESS, SecurityGroup.class); + entityEventDetails.put(EVENT_SECURITY_GROUP_REVOKE_EGRESS, SecurityGroup.class); + entityEventDetails.put(EVENT_SECURITY_GROUP_CREATE, SecurityGroup.class); + entityEventDetails.put(EVENT_SECURITY_GROUP_DELETE, SecurityGroup.class); + entityEventDetails.put(EVENT_SECURITY_GROUP_ASSIGN, SecurityGroup.class); + entityEventDetails.put(EVENT_SECURITY_GROUP_REMOVE, SecurityGroup.class); // Host - entityEventDetails.put(EVENT_HOST_RECONNECT, Host.class.getName()); + entityEventDetails.put(EVENT_HOST_RECONNECT, Host.class); // Maintenance - entityEventDetails.put(EVENT_MAINTENANCE_CANCEL, Host.class.getName()); - entityEventDetails.put(EVENT_MAINTENANCE_CANCEL_PRIMARY_STORAGE, Host.class.getName()); - entityEventDetails.put(EVENT_MAINTENANCE_PREPARE, Host.class.getName()); - entityEventDetails.put(EVENT_MAINTENANCE_PREPARE_PRIMARY_STORAGE, Host.class.getName()); + entityEventDetails.put(EVENT_MAINTENANCE_CANCEL, Host.class); + entityEventDetails.put(EVENT_MAINTENANCE_CANCEL_PRIMARY_STORAGE, Host.class); + entityEventDetails.put(EVENT_MAINTENANCE_PREPARE, Host.class); + entityEventDetails.put(EVENT_MAINTENANCE_PREPARE_PRIMARY_STORAGE, Host.class); // VPN - entityEventDetails.put(EVENT_REMOTE_ACCESS_VPN_CREATE, RemoteAccessVpn.class.getName()); - entityEventDetails.put(EVENT_REMOTE_ACCESS_VPN_DESTROY, RemoteAccessVpn.class.getName()); - entityEventDetails.put(EVENT_VPN_USER_ADD, RemoteAccessVpn.class.getName()); - entityEventDetails.put(EVENT_VPN_USER_REMOVE, RemoteAccessVpn.class.getName()); - entityEventDetails.put(EVENT_S2S_VPN_GATEWAY_CREATE, RemoteAccessVpn.class.getName()); - entityEventDetails.put(EVENT_S2S_VPN_GATEWAY_DELETE, RemoteAccessVpn.class.getName()); - entityEventDetails.put(EVENT_S2S_VPN_CUSTOMER_GATEWAY_CREATE, RemoteAccessVpn.class.getName()); - entityEventDetails.put(EVENT_S2S_VPN_CUSTOMER_GATEWAY_DELETE, RemoteAccessVpn.class.getName()); - entityEventDetails.put(EVENT_S2S_VPN_CUSTOMER_GATEWAY_UPDATE, RemoteAccessVpn.class.getName()); - entityEventDetails.put(EVENT_S2S_VPN_CONNECTION_CREATE, RemoteAccessVpn.class.getName()); - entityEventDetails.put(EVENT_S2S_VPN_CONNECTION_DELETE, RemoteAccessVpn.class.getName()); - entityEventDetails.put(EVENT_S2S_VPN_CONNECTION_RESET, RemoteAccessVpn.class.getName()); + entityEventDetails.put(EVENT_REMOTE_ACCESS_VPN_CREATE, RemoteAccessVpn.class); + entityEventDetails.put(EVENT_REMOTE_ACCESS_VPN_DESTROY, RemoteAccessVpn.class); + entityEventDetails.put(EVENT_VPN_USER_ADD, RemoteAccessVpn.class); + entityEventDetails.put(EVENT_VPN_USER_REMOVE, RemoteAccessVpn.class); + entityEventDetails.put(EVENT_S2S_VPN_GATEWAY_CREATE, Site2SiteVpnGateway.class); + entityEventDetails.put(EVENT_S2S_VPN_GATEWAY_DELETE, Site2SiteVpnGateway.class); + entityEventDetails.put(EVENT_S2S_VPN_CUSTOMER_GATEWAY_CREATE, Site2SiteCustomerGateway.class); + entityEventDetails.put(EVENT_S2S_VPN_CUSTOMER_GATEWAY_DELETE, Site2SiteCustomerGateway.class); + entityEventDetails.put(EVENT_S2S_VPN_CUSTOMER_GATEWAY_UPDATE, Site2SiteCustomerGateway.class); + entityEventDetails.put(EVENT_S2S_VPN_CONNECTION_CREATE, Site2SiteVpnConnection.class); + entityEventDetails.put(EVENT_S2S_VPN_CONNECTION_DELETE, Site2SiteVpnConnection.class); + entityEventDetails.put(EVENT_S2S_VPN_CONNECTION_RESET, Site2SiteVpnConnection.class); // Custom certificates entityEventDetails.put(EVENT_UPLOAD_CUSTOM_CERTIFICATE, "Certificate"); // OneToOnenat - entityEventDetails.put(EVENT_ENABLE_STATIC_NAT, StaticNat.class.getName()); - entityEventDetails.put(EVENT_DISABLE_STATIC_NAT, StaticNat.class.getName()); + entityEventDetails.put(EVENT_ENABLE_STATIC_NAT, StaticNat.class); + entityEventDetails.put(EVENT_DISABLE_STATIC_NAT, StaticNat.class); - entityEventDetails.put(EVENT_ZONE_VLAN_ASSIGN, Vlan.class.getName()); - entityEventDetails.put(EVENT_ZONE_VLAN_RELEASE, Vlan.class.getName()); + entityEventDetails.put(EVENT_ZONE_VLAN_ASSIGN, Vlan.class); + entityEventDetails.put(EVENT_ZONE_VLAN_RELEASE, Vlan.class); // Projects - entityEventDetails.put(EVENT_PROJECT_CREATE, Project.class.getName()); - entityEventDetails.put(EVENT_PROJECT_UPDATE, Project.class.getName()); - entityEventDetails.put(EVENT_PROJECT_DELETE, Project.class.getName()); - entityEventDetails.put(EVENT_PROJECT_ACTIVATE, Project.class.getName()); - entityEventDetails.put(EVENT_PROJECT_SUSPEND, Project.class.getName()); - entityEventDetails.put(EVENT_PROJECT_ACCOUNT_ADD, Project.class.getName()); - entityEventDetails.put(EVENT_PROJECT_INVITATION_UPDATE, Project.class.getName()); - entityEventDetails.put(EVENT_PROJECT_INVITATION_REMOVE, Project.class.getName()); - entityEventDetails.put(EVENT_PROJECT_ACCOUNT_REMOVE, Project.class.getName()); + entityEventDetails.put(EVENT_PROJECT_CREATE, Project.class); + entityEventDetails.put(EVENT_PROJECT_UPDATE, Project.class); + entityEventDetails.put(EVENT_PROJECT_DELETE, Project.class); + entityEventDetails.put(EVENT_PROJECT_ACTIVATE, Project.class); + entityEventDetails.put(EVENT_PROJECT_SUSPEND, Project.class); + entityEventDetails.put(EVENT_PROJECT_ACCOUNT_ADD, Project.class); + entityEventDetails.put(EVENT_PROJECT_INVITATION_UPDATE, Project.class); + entityEventDetails.put(EVENT_PROJECT_INVITATION_REMOVE, Project.class); + entityEventDetails.put(EVENT_PROJECT_ACCOUNT_REMOVE, Project.class); // Network as a Service - entityEventDetails.put(EVENT_NETWORK_ELEMENT_CONFIGURE, Network.class.getName()); + entityEventDetails.put(EVENT_NETWORK_ELEMENT_CONFIGURE, Network.class); // Physical Network Events - entityEventDetails.put(EVENT_PHYSICAL_NETWORK_CREATE, PhysicalNetwork.class.getName()); - entityEventDetails.put(EVENT_PHYSICAL_NETWORK_DELETE, PhysicalNetwork.class.getName()); - entityEventDetails.put(EVENT_PHYSICAL_NETWORK_UPDATE, PhysicalNetwork.class.getName()); + entityEventDetails.put(EVENT_PHYSICAL_NETWORK_CREATE, PhysicalNetwork.class); + entityEventDetails.put(EVENT_PHYSICAL_NETWORK_DELETE, PhysicalNetwork.class); + entityEventDetails.put(EVENT_PHYSICAL_NETWORK_UPDATE, PhysicalNetwork.class); // Physical Network Service Provider Events - entityEventDetails.put(EVENT_SERVICE_PROVIDER_CREATE, PhysicalNetworkServiceProvider.class.getName()); - entityEventDetails.put(EVENT_SERVICE_PROVIDER_DELETE, PhysicalNetworkServiceProvider.class.getName()); - entityEventDetails.put(EVENT_SERVICE_PROVIDER_UPDATE, PhysicalNetworkServiceProvider.class.getName()); + entityEventDetails.put(EVENT_SERVICE_PROVIDER_CREATE, PhysicalNetworkServiceProvider.class); + entityEventDetails.put(EVENT_SERVICE_PROVIDER_DELETE, PhysicalNetworkServiceProvider.class); + entityEventDetails.put(EVENT_SERVICE_PROVIDER_UPDATE, PhysicalNetworkServiceProvider.class); // Physical Network TrafficType Events - entityEventDetails.put(EVENT_TRAFFIC_TYPE_CREATE, PhysicalNetworkTrafficType.class.getName()); - entityEventDetails.put(EVENT_TRAFFIC_TYPE_DELETE, PhysicalNetworkTrafficType.class.getName()); - entityEventDetails.put(EVENT_TRAFFIC_TYPE_UPDATE, PhysicalNetworkTrafficType.class.getName()); + entityEventDetails.put(EVENT_TRAFFIC_TYPE_CREATE, PhysicalNetworkTrafficType.class); + entityEventDetails.put(EVENT_TRAFFIC_TYPE_DELETE, PhysicalNetworkTrafficType.class); + entityEventDetails.put(EVENT_TRAFFIC_TYPE_UPDATE, PhysicalNetworkTrafficType.class); // external network device events - entityEventDetails.put(EVENT_EXTERNAL_LB_DEVICE_ADD, PhysicalNetwork.class.getName()); - entityEventDetails.put(EVENT_EXTERNAL_LB_DEVICE_DELETE, PhysicalNetwork.class.getName()); - entityEventDetails.put(EVENT_EXTERNAL_LB_DEVICE_CONFIGURE, PhysicalNetwork.class.getName()); + entityEventDetails.put(EVENT_EXTERNAL_LB_DEVICE_ADD, PhysicalNetwork.class); + entityEventDetails.put(EVENT_EXTERNAL_LB_DEVICE_DELETE, PhysicalNetwork.class); + entityEventDetails.put(EVENT_EXTERNAL_LB_DEVICE_CONFIGURE, PhysicalNetwork.class); // external switch management device events (E.g.: Cisco Nexus 1000v Virtual Supervisor Module. entityEventDetails.put(EVENT_EXTERNAL_SWITCH_MGMT_DEVICE_ADD, "Nexus1000v"); @@ -750,32 +776,41 @@ public class EventTypes { entityEventDetails.put(EVENT_EXTERNAL_SWITCH_MGMT_DEVICE_ENABLE, "Nexus1000v"); entityEventDetails.put(EVENT_EXTERNAL_SWITCH_MGMT_DEVICE_DISABLE, "Nexus1000v"); - entityEventDetails.put(EVENT_EXTERNAL_FIREWALL_DEVICE_ADD, PhysicalNetwork.class.getName()); - entityEventDetails.put(EVENT_EXTERNAL_FIREWALL_DEVICE_DELETE, PhysicalNetwork.class.getName()); - entityEventDetails.put(EVENT_EXTERNAL_FIREWALL_DEVICE_CONFIGURE, PhysicalNetwork.class.getName()); + entityEventDetails.put(EVENT_EXTERNAL_FIREWALL_DEVICE_ADD, PhysicalNetwork.class); + entityEventDetails.put(EVENT_EXTERNAL_FIREWALL_DEVICE_DELETE, PhysicalNetwork.class); + entityEventDetails.put(EVENT_EXTERNAL_FIREWALL_DEVICE_CONFIGURE, PhysicalNetwork.class); + + // Network ACL + entityEventDetails.put(EVENT_NETWORK_ACL_CREATE, NetworkACL.class); + entityEventDetails.put(EVENT_NETWORK_ACL_DELETE, NetworkACL.class); + entityEventDetails.put(EVENT_NETWORK_ACL_REPLACE, NetworkACL.class); + entityEventDetails.put(EVENT_NETWORK_ACL_UPDATE, NetworkACL.class); + entityEventDetails.put(EVENT_NETWORK_ACL_ITEM_CREATE, NetworkACLItem.class); + entityEventDetails.put(EVENT_NETWORK_ACL_ITEM_UPDATE, NetworkACLItem.class); + entityEventDetails.put(EVENT_NETWORK_ACL_ITEM_DELETE, NetworkACLItem.class); // VPC - entityEventDetails.put(EVENT_VPC_CREATE, Vpc.class.getName()); - entityEventDetails.put(EVENT_VPC_UPDATE, Vpc.class.getName()); - entityEventDetails.put(EVENT_VPC_DELETE, Vpc.class.getName()); - entityEventDetails.put(EVENT_VPC_RESTART, Vpc.class.getName()); + entityEventDetails.put(EVENT_VPC_CREATE, Vpc.class); + entityEventDetails.put(EVENT_VPC_UPDATE, Vpc.class); + entityEventDetails.put(EVENT_VPC_DELETE, Vpc.class); + entityEventDetails.put(EVENT_VPC_RESTART, Vpc.class); // VPC offerings - entityEventDetails.put(EVENT_VPC_OFFERING_CREATE, Vpc.class.getName()); - entityEventDetails.put(EVENT_VPC_OFFERING_UPDATE, Vpc.class.getName()); - entityEventDetails.put(EVENT_VPC_OFFERING_DELETE, Vpc.class.getName()); + entityEventDetails.put(EVENT_VPC_OFFERING_CREATE, Vpc.class); + entityEventDetails.put(EVENT_VPC_OFFERING_UPDATE, Vpc.class); + entityEventDetails.put(EVENT_VPC_OFFERING_DELETE, Vpc.class); // Private gateway - entityEventDetails.put(EVENT_PRIVATE_GATEWAY_CREATE, PrivateGateway.class.getName()); - entityEventDetails.put(EVENT_PRIVATE_GATEWAY_DELETE, PrivateGateway.class.getName()); + entityEventDetails.put(EVENT_PRIVATE_GATEWAY_CREATE, PrivateGateway.class); + entityEventDetails.put(EVENT_PRIVATE_GATEWAY_DELETE, PrivateGateway.class); // Static routes - entityEventDetails.put(EVENT_STATIC_ROUTE_CREATE, StaticRoute.class.getName()); - entityEventDetails.put(EVENT_STATIC_ROUTE_DELETE, StaticRoute.class.getName()); + entityEventDetails.put(EVENT_STATIC_ROUTE_CREATE, StaticRoute.class); + entityEventDetails.put(EVENT_STATIC_ROUTE_DELETE, StaticRoute.class); // tag related events - entityEventDetails.put(EVENT_TAGS_CREATE, "Tag"); - entityEventDetails.put(EVENT_TAGS_DELETE, "tag"); + entityEventDetails.put(EVENT_TAGS_CREATE, ResourceTag.class); + entityEventDetails.put(EVENT_TAGS_DELETE, ResourceTag.class); // external network device events entityEventDetails.put(EVENT_EXTERNAL_NVP_CONTROLLER_ADD, "NvpController"); @@ -783,23 +818,23 @@ public class EventTypes { entityEventDetails.put(EVENT_EXTERNAL_NVP_CONTROLLER_CONFIGURE, "NvpController"); // AutoScale - entityEventDetails.put(EVENT_COUNTER_CREATE, AutoScaleCounter.class.getName()); - entityEventDetails.put(EVENT_COUNTER_DELETE, AutoScaleCounter.class.getName()); - entityEventDetails.put(EVENT_CONDITION_CREATE, Condition.class.getName()); - entityEventDetails.put(EVENT_CONDITION_DELETE, Condition.class.getName()); - entityEventDetails.put(EVENT_AUTOSCALEPOLICY_CREATE, AutoScalePolicy.class.getName()); - entityEventDetails.put(EVENT_AUTOSCALEPOLICY_UPDATE, AutoScalePolicy.class.getName()); - entityEventDetails.put(EVENT_AUTOSCALEPOLICY_DELETE, AutoScalePolicy.class.getName()); - entityEventDetails.put(EVENT_AUTOSCALEVMPROFILE_CREATE, AutoScaleVmProfile.class.getName()); - entityEventDetails.put(EVENT_AUTOSCALEVMPROFILE_DELETE, AutoScaleVmProfile.class.getName()); - entityEventDetails.put(EVENT_AUTOSCALEVMPROFILE_UPDATE, AutoScaleVmProfile.class.getName()); - entityEventDetails.put(EVENT_AUTOSCALEVMGROUP_CREATE, AutoScaleVmGroup.class.getName()); - entityEventDetails.put(EVENT_AUTOSCALEVMGROUP_DELETE, AutoScaleVmGroup.class.getName()); - entityEventDetails.put(EVENT_AUTOSCALEVMGROUP_UPDATE, AutoScaleVmGroup.class.getName()); - entityEventDetails.put(EVENT_AUTOSCALEVMGROUP_ENABLE, AutoScaleVmGroup.class.getName()); - entityEventDetails.put(EVENT_AUTOSCALEVMGROUP_DISABLE, AutoScaleVmGroup.class.getName()); - entityEventDetails.put(EVENT_GUEST_VLAN_RANGE_DEDICATE, GuestVlan.class.getName()); - entityEventDetails.put(EVENT_DEDICATED_GUEST_VLAN_RANGE_RELEASE, GuestVlan.class.getName()); + entityEventDetails.put(EVENT_COUNTER_CREATE, AutoScaleCounter.class); + entityEventDetails.put(EVENT_COUNTER_DELETE, AutoScaleCounter.class); + entityEventDetails.put(EVENT_CONDITION_CREATE, Condition.class); + entityEventDetails.put(EVENT_CONDITION_DELETE, Condition.class); + entityEventDetails.put(EVENT_AUTOSCALEPOLICY_CREATE, AutoScalePolicy.class); + entityEventDetails.put(EVENT_AUTOSCALEPOLICY_UPDATE, AutoScalePolicy.class); + entityEventDetails.put(EVENT_AUTOSCALEPOLICY_DELETE, AutoScalePolicy.class); + entityEventDetails.put(EVENT_AUTOSCALEVMPROFILE_CREATE, AutoScaleVmProfile.class); + entityEventDetails.put(EVENT_AUTOSCALEVMPROFILE_DELETE, AutoScaleVmProfile.class); + entityEventDetails.put(EVENT_AUTOSCALEVMPROFILE_UPDATE, AutoScaleVmProfile.class); + entityEventDetails.put(EVENT_AUTOSCALEVMGROUP_CREATE, AutoScaleVmGroup.class); + entityEventDetails.put(EVENT_AUTOSCALEVMGROUP_DELETE, AutoScaleVmGroup.class); + entityEventDetails.put(EVENT_AUTOSCALEVMGROUP_UPDATE, AutoScaleVmGroup.class); + entityEventDetails.put(EVENT_AUTOSCALEVMGROUP_ENABLE, AutoScaleVmGroup.class); + entityEventDetails.put(EVENT_AUTOSCALEVMGROUP_DISABLE, AutoScaleVmGroup.class); + entityEventDetails.put(EVENT_GUEST_VLAN_RANGE_DEDICATE, GuestVlan.class); + entityEventDetails.put(EVENT_DEDICATED_GUEST_VLAN_RANGE_RELEASE, GuestVlan.class); // OpenDaylight entityEventDetails.put(EVENT_EXTERNAL_OPENDAYLIGHT_ADD_CONTROLLER, "OpenDaylightController"); @@ -807,24 +842,40 @@ public class EventTypes { entityEventDetails.put(EVENT_EXTERNAL_OPENDAYLIGHT_CONFIGURE_CONTROLLER, "OpenDaylightController"); //Guest OS - entityEventDetails.put(EVENT_GUEST_OS_ADD, GuestOS.class.getName()); - entityEventDetails.put(EVENT_GUEST_OS_REMOVE, GuestOS.class.getName()); - entityEventDetails.put(EVENT_GUEST_OS_UPDATE, GuestOS.class.getName()); - entityEventDetails.put(EVENT_GUEST_OS_MAPPING_ADD, GuestOSHypervisor.class.getName()); - entityEventDetails.put(EVENT_GUEST_OS_MAPPING_REMOVE, GuestOSHypervisor.class.getName()); - entityEventDetails.put(EVENT_GUEST_OS_MAPPING_UPDATE, GuestOSHypervisor.class.getName()); + entityEventDetails.put(EVENT_GUEST_OS_ADD, GuestOS.class); + entityEventDetails.put(EVENT_GUEST_OS_REMOVE, GuestOS.class); + entityEventDetails.put(EVENT_GUEST_OS_UPDATE, GuestOS.class); + entityEventDetails.put(EVENT_GUEST_OS_MAPPING_ADD, GuestOSHypervisor.class); + entityEventDetails.put(EVENT_GUEST_OS_MAPPING_REMOVE, GuestOSHypervisor.class); + entityEventDetails.put(EVENT_GUEST_OS_MAPPING_UPDATE, GuestOSHypervisor.class); } public static String getEntityForEvent(String eventName) { - String entityClassName = entityEventDetails.get(eventName); - if (entityClassName == null || entityClassName.isEmpty()) { + Object entityClass = entityEventDetails.get(eventName); + if (entityClass == null) { return null; + } else if (entityClass instanceof String){ + return (String)entityClass; + } else if (entityClass instanceof Class){ + String entityClassName = ((Class)entityClass).getName(); + int index = entityClassName.lastIndexOf("."); + String entityName = entityClassName; + if (index != -1) { + entityName = entityClassName.substring(index + 1); + } + return entityName; } - int index = entityClassName.lastIndexOf("."); - String entityName = entityClassName; - if (index != -1) { - entityName = entityClassName.substring(index + 1); + + return null; + } + + public static Class getEntityClassForEvent(String eventName) { + Object clz = entityEventDetails.get(eventName); + + if(clz instanceof Class){ + return (Class)entityEventDetails.get(eventName); } - return entityName; + + return null; } } diff --git a/api/src/com/cloud/gpu/GPU.java b/api/src/com/cloud/gpu/GPU.java index 0eb466758f..9177edbf9c 100644 --- a/api/src/com/cloud/gpu/GPU.java +++ b/api/src/com/cloud/gpu/GPU.java @@ -23,15 +23,13 @@ public enum Keys { pciDevice, vgpuType } - public enum Type { - GPU_Passthrough, - VGPU - } public enum vGPUType { GRID_K100("GRID K100"), + GRID_K120Q("GRID K120Q"), GRID_K140Q("GRID K140Q"), GRID_K200("GRID K200"), + GRID_K220Q("GRID K220Q"), GRID_K240Q("GRID K240Q"), GRID_K260("GRID K260Q"), passthrough("passthrough"); diff --git a/api/src/com/cloud/network/IpAddress.java b/api/src/com/cloud/network/IpAddress.java index 5aae784279..2061771ed3 100644 --- a/api/src/com/cloud/network/IpAddress.java +++ b/api/src/com/cloud/network/IpAddress.java @@ -19,6 +19,7 @@ import java.util.Date; import org.apache.cloudstack.acl.ControlledEntity; +import org.apache.cloudstack.api.Displayable; import org.apache.cloudstack.api.Identity; import org.apache.cloudstack.api.InternalIdentity; @@ -35,7 +36,7 @@ * - DomainId = domain of the account owner. * - Allocated = time it was allocated. */ -public interface IpAddress extends ControlledEntity, Identity, InternalIdentity { +public interface IpAddress extends ControlledEntity, Identity, InternalIdentity, Displayable { enum State { Allocating, // The IP Address is being propagated to other network elements and is not ready for use yet. Allocated, // The IP address is in used. @@ -87,4 +88,8 @@ enum Purpose { boolean isDisplay(); + public Date getRemoved(); + + public Date getCreated(); + } diff --git a/api/src/com/cloud/network/Network.java b/api/src/com/cloud/network/Network.java index 3283a55bfe..885bffef98 100644 --- a/api/src/com/cloud/network/Network.java +++ b/api/src/com/cloud/network/Network.java @@ -22,6 +22,7 @@ import java.util.List; import org.apache.cloudstack.acl.ControlledEntity; +import org.apache.cloudstack.api.Displayable; import org.apache.cloudstack.api.Identity; import org.apache.cloudstack.api.InternalIdentity; @@ -34,7 +35,7 @@ /** * owned by an account. */ -public interface Network extends ControlledEntity, StateObject, InternalIdentity, Identity, Serializable { +public interface Network extends ControlledEntity, StateObject, InternalIdentity, Identity, Serializable, Displayable { public enum GuestType { Shared, Isolated @@ -57,7 +58,7 @@ public static class Service { public static final Service PortForwarding = new Service("PortForwarding"); public static final Service SecurityGroup = new Service("SecurityGroup"); public static final Service NetworkACL = new Service("NetworkACL", Capability.SupportedProtocols); - public static final Service Connectivity = new Service("Connectivity", Capability.DistributedRouter); + public static final Service Connectivity = new Service("Connectivity", Capability.DistributedRouter, Capability.RegionLevelVpc, Capability.StretchedL2Subnet); private final String name; private final Capability[] caps; @@ -187,6 +188,8 @@ public static class Capability { public static final Capability LbSchemes = new Capability("LbSchemes"); public static final Capability DhcpAccrossMultipleSubnets = new Capability("DhcpAccrossMultipleSubnets"); public static final Capability DistributedRouter = new Capability("DistributedRouter"); + public static final Capability StretchedL2Subnet = new Capability("StretchedL2Subnet"); + public static final Capability RegionLevelVpc = new Capability("RegionLevelVpc"); private final String name; @@ -325,8 +328,11 @@ public void setIp6Address(String ip6Address) { boolean getSpecifyIpRanges(); + @Deprecated boolean getDisplayNetwork(); + boolean isDisplay(); + String getGuruName(); /** @@ -337,4 +343,6 @@ public void setIp6Address(String ip6Address) { Long getNetworkACLId(); void setNetworkACLId(Long networkACLId); + + boolean isStrechedL2Network(); } diff --git a/api/src/com/cloud/network/NetworkModel.java b/api/src/com/cloud/network/NetworkModel.java index f6555db565..574160d2c6 100644 --- a/api/src/com/cloud/network/NetworkModel.java +++ b/api/src/com/cloud/network/NetworkModel.java @@ -90,6 +90,8 @@ public interface NetworkModel { boolean areServicesSupportedByNetworkOffering(long networkOfferingId, Service... services); + Network getNetworkWithSGWithFreeIPs(Long zoneId); + Network getNetworkWithSecurityGroupEnabled(Long zoneId); String getIpOfNetworkElementInVirtualNetwork(long accountId, long dataCenterId); @@ -273,4 +275,4 @@ public interface NetworkModel { boolean isNetworkReadyForGc(long networkId); boolean getNetworkEgressDefaultPolicy(Long networkId); -} \ No newline at end of file +} diff --git a/api/src/com/cloud/network/NetworkProfile.java b/api/src/com/cloud/network/NetworkProfile.java index 3f576945a5..1b806d56de 100644 --- a/api/src/com/cloud/network/NetworkProfile.java +++ b/api/src/com/cloud/network/NetworkProfile.java @@ -18,8 +18,6 @@ import java.net.URI; -import org.apache.cloudstack.acl.IAMEntityType; - import com.cloud.network.Networks.BroadcastDomainType; import com.cloud.network.Networks.Mode; import com.cloud.network.Networks.TrafficType; @@ -57,6 +55,7 @@ public class NetworkProfile implements Network { private final boolean displayNetwork; private Long networkAclId; private final String guruName; + private boolean strechedL2Subnet; public NetworkProfile(Network network) { id = network.getId(); @@ -89,6 +88,7 @@ public NetworkProfile(Network network) { displayNetwork = network.getDisplayNetwork(); networkAclId = network.getNetworkACLId(); guruName = network.getGuruName(); + strechedL2Subnet = network.isStrechedL2Network(); } public String getDns1() { @@ -248,6 +248,11 @@ public boolean getDisplayNetwork() { return displayNetwork; } + @Override + public boolean isDisplay(){ + return displayNetwork; + } + @Override public Long getVpcId() { return vpcId; @@ -279,7 +284,13 @@ public String getIp6Cidr() { } @Override - public IAMEntityType getEntityType() { - return IAMEntityType.Network; + public Class getEntityType() { + return Network.class; } + + @Override + public boolean isStrechedL2Network() { + return false; + } + } diff --git a/api/src/com/cloud/network/RemoteAccessVpn.java b/api/src/com/cloud/network/RemoteAccessVpn.java index 4d7e4d49b1..25b4fbbcde 100644 --- a/api/src/com/cloud/network/RemoteAccessVpn.java +++ b/api/src/com/cloud/network/RemoteAccessVpn.java @@ -17,10 +17,11 @@ package com.cloud.network; import org.apache.cloudstack.acl.ControlledEntity; +import org.apache.cloudstack.api.Displayable; import org.apache.cloudstack.api.Identity; import org.apache.cloudstack.api.InternalIdentity; -public interface RemoteAccessVpn extends ControlledEntity, InternalIdentity, Identity { +public interface RemoteAccessVpn extends ControlledEntity, InternalIdentity, Identity, Displayable { enum State { Added, Running, Removed } @@ -39,5 +40,6 @@ enum State { State getState(); + @Override boolean isDisplay(); } diff --git a/api/src/com/cloud/network/Site2SiteVpnConnection.java b/api/src/com/cloud/network/Site2SiteVpnConnection.java index 81e8180119..cfc439abcd 100644 --- a/api/src/com/cloud/network/Site2SiteVpnConnection.java +++ b/api/src/com/cloud/network/Site2SiteVpnConnection.java @@ -19,9 +19,10 @@ import java.util.Date; import org.apache.cloudstack.acl.ControlledEntity; +import org.apache.cloudstack.api.Displayable; import org.apache.cloudstack.api.InternalIdentity; -public interface Site2SiteVpnConnection extends ControlledEntity, InternalIdentity { +public interface Site2SiteVpnConnection extends ControlledEntity, InternalIdentity, Displayable { enum State { Pending, Connected, Disconnected, Error, } @@ -43,5 +44,6 @@ enum State { public boolean isPassive(); + @Override boolean isDisplay(); } diff --git a/api/src/com/cloud/network/Site2SiteVpnGateway.java b/api/src/com/cloud/network/Site2SiteVpnGateway.java index bae12597f2..57037d6b64 100644 --- a/api/src/com/cloud/network/Site2SiteVpnGateway.java +++ b/api/src/com/cloud/network/Site2SiteVpnGateway.java @@ -19,16 +19,18 @@ import java.util.Date; import org.apache.cloudstack.acl.ControlledEntity; +import org.apache.cloudstack.api.Displayable; import org.apache.cloudstack.api.Identity; import org.apache.cloudstack.api.InternalIdentity; -public interface Site2SiteVpnGateway extends ControlledEntity, Identity, InternalIdentity { +public interface Site2SiteVpnGateway extends ControlledEntity, Identity, InternalIdentity, Displayable { public long getAddrId(); public long getVpcId(); public Date getRemoved(); + @Override boolean isDisplay(); } diff --git a/api/src/com/cloud/network/as/AutoScaleVmGroup.java b/api/src/com/cloud/network/as/AutoScaleVmGroup.java index 14c761593b..cf2c15c421 100644 --- a/api/src/com/cloud/network/as/AutoScaleVmGroup.java +++ b/api/src/com/cloud/network/as/AutoScaleVmGroup.java @@ -20,9 +20,10 @@ import java.util.Date; import org.apache.cloudstack.acl.ControlledEntity; +import org.apache.cloudstack.api.Displayable; import org.apache.cloudstack.api.InternalIdentity; -public interface AutoScaleVmGroup extends ControlledEntity, InternalIdentity { +public interface AutoScaleVmGroup extends ControlledEntity, InternalIdentity, Displayable { String State_New = "new"; String State_Revoke = "revoke"; @@ -53,6 +54,7 @@ public interface AutoScaleVmGroup extends ControlledEntity, InternalIdentity { String getUuid(); + @Override boolean isDisplay(); } diff --git a/api/src/com/cloud/network/as/AutoScaleVmProfile.java b/api/src/com/cloud/network/as/AutoScaleVmProfile.java index 6e0b5ffb91..495446a6e8 100644 --- a/api/src/com/cloud/network/as/AutoScaleVmProfile.java +++ b/api/src/com/cloud/network/as/AutoScaleVmProfile.java @@ -20,6 +20,7 @@ import java.util.List; import org.apache.cloudstack.acl.ControlledEntity; +import org.apache.cloudstack.api.Displayable; import org.apache.cloudstack.api.InternalIdentity; import com.cloud.utils.Pair; @@ -27,7 +28,7 @@ /** * AutoScaleVmProfile */ -public interface AutoScaleVmProfile extends ControlledEntity, InternalIdentity { +public interface AutoScaleVmProfile extends ControlledEntity, InternalIdentity, Displayable { @Override public long getId(); @@ -48,6 +49,7 @@ public interface AutoScaleVmProfile extends ControlledEntity, InternalIdentity { public long getAutoScaleUserId(); + @Override boolean isDisplay(); } diff --git a/api/src/com/cloud/network/firewall/FirewallService.java b/api/src/com/cloud/network/firewall/FirewallService.java index 5ab789121a..41b170da5b 100644 --- a/api/src/com/cloud/network/firewall/FirewallService.java +++ b/api/src/com/cloud/network/firewall/FirewallService.java @@ -40,7 +40,8 @@ public interface FirewallService { * the id of the rule to revoke. * @return */ - boolean revokeFirewallRule(long ruleId, boolean apply); + boolean revokeIngressFirewallRule(long ruleId, boolean apply); + boolean revokeEgressFirewallRule(long ruleId, boolean apply); boolean applyEgressFirewallRules(FirewallRule rule, Account caller) throws ResourceUnavailableException; @@ -50,6 +51,9 @@ public interface FirewallService { boolean revokeRelatedFirewallRule(long ruleId, boolean apply); - FirewallRule updateFirewallRule(long ruleId, String customId, Boolean forDisplay); + FirewallRule updateIngressFirewallRule(long ruleId, String customId, Boolean forDisplay); + FirewallRule updateEgressFirewallRule(long ruleId, String customId, Boolean forDisplay); + boolean applyIngressFwRules(long ipId, Account caller) throws ResourceUnavailableException; + boolean revokeIngressFwRule(long ruleId, boolean apply); } diff --git a/api/src/com/cloud/network/lb/LoadBalancingRulesService.java b/api/src/com/cloud/network/lb/LoadBalancingRulesService.java index 4c87d342db..50b39d2f33 100644 --- a/api/src/com/cloud/network/lb/LoadBalancingRulesService.java +++ b/api/src/com/cloud/network/lb/LoadBalancingRulesService.java @@ -92,13 +92,13 @@ LoadBalancer createPublicLoadBalancerRule(String xId, String name, String descri boolean deleteLBHealthCheckPolicy(long healthCheckPolicyId, boolean apply); /** - * Assign a virtual machine, or list of virtual machines, to a load balancer. + * Assign a virtual machine or list of virtual machines, or Map of to a load balancer. */ - boolean assignToLoadBalancer(long lbRuleId, List vmIds); + boolean assignToLoadBalancer(long lbRuleId, List vmIds, Map> vmIdIpMap); boolean assignSSLCertToLoadBalancerRule(Long lbRuleId, String certName, String publicCert, String privateKey); - boolean removeFromLoadBalancer(long lbRuleId, List vmIds); + boolean removeFromLoadBalancer(long lbRuleId, List vmIds, Map> vmIdIpMap); boolean applyLoadBalancerConfig(long lbRuleId) throws ResourceUnavailableException; @@ -151,4 +151,16 @@ LoadBalancer createPublicLoadBalancerRule(String xId, String name, String descri public void updateLBHealthChecks(Scheme scheme) throws ResourceUnavailableException; Map getLbInstances(long lbId); + + boolean isLbRuleMappedToVmGuestIp(String vmSecondaryIp); + + List listLbVmIpAddress(long id, long vmId); + + StickinessPolicy updateLBStickinessPolicy(long id, String customId, Boolean forDisplay); + + HealthCheckPolicy updateLBHealthCheckPolicy(long id, String customId, Boolean forDisplay); + + LoadBalancer findLbByStickinessId(long stickinessPolicyId); + + Long findLBIdByHealtCheckPolicyId(long lbHealthCheckPolicy); } diff --git a/api/src/com/cloud/network/rules/FirewallRule.java b/api/src/com/cloud/network/rules/FirewallRule.java index b02257b7c8..4346e2f665 100644 --- a/api/src/com/cloud/network/rules/FirewallRule.java +++ b/api/src/com/cloud/network/rules/FirewallRule.java @@ -19,10 +19,11 @@ import java.util.List; import org.apache.cloudstack.acl.ControlledEntity; +import org.apache.cloudstack.api.Displayable; import org.apache.cloudstack.api.Identity; import org.apache.cloudstack.api.InternalIdentity; -public interface FirewallRule extends ControlledEntity, Identity, InternalIdentity { +public interface FirewallRule extends ControlledEntity, Identity, InternalIdentity, Displayable { enum Purpose { Firewall, PortForwarding, LoadBalancing, Vpn, StaticNat, NetworkACL, } @@ -87,6 +88,7 @@ enum TrafficType { */ TrafficType getTrafficType(); + @Override boolean isDisplay(); } diff --git a/api/src/com/cloud/network/rules/HealthCheckPolicy.java b/api/src/com/cloud/network/rules/HealthCheckPolicy.java index 6157bd4020..f7562e8e89 100644 --- a/api/src/com/cloud/network/rules/HealthCheckPolicy.java +++ b/api/src/com/cloud/network/rules/HealthCheckPolicy.java @@ -16,12 +16,13 @@ // under the License. package com.cloud.network.rules; +import org.apache.cloudstack.api.Displayable; import org.apache.cloudstack.api.Identity; import org.apache.cloudstack.api.InternalIdentity; /** */ -public interface HealthCheckPolicy extends InternalIdentity, Identity { +public interface HealthCheckPolicy extends InternalIdentity, Identity, Displayable { public long getLoadBalancerId(); @@ -39,4 +40,7 @@ public interface HealthCheckPolicy extends InternalIdentity, Identity { public boolean isRevoke(); + @Override + boolean isDisplay(); + } diff --git a/api/src/com/cloud/network/rules/StickinessPolicy.java b/api/src/com/cloud/network/rules/StickinessPolicy.java index da48754666..7f956f98d4 100644 --- a/api/src/com/cloud/network/rules/StickinessPolicy.java +++ b/api/src/com/cloud/network/rules/StickinessPolicy.java @@ -18,6 +18,7 @@ import java.util.List; +import org.apache.cloudstack.api.Displayable; import org.apache.cloudstack.api.Identity; import org.apache.cloudstack.api.InternalIdentity; @@ -25,7 +26,7 @@ /** */ -public interface StickinessPolicy extends InternalIdentity, Identity { +public interface StickinessPolicy extends InternalIdentity, Identity, Displayable { public long getLoadBalancerId(); @@ -39,4 +40,7 @@ public interface StickinessPolicy extends InternalIdentity, Identity { public List> getParams(); /* get params in Map format */ + @Override + boolean isDisplay(); + } diff --git a/api/src/com/cloud/network/vpc/NetworkACL.java b/api/src/com/cloud/network/vpc/NetworkACL.java index 3ebee146ed..b0c87cc112 100644 --- a/api/src/com/cloud/network/vpc/NetworkACL.java +++ b/api/src/com/cloud/network/vpc/NetworkACL.java @@ -17,9 +17,11 @@ package com.cloud.network.vpc; +import org.apache.cloudstack.api.Displayable; +import org.apache.cloudstack.api.Identity; import org.apache.cloudstack.api.InternalIdentity; -public interface NetworkACL extends InternalIdentity { +public interface NetworkACL extends InternalIdentity, Identity, Displayable { public static final long DEFAULT_DENY = 1; public static final long DEFAULT_ALLOW = 2; @@ -34,5 +36,6 @@ public interface NetworkACL extends InternalIdentity { String getName(); + @Override boolean isDisplay(); } diff --git a/api/src/com/cloud/network/vpc/NetworkACLItem.java b/api/src/com/cloud/network/vpc/NetworkACLItem.java index faa4d273c9..75153fd7c5 100644 --- a/api/src/com/cloud/network/vpc/NetworkACLItem.java +++ b/api/src/com/cloud/network/vpc/NetworkACLItem.java @@ -18,9 +18,11 @@ import java.util.List; +import org.apache.cloudstack.api.Displayable; +import org.apache.cloudstack.api.Identity; import org.apache.cloudstack.api.InternalIdentity; -public interface NetworkACLItem extends InternalIdentity { +public interface NetworkACLItem extends InternalIdentity, Identity, Displayable { String getUuid(); @@ -73,6 +75,7 @@ enum Action { */ TrafficType getTrafficType(); + @Override boolean isDisplay(); } diff --git a/api/src/com/cloud/network/vpc/StaticRouteProfile.java b/api/src/com/cloud/network/vpc/StaticRouteProfile.java index b5bd5f7af5..737541f0a4 100644 --- a/api/src/com/cloud/network/vpc/StaticRouteProfile.java +++ b/api/src/com/cloud/network/vpc/StaticRouteProfile.java @@ -16,7 +16,6 @@ // under the License. package com.cloud.network.vpc; -import org.apache.cloudstack.acl.IAMEntityType; public class StaticRouteProfile implements StaticRoute { private long id; @@ -104,7 +103,7 @@ public String getNetmask() { } @Override - public IAMEntityType getEntityType() { - return IAMEntityType.StaticRoute; + public Class getEntityType() { + return StaticRoute.class; } } diff --git a/api/src/com/cloud/network/vpc/Vpc.java b/api/src/com/cloud/network/vpc/Vpc.java index 4bc8c98872..23388787d2 100644 --- a/api/src/com/cloud/network/vpc/Vpc.java +++ b/api/src/com/cloud/network/vpc/Vpc.java @@ -79,4 +79,10 @@ public enum State { * @return true if VPC is configured to use distributed router to provides one-hop forwarding and hypervisor based ACL */ boolean usesDistributedRouter(); + + /** + * + * @return true if VPC spans multiple zones in the region + */ + boolean isRegionLevelVpc(); } diff --git a/api/src/com/cloud/network/vpc/VpcOffering.java b/api/src/com/cloud/network/vpc/VpcOffering.java index a0a1b1528c..660c79dc1e 100644 --- a/api/src/com/cloud/network/vpc/VpcOffering.java +++ b/api/src/com/cloud/network/vpc/VpcOffering.java @@ -56,8 +56,12 @@ public enum State { Long getServiceOfferingId(); /** - * * @return true if the offering provides a distributed router capable of one-hop forwarding */ boolean supportsDistributedRouter(); + + /** + * @return true if VPC created with the offering can span multiple zones in the region + */ + boolean offersRegionLevelVPC(); } diff --git a/api/src/com/cloud/network/vpc/VpcProvisioningService.java b/api/src/com/cloud/network/vpc/VpcProvisioningService.java index e545275217..82a7baae95 100644 --- a/api/src/com/cloud/network/vpc/VpcProvisioningService.java +++ b/api/src/com/cloud/network/vpc/VpcProvisioningService.java @@ -16,6 +16,7 @@ // under the License. package com.cloud.network.vpc; + import java.util.List; import java.util.Map; diff --git a/api/src/com/cloud/network/vpn/RemoteAccessVpnService.java b/api/src/com/cloud/network/vpn/RemoteAccessVpnService.java index acf007bbb3..decf8c4373 100644 --- a/api/src/com/cloud/network/vpn/RemoteAccessVpnService.java +++ b/api/src/com/cloud/network/vpn/RemoteAccessVpnService.java @@ -33,7 +33,7 @@ public interface RemoteAccessVpnService { RemoteAccessVpn createRemoteAccessVpn(long vpnServerAddressId, String ipRange, boolean openFirewall, Boolean forDisplay) throws NetworkRuleConflictException; - void destroyRemoteAccessVpnForIp(long vpnServerAddressId, Account caller) throws ResourceUnavailableException; + boolean destroyRemoteAccessVpnForIp(long ipId, Account caller) throws ResourceUnavailableException; RemoteAccessVpn startRemoteAccessVpn(long vpnServerAddressId, boolean openFirewall) throws ResourceUnavailableException; diff --git a/api/src/com/cloud/offering/NetworkOffering.java b/api/src/com/cloud/offering/NetworkOffering.java index b4f3863293..f1ef69c2f6 100644 --- a/api/src/com/cloud/offering/NetworkOffering.java +++ b/api/src/com/cloud/offering/NetworkOffering.java @@ -129,4 +129,6 @@ public enum Detail { Integer getConcurrentConnections(); boolean isKeepAliveEnabled(); + + boolean getSupportsStrechedL2(); } diff --git a/api/src/com/cloud/server/ResourceMetaDataService.java b/api/src/com/cloud/server/ResourceMetaDataService.java index 56fe1045ab..113dc0703b 100644 --- a/api/src/com/cloud/server/ResourceMetaDataService.java +++ b/api/src/com/cloud/server/ResourceMetaDataService.java @@ -46,6 +46,16 @@ public interface ResourceMetaDataService { ResourceDetail getDetail(long resourceId, ResourceObjectType resourceType, String key); + /** + * List by key, value pair + * @param resourceType + * @param key + * @param value + * @param forDisplay + * @return + */ + List getDetails(ResourceObjectType resourceType, String key, String value, Boolean forDisplay); + Map getDetailsMap(long resourceId, ResourceObjectType resourceType, Boolean forDisplay); List getDetailsList(long resourceId, ResourceObjectType resourceType, Boolean forDisplay); diff --git a/api/src/com/cloud/server/ResourceTag.java b/api/src/com/cloud/server/ResourceTag.java index 275510e1a1..bf18d65e8c 100644 --- a/api/src/com/cloud/server/ResourceTag.java +++ b/api/src/com/cloud/server/ResourceTag.java @@ -53,7 +53,11 @@ public enum ResourceObjectType { User(true, true), DiskOffering(false, true), AutoScaleVmProfile(false, true), - AutoScaleVmGroup(false, true); + AutoScaleVmGroup(false, true), + LBStickinessPolicy(false, true), + LBHealthCheckPolicy(false, true), + SnapshotPolicy(false, true); + ResourceObjectType(boolean resourceTagsSupport, boolean resourceMetadataSupport) { this.resourceTagsSupport = resourceTagsSupport; diff --git a/api/src/com/cloud/storage/GuestOS.java b/api/src/com/cloud/storage/GuestOS.java index 767a60ecf9..371260bec6 100644 --- a/api/src/com/cloud/storage/GuestOS.java +++ b/api/src/com/cloud/storage/GuestOS.java @@ -32,4 +32,6 @@ public interface GuestOS extends InternalIdentity, Identity { Date getCreated(); Date getRemoved(); + + boolean getIsUserDefined(); } diff --git a/api/src/com/cloud/storage/GuestOSHypervisor.java b/api/src/com/cloud/storage/GuestOSHypervisor.java index 1cfc3a1728..f579ce343a 100644 --- a/api/src/com/cloud/storage/GuestOSHypervisor.java +++ b/api/src/com/cloud/storage/GuestOSHypervisor.java @@ -35,4 +35,6 @@ public interface GuestOSHypervisor extends InternalIdentity { Date getRemoved(); Date getCreated(); + + boolean getIsUserDefined(); } diff --git a/api/src/com/cloud/storage/StoragePool.java b/api/src/com/cloud/storage/StoragePool.java index 6ede960c1f..8e03c3348f 100644 --- a/api/src/com/cloud/storage/StoragePool.java +++ b/api/src/com/cloud/storage/StoragePool.java @@ -21,6 +21,7 @@ import org.apache.cloudstack.api.Identity; import org.apache.cloudstack.api.InternalIdentity; +import com.cloud.hypervisor.Hypervisor; import com.cloud.storage.Storage.StoragePoolType; public interface StoragePool extends Identity, InternalIdentity { @@ -98,10 +99,9 @@ public interface StoragePool extends Identity, InternalIdentity { Long getPodId(); - /** - * @return - */ String getStorageProviderName(); boolean isInMaintenance(); + + Hypervisor.HypervisorType getHypervisor(); } diff --git a/api/src/com/cloud/storage/Volume.java b/api/src/com/cloud/storage/Volume.java index 304dbcfe34..a78049b5c9 100755 --- a/api/src/com/cloud/storage/Volume.java +++ b/api/src/com/cloud/storage/Volume.java @@ -19,6 +19,7 @@ import java.util.Date; import org.apache.cloudstack.acl.ControlledEntity; +import org.apache.cloudstack.api.Displayable; import org.apache.cloudstack.api.Identity; import org.apache.cloudstack.api.InternalIdentity; @@ -26,7 +27,7 @@ import com.cloud.utils.fsm.StateMachine2; import com.cloud.utils.fsm.StateObject; -public interface Volume extends ControlledEntity, Identity, InternalIdentity, BasedOn, StateObject { +public interface Volume extends ControlledEntity, Identity, InternalIdentity, BasedOn, StateObject, Displayable { enum Type { UNKNOWN, ROOT, SWAP, DATADISK, ISO }; @@ -191,5 +192,8 @@ enum Event { Integer getHypervisorSnapshotReserve(); + @Deprecated boolean isDisplayVolume(); + + boolean isDisplay(); } diff --git a/api/src/com/cloud/storage/VolumeApiService.java b/api/src/com/cloud/storage/VolumeApiService.java index beaa29096e..5487a4bf9b 100644 --- a/api/src/com/cloud/storage/VolumeApiService.java +++ b/api/src/com/cloud/storage/VolumeApiService.java @@ -96,4 +96,6 @@ public interface VolumeApiService { String extractVolume(ExtractVolumeCmd cmd); boolean isDisplayResourceEnabled(Long id); + + void updateDisplay(Volume volume, Boolean displayVolume); } diff --git a/api/src/com/cloud/storage/snapshot/SnapshotApiService.java b/api/src/com/cloud/storage/snapshot/SnapshotApiService.java index 91c08307bb..0300980edb 100644 --- a/api/src/com/cloud/storage/snapshot/SnapshotApiService.java +++ b/api/src/com/cloud/storage/snapshot/SnapshotApiService.java @@ -29,6 +29,7 @@ import com.cloud.storage.Volume; import com.cloud.user.Account; import com.cloud.utils.Pair; +import org.apache.cloudstack.api.command.user.snapshot.UpdateSnapshotPolicyCmd; public interface SnapshotApiService { @@ -106,4 +107,6 @@ public interface SnapshotApiService { Long getHostIdForSnapshotOperation(Volume vol); boolean revertSnapshot(Long snapshotId); + + SnapshotPolicy updateSnapshotPolicy(UpdateSnapshotPolicyCmd updateSnapshotPolicyCmd); } diff --git a/api/src/com/cloud/storage/snapshot/SnapshotPolicy.java b/api/src/com/cloud/storage/snapshot/SnapshotPolicy.java index 37ce6fd153..22d5dfb9c1 100644 --- a/api/src/com/cloud/storage/snapshot/SnapshotPolicy.java +++ b/api/src/com/cloud/storage/snapshot/SnapshotPolicy.java @@ -16,10 +16,11 @@ // under the License. package com.cloud.storage.snapshot; +import org.apache.cloudstack.api.Displayable; import org.apache.cloudstack.api.Identity; import org.apache.cloudstack.api.InternalIdentity; -public interface SnapshotPolicy extends Identity, InternalIdentity { +public interface SnapshotPolicy extends Identity, InternalIdentity, Displayable { long getVolumeId(); diff --git a/api/src/com/cloud/user/AccountService.java b/api/src/com/cloud/user/AccountService.java index 7e37b386b9..eac8a76849 100755 --- a/api/src/com/cloud/user/AccountService.java +++ b/api/src/com/cloud/user/AccountService.java @@ -24,7 +24,6 @@ import org.apache.cloudstack.api.command.admin.user.RegisterCmd; import com.cloud.domain.Domain; -import com.cloud.domain.PartOf; import com.cloud.exception.PermissionDeniedException; public interface AccountService { @@ -74,7 +73,7 @@ UserAccount createUserAccount(String userName, String password, String firstName User createUser(String userName, String password, String firstName, String lastName, String email, String timeZone, String accountName, Long domainId, String userUUID); - boolean isAdmin(short accountType); + boolean isAdmin(Long accountId); Account finalizeOwner(Account caller, String accountName, Long domainId, Long projectId); @@ -111,8 +110,13 @@ UserAccount createUserAccount(String userName, String password, String firstName void checkAccess(Account account, AccessType accessType, boolean sameOwner, String apiName, ControlledEntity... entities) throws PermissionDeniedException; - //TO be implemented, to check accessibility for an entity owned by domain - void checkAccess(Account account, AccessType accessType, boolean sameOwner, PartOf... entities) throws PermissionDeniedException; - Long finalyzeAccountId(String accountName, Long domainId, Long projectId, boolean enabledOnly); + + /** + * returns the user account object for a given user id + * @param userId user id + * @return useraccount object if it exists else null + */ + UserAccount getUserAccountById(Long userId); + } diff --git a/api/src/com/cloud/vm/UserVmService.java b/api/src/com/cloud/vm/UserVmService.java index af4e1d3699..c0c0335675 100755 --- a/api/src/com/cloud/vm/UserVmService.java +++ b/api/src/com/cloud/vm/UserVmService.java @@ -21,7 +21,6 @@ import org.apache.cloudstack.api.BaseCmd.HTTPMethod; import org.apache.cloudstack.api.command.admin.vm.AssignVMCmd; -import org.apache.cloudstack.api.command.admin.vm.ExpungeVMCmd; import org.apache.cloudstack.api.command.admin.vm.RecoverVMCmd; import org.apache.cloudstack.api.command.user.vm.AddNicToVMCmd; import org.apache.cloudstack.api.command.user.vm.DeployVMCmd; @@ -457,8 +456,6 @@ UserVm moveVMToUser(AssignVMCmd moveUserVMCmd) throws ResourceAllocationExceptio UserVm upgradeVirtualMachine(ScaleVMCmd cmd) throws ResourceUnavailableException, ConcurrentOperationException, ManagementServerException, VirtualMachineMigrationException; - UserVm expungeVm(ExpungeVMCmd cmd) throws ResourceUnavailableException, ConcurrentOperationException; - UserVm expungeVm(long vmId) throws ResourceUnavailableException, ConcurrentOperationException; /** diff --git a/api/src/com/cloud/vm/VirtualMachine.java b/api/src/com/cloud/vm/VirtualMachine.java index b085d4a7c4..34387ebea8 100755 --- a/api/src/com/cloud/vm/VirtualMachine.java +++ b/api/src/com/cloud/vm/VirtualMachine.java @@ -20,6 +20,7 @@ import java.util.Map; import org.apache.cloudstack.acl.ControlledEntity; +import org.apache.cloudstack.api.Displayable; import org.apache.cloudstack.api.Identity; import org.apache.cloudstack.api.InternalIdentity; @@ -31,7 +32,7 @@ * VirtualMachine describes the properties held by a virtual machine * */ -public interface VirtualMachine extends RunningOn, ControlledEntity, Identity, InternalIdentity, StateObject { +public interface VirtualMachine extends RunningOn, ControlledEntity, Identity, InternalIdentity, Displayable, StateObject { public enum PowerState { PowerUnknown, @@ -102,6 +103,7 @@ public static StateMachine2 getStat s_fsm.addTransition(State.Running, VirtualMachine.Event.StopRequested, State.Stopping); s_fsm.addTransition(State.Running, VirtualMachine.Event.AgentReportShutdowned, State.Stopped); s_fsm.addTransition(State.Running, VirtualMachine.Event.AgentReportMigrated, State.Running); + s_fsm.addTransition(State.Running, VirtualMachine.Event.OperationSucceeded, State.Running); s_fsm.addTransition(State.Migrating, VirtualMachine.Event.MigrationRequested, State.Migrating); s_fsm.addTransition(State.Migrating, VirtualMachine.Event.OperationSucceeded, State.Running); s_fsm.addTransition(State.Migrating, VirtualMachine.Event.OperationFailed, State.Running); @@ -320,4 +322,7 @@ public boolean isUsedBySystem() { long getUpdated(); + @Override + boolean isDisplay(); + } diff --git a/api/src/com/cloud/vm/VirtualMachineName.java b/api/src/com/cloud/vm/VirtualMachineName.java index 4bbcb64ebc..e6c2fbaab1 100755 --- a/api/src/com/cloud/vm/VirtualMachineName.java +++ b/api/src/com/cloud/vm/VirtualMachineName.java @@ -18,8 +18,6 @@ import java.util.Formatter; -import com.cloud.dc.Vlan; - /** * VM Name. */ @@ -52,26 +50,16 @@ public static boolean isValidVmName(String vmName) { public static boolean isValidVmName(String vmName, String instance) { String[] tokens = vmName.split(SEPARATOR); - /*Some vms doesn't have vlan/vnet id*/ - if (tokens.length != 5 && tokens.length != 4) { - return false; - } - if (!tokens[0].equals("i")) { + if (tokens.length <= 1) { return false; } - try { - Long.parseLong(tokens[1]); - Long.parseLong(tokens[2]); - if (tokens.length == 5 && !Vlan.UNTAGGED.equalsIgnoreCase(tokens[4])) { - Long.parseLong(tokens[4], 16); - } - } catch (NumberFormatException e) { + if (!tokens[0].equals("i")) { return false; } - return instance == null || instance.equals(tokens[3]); + return true; } public static String getVmName(long vmId, long userId, String instance) { diff --git a/api/src/com/cloud/vm/VirtualMachineProfile.java b/api/src/com/cloud/vm/VirtualMachineProfile.java index c098e85db5..29f3164632 100644 --- a/api/src/com/cloud/vm/VirtualMachineProfile.java +++ b/api/src/com/cloud/vm/VirtualMachineProfile.java @@ -53,6 +53,23 @@ public Param(String name) { public String getName() { return name; } + + @Override + public int hashCode() { + return this.getName() != null ? this.getName().hashCode() : 0; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Param other = (Param) obj; + return (other.getName().equals(this.getName())); + } } String getHostName(); diff --git a/api/src/org/apache/cloudstack/acl/ControlledEntity.java b/api/src/org/apache/cloudstack/acl/ControlledEntity.java index 2572705daa..b8a244f3bd 100644 --- a/api/src/org/apache/cloudstack/acl/ControlledEntity.java +++ b/api/src/org/apache/cloudstack/acl/ControlledEntity.java @@ -29,5 +29,5 @@ public enum ACLType { Account, Domain } - IAMEntityType getEntityType(); + Class getEntityType(); } diff --git a/api/src/org/apache/cloudstack/acl/IAMEntityType.java b/api/src/org/apache/cloudstack/acl/IAMEntityType.java deleted file mode 100644 index c1703ea5c3..0000000000 --- a/api/src/org/apache/cloudstack/acl/IAMEntityType.java +++ /dev/null @@ -1,61 +0,0 @@ -// 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.acl; - -public enum IAMEntityType { - // currently supported entity, to be added one by one after we support acl on the entity - VirtualMachine, - Volume, - ResourceTag, - Account, - AffinityGroup, - AutoScalePolicy, - AutoScaleVmGroup, - AutoScaleVmProfile, - Condition, - Vpc, - VpcGateway, - PrivateGateway, - VpnUser, - VMSnapshot, - VirtualMachineTemplate, - UserIpv6Address, - StaticRoute, - SSHKeyPair, - Snapshot, - Site2SiteVpnGateway, - Site2SiteVpnConnection, - Site2SiteCustomerGateway, - SecurityGroup, - RemoteAccessVpn, - PublicIpAddress, - ProjectInvitation, - NicSecondaryIp, - NicIpAlias, - Network, - IpAddress, - InstanceGroup, - GlobalLoadBalancerRule, - FirewallRule, - PortForwardingRule, - Event, - AsyncJob, - IAMPolicy, - IAMGroup, - MonitorService, - SSLCert -} diff --git a/api/src/org/apache/cloudstack/acl/QuerySelector.java b/api/src/org/apache/cloudstack/acl/QuerySelector.java index b89aa4e9ef..229ce9866f 100644 --- a/api/src/org/apache/cloudstack/acl/QuerySelector.java +++ b/api/src/org/apache/cloudstack/acl/QuerySelector.java @@ -18,6 +18,8 @@ import java.util.List; +import org.apache.cloudstack.acl.SecurityChecker.AccessType; + import com.cloud.user.Account; import com.cloud.utils.component.Adapter; @@ -33,7 +35,7 @@ public interface QuerySelector extends Adapter { * @param action action * @return list of domain Ids granted to the caller account. */ - List getAuthorizedDomains(Account caller, String action); + List getAuthorizedDomains(Account caller, String action, AccessType accessType); /** * List granted accounts for the caller, given a specific action. @@ -42,7 +44,7 @@ public interface QuerySelector extends Adapter { * @param action action. * @return list of domain Ids granted to the caller account. */ - List getAuthorizedAccounts(Account caller, String action); + List getAuthorizedAccounts(Account caller, String action, AccessType accessType); /** @@ -52,7 +54,7 @@ public interface QuerySelector extends Adapter { * @param action action. * @return list of domain Ids granted to the caller account. */ - List getAuthorizedResources(Account caller, String action); + List getAuthorizedResources(Account caller, String action, AccessType accessType); /** * Check if this account is associated with a policy with scope of ALL @@ -60,7 +62,7 @@ public interface QuerySelector extends Adapter { * @param action action. * @return true if this account is attached with a policy for the given action of ALL scope. */ - boolean isGrantedAll(Account caller, String action); + boolean isGrantedAll(Account caller, String action, AccessType accessType); /** * List of ACL group the given account belongs to diff --git a/api/src/org/apache/cloudstack/acl/SecurityChecker.java b/api/src/org/apache/cloudstack/acl/SecurityChecker.java index 614f604aec..4170871754 100644 --- a/api/src/org/apache/cloudstack/acl/SecurityChecker.java +++ b/api/src/org/apache/cloudstack/acl/SecurityChecker.java @@ -33,7 +33,8 @@ public interface SecurityChecker extends Adapter { public enum AccessType { ModifyProject, OperateEntry, - UseEntry + UseEntry, + ListEntry } /** @@ -99,6 +100,26 @@ boolean checkAccess(Account caller, ControlledEntity entity, AccessType accessTy */ boolean checkAccess(Account caller, ControlledEntity entity, AccessType accessType, String action) throws PermissionDeniedException; + /** + * Checks if the account can access multiple objects. + * + * @param caller + * account to check against. + * @param entities + * objects that the account is trying to access. + * @param accessType + * TODO + * @param action + * name of the API + * @return true if access allowed. false if this adapter cannot provide + * permission. + * @throws PermissionDeniedException + * if this adapter is suppose to authenticate ownership and the + * check failed. + */ + boolean checkAccess(Account caller, AccessType accessType, String action, ControlledEntity... entities) + throws PermissionDeniedException; + /** * Checks if the user belongs to an account that can access the object. diff --git a/api/src/org/apache/cloudstack/api/APICommand.java b/api/src/org/apache/cloudstack/api/APICommand.java index 9b4dfafdb6..d451e4b10a 100644 --- a/api/src/org/apache/cloudstack/api/APICommand.java +++ b/api/src/org/apache/cloudstack/api/APICommand.java @@ -22,7 +22,6 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.api.ResponseObject.ResponseView; @@ -49,5 +48,5 @@ RoleType[] authorized() default {}; - IAMEntityType[] entityType() default {}; + Class[] entityType() default {}; } diff --git a/api/src/org/apache/cloudstack/api/ApiConstants.java b/api/src/org/apache/cloudstack/api/ApiConstants.java index 32107edf84..5e9c973c13 100755 --- a/api/src/org/apache/cloudstack/api/ApiConstants.java +++ b/api/src/org/apache/cloudstack/api/ApiConstants.java @@ -26,6 +26,7 @@ public class ApiConstants { public static final String API_KEY = "apikey"; public static final String USER_API_KEY = "userapikey"; public static final String APPLIED = "applied"; + public static final String LIST_LB_VMIPS = "lbvmips"; public static final String AVAILABLE = "available"; public static final String BITS = "bits"; public static final String BOOTABLE = "bootable"; @@ -57,6 +58,7 @@ public class ApiConstants { public static final String CPU_SPEED = "cpuspeed"; public static final String CREATED = "created"; public static final String CTX_ACCOUNT_ID = "ctxaccountid"; + public static final String CTX_DETAILS = "ctxDetails"; public static final String CTX_USER_ID = "ctxuserid"; public static final String CTXSTARTEVENTID = "ctxstarteventid"; public static final String CTX_START_EVENT_ID = "ctxStartEventId"; @@ -262,6 +264,8 @@ public class ApiConstants { public static final String VALUE = "value"; public static final String VIRTUAL_MACHINE_ID = "virtualmachineid"; public static final String VIRTUAL_MACHINE_IDS = "virtualmachineids"; + public static final String VIRTUAL_MACHINE_ID_IP = "vmidipmap"; + public static final String VLAN = "vlan"; public static final String VLAN_RANGE = "vlanrange"; public static final String REMOVE_VLAN = "removevlan"; @@ -287,6 +291,7 @@ public class ApiConstants { public static final String SPECIFY_VLAN = "specifyvlan"; public static final String IS_DEFAULT = "isdefault"; public static final String IS_SYSTEM = "issystem"; + public static final String IS_USER_DEFINED = "isuserdefined"; public static final String AVAILABILITY = "availability"; public static final String NETWORKRATE = "networkrate"; public static final String HOST_TAGS = "hosttags"; @@ -417,6 +422,7 @@ public class ApiConstants { public static final String INSTANCE_NAME = "instancename"; public static final String START_VM = "startvm"; public static final String HA_HOST = "hahost"; + public static final String CUSTOM_DISK_OFF_MIN_SIZE = "customdiskofferingminsize"; public static final String CUSTOM_DISK_OFF_MAX_SIZE = "customdiskofferingmaxsize"; public static final String DEFAULT_ZONE_ID = "defaultzoneid"; public static final String LIVE_MIGRATE = "livemigrate"; @@ -587,9 +593,20 @@ public class ApiConstants { public static final String GPUGROUPNAME = "gpugroupname"; public static final String VGPU = "vgpu"; public static final String VGPUTYPE = "vgputype"; + public static final String VIDEORAM = "videoram"; + public static final String MAXHEADS = "maxheads"; + public static final String MAXRESOLUTIONX = "maxresolutionx"; + public static final String MAXRESOLUTIONY = "maxresolutiony"; + public static final String MAXVGPUPERPGPU = "maxvgpuperpgpu"; public static final String REMAININGCAPACITY = "remainingcapacity"; + public static final String MAXCAPACITY = "maxcapacity"; public static final String DISTRIBUTED_VPC_ROUTER = "distributedvpcrouter"; - + public static final String SUPPORTS_REGION_LEVEL_VPC = "supportsregionLevelvpc"; + public static final String SUPPORTS_STRECHED_L2_SUBNET = "supportsstrechedl2subnet"; + public static final String REGION_LEVEL_VPC = "regionlevelvpc"; + public static final String READ_ONLY = "readonly"; + public static final String STRECHED_L2_SUBNET = "strechedl2subnet"; + public static final String NETWORK_SPANNED_ZONES = "zonesnetworkspans"; public enum HostDetails { all, capacity, events, stats, min; diff --git a/api/src/org/apache/cloudstack/api/BaseAsyncCmd.java b/api/src/org/apache/cloudstack/api/BaseAsyncCmd.java index 0b1396fbf8..6b83d39dc9 100644 --- a/api/src/org/apache/cloudstack/api/BaseAsyncCmd.java +++ b/api/src/org/apache/cloudstack/api/BaseAsyncCmd.java @@ -17,6 +17,8 @@ package org.apache.cloudstack.api; +import org.apache.log4j.Logger; + /** * queryAsyncJobResult API command. */ @@ -27,6 +29,7 @@ public abstract class BaseAsyncCmd extends BaseCmd { public static final String vpcSyncObject = "vpc"; public static final String snapshotHostSyncObject = "snapshothost"; public static final String gslbSyncObject = "globalserverloadbalacner"; + private static final Logger s_logger = Logger.getLogger(BaseAsyncCmd.class.getName()); private Object job; @@ -89,4 +92,5 @@ public Long getSyncObjId() { public Object getJob() { return job; } + } diff --git a/api/src/org/apache/cloudstack/api/BaseCmd.java b/api/src/org/apache/cloudstack/api/BaseCmd.java index f6f21ae716..ac9a20866a 100644 --- a/api/src/org/apache/cloudstack/api/BaseCmd.java +++ b/api/src/org/apache/cloudstack/api/BaseCmd.java @@ -360,7 +360,53 @@ public void validateSpecificParameters(final Map params){ * display flag is used to control the display of the resource only to the end user. It doesnt affect Root Admin. * @return display flag */ - public boolean isDisplayResourceEnabled(){ - return true; + public boolean isDisplay(){ + CallContext context = CallContext.current(); + Map contextMap = context.getContextParameters(); + boolean isDisplay = true; + + // Iterate over all the first class entities in context and check their display property. + for(Map.Entry entry : contextMap.entrySet()){ + try{ + Object key = entry.getKey(); + Class clz = Class.forName((String)key); + if(Displayable.class.isAssignableFrom(clz)){ + final Object objVO = getEntityVO(clz, entry.getValue()); + isDisplay = ((Displayable) objVO).isDisplay(); + } + + // If the flag is false break immediately + if(!isDisplay) + break; + } catch (Exception e){ + s_logger.trace("Caught exception while checking first class entities for display property, continuing on", e); + } + } + + context.setEventDisplayEnabled(isDisplay); + return isDisplay; + } + + private Object getEntityVO(Class entityType, Object entityId){ + + // entityId can be internal db id or UUID so accordingly call findbyId or findByUUID + + if (entityId instanceof Long){ + // Its internal db id - use findById + return _entityMgr.findById(entityType, (Long)entityId); + } else if(entityId instanceof String){ + try{ + // In case its an async job the internal db id would be a string because of json deserialization + Long internalId = Long.valueOf((String) entityId); + return _entityMgr.findById(entityType, internalId); + } catch (NumberFormatException e){ + // It is uuid - use findByUuid` + return _entityMgr.findByUuid(entityType, (String)entityId); + } + } + + return null; + } + } diff --git a/api/src/org/apache/cloudstack/api/BaseListAccountResourcesCmd.java b/api/src/org/apache/cloudstack/api/BaseListAccountResourcesCmd.java index 63d2b7f761..d494f6403f 100644 --- a/api/src/org/apache/cloudstack/api/BaseListAccountResourcesCmd.java +++ b/api/src/org/apache/cloudstack/api/BaseListAccountResourcesCmd.java @@ -16,9 +16,6 @@ // under the License. package org.apache.cloudstack.api; -import org.apache.cloudstack.context.CallContext; - -import com.cloud.user.Account; public abstract class BaseListAccountResourcesCmd extends BaseListDomainResourcesCmd { @@ -30,10 +27,6 @@ public String getAccountName() { } public Boolean getDisplay() { - Account caller = CallContext.current().getCallingAccount(); - if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL) { - return true; - } - return null; + return true; } } diff --git a/api/src/org/apache/cloudstack/api/BaseAsyncVMCmd.java b/api/src/org/apache/cloudstack/api/Displayable.java similarity index 72% rename from api/src/org/apache/cloudstack/api/BaseAsyncVMCmd.java rename to api/src/org/apache/cloudstack/api/Displayable.java index abfc953027..2a83c8dc73 100644 --- a/api/src/org/apache/cloudstack/api/BaseAsyncVMCmd.java +++ b/api/src/org/apache/cloudstack/api/Displayable.java @@ -16,15 +16,6 @@ // under the License. package org.apache.cloudstack.api; -/** - * A generic class for implementing methods common to all async vm commands - */ -public abstract class BaseAsyncVMCmd extends BaseAsyncCmd { - - @Override - public boolean isDisplayResourceEnabled(){ - return _userVmService.isDisplayResourceEnabled(getId()); - } - - public abstract Long getId(); +public interface Displayable { + boolean isDisplay(); } diff --git a/api/src/org/apache/cloudstack/api/command/admin/account/CreateAccountCmd.java b/api/src/org/apache/cloudstack/api/command/admin/account/CreateAccountCmd.java index 0c46d501bd..50d67d993d 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/account/CreateAccountCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/account/CreateAccountCmd.java @@ -21,7 +21,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.ApiErrorCode; @@ -37,7 +36,7 @@ import com.cloud.user.UserAccount; -@APICommand(name = "createAccount", description = "Creates an account", responseObject = AccountResponse.class, entityType = {IAMEntityType.Account}, +@APICommand(name = "createAccount", description = "Creates an account", responseObject = AccountResponse.class, entityType = {Account.class}, requestHasSensitiveInfo = true, responseHasSensitiveInfo = true) public class CreateAccountCmd extends BaseCmd { public static final Logger s_logger = Logger.getLogger(CreateAccountCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/admin/account/DeleteAccountCmd.java b/api/src/org/apache/cloudstack/api/command/admin/account/DeleteAccountCmd.java index 8cc87c2884..5754ec5010 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/account/DeleteAccountCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/account/DeleteAccountCmd.java @@ -20,7 +20,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ACL; import org.apache.cloudstack.api.APICommand; @@ -39,7 +38,7 @@ import com.cloud.user.Account; import com.cloud.user.User; -@APICommand(name = "deleteAccount", description = "Deletes a account, and all users associated with this account", responseObject = SuccessResponse.class, entityType = {IAMEntityType.Account}, +@APICommand(name = "deleteAccount", description = "Deletes a account, and all users associated with this account", responseObject = SuccessResponse.class, entityType = {Account.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class DeleteAccountCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(DeleteAccountCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/admin/account/DisableAccountCmd.java b/api/src/org/apache/cloudstack/api/command/admin/account/DisableAccountCmd.java index 1e810091ee..3e5e1d3d01 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/account/DisableAccountCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/account/DisableAccountCmd.java @@ -20,7 +20,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ACL; import org.apache.cloudstack.api.APICommand; @@ -41,7 +40,7 @@ import com.cloud.exception.ResourceUnavailableException; import com.cloud.user.Account; -@APICommand(name = "disableAccount", description = "Disables an account", responseObject = AccountResponse.class, entityType = {IAMEntityType.Account}, +@APICommand(name = "disableAccount", description = "Disables an account", responseObject = AccountResponse.class, entityType = {Account.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = true) public class DisableAccountCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(DisableAccountCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/admin/account/EnableAccountCmd.java b/api/src/org/apache/cloudstack/api/command/admin/account/EnableAccountCmd.java index 1bfd71c804..f30c985c96 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/account/EnableAccountCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/account/EnableAccountCmd.java @@ -20,7 +20,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ACL; import org.apache.cloudstack.api.APICommand; @@ -36,7 +35,7 @@ import com.cloud.user.Account; -@APICommand(name = "enableAccount", description = "Enables an account", responseObject = AccountResponse.class, entityType = {IAMEntityType.Account}, +@APICommand(name = "enableAccount", description = "Enables an account", responseObject = AccountResponse.class, entityType = {Account.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = true) public class EnableAccountCmd extends BaseCmd { public static final Logger s_logger = Logger.getLogger(EnableAccountCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/admin/account/LockAccountCmd.java b/api/src/org/apache/cloudstack/api/command/admin/account/LockAccountCmd.java index 780dac1d7a..3c185e41bd 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/account/LockAccountCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/account/LockAccountCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseCmd; @@ -28,7 +27,7 @@ import com.cloud.user.Account; -@APICommand(name = "lockAccount", description = "Locks an account", responseObject = AccountResponse.class, entityType = {IAMEntityType.Account}, +@APICommand(name = "lockAccount", description = "Locks an account", responseObject = AccountResponse.class, entityType = {Account.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = true) public class LockAccountCmd extends BaseCmd { public static final Logger s_logger = Logger.getLogger(LockAccountCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/admin/account/UpdateAccountCmd.java b/api/src/org/apache/cloudstack/api/command/admin/account/UpdateAccountCmd.java index 8d9fe261f9..a7ce74a129 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/account/UpdateAccountCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/account/UpdateAccountCmd.java @@ -23,7 +23,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ACL; import org.apache.cloudstack.api.APICommand; @@ -39,7 +38,7 @@ import com.cloud.user.Account; -@APICommand(name = "updateAccount", description = "Updates account information for the authenticated user", responseObject = AccountResponse.class, entityType = {IAMEntityType.Account}, +@APICommand(name = "updateAccount", description = "Updates account information for the authenticated user", responseObject = AccountResponse.class, entityType = {Account.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = true) public class UpdateAccountCmd extends BaseCmd { public static final Logger s_logger = Logger.getLogger(UpdateAccountCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/admin/internallb/ListInternalLBVMsCmd.java b/api/src/org/apache/cloudstack/api/command/admin/internallb/ListInternalLBVMsCmd.java index e6ea519778..0b59b73f9d 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/internallb/ListInternalLBVMsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/internallb/ListInternalLBVMsCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiCommandJobType; import org.apache.cloudstack.api.ApiConstants; @@ -34,8 +33,9 @@ import org.apache.cloudstack.api.response.ZoneResponse; import com.cloud.network.router.VirtualRouter.Role; +import com.cloud.vm.VirtualMachine; -@APICommand(name = "listInternalLoadBalancerVMs", description = "List internal LB VMs.", responseObject = DomainRouterResponse.class, entityType = {IAMEntityType.VirtualMachine}, +@APICommand(name = "listInternalLoadBalancerVMs", description = "List internal LB VMs.", responseObject = DomainRouterResponse.class, entityType = {VirtualMachine.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class ListInternalLBVMsCmd extends BaseListProjectAndAccountResourcesCmd { public static final Logger s_logger = Logger.getLogger(ListInternalLBVMsCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/admin/internallb/ListInternalLoadBalancerElementsCmd.java b/api/src/org/apache/cloudstack/api/command/admin/internallb/ListInternalLoadBalancerElementsCmd.java index 489b64325f..8f62b41969 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/internallb/ListInternalLoadBalancerElementsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/internallb/ListInternalLoadBalancerElementsCmd.java @@ -47,7 +47,7 @@ responseHasSensitiveInfo = false) public class ListInternalLoadBalancerElementsCmd extends BaseListCmd { public static final Logger s_logger = Logger.getLogger(ListInternalLoadBalancerElementsCmd.class.getName()); - private static final String Name = "listinternalloadbalancerelementsresponse"; + private static final String s_name = "listinternalloadbalancerelementsresponse"; @Inject private InternalLoadBalancerElementService _service; @@ -88,7 +88,7 @@ public Boolean getEnabled() { @Override public String getCommandName() { - return Name; + return s_name; } @Override diff --git a/api/src/org/apache/cloudstack/api/command/admin/internallb/StartInternalLBVMCmd.java b/api/src/org/apache/cloudstack/api/command/admin/internallb/StartInternalLBVMCmd.java index 54d7621600..7040e7cf29 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/internallb/StartInternalLBVMCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/internallb/StartInternalLBVMCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ACL; import org.apache.cloudstack.api.APICommand; @@ -38,8 +37,9 @@ import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.router.VirtualRouter; import com.cloud.network.router.VirtualRouter.Role; +import com.cloud.vm.VirtualMachine; -@APICommand(name = "startInternalLoadBalancerVM", responseObject = DomainRouterResponse.class, description = "Starts an existing internal lb vm.", entityType = {IAMEntityType.VirtualMachine}, +@APICommand(name = "startInternalLoadBalancerVM", responseObject = DomainRouterResponse.class, description = "Starts an existing internal lb vm.", entityType = {VirtualMachine.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class StartInternalLBVMCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(StartInternalLBVMCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/admin/internallb/StopInternalLBVMCmd.java b/api/src/org/apache/cloudstack/api/command/admin/internallb/StopInternalLBVMCmd.java index aa946bee31..51a3d9f8fa 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/internallb/StopInternalLBVMCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/internallb/StopInternalLBVMCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ACL; import org.apache.cloudstack.api.APICommand; @@ -37,8 +36,9 @@ import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.router.VirtualRouter; import com.cloud.network.router.VirtualRouter.Role; +import com.cloud.vm.VirtualMachine; -@APICommand(name = "stopInternalLoadBalancerVM", description = "Stops an Internal LB vm.", responseObject = DomainRouterResponse.class, entityType = {IAMEntityType.VirtualMachine}, +@APICommand(name = "stopInternalLoadBalancerVM", description = "Stops an Internal LB vm.", responseObject = DomainRouterResponse.class, entityType = {VirtualMachine.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class StopInternalLBVMCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(StopInternalLBVMCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/admin/iso/CopyIsoCmdByAdmin.java b/api/src/org/apache/cloudstack/api/command/admin/iso/CopyIsoCmdByAdmin.java new file mode 100644 index 0000000000..0475b37155 --- /dev/null +++ b/api/src/org/apache/cloudstack/api/command/admin/iso/CopyIsoCmdByAdmin.java @@ -0,0 +1,12 @@ +package org.apache.cloudstack.api.command.admin.iso; + +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.ResponseObject.ResponseView; +import org.apache.cloudstack.api.command.user.iso.CopyIsoCmd; +import org.apache.cloudstack.api.response.TemplateResponse; + +@APICommand(name = "copyIso", description = "Copies an iso from one zone to another.", responseObject = TemplateResponse.class, responseView = ResponseView.Full, + requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) +public class CopyIsoCmdByAdmin extends CopyIsoCmd { + +} diff --git a/api/src/org/apache/cloudstack/api/command/admin/loadbalancer/ListLoadBalancerRuleInstancesCmdByAdmin.java b/api/src/org/apache/cloudstack/api/command/admin/loadbalancer/ListLoadBalancerRuleInstancesCmdByAdmin.java index 26202b9bae..6c0d8a4888 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/loadbalancer/ListLoadBalancerRuleInstancesCmdByAdmin.java +++ b/api/src/org/apache/cloudstack/api/command/admin/loadbalancer/ListLoadBalancerRuleInstancesCmdByAdmin.java @@ -19,6 +19,8 @@ import java.util.ArrayList; import java.util.List; +import com.cloud.vm.VirtualMachine; +import org.apache.cloudstack.api.response.LoadBalancerRuleVmMapResponse; import org.apache.log4j.Logger; import org.apache.cloudstack.api.APICommand; @@ -30,7 +32,7 @@ import com.cloud.uservm.UserVm; import com.cloud.utils.Pair; -@APICommand(name = "listLoadBalancerRuleInstances", description = "List all virtual machine instances that are assigned to a load balancer rule.", responseObject = UserVmResponse.class, responseView = ResponseView.Full) +@APICommand(name = "listLoadBalancerRuleInstances", description = "List all virtual machine instances that are assigned to a load balancer rule.", responseObject = LoadBalancerRuleVmMapResponse.class, responseView = ResponseView.Full) public class ListLoadBalancerRuleInstancesCmdByAdmin extends ListLoadBalancerRuleInstancesCmd { public static final Logger s_logger = Logger.getLogger (ListLoadBalancerRuleInstancesCmdByAdmin.class.getName()); @@ -41,17 +43,50 @@ public void execute(){ Pair, List> vmServiceMap = _lbService.listLoadBalancerInstances(this); List result = vmServiceMap.first(); List serviceStates = vmServiceMap.second(); - ListResponse response = new ListResponse(); - List vmResponses = new ArrayList(); - if (result != null) { - vmResponses = _responseGenerator.createUserVmResponse(ResponseView.Full, "loadbalancerruleinstance", result.toArray(new UserVm[result.size()])); - } - for (int i=0;i response = new ListResponse(); + List vmResponses = new ArrayList(); + if (result != null) { + vmResponses = _responseGenerator.createUserVmResponse(ResponseView.Restricted, "loadbalancerruleinstance", result.toArray(new UserVm[result.size()])); + + + for (int i = 0; i < result.size(); i++) { + vmResponses.get(i).setServiceState(serviceStates.get(i)); + } + } + response.setResponses(vmResponses); + response.setResponseName(getCommandName()); + setResponseObject(response); + + } else { + ListResponse lbRes = new ListResponse(); + + List vmResponses = new ArrayList(); + List listlbVmRes = new ArrayList(); + + if (result != null) { + vmResponses = _responseGenerator.createUserVmResponse(ResponseView.Full, "loadbalancerruleinstance", result.toArray(new UserVm[result.size()])); + + List ipaddr = null; + + for (int i=0;i getDetails() { ///////////////////////////////////////////////////// @Override public String getCommandName() { - return Name; + return s_name; } @Override diff --git a/api/src/org/apache/cloudstack/api/command/admin/network/ListSupportedNetworkServicesCmd.java b/api/src/org/apache/cloudstack/api/command/admin/network/ListSupportedNetworkServicesCmd.java index 612c733a34..39e99a43a6 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/network/ListSupportedNetworkServicesCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/network/ListSupportedNetworkServicesCmd.java @@ -41,7 +41,7 @@ responseHasSensitiveInfo = false) public class ListSupportedNetworkServicesCmd extends BaseListCmd { public static final Logger s_logger = Logger.getLogger(ListSupportedNetworkServicesCmd.class.getName()); - private static final String Name = "listsupportednetworkservicesresponse"; + private static final String s_name = "listsupportednetworkservicesresponse"; @Parameter(name = ApiConstants.PROVIDER, type = CommandType.STRING, description = "network service provider name") private String providerName; @@ -74,7 +74,7 @@ public String getServiceName() { ///////////////////////////////////////////////////// @Override public String getCommandName() { - return Name; + return s_name; } @Override diff --git a/api/src/org/apache/cloudstack/api/command/admin/network/UpdateNetworkOfferingCmd.java b/api/src/org/apache/cloudstack/api/command/admin/network/UpdateNetworkOfferingCmd.java index f650b4ffb0..411da4fd36 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/network/UpdateNetworkOfferingCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/network/UpdateNetworkOfferingCmd.java @@ -33,7 +33,7 @@ requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class UpdateNetworkOfferingCmd extends BaseCmd { public static final Logger s_logger = Logger.getLogger(UpdateNetworkOfferingCmd.class.getName()); - private static final String Name = "updatenetworkofferingresponse"; + private static final String s_name = "updatenetworkofferingresponse"; ///////////////////////////////////////////////////// //////////////// API parameters ///////////////////// @@ -110,7 +110,7 @@ public Boolean getKeepAliveEnabled() { ///////////////////////////////////////////////////// @Override public String getCommandName() { - return Name; + return s_name; } @Override diff --git a/api/src/org/apache/cloudstack/api/command/admin/offering/CreateServiceOfferingCmd.java b/api/src/org/apache/cloudstack/api/command/admin/offering/CreateServiceOfferingCmd.java index 78101fb11a..6cd5d84a07 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/offering/CreateServiceOfferingCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/offering/CreateServiceOfferingCmd.java @@ -38,7 +38,7 @@ requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class CreateServiceOfferingCmd extends BaseCmd { public static final Logger s_logger = Logger.getLogger(CreateServiceOfferingCmd.class.getName()); - private static final String Name = "createserviceofferingresponse"; + private static final String s_name = "createserviceofferingresponse"; ///////////////////////////////////////////////////// //////////////// API parameters ///////////////////// @@ -118,19 +118,20 @@ public class CreateServiceOfferingCmd extends BaseCmd { @Parameter(name = ApiConstants.IOPS_WRITE_RATE, type = CommandType.LONG, required = false, description = "io requests write rate of the disk offering") private Long iopsWriteRate; - @Parameter(name = ApiConstants.CUSTOMIZED_IOPS, type = CommandType.BOOLEAN, required = false, description = "whether compute offering iops is custom or not") + @Parameter(name = ApiConstants.CUSTOMIZED_IOPS, type = CommandType.BOOLEAN, required = false, description = "whether compute offering iops is custom or not", since = "4.4") private Boolean customizedIops; - @Parameter(name = ApiConstants.MIN_IOPS, type = CommandType.LONG, required = false, description = "min iops of the compute offering") + @Parameter(name = ApiConstants.MIN_IOPS, type = CommandType.LONG, required = false, description = "min iops of the compute offering", since = "4.4") private Long minIops; - @Parameter(name = ApiConstants.MAX_IOPS, type = CommandType.LONG, required = false, description = "max iops of the compute offering") + @Parameter(name = ApiConstants.MAX_IOPS, type = CommandType.LONG, required = false, description = "max iops of the compute offering", since = "4.4") private Long maxIops; @Parameter(name = ApiConstants.HYPERVISOR_SNAPSHOT_RESERVE, type = CommandType.INTEGER, required = false, - description = "Hypervisor snapshot reserve space as a percent of a volume (for managed storage using Xen or VMware)") + description = "Hypervisor snapshot reserve space as a percent of a volume (for managed storage using Xen or VMware)", + since = "4.4") private Integer hypervisorSnapshotReserve; ///////////////////////////////////////////////////// @@ -257,7 +258,7 @@ public Integer getHypervisorSnapshotReserve() { @Override public String getCommandName() { - return Name; + return s_name; } @Override diff --git a/api/src/org/apache/cloudstack/api/command/admin/router/DestroyRouterCmd.java b/api/src/org/apache/cloudstack/api/command/admin/router/DestroyRouterCmd.java index 26440d4be9..4513e2e85e 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/router/DestroyRouterCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/router/DestroyRouterCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiCommandJobType; import org.apache.cloudstack.api.ApiConstants; @@ -34,8 +33,9 @@ import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.router.VirtualRouter; import com.cloud.user.Account; +import com.cloud.vm.VirtualMachine; -@APICommand(name = "destroyRouter", description = "Destroys a router.", responseObject = DomainRouterResponse.class, entityType = {IAMEntityType.VirtualMachine}, +@APICommand(name = "destroyRouter", description = "Destroys a router.", responseObject = DomainRouterResponse.class, entityType = {VirtualMachine.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class DestroyRouterCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(DestroyRouterCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/admin/router/ListRoutersCmd.java b/api/src/org/apache/cloudstack/api/command/admin/router/ListRoutersCmd.java index d55a5f3ed9..121fc5bc14 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/router/ListRoutersCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/router/ListRoutersCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiCommandJobType; import org.apache.cloudstack.api.ApiConstants; @@ -35,8 +34,9 @@ import org.apache.cloudstack.api.response.ZoneResponse; import com.cloud.network.router.VirtualRouter.Role; +import com.cloud.vm.VirtualMachine; -@APICommand(name = "listRouters", description = "List routers.", responseObject = DomainRouterResponse.class, entityType = {IAMEntityType.VirtualMachine}, +@APICommand(name = "listRouters", description = "List routers.", responseObject = DomainRouterResponse.class, entityType = {VirtualMachine.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class ListRoutersCmd extends BaseListProjectAndAccountResourcesCmd { public static final Logger s_logger = Logger.getLogger(ListRoutersCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/admin/router/ListVirtualRouterElementsCmd.java b/api/src/org/apache/cloudstack/api/command/admin/router/ListVirtualRouterElementsCmd.java index 62c6da5ee2..24bbf5ae2e 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/router/ListVirtualRouterElementsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/router/ListVirtualRouterElementsCmd.java @@ -44,7 +44,7 @@ requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class ListVirtualRouterElementsCmd extends BaseListCmd { public static final Logger s_logger = Logger.getLogger(ListNetworkOfferingsCmd.class.getName()); - private static final String Name = "listvirtualrouterelementsresponse"; + private static final String s_name = "listvirtualrouterelementsresponse"; // TODO, VirtualRouterElementServer is not singleton in system! @Inject @@ -95,7 +95,7 @@ public Boolean getEnabled() { @Override public String getCommandName() { - return Name; + return s_name; } @Override diff --git a/api/src/org/apache/cloudstack/api/command/admin/router/RebootRouterCmd.java b/api/src/org/apache/cloudstack/api/command/admin/router/RebootRouterCmd.java index 3a8938812b..4b138f3cfc 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/router/RebootRouterCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/router/RebootRouterCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiCommandJobType; import org.apache.cloudstack.api.ApiConstants; @@ -35,8 +34,9 @@ import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.router.VirtualRouter; import com.cloud.user.Account; +import com.cloud.vm.VirtualMachine; -@APICommand(name = "rebootRouter", description = "Starts a router.", responseObject = DomainRouterResponse.class, entityType = {IAMEntityType.VirtualMachine}, +@APICommand(name = "rebootRouter", description = "Starts a router.", responseObject = DomainRouterResponse.class, entityType = {VirtualMachine.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class RebootRouterCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(RebootRouterCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/admin/router/StartRouterCmd.java b/api/src/org/apache/cloudstack/api/command/admin/router/StartRouterCmd.java index f83466b1dc..173833cb42 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/router/StartRouterCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/router/StartRouterCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiCommandJobType; import org.apache.cloudstack.api.ApiConstants; @@ -37,8 +36,9 @@ import com.cloud.network.router.VirtualRouter; import com.cloud.network.router.VirtualRouter.Role; import com.cloud.user.Account; +import com.cloud.vm.VirtualMachine; -@APICommand(name = "startRouter", responseObject = DomainRouterResponse.class, description = "Starts a router.", entityType = {IAMEntityType.VirtualMachine}, +@APICommand(name = "startRouter", responseObject = DomainRouterResponse.class, description = "Starts a router.", entityType = {VirtualMachine.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class StartRouterCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(StartRouterCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/admin/router/StopRouterCmd.java b/api/src/org/apache/cloudstack/api/command/admin/router/StopRouterCmd.java index e2d420073d..2592cae545 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/router/StopRouterCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/router/StopRouterCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiCommandJobType; import org.apache.cloudstack.api.ApiConstants; @@ -36,8 +35,9 @@ import com.cloud.network.router.VirtualRouter; import com.cloud.network.router.VirtualRouter.Role; import com.cloud.user.Account; +import com.cloud.vm.VirtualMachine; -@APICommand(name = "stopRouter", description = "Stops a router.", responseObject = DomainRouterResponse.class, entityType = {IAMEntityType.VirtualMachine}, +@APICommand(name = "stopRouter", description = "Stops a router.", responseObject = DomainRouterResponse.class, entityType = {VirtualMachine.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class StopRouterCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(StopRouterCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/admin/router/UpgradeRouterCmd.java b/api/src/org/apache/cloudstack/api/command/admin/router/UpgradeRouterCmd.java index 0b67db9cef..067d344337 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/router/UpgradeRouterCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/router/UpgradeRouterCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.ApiErrorCode; @@ -30,8 +29,9 @@ import com.cloud.network.router.VirtualRouter; import com.cloud.user.Account; +import com.cloud.vm.VirtualMachine; -@APICommand(name = "changeServiceForRouter", description = "Upgrades domain router to a new service offering", responseObject = DomainRouterResponse.class, entityType = {IAMEntityType.VirtualMachine}, +@APICommand(name = "changeServiceForRouter", description = "Upgrades domain router to a new service offering", responseObject = DomainRouterResponse.class, entityType = {VirtualMachine.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class UpgradeRouterCmd extends BaseCmd { public static final Logger s_logger = Logger.getLogger(UpgradeRouterCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/admin/storage/AddS3Cmd.java b/api/src/org/apache/cloudstack/api/command/admin/storage/AddS3Cmd.java index 8a82e89d7a..4164394f5e 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/storage/AddS3Cmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/storage/AddS3Cmd.java @@ -57,7 +57,7 @@ public final class AddS3Cmd extends BaseCmd { public static final Logger s_logger = Logger.getLogger(AddS3Cmd.class.getName()); - private static final String COMMAND_NAME = "adds3response"; + private static final String s_name = "adds3response"; @Parameter(name = S3_ACCESS_KEY, type = STRING, required = true, description = "S3 access key") private String accessKey; @@ -190,7 +190,7 @@ public int hashCode() { @Override public String getCommandName() { - return COMMAND_NAME; + return s_name; } @Override diff --git a/api/src/org/apache/cloudstack/api/command/admin/systemvm/DestroySystemVmCmd.java b/api/src/org/apache/cloudstack/api/command/admin/systemvm/DestroySystemVmCmd.java index bc977a456e..47dfe8b724 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/systemvm/DestroySystemVmCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/systemvm/DestroySystemVmCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ACL; import org.apache.cloudstack.api.APICommand; @@ -35,7 +34,7 @@ import com.cloud.user.Account; import com.cloud.vm.VirtualMachine; -@APICommand(name = "destroySystemVm", responseObject = SystemVmResponse.class, description = "Destroyes a system virtual machine.", entityType = {IAMEntityType.VirtualMachine}, +@APICommand(name = "destroySystemVm", responseObject = SystemVmResponse.class, description = "Destroyes a system virtual machine.", entityType = {VirtualMachine.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class DestroySystemVmCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(DestroySystemVmCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/admin/systemvm/ListSystemVMsCmd.java b/api/src/org/apache/cloudstack/api/command/admin/systemvm/ListSystemVMsCmd.java index bfecd1857f..2b2faf5011 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/systemvm/ListSystemVMsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/systemvm/ListSystemVMsCmd.java @@ -21,7 +21,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiCommandJobType; import org.apache.cloudstack.api.ApiConstants; @@ -37,7 +36,7 @@ import com.cloud.utils.Pair; import com.cloud.vm.VirtualMachine; -@APICommand(name = "listSystemVms", description = "List system virtual machines.", responseObject = SystemVmResponse.class, entityType = {IAMEntityType.VirtualMachine}, +@APICommand(name = "listSystemVms", description = "List system virtual machines.", responseObject = SystemVmResponse.class, entityType = {VirtualMachine.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class ListSystemVMsCmd extends BaseListCmd { public static final Logger s_logger = Logger.getLogger(ListSystemVMsCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/admin/systemvm/MigrateSystemVMCmd.java b/api/src/org/apache/cloudstack/api/command/admin/systemvm/MigrateSystemVMCmd.java index 994635a1b7..97acfe0c46 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/systemvm/MigrateSystemVMCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/systemvm/MigrateSystemVMCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ACL; import org.apache.cloudstack.api.APICommand; @@ -41,7 +40,7 @@ import com.cloud.user.Account; import com.cloud.vm.VirtualMachine; -@APICommand(name = "migrateSystemVm", description = "Attempts Migration of a system virtual machine to the host specified.", responseObject = SystemVmResponse.class, entityType = {IAMEntityType.VirtualMachine}, +@APICommand(name = "migrateSystemVm", description = "Attempts Migration of a system virtual machine to the host specified.", responseObject = SystemVmResponse.class, entityType = {VirtualMachine.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class MigrateSystemVMCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(MigrateSystemVMCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/admin/systemvm/RebootSystemVmCmd.java b/api/src/org/apache/cloudstack/api/command/admin/systemvm/RebootSystemVmCmd.java index 0031d60351..f439ddf4de 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/systemvm/RebootSystemVmCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/systemvm/RebootSystemVmCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ACL; import org.apache.cloudstack.api.APICommand; @@ -35,7 +34,7 @@ import com.cloud.user.Account; import com.cloud.vm.VirtualMachine; -@APICommand(name = "rebootSystemVm", description = "Reboots a system VM.", responseObject = SystemVmResponse.class, entityType = {IAMEntityType.VirtualMachine}, +@APICommand(name = "rebootSystemVm", description = "Reboots a system VM.", responseObject = SystemVmResponse.class, entityType = {VirtualMachine.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class RebootSystemVmCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(RebootSystemVmCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/admin/systemvm/ScaleSystemVMCmd.java b/api/src/org/apache/cloudstack/api/command/admin/systemvm/ScaleSystemVMCmd.java index f50b2c4b2c..68e9f94a8b 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/systemvm/ScaleSystemVMCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/systemvm/ScaleSystemVMCmd.java @@ -23,7 +23,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ACL; import org.apache.cloudstack.api.APICommand; @@ -48,7 +47,7 @@ import com.cloud.vm.VirtualMachine; @APICommand(name = "scaleSystemVm", responseObject = SystemVmResponse.class, description = "Scale the service offering for a system vm (console proxy or secondary storage). " - + "The system vm must be in a \"Stopped\" state for " + "this command to take effect.", entityType = {IAMEntityType.VirtualMachine}, + + "The system vm must be in a \"Stopped\" state for " + "this command to take effect.", entityType = {VirtualMachine.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class ScaleSystemVMCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(UpgradeVMCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/admin/systemvm/StartSystemVMCmd.java b/api/src/org/apache/cloudstack/api/command/admin/systemvm/StartSystemVMCmd.java index 6aecc9117c..c456592d10 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/systemvm/StartSystemVMCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/systemvm/StartSystemVMCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ACL; import org.apache.cloudstack.api.APICommand; @@ -35,7 +34,7 @@ import com.cloud.user.Account; import com.cloud.vm.VirtualMachine; -@APICommand(name = "startSystemVm", responseObject = SystemVmResponse.class, description = "Starts a system virtual machine.", entityType = {IAMEntityType.VirtualMachine}, +@APICommand(name = "startSystemVm", responseObject = SystemVmResponse.class, description = "Starts a system virtual machine.", entityType = {VirtualMachine.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class StartSystemVMCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(StartSystemVMCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/admin/systemvm/StopSystemVmCmd.java b/api/src/org/apache/cloudstack/api/command/admin/systemvm/StopSystemVmCmd.java index 9a049c2afe..d60460ced1 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/systemvm/StopSystemVmCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/systemvm/StopSystemVmCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ACL; import org.apache.cloudstack.api.APICommand; @@ -37,7 +36,7 @@ import com.cloud.user.Account; import com.cloud.vm.VirtualMachine; -@APICommand(name = "stopSystemVm", description = "Stops a system VM.", responseObject = SystemVmResponse.class, entityType = {IAMEntityType.VirtualMachine}, +@APICommand(name = "stopSystemVm", description = "Stops a system VM.", responseObject = SystemVmResponse.class, entityType = {VirtualMachine.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class StopSystemVmCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(StopSystemVmCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/admin/systemvm/UpgradeSystemVMCmd.java b/api/src/org/apache/cloudstack/api/command/admin/systemvm/UpgradeSystemVMCmd.java index 033709aca4..d71ef03244 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/systemvm/UpgradeSystemVMCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/systemvm/UpgradeSystemVMCmd.java @@ -23,7 +23,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ACL; import org.apache.cloudstack.api.APICommand; @@ -43,7 +42,7 @@ import com.cloud.vm.VirtualMachine; @APICommand(name = "changeServiceForSystemVm", responseObject = SystemVmResponse.class, description = "Changes the service offering for a system vm (console proxy or secondary storage). " - + "The system vm must be in a \"Stopped\" state for " + "this command to take effect.", entityType = {IAMEntityType.VirtualMachine}, + + "The system vm must be in a \"Stopped\" state for " + "this command to take effect.", entityType = {VirtualMachine.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class UpgradeSystemVMCmd extends BaseCmd { public static final Logger s_logger = Logger.getLogger(UpgradeVMCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/admin/template/ListTemplatesCmdByAdmin.java b/api/src/org/apache/cloudstack/api/command/admin/template/ListTemplatesCmdByAdmin.java index b2e9ef54e2..4e2bb018d0 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/template/ListTemplatesCmdByAdmin.java +++ b/api/src/org/apache/cloudstack/api/command/admin/template/ListTemplatesCmdByAdmin.java @@ -16,13 +16,14 @@ // under the License. package org.apache.cloudstack.api.command.admin.template; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ResponseObject.ResponseView; import org.apache.cloudstack.api.command.user.template.ListTemplatesCmd; import org.apache.cloudstack.api.response.TemplateResponse; -@APICommand(name = "listTemplates", description = "List all public, private, and privileged templates.", responseObject = TemplateResponse.class, entityType = {IAMEntityType.VirtualMachineTemplate}, responseView = ResponseView.Full) +import com.cloud.template.VirtualMachineTemplate; + +@APICommand(name = "listTemplates", description = "List all public, private, and privileged templates.", responseObject = TemplateResponse.class, entityType = {VirtualMachineTemplate.class}, responseView = ResponseView.Full) public class ListTemplatesCmdByAdmin extends ListTemplatesCmd { } diff --git a/api/src/org/apache/cloudstack/api/command/admin/template/PrepareTemplateCmd.java b/api/src/org/apache/cloudstack/api/command/admin/template/PrepareTemplateCmd.java index ce432430e1..d4c26966d9 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/template/PrepareTemplateCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/template/PrepareTemplateCmd.java @@ -20,7 +20,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ACL; import org.apache.cloudstack.api.APICommand; @@ -35,7 +34,7 @@ import com.cloud.template.VirtualMachineTemplate; import com.cloud.user.Account; -@APICommand(name = "prepareTemplate", responseObject = TemplateResponse.class, description = "load template into primary storage", entityType = {IAMEntityType.VirtualMachineTemplate}, +@APICommand(name = "prepareTemplate", responseObject = TemplateResponse.class, description = "load template into primary storage", entityType = {VirtualMachineTemplate.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class PrepareTemplateCmd extends BaseCmd { public static final Logger s_logger = Logger.getLogger(PrepareTemplateCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/admin/usage/ListTrafficTypeImplementorsCmd.java b/api/src/org/apache/cloudstack/api/command/admin/usage/ListTrafficTypeImplementorsCmd.java index a1ff29fd00..bd634bbe5c 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/usage/ListTrafficTypeImplementorsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/usage/ListTrafficTypeImplementorsCmd.java @@ -45,7 +45,7 @@ responseHasSensitiveInfo = false) public class ListTrafficTypeImplementorsCmd extends BaseListCmd { public static final Logger s_logger = Logger.getLogger(ListTrafficTypeImplementorsCmd.class); - private static final String Name = "listtraffictypeimplementorsresponse"; + private static final String s_name = "listtraffictypeimplementorsresponse"; ///////////////////////////////////////////////////// //////////////// API parameters ///////////////////// @@ -89,6 +89,6 @@ public long getEntityOwnerId() { @Override public String getCommandName() { - return Name; + return s_name; } } diff --git a/api/src/org/apache/cloudstack/api/command/admin/usage/ListTrafficTypesCmd.java b/api/src/org/apache/cloudstack/api/command/admin/usage/ListTrafficTypesCmd.java index 33ee29611d..fd0635959b 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/usage/ListTrafficTypesCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/usage/ListTrafficTypesCmd.java @@ -38,7 +38,7 @@ requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class ListTrafficTypesCmd extends BaseListCmd { public static final Logger s_logger = Logger.getLogger(ListTrafficTypesCmd.class.getName()); - private static final String Name = "listtraffictypesresponse"; + private static final String s_name = "listtraffictypesresponse"; ///////////////////////////////////////////////////// //////////////// API parameters ///////////////////// @@ -67,7 +67,7 @@ public Long getPhysicalNetworkId() { ///////////////////////////////////////////////////// @Override public String getCommandName() { - return Name; + return s_name; } @Override diff --git a/api/src/org/apache/cloudstack/api/command/admin/user/CreateUserCmd.java b/api/src/org/apache/cloudstack/api/command/admin/user/CreateUserCmd.java index 51e218d7de..bd67436f6e 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/user/CreateUserCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/user/CreateUserCmd.java @@ -31,7 +31,7 @@ import com.cloud.user.User; @APICommand(name = "createUser", description = "Creates a user for an account that already exists", responseObject = UserResponse.class, - requestHasSensitiveInfo = true, responseHasSensitiveInfo = true) + requestHasSensitiveInfo = true, responseHasSensitiveInfo = true, entityType = { Account.class }) public class CreateUserCmd extends BaseCmd { public static final Logger s_logger = Logger.getLogger(CreateUserCmd.class.getName()); @@ -131,7 +131,7 @@ public String getCommandName() { @Override public long getEntityOwnerId() { Account account = CallContext.current().getCallingAccount(); - if ((account == null) || _accountService.isAdmin(account.getType())) { + if ((account == null) || _accountService.isAdmin(account.getId())) { if ((domainId != null) && (accountName != null)) { Account userAccount = _responseGenerator.findAccountByNameDomain(accountName, domainId); if (userAccount != null) { diff --git a/api/src/org/apache/cloudstack/api/command/admin/user/DeleteUserCmd.java b/api/src/org/apache/cloudstack/api/command/admin/user/DeleteUserCmd.java index 08ba521ed6..f90a48043d 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/user/DeleteUserCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/user/DeleteUserCmd.java @@ -35,7 +35,7 @@ import com.cloud.user.User; @APICommand(name = "deleteUser", description = "Deletes a user for an account", responseObject = SuccessResponse.class, - requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) + requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, entityType = { Account.class }) public class DeleteUserCmd extends BaseCmd { public static final Logger s_logger = Logger.getLogger(DeleteUserCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/admin/user/DisableUserCmd.java b/api/src/org/apache/cloudstack/api/command/admin/user/DisableUserCmd.java index c6e09ef0f9..3a9676e246 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/user/DisableUserCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/user/DisableUserCmd.java @@ -37,7 +37,7 @@ import com.cloud.user.UserAccount; @APICommand(name = "disableUser", description = "Disables a user account", responseObject = UserResponse.class, - requestHasSensitiveInfo = false, responseHasSensitiveInfo = true) + requestHasSensitiveInfo = false, responseHasSensitiveInfo = true, entityType = { Account.class }) public class DisableUserCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(DisableUserCmd.class.getName()); private static final String s_name = "disableuserresponse"; diff --git a/api/src/org/apache/cloudstack/api/command/admin/user/EnableUserCmd.java b/api/src/org/apache/cloudstack/api/command/admin/user/EnableUserCmd.java index d69eccf934..e4f4477103 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/user/EnableUserCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/user/EnableUserCmd.java @@ -35,7 +35,7 @@ import com.cloud.user.UserAccount; @APICommand(name = "enableUser", description = "Enables a user account", responseObject = UserResponse.class, - requestHasSensitiveInfo = false, responseHasSensitiveInfo = true) + requestHasSensitiveInfo = false, responseHasSensitiveInfo = true, entityType = { Account.class }) public class EnableUserCmd extends BaseCmd { public static final Logger s_logger = Logger.getLogger(EnableUserCmd.class.getName()); private static final String s_name = "enableuserresponse"; diff --git a/api/src/org/apache/cloudstack/api/command/admin/user/GetUserCmd.java b/api/src/org/apache/cloudstack/api/command/admin/user/GetUserCmd.java index b2c6734c9e..f8c7589e78 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/user/GetUserCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/user/GetUserCmd.java @@ -25,10 +25,11 @@ import org.apache.cloudstack.api.response.UserResponse; import com.cloud.exception.InvalidParameterValueException; +import com.cloud.user.Account; import com.cloud.user.UserAccount; @APICommand(name = "getUser", description = "Find user account by API key", responseObject = UserResponse.class, - requestHasSensitiveInfo = false, responseHasSensitiveInfo = true) + requestHasSensitiveInfo = false, responseHasSensitiveInfo = true, entityType = { Account.class }) public class GetUserCmd extends BaseCmd { public static final Logger s_logger = Logger.getLogger(GetUserCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/admin/user/ListUsersCmd.java b/api/src/org/apache/cloudstack/api/command/admin/user/ListUsersCmd.java index c0c2b24814..14cbb26602 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/user/ListUsersCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/user/ListUsersCmd.java @@ -25,8 +25,10 @@ import org.apache.cloudstack.api.response.ListResponse; import org.apache.cloudstack.api.response.UserResponse; +import com.cloud.user.Account; + @APICommand(name = "listUsers", description = "Lists user accounts", responseObject = UserResponse.class, - requestHasSensitiveInfo = false, responseHasSensitiveInfo = true) + requestHasSensitiveInfo = false, responseHasSensitiveInfo = true, entityType = { Account.class }) public class ListUsersCmd extends BaseListAccountResourcesCmd { public static final Logger s_logger = Logger.getLogger(ListUsersCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/admin/user/UpdateUserCmd.java b/api/src/org/apache/cloudstack/api/command/admin/user/UpdateUserCmd.java index cf5d355e26..e7236e8659 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/user/UpdateUserCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/user/UpdateUserCmd.java @@ -35,7 +35,7 @@ import com.cloud.user.UserAccount; @APICommand(name = "updateUser", description = "Updates a user account", responseObject = UserResponse.class, - requestHasSensitiveInfo = true, responseHasSensitiveInfo = true) + requestHasSensitiveInfo = true, responseHasSensitiveInfo = true, entityType = { Account.class }) public class UpdateUserCmd extends BaseCmd { public static final Logger s_logger = Logger.getLogger(UpdateUserCmd.class.getName()); @@ -45,7 +45,7 @@ public class UpdateUserCmd extends BaseCmd { //////////////// API parameters ///////////////////// ///////////////////////////////////////////////////// - @Parameter(name = ApiConstants.API_KEY, type = CommandType.STRING, description = "The API key for the user. Must be specified with userSecretKey") + @Parameter(name = ApiConstants.USER_API_KEY, type = CommandType.STRING, description = "The API key for the user. Must be specified with userSecretKey") private String apiKey; @Parameter(name = ApiConstants.EMAIL, type = CommandType.STRING, description = "email") @@ -65,7 +65,7 @@ public class UpdateUserCmd extends BaseCmd { description = "Clear text password (default hashed to SHA256SALT). If you wish to use any other hasing algorithm, you would need to write a custom authentication adapter") private String password; - @Parameter(name = ApiConstants.SECRET_KEY, type = CommandType.STRING, description = "The secret key for the user. Must be specified with userApiKey") + @Parameter(name = ApiConstants.SECRET_KEY, type = CommandType.STRING, description = "The secret key for the user. Must be specified with userSecretKey") private String secretKey; @Parameter(name = ApiConstants.TIMEZONE, diff --git a/api/src/org/apache/cloudstack/api/command/admin/vlan/CreateVlanIpRangeCmd.java b/api/src/org/apache/cloudstack/api/command/admin/vlan/CreateVlanIpRangeCmd.java index 75edfce3f9..60326257f2 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/vlan/CreateVlanIpRangeCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/vlan/CreateVlanIpRangeCmd.java @@ -16,6 +16,7 @@ // under the License. package org.apache.cloudstack.api.command.admin.vlan; +import com.cloud.utils.net.NetUtils; import org.apache.log4j.Logger; import org.apache.cloudstack.api.APICommand; @@ -166,28 +167,28 @@ public String getStartIpv6() { if (startIpv6 == null) { return null; } - return startIpv6.toLowerCase(); + return NetUtils.standardizeIp6Address(startIpv6); } public String getEndIpv6() { if (endIpv6 == null) { return null; } - return endIpv6.toLowerCase(); + return NetUtils.standardizeIp6Address(endIpv6); } public String getIp6Gateway() { if (ip6Gateway == null) { return null; } - return ip6Gateway.toLowerCase(); + return NetUtils.standardizeIp6Address(ip6Gateway); } public String getIp6Cidr() { if (ip6Cidr == null) { return null; } - return ip6Cidr.toLowerCase(); + return NetUtils.standardizeIp6Cidr(ip6Cidr); } ///////////////////////////////////////////////////// diff --git a/api/src/org/apache/cloudstack/api/command/admin/vm/AddNicToVMCmdByAdmin.java b/api/src/org/apache/cloudstack/api/command/admin/vm/AddNicToVMCmdByAdmin.java index 996d1bd49e..945f8499fe 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/vm/AddNicToVMCmdByAdmin.java +++ b/api/src/org/apache/cloudstack/api/command/admin/vm/AddNicToVMCmdByAdmin.java @@ -31,9 +31,11 @@ import org.apache.cloudstack.context.CallContext; import com.cloud.uservm.UserVm; +import com.cloud.vm.VirtualMachine; -@APICommand(name = "addNicToVirtualMachine", description = "Adds VM to specified network by creating a NIC", responseObject = UserVmResponse.class, responseView = ResponseView.Full) +@APICommand(name = "addNicToVirtualMachine", description = "Adds VM to specified network by creating a NIC", responseObject = UserVmResponse.class, responseView = ResponseView.Full, entityType = {VirtualMachine.class}, + requestHasSensitiveInfo = false, responseHasSensitiveInfo = true) public class AddNicToVMCmdByAdmin extends AddNicToVMCmd { public static final Logger s_logger = Logger.getLogger(AddNicToVMCmdByAdmin.class); diff --git a/api/src/org/apache/cloudstack/api/command/admin/vm/AssignVMCmd.java b/api/src/org/apache/cloudstack/api/command/admin/vm/AssignVMCmd.java index dd84ec2a60..435b7f1848 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/vm/AssignVMCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/vm/AssignVMCmd.java @@ -20,7 +20,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.ApiErrorCode; @@ -35,11 +34,12 @@ import com.cloud.user.Account; import com.cloud.uservm.UserVm; +import com.cloud.vm.VirtualMachine; @APICommand(name = "assignVirtualMachine", description = "Change ownership of a VM from one account to another. This API is available for Basic zones with security groups and Advanced zones with guest networks. A root administrator can reassign a VM from any account to any other account in any domain. A domain administrator can reassign a VM to any account in the same domain.", responseObject = UserVmResponse.class, - since = "3.0.0", entityType = {IAMEntityType.VirtualMachine}, + since = "3.0.0", entityType = {VirtualMachine.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = true) public class AssignVMCmd extends BaseCmd { diff --git a/api/src/org/apache/cloudstack/api/command/admin/vm/DeployVMCmdByAdmin.java b/api/src/org/apache/cloudstack/api/command/admin/vm/DeployVMCmdByAdmin.java index 99fec6b5a7..77aa20f3ca 100755 --- a/api/src/org/apache/cloudstack/api/command/admin/vm/DeployVMCmdByAdmin.java +++ b/api/src/org/apache/cloudstack/api/command/admin/vm/DeployVMCmdByAdmin.java @@ -68,7 +68,7 @@ public void execute(){ } if (result != null) { - UserVmResponse response = _responseGenerator.createUserVmResponse(ResponseView.Restricted, "virtualmachine", result).get(0); + UserVmResponse response = _responseGenerator.createUserVmResponse(ResponseView.Full, "virtualmachine", result).get(0); response.setResponseName(getCommandName()); setResponseObject(response); } else { diff --git a/api/src/org/apache/cloudstack/api/command/admin/vm/ExpungeVMCmd.java b/api/src/org/apache/cloudstack/api/command/admin/vm/ExpungeVMCmd.java index 623ddb6779..155fcfff4d 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/vm/ExpungeVMCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/vm/ExpungeVMCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ACL; import org.apache.cloudstack.api.APICommand; @@ -39,8 +38,9 @@ import com.cloud.user.Account; import com.cloud.uservm.UserVm; import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.vm.VirtualMachine; -@APICommand(name = "expungeVirtualMachine", description = "Expunge a virtual machine. Once expunged, it cannot be recoverd.", responseObject = SuccessResponse.class, entityType = {IAMEntityType.VirtualMachine}, +@APICommand(name = "expungeVirtualMachine", description = "Expunge a virtual machine. Once expunged, it cannot be recoverd.", responseObject = SuccessResponse.class, entityType = {VirtualMachine.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class ExpungeVMCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(ExpungeVMCmd.class.getName()); @@ -106,7 +106,7 @@ public Long getInstanceId() { public void execute() throws ResourceUnavailableException, ConcurrentOperationException { CallContext.current().setEventDetails("Vm Id: " + getId()); try { - UserVm result = _userVmService.expungeVm(this); + UserVm result = _userVmService.expungeVm(this.getId()); if (result != null) { SuccessResponse response = new SuccessResponse(getCommandName()); diff --git a/api/src/org/apache/cloudstack/api/command/admin/vm/MigrateVMCmd.java b/api/src/org/apache/cloudstack/api/command/admin/vm/MigrateVMCmd.java index fe8446859c..ef9619effa 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/vm/MigrateVMCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/vm/MigrateVMCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.ApiErrorCode; @@ -45,7 +44,7 @@ @APICommand(name = "migrateVirtualMachine", description = "Attempts Migration of a VM to a different host or Root volume of the vm to a different storage pool", - responseObject = UserVmResponse.class, entityType = {IAMEntityType.VirtualMachine}, + responseObject = UserVmResponse.class, entityType = {VirtualMachine.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = true) public class MigrateVMCmd extends BaseAsyncCmd { diff --git a/api/src/org/apache/cloudstack/api/command/admin/vm/MigrateVirtualMachineWithVolumeCmd.java b/api/src/org/apache/cloudstack/api/command/admin/vm/MigrateVirtualMachineWithVolumeCmd.java index b5d1ae9315..f1d3fe975f 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/vm/MigrateVirtualMachineWithVolumeCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/vm/MigrateVirtualMachineWithVolumeCmd.java @@ -23,7 +23,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.ApiErrorCode; @@ -47,7 +46,7 @@ @APICommand(name = "migrateVirtualMachineWithVolume", description = "Attempts Migration of a VM with its volumes to a different host", - responseObject = UserVmResponse.class, entityType = {IAMEntityType.VirtualMachine}, + responseObject = UserVmResponse.class, entityType = {VirtualMachine.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = true) public class MigrateVirtualMachineWithVolumeCmd extends BaseAsyncCmd { diff --git a/api/src/org/apache/cloudstack/api/command/admin/vm/RecoverVMCmd.java b/api/src/org/apache/cloudstack/api/command/admin/vm/RecoverVMCmd.java index e7fbbdb784..4ad0917154 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/vm/RecoverVMCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/vm/RecoverVMCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.ApiErrorCode; @@ -31,8 +30,9 @@ import com.cloud.exception.ResourceAllocationException; import com.cloud.user.Account; import com.cloud.uservm.UserVm; +import com.cloud.vm.VirtualMachine; -@APICommand(name = "recoverVirtualMachine", description = "Recovers a virtual machine.", responseObject = UserVmResponse.class, entityType = {IAMEntityType.VirtualMachine}, +@APICommand(name = "recoverVirtualMachine", description = "Recovers a virtual machine.", responseObject = UserVmResponse.class, entityType = {VirtualMachine.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = true) public class RecoverVMCmd extends BaseCmd { public static final Logger s_logger = Logger.getLogger(RecoverVMCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/admin/volume/CreateVolumeCmdByAdmin.java b/api/src/org/apache/cloudstack/api/command/admin/volume/CreateVolumeCmdByAdmin.java index 5df7481497..8ff3993cd5 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/volume/CreateVolumeCmdByAdmin.java +++ b/api/src/org/apache/cloudstack/api/command/admin/volume/CreateVolumeCmdByAdmin.java @@ -28,8 +28,11 @@ import com.cloud.storage.Snapshot; import com.cloud.storage.Volume; +import com.cloud.vm.VirtualMachine; -@APICommand(name = "createVolume", responseObject = VolumeResponse.class, description = "Creates a disk volume from a disk offering. This disk volume must still be attached to a virtual machine to make use of it.", responseView = ResponseView.Full) +@APICommand(name = "createVolume", responseObject = VolumeResponse.class, description = "Creates a disk volume from a disk offering. This disk volume must still be attached to a virtual machine to make use of it.", responseView = ResponseView.Full, entityType = { + Volume.class, VirtualMachine.class}, + requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class CreateVolumeCmdByAdmin extends CreateVolumeCmd { public static final Logger s_logger = Logger.getLogger(CreateVolumeCmdByAdmin.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/admin/vpc/CreatePrivateGatewayCmd.java b/api/src/org/apache/cloudstack/api/command/admin/vpc/CreatePrivateGatewayCmd.java index ff88ada781..01db44e25d 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/vpc/CreatePrivateGatewayCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/vpc/CreatePrivateGatewayCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiCommandJobType; import org.apache.cloudstack.api.ApiConstants; @@ -41,9 +40,10 @@ import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.vpc.PrivateGateway; import com.cloud.network.vpc.Vpc; +import com.cloud.network.vpc.VpcGateway; import com.cloud.user.Account; -@APICommand(name = "createPrivateGateway", description = "Creates a private gateway", responseObject = PrivateGatewayResponse.class, entityType = {IAMEntityType.PrivateGateway}, +@APICommand(name = "createPrivateGateway", description = "Creates a private gateway", responseObject = PrivateGatewayResponse.class, entityType = {VpcGateway.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class CreatePrivateGatewayCmd extends BaseAsyncCreateCmd { public static final Logger s_logger = Logger.getLogger(CreatePrivateGatewayCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/admin/vpc/CreateVPCCmdByAdmin.java b/api/src/org/apache/cloudstack/api/command/admin/vpc/CreateVPCCmdByAdmin.java index f063cdbde4..25e6325015 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/vpc/CreateVPCCmdByAdmin.java +++ b/api/src/org/apache/cloudstack/api/command/admin/vpc/CreateVPCCmdByAdmin.java @@ -19,6 +19,7 @@ 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.ResponseObject.ResponseView; import org.apache.cloudstack.api.ServerApiException; @@ -37,10 +38,14 @@ public class CreateVPCCmdByAdmin extends CreateVPCCmd { @Override public void execute() { Vpc vpc = null; + boolean success = true; try { - if (_vpcService.startVpc(getEntityId(), true)) { - vpc = _entityMgr.findById(Vpc.class, getEntityId()); + if (isStart()) { + success = _vpcService.startVpc(getEntityId(), true); + } else { + s_logger.debug("Not starting VPC as " + ApiConstants.START + "=false was passed to the API"); } + vpc = _entityMgr.findById(Vpc.class, getEntityId()); } catch (ResourceUnavailableException ex) { s_logger.warn("Exception: ", ex); throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage()); diff --git a/api/src/org/apache/cloudstack/api/command/admin/vpc/CreateVPCOfferingCmd.java b/api/src/org/apache/cloudstack/api/command/admin/vpc/CreateVPCOfferingCmd.java index 5b3090bd75..13e4c0e04b 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/vpc/CreateVPCOfferingCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/vpc/CreateVPCOfferingCmd.java @@ -43,7 +43,7 @@ requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class CreateVPCOfferingCmd extends BaseAsyncCreateCmd { public static final Logger s_logger = Logger.getLogger(CreateVPCOfferingCmd.class.getName()); - private static final String Name = "createvpcofferingresponse"; + private static final String s_name = "createvpcofferingresponse"; ///////////////////////////////////////////////////// //////////////// API parameters ///////////////////// @@ -66,7 +66,7 @@ public class CreateVPCOfferingCmd extends BaseAsyncCreateCmd { + "If not specified, the provider for the service will be mapped to the default provider on the physical network") private Map serviceProviderList; - @Parameter(name = ApiConstants.SERVICE_CAPABILITY_LIST, type = CommandType.MAP, description = "desired service capabilities as part of vpc offering") + @Parameter(name = ApiConstants.SERVICE_CAPABILITY_LIST, type = CommandType.MAP, description = "desired service capabilities as part of vpc offering", since = "4.4") private Map serviceCapabilitystList; @Parameter(name = ApiConstants.SERVICE_OFFERING_ID, @@ -159,7 +159,7 @@ public String getEventDescription() { @Override public String getCommandName() { - return Name; + return s_name; } @Override diff --git a/api/src/org/apache/cloudstack/api/command/admin/vpc/DeletePrivateGatewayCmd.java b/api/src/org/apache/cloudstack/api/command/admin/vpc/DeletePrivateGatewayCmd.java index dcce58e227..8d67a4ed8c 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/vpc/DeletePrivateGatewayCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/vpc/DeletePrivateGatewayCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiCommandJobType; import org.apache.cloudstack.api.ApiConstants; @@ -37,7 +36,7 @@ import com.cloud.network.vpc.VpcGateway; import com.cloud.user.Account; -@APICommand(name = "deletePrivateGateway", description = "Deletes a Private gateway", responseObject = SuccessResponse.class, entityType = {IAMEntityType.PrivateGateway}, +@APICommand(name = "deletePrivateGateway", description = "Deletes a Private gateway", responseObject = SuccessResponse.class, entityType = {VpcGateway.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class DeletePrivateGatewayCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(DeletePrivateGatewayCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/admin/vpc/UpdateVPCOfferingCmd.java b/api/src/org/apache/cloudstack/api/command/admin/vpc/UpdateVPCOfferingCmd.java index 8b05a7a5a2..5af47d3a4c 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/vpc/UpdateVPCOfferingCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/vpc/UpdateVPCOfferingCmd.java @@ -34,7 +34,7 @@ requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class UpdateVPCOfferingCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(UpdateVPCOfferingCmd.class.getName()); - private static final String Name = "updatevpcofferingresponse"; + private static final String s_name = "updatevpcofferingresponse"; ///////////////////////////////////////////////////// //////////////// API parameters ///////////////////// @@ -77,7 +77,7 @@ public String getState() { ///////////////////////////////////////////////////// @Override public String getCommandName() { - return Name; + return s_name; } @Override diff --git a/api/src/org/apache/cloudstack/api/command/user/account/ListAccountsCmd.java b/api/src/org/apache/cloudstack/api/command/user/account/ListAccountsCmd.java index 65331e4c4a..0b5ae7c0ba 100644 --- a/api/src/org/apache/cloudstack/api/command/user/account/ListAccountsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/account/ListAccountsCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseListDomainResourcesCmd; @@ -27,7 +26,9 @@ import org.apache.cloudstack.api.response.AccountResponse; import org.apache.cloudstack.api.response.ListResponse; -@APICommand(name = "listAccounts", description = "Lists accounts and provides detailed account information for listed accounts", responseObject = AccountResponse.class, responseView = ResponseView.Restricted, entityType = {IAMEntityType.Account}, +import com.cloud.user.Account; + +@APICommand(name = "listAccounts", description = "Lists accounts and provides detailed account information for listed accounts", responseObject = AccountResponse.class, responseView = ResponseView.Restricted, entityType = {Account.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = true) public class ListAccountsCmd extends BaseListDomainResourcesCmd { public static final Logger s_logger = Logger.getLogger(ListAccountsCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/address/AssociateIPAddrCmd.java b/api/src/org/apache/cloudstack/api/command/user/address/AssociateIPAddrCmd.java index 3f0d2467bf..96174e1237 100644 --- a/api/src/org/apache/cloudstack/api/command/user/address/AssociateIPAddrCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/address/AssociateIPAddrCmd.java @@ -201,10 +201,19 @@ public Long getNetworkId() { } } + @Deprecated public Boolean getDisplayIp() { return display; } + @Override + public boolean isDisplay() { + if(display == null) + return true; + else + return display; + } + @Override public long getEntityOwnerId() { Account caller = CallContext.current().getCallingAccount(); diff --git a/api/src/org/apache/cloudstack/api/command/user/address/DisassociateIPAddrCmd.java b/api/src/org/apache/cloudstack/api/command/user/address/DisassociateIPAddrCmd.java index 269fcb552b..ba4184434e 100644 --- a/api/src/org/apache/cloudstack/api/command/user/address/DisassociateIPAddrCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/address/DisassociateIPAddrCmd.java @@ -37,7 +37,7 @@ import com.cloud.user.Account; @APICommand(name = "disassociateIpAddress", description = "Disassociates an ip address from the account.", responseObject = SuccessResponse.class, - requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) + requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, entityType = { IpAddress.class }) public class DisassociateIPAddrCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(DisassociateIPAddrCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/address/ListPublicIpAddressesCmd.java b/api/src/org/apache/cloudstack/api/command/user/address/ListPublicIpAddressesCmd.java index 321871380d..07ccfe9918 100644 --- a/api/src/org/apache/cloudstack/api/command/user/address/ListPublicIpAddressesCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/address/ListPublicIpAddressesCmd.java @@ -40,7 +40,7 @@ import com.cloud.utils.Pair; @APICommand(name = "listPublicIpAddresses", description = "Lists all public ip addresses", responseObject = IPAddressResponse.class, responseView = ResponseView.Restricted, - requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) + requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, entityType = { IpAddress.class }) public class ListPublicIpAddressesCmd extends BaseListTaggedResourcesCmd { public static final Logger s_logger = Logger.getLogger(ListPublicIpAddressesCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/address/UpdateIPAddrCmd.java b/api/src/org/apache/cloudstack/api/command/user/address/UpdateIPAddrCmd.java index cc736d0d64..c64b6411c5 100644 --- a/api/src/org/apache/cloudstack/api/command/user/address/UpdateIPAddrCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/address/UpdateIPAddrCmd.java @@ -38,8 +38,8 @@ import com.cloud.network.IpAddress; import com.cloud.user.Account; -@APICommand(name = "updatePublicIpAddress", description = "Updates an ip address", responseObject = IPAddressResponse.class, - requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) +@APICommand(name = "updateIpAddress", description = "Updates an ip address", responseObject = IPAddressResponse.class, + requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, entityType = { IpAddress.class }) public class UpdateIPAddrCmd extends BaseAsyncCustomIdCmd { public static final Logger s_logger = Logger.getLogger(UpdateIPAddrCmd.class.getName()); private static final String s_name = "updateipaddressresponse"; diff --git a/api/src/org/apache/cloudstack/api/command/user/affinitygroup/CreateAffinityGroupCmd.java b/api/src/org/apache/cloudstack/api/command/user/affinitygroup/CreateAffinityGroupCmd.java index 50573e9683..96d8bec96d 100644 --- a/api/src/org/apache/cloudstack/api/command/user/affinitygroup/CreateAffinityGroupCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/affinitygroup/CreateAffinityGroupCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.affinity.AffinityGroup; import org.apache.cloudstack.affinity.AffinityGroupResponse; import org.apache.cloudstack.api.APICommand; @@ -35,7 +34,7 @@ import com.cloud.exception.ResourceAllocationException; import com.cloud.user.Account; -@APICommand(name = "createAffinityGroup", responseObject = AffinityGroupResponse.class, description = "Creates an affinity/anti-affinity group", entityType = {IAMEntityType.AffinityGroup}, +@APICommand(name = "createAffinityGroup", responseObject = AffinityGroupResponse.class, description = "Creates an affinity/anti-affinity group", entityType = {AffinityGroup.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class CreateAffinityGroupCmd extends BaseAsyncCreateCmd { public static final Logger s_logger = Logger.getLogger(CreateAffinityGroupCmd.class.getName()); @@ -103,7 +102,7 @@ public String getCommandName() { @Override public long getEntityOwnerId() { Account account = CallContext.current().getCallingAccount(); - if ((account == null) || _accountService.isAdmin(account.getType())) { + if ((account == null) || _accountService.isAdmin(account.getId())) { if ((domainId != null) && (accountName != null)) { Account userAccount = _responseGenerator.findAccountByNameDomain(accountName, domainId); if (userAccount != null) { diff --git a/api/src/org/apache/cloudstack/api/command/user/affinitygroup/DeleteAffinityGroupCmd.java b/api/src/org/apache/cloudstack/api/command/user/affinitygroup/DeleteAffinityGroupCmd.java index 378a826ef8..21c2fa86d0 100644 --- a/api/src/org/apache/cloudstack/api/command/user/affinitygroup/DeleteAffinityGroupCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/affinitygroup/DeleteAffinityGroupCmd.java @@ -19,8 +19,8 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; +import org.apache.cloudstack.affinity.AffinityGroup; import org.apache.cloudstack.affinity.AffinityGroupResponse; import org.apache.cloudstack.api.ACL; import org.apache.cloudstack.api.APICommand; @@ -38,7 +38,7 @@ import com.cloud.exception.InvalidParameterValueException; import com.cloud.user.Account; -@APICommand(name = "deleteAffinityGroup", description = "Deletes affinity group", responseObject = SuccessResponse.class, entityType = {IAMEntityType.AffinityGroup}, +@APICommand(name = "deleteAffinityGroup", description = "Deletes affinity group", responseObject = SuccessResponse.class, entityType = {AffinityGroup.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class DeleteAffinityGroupCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(DeleteAffinityGroupCmd.class.getName()); @@ -110,7 +110,7 @@ public String getCommandName() { @Override public long getEntityOwnerId() { Account account = CallContext.current().getCallingAccount(); - if ((account == null) || _accountService.isAdmin(account.getType())) { + if ((account == null) || _accountService.isAdmin(account.getId())) { if ((domainId != null) && (accountName != null)) { Account userAccount = _responseGenerator.findAccountByNameDomain(accountName, domainId); if (userAccount != null) { diff --git a/api/src/org/apache/cloudstack/api/command/user/affinitygroup/ListAffinityGroupsCmd.java b/api/src/org/apache/cloudstack/api/command/user/affinitygroup/ListAffinityGroupsCmd.java index e469eab2c1..6313c4812e 100644 --- a/api/src/org/apache/cloudstack/api/command/user/affinitygroup/ListAffinityGroupsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/affinitygroup/ListAffinityGroupsCmd.java @@ -18,7 +18,7 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; +import org.apache.cloudstack.affinity.AffinityGroup; import org.apache.cloudstack.affinity.AffinityGroupResponse; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiCommandJobType; @@ -28,7 +28,7 @@ import org.apache.cloudstack.api.response.ListResponse; import org.apache.cloudstack.api.response.UserVmResponse; -@APICommand(name = "listAffinityGroups", description = "Lists affinity groups", responseObject = AffinityGroupResponse.class, entityType = {IAMEntityType.AffinityGroup}, +@APICommand(name = "listAffinityGroups", description = "Lists affinity groups", responseObject = AffinityGroupResponse.class, entityType = {AffinityGroup.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class ListAffinityGroupsCmd extends BaseListAccountResourcesCmd { public static final Logger s_logger = Logger.getLogger(ListAffinityGroupsCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/affinitygroup/UpdateVMAffinityGroupCmd.java b/api/src/org/apache/cloudstack/api/command/user/affinitygroup/UpdateVMAffinityGroupCmd.java index 4bfcddb3a6..66201477b9 100644 --- a/api/src/org/apache/cloudstack/api/command/user/affinitygroup/UpdateVMAffinityGroupCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/affinitygroup/UpdateVMAffinityGroupCmd.java @@ -22,7 +22,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.affinity.AffinityGroupResponse; import org.apache.cloudstack.api.ACL; @@ -44,13 +43,14 @@ import com.cloud.exception.ResourceUnavailableException; import com.cloud.user.Account; import com.cloud.uservm.UserVm; +import com.cloud.vm.VirtualMachine; @APICommand(name = "updateVMAffinityGroup", description = "Updates the affinity/anti-affinity group associations of a virtual machine. The VM has to be stopped and restarted for the " + "new properties to take effect.", responseObject = UserVmResponse.class, responseView = ResponseView.Restricted, - entityType = {IAMEntityType.VirtualMachine}, + entityType = {VirtualMachine.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = true) public class UpdateVMAffinityGroupCmd extends BaseAsyncCmd { diff --git a/api/src/org/apache/cloudstack/api/command/user/autoscale/CreateAutoScalePolicyCmd.java b/api/src/org/apache/cloudstack/api/command/user/autoscale/CreateAutoScalePolicyCmd.java index 8b5708d072..4541efa798 100644 --- a/api/src/org/apache/cloudstack/api/command/user/autoscale/CreateAutoScalePolicyCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/autoscale/CreateAutoScalePolicyCmd.java @@ -20,7 +20,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiCommandJobType; import org.apache.cloudstack.api.ApiConstants; @@ -40,7 +39,7 @@ @APICommand(name = "createAutoScalePolicy", description = "Creates an autoscale policy for a provision or deprovision action, the action is taken when the all the conditions evaluates to true for the specified duration. The policy is in effect once it is attached to a autscale vm group.", - responseObject = AutoScalePolicyResponse.class, entityType = {IAMEntityType.AutoScalePolicy}, + responseObject = AutoScalePolicyResponse.class, entityType = {AutoScalePolicy.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class CreateAutoScalePolicyCmd extends BaseAsyncCreateCmd { diff --git a/api/src/org/apache/cloudstack/api/command/user/autoscale/CreateAutoScaleVmGroupCmd.java b/api/src/org/apache/cloudstack/api/command/user/autoscale/CreateAutoScaleVmGroupCmd.java index 43a7f18189..0308c1710c 100644 --- a/api/src/org/apache/cloudstack/api/command/user/autoscale/CreateAutoScaleVmGroupCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/autoscale/CreateAutoScaleVmGroupCmd.java @@ -20,7 +20,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiCommandJobType; @@ -42,7 +41,7 @@ @APICommand(name = "createAutoScaleVmGroup", description = "Creates and automatically starts a virtual machine based on a service offering, disk offering, and template.", - responseObject = AutoScaleVmGroupResponse.class, entityType = { IAMEntityType.AutoScaleVmGroup }, + responseObject = AutoScaleVmGroupResponse.class, entityType = {AutoScaleVmGroup.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class CreateAutoScaleVmGroupCmd extends BaseAsyncCreateCmd { @@ -185,10 +184,19 @@ public ApiCommandJobType getInstanceType() { return ApiCommandJobType.AutoScaleVmGroup; } + @Deprecated public Boolean getDisplay() { return display; } + @Override + public boolean isDisplay() { + if(display == null) + return true; + else + return display; + } + @Override public void create() throws ResourceAllocationException { AutoScaleVmGroup result = _autoScaleService.createAutoScaleVmGroup(this); diff --git a/api/src/org/apache/cloudstack/api/command/user/autoscale/CreateAutoScaleVmProfileCmd.java b/api/src/org/apache/cloudstack/api/command/user/autoscale/CreateAutoScaleVmProfileCmd.java index 5d78593832..447085e79b 100644 --- a/api/src/org/apache/cloudstack/api/command/user/autoscale/CreateAutoScaleVmProfileCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/autoscale/CreateAutoScaleVmProfileCmd.java @@ -21,7 +21,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiCommandJobType; @@ -46,7 +45,7 @@ @APICommand(name = "createAutoScaleVmProfile", description = "Creates a profile that contains information about the virtual machine which will be provisioned automatically by autoscale feature.", - responseObject = AutoScaleVmProfileResponse.class, entityType = { IAMEntityType.AutoScaleVmProfile }, + responseObject = AutoScaleVmProfileResponse.class, entityType = {AutoScaleVmProfile.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) @SuppressWarnings("rawtypes") @@ -132,10 +131,19 @@ public Long getTemplateId() { return templateId; } + @Deprecated public Boolean getDisplay() { return display; } + @Override + public boolean isDisplay() { + if(display == null) + return true; + else + return display; + } + public Map getCounterParamList() { return counterParamList; } diff --git a/api/src/org/apache/cloudstack/api/command/user/autoscale/CreateConditionCmd.java b/api/src/org/apache/cloudstack/api/command/user/autoscale/CreateConditionCmd.java index b603a152d5..847866ef3a 100644 --- a/api/src/org/apache/cloudstack/api/command/user/autoscale/CreateConditionCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/autoscale/CreateConditionCmd.java @@ -19,7 +19,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiCommandJobType; import org.apache.cloudstack.api.ApiConstants; @@ -36,7 +35,7 @@ import com.cloud.exception.ResourceAllocationException; import com.cloud.network.as.Condition; -@APICommand(name = "createCondition", description = "Creates a condition", responseObject = ConditionResponse.class, entityType = {IAMEntityType.Condition}, +@APICommand(name = "createCondition", description = "Creates a condition", responseObject = ConditionResponse.class, entityType = {Condition.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class CreateConditionCmd extends BaseAsyncCreateCmd { public static final Logger s_logger = Logger.getLogger(CreateConditionCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/autoscale/DeleteAutoScalePolicyCmd.java b/api/src/org/apache/cloudstack/api/command/user/autoscale/DeleteAutoScalePolicyCmd.java index 779ee0a392..c0a3a00f7d 100644 --- a/api/src/org/apache/cloudstack/api/command/user/autoscale/DeleteAutoScalePolicyCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/autoscale/DeleteAutoScalePolicyCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ACL; import org.apache.cloudstack.api.APICommand; @@ -36,7 +35,7 @@ import com.cloud.network.as.AutoScalePolicy; import com.cloud.user.Account; -@APICommand(name = "deleteAutoScalePolicy", description = "Deletes a autoscale policy.", responseObject = SuccessResponse.class, entityType = {IAMEntityType.AutoScalePolicy}, +@APICommand(name = "deleteAutoScalePolicy", description = "Deletes a autoscale policy.", responseObject = SuccessResponse.class, entityType = {AutoScalePolicy.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class DeleteAutoScalePolicyCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(DeleteAutoScalePolicyCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/autoscale/DeleteAutoScaleVmGroupCmd.java b/api/src/org/apache/cloudstack/api/command/user/autoscale/DeleteAutoScaleVmGroupCmd.java index 5a43abe866..a9d2f4e232 100644 --- a/api/src/org/apache/cloudstack/api/command/user/autoscale/DeleteAutoScaleVmGroupCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/autoscale/DeleteAutoScaleVmGroupCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ACL; import org.apache.cloudstack.api.APICommand; @@ -36,7 +35,7 @@ import com.cloud.network.as.AutoScaleVmGroup; import com.cloud.user.Account; -@APICommand(name = "deleteAutoScaleVmGroup", description = "Deletes a autoscale vm group.", responseObject = SuccessResponse.class, entityType = {IAMEntityType.AutoScaleVmGroup}, +@APICommand(name = "deleteAutoScaleVmGroup", description = "Deletes a autoscale vm group.", responseObject = SuccessResponse.class, entityType = {AutoScaleVmGroup.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class DeleteAutoScaleVmGroupCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(DeleteAutoScaleVmGroupCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/autoscale/DeleteAutoScaleVmProfileCmd.java b/api/src/org/apache/cloudstack/api/command/user/autoscale/DeleteAutoScaleVmProfileCmd.java index 2391a938d8..779315a96d 100644 --- a/api/src/org/apache/cloudstack/api/command/user/autoscale/DeleteAutoScaleVmProfileCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/autoscale/DeleteAutoScaleVmProfileCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ACL; import org.apache.cloudstack.api.APICommand; @@ -36,7 +35,7 @@ import com.cloud.network.as.AutoScaleVmProfile; import com.cloud.user.Account; -@APICommand(name = "deleteAutoScaleVmProfile", description = "Deletes a autoscale vm profile.", responseObject = SuccessResponse.class, entityType = {IAMEntityType.AutoScaleVmProfile}, +@APICommand(name = "deleteAutoScaleVmProfile", description = "Deletes a autoscale vm profile.", responseObject = SuccessResponse.class, entityType = {AutoScaleVmProfile.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class DeleteAutoScaleVmProfileCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(DeleteAutoScaleVmProfileCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/autoscale/DeleteConditionCmd.java b/api/src/org/apache/cloudstack/api/command/user/autoscale/DeleteConditionCmd.java index 9a7d2d7df8..24f4cc6878 100644 --- a/api/src/org/apache/cloudstack/api/command/user/autoscale/DeleteConditionCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/autoscale/DeleteConditionCmd.java @@ -19,7 +19,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ACL; import org.apache.cloudstack.api.APICommand; @@ -37,7 +36,7 @@ import com.cloud.network.as.Condition; import com.cloud.user.Account; -@APICommand(name = "deleteCondition", description = "Removes a condition", responseObject = SuccessResponse.class, entityType = {IAMEntityType.Condition}, +@APICommand(name = "deleteCondition", description = "Removes a condition", responseObject = SuccessResponse.class, entityType = {Condition.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class DeleteConditionCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(DeleteConditionCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/autoscale/DisableAutoScaleVmGroupCmd.java b/api/src/org/apache/cloudstack/api/command/user/autoscale/DisableAutoScaleVmGroupCmd.java index 6575d27ba7..8eb1809f88 100644 --- a/api/src/org/apache/cloudstack/api/command/user/autoscale/DisableAutoScaleVmGroupCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/autoscale/DisableAutoScaleVmGroupCmd.java @@ -19,7 +19,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ACL; import org.apache.cloudstack.api.APICommand; @@ -35,7 +34,7 @@ import com.cloud.network.as.AutoScaleVmGroup; import com.cloud.user.Account; -@APICommand(name = "disableAutoScaleVmGroup", description = "Disables an AutoScale Vm Group", responseObject = AutoScaleVmGroupResponse.class, entityType = {IAMEntityType.AutoScaleVmGroup}, +@APICommand(name = "disableAutoScaleVmGroup", description = "Disables an AutoScale Vm Group", responseObject = AutoScaleVmGroupResponse.class, entityType = {AutoScaleVmGroup.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class DisableAutoScaleVmGroupCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(DisableAutoScaleVmGroupCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/autoscale/EnableAutoScaleVmGroupCmd.java b/api/src/org/apache/cloudstack/api/command/user/autoscale/EnableAutoScaleVmGroupCmd.java index 6b9f2c3ac0..59c9f7a9aa 100644 --- a/api/src/org/apache/cloudstack/api/command/user/autoscale/EnableAutoScaleVmGroupCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/autoscale/EnableAutoScaleVmGroupCmd.java @@ -19,7 +19,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ACL; import org.apache.cloudstack.api.APICommand; @@ -35,7 +34,7 @@ import com.cloud.network.as.AutoScaleVmGroup; import com.cloud.user.Account; -@APICommand(name = "enableAutoScaleVmGroup", description = "Enables an AutoScale Vm Group", responseObject = AutoScaleVmGroupResponse.class, entityType = {IAMEntityType.AutoScaleVmGroup}, +@APICommand(name = "enableAutoScaleVmGroup", description = "Enables an AutoScale Vm Group", responseObject = AutoScaleVmGroupResponse.class, entityType = {AutoScaleVmGroup.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class EnableAutoScaleVmGroupCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(EnableAutoScaleVmGroupCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/autoscale/ListAutoScalePoliciesCmd.java b/api/src/org/apache/cloudstack/api/command/user/autoscale/ListAutoScalePoliciesCmd.java index 43c4c72a80..c2b244f2a7 100644 --- a/api/src/org/apache/cloudstack/api/command/user/autoscale/ListAutoScalePoliciesCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/autoscale/ListAutoScalePoliciesCmd.java @@ -21,7 +21,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseListAccountResourcesCmd; @@ -33,7 +32,7 @@ import com.cloud.network.as.AutoScalePolicy; -@APICommand(name = "listAutoScalePolicies", description = "Lists autoscale policies.", responseObject = AutoScalePolicyResponse.class, entityType = {IAMEntityType.AutoScalePolicy}, +@APICommand(name = "listAutoScalePolicies", description = "Lists autoscale policies.", responseObject = AutoScalePolicyResponse.class, entityType = {AutoScalePolicy.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class ListAutoScalePoliciesCmd extends BaseListAccountResourcesCmd { public static final Logger s_logger = Logger.getLogger(ListAutoScalePoliciesCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/autoscale/ListAutoScaleVmGroupsCmd.java b/api/src/org/apache/cloudstack/api/command/user/autoscale/ListAutoScaleVmGroupsCmd.java index 2e88c27b7d..37c90b9bfd 100644 --- a/api/src/org/apache/cloudstack/api/command/user/autoscale/ListAutoScaleVmGroupsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/autoscale/ListAutoScaleVmGroupsCmd.java @@ -21,7 +21,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; @@ -37,7 +36,7 @@ import com.cloud.exception.InvalidParameterValueException; import com.cloud.network.as.AutoScaleVmGroup; -@APICommand(name = "listAutoScaleVmGroups", description = "Lists autoscale vm groups.", responseObject = AutoScaleVmGroupResponse.class, entityType = { IAMEntityType.AutoScaleVmGroup }, +@APICommand(name = "listAutoScaleVmGroups", description = "Lists autoscale vm groups.", responseObject = AutoScaleVmGroupResponse.class, entityType = {AutoScaleVmGroup.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class ListAutoScaleVmGroupsCmd extends BaseListProjectAndAccountResourcesCmd { public static final Logger s_logger = Logger.getLogger(ListAutoScaleVmGroupsCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/autoscale/ListAutoScaleVmProfilesCmd.java b/api/src/org/apache/cloudstack/api/command/user/autoscale/ListAutoScaleVmProfilesCmd.java index 94f0eee7f5..554b48854a 100644 --- a/api/src/org/apache/cloudstack/api/command/user/autoscale/ListAutoScaleVmProfilesCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/autoscale/ListAutoScaleVmProfilesCmd.java @@ -21,7 +21,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; @@ -35,7 +34,7 @@ import com.cloud.network.as.AutoScaleVmProfile; -@APICommand(name = "listAutoScaleVmProfiles", description = "Lists autoscale vm profiles.", responseObject = AutoScaleVmProfileResponse.class, entityType = { IAMEntityType.AutoScaleVmProfile }, +@APICommand(name = "listAutoScaleVmProfiles", description = "Lists autoscale vm profiles.", responseObject = AutoScaleVmProfileResponse.class, entityType = {AutoScaleVmProfile.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class ListAutoScaleVmProfilesCmd extends BaseListProjectAndAccountResourcesCmd { public static final Logger s_logger = Logger.getLogger(ListAutoScaleVmProfilesCmd.class.getName()); @@ -52,7 +51,7 @@ public class ListAutoScaleVmProfilesCmd extends BaseListProjectAndAccountResourc @Parameter(name = ApiConstants.TEMPLATE_ID, type = CommandType.UUID, entityType = TemplateResponse.class, description = "the templateid of the autoscale vm profile") private Long templateId; - @Parameter(name = ApiConstants.SERVICE_OFFERING_ID, type = CommandType.UUID, entityType = ServiceOfferingResponse.class, description = "list profiles by service offering id") + @Parameter(name = ApiConstants.SERVICE_OFFERING_ID, type = CommandType.UUID, entityType = ServiceOfferingResponse.class, description = "list profiles by service offering id", since = "4.4") private Long serviceOffId; @Parameter(name = ApiConstants.OTHER_DEPLOY_PARAMS, type = CommandType.STRING, description = "the otherdeployparameters of the autoscale vm profile") diff --git a/api/src/org/apache/cloudstack/api/command/user/autoscale/UpdateAutoScalePolicyCmd.java b/api/src/org/apache/cloudstack/api/command/user/autoscale/UpdateAutoScalePolicyCmd.java index 8cd7211a2f..24858f4656 100644 --- a/api/src/org/apache/cloudstack/api/command/user/autoscale/UpdateAutoScalePolicyCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/autoscale/UpdateAutoScalePolicyCmd.java @@ -21,7 +21,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ACL; import org.apache.cloudstack.api.APICommand; @@ -39,7 +38,7 @@ import com.cloud.network.as.AutoScalePolicy; import com.cloud.user.Account; -@APICommand(name = "updateAutoScalePolicy", description = "Updates an existing autoscale policy.", responseObject = AutoScalePolicyResponse.class, entityType = {IAMEntityType.AutoScalePolicy}, +@APICommand(name = "updateAutoScalePolicy", description = "Updates an existing autoscale policy.", responseObject = AutoScalePolicyResponse.class, entityType = {AutoScalePolicy.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class UpdateAutoScalePolicyCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(UpdateAutoScalePolicyCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/autoscale/UpdateAutoScaleVmGroupCmd.java b/api/src/org/apache/cloudstack/api/command/user/autoscale/UpdateAutoScaleVmGroupCmd.java index 60ea51efc9..76fa3d75d1 100644 --- a/api/src/org/apache/cloudstack/api/command/user/autoscale/UpdateAutoScaleVmGroupCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/autoscale/UpdateAutoScaleVmGroupCmd.java @@ -21,7 +21,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ACL; @@ -40,7 +39,7 @@ import com.cloud.network.as.AutoScaleVmGroup; import com.cloud.user.Account; -@APICommand(name = "updateAutoScaleVmGroup", description = "Updates an existing autoscale vm group.", responseObject = AutoScaleVmGroupResponse.class, entityType = { IAMEntityType.AutoScaleVmGroup }, +@APICommand(name = "updateAutoScaleVmGroup", description = "Updates an existing autoscale vm group.", responseObject = AutoScaleVmGroupResponse.class, entityType = {AutoScaleVmGroup.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class UpdateAutoScaleVmGroupCmd extends BaseAsyncCustomIdCmd { public static final Logger s_logger = Logger.getLogger(UpdateAutoScaleVmGroupCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/autoscale/UpdateAutoScaleVmProfileCmd.java b/api/src/org/apache/cloudstack/api/command/user/autoscale/UpdateAutoScaleVmProfileCmd.java index 54e34da196..deebe2ecc9 100644 --- a/api/src/org/apache/cloudstack/api/command/user/autoscale/UpdateAutoScaleVmProfileCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/autoscale/UpdateAutoScaleVmProfileCmd.java @@ -21,7 +21,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ACL; @@ -41,7 +40,7 @@ import com.cloud.network.as.AutoScaleVmProfile; import com.cloud.user.Account; -@APICommand(name = "updateAutoScaleVmProfile", description = "Updates an existing autoscale vm profile.", responseObject = AutoScaleVmProfileResponse.class, entityType = { IAMEntityType.AutoScaleVmProfile }, +@APICommand(name = "updateAutoScaleVmProfile", description = "Updates an existing autoscale vm profile.", responseObject = AutoScaleVmProfileResponse.class, entityType = {AutoScaleVmProfile.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class UpdateAutoScaleVmProfileCmd extends BaseAsyncCustomIdCmd { public static final Logger s_logger = Logger.getLogger(UpdateAutoScaleVmProfileCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/config/ListCapabilitiesCmd.java b/api/src/org/apache/cloudstack/api/command/user/config/ListCapabilitiesCmd.java index d47645b956..e6696e17ff 100644 --- a/api/src/org/apache/cloudstack/api/command/user/config/ListCapabilitiesCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/config/ListCapabilitiesCmd.java @@ -53,6 +53,7 @@ public void execute() { response.setSupportELB((String)capabilities.get("supportELB")); response.setProjectInviteRequired((Boolean)capabilities.get("projectInviteRequired")); response.setAllowUsersCreateProjects((Boolean)capabilities.get("allowusercreateprojects")); + response.setDiskOffMinSize((Long)capabilities.get("customDiskOffMinSize")); response.setDiskOffMaxSize((Long)capabilities.get("customDiskOffMaxSize")); response.setRegionSecondaryEnabled((Boolean)capabilities.get("regionSecondaryEnabled")); response.setKVMSnapshotEnabled((Boolean)capabilities.get("KVMSnapshotEnabled")); diff --git a/api/src/org/apache/cloudstack/api/command/user/event/ArchiveEventsCmd.java b/api/src/org/apache/cloudstack/api/command/user/event/ArchiveEventsCmd.java index 8ff2c3e445..e4970d6530 100644 --- a/api/src/org/apache/cloudstack/api/command/user/event/ArchiveEventsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/event/ArchiveEventsCmd.java @@ -21,7 +21,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.ApiErrorCode; @@ -32,10 +31,11 @@ import org.apache.cloudstack.api.response.SuccessResponse; import org.apache.cloudstack.context.CallContext; +import com.cloud.event.Event; import com.cloud.exception.InvalidParameterValueException; import com.cloud.user.Account; -@APICommand(name = "archiveEvents", description = "Archive one or more events.", responseObject = SuccessResponse.class, entityType = {IAMEntityType.Event}, +@APICommand(name = "archiveEvents", description = "Archive one or more events.", responseObject = SuccessResponse.class, entityType = {Event.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class ArchiveEventsCmd extends BaseCmd { diff --git a/api/src/org/apache/cloudstack/api/command/user/event/DeleteEventsCmd.java b/api/src/org/apache/cloudstack/api/command/user/event/DeleteEventsCmd.java index 10c1c0c860..defb009696 100644 --- a/api/src/org/apache/cloudstack/api/command/user/event/DeleteEventsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/event/DeleteEventsCmd.java @@ -21,7 +21,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.ApiErrorCode; @@ -32,10 +31,11 @@ import org.apache.cloudstack.api.response.SuccessResponse; import org.apache.cloudstack.context.CallContext; +import com.cloud.event.Event; import com.cloud.exception.InvalidParameterValueException; import com.cloud.user.Account; -@APICommand(name = "deleteEvents", description = "Delete one or more events.", responseObject = SuccessResponse.class, entityType = {IAMEntityType.Event}, +@APICommand(name = "deleteEvents", description = "Delete one or more events.", responseObject = SuccessResponse.class, entityType = {Event.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class DeleteEventsCmd extends BaseCmd { diff --git a/api/src/org/apache/cloudstack/api/command/user/event/ListEventsCmd.java b/api/src/org/apache/cloudstack/api/command/user/event/ListEventsCmd.java index b420cf1ed2..a4934fa1dd 100644 --- a/api/src/org/apache/cloudstack/api/command/user/event/ListEventsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/event/ListEventsCmd.java @@ -20,7 +20,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseListProjectAndAccountResourcesCmd; @@ -28,7 +27,9 @@ import org.apache.cloudstack.api.response.EventResponse; import org.apache.cloudstack.api.response.ListResponse; -@APICommand(name = "listEvents", description = "A command to list events.", responseObject = EventResponse.class, entityType = {IAMEntityType.Event}, +import com.cloud.event.Event; + +@APICommand(name = "listEvents", description = "A command to list events.", responseObject = EventResponse.class, entityType = {Event.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class ListEventsCmd extends BaseListProjectAndAccountResourcesCmd { public static final Logger s_logger = Logger.getLogger(ListEventsCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/firewall/CreateEgressFirewallRuleCmd.java b/api/src/org/apache/cloudstack/api/command/user/firewall/CreateEgressFirewallRuleCmd.java index 8ef1b89518..90aed5e507 100644 --- a/api/src/org/apache/cloudstack/api/command/user/firewall/CreateEgressFirewallRuleCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/firewall/CreateEgressFirewallRuleCmd.java @@ -22,7 +22,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiCommandJobType; @@ -45,7 +44,7 @@ import com.cloud.user.Account; import com.cloud.utils.net.NetUtils; -@APICommand(name = "createEgressFirewallRule", description = "Creates a egress firewall rule for a given network ", responseObject = FirewallResponse.class, entityType = { IAMEntityType.FirewallRule }, +@APICommand(name = "createEgressFirewallRule", description = "Creates a egress firewall rule for a given network ", responseObject = FirewallResponse.class, entityType = {FirewallRule.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class CreateEgressFirewallRuleCmd extends BaseAsyncCreateCmd implements FirewallRule { public static final Logger s_logger = Logger.getLogger(CreateEgressFirewallRuleCmd.class.getName()); @@ -155,7 +154,7 @@ public void execute() throws ResourceUnavailableException { fwResponse.setResponseName(getCommandName()); } finally { if (!success || rule == null) { - _firewallService.revokeFirewallRule(getEntityId(), true); + _firewallService.revokeEgressFirewallRule(getEntityId(), true); throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create firewall rule"); } } @@ -271,7 +270,7 @@ public void create() { @Override public String getEventType() { - return EventTypes.EVENT_FIREWALL_OPEN; + return EventTypes.EVENT_FIREWALL_EGRESS_OPEN; } @Override @@ -357,8 +356,8 @@ public boolean isDisplay() { } @Override - public IAMEntityType getEntityType() { - return IAMEntityType.FirewallRule; + public Class getEntityType() { + return FirewallRule.class; } } diff --git a/api/src/org/apache/cloudstack/api/command/user/firewall/CreateFirewallRuleCmd.java b/api/src/org/apache/cloudstack/api/command/user/firewall/CreateFirewallRuleCmd.java index 21e680ae62..06669359e8 100644 --- a/api/src/org/apache/cloudstack/api/command/user/firewall/CreateFirewallRuleCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/firewall/CreateFirewallRuleCmd.java @@ -21,7 +21,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiCommandJobType; @@ -44,7 +43,7 @@ import com.cloud.user.Account; import com.cloud.utils.net.NetUtils; -@APICommand(name = "createFirewallRule", description = "Creates a firewall rule for a given ip address", responseObject = FirewallResponse.class, entityType = { IAMEntityType.FirewallRule }, +@APICommand(name = "createFirewallRule", description = "Creates a firewall rule for a given ip address", responseObject = FirewallResponse.class, entityType = {FirewallRule.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class CreateFirewallRuleCmd extends BaseAsyncCreateCmd implements FirewallRule { public static final Logger s_logger = Logger.getLogger(CreateFirewallRuleCmd.class.getName()); @@ -135,7 +134,7 @@ public void execute() throws ResourceUnavailableException { FirewallRule rule = _entityMgr.findById(FirewallRule.class, getEntityId()); try { CallContext.current().setEventDetails("Rule Id: " + getEntityId()); - success = _firewallService.applyIngressFirewallRules(rule.getSourceIpAddressId(), callerContext.getCallingAccount()); + success = _firewallService.applyIngressFwRules(rule.getSourceIpAddressId(), callerContext.getCallingAccount()); // State is different after the rule is applied, so get new object here rule = _entityMgr.findById(FirewallRule.class, getEntityId()); @@ -147,7 +146,7 @@ public void execute() throws ResourceUnavailableException { fwResponse.setResponseName(getCommandName()); } finally { if (!success || rule == null) { - _firewallService.revokeFirewallRule(getEntityId(), true); + _firewallService.revokeIngressFwRule(getEntityId(), true); throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create firewall rule"); } } @@ -350,8 +349,8 @@ public boolean isDisplay() { } @Override - public IAMEntityType getEntityType() { - return IAMEntityType.FirewallRule; + public Class getEntityType() { + return FirewallRule.class; } } diff --git a/api/src/org/apache/cloudstack/api/command/user/firewall/CreatePortForwardingRuleCmd.java b/api/src/org/apache/cloudstack/api/command/user/firewall/CreatePortForwardingRuleCmd.java index 7328374f5c..865cd1b764 100644 --- a/api/src/org/apache/cloudstack/api/command/user/firewall/CreatePortForwardingRuleCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/firewall/CreatePortForwardingRuleCmd.java @@ -20,8 +20,9 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.RoleType; +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; @@ -41,12 +42,16 @@ import com.cloud.exception.NetworkRuleConflictException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.IpAddress; +import com.cloud.network.rules.FirewallRule; import com.cloud.network.rules.PortForwardingRule; import com.cloud.user.Account; import com.cloud.utils.net.Ip; import com.cloud.utils.net.NetUtils; +import com.cloud.vm.VirtualMachine; -@APICommand(name = "createPortForwardingRule", description = "Creates a port forwarding rule", responseObject = FirewallRuleResponse.class, entityType = { IAMEntityType.PortForwardingRule }, + +@APICommand(name = "createPortForwardingRule", description = "Creates a port forwarding rule", responseObject = FirewallRuleResponse.class, entityType = {FirewallRule.class, + VirtualMachine.class, IpAddress.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class CreatePortForwardingRuleCmd extends BaseAsyncCreateCmd implements PortForwardingRule { public static final Logger s_logger = Logger.getLogger(CreatePortForwardingRuleCmd.class.getName()); @@ -57,6 +62,7 @@ public class CreatePortForwardingRuleCmd extends BaseAsyncCreateCmd implements P // ////////////// API parameters ///////////////////// // /////////////////////////////////////////////////// + @ACL(accessType = AccessType.OperateEntry) @Parameter(name = ApiConstants.IP_ADDRESS_ID, type = CommandType.UUID, entityType = IPAddressResponse.class, @@ -94,6 +100,7 @@ public class CreatePortForwardingRuleCmd extends BaseAsyncCreateCmd implements P description = "the ending port of port forwarding rule's private port range") private Integer publicEndPort; + @ACL(accessType = AccessType.OperateEntry) @Parameter(name = ApiConstants.VIRTUAL_MACHINE_ID, type = CommandType.UUID, entityType = UserVmResponse.class, @@ -432,8 +439,8 @@ public boolean isDisplay() { } @Override - public IAMEntityType getEntityType() { - return IAMEntityType.FirewallRule; + public Class getEntityType() { + return FirewallRule.class; } } diff --git a/api/src/org/apache/cloudstack/api/command/user/firewall/DeleteEgressFirewallRuleCmd.java b/api/src/org/apache/cloudstack/api/command/user/firewall/DeleteEgressFirewallRuleCmd.java index ebed335ba3..17968fce58 100644 --- a/api/src/org/apache/cloudstack/api/command/user/firewall/DeleteEgressFirewallRuleCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/firewall/DeleteEgressFirewallRuleCmd.java @@ -19,7 +19,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ACL; import org.apache.cloudstack.api.APICommand; @@ -39,7 +38,7 @@ import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.rules.FirewallRule; -@APICommand(name = "deleteEgressFirewallRule", description = "Deletes an ggress firewall rule", responseObject = SuccessResponse.class, entityType = {IAMEntityType.FirewallRule}, +@APICommand(name = "deleteEgressFirewallRule", description = "Deletes an ggress firewall rule", responseObject = SuccessResponse.class, entityType = {FirewallRule.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class DeleteEgressFirewallRuleCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(DeleteEgressFirewallRuleCmd.class.getName()); @@ -75,7 +74,7 @@ public String getCommandName() { @Override public String getEventType() { - return EventTypes.EVENT_FIREWALL_CLOSE; + return EventTypes.EVENT_FIREWALL_EGRESS_CLOSE; } @Override @@ -99,7 +98,7 @@ public long getEntityOwnerId() { @Override public void execute() throws ResourceUnavailableException { CallContext.current().setEventDetails("Rule Id: " + id); - boolean result = _firewallService.revokeFirewallRule(id, true); + boolean result = _firewallService.revokeEgressFirewallRule(id, true); if (result) { SuccessResponse response = new SuccessResponse(getCommandName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/firewall/DeleteFirewallRuleCmd.java b/api/src/org/apache/cloudstack/api/command/user/firewall/DeleteFirewallRuleCmd.java index 3f61e640c8..f8d1c18329 100644 --- a/api/src/org/apache/cloudstack/api/command/user/firewall/DeleteFirewallRuleCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/firewall/DeleteFirewallRuleCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ACL; import org.apache.cloudstack.api.APICommand; @@ -38,7 +37,7 @@ import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.rules.FirewallRule; -@APICommand(name = "deleteFirewallRule", description = "Deletes a firewall rule", responseObject = SuccessResponse.class, entityType = {IAMEntityType.FirewallRule}, +@APICommand(name = "deleteFirewallRule", description = "Deletes a firewall rule", responseObject = SuccessResponse.class, entityType = {FirewallRule.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class DeleteFirewallRuleCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(DeleteFirewallRuleCmd.class.getName()); @@ -97,7 +96,7 @@ public long getEntityOwnerId() { @Override public void execute() throws ResourceUnavailableException { CallContext.current().setEventDetails("Rule Id: " + id); - boolean result = _firewallService.revokeFirewallRule(id, true); + boolean result = _firewallService.revokeIngressFwRule(id, true); if (result) { SuccessResponse response = new SuccessResponse(getCommandName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/firewall/DeletePortForwardingRuleCmd.java b/api/src/org/apache/cloudstack/api/command/user/firewall/DeletePortForwardingRuleCmd.java index 551885d017..4c7b07f14f 100644 --- a/api/src/org/apache/cloudstack/api/command/user/firewall/DeletePortForwardingRuleCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/firewall/DeletePortForwardingRuleCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ACL; import org.apache.cloudstack.api.APICommand; @@ -37,7 +36,7 @@ import com.cloud.exception.InvalidParameterValueException; import com.cloud.network.rules.PortForwardingRule; -@APICommand(name = "deletePortForwardingRule", description = "Deletes a port forwarding rule", responseObject = SuccessResponse.class, entityType = {IAMEntityType.PortForwardingRule}, +@APICommand(name = "deletePortForwardingRule", description = "Deletes a port forwarding rule", responseObject = SuccessResponse.class, entityType = {PortForwardingRule.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class DeletePortForwardingRuleCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(DeletePortForwardingRuleCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/firewall/ListEgressFirewallRulesCmd.java b/api/src/org/apache/cloudstack/api/command/user/firewall/ListEgressFirewallRulesCmd.java index ece2201a89..e31496e474 100644 --- a/api/src/org/apache/cloudstack/api/command/user/firewall/ListEgressFirewallRulesCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/firewall/ListEgressFirewallRulesCmd.java @@ -22,7 +22,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.Parameter; @@ -34,7 +33,7 @@ import com.cloud.network.rules.FirewallRule; import com.cloud.utils.Pair; -@APICommand(name = "listEgressFirewallRules", description = "Lists all egress firewall rules for network id.", responseObject = FirewallResponse.class, entityType = { IAMEntityType.FirewallRule }, +@APICommand(name = "listEgressFirewallRules", description = "Lists all egress firewall rules for network id.", responseObject = FirewallResponse.class, entityType = {FirewallRule.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class ListEgressFirewallRulesCmd extends ListFirewallRulesCmd { public static final Logger s_logger = Logger.getLogger(ListEgressFirewallRulesCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/firewall/ListFirewallRulesCmd.java b/api/src/org/apache/cloudstack/api/command/user/firewall/ListFirewallRulesCmd.java index 870f81d914..9c9fbc8397 100644 --- a/api/src/org/apache/cloudstack/api/command/user/firewall/ListFirewallRulesCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/firewall/ListFirewallRulesCmd.java @@ -21,7 +21,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; @@ -36,7 +35,7 @@ import com.cloud.network.rules.FirewallRule; import com.cloud.utils.Pair; -@APICommand(name = "listFirewallRules", description = "Lists all firewall rules for an IP address.", responseObject = FirewallResponse.class, entityType = {IAMEntityType.FirewallRule}, +@APICommand(name = "listFirewallRules", description = "Lists all firewall rules for an IP address.", responseObject = FirewallResponse.class, entityType = {FirewallRule.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class ListFirewallRulesCmd extends BaseListTaggedResourcesCmd { public static final Logger s_logger = Logger.getLogger(ListFirewallRulesCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/firewall/ListPortForwardingRulesCmd.java b/api/src/org/apache/cloudstack/api/command/user/firewall/ListPortForwardingRulesCmd.java index 681da333f0..cde2563f9a 100644 --- a/api/src/org/apache/cloudstack/api/command/user/firewall/ListPortForwardingRulesCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/firewall/ListPortForwardingRulesCmd.java @@ -21,7 +21,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; @@ -35,7 +34,7 @@ import com.cloud.network.rules.PortForwardingRule; import com.cloud.utils.Pair; -@APICommand(name = "listPortForwardingRules", description = "Lists all port forwarding rules for an IP address.", responseObject = FirewallRuleResponse.class, entityType = {IAMEntityType.PortForwardingRule}, +@APICommand(name = "listPortForwardingRules", description = "Lists all port forwarding rules for an IP address.", responseObject = FirewallRuleResponse.class, entityType = {PortForwardingRule.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class ListPortForwardingRulesCmd extends BaseListTaggedResourcesCmd { public static final Logger s_logger = Logger.getLogger(ListPortForwardingRulesCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/firewall/UpdateEgressFirewallRuleCmd.java b/api/src/org/apache/cloudstack/api/command/user/firewall/UpdateEgressFirewallRuleCmd.java index 079539624c..b597a891ba 100644 --- a/api/src/org/apache/cloudstack/api/command/user/firewall/UpdateEgressFirewallRuleCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/firewall/UpdateEgressFirewallRuleCmd.java @@ -78,7 +78,7 @@ public String getCommandName() { @Override public void execute() throws ResourceUnavailableException { CallContext.current().setEventDetails("Rule Id: " + id); - FirewallRule rule = _firewallService.updateFirewallRule(id, this.getCustomId(), getDisplay()); + FirewallRule rule = _firewallService.updateEgressFirewallRule(id, this.getCustomId(), getDisplay()); FirewallResponse fwResponse = new FirewallResponse(); if (rule != null) { @@ -97,7 +97,7 @@ public void checkUuid() { @Override public String getEventType() { - return EventTypes.EVENT_FIREWALL_UPDATE; + return EventTypes.EVENT_FIREWALL_EGRESS_UPDATE; } diff --git a/api/src/org/apache/cloudstack/api/command/user/firewall/UpdateFirewallRuleCmd.java b/api/src/org/apache/cloudstack/api/command/user/firewall/UpdateFirewallRuleCmd.java index f68437192b..e9c87d0163 100644 --- a/api/src/org/apache/cloudstack/api/command/user/firewall/UpdateFirewallRuleCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/firewall/UpdateFirewallRuleCmd.java @@ -79,7 +79,7 @@ public String getCommandName() { @Override public void execute() throws ResourceUnavailableException { CallContext.current().setEventDetails("Rule Id: " + id); - FirewallRule rule = _firewallService.updateFirewallRule(id, this.getCustomId(), getDisplay()); + FirewallRule rule = _firewallService.updateIngressFirewallRule(id, this.getCustomId(), getDisplay()); FirewallResponse fwResponse = new FirewallResponse(); if (rule != null) { diff --git a/api/src/org/apache/cloudstack/api/command/user/firewall/UpdatePortForwardingRuleCmd.java b/api/src/org/apache/cloudstack/api/command/user/firewall/UpdatePortForwardingRuleCmd.java index 55b378a21a..eb4d468886 100644 --- a/api/src/org/apache/cloudstack/api/command/user/firewall/UpdatePortForwardingRuleCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/firewall/UpdatePortForwardingRuleCmd.java @@ -16,9 +16,6 @@ // under the License. package org.apache.cloudstack.api.command.user.firewall; -import org.apache.log4j.Logger; - -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; @@ -28,17 +25,17 @@ import org.apache.cloudstack.api.response.FirewallRuleResponse; import org.apache.cloudstack.api.response.IPAddressResponse; import org.apache.cloudstack.api.response.UserVmResponse; +import org.apache.log4j.Logger; import com.cloud.event.EventTypes; import com.cloud.exception.InvalidParameterValueException; -import com.cloud.network.IpAddress; import com.cloud.network.rules.FirewallRule; import com.cloud.network.rules.PortForwardingRule; import com.cloud.user.Account; @APICommand(name = "updatePortForwardingRule", responseObject = FirewallRuleResponse.class, - description = "Updates a port forwarding rule. Only the private port and the virtual machine can be updated.", entityType = {IAMEntityType.PortForwardingRule}, + description = "Updates a port forwarding rule. Only the private port and the virtual machine can be updated.", entityType = {PortForwardingRule.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class UpdatePortForwardingRuleCmd extends BaseAsyncCustomIdCmd { public static final Logger s_logger = Logger.getLogger(UpdatePortForwardingRuleCmd.class.getName()); @@ -47,7 +44,7 @@ public class UpdatePortForwardingRuleCmd extends BaseAsyncCustomIdCmd { ///////////////////////////////////////////////////// //////////////// API parameters ///////////////////// ///////////////////////////////////////////////////// - @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = FirewallRuleResponse.class, required = true, description = "the ID of the port forwarding rule") + @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = FirewallRuleResponse.class, required = true, description = "the ID of the port forwarding rule", since = "4.4") private Long id; @Parameter(name = ApiConstants.PRIVATE_IP, type = CommandType.STRING, description = "the private IP address of the port forwarding rule") @@ -95,10 +92,6 @@ public String getProtocol() { return protocol; } - public Long getPublicIpId() { - return publicIpId; - } - public String getPublicPort() { return publicPort; } @@ -110,11 +103,16 @@ public Long getVirtualMachineId() { public Boolean getDisplay() { return display; } + public Long getId() { + return id; + } ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// + + @Override public String getCommandName() { return s_name; @@ -122,9 +120,9 @@ public String getCommandName() { @Override public long getEntityOwnerId() { - IpAddress addr = _entityMgr.findById(IpAddress.class, getPublicIpId()); - if (addr != null) { - return addr.getAccountId(); + PortForwardingRule rule = _entityMgr.findById(PortForwardingRule.class, getId()); + if (rule != null) { + return rule.getAccountId(); } // bad address given, parent this command to SYSTEM so ERROR events are tracked @@ -174,14 +172,11 @@ public String getSyncObjType() { @Override public Long getSyncObjId() { - return getIp().getAssociatedWithNetworkId(); - } - - private IpAddress getIp() { - IpAddress ip = _networkService.getIp(publicIpId); - if (ip == null) { - throw new InvalidParameterValueException("Unable to find ip address by id " + publicIpId); + PortForwardingRule rule = _entityMgr.findById(PortForwardingRule.class, getId()); + if (rule != null) { + return rule.getNetworkId(); + } else { + throw new InvalidParameterValueException("Unable to find the rule by id"); } - return ip; } } diff --git a/api/src/org/apache/cloudstack/api/command/user/iso/CopyIsoCmd.java b/api/src/org/apache/cloudstack/api/command/user/iso/CopyIsoCmd.java index 21196bcb65..9002624c48 100644 --- a/api/src/org/apache/cloudstack/api/command/user/iso/CopyIsoCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/iso/CopyIsoCmd.java @@ -19,10 +19,11 @@ import org.apache.log4j.Logger; import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.ResponseObject.ResponseView; import org.apache.cloudstack.api.command.user.template.CopyTemplateCmd; import org.apache.cloudstack.api.response.TemplateResponse; -@APICommand(name = "copyIso", description = "Copies an iso from one zone to another.", responseObject = TemplateResponse.class, +@APICommand(name = "copyIso", description = "Copies an iso from one zone to another.", responseObject = TemplateResponse.class, responseView = ResponseView.Restricted, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class CopyIsoCmd extends CopyTemplateCmd { public static final Logger s_logger = Logger.getLogger(CopyIsoCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/iso/ListIsosCmd.java b/api/src/org/apache/cloudstack/api/command/user/iso/ListIsosCmd.java index 3aabf926fc..88e4326c7d 100644 --- a/api/src/org/apache/cloudstack/api/command/user/iso/ListIsosCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/iso/ListIsosCmd.java @@ -121,7 +121,7 @@ public Boolean getShowRemoved() { public boolean listInReadyState() { Account account = CallContext.current().getCallingAccount(); // It is account specific if account is admin type and domainId and accountName are not null - boolean isAccountSpecific = (account == null || _accountService.isAdmin(account.getType())) && (getAccountName() != null) && (getDomainId() != null); + boolean isAccountSpecific = (account == null || _accountService.isAdmin(account.getId())) && (getAccountName() != null) && (getDomainId() != null); // Show only those that are downloaded. TemplateFilter templateFilter = TemplateFilter.valueOf(getIsoFilter()); boolean onlyReady = diff --git a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/AssignToLoadBalancerRuleCmd.java b/api/src/org/apache/cloudstack/api/command/user/loadbalancer/AssignToLoadBalancerRuleCmd.java index 6bd7537827..dd9adefb6c 100644 --- a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/AssignToLoadBalancerRuleCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/loadbalancer/AssignToLoadBalancerRuleCmd.java @@ -16,7 +16,12 @@ // under the License. package org.apache.cloudstack.api.command.user.loadbalancer; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; import java.util.List; +import java.util.Map; import org.apache.log4j.Logger; @@ -36,6 +41,8 @@ import com.cloud.network.rules.LoadBalancer; import com.cloud.user.Account; import com.cloud.utils.StringUtils; +import com.cloud.utils.net.NetUtils; +import com.cloud.vm.VirtualMachine; @APICommand(name = "assignToLoadBalancerRule", description = "Assigns virtual machine or a list of virtual machines to a load balancer rule.", @@ -62,10 +69,15 @@ public class AssignToLoadBalancerRuleCmd extends BaseAsyncCmd { type = CommandType.LIST, collectionType = CommandType.UUID, entityType = UserVmResponse.class, - required = true, description = "the list of IDs of the virtual machine that are being assigned to the load balancer rule(i.e. virtualMachineIds=1,2,3)") private List virtualMachineIds; + @Parameter(name = ApiConstants.VIRTUAL_MACHINE_ID_IP, + type = CommandType.MAP, + description = "VM ID and IP map, vmidipmap[0].vmid=1 vmidipmap[0].ip=10.1.1.75", + since = "4.4") + private Map vmIdIpMap; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -78,6 +90,10 @@ public List getVirtualMachineIds() { return virtualMachineIds; } + public Map getVmIdIpMap() { + return vmIdIpMap; + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// @@ -106,13 +122,54 @@ public String getEventDescription() { return "applying instances for load balancer: " + getLoadBalancerId() + " (ids: " + StringUtils.join(getVirtualMachineIds(), ",") + ")"; } + + public Map> getVmIdIpListMap() { + Map> vmIdIpsMap = new HashMap>(); + if (vmIdIpMap != null && !vmIdIpMap.isEmpty()) { + Collection idIpsCollection = vmIdIpMap.values(); + Iterator iter = idIpsCollection.iterator(); + while (iter.hasNext()) { + HashMap idIpsMap = (HashMap)iter.next(); + String vmId = idIpsMap.get("vmid"); + String vmIp = idIpsMap.get("vmip"); + + VirtualMachine lbvm = _entityMgr.findByUuid(VirtualMachine.class, vmId); + if (lbvm == null) { + throw new InvalidParameterValueException("Unable to find virtual machine ID: " + vmId); + } + + //check wether the given ip is valid ip or not + if (vmIp == null || !NetUtils.isValidIp(vmIp)) { + throw new InvalidParameterValueException("Invalid ip address "+ vmIp +" passed in vmidipmap for " + + "vmid " + vmId); + } + Long longVmId = lbvm.getId(); + + List ipsList = null; + if (vmIdIpsMap.containsKey(longVmId)) { + ipsList = vmIdIpsMap.get(longVmId); + } else { + ipsList = new ArrayList(); + } + ipsList.add(vmIp); + vmIdIpsMap.put(longVmId, ipsList); + + } + } + + return vmIdIpsMap; + } + @Override public void execute() { CallContext.current().setEventDetails("Load balancer Id: " + getLoadBalancerId() + " VmIds: " + StringUtils.join(getVirtualMachineIds(), ",")); - boolean result = _lbService.assignToLoadBalancer(getLoadBalancerId(), virtualMachineIds); + + Map> vmIdIpsMap = getVmIdIpListMap(); + + boolean result = _lbService.assignToLoadBalancer(getLoadBalancerId(), virtualMachineIds, vmIdIpsMap); if (result) { SuccessResponse response = new SuccessResponse(getCommandName()); - this.setResponseObject(response); + setResponseObject(response); } else { throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to assign load balancer rule"); } diff --git a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/CreateLBHealthCheckPolicyCmd.java b/api/src/org/apache/cloudstack/api/command/user/loadbalancer/CreateLBHealthCheckPolicyCmd.java index 547274dc53..f6eb48e800 100644 --- a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/CreateLBHealthCheckPolicyCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/loadbalancer/CreateLBHealthCheckPolicyCmd.java @@ -16,8 +16,7 @@ // under the License. package org.apache.cloudstack.api.command.user.loadbalancer; -import org.apache.log4j.Logger; - +import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.ApiErrorCode; @@ -27,6 +26,7 @@ import org.apache.cloudstack.api.response.FirewallRuleResponse; import org.apache.cloudstack.api.response.LBHealthCheckResponse; import org.apache.cloudstack.context.CallContext; +import org.apache.log4j.Logger; import com.cloud.event.EventTypes; import com.cloud.exception.InvalidParameterValueException; @@ -89,10 +89,27 @@ public class CreateLBHealthCheckPolicyCmd extends BaseAsyncCreateCmd { description = "Number of consecutive health check failures before declaring an instance unhealthy") private int unhealthyThreshold; + @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; + + // /////////////////////////////////////////////////// // ///////////////// Accessors /////////////////////// // /////////////////////////////////////////////////// + @Deprecated + public Boolean getDisplay() { + return display; + } + + @Override + public boolean isDisplay() { + if(display == null) + return true; + else + return display; + } + public Long getLbRuleId() { return lbRuleId; } diff --git a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/CreateLBStickinessPolicyCmd.java b/api/src/org/apache/cloudstack/api/command/user/loadbalancer/CreateLBStickinessPolicyCmd.java index 738f837ccd..152f6612f0 100644 --- a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/CreateLBStickinessPolicyCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/loadbalancer/CreateLBStickinessPolicyCmd.java @@ -18,8 +18,7 @@ import java.util.Map; -import org.apache.log4j.Logger; - +import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.ApiErrorCode; @@ -30,6 +29,7 @@ import org.apache.cloudstack.api.response.FirewallRuleResponse; import org.apache.cloudstack.api.response.LBStickinessResponse; import org.apache.cloudstack.context.CallContext; +import org.apache.log4j.Logger; import com.cloud.event.EventTypes; import com.cloud.exception.InvalidParameterValueException; @@ -74,10 +74,27 @@ public class CreateLBStickinessPolicyCmd extends BaseAsyncCreateCmd { @Parameter(name = ApiConstants.PARAM_LIST, type = CommandType.MAP, description = "param list. Example: param[0].name=cookiename¶m[0].value=LBCookie ") private Map paramList; + @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; + + // /////////////////////////////////////////////////// // ///////////////// Accessors /////////////////////// // /////////////////////////////////////////////////// + @Deprecated + public Boolean getDisplay() { + return display; + } + + @Override + public boolean isDisplay() { + if(display == null) + return true; + else + return display; + } + public Long getLbRuleId() { return lbRuleId; } diff --git a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/CreateLoadBalancerRuleCmd.java b/api/src/org/apache/cloudstack/api/command/user/loadbalancer/CreateLoadBalancerRuleCmd.java index a405913f78..7c371928d9 100644 --- a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/CreateLoadBalancerRuleCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/loadbalancer/CreateLoadBalancerRuleCmd.java @@ -124,8 +124,13 @@ public class CreateLoadBalancerRuleCmd extends BaseAsyncCreateCmd /*implements L /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// - public Boolean getDisplay() { - return display; + @Override + public boolean isDisplay() { + if (display != null) { + return display; + } else { + return true; + } } public String getAlgorithm() { @@ -309,7 +314,7 @@ public void create() { try { LoadBalancer result = _lbService.createPublicLoadBalancerRule(getXid(), getName(), getDescription(), getSourcePortStart(), getSourcePortEnd(), getDefaultPortStart(), - getDefaultPortEnd(), getSourceIpAddressId(), getProtocol(), getAlgorithm(), getNetworkId(), getEntityOwnerId(), getOpenFirewall(), getLbProtocol(), getDisplay()); + getDefaultPortEnd(), getSourceIpAddressId(), getProtocol(), getAlgorithm(), getNetworkId(), getEntityOwnerId(), getOpenFirewall(), getLbProtocol(), isDisplay()); this.setEntityId(result.getId()); this.setEntityUuid(result.getUuid()); } catch (NetworkRuleConflictException e) { diff --git a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/ListLBHealthCheckPoliciesCmd.java b/api/src/org/apache/cloudstack/api/command/user/loadbalancer/ListLBHealthCheckPoliciesCmd.java index 5f4ca09ec9..3f2082af5c 100644 --- a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/ListLBHealthCheckPoliciesCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/loadbalancer/ListLBHealthCheckPoliciesCmd.java @@ -19,8 +19,7 @@ import java.util.ArrayList; import java.util.List; -import org.apache.log4j.Logger; - +import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseListCmd; @@ -28,7 +27,10 @@ import org.apache.cloudstack.api.response.FirewallRuleResponse; import org.apache.cloudstack.api.response.LBHealthCheckResponse; import org.apache.cloudstack.api.response.ListResponse; +import org.apache.log4j.Logger; + +import com.cloud.exception.InvalidParameterValueException; import com.cloud.network.rules.HealthCheckPolicy; import com.cloud.network.rules.LoadBalancer; @@ -45,10 +47,15 @@ public class ListLBHealthCheckPoliciesCmd extends BaseListCmd { @Parameter(name = ApiConstants.LBID, type = CommandType.UUID, entityType = FirewallRuleResponse.class, - required = true, description = "the ID of the load balancer rule") private Long lbRuleId; + @Parameter(name = ApiConstants.FOR_DISPLAY, type = CommandType.BOOLEAN, description = "list resources by display flag; only ROOT admin is eligible to pass this parameter", since = "4.4", authorized = {RoleType.Admin}) + private Boolean display; + + @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = LBHealthCheckResponse.class, description = "the ID of the healthcheck policy", since = "4.4") + private Long id; + // /////////////////////////////////////////////////// // ///////////////// Accessors /////////////////////// // /////////////////////////////////////////////////// @@ -56,6 +63,17 @@ public Long getLbRuleId() { return lbRuleId; } + public Long getId() { + return id; + } + + public boolean getDisplay() { + if (display != null) { + return display; + } + return true; + } + // /////////////////////////////////////////////////// // ///////////// API Implementation/////////////////// // /////////////////////////////////////////////////// @@ -68,9 +86,18 @@ public String getCommandName() { @Override public void execute() { List hcpResponses = new ArrayList(); - LoadBalancer lb = _lbService.findById(getLbRuleId()); ListResponse response = new ListResponse(); + Long lbRuleId = getLbRuleId(); + Long hId = getId(); + if(lbRuleId == null) { + if(hId != null) { + lbRuleId = _lbService.findLBIdByHealtCheckPolicyId(hId); + } else { + throw new InvalidParameterValueException("Either LB Ruleid or HealthCheckpolicy Id should be specified"); + } + } + LoadBalancer lb = _lbService.findById(lbRuleId); if (lb != null) { List healthCheckPolicies = _lbService.searchForLBHealthCheckPolicies(this); LBHealthCheckResponse spResponse = _responseGenerator.createLBHealthCheckPolicyResponse(healthCheckPolicies, lb); diff --git a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/ListLBStickinessPoliciesCmd.java b/api/src/org/apache/cloudstack/api/command/user/loadbalancer/ListLBStickinessPoliciesCmd.java index 2e7ae3c5e1..6477621301 100644 --- a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/ListLBStickinessPoliciesCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/loadbalancer/ListLBStickinessPoliciesCmd.java @@ -19,8 +19,8 @@ import java.util.ArrayList; import java.util.List; -import org.apache.log4j.Logger; - +import com.cloud.exception.InvalidParameterValueException; +import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseListCmd; @@ -29,6 +29,7 @@ import org.apache.cloudstack.api.response.LBStickinessResponse; import org.apache.cloudstack.api.response.ListResponse; import org.apache.cloudstack.context.CallContext; +import org.apache.log4j.Logger; import com.cloud.network.rules.LoadBalancer; import com.cloud.network.rules.StickinessPolicy; @@ -47,10 +48,19 @@ public class ListLBStickinessPoliciesCmd extends BaseListCmd { @Parameter(name = ApiConstants.LBID, type = CommandType.UUID, entityType = FirewallRuleResponse.class, - required = true, description = "the ID of the load balancer rule") private Long lbRuleId; + @Parameter(name = ApiConstants.ID, + type = CommandType.UUID, + entityType = LBStickinessResponse.class, + description = "the ID of the load balancer stickiness policy") + private Long id; + + + @Parameter(name = ApiConstants.FOR_DISPLAY, type = CommandType.BOOLEAN, description = "list resources by display flag; only ROOT admin is eligible to pass this parameter", since = "4.4", authorized = {RoleType.Admin}) + private Boolean display; + // /////////////////////////////////////////////////// // ///////////////// Accessors /////////////////////// // /////////////////////////////////////////////////// @@ -58,6 +68,17 @@ public Long getLbRuleId() { return lbRuleId; } + public Long getId() { + return id; + } + + public boolean getDisplay() { + if (display != null) { + return display; + } + return true; + } + // /////////////////////////////////////////////////// // ///////////// API Implementation/////////////////// // /////////////////////////////////////////////////// @@ -69,8 +90,28 @@ public String getCommandName() { @Override public void execute() { + + LoadBalancer lb = null; + if (lbRuleId == null && id == null) { + throw new InvalidParameterValueException("LB rule id and stickiness policy id can't be null"); + } + + if (id != null) { + lb = _lbService.findLbByStickinessId(id); + if (lb == null) { + throw new InvalidParameterValueException("stickiness policy id doesn't exist"); + } + + if ((lbRuleId != null) && (lbRuleId != lb.getId())) { + throw new InvalidParameterValueException("stickiness policy id doesn't belong to lbId" + lbRuleId); + } + } + + if (lbRuleId != null && lb == null) { + lb = _lbService.findById(getLbRuleId()); + } + List spResponses = new ArrayList(); - LoadBalancer lb = _lbService.findById(getLbRuleId()); ListResponse response = new ListResponse(); if (lb != null) { diff --git a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/ListLoadBalancerRuleInstancesCmd.java b/api/src/org/apache/cloudstack/api/command/user/loadbalancer/ListLoadBalancerRuleInstancesCmd.java index 2d458a7408..cc4203c359 100644 --- a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/ListLoadBalancerRuleInstancesCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/loadbalancer/ListLoadBalancerRuleInstancesCmd.java @@ -19,6 +19,7 @@ import java.util.ArrayList; import java.util.List; +import org.apache.cloudstack.api.response.LoadBalancerRuleVmMapResponse; import org.apache.log4j.Logger; import org.apache.cloudstack.api.APICommand; @@ -33,7 +34,7 @@ import com.cloud.uservm.UserVm; import com.cloud.utils.Pair; -@APICommand(name = "listLoadBalancerRuleInstances", description = "List all virtual machine instances that are assigned to a load balancer rule.", responseObject = UserVmResponse.class, responseView = ResponseView.Restricted, +@APICommand(name = "listLoadBalancerRuleInstances", description = "List all virtual machine instances that are assigned to a load balancer rule.", responseObject = LoadBalancerRuleVmMapResponse.class, responseView = ResponseView.Restricted, requestHasSensitiveInfo = false, responseHasSensitiveInfo = true) public class ListLoadBalancerRuleInstancesCmd extends BaseListCmd { @@ -57,6 +58,13 @@ public class ListLoadBalancerRuleInstancesCmd extends BaseListCmd { description = "the ID of the load balancer rule") private Long id; + + @Parameter(name = ApiConstants.LIST_LB_VMIPS, + type = CommandType.BOOLEAN, + description = "true if lb rule vm ip information to be included; default is false") + private boolean isListLbVmip; + + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -69,6 +77,10 @@ public Long getId() { return id; } + public boolean isListLbVmip() { + return isListLbVmip; + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// @@ -83,17 +95,49 @@ public void execute() { Pair, List> vmServiceMap = _lbService.listLoadBalancerInstances(this); List result = vmServiceMap.first(); List serviceStates = vmServiceMap.second(); - ListResponse response = new ListResponse(); - List vmResponses = new ArrayList(); - if (result != null) { - vmResponses = _responseGenerator.createUserVmResponse(ResponseView.Restricted, "loadbalancerruleinstance", result.toArray(new UserVm[result.size()])); - } - for (int i = 0; i < result.size(); i++) { - vmResponses.get(i).setServiceState(serviceStates.get(i)); + if (!isListLbVmip()) { + // list lb instances + ListResponse response = new ListResponse(); + List vmResponses = new ArrayList(); + if (result != null) { + vmResponses = _responseGenerator.createUserVmResponse(ResponseView.Restricted, "loadbalancerruleinstance", result.toArray(new UserVm[result.size()])); + + + for (int i = 0; i < result.size(); i++) { + vmResponses.get(i).setServiceState(serviceStates.get(i)); + } + } + response.setResponses(vmResponses); + response.setResponseName(getCommandName()); + setResponseObject(response); + + + } else { + ListResponse lbRes = new ListResponse(); + + List vmResponses = new ArrayList(); + List listlbVmRes = new ArrayList(); + + if (result != null) { + vmResponses = _responseGenerator.createUserVmResponse(ResponseView.Full, "loadbalancerruleinstance", result.toArray(new UserVm[result.size()])); + + + List ipaddr = null; + + for (int i=0;i virtualMachineIds; + @Parameter(name = ApiConstants.VIRTUAL_MACHINE_ID_IP, + type = CommandType.MAP, + description = "VM ID and IP map, vmidipmap[0].vmid=1 vmidipmap[0].ip=10.1.1.75", + since = "4.4") + private Map vmIdIpMap; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -78,6 +89,10 @@ public List getVirtualMachineIds() { return virtualMachineIds; } + public Map getVmIdIpMap() { + return vmIdIpMap; + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// @@ -101,20 +116,58 @@ public String getEventType() { return EventTypes.EVENT_REMOVE_FROM_LOAD_BALANCER_RULE; } + + public Map> getVmIdIpListMap() { + Map> vmIdIpsMap = new HashMap>(); + if (vmIdIpMap != null && !vmIdIpMap.isEmpty()) { + Collection idIpsCollection = vmIdIpMap.values(); + Iterator iter = idIpsCollection.iterator(); + while (iter.hasNext()) { + HashMap idIpsMap = (HashMap)iter.next(); + String vmId = idIpsMap.get("vmid"); + String vmIp = idIpsMap.get("vmip"); + + VirtualMachine lbvm = _entityMgr.findByUuid(VirtualMachine.class, vmId); + if (lbvm == null) { + throw new InvalidParameterValueException("Unable to find virtual machine ID: " + vmId); + } + + Long longVmId = lbvm.getId(); + + List ipsList = null; + if (vmIdIpsMap.containsKey(longVmId)) { + ipsList = vmIdIpsMap.get(longVmId); + } else { + ipsList = new ArrayList(); + } + ipsList.add(vmIp); + vmIdIpsMap.put(longVmId, ipsList); + + } + } + + return vmIdIpsMap; + } + @Override public String getEventDescription() { return "removing instances from load balancer: " + getId() + " (ids: " + StringUtils.join(getVirtualMachineIds(), ",") + ")"; } @Override - public void execute() { + public void execute() { CallContext.current().setEventDetails("Load balancer Id: " + getId() + " VmIds: " + StringUtils.join(getVirtualMachineIds(), ",")); - boolean result = _lbService.removeFromLoadBalancer(id, virtualMachineIds); - if (result) { - SuccessResponse response = new SuccessResponse(getCommandName()); - this.setResponseObject(response); - } else { - throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to remove instance from load balancer rule"); + Map> vmIdIpsMap = getVmIdIpListMap(); + try { + boolean result = _lbService.removeFromLoadBalancer(id, virtualMachineIds, vmIdIpsMap); + if (result) { + SuccessResponse response = new SuccessResponse(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to remove instance from load balancer rule"); + } + }catch (InvalidParameterValueException ex) { + throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Failed to remove instance from load balancer rule"); } } diff --git a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/UpdateLBHealthCheckPolicyCmd.java b/api/src/org/apache/cloudstack/api/command/user/loadbalancer/UpdateLBHealthCheckPolicyCmd.java new file mode 100644 index 0000000000..0b0c34fff9 --- /dev/null +++ b/api/src/org/apache/cloudstack/api/command/user/loadbalancer/UpdateLBHealthCheckPolicyCmd.java @@ -0,0 +1,100 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package org.apache.cloudstack.api.command.user.loadbalancer; + +import org.apache.cloudstack.acl.RoleType; +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.BaseAsyncCustomIdCmd; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.response.LBHealthCheckResponse; +import org.apache.cloudstack.context.CallContext; +import org.apache.log4j.Logger; + +import com.cloud.event.EventTypes; +import com.cloud.network.rules.HealthCheckPolicy; +import com.cloud.network.rules.LoadBalancer; +import com.cloud.network.rules.StickinessPolicy; +import com.cloud.user.Account; + +@APICommand(name = "updateLBHealthCheckPolicy", description = "Updates LB HealthCheck policy", responseObject = LBHealthCheckResponse.class, since = "4.4", +requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) +public class UpdateLBHealthCheckPolicyCmd extends BaseAsyncCustomIdCmd{ + public static final Logger s_logger = Logger.getLogger(UpdateLBHealthCheckPolicyCmd.class.getName()); + + private static final String s_name = "updatelbhealthcheckpolicyresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = LBHealthCheckResponse.class, required = true, description = "id of lb healthcheck policy") + private Long id; + + @Parameter(name = ApiConstants.FOR_DISPLAY, type = CommandType.BOOLEAN, description = "an optional field, whether to the display the policy to the end user or not", since = "4.4", authorized = {RoleType.Admin}) + private Boolean display; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + public Long getId() { + return id; + } + + public Boolean getDisplay() { + return display; + } + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + Account account = CallContext.current().getCallingAccount(); + if (account != null) { + return account.getId(); + } + + return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked + } + + @Override + public String getEventDescription() { + return "Update LB healthcheck policy id= " + id; + } + + @Override + public String getEventType() { + return EventTypes.EVENT_LB_HEALTHCHECKPOLICY_UPDATE; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + @Override + public void execute() { + HealthCheckPolicy policy = _lbService.updateLBHealthCheckPolicy(this.getId(), this.getCustomId(), this.getDisplay()); + LoadBalancer lb = _lbService.findById(policy.getLoadBalancerId()); + LBHealthCheckResponse hcResponse = _responseGenerator.createLBHealthCheckPolicyResponse(policy, lb); + setResponseObject(hcResponse); + hcResponse.setResponseName(getCommandName()); + } + + @Override + public void checkUuid() { + if (this.getCustomId() != null) { + _uuidMgr.checkUuid(this.getCustomId(), StickinessPolicy.class); + } + } +} diff --git a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/UpdateLBStickinessPolicyCmd.java b/api/src/org/apache/cloudstack/api/command/user/loadbalancer/UpdateLBStickinessPolicyCmd.java new file mode 100644 index 0000000000..c652945477 --- /dev/null +++ b/api/src/org/apache/cloudstack/api/command/user/loadbalancer/UpdateLBStickinessPolicyCmd.java @@ -0,0 +1,99 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package org.apache.cloudstack.api.command.user.loadbalancer; + +import org.apache.cloudstack.acl.RoleType; +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.BaseAsyncCustomIdCmd; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.response.LBStickinessResponse; +import org.apache.cloudstack.context.CallContext; +import org.apache.log4j.Logger; + +import com.cloud.event.EventTypes; +import com.cloud.network.rules.LoadBalancer; +import com.cloud.network.rules.StickinessPolicy; +import com.cloud.user.Account; + +@APICommand(name = "updateLBStickinessPolicy", description = "Updates LB Stickiness policy", responseObject = LBStickinessResponse.class, since = "4.4", +requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) +public class UpdateLBStickinessPolicyCmd extends BaseAsyncCustomIdCmd{ + public static final Logger s_logger = Logger.getLogger(UpdateLBStickinessPolicyCmd.class.getName()); + + private static final String s_name = "updatelbstickinesspolicyresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = LBStickinessResponse.class, required = true, description = "id of lb stickiness policy") + private Long id; + + @Parameter(name = ApiConstants.FOR_DISPLAY, type = CommandType.BOOLEAN, description = "an optional field, whether to the display the policy to the end user or not", since = "4.4", authorized = {RoleType.Admin}) + private Boolean display; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + public Long getId() { + return id; + } + + public Boolean getDisplay() { + return display; + } + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + Account account = CallContext.current().getCallingAccount(); + if (account != null) { + return account.getId(); + } + + return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked + } + + @Override + public String getEventDescription() { + return "Update LB stickiness policy id= " + id; + } + + @Override + public String getEventType() { + return EventTypes.EVENT_LB_STICKINESSPOLICY_UPDATE; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + @Override + public void execute() { + StickinessPolicy policy = _lbService.updateLBStickinessPolicy(this.getId(), this.getCustomId(), this.getDisplay()); + LoadBalancer lb = _lbService.findById(policy.getLoadBalancerId()); + LBStickinessResponse spResponse = _responseGenerator.createLBStickinessPolicyResponse(policy, lb); + setResponseObject(spResponse); + spResponse.setResponseName(getCommandName()); + } + + @Override + public void checkUuid() { + if (this.getCustomId() != null) { + _uuidMgr.checkUuid(this.getCustomId(), StickinessPolicy.class); + } + } +} diff --git a/api/src/org/apache/cloudstack/api/command/user/nat/CreateIpForwardingRuleCmd.java b/api/src/org/apache/cloudstack/api/command/user/nat/CreateIpForwardingRuleCmd.java index 77edbfccca..8925d066fe 100644 --- a/api/src/org/apache/cloudstack/api/command/user/nat/CreateIpForwardingRuleCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/nat/CreateIpForwardingRuleCmd.java @@ -20,7 +20,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiCommandJobType; import org.apache.cloudstack.api.ApiConstants; @@ -325,8 +324,8 @@ public boolean isDisplay() { } @Override - public IAMEntityType getEntityType() { - return IAMEntityType.FirewallRule; + public Class getEntityType() { + return FirewallRule.class; } } diff --git a/api/src/org/apache/cloudstack/api/command/user/network/CreateNetworkACLCmd.java b/api/src/org/apache/cloudstack/api/command/user/network/CreateNetworkACLCmd.java index e47fa8b2cf..b4d54896d9 100644 --- a/api/src/org/apache/cloudstack/api/command/user/network/CreateNetworkACLCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/network/CreateNetworkACLCmd.java @@ -103,10 +103,20 @@ public class CreateNetworkACLCmd extends BaseAsyncCreateCmd { // /////////////////////////////////////////////////// // ///////////////// Accessors /////////////////////// // /////////////////////////////////////////////////// + @Deprecated public Boolean getDisplay() { return display; } + @Override + public boolean isDisplay() { + if (display != null) { + return display; + } else { + return true; + } + } + public String getProtocol() { String p = protocol.trim(); // Deal with ICMP(protocol number 1) specially because it need to be paired with icmp type and code diff --git a/api/src/org/apache/cloudstack/api/command/user/network/CreateNetworkACLListCmd.java b/api/src/org/apache/cloudstack/api/command/user/network/CreateNetworkACLListCmd.java index 07156cf944..9aa0bab5ae 100644 --- a/api/src/org/apache/cloudstack/api/command/user/network/CreateNetworkACLListCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/network/CreateNetworkACLListCmd.java @@ -77,8 +77,13 @@ public Long getVpcId() { return vpcId; } - public Boolean getDisplay() { - return display; + @Override + public boolean isDisplay() { + if (display != null) { + return display; + } else { + return true; + } } // /////////////////////////////////////////////////// @@ -92,7 +97,7 @@ public String getCommandName() { @Override public void create() { - NetworkACL result = _networkACLService.createNetworkACL(getName(), getDescription(), getVpcId(), getDisplay()); + NetworkACL result = _networkACLService.createNetworkACL(getName(), getDescription(), getVpcId(), isDisplay()); setEntityId(result.getId()); setEntityUuid(result.getUuid()); } diff --git a/api/src/org/apache/cloudstack/api/command/user/network/CreateNetworkCmd.java b/api/src/org/apache/cloudstack/api/command/user/network/CreateNetworkCmd.java index 3ecec7bde8..8390b7525b 100644 --- a/api/src/org/apache/cloudstack/api/command/user/network/CreateNetworkCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/network/CreateNetworkCmd.java @@ -16,9 +16,9 @@ // under the License. package org.apache.cloudstack.api.command.user.network; +import com.cloud.utils.net.NetUtils; import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; @@ -45,7 +45,7 @@ import com.cloud.network.Network.GuestType; import com.cloud.offering.NetworkOffering; -@APICommand(name = "createNetwork", description = "Creates a network", responseObject = NetworkResponse.class, responseView = ResponseView.Restricted, entityType = {IAMEntityType.Network}, +@APICommand(name = "createNetwork", description = "Creates a network", responseObject = NetworkResponse.class, responseView = ResponseView.Restricted, entityType = {Network.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class CreateNetworkCmd extends BaseCmd { public static final Logger s_logger = Logger.getLogger(CreateNetworkCmd.class.getName()); @@ -213,6 +213,14 @@ public Boolean getDisplayNetwork() { return displayNetwork; } + @Override + public boolean isDisplay() { + if(displayNetwork == null) + return true; + else + return displayNetwork; + } + public Long getZoneId() { Long physicalNetworkId = getPhysicalNetworkId(); @@ -247,28 +255,28 @@ public String getStartIpv6() { if (startIpv6 == null) { return null; } - return startIpv6.toLowerCase(); + return NetUtils.standardizeIp6Address(startIpv6); } public String getEndIpv6() { if (endIpv6 == null) { return null; } - return endIpv6.toLowerCase(); + return NetUtils.standardizeIp6Address(endIpv6); } public String getIp6Gateway() { if (ip6Gateway == null) { return null; } - return ip6Gateway.toLowerCase(); + return NetUtils.standardizeIp6Address(ip6Gateway); } public String getIp6Cidr() { if (ip6Cidr == null) { return null; } - return ip6Cidr.toLowerCase(); + return NetUtils.standardizeIp6Cidr(ip6Cidr); } public Long getAclId() { diff --git a/api/src/org/apache/cloudstack/api/command/user/network/DeleteNetworkCmd.java b/api/src/org/apache/cloudstack/api/command/user/network/DeleteNetworkCmd.java index 50bc94a126..4c3a292c4a 100644 --- a/api/src/org/apache/cloudstack/api/command/user/network/DeleteNetworkCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/network/DeleteNetworkCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ACL; import org.apache.cloudstack.api.APICommand; @@ -36,7 +35,7 @@ import com.cloud.exception.InvalidParameterValueException; import com.cloud.network.Network; -@APICommand(name = "deleteNetwork", description = "Deletes a network", responseObject = SuccessResponse.class, entityType = {IAMEntityType.Network}, +@APICommand(name = "deleteNetwork", description = "Deletes a network", responseObject = SuccessResponse.class, entityType = {Network.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class DeleteNetworkCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(DeleteNetworkOfferingCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/network/ListNetworkOfferingsCmd.java b/api/src/org/apache/cloudstack/api/command/user/network/ListNetworkOfferingsCmd.java index a08e28fb6d..6ac0f395b7 100644 --- a/api/src/org/apache/cloudstack/api/command/user/network/ListNetworkOfferingsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/network/ListNetworkOfferingsCmd.java @@ -36,7 +36,7 @@ requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class ListNetworkOfferingsCmd extends BaseListCmd { public static final Logger s_logger = Logger.getLogger(ListNetworkOfferingsCmd.class.getName()); - private static final String Name = "listnetworkofferingsresponse"; + private static final String s_name = "listnetworkofferingsresponse"; ///////////////////////////////////////////////////// //////////////// API parameters ///////////////////// @@ -182,7 +182,7 @@ public Boolean getForVpc() { ///////////////////////////////////////////////////// @Override public String getCommandName() { - return Name; + return s_name; } @Override diff --git a/api/src/org/apache/cloudstack/api/command/user/network/ListNetworksCmd.java b/api/src/org/apache/cloudstack/api/command/user/network/ListNetworksCmd.java index 455d8dc6a0..86f3ba2ad6 100644 --- a/api/src/org/apache/cloudstack/api/command/user/network/ListNetworksCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/network/ListNetworksCmd.java @@ -21,7 +21,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; @@ -37,11 +36,11 @@ import com.cloud.network.Network; import com.cloud.utils.Pair; -@APICommand(name = "listNetworks", description = "Lists all available networks.", responseObject = NetworkResponse.class, responseView = ResponseView.Restricted, entityType = { IAMEntityType.Network }, +@APICommand(name = "listNetworks", description = "Lists all available networks.", responseObject = NetworkResponse.class, responseView = ResponseView.Restricted, entityType = {Network.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class ListNetworksCmd extends BaseListTaggedResourcesCmd { public static final Logger s_logger = Logger.getLogger(ListNetworksCmd.class.getName()); - private static final String Name = "listnetworksresponse"; + private static final String s_name = "listnetworksresponse"; ///////////////////////////////////////////////////// //////////////// API parameters ///////////////////// @@ -156,7 +155,7 @@ public Boolean getDisplay() { ///////////////////////////////////////////////////// @Override public String getCommandName() { - return Name; + return s_name; } @Override diff --git a/api/src/org/apache/cloudstack/api/command/user/network/RestartNetworkCmd.java b/api/src/org/apache/cloudstack/api/command/user/network/RestartNetworkCmd.java index 6baafda7c8..eba8310421 100644 --- a/api/src/org/apache/cloudstack/api/command/user/network/RestartNetworkCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/network/RestartNetworkCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ACL; import org.apache.cloudstack.api.APICommand; @@ -41,7 +40,7 @@ @APICommand(name = "restartNetwork", description = "Restarts the network; includes 1) restarting network elements - virtual routers, dhcp servers 2) reapplying all public ips 3) reapplying loadBalancing/portForwarding rules", - responseObject = IPAddressResponse.class, entityType = {IAMEntityType.Network}, + responseObject = IPAddressResponse.class, entityType = {Network.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class RestartNetworkCmd extends BaseAsyncCmd { diff --git a/api/src/org/apache/cloudstack/api/command/user/network/UpdateNetworkACLItemCmd.java b/api/src/org/apache/cloudstack/api/command/user/network/UpdateNetworkACLItemCmd.java index eb095df209..59ae05df40 100644 --- a/api/src/org/apache/cloudstack/api/command/user/network/UpdateNetworkACLItemCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/network/UpdateNetworkACLItemCmd.java @@ -88,8 +88,14 @@ public class UpdateNetworkACLItemCmd extends BaseAsyncCustomIdCmd { // /////////////////////////////////////////////////// // ///////////////// Accessors /////////////////////// // /////////////////////////////////////////////////// - public Boolean getDisplay() { - return display; + + @Override + public boolean isDisplay() { + if (display != null) { + return display; + } else { + return true; + } } public Long getId() { @@ -172,7 +178,7 @@ public void execute() throws ResourceUnavailableException { CallContext.current().setEventDetails("Rule Id: " + getId()); NetworkACLItem aclItem = _networkACLService.updateNetworkACLItem(getId(), getProtocol(), getSourceCidrList(), getTrafficType(), getAction(), getNumber(), getSourcePortStart(), - getSourcePortEnd(), getIcmpCode(), getIcmpType(), this.getCustomId(), this.getDisplay()); + getSourcePortEnd(), getIcmpCode(), getIcmpType(), this.getCustomId(), this.isDisplay()); if (aclItem == null) { throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update network ACL Item"); } diff --git a/api/src/org/apache/cloudstack/api/command/user/network/UpdateNetworkCmd.java b/api/src/org/apache/cloudstack/api/command/user/network/UpdateNetworkCmd.java index aea7448ab3..0f73ddef93 100644 --- a/api/src/org/apache/cloudstack/api/command/user/network/UpdateNetworkCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/network/UpdateNetworkCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ACL; @@ -43,7 +42,7 @@ import com.cloud.user.Account; import com.cloud.user.User; -@APICommand(name = "updateNetwork", description = "Updates a network", responseObject = NetworkResponse.class, responseView = ResponseView.Restricted, entityType = {IAMEntityType.Network}, +@APICommand(name = "updateNetwork", description = "Updates a network", responseObject = NetworkResponse.class, responseView = ResponseView.Restricted, entityType = {Network.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class UpdateNetworkCmd extends BaseAsyncCustomIdCmd { public static final Logger s_logger = Logger.getLogger(UpdateNetworkCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/resource/UpdateResourceCountCmd.java b/api/src/org/apache/cloudstack/api/command/user/resource/UpdateResourceCountCmd.java index 5a417496eb..81d725b919 100644 --- a/api/src/org/apache/cloudstack/api/command/user/resource/UpdateResourceCountCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/resource/UpdateResourceCountCmd.java @@ -106,7 +106,7 @@ public String getCommandName() { @Override public long getEntityOwnerId() { Account account = CallContext.current().getCallingAccount(); - if ((account == null) || _accountService.isAdmin(account.getType())) { + if ((account == null) || _accountService.isAdmin(account.getId())) { if ((domainId != null) && (accountName != null)) { Account userAccount = _responseGenerator.findAccountByNameDomain(accountName, domainId); if (userAccount != null) { diff --git a/api/src/org/apache/cloudstack/api/command/user/securitygroup/AuthorizeSecurityGroupEgressCmd.java b/api/src/org/apache/cloudstack/api/command/user/securitygroup/AuthorizeSecurityGroupEgressCmd.java index 96509f1081..9909bf3085 100644 --- a/api/src/org/apache/cloudstack/api/command/user/securitygroup/AuthorizeSecurityGroupEgressCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/securitygroup/AuthorizeSecurityGroupEgressCmd.java @@ -24,7 +24,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ACL; import org.apache.cloudstack.api.APICommand; @@ -42,10 +41,11 @@ import com.cloud.event.EventTypes; import com.cloud.exception.InvalidParameterValueException; +import com.cloud.network.security.SecurityGroup; import com.cloud.network.security.SecurityRule; import com.cloud.utils.StringUtils; -@APICommand(name = "authorizeSecurityGroupEgress", responseObject = SecurityGroupRuleResponse.class, description = "Authorizes a particular egress rule for this security group", since = "3.0.0", entityType = {IAMEntityType.SecurityGroup}, +@APICommand(name = "authorizeSecurityGroupEgress", responseObject = SecurityGroupRuleResponse.class, description = "Authorizes a particular egress rule for this security group", since = "3.0.0", entityType = {SecurityGroup.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) @SuppressWarnings("rawtypes") @@ -95,7 +95,8 @@ public class AuthorizeSecurityGroupEgressCmd extends BaseAsyncCmd { @Parameter(name=ApiConstants.SECURITY_GROUP_ID, type=CommandType.UUID, description="The ID of the security group. Mutually exclusive with securityGroupName parameter", entityType=SecurityGroupResponse.class) private Long securityGroupId; - @ACL(accessType = AccessType.OperateEntry) + // This @ACL will not work, since we don't have a way to convert this parameter to the entity like securityGroupId. + //@ACL(accessType = AccessType.OperateEntry) @Parameter(name=ApiConstants.SECURITY_GROUP_NAME, type=CommandType.STRING, description="The name of the security group. Mutually exclusive with securityGroupName parameter") private String securityGroupName; diff --git a/api/src/org/apache/cloudstack/api/command/user/securitygroup/AuthorizeSecurityGroupIngressCmd.java b/api/src/org/apache/cloudstack/api/command/user/securitygroup/AuthorizeSecurityGroupIngressCmd.java index 1e324e2a1e..3549d5139d 100644 --- a/api/src/org/apache/cloudstack/api/command/user/securitygroup/AuthorizeSecurityGroupIngressCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/securitygroup/AuthorizeSecurityGroupIngressCmd.java @@ -24,7 +24,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ACL; import org.apache.cloudstack.api.APICommand; @@ -42,10 +41,11 @@ import com.cloud.event.EventTypes; import com.cloud.exception.InvalidParameterValueException; +import com.cloud.network.security.SecurityGroup; import com.cloud.network.security.SecurityRule; import com.cloud.utils.StringUtils; -@APICommand(name = "authorizeSecurityGroupIngress", responseObject = SecurityGroupRuleResponse.class, description = "Authorizes a particular ingress rule for this security group", entityType = {IAMEntityType.SecurityGroup}, +@APICommand(name = "authorizeSecurityGroupIngress", responseObject = SecurityGroupRuleResponse.class, description = "Authorizes a particular ingress rule for this security group", entityType = {SecurityGroup.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) @SuppressWarnings("rawtypes") @@ -95,7 +95,8 @@ public class AuthorizeSecurityGroupIngressCmd extends BaseAsyncCmd { @Parameter(name=ApiConstants.SECURITY_GROUP_ID, type=CommandType.UUID, description="The ID of the security group. Mutually exclusive with securityGroupName parameter", entityType=SecurityGroupResponse.class) private Long securityGroupId; - @ACL(accessType = AccessType.OperateEntry) + // This @ACL will not work, since we don't have a way to convert this parameter to the entity like securityGroupId. + //@ACL(accessType = AccessType.OperateEntry) @Parameter(name=ApiConstants.SECURITY_GROUP_NAME, type=CommandType.STRING, description="The name of the security group. Mutually exclusive with securityGroupName parameter") private String securityGroupName; diff --git a/api/src/org/apache/cloudstack/api/command/user/securitygroup/CreateSecurityGroupCmd.java b/api/src/org/apache/cloudstack/api/command/user/securitygroup/CreateSecurityGroupCmd.java index 1f7f872f1e..d3d35bc0b3 100644 --- a/api/src/org/apache/cloudstack/api/command/user/securitygroup/CreateSecurityGroupCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/securitygroup/CreateSecurityGroupCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.ApiErrorCode; @@ -33,7 +32,7 @@ import com.cloud.network.security.SecurityGroup; import com.cloud.user.Account; -@APICommand(name = "createSecurityGroup", responseObject = SecurityGroupResponse.class, description = "Creates a security group", entityType = {IAMEntityType.SecurityGroup}, +@APICommand(name = "createSecurityGroup", responseObject = SecurityGroupResponse.class, description = "Creates a security group", entityType = {SecurityGroup.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class CreateSecurityGroupCmd extends BaseCmd { public static final Logger s_logger = Logger.getLogger(CreateSecurityGroupCmd.class.getName()); @@ -98,7 +97,7 @@ public String getCommandName() { @Override public long getEntityOwnerId() { Account account = CallContext.current().getCallingAccount(); - if ((account == null) || _accountService.isAdmin(account.getType())) { + if ((account == null) || _accountService.isAdmin(account.getId())) { if ((domainId != null) && (accountName != null)) { Account userAccount = _responseGenerator.findAccountByNameDomain(accountName, domainId); if (userAccount != null) { diff --git a/api/src/org/apache/cloudstack/api/command/user/securitygroup/DeleteSecurityGroupCmd.java b/api/src/org/apache/cloudstack/api/command/user/securitygroup/DeleteSecurityGroupCmd.java index 827c7d7389..87e6df41b6 100644 --- a/api/src/org/apache/cloudstack/api/command/user/securitygroup/DeleteSecurityGroupCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/securitygroup/DeleteSecurityGroupCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ACL; import org.apache.cloudstack.api.APICommand; @@ -35,8 +34,9 @@ import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.ResourceInUseException; +import com.cloud.network.security.SecurityGroup; -@APICommand(name = "deleteSecurityGroup", description = "Deletes security group", responseObject = SuccessResponse.class, entityType = {IAMEntityType.SecurityGroup}, +@APICommand(name = "deleteSecurityGroup", description = "Deletes security group", responseObject = SuccessResponse.class, entityType = {SecurityGroup.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class DeleteSecurityGroupCmd extends BaseCmd { public static final Logger s_logger = Logger.getLogger(DeleteSecurityGroupCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/securitygroup/ListSecurityGroupsCmd.java b/api/src/org/apache/cloudstack/api/command/user/securitygroup/ListSecurityGroupsCmd.java index 02be63d0b4..4a8081a350 100644 --- a/api/src/org/apache/cloudstack/api/command/user/securitygroup/ListSecurityGroupsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/securitygroup/ListSecurityGroupsCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiCommandJobType; import org.apache.cloudstack.api.ApiConstants; @@ -28,7 +27,9 @@ import org.apache.cloudstack.api.response.SecurityGroupResponse; import org.apache.cloudstack.api.response.UserVmResponse; -@APICommand(name = "listSecurityGroups", description = "Lists security groups", responseObject = SecurityGroupResponse.class, entityType = {IAMEntityType.SecurityGroup}, +import com.cloud.network.security.SecurityGroup; + +@APICommand(name = "listSecurityGroups", description = "Lists security groups", responseObject = SecurityGroupResponse.class, entityType = {SecurityGroup.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class ListSecurityGroupsCmd extends BaseListTaggedResourcesCmd { public static final Logger s_logger = Logger.getLogger(ListSecurityGroupsCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/securitygroup/RevokeSecurityGroupEgressCmd.java b/api/src/org/apache/cloudstack/api/command/user/securitygroup/RevokeSecurityGroupEgressCmd.java index d1ffc1e5ea..a28a220b53 100644 --- a/api/src/org/apache/cloudstack/api/command/user/securitygroup/RevokeSecurityGroupEgressCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/securitygroup/RevokeSecurityGroupEgressCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiCommandJobType; import org.apache.cloudstack.api.ApiConstants; @@ -35,7 +34,7 @@ import com.cloud.user.Account; -@APICommand(name = "revokeSecurityGroupEgress", responseObject = SuccessResponse.class, description = "Deletes a particular egress rule from this security group", since = "3.0.0", entityType = {IAMEntityType.SecurityGroup}, +@APICommand(name = "revokeSecurityGroupEgress", responseObject = SuccessResponse.class, description = "Deletes a particular egress rule from this security group", since = "3.0.0", entityType = {SecurityGroup.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class RevokeSecurityGroupEgressCmd extends BaseAsyncCmd { diff --git a/api/src/org/apache/cloudstack/api/command/user/securitygroup/RevokeSecurityGroupIngressCmd.java b/api/src/org/apache/cloudstack/api/command/user/securitygroup/RevokeSecurityGroupIngressCmd.java index 8543e0e1de..9e81d0bc4e 100644 --- a/api/src/org/apache/cloudstack/api/command/user/securitygroup/RevokeSecurityGroupIngressCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/securitygroup/RevokeSecurityGroupIngressCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ACL; import org.apache.cloudstack.api.APICommand; @@ -36,7 +35,7 @@ import com.cloud.network.security.SecurityRule; import com.cloud.user.Account; -@APICommand(name = "revokeSecurityGroupIngress", responseObject = SuccessResponse.class, description = "Deletes a particular ingress rule from this security group", entityType = {IAMEntityType.SecurityGroup}, +@APICommand(name = "revokeSecurityGroupIngress", responseObject = SuccessResponse.class, description = "Deletes a particular ingress rule from this security group", entityType = {SecurityGroup.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class RevokeSecurityGroupIngressCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(RevokeSecurityGroupIngressCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/snapshot/CreateSnapshotCmd.java b/api/src/org/apache/cloudstack/api/command/user/snapshot/CreateSnapshotCmd.java index 2020518528..df7fe8296b 100644 --- a/api/src/org/apache/cloudstack/api/command/user/snapshot/CreateSnapshotCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/snapshot/CreateSnapshotCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiCommandJobType; import org.apache.cloudstack.api.ApiConstants; @@ -42,7 +41,7 @@ import com.cloud.storage.Volume; import com.cloud.user.Account; -@APICommand(name = "createSnapshot", description = "Creates an instant snapshot of a volume.", responseObject = SnapshotResponse.class, entityType = {IAMEntityType.Snapshot}, +@APICommand(name = "createSnapshot", description = "Creates an instant snapshot of a volume.", responseObject = SnapshotResponse.class, entityType = {Snapshot.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class CreateSnapshotCmd extends BaseAsyncCreateCmd { public static final Logger s_logger = Logger.getLogger(CreateSnapshotCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/snapshot/CreateSnapshotPolicyCmd.java b/api/src/org/apache/cloudstack/api/command/user/snapshot/CreateSnapshotPolicyCmd.java index c1381c8d7c..4e2e6bd3bb 100644 --- a/api/src/org/apache/cloudstack/api/command/user/snapshot/CreateSnapshotPolicyCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/snapshot/CreateSnapshotPolicyCmd.java @@ -16,6 +16,7 @@ // under the License. package org.apache.cloudstack.api.command.user.snapshot; +import org.apache.cloudstack.acl.RoleType; import org.apache.log4j.Logger; import org.apache.cloudstack.api.APICommand; @@ -64,6 +65,9 @@ public class CreateSnapshotPolicyCmd extends BaseCmd { @Parameter(name = ApiConstants.VOLUME_ID, type = CommandType.UUID, entityType = VolumeResponse.class, required = true, description = "the ID of the disk volume") private Long volumeId; + @Parameter(name = ApiConstants.FOR_DISPLAY, type = CommandType.BOOLEAN, description = "an optional field, whether to the display the policy to the end user or not", since = "4.4", authorized = {RoleType.Admin}) + private Boolean display; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -88,6 +92,14 @@ public Long getVolumeId() { return volumeId; } + @Override + public boolean isDisplay() { + if(display == null) + return true; + else + return display; + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// diff --git a/api/src/org/apache/cloudstack/api/command/user/snapshot/DeleteSnapshotCmd.java b/api/src/org/apache/cloudstack/api/command/user/snapshot/DeleteSnapshotCmd.java index 7d57c21459..64a432d0bc 100644 --- a/api/src/org/apache/cloudstack/api/command/user/snapshot/DeleteSnapshotCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/snapshot/DeleteSnapshotCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ACL; import org.apache.cloudstack.api.APICommand; @@ -36,7 +35,7 @@ import com.cloud.storage.Snapshot; import com.cloud.user.Account; -@APICommand(name = "deleteSnapshot", description = "Deletes a snapshot of a disk volume.", responseObject = SuccessResponse.class, entityType = {IAMEntityType.Snapshot}, +@APICommand(name = "deleteSnapshot", description = "Deletes a snapshot of a disk volume.", responseObject = SuccessResponse.class, entityType = {Snapshot.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class DeleteSnapshotCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(DeleteSnapshotCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/snapshot/ListSnapshotPoliciesCmd.java b/api/src/org/apache/cloudstack/api/command/user/snapshot/ListSnapshotPoliciesCmd.java index ffafe2df7b..282f82c36d 100644 --- a/api/src/org/apache/cloudstack/api/command/user/snapshot/ListSnapshotPoliciesCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/snapshot/ListSnapshotPoliciesCmd.java @@ -19,6 +19,7 @@ import java.util.ArrayList; import java.util.List; +import org.apache.cloudstack.acl.RoleType; import org.apache.log4j.Logger; import org.apache.cloudstack.api.APICommand; @@ -43,9 +44,15 @@ public class ListSnapshotPoliciesCmd extends BaseListCmd { //////////////// API parameters ///////////////////// ///////////////////////////////////////////////////// - @Parameter(name = ApiConstants.VOLUME_ID, type = CommandType.UUID, entityType = VolumeResponse.class, required = true, description = "the ID of the disk volume") + @Parameter(name = ApiConstants.VOLUME_ID, type = CommandType.UUID, entityType = VolumeResponse.class, description = "the ID of the disk volume") private Long volumeId; + @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = SnapshotPolicyResponse.class, description = "the ID of the snapshot policy") + private Long id; + + @Parameter(name = ApiConstants.FOR_DISPLAY, type = CommandType.BOOLEAN, description = "list resources by display flag; only ROOT admin is eligible to pass this parameter", since = "4.4", authorized = {RoleType.Admin}) + private Boolean display; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -54,6 +61,17 @@ public Long getVolumeId() { return volumeId; } + @Override + public boolean isDisplay() { + if (display != null) { + return display; + } + return true; + } + + public Long getId() { + return id; + } ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// diff --git a/api/src/org/apache/cloudstack/api/command/user/snapshot/ListSnapshotsCmd.java b/api/src/org/apache/cloudstack/api/command/user/snapshot/ListSnapshotsCmd.java index ed26e7ff6f..47a6876d09 100644 --- a/api/src/org/apache/cloudstack/api/command/user/snapshot/ListSnapshotsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/snapshot/ListSnapshotsCmd.java @@ -21,7 +21,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiCommandJobType; import org.apache.cloudstack.api.ApiConstants; @@ -35,7 +34,7 @@ import com.cloud.storage.Snapshot; import com.cloud.utils.Pair; -@APICommand(name = "listSnapshots", description = "Lists all available snapshots for the account.", responseObject = SnapshotResponse.class, entityType = {IAMEntityType.Snapshot}, +@APICommand(name = "listSnapshots", description = "Lists all available snapshots for the account.", responseObject = SnapshotResponse.class, entityType = {Snapshot.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class ListSnapshotsCmd extends BaseListTaggedResourcesCmd { public static final Logger s_logger = Logger.getLogger(ListSnapshotsCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/snapshot/RevertSnapshotCmd.java b/api/src/org/apache/cloudstack/api/command/user/snapshot/RevertSnapshotCmd.java index ab83812262..0c79f81564 100644 --- a/api/src/org/apache/cloudstack/api/command/user/snapshot/RevertSnapshotCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/snapshot/RevertSnapshotCmd.java @@ -18,7 +18,6 @@ */ package org.apache.cloudstack.api.command.user.snapshot; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ACL; import org.apache.cloudstack.api.APICommand; @@ -37,7 +36,7 @@ import com.cloud.storage.Snapshot; import com.cloud.user.Account; -@APICommand(name = "revertSnapshot", description = "revert a volume snapshot.", responseObject = SnapshotResponse.class, entityType = {IAMEntityType.Snapshot}, +@APICommand(name = "revertSnapshot", description = "revert a volume snapshot.", responseObject = SnapshotResponse.class, entityType = {Snapshot.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class RevertSnapshotCmd extends BaseAsyncCmd { private static final String s_name = "revertsnapshotresponse"; diff --git a/api/src/org/apache/cloudstack/api/command/user/snapshot/UpdateSnapshotPolicyCmd.java b/api/src/org/apache/cloudstack/api/command/user/snapshot/UpdateSnapshotPolicyCmd.java new file mode 100644 index 0000000000..7181fd50d0 --- /dev/null +++ b/api/src/org/apache/cloudstack/api/command/user/snapshot/UpdateSnapshotPolicyCmd.java @@ -0,0 +1,133 @@ +package org.apache.cloudstack.api.command.user.snapshot; + +// 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 com.cloud.event.EventTypes; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.storage.Volume; +import com.cloud.storage.snapshot.SnapshotPolicy; +import org.apache.cloudstack.acl.RoleType; +import org.apache.cloudstack.acl.SecurityChecker; +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.BaseAsyncCustomIdCmd; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.ResponseObject; +import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.response.SnapshotPolicyResponse; +import org.apache.cloudstack.context.CallContext; +import org.apache.log4j.Logger; + + +@APICommand(name = "updateSnapshotPolicy", description = "Updates the snapshot policy.", responseObject = SnapshotPolicyResponse.class, responseView = ResponseObject.ResponseView.Restricted, entityType = {Volume.class}, + requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) +public class UpdateSnapshotPolicyCmd extends BaseAsyncCustomIdCmd { + public static final Logger s_logger = Logger.getLogger(UpdateSnapshotPolicyCmd.class.getName()); + private static final String s_name = "updatesnapshotpolicyresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @ACL(accessType = SecurityChecker.AccessType.OperateEntry) + @Parameter(name= ApiConstants.ID, type=CommandType.UUID, entityType=SnapshotPolicyResponse.class, description="the ID of the snapshot policy") + private Long id; + + @Parameter(name = ApiConstants.FOR_DISPLAY, + type = CommandType.BOOLEAN, + description = "an optional field, whether to the display the snapshot policy to the end user or not.", + since = "4.4", + authorized = {RoleType.Admin}) + private Boolean display; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public Long getId() { + return id; + } + + public Boolean getDisplay() { + return display; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public Long getInstanceId() { + return getId(); + } + + @Override + public long getEntityOwnerId() { + + SnapshotPolicy policy = _entityMgr.findById(SnapshotPolicy.class, getId()); + if (policy == null) { + throw new InvalidParameterValueException("Invalid snapshot policy id was provided"); + } + Volume volume = _responseGenerator.findVolumeById(policy.getVolumeId()); + if (volume == null) { + throw new InvalidParameterValueException("Snapshot policy's volume id doesnt exist"); + }else{ + return volume.getAccountId(); + } + } + + @Override + public String getEventType() { + return EventTypes.EVENT_SNAPSHOT_POLICY_UPDATE; + } + + @Override + public String getEventDescription() { + StringBuilder desc = new StringBuilder("Updating snapshot policy: "); + desc.append(getId()); + return desc.toString(); + } + + @Override + public void execute() { + CallContext.current().setEventDetails("SnapshotPolicy Id: " + getId()); + SnapshotPolicy result = _snapshotService.updateSnapshotPolicy(this); + if (result != null) { + SnapshotPolicyResponse response = _responseGenerator.createSnapshotPolicyResponse(result); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update snapshot policy"); + } + } + + @Override + public void checkUuid() { + if (getCustomId() != null) { + _uuidMgr.checkUuid(getCustomId(), SnapshotPolicy.class); + } + } + +} \ No newline at end of file diff --git a/api/src/org/apache/cloudstack/api/command/user/ssh/CreateSSHKeyPairCmd.java b/api/src/org/apache/cloudstack/api/command/user/ssh/CreateSSHKeyPairCmd.java index a0f05d18d3..bd7f613f89 100644 --- a/api/src/org/apache/cloudstack/api/command/user/ssh/CreateSSHKeyPairCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/ssh/CreateSSHKeyPairCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseCmd; @@ -30,7 +29,7 @@ import com.cloud.user.SSHKeyPair; -@APICommand(name = "createSSHKeyPair", description = "Create a new keypair and returns the private key", responseObject = CreateSSHKeyPairResponse.class, entityType = {IAMEntityType.SSHKeyPair}, +@APICommand(name = "createSSHKeyPair", description = "Create a new keypair and returns the private key", responseObject = CreateSSHKeyPairResponse.class, entityType = {SSHKeyPair.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = true) public class CreateSSHKeyPairCmd extends BaseCmd { public static final Logger s_logger = Logger.getLogger(CreateSSHKeyPairCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/ssh/DeleteSSHKeyPairCmd.java b/api/src/org/apache/cloudstack/api/command/user/ssh/DeleteSSHKeyPairCmd.java index d0a5234e05..9258587735 100644 --- a/api/src/org/apache/cloudstack/api/command/user/ssh/DeleteSSHKeyPairCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/ssh/DeleteSSHKeyPairCmd.java @@ -19,7 +19,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseCmd; @@ -30,8 +29,9 @@ import org.apache.cloudstack.context.CallContext; import com.cloud.user.Account; +import com.cloud.user.SSHKeyPair; -@APICommand(name = "deleteSSHKeyPair", description = "Deletes a keypair by name", responseObject = SuccessResponse.class, entityType = {IAMEntityType.SSHKeyPair}, +@APICommand(name = "deleteSSHKeyPair", description = "Deletes a keypair by name", responseObject = SuccessResponse.class, entityType = {SSHKeyPair.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class DeleteSSHKeyPairCmd extends BaseCmd { public static final Logger s_logger = Logger.getLogger(CreateSSHKeyPairCmd.class.getName()); @@ -93,7 +93,7 @@ public String getCommandName() { @Override public long getEntityOwnerId() { Account account = CallContext.current().getCallingAccount(); - if ((account == null) || _accountService.isAdmin(account.getType())) { + if ((account == null) || _accountService.isAdmin(account.getId())) { if ((domainId != null) && (accountName != null)) { Account userAccount = _responseGenerator.findAccountByNameDomain(accountName, domainId); if (userAccount != null) { diff --git a/api/src/org/apache/cloudstack/api/command/user/ssh/ListSSHKeyPairsCmd.java b/api/src/org/apache/cloudstack/api/command/user/ssh/ListSSHKeyPairsCmd.java index f02bf9f4f5..022cbc5068 100644 --- a/api/src/org/apache/cloudstack/api/command/user/ssh/ListSSHKeyPairsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/ssh/ListSSHKeyPairsCmd.java @@ -21,7 +21,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseListProjectAndAccountResourcesCmd; @@ -32,7 +31,7 @@ import com.cloud.user.SSHKeyPair; import com.cloud.utils.Pair; -@APICommand(name = "listSSHKeyPairs", description = "List registered keypairs", responseObject = SSHKeyPairResponse.class, entityType = {IAMEntityType.SSHKeyPair}, +@APICommand(name = "listSSHKeyPairs", description = "List registered keypairs", responseObject = SSHKeyPairResponse.class, entityType = {SSHKeyPair.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class ListSSHKeyPairsCmd extends BaseListProjectAndAccountResourcesCmd { public static final Logger s_logger = Logger.getLogger(ListSSHKeyPairsCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/ssh/RegisterSSHKeyPairCmd.java b/api/src/org/apache/cloudstack/api/command/user/ssh/RegisterSSHKeyPairCmd.java index e095227d98..c7cbc56ae6 100644 --- a/api/src/org/apache/cloudstack/api/command/user/ssh/RegisterSSHKeyPairCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/ssh/RegisterSSHKeyPairCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseCmd; @@ -30,7 +29,7 @@ import com.cloud.user.SSHKeyPair; -@APICommand(name = "registerSSHKeyPair", description = "Register a public key in a keypair under a certain name", responseObject = SSHKeyPairResponse.class, entityType = {IAMEntityType.SSHKeyPair}, +@APICommand(name = "registerSSHKeyPair", description = "Register a public key in a keypair under a certain name", responseObject = SSHKeyPairResponse.class, entityType = {SSHKeyPair.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class RegisterSSHKeyPairCmd extends BaseCmd { public static final Logger s_logger = Logger.getLogger(RegisterSSHKeyPairCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/tag/CreateTagsCmd.java b/api/src/org/apache/cloudstack/api/command/user/tag/CreateTagsCmd.java index eab114fea8..6aecc05548 100644 --- a/api/src/org/apache/cloudstack/api/command/user/tag/CreateTagsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/tag/CreateTagsCmd.java @@ -25,7 +25,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.ApiErrorCode; @@ -38,7 +37,7 @@ import com.cloud.server.ResourceTag; import com.cloud.server.ResourceTag.ResourceObjectType; -@APICommand(name = "createTags", description = "Creates resource tag(s)", responseObject = SuccessResponse.class, since = "4.0.0", entityType = {IAMEntityType.ResourceTag}, +@APICommand(name = "createTags", description = "Creates resource tag(s)", responseObject = SuccessResponse.class, since = "4.0.0", entityType = {ResourceTag.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class CreateTagsCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(CreateTagsCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/tag/DeleteTagsCmd.java b/api/src/org/apache/cloudstack/api/command/user/tag/DeleteTagsCmd.java index 39b6630b61..e42cfce4d9 100644 --- a/api/src/org/apache/cloudstack/api/command/user/tag/DeleteTagsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/tag/DeleteTagsCmd.java @@ -25,7 +25,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.ApiErrorCode; @@ -35,9 +34,10 @@ import org.apache.cloudstack.api.response.SuccessResponse; import com.cloud.event.EventTypes; +import com.cloud.server.ResourceTag; import com.cloud.server.ResourceTag.ResourceObjectType; -@APICommand(name = "deleteTags", description = "Deleting resource tag(s)", responseObject = SuccessResponse.class, since = "4.0.0", entityType = {IAMEntityType.ResourceTag}, +@APICommand(name = "deleteTags", description = "Deleting resource tag(s)", responseObject = SuccessResponse.class, since = "4.0.0", entityType = {ResourceTag.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class DeleteTagsCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(DeleteTagsCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/tag/ListTagsCmd.java b/api/src/org/apache/cloudstack/api/command/user/tag/ListTagsCmd.java index b2249104ac..e02b25c446 100644 --- a/api/src/org/apache/cloudstack/api/command/user/tag/ListTagsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/tag/ListTagsCmd.java @@ -17,7 +17,6 @@ package org.apache.cloudstack.api.command.user.tag; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseListProjectAndAccountResourcesCmd; @@ -25,7 +24,9 @@ import org.apache.cloudstack.api.response.ListResponse; import org.apache.cloudstack.api.response.ResourceTagResponse; -@APICommand(name = "listTags", description = "List resource tag(s)", responseObject = ResourceTagResponse.class, since = "4.0.0", entityType = {IAMEntityType.ResourceTag}, +import com.cloud.server.ResourceTag; + +@APICommand(name = "listTags", description = "List resource tag(s)", responseObject = ResourceTagResponse.class, since = "4.0.0", entityType = {ResourceTag.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class ListTagsCmd extends BaseListProjectAndAccountResourcesCmd { private static final String s_name = "listtagsresponse"; diff --git a/api/src/org/apache/cloudstack/api/command/user/template/ListTemplatesCmd.java b/api/src/org/apache/cloudstack/api/command/user/template/ListTemplatesCmd.java index 0be9ab8007..7a2a15834a 100644 --- a/api/src/org/apache/cloudstack/api/command/user/template/ListTemplatesCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/template/ListTemplatesCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiCommandJobType; import org.apache.cloudstack.api.ApiConstants; @@ -30,10 +29,11 @@ import org.apache.cloudstack.api.response.ZoneResponse; import org.apache.cloudstack.context.CallContext; +import com.cloud.template.VirtualMachineTemplate; import com.cloud.template.VirtualMachineTemplate.TemplateFilter; import com.cloud.user.Account; -@APICommand(name = "listTemplates", description = "List all public, private, and privileged templates.", responseObject = TemplateResponse.class, entityType = {IAMEntityType.VirtualMachineTemplate}, responseView = ResponseView.Restricted, +@APICommand(name = "listTemplates", description = "List all public, private, and privileged templates.", responseObject = TemplateResponse.class, entityType = {VirtualMachineTemplate.class}, responseView = ResponseView.Restricted, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class ListTemplatesCmd extends BaseListTaggedResourcesCmd { public static final Logger s_logger = Logger.getLogger(ListTemplatesCmd.class.getName()); @@ -103,7 +103,7 @@ public boolean listInReadyState() { Account account = CallContext.current().getCallingAccount(); // It is account specific if account is admin type and domainId and accountName are not null - boolean isAccountSpecific = (account == null || _accountService.isAdmin(account.getType())) && (getAccountName() != null) && (getDomainId() != null); + boolean isAccountSpecific = (account == null || _accountService.isAdmin(account.getId())) && (getAccountName() != null) && (getDomainId() != null); // Show only those that are downloaded. TemplateFilter templateFilter = TemplateFilter.valueOf(getTemplateFilter()); boolean onlyReady = diff --git a/api/src/org/apache/cloudstack/api/command/user/template/UpdateTemplatePermissionsCmd.java b/api/src/org/apache/cloudstack/api/command/user/template/UpdateTemplatePermissionsCmd.java index d5d0c58742..2029156837 100644 --- a/api/src/org/apache/cloudstack/api/command/user/template/UpdateTemplatePermissionsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/template/UpdateTemplatePermissionsCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.BaseUpdateTemplateOrIsoPermissionsCmd; import org.apache.cloudstack.api.response.SuccessResponse; @@ -28,7 +27,7 @@ @APICommand(name = "updateTemplatePermissions", responseObject = SuccessResponse.class, description = "Updates a template visibility permissions. " + "A public template is visible to all accounts within the same domain. " + "A private template is visible only to the owner of the template. " - + "A priviledged template is a private template with account permissions added. " + "Only accounts specified under the template permissions are visible to them.", entityType = {IAMEntityType.VirtualMachineTemplate}, + + "A priviledged template is a private template with account permissions added. " + "Only accounts specified under the template permissions are visible to them.", entityType = {VirtualMachineTemplate.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class UpdateTemplatePermissionsCmd extends BaseUpdateTemplateOrIsoPermissionsCmd { @Override diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/AddIpToVmNicCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/AddIpToVmNicCmd.java index a7f94368dc..870bbbf01e 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vm/AddIpToVmNicCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vm/AddIpToVmNicCmd.java @@ -92,6 +92,12 @@ private NetworkType getNetworkType() { return dc.getNetworkType(); } + private boolean isZoneSGEnabled() { + Network ntwk = _entityMgr.findById(Network.class, getNetworkId()); + DataCenter dc = _entityMgr.findById(DataCenter.class, ntwk.getDataCenterId()); + return dc.isSecurityGroupEnabled(); + } + @Override public String getEventType() { return EventTypes.EVENT_NET_IP_ASSIGN; @@ -136,7 +142,7 @@ public void execute() throws ResourceUnavailableException, ResourceAllocationExc if (result != null) { secondaryIp = result.getIp4Address(); - if (getNetworkType() == NetworkType.Basic) { + if (isZoneSGEnabled()) { // add security group rules for the secondary ip addresses boolean success = false; success = _securityGroupService.securityGroupRulesForVmSecIp(getNicId(), secondaryIp, true); diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/AddNicToVMCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/AddNicToVMCmd.java index a1bbe2a45b..f265ecf236 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vm/AddNicToVMCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vm/AddNicToVMCmd.java @@ -21,7 +21,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ACL; import org.apache.cloudstack.api.APICommand; @@ -39,8 +38,9 @@ import com.cloud.event.EventTypes; import com.cloud.user.Account; import com.cloud.uservm.UserVm; +import com.cloud.vm.VirtualMachine; -@APICommand(name = "addNicToVirtualMachine", description = "Adds VM to specified network by creating a NIC", responseObject = UserVmResponse.class, responseView = ResponseView.Restricted, entityType = {IAMEntityType.VirtualMachine}, +@APICommand(name = "addNicToVirtualMachine", description = "Adds VM to specified network by creating a NIC", responseObject = UserVmResponse.class, responseView = ResponseView.Restricted, entityType = {VirtualMachine.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = true) public class AddNicToVMCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(AddNicToVMCmd.class); diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java index 0235fcc305..1beb5957e5 100755 --- a/api/src/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java @@ -16,19 +16,26 @@ // under the License. package org.apache.cloudstack.api.command.user.vm; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import org.apache.log4j.Logger; - -import org.apache.cloudstack.acl.IAMEntityType; +import com.cloud.dc.DataCenter; +import com.cloud.dc.DataCenter.NetworkType; +import com.cloud.event.EventTypes; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.InsufficientServerCapacityException; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.ResourceAllocationException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.network.Network; +import com.cloud.network.Network.IpAddresses; +import com.cloud.offering.DiskOffering; +import com.cloud.offering.ServiceOffering; +import com.cloud.template.VirtualMachineTemplate; +import com.cloud.user.Account; +import com.cloud.uservm.UserVm; +import com.cloud.utils.net.NetUtils; +import com.cloud.vm.VirtualMachine; import org.apache.cloudstack.acl.RoleType; -import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.affinity.AffinityGroupResponse; import org.apache.cloudstack.api.ACL; import org.apache.cloudstack.api.APICommand; @@ -50,26 +57,17 @@ import org.apache.cloudstack.api.response.UserVmResponse; import org.apache.cloudstack.api.response.ZoneResponse; import org.apache.cloudstack.context.CallContext; +import org.apache.log4j.Logger; -import com.cloud.dc.DataCenter; -import com.cloud.dc.DataCenter.NetworkType; -import com.cloud.event.EventTypes; -import com.cloud.exception.ConcurrentOperationException; -import com.cloud.exception.InsufficientCapacityException; -import com.cloud.exception.InsufficientServerCapacityException; -import com.cloud.exception.InvalidParameterValueException; -import com.cloud.exception.ResourceAllocationException; -import com.cloud.exception.ResourceUnavailableException; -import com.cloud.hypervisor.Hypervisor.HypervisorType; -import com.cloud.network.Network; -import com.cloud.network.Network.IpAddresses; -import com.cloud.offering.DiskOffering; -import com.cloud.offering.ServiceOffering; -import com.cloud.template.VirtualMachineTemplate; -import com.cloud.user.Account; -import com.cloud.uservm.UserVm; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; -@APICommand(name = "deployVirtualMachine", description = "Creates and automatically starts a virtual machine based on a service offering, disk offering, and template.", responseObject = UserVmResponse.class, responseView = ResponseView.Restricted, entityType = { IAMEntityType.VirtualMachine }, +@APICommand(name = "deployVirtualMachine", description = "Creates and automatically starts a virtual machine based on a service offering, disk offering, and template.", responseObject = UserVmResponse.class, responseView = ResponseView.Restricted, entityType = {VirtualMachine.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = true) public class DeployVMCmd extends BaseAsyncCreateCustomIdCmd { public static final Logger s_logger = Logger.getLogger(DeployVMCmd.class.getName()); @@ -105,7 +103,7 @@ public class DeployVMCmd extends BaseAsyncCreateCustomIdCmd { private Long domainId; //Network information - @ACL(accessType = AccessType.UseEntry) + //@ACL(accessType = AccessType.UseEntry) @Parameter(name = ApiConstants.NETWORK_IDS, type = CommandType.LIST, collectionType = CommandType.UUID, entityType = NetworkResponse.class, description = "list of network ids used by virtual machine. Can't be specified with ipToNetworkList parameter") private List networkIds; @@ -121,6 +119,12 @@ public class DeployVMCmd extends BaseAsyncCreateCustomIdCmd { @Parameter(name = ApiConstants.SIZE, type = CommandType.LONG, description = "the arbitrary size for the DATADISK volume. Mutually exclusive with diskOfferingId") private Long size; + @Parameter(name = ApiConstants.ROOT_DISK_SIZE, + type = CommandType.LONG, + description = "Optional field to resize root disk on deploy. Only applies to template-based deployments. Analogous to details[0].rootdisksize, which takes precedence over this parameter if both are provided", + since = "4.4") + private Long rootdisksize; + @Parameter(name = ApiConstants.GROUP, type = CommandType.STRING, description = "an optional group for the virtual machine") private String group; @@ -226,6 +230,9 @@ public Map getDetails() { } } } + if (rootdisksize != null && !customparameterMap.containsKey("rootdisksize")) { + customparameterMap.put("rootdisksize", rootdisksize.toString()); + } return customparameterMap; } @@ -241,6 +248,14 @@ public Boolean getDisplayVm() { return displayVm; } + @Override + public boolean isDisplay() { + if(displayVm == null) + return true; + else + return displayVm; + } + public List getSecurityGroupIdList() { if (securityGroupNameList != null && securityGroupIdList != null) { throw new InvalidParameterValueException("securitygroupids parameter is mutually exclusive with securitygroupnames parameter"); @@ -337,7 +352,7 @@ private Map getIpToNetworkMap() { String requestedIp = ips.get("ip"); String requestedIpv6 = ips.get("ipv6"); if (requestedIpv6 != null) { - requestedIpv6 = requestedIpv6.toLowerCase(); + requestedIpv6 = NetUtils.standardizeIp6Address(requestedIpv6); } IpAddresses addrs = new IpAddresses(requestedIp, requestedIpv6); ipToNetworkMap.put(networkId, addrs); @@ -351,7 +366,7 @@ public String getIp6Address() { if (ip6Address == null) { return null; } - return ip6Address.toLowerCase(); + return NetUtils.standardizeIp6Address(ip6Address); } public List getAffinityGroupIdList() { @@ -399,16 +414,6 @@ public long getEntityOwnerId() { return accountId; } - @Override - public boolean isDisplayResourceEnabled(){ - Boolean display = getDisplayVm(); - if(display == null){ - return true; - } else { - return display; - } - } - @Override public String getEventType() { return EventTypes.EVENT_VM_CREATE; @@ -482,41 +487,50 @@ private void verifyDetails() { String minIops = (String)map.get("minIops"); String maxIops = (String)map.get("maxIops"); - if ((minIops != null && maxIops == null) || (minIops == null && maxIops != null)) { - throw new InvalidParameterValueException("Either 'Min IOPS' and 'Max IOPS' must both be specified or neither be specified."); - } + verifyMinAndMaxIops(minIops, maxIops); - long lMinIops; + minIops = (String)map.get("minIopsDo"); + maxIops = (String)map.get("maxIopsDo"); - try { - if (minIops != null) { - lMinIops = Long.valueOf(minIops); - } - else { - lMinIops = 0; - } + verifyMinAndMaxIops(minIops, maxIops); + } + } + + private void verifyMinAndMaxIops(String minIops, String maxIops) { + if ((minIops != null && maxIops == null) || (minIops == null && maxIops != null)) { + throw new InvalidParameterValueException("Either 'Min IOPS' and 'Max IOPS' must both be specified or neither be specified."); + } + + long lMinIops; + + try { + if (minIops != null) { + lMinIops = Long.valueOf(minIops); } - catch (NumberFormatException ex) { - throw new InvalidParameterValueException("'Min IOPS' must be a whole number."); + else { + lMinIops = 0; } + } + catch (NumberFormatException ex) { + throw new InvalidParameterValueException("'Min IOPS' must be a whole number."); + } - long lMaxIops; + long lMaxIops; - try { - if (maxIops != null) { - lMaxIops = Long.valueOf(maxIops); - } - else { - lMaxIops = 0; - } + try { + if (maxIops != null) { + lMaxIops = Long.valueOf(maxIops); } - catch (NumberFormatException ex) { - throw new InvalidParameterValueException("'Max IOPS' must be a whole number."); + else { + lMaxIops = 0; } + } + catch (NumberFormatException ex) { + throw new InvalidParameterValueException("'Max IOPS' must be a whole number."); + } - if (lMinIops > lMaxIops) { - throw new InvalidParameterValueException("'Min IOPS' must be less than or equal to 'Max IOPS'."); - } + if (lMinIops > lMaxIops) { + throw new InvalidParameterValueException("'Min IOPS' must be less than or equal to 'Max IOPS'."); } } diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/DestroyVMCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/DestroyVMCmd.java index 4c3a41589c..3de0e4f72d 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vm/DestroyVMCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vm/DestroyVMCmd.java @@ -18,16 +18,15 @@ import java.util.List; -import org.apache.cloudstack.api.BaseAsyncVMCmd; import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; 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.ResponseObject.ResponseView; import org.apache.cloudstack.api.ServerApiException; @@ -39,11 +38,12 @@ import com.cloud.exception.ResourceUnavailableException; import com.cloud.user.Account; import com.cloud.uservm.UserVm; +import com.cloud.vm.VirtualMachine; -@APICommand(name = "destroyVirtualMachine", description = "Destroys a virtual machine. Once destroyed, only the administrator can recover it.", responseObject = UserVmResponse.class, responseView = ResponseView.Restricted, entityType = {IAMEntityType.VirtualMachine}, +@APICommand(name = "destroyVirtualMachine", description = "Destroys a virtual machine. Once destroyed, only the administrator can recover it.", responseObject = UserVmResponse.class, responseView = ResponseView.Restricted, entityType = {VirtualMachine.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = true) -public class DestroyVMCmd extends BaseAsyncVMCmd { +public class DestroyVMCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(DestroyVMCmd.class.getName()); private static final String s_name = "destroyvirtualmachineresponse"; diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/GetVMPasswordCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/GetVMPasswordCmd.java index ebee189d35..0ba9db538a 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vm/GetVMPasswordCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vm/GetVMPasswordCmd.java @@ -20,7 +20,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ACL; import org.apache.cloudstack.api.APICommand; @@ -32,8 +31,9 @@ import com.cloud.user.Account; import com.cloud.uservm.UserVm; +import com.cloud.vm.VirtualMachine; -@APICommand(name = "getVMPassword", responseObject = GetVMPasswordResponse.class, description = "Returns an encrypted password for the VM", entityType = {IAMEntityType.VirtualMachine}, +@APICommand(name = "getVMPassword", responseObject = GetVMPasswordResponse.class, description = "Returns an encrypted password for the VM", entityType = {VirtualMachine.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class GetVMPasswordCmd extends BaseCmd { public static final Logger s_logger = Logger.getLogger(GetVMPasswordCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/ListNicsCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/ListNicsCmd.java index 408497cbc6..49402dc70d 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vm/ListNicsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vm/ListNicsCmd.java @@ -99,11 +99,10 @@ public long getEntityOwnerId() { public Boolean getDisplay() { - Account caller = CallContext.current().getCallingAccount(); - if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL) { - return true; + if (display != null) { + return display; } - return display; + return true; } ///////////////////////////////////////////////////// diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/ListVMsCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/ListVMsCmd.java index 6c95a1215e..76e3db07b7 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vm/ListVMsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vm/ListVMsCmd.java @@ -22,7 +22,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.affinity.AffinityGroupResponse; import org.apache.cloudstack.api.APICommand; @@ -46,9 +45,10 @@ import org.apache.cloudstack.api.response.ZoneResponse; import com.cloud.exception.InvalidParameterValueException; +import com.cloud.vm.VirtualMachine; -@APICommand(name = "listVirtualMachines", description = "List the virtual machines owned by the account.", responseObject = UserVmResponse.class, responseView = ResponseView.Restricted, entityType = { IAMEntityType.VirtualMachine }, +@APICommand(name = "listVirtualMachines", description = "List the virtual machines owned by the account.", responseObject = UserVmResponse.class, responseView = ResponseView.Restricted, entityType = {VirtualMachine.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = true) public class ListVMsCmd extends BaseListTaggedResourcesCmd { public static final Logger s_logger = Logger.getLogger(ListVMsCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/RebootVMCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/RebootVMCmd.java index 0f041148cd..e7a0c16b10 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vm/RebootVMCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vm/RebootVMCmd.java @@ -16,16 +16,15 @@ // under the License. package org.apache.cloudstack.api.command.user.vm; -import org.apache.cloudstack.api.BaseAsyncVMCmd; import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; 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.ResponseObject.ResponseView; import org.apache.cloudstack.api.ServerApiException; @@ -37,10 +36,11 @@ import com.cloud.exception.ResourceUnavailableException; import com.cloud.user.Account; import com.cloud.uservm.UserVm; +import com.cloud.vm.VirtualMachine; -@APICommand(name = "rebootVirtualMachine", description = "Reboots a virtual machine.", responseObject = UserVmResponse.class, responseView = ResponseView.Restricted, entityType = {IAMEntityType.VirtualMachine}, +@APICommand(name = "rebootVirtualMachine", description = "Reboots a virtual machine.", responseObject = UserVmResponse.class, responseView = ResponseView.Restricted, entityType = {VirtualMachine.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = true) -public class RebootVMCmd extends BaseAsyncVMCmd { +public class RebootVMCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(RebootVMCmd.class.getName()); private static final String s_name = "rebootvirtualmachineresponse"; diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/RemoveIpFromVmNicCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/RemoveIpFromVmNicCmd.java index 75eafa9503..70d5b48a16 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vm/RemoveIpFromVmNicCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vm/RemoveIpFromVmNicCmd.java @@ -131,6 +131,13 @@ public NetworkType getNetworkType() { return null; } + + private boolean isZoneSGEnabled() { + Network ntwk = _entityMgr.findById(Network.class, getNetworkId()); + DataCenter dc = _entityMgr.findById(DataCenter.class, ntwk.getDataCenterId()); + return dc.isSecurityGroupEnabled(); + } + @Override public void execute() throws InvalidParameterValueException { CallContext.current().setEventDetails("Ip Id: " + id); @@ -140,7 +147,7 @@ public void execute() throws InvalidParameterValueException { throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Invalid IP id is passed"); } - if (getNetworkType() == NetworkType.Basic) { + if (isZoneSGEnabled()) { //remove the security group rules for this secondary ip boolean success = false; success = _securityGroupService.securityGroupRulesForVmSecIp(nicSecIp.getNicId(), nicSecIp.getIp4Address(), false); diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/RemoveNicFromVMCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/RemoveNicFromVMCmd.java index 44dfcf61af..d740260fc6 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vm/RemoveNicFromVMCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vm/RemoveNicFromVMCmd.java @@ -21,7 +21,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ACL; import org.apache.cloudstack.api.APICommand; @@ -39,8 +38,9 @@ import com.cloud.event.EventTypes; import com.cloud.user.Account; import com.cloud.uservm.UserVm; +import com.cloud.vm.VirtualMachine; -@APICommand(name = "removeNicFromVirtualMachine", description = "Removes VM from specified network by deleting a NIC", responseObject = UserVmResponse.class, responseView = ResponseView.Restricted, entityType = {IAMEntityType.VirtualMachine}, +@APICommand(name = "removeNicFromVirtualMachine", description = "Removes VM from specified network by deleting a NIC", responseObject = UserVmResponse.class, responseView = ResponseView.Restricted, entityType = {VirtualMachine.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = true) public class RemoveNicFromVMCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(RemoveNicFromVMCmd.class); diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/ResetVMPasswordCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/ResetVMPasswordCmd.java index 615ef69369..365f3ed16a 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vm/ResetVMPasswordCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vm/ResetVMPasswordCmd.java @@ -16,16 +16,15 @@ // under the License. package org.apache.cloudstack.api.command.user.vm; -import org.apache.cloudstack.api.BaseAsyncVMCmd; import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; 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.ResponseObject.ResponseView; import org.apache.cloudstack.api.ServerApiException; @@ -37,12 +36,13 @@ import com.cloud.exception.ResourceUnavailableException; import com.cloud.user.Account; import com.cloud.uservm.UserVm; +import com.cloud.vm.VirtualMachine; @APICommand(name = "resetPasswordForVirtualMachine", responseObject=UserVmResponse.class, description="Resets the password for virtual machine. " + "The virtual machine must be in a \"Stopped\" state and the template must already " + - "support this feature for this command to take effect. [async]", responseView = ResponseView.Restricted, entityType = {IAMEntityType.VirtualMachine}, + "support this feature for this command to take effect. [async]", responseView = ResponseView.Restricted, entityType = {VirtualMachine.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = true) -public class ResetVMPasswordCmd extends BaseAsyncVMCmd { +public class ResetVMPasswordCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(ResetVMPasswordCmd.class.getName()); private static final String s_name = "resetpasswordforvirtualmachineresponse"; diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/ResetVMSSHKeyCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/ResetVMSSHKeyCmd.java index 7d43853149..db2c7ff87d 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vm/ResetVMSSHKeyCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vm/ResetVMSSHKeyCmd.java @@ -17,16 +17,15 @@ package org.apache.cloudstack.api.command.user.vm; -import org.apache.cloudstack.api.BaseAsyncVMCmd; import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; 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.ResponseObject.ResponseView; import org.apache.cloudstack.api.ServerApiException; @@ -40,11 +39,12 @@ import com.cloud.exception.ResourceUnavailableException; import com.cloud.user.Account; import com.cloud.uservm.UserVm; +import com.cloud.vm.VirtualMachine; @APICommand(name = "resetSSHKeyForVirtualMachine", responseObject = UserVmResponse.class, description = "Resets the SSH Key for virtual machine. " + - "The virtual machine must be in a \"Stopped\" state. [async]", responseView = ResponseView.Restricted, entityType = {IAMEntityType.VirtualMachine}, + "The virtual machine must be in a \"Stopped\" state. [async]", responseView = ResponseView.Restricted, entityType = {VirtualMachine.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = true) -public class ResetVMSSHKeyCmd extends BaseAsyncVMCmd { +public class ResetVMSSHKeyCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(ResetVMSSHKeyCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/RestoreVMCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/RestoreVMCmd.java index 0d5ef70bee..44265a32f5 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vm/RestoreVMCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vm/RestoreVMCmd.java @@ -16,15 +16,14 @@ // under the License. package org.apache.cloudstack.api.command.user.vm; -import org.apache.cloudstack.api.BaseAsyncVMCmd; import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; 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.ResponseObject.ResponseView; import org.apache.cloudstack.api.ServerApiException; @@ -39,11 +38,12 @@ import com.cloud.exception.ResourceUnavailableException; import com.cloud.user.Account; import com.cloud.uservm.UserVm; +import com.cloud.vm.VirtualMachine; -@APICommand(name = "restoreVirtualMachine", description = "Restore a VM to original template/ISO or new template/ISO", responseObject = UserVmResponse.class, since = "3.0.0", responseView = ResponseView.Restricted, entityType = {IAMEntityType.VirtualMachine}, +@APICommand(name = "restoreVirtualMachine", description = "Restore a VM to original template/ISO or new template/ISO", responseObject = UserVmResponse.class, since = "3.0.0", responseView = ResponseView.Restricted, entityType = {VirtualMachine.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = true) -public class RestoreVMCmd extends BaseAsyncVMCmd { +public class RestoreVMCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(RestoreVMCmd.class); private static final String s_name = "restorevmresponse"; @@ -106,7 +106,6 @@ public Long getTemplateId() { } // TODO - Remove vmid param and make it "id" in 5.0 so that we dont have two getters - @Override public Long getId() { return getVmId(); } diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/ScaleVMCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/ScaleVMCmd.java index d668ad4fed..661100b533 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vm/ScaleVMCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vm/ScaleVMCmd.java @@ -24,13 +24,12 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; 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.BaseAsyncVMCmd; +import org.apache.cloudstack.api.BaseAsyncCmd; import org.apache.cloudstack.api.BaseCmd; import org.apache.cloudstack.api.Parameter; import org.apache.cloudstack.api.ResponseObject.ResponseView; @@ -46,11 +45,12 @@ import com.cloud.exception.VirtualMachineMigrationException; import com.cloud.user.Account; import com.cloud.uservm.UserVm; +import com.cloud.vm.VirtualMachine; -@APICommand(name = "scaleVirtualMachine", description = "Scales the virtual machine to a new service offering.", responseObject = SuccessResponse.class, responseView = ResponseView.Restricted, entityType = {IAMEntityType.VirtualMachine}, +@APICommand(name = "scaleVirtualMachine", description = "Scales the virtual machine to a new service offering.", responseObject = SuccessResponse.class, responseView = ResponseView.Restricted, entityType = {VirtualMachine.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) -public class ScaleVMCmd extends BaseAsyncVMCmd { +public class ScaleVMCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(ScaleVMCmd.class.getName()); private static final String s_name = "scalevirtualmachineresponse"; diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/StartVMCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/StartVMCmd.java index 13b7442eaf..8289412404 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vm/StartVMCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vm/StartVMCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ACL; @@ -26,7 +25,7 @@ import org.apache.cloudstack.api.ApiCommandJobType; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.ApiErrorCode; -import org.apache.cloudstack.api.BaseAsyncVMCmd; +import org.apache.cloudstack.api.BaseAsyncCmd; import org.apache.cloudstack.api.Parameter; import org.apache.cloudstack.api.ResponseObject.ResponseView; import org.apache.cloudstack.api.ServerApiException; @@ -44,10 +43,11 @@ import com.cloud.user.Account; import com.cloud.uservm.UserVm; import com.cloud.utils.exception.ExecutionException; +import com.cloud.vm.VirtualMachine; -@APICommand(name = "startVirtualMachine", responseObject = UserVmResponse.class, description = "Starts a virtual machine.", responseView = ResponseView.Restricted, entityType = {IAMEntityType.VirtualMachine}, +@APICommand(name = "startVirtualMachine", responseObject = UserVmResponse.class, description = "Starts a virtual machine.", responseView = ResponseView.Restricted, entityType = {VirtualMachine.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = true) -public class StartVMCmd extends BaseAsyncVMCmd { +public class StartVMCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(StartVMCmd.class.getName()); private static final String s_name = "startvirtualmachineresponse"; @@ -74,7 +74,6 @@ public class StartVMCmd extends BaseAsyncVMCmd { // ///////////////// Accessors /////////////////////// // /////////////////////////////////////////////////// - @Override public Long getId() { return id; } diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/StopVMCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/StopVMCmd.java index 6db5d18d30..ece41b8dcc 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vm/StopVMCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vm/StopVMCmd.java @@ -16,16 +16,15 @@ // under the License. package org.apache.cloudstack.api.command.user.vm; -import org.apache.cloudstack.api.BaseAsyncVMCmd; import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; 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.ResponseObject.ResponseView; import org.apache.cloudstack.api.ServerApiException; @@ -36,10 +35,11 @@ import com.cloud.exception.ConcurrentOperationException; import com.cloud.user.Account; import com.cloud.uservm.UserVm; +import com.cloud.vm.VirtualMachine; -@APICommand(name = "stopVirtualMachine", responseObject = UserVmResponse.class, description = "Stops a virtual machine.", responseView = ResponseView.Restricted, entityType = {IAMEntityType.VirtualMachine}, +@APICommand(name = "stopVirtualMachine", responseObject = UserVmResponse.class, description = "Stops a virtual machine.", responseView = ResponseView.Restricted, entityType = {VirtualMachine.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = true) -public class StopVMCmd extends BaseAsyncVMCmd { +public class StopVMCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(StopVMCmd.class.getName()); private static final String s_name = "stopvirtualmachineresponse"; diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/UpdateDefaultNicForVMCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/UpdateDefaultNicForVMCmd.java index c70f7e502d..cffd903792 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vm/UpdateDefaultNicForVMCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vm/UpdateDefaultNicForVMCmd.java @@ -21,7 +21,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ACL; import org.apache.cloudstack.api.APICommand; @@ -39,8 +38,9 @@ import com.cloud.event.EventTypes; import com.cloud.user.Account; import com.cloud.uservm.UserVm; +import com.cloud.vm.VirtualMachine; -@APICommand(name = "updateDefaultNicForVirtualMachine", description = "Changes the default NIC on a VM", responseObject = UserVmResponse.class, responseView = ResponseView.Restricted, entityType = {IAMEntityType.VirtualMachine}, +@APICommand(name = "updateDefaultNicForVirtualMachine", description = "Changes the default NIC on a VM", responseObject = UserVmResponse.class, responseView = ResponseView.Restricted, entityType = {VirtualMachine.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = true) public class UpdateDefaultNicForVMCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(UpdateDefaultNicForVMCmd.class); diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/UpdateVMCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/UpdateVMCmd.java index fac82aac9b..7938c56671 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vm/UpdateVMCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vm/UpdateVMCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ACL; @@ -37,10 +36,11 @@ import com.cloud.exception.ResourceUnavailableException; import com.cloud.user.Account; import com.cloud.uservm.UserVm; +import com.cloud.vm.VirtualMachine; @APICommand(name = "updateVirtualMachine", description="Updates properties of a virtual machine. The VM has to be stopped and restarted for the " + "new properties to take effect. UpdateVirtualMachine does not first check whether the VM is stopped. " + - "Therefore, stop the VM manually before issuing this call.", responseObject = UserVmResponse.class, responseView = ResponseView.Restricted, entityType = {IAMEntityType.VirtualMachine}, + "Therefore, stop the VM manually before issuing this call.", responseObject = UserVmResponse.class, responseView = ResponseView.Restricted, entityType = {VirtualMachine.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = true) public class UpdateVMCmd extends BaseCustomIdCmd { public static final Logger s_logger = Logger.getLogger(UpdateVMCmd.class.getName()); @@ -150,16 +150,6 @@ public long getEntityOwnerId() { return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked } - @Override - public boolean isDisplayResourceEnabled(){ - UserVm userVm = _entityMgr.findById(UserVm.class, getId()); - if (userVm != null) { - return userVm.isDisplayVm(); - } - - return true; // no info means true - } - @Override public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException { CallContext.current().setEventDetails("Vm Id: " + getId()); diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/UpgradeVMCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/UpgradeVMCmd.java index 3560b04098..b10555556b 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vm/UpgradeVMCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vm/UpgradeVMCmd.java @@ -23,7 +23,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ACL; import org.apache.cloudstack.api.APICommand; @@ -42,10 +41,11 @@ import com.cloud.offering.ServiceOffering; import com.cloud.user.Account; import com.cloud.uservm.UserVm; +import com.cloud.vm.VirtualMachine; @APICommand(name = "changeServiceForVirtualMachine", responseObject=UserVmResponse.class, description="Changes the service offering for a virtual machine. " + "The virtual machine must be in a \"Stopped\" state for " + - "this command to take effect.", responseView = ResponseView.Restricted, entityType = {IAMEntityType.VirtualMachine}, + "this command to take effect.", responseView = ResponseView.Restricted, entityType = {VirtualMachine.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = true) public class UpgradeVMCmd extends BaseCmd { public static final Logger s_logger = Logger.getLogger(UpgradeVMCmd.class.getName()); @@ -117,11 +117,6 @@ public long getEntityOwnerId() { return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked } - @Override - public boolean isDisplayResourceEnabled(){ - return _userVmService.isDisplayResourceEnabled(getId()); - } - @Override public void execute() throws ResourceAllocationException { CallContext.current().setEventDetails("Vm Id: " + getId()); diff --git a/api/src/org/apache/cloudstack/api/command/user/vmgroup/CreateVMGroupCmd.java b/api/src/org/apache/cloudstack/api/command/user/vmgroup/CreateVMGroupCmd.java index 104cfa3672..6947f15059 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vmgroup/CreateVMGroupCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vmgroup/CreateVMGroupCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.ApiErrorCode; @@ -32,7 +31,7 @@ import com.cloud.vm.InstanceGroup; -@APICommand(name = "createInstanceGroup", description = "Creates a vm group", responseObject = InstanceGroupResponse.class, entityType = {IAMEntityType.InstanceGroup}, +@APICommand(name = "createInstanceGroup", description = "Creates a vm group", responseObject = InstanceGroupResponse.class, entityType = {InstanceGroup.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class CreateVMGroupCmd extends BaseCmd { public static final Logger s_logger = Logger.getLogger(CreateVMGroupCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/vmgroup/DeleteVMGroupCmd.java b/api/src/org/apache/cloudstack/api/command/user/vmgroup/DeleteVMGroupCmd.java index 0bc52369d2..8311eccf99 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vmgroup/DeleteVMGroupCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vmgroup/DeleteVMGroupCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ACL; import org.apache.cloudstack.api.APICommand; @@ -33,7 +32,7 @@ import com.cloud.user.Account; import com.cloud.vm.InstanceGroup; -@APICommand(name = "deleteInstanceGroup", description = "Deletes a vm group", responseObject = SuccessResponse.class, entityType = {IAMEntityType.InstanceGroup}, +@APICommand(name = "deleteInstanceGroup", description = "Deletes a vm group", responseObject = SuccessResponse.class, entityType = {InstanceGroup.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class DeleteVMGroupCmd extends BaseCmd { public static final Logger s_logger = Logger.getLogger(DeleteVMGroupCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/vmgroup/ListVMGroupsCmd.java b/api/src/org/apache/cloudstack/api/command/user/vmgroup/ListVMGroupsCmd.java index e9844dd19a..73fdb8aa18 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vmgroup/ListVMGroupsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vmgroup/ListVMGroupsCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseListProjectAndAccountResourcesCmd; @@ -26,7 +25,9 @@ import org.apache.cloudstack.api.response.InstanceGroupResponse; import org.apache.cloudstack.api.response.ListResponse; -@APICommand(name = "listInstanceGroups", description = "Lists vm groups", responseObject = InstanceGroupResponse.class, entityType = {IAMEntityType.InstanceGroup}, +import com.cloud.vm.InstanceGroup; + +@APICommand(name = "listInstanceGroups", description = "Lists vm groups", responseObject = InstanceGroupResponse.class, entityType = {InstanceGroup.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class ListVMGroupsCmd extends BaseListProjectAndAccountResourcesCmd { public static final Logger s_logger = Logger.getLogger(ListVMGroupsCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/vmgroup/UpdateVMGroupCmd.java b/api/src/org/apache/cloudstack/api/command/user/vmgroup/UpdateVMGroupCmd.java index e06ec52e1a..befa46c9ce 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vmgroup/UpdateVMGroupCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vmgroup/UpdateVMGroupCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ACL; import org.apache.cloudstack.api.APICommand; @@ -32,7 +31,7 @@ import com.cloud.user.Account; import com.cloud.vm.InstanceGroup; -@APICommand(name = "updateInstanceGroup", description = "Updates a vm group", responseObject = InstanceGroupResponse.class, entityType = {IAMEntityType.InstanceGroup}, +@APICommand(name = "updateInstanceGroup", description = "Updates a vm group", responseObject = InstanceGroupResponse.class, entityType = {InstanceGroup.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class UpdateVMGroupCmd extends BaseCmd { diff --git a/api/src/org/apache/cloudstack/api/command/user/vmsnapshot/CreateVMSnapshotCmd.java b/api/src/org/apache/cloudstack/api/command/user/vmsnapshot/CreateVMSnapshotCmd.java index fae0e61723..10ff5cddb1 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vmsnapshot/CreateVMSnapshotCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vmsnapshot/CreateVMSnapshotCmd.java @@ -19,7 +19,6 @@ import java.util.logging.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ACL; import org.apache.cloudstack.api.APICommand; @@ -37,7 +36,7 @@ import com.cloud.uservm.UserVm; import com.cloud.vm.snapshot.VMSnapshot; -@APICommand(name = "createVMSnapshot", description = "Creates snapshot for a vm.", responseObject = VMSnapshotResponse.class, since = "4.2.0", entityType = {IAMEntityType.VMSnapshot}, +@APICommand(name = "createVMSnapshot", description = "Creates snapshot for a vm.", responseObject = VMSnapshotResponse.class, since = "4.2.0", entityType = {VMSnapshot.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class CreateVMSnapshotCmd extends BaseAsyncCreateCmd { diff --git a/api/src/org/apache/cloudstack/api/command/user/vmsnapshot/DeleteVMSnapshotCmd.java b/api/src/org/apache/cloudstack/api/command/user/vmsnapshot/DeleteVMSnapshotCmd.java index af076cff57..7baad7cd59 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vmsnapshot/DeleteVMSnapshotCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vmsnapshot/DeleteVMSnapshotCmd.java @@ -19,7 +19,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ACL; import org.apache.cloudstack.api.APICommand; @@ -36,7 +35,7 @@ import com.cloud.user.Account; import com.cloud.vm.snapshot.VMSnapshot; -@APICommand(name = "deleteVMSnapshot", description = "Deletes a vmsnapshot.", responseObject = SuccessResponse.class, since = "4.2.0", entityType = {IAMEntityType.VMSnapshot}, +@APICommand(name = "deleteVMSnapshot", description = "Deletes a vmsnapshot.", responseObject = SuccessResponse.class, since = "4.2.0", entityType = {VMSnapshot.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class DeleteVMSnapshotCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(DeleteVMSnapshotCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/vmsnapshot/ListVMSnapshotCmd.java b/api/src/org/apache/cloudstack/api/command/user/vmsnapshot/ListVMSnapshotCmd.java index 3167d09f01..c9bc2430d2 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vmsnapshot/ListVMSnapshotCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vmsnapshot/ListVMSnapshotCmd.java @@ -20,7 +20,6 @@ import java.util.ArrayList; import java.util.List; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseListTaggedResourcesCmd; @@ -31,7 +30,7 @@ import com.cloud.vm.snapshot.VMSnapshot; -@APICommand(name = "listVMSnapshot", description = "List virtual machine snapshot by conditions", responseObject = VMSnapshotResponse.class, since = "4.2.0", entityType = {IAMEntityType.VMSnapshot}, +@APICommand(name = "listVMSnapshot", description = "List virtual machine snapshot by conditions", responseObject = VMSnapshotResponse.class, since = "4.2.0", entityType = {VMSnapshot.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class ListVMSnapshotCmd extends BaseListTaggedResourcesCmd { diff --git a/api/src/org/apache/cloudstack/api/command/user/volume/AttachVolumeCmd.java b/api/src/org/apache/cloudstack/api/command/user/volume/AttachVolumeCmd.java index f9d9081f36..467ffc4afd 100644 --- a/api/src/org/apache/cloudstack/api/command/user/volume/AttachVolumeCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/volume/AttachVolumeCmd.java @@ -16,16 +16,15 @@ // under the License. package org.apache.cloudstack.api.command.user.volume; +import org.apache.cloudstack.api.BaseAsyncCmd; import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; 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.BaseAsyncVolumeCmd; import org.apache.cloudstack.api.Parameter; import org.apache.cloudstack.api.ResponseObject.ResponseView; import org.apache.cloudstack.api.ServerApiException; @@ -36,10 +35,11 @@ import com.cloud.event.EventTypes; import com.cloud.storage.Volume; import com.cloud.user.Account; +import com.cloud.vm.VirtualMachine; -@APICommand(name = "attachVolume", description = "Attaches a disk volume to a virtual machine.", responseObject = VolumeResponse.class, responseView = ResponseView.Restricted, entityType = {IAMEntityType.VirtualMachine}, +@APICommand(name = "attachVolume", description = "Attaches a disk volume to a virtual machine.", responseObject = VolumeResponse.class, responseView = ResponseView.Restricted, entityType = {VirtualMachine.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) -public class AttachVolumeCmd extends BaseAsyncVolumeCmd { +public class AttachVolumeCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(AttachVolumeCmd.class.getName()); private static final String s_name = "attachvolumeresponse"; @@ -68,7 +68,6 @@ public Long getDeviceId() { return deviceId; } - @Override public Long getId() { return id; } diff --git a/api/src/org/apache/cloudstack/api/command/user/volume/CreateVolumeCmd.java b/api/src/org/apache/cloudstack/api/command/user/volume/CreateVolumeCmd.java index 9b83f61b0b..1e3c01cec9 100644 --- a/api/src/org/apache/cloudstack/api/command/user/volume/CreateVolumeCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/volume/CreateVolumeCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiCommandJobType; @@ -42,8 +41,10 @@ import com.cloud.exception.ResourceAllocationException; import com.cloud.storage.Snapshot; import com.cloud.storage.Volume; +import com.cloud.vm.VirtualMachine; -@APICommand(name = "createVolume", responseObject = VolumeResponse.class, description = "Creates a disk volume from a disk offering. This disk volume must still be attached to a virtual machine to make use of it.", responseView = ResponseView.Restricted, entityType = {IAMEntityType.Volume}, +@APICommand(name = "createVolume", responseObject = VolumeResponse.class, description = "Creates a disk volume from a disk offering. This disk volume must still be attached to a virtual machine to make use of it.", responseView = ResponseView.Restricted, entityType = { + Volume.class, VirtualMachine.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class CreateVolumeCmd extends BaseAsyncCreateCustomIdCmd { public static final Logger s_logger = Logger.getLogger(CreateVolumeCmd.class.getName()); @@ -156,6 +157,14 @@ public Boolean getDisplayVolume() { return displayVolume; } + @Override + public boolean isDisplay() { + if(displayVolume == null) + return true; + else + return displayVolume; + } + public Long getVirtualMachineId() { return virtualMachineId; } @@ -192,16 +201,6 @@ public String getEventType() { return EventTypes.EVENT_VOLUME_CREATE; } - @Override - public boolean isDisplayResourceEnabled(){ - Boolean display = getDisplayVolume(); - if(display == null){ - return true; - } else { - return display; - } - } - @Override public String getEventDescription() { return "creating volume: " + getVolumeName() + ((getSnapshotId() == null) ? "" : " from snapshot: " + getSnapshotId()); diff --git a/api/src/org/apache/cloudstack/api/command/user/volume/DeleteVolumeCmd.java b/api/src/org/apache/cloudstack/api/command/user/volume/DeleteVolumeCmd.java index 6ca96b08b0..0b0c1b7303 100644 --- a/api/src/org/apache/cloudstack/api/command/user/volume/DeleteVolumeCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/volume/DeleteVolumeCmd.java @@ -17,7 +17,6 @@ package org.apache.cloudstack.api.command.user.volume; import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ACL; import org.apache.cloudstack.api.APICommand; @@ -34,7 +33,7 @@ import com.cloud.storage.Volume; import com.cloud.user.Account; -@APICommand(name = "deleteVolume", description = "Deletes a detached disk volume.", responseObject = SuccessResponse.class, entityType = {IAMEntityType.Volume}, +@APICommand(name = "deleteVolume", description = "Deletes a detached disk volume.", responseObject = SuccessResponse.class, entityType = {Volume.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class DeleteVolumeCmd extends BaseCmd { public static final Logger s_logger = Logger.getLogger(DeleteVolumeCmd.class.getName()); @@ -80,11 +79,6 @@ public long getEntityOwnerId() { return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked } - @Override - public boolean isDisplayResourceEnabled(){ - return _volumeService.isDisplayResourceEnabled(getId()); - } - @Override public void execute() throws ConcurrentOperationException { CallContext.current().setEventDetails("Volume Id: " + getId()); diff --git a/api/src/org/apache/cloudstack/api/command/user/volume/DetachVolumeCmd.java b/api/src/org/apache/cloudstack/api/command/user/volume/DetachVolumeCmd.java index bfd032203c..cad0a7ffe0 100644 --- a/api/src/org/apache/cloudstack/api/command/user/volume/DetachVolumeCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/volume/DetachVolumeCmd.java @@ -16,16 +16,15 @@ // under the License. package org.apache.cloudstack.api.command.user.volume; +import org.apache.cloudstack.api.BaseAsyncCmd; import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; 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.BaseAsyncVolumeCmd; import org.apache.cloudstack.api.Parameter; import org.apache.cloudstack.api.ResponseObject.ResponseView; import org.apache.cloudstack.api.ServerApiException; @@ -37,10 +36,11 @@ import com.cloud.storage.Volume; import com.cloud.user.Account; import com.cloud.uservm.UserVm; +import com.cloud.vm.VirtualMachine; -@APICommand(name = "detachVolume", description = "Detaches a disk volume from a virtual machine.", responseObject = VolumeResponse.class, responseView = ResponseView.Restricted, entityType = {IAMEntityType.Volume}, +@APICommand(name = "detachVolume", description = "Detaches a disk volume from a virtual machine.", responseObject = VolumeResponse.class, responseView = ResponseView.Restricted, entityType = {VirtualMachine.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) -public class DetachVolumeCmd extends BaseAsyncVolumeCmd { +public class DetachVolumeCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(DetachVolumeCmd.class.getName()); private static final String s_name = "detachvolumeresponse"; @@ -48,7 +48,6 @@ public class DetachVolumeCmd extends BaseAsyncVolumeCmd { //////////////// API parameters ///////////////////// ///////////////////////////////////////////////////// - @ACL(accessType = AccessType.OperateEntry) @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=VolumeResponse.class, description="the ID of the disk volume") private Long id; @@ -56,6 +55,7 @@ public class DetachVolumeCmd extends BaseAsyncVolumeCmd { @Parameter(name = ApiConstants.DEVICE_ID, type = CommandType.LONG, description = "the device ID on the virtual machine where volume is detached from") private Long deviceId; + @ACL(accessType = AccessType.OperateEntry) @Parameter(name = ApiConstants.VIRTUAL_MACHINE_ID, type = CommandType.UUID, entityType = UserVmResponse.class, @@ -66,7 +66,6 @@ public class DetachVolumeCmd extends BaseAsyncVolumeCmd { /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// - @Override public Long getId() { return id; } diff --git a/api/src/org/apache/cloudstack/api/command/user/volume/ExtractVolumeCmd.java b/api/src/org/apache/cloudstack/api/command/user/volume/ExtractVolumeCmd.java index cc7f56cc7b..049396c370 100644 --- a/api/src/org/apache/cloudstack/api/command/user/volume/ExtractVolumeCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/volume/ExtractVolumeCmd.java @@ -16,16 +16,15 @@ // under the License. package org.apache.cloudstack.api.command.user.volume; -import org.apache.cloudstack.api.BaseAsyncVolumeCmd; import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; 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.ExtractResponse; @@ -39,9 +38,9 @@ import com.cloud.storage.Volume; import com.cloud.user.Account; -@APICommand(name = "extractVolume", description = "Extracts volume", responseObject = ExtractResponse.class, entityType = {IAMEntityType.Volume}, +@APICommand(name = "extractVolume", description = "Extracts volume", responseObject = ExtractResponse.class, entityType = {Volume.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) -public class ExtractVolumeCmd extends BaseAsyncVolumeCmd { +public class ExtractVolumeCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(ExtractVolumeCmd.class.getName()); private static final String s_name = "extractvolumeresponse"; diff --git a/api/src/org/apache/cloudstack/api/command/user/volume/ListResourceDetailsCmd.java b/api/src/org/apache/cloudstack/api/command/user/volume/ListResourceDetailsCmd.java index 0aeff0c63c..47f80a034f 100644 --- a/api/src/org/apache/cloudstack/api/command/user/volume/ListResourceDetailsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/volume/ListResourceDetailsCmd.java @@ -19,6 +19,7 @@ import java.util.List; +import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseListProjectAndAccountResourcesCmd; @@ -26,7 +27,6 @@ import org.apache.cloudstack.api.response.ListResponse; import org.apache.cloudstack.api.response.ResourceDetailResponse; import org.apache.cloudstack.api.response.ResourceTagResponse; -import org.apache.cloudstack.context.CallContext; import com.cloud.server.ResourceTag; @@ -44,8 +44,12 @@ public class ListResourceDetailsCmd extends BaseListProjectAndAccountResourcesCm @Parameter(name = ApiConstants.KEY, type = CommandType.STRING, description = "list by key") private String key; + @Parameter(name = ApiConstants.VALUE, type = CommandType.STRING, description = "list by key, value. Needs to be passed only along with key" , + since = "4.4", authorized = { RoleType.Admin }) + private String value; + @Parameter(name = ApiConstants.FOR_DISPLAY, type = CommandType.BOOLEAN, description = "if set to true, only details marked with display=true, are returned." - + " Always false is the call is made by the regular user", since = "4.3") + + " False by default", since = "4.3", authorized = { RoleType.Admin }) private Boolean forDisplay; public String getResourceId() { @@ -56,17 +60,21 @@ public String getKey() { return key; } + public String getValue() { + return value; + } + @Override public String getCommandName() { return s_name; } - public Boolean forDisplay() { - if (!_accountService.isAdmin(CallContext.current().getCallingAccount().getType())) { - return true; + @Override + public Boolean getDisplay() { + if (forDisplay != null) { + return forDisplay; } - - return forDisplay; + return super.getDisplay(); } ///////////////////////////////////////////////////// diff --git a/api/src/org/apache/cloudstack/api/command/user/volume/ListVolumesCmd.java b/api/src/org/apache/cloudstack/api/command/user/volume/ListVolumesCmd.java index b4ac4ae64c..cc218f7197 100644 --- a/api/src/org/apache/cloudstack/api/command/user/volume/ListVolumesCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/volume/ListVolumesCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiCommandJobType; @@ -35,7 +34,9 @@ import org.apache.cloudstack.api.response.VolumeResponse; import org.apache.cloudstack.api.response.ZoneResponse; -@APICommand(name = "listVolumes", description = "Lists all volumes.", responseObject = VolumeResponse.class, responseView = ResponseView.Restricted, entityType = { IAMEntityType.Volume }, +import com.cloud.storage.Volume; + +@APICommand(name = "listVolumes", description = "Lists all volumes.", responseObject = VolumeResponse.class, responseView = ResponseView.Restricted, entityType = {Volume.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class ListVolumesCmd extends BaseListTaggedResourcesCmd { public static final Logger s_logger = Logger.getLogger(ListVolumesCmd.class.getName()); @@ -75,7 +76,11 @@ public class ListVolumesCmd extends BaseListTaggedResourcesCmd { authorized = {RoleType.Admin}) private Long storageId; - @Parameter(name = ApiConstants.DISK_OFFERING_ID, type = CommandType.UUID, entityType = DiskOfferingResponse.class, description = "list volumes by disk offering") + @Parameter(name = ApiConstants.DISK_OFFERING_ID, + type = CommandType.UUID, + entityType = DiskOfferingResponse.class, + description = "list volumes by disk offering", + since = "4.4") private Long diskOfferingId; @Parameter(name = ApiConstants.DISPLAY_VOLUME, type = CommandType.BOOLEAN, description = "list resources by display flag; only ROOT admin is eligible to pass this parameter", since = "4.4", authorized = {RoleType.Admin}) diff --git a/api/src/org/apache/cloudstack/api/command/user/volume/MigrateVolumeCmd.java b/api/src/org/apache/cloudstack/api/command/user/volume/MigrateVolumeCmd.java index d80595a78f..e751da342a 100644 --- a/api/src/org/apache/cloudstack/api/command/user/volume/MigrateVolumeCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/volume/MigrateVolumeCmd.java @@ -16,11 +16,10 @@ // under the License. package org.apache.cloudstack.api.command.user.volume; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.ApiErrorCode; -import org.apache.cloudstack.api.BaseAsyncVolumeCmd; +import org.apache.cloudstack.api.BaseAsyncCmd; import org.apache.cloudstack.api.Parameter; import org.apache.cloudstack.api.ResponseObject.ResponseView; import org.apache.cloudstack.api.ServerApiException; @@ -31,9 +30,9 @@ import com.cloud.storage.Volume; import com.cloud.user.Account; -@APICommand(name = "migrateVolume", description = "Migrate volume", responseObject = VolumeResponse.class, since = "3.0.0", responseView = ResponseView.Restricted, entityType = {IAMEntityType.Volume}, +@APICommand(name = "migrateVolume", description = "Migrate volume", responseObject = VolumeResponse.class, since = "3.0.0", responseView = ResponseView.Restricted, entityType = {Volume.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) -public class MigrateVolumeCmd extends BaseAsyncVolumeCmd { +public class MigrateVolumeCmd extends BaseAsyncCmd { private static final String s_name = "migratevolumeresponse"; ///////////////////////////////////////////////////// @@ -65,7 +64,6 @@ public Long getVolumeId() { return volumeId; } - @Override public Long getId() { return getVolumeId(); } diff --git a/api/src/org/apache/cloudstack/api/command/user/volume/ResizeVolumeCmd.java b/api/src/org/apache/cloudstack/api/command/user/volume/ResizeVolumeCmd.java index d5cd62bbc3..1cf4f29dc2 100644 --- a/api/src/org/apache/cloudstack/api/command/user/volume/ResizeVolumeCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/volume/ResizeVolumeCmd.java @@ -15,16 +15,15 @@ // specific language governing permissions and limitations // under the License. package org.apache.cloudstack.api.command.user.volume; +import org.apache.cloudstack.api.BaseAsyncCmd; import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; 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.BaseAsyncVolumeCmd; import org.apache.cloudstack.api.Parameter; import org.apache.cloudstack.api.ResponseObject.ResponseView; import org.apache.cloudstack.api.ServerApiException; @@ -41,9 +40,9 @@ import com.cloud.user.Account; -@APICommand(name = "resizeVolume", description = "Resizes a volume", responseObject = VolumeResponse.class, responseView = ResponseView.Restricted, entityType = {IAMEntityType.Volume}, +@APICommand(name = "resizeVolume", description = "Resizes a volume", responseObject = VolumeResponse.class, responseView = ResponseView.Restricted, entityType = {Volume.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) -public class ResizeVolumeCmd extends BaseAsyncVolumeCmd { +public class ResizeVolumeCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(ResizeVolumeCmd.class.getName()); private static final String s_name = "resizevolumeresponse"; @@ -78,7 +77,6 @@ public Long getEntityId() { return id; } - @Override public Long getId() { return getEntityId(); } diff --git a/api/src/org/apache/cloudstack/api/command/user/volume/UpdateVolumeCmd.java b/api/src/org/apache/cloudstack/api/command/user/volume/UpdateVolumeCmd.java index 05e461e5ec..e7e3820da4 100644 --- a/api/src/org/apache/cloudstack/api/command/user/volume/UpdateVolumeCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/volume/UpdateVolumeCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ACL; @@ -38,7 +37,7 @@ import com.cloud.exception.InvalidParameterValueException; import com.cloud.storage.Volume; -@APICommand(name = "updateVolume", description = "Updates the volume.", responseObject = VolumeResponse.class, responseView = ResponseView.Restricted, entityType = { IAMEntityType.Volume }, +@APICommand(name = "updateVolume", description = "Updates the volume.", responseObject = VolumeResponse.class, responseView = ResponseView.Restricted, entityType = {Volume.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class UpdateVolumeCmd extends BaseAsyncCustomIdCmd { public static final Logger s_logger = Logger.getLogger(UpdateVolumeCmd.class.getName()); @@ -55,7 +54,10 @@ public class UpdateVolumeCmd extends BaseAsyncCustomIdCmd { @Parameter(name = ApiConstants.PATH, type = CommandType.STRING, description = "The path of the volume") private String path; - @Parameter(name = ApiConstants.CHAIN_INFO, type = CommandType.STRING, description = "The chain info of the volume") + @Parameter(name = ApiConstants.CHAIN_INFO, + type = CommandType.STRING, + description = "The chain info of the volume", + since = "4.4") private String chainInfo; @Parameter(name = ApiConstants.STORAGE_ID, @@ -128,11 +130,6 @@ public long getEntityOwnerId() { return volume.getAccountId(); } - @Override - public boolean isDisplayResourceEnabled(){ - return _volumeService.isDisplayResourceEnabled(getId()); - } - @Override public String getEventType() { return EventTypes.EVENT_VOLUME_UPDATE; diff --git a/api/src/org/apache/cloudstack/api/command/user/volume/UploadVolumeCmd.java b/api/src/org/apache/cloudstack/api/command/user/volume/UploadVolumeCmd.java index e992759224..c360c146d6 100644 --- a/api/src/org/apache/cloudstack/api/command/user/volume/UploadVolumeCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/volume/UploadVolumeCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.ApiErrorCode; @@ -26,6 +25,7 @@ import org.apache.cloudstack.api.Parameter; import org.apache.cloudstack.api.ResponseObject.ResponseView; import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.response.DiskOfferingResponse; import org.apache.cloudstack.api.response.DomainResponse; import org.apache.cloudstack.api.response.ProjectResponse; import org.apache.cloudstack.api.response.VolumeResponse; @@ -40,7 +40,7 @@ import com.cloud.exception.ResourceUnavailableException; import com.cloud.storage.Volume; -@APICommand(name = "uploadVolume", description = "Uploads a data disk.", responseObject = VolumeResponse.class, responseView = ResponseView.Restricted, entityType = {IAMEntityType.Volume}, +@APICommand(name = "uploadVolume", description = "Uploads a data disk.", responseObject = VolumeResponse.class, responseView = ResponseView.Restricted, entityType = {Volume.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class UploadVolumeCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(UploadVolumeCmd.class.getName()); @@ -90,6 +90,9 @@ public class UploadVolumeCmd extends BaseAsyncCmd { @Parameter(name = ApiConstants.PROJECT_ID, type = CommandType.UUID, entityType = ProjectResponse.class, description = "Upload volume for the project") private Long projectId; + @Parameter(name = ApiConstants.DISK_OFFERING_ID, required = false, type = CommandType.UUID, entityType = DiskOfferingResponse.class, description = "the ID of the disk offering. This must be a custom sized offering since during uploadVolume volume size is unknown.") + private Long diskOfferingId; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -126,6 +129,10 @@ public String getImageStoreUuid() { return imageStoreUuid; } + public Long getDiskOfferingId() { + return diskOfferingId; + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// diff --git a/api/src/org/apache/cloudstack/api/command/user/vpc/CreateStaticRouteCmd.java b/api/src/org/apache/cloudstack/api/command/user/vpc/CreateStaticRouteCmd.java index f2c9e2c2e2..e2f2029ce0 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vpc/CreateStaticRouteCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vpc/CreateStaticRouteCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiCommandJobType; import org.apache.cloudstack.api.ApiConstants; @@ -40,7 +39,7 @@ import com.cloud.network.vpc.Vpc; import com.cloud.network.vpc.VpcGateway; -@APICommand(name = "createStaticRoute", description = "Creates a static route", responseObject = StaticRouteResponse.class, entityType = {IAMEntityType.StaticRoute}, +@APICommand(name = "createStaticRoute", description = "Creates a static route", responseObject = StaticRouteResponse.class, entityType = {StaticRoute.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class CreateStaticRouteCmd extends BaseAsyncCreateCmd { private static final String s_name = "createstaticrouteresponse"; diff --git a/api/src/org/apache/cloudstack/api/command/user/vpc/CreateVPCCmd.java b/api/src/org/apache/cloudstack/api/command/user/vpc/CreateVPCCmd.java index c179ec857f..e2f261e1ba 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vpc/CreateVPCCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vpc/CreateVPCCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; @@ -41,7 +40,7 @@ import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.vpc.Vpc; -@APICommand(name = "createVPC", description = "Creates a VPC", responseObject = VpcResponse.class, responseView = ResponseView.Restricted, entityType = {IAMEntityType.Vpc}, +@APICommand(name = "createVPC", description = "Creates a VPC", responseObject = VpcResponse.class, responseView = ResponseView.Restricted, entityType = {Vpc.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class CreateVPCCmd extends BaseAsyncCreateCmd { public static final Logger s_logger = Logger.getLogger(CreateVPCCmd.class.getName()); @@ -65,7 +64,7 @@ public class CreateVPCCmd extends BaseAsyncCreateCmd { private Long projectId; @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, - required = true, description = "the ID of the availability zone") + required = true, description = "the ID of the availability zone") private Long zoneId; @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "the name of the VPC") diff --git a/api/src/org/apache/cloudstack/api/command/user/vpc/DeleteStaticRouteCmd.java b/api/src/org/apache/cloudstack/api/command/user/vpc/DeleteStaticRouteCmd.java index 0017753e33..9449e6d534 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vpc/DeleteStaticRouteCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vpc/DeleteStaticRouteCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ACL; import org.apache.cloudstack.api.APICommand; @@ -38,7 +37,7 @@ import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.vpc.StaticRoute; -@APICommand(name = "deleteStaticRoute", description = "Deletes a static route", responseObject = SuccessResponse.class, entityType = {IAMEntityType.StaticRoute}, +@APICommand(name = "deleteStaticRoute", description = "Deletes a static route", responseObject = SuccessResponse.class, entityType = {StaticRoute.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class DeleteStaticRouteCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(DeleteStaticRouteCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/vpc/DeleteVPCCmd.java b/api/src/org/apache/cloudstack/api/command/user/vpc/DeleteVPCCmd.java index 5928aabff6..9d13b63e6a 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vpc/DeleteVPCCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vpc/DeleteVPCCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ACL; import org.apache.cloudstack.api.APICommand; @@ -36,7 +35,7 @@ import com.cloud.network.vpc.Vpc; import com.cloud.user.Account; -@APICommand(name = "deleteVPC", description = "Deletes a VPC", responseObject = SuccessResponse.class, entityType = {IAMEntityType.Vpc}, +@APICommand(name = "deleteVPC", description = "Deletes a VPC", responseObject = SuccessResponse.class, entityType = {Vpc.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class DeleteVPCCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(DeleteVPCCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/vpc/ListPrivateGatewaysCmd.java b/api/src/org/apache/cloudstack/api/command/user/vpc/ListPrivateGatewaysCmd.java index 160355a481..a985e7633c 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vpc/ListPrivateGatewaysCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vpc/ListPrivateGatewaysCmd.java @@ -21,7 +21,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseListProjectAndAccountResourcesCmd; @@ -31,9 +30,10 @@ import org.apache.cloudstack.api.response.VpcResponse; import com.cloud.network.vpc.PrivateGateway; +import com.cloud.network.vpc.VpcGateway; import com.cloud.utils.Pair; -@APICommand(name = "listPrivateGateways", description = "List private gateways", responseObject = PrivateGatewayResponse.class, entityType = {IAMEntityType.VpcGateway}, +@APICommand(name = "listPrivateGateways", description = "List private gateways", responseObject = PrivateGatewayResponse.class, entityType = {VpcGateway.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class ListPrivateGatewaysCmd extends BaseListProjectAndAccountResourcesCmd { public static final Logger s_logger = Logger.getLogger(ListPrivateGatewaysCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/vpc/ListStaticRoutesCmd.java b/api/src/org/apache/cloudstack/api/command/user/vpc/ListStaticRoutesCmd.java index b2cdf87911..3dba84c8a7 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vpc/ListStaticRoutesCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vpc/ListStaticRoutesCmd.java @@ -19,7 +19,6 @@ import java.util.ArrayList; import java.util.List; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseListTaggedResourcesCmd; @@ -32,7 +31,7 @@ import com.cloud.network.vpc.StaticRoute; import com.cloud.utils.Pair; -@APICommand(name = "listStaticRoutes", description = "Lists all static routes", responseObject = StaticRouteResponse.class, entityType = {IAMEntityType.StaticRoute}, +@APICommand(name = "listStaticRoutes", description = "Lists all static routes", responseObject = StaticRouteResponse.class, entityType = {StaticRoute.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class ListStaticRoutesCmd extends BaseListTaggedResourcesCmd { private static final String s_name = "liststaticroutesresponse"; diff --git a/api/src/org/apache/cloudstack/api/command/user/vpc/ListVPCOfferingsCmd.java b/api/src/org/apache/cloudstack/api/command/user/vpc/ListVPCOfferingsCmd.java index 66ea17654a..e76afc92cd 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vpc/ListVPCOfferingsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vpc/ListVPCOfferingsCmd.java @@ -34,7 +34,7 @@ requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class ListVPCOfferingsCmd extends BaseListCmd { public static final Logger s_logger = Logger.getLogger(ListVPCOfferingsCmd.class.getName()); - private static final String Name = "listvpcofferingsresponse"; + private static final String s_name = "listvpcofferingsresponse"; ///////////////////////////////////////////////////// //////////////// API parameters ///////////////////// @@ -110,7 +110,7 @@ public void execute() { @Override public String getCommandName() { - return Name; + return s_name; } } diff --git a/api/src/org/apache/cloudstack/api/command/user/vpc/ListVPCsCmd.java b/api/src/org/apache/cloudstack/api/command/user/vpc/ListVPCsCmd.java index fa60f6f773..9079dff11d 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vpc/ListVPCsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vpc/ListVPCsCmd.java @@ -21,7 +21,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; @@ -36,7 +35,7 @@ import com.cloud.network.vpc.Vpc; -@APICommand(name = "listVPCs", description = "Lists VPCs", responseObject = VpcResponse.class, responseView = ResponseView.Restricted, entityType = { IAMEntityType.Vpc }, +@APICommand(name = "listVPCs", description = "Lists VPCs", responseObject = VpcResponse.class, responseView = ResponseView.Restricted, entityType = {Vpc.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class ListVPCsCmd extends BaseListTaggedResourcesCmd { public static final Logger s_logger = Logger.getLogger(ListVPCsCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/vpc/RestartVPCCmd.java b/api/src/org/apache/cloudstack/api/command/user/vpc/RestartVPCCmd.java index d1d805ae48..84e790c3b2 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vpc/RestartVPCCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vpc/RestartVPCCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ACL; import org.apache.cloudstack.api.APICommand; @@ -37,11 +36,11 @@ import com.cloud.network.vpc.Vpc; import com.cloud.user.Account; -@APICommand(name = "restartVPC", description = "Restarts a VPC", responseObject = VpcResponse.class, entityType = {IAMEntityType.Vpc}, +@APICommand(name = "restartVPC", description = "Restarts a VPC", responseObject = VpcResponse.class, entityType = {Vpc.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class RestartVPCCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(RestartVPCCmd.class.getName()); - private static final String Name = "restartvpcresponse"; + private static final String s_name = "restartvpcresponse"; ///////////////////////////////////////////////////// //////////////// API parameters ///////////////////// @@ -63,7 +62,7 @@ public Long getId() { ///////////////////////////////////////////////////// @Override public String getCommandName() { - return Name; + return s_name; } @Override diff --git a/api/src/org/apache/cloudstack/api/command/user/vpc/UpdateVPCCmd.java b/api/src/org/apache/cloudstack/api/command/user/vpc/UpdateVPCCmd.java index 76244233b9..94d0e6efcd 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vpc/UpdateVPCCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vpc/UpdateVPCCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ACL; @@ -36,11 +35,11 @@ import com.cloud.network.vpc.Vpc; import com.cloud.user.Account; -@APICommand(name = "updateVPC", description = "Updates a VPC", responseObject = VpcResponse.class, responseView = ResponseView.Restricted, entityType = { IAMEntityType.Vpc }, +@APICommand(name = "updateVPC", description = "Updates a VPC", responseObject = VpcResponse.class, responseView = ResponseView.Restricted, entityType = {Vpc.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class UpdateVPCCmd extends BaseAsyncCustomIdCmd { public static final Logger s_logger = Logger.getLogger(UpdateVPCCmd.class.getName()); - private static final String Name = "updatevpcresponse"; + private static final String s_name = "updatevpcresponse"; ///////////////////////////////////////////////////// //////////////// API parameters ///////////////////// @@ -83,7 +82,7 @@ public Boolean getDisplayVpc() { ///////////////////////////////////////////////////// @Override public String getCommandName() { - return Name; + return s_name; } @Override diff --git a/api/src/org/apache/cloudstack/api/command/user/vpn/AddVpnUserCmd.java b/api/src/org/apache/cloudstack/api/command/user/vpn/AddVpnUserCmd.java index e839f9feff..9993102eca 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vpn/AddVpnUserCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vpn/AddVpnUserCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.ApiErrorCode; @@ -35,7 +34,7 @@ import com.cloud.network.VpnUser; import com.cloud.user.Account; -@APICommand(name = "addVpnUser", description = "Adds vpn users", responseObject = VpnUsersResponse.class, entityType = {IAMEntityType.VpnUser}, +@APICommand(name = "addVpnUser", description = "Adds vpn users", responseObject = VpnUsersResponse.class, entityType = {VpnUser.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class AddVpnUserCmd extends BaseAsyncCreateCmd { public static final Logger s_logger = Logger.getLogger(AddVpnUserCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/vpn/CreateRemoteAccessVpnCmd.java b/api/src/org/apache/cloudstack/api/command/user/vpn/CreateRemoteAccessVpnCmd.java index 4df21345ec..2bef64e1c6 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vpn/CreateRemoteAccessVpnCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vpn/CreateRemoteAccessVpnCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; @@ -38,7 +37,7 @@ import com.cloud.network.IpAddress; import com.cloud.network.RemoteAccessVpn; -@APICommand(name = "createRemoteAccessVpn", description = "Creates a l2tp/ipsec remote access vpn", responseObject = RemoteAccessVpnResponse.class, entityType = { IAMEntityType.RemoteAccessVpn }, +@APICommand(name = "createRemoteAccessVpn", description = "Creates a l2tp/ipsec remote access vpn", responseObject = RemoteAccessVpnResponse.class, entityType = {RemoteAccessVpn.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class CreateRemoteAccessVpnCmd extends BaseAsyncCreateCmd { public static final Logger s_logger = Logger.getLogger(CreateRemoteAccessVpnCmd.class.getName()); @@ -146,14 +145,10 @@ public String getEventType() { @Override public void create() { try { - RemoteAccessVpn vpn = _ravService.createRemoteAccessVpn(publicIpId, ipRange, getOpenFirewall(), getDisplay()); + RemoteAccessVpn vpn = _ravService.createRemoteAccessVpn(publicIpId, ipRange, getOpenFirewall(), isDisplay()); if (vpn != null) { - setEntityId(vpn.getServerAddressId()); - // find uuid for server ip address - IpAddress ipAddr = _entityMgr.findById(IpAddress.class, vpn.getServerAddressId()); - if (ipAddr != null) { - setEntityUuid(ipAddr.getUuid()); - } + setEntityId(vpn.getId()); + setEntityUuid(vpn.getUuid()); } else { throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create remote access vpn"); } @@ -199,7 +194,11 @@ private IpAddress getIp() { return ip; } - public Boolean getDisplay() { - return display; + @Override + public boolean isDisplay() { + if(display == null) + return true; + else + return display; } } diff --git a/api/src/org/apache/cloudstack/api/command/user/vpn/CreateVpnConnectionCmd.java b/api/src/org/apache/cloudstack/api/command/user/vpn/CreateVpnConnectionCmd.java index d405c17ac3..6c08a42325 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vpn/CreateVpnConnectionCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vpn/CreateVpnConnectionCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; @@ -39,7 +38,7 @@ import com.cloud.network.vpc.Vpc; -@APICommand(name = "createVpnConnection", description = "Create site to site vpn connection", responseObject = Site2SiteVpnConnectionResponse.class, entityType = { IAMEntityType.Site2SiteVpnConnection }, +@APICommand(name = "createVpnConnection", description = "Create site to site vpn connection", responseObject = Site2SiteVpnConnectionResponse.class, entityType = {Site2SiteVpnConnection.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class CreateVpnConnectionCmd extends BaseAsyncCreateCmd { public static final Logger s_logger = Logger.getLogger(CreateVpnConnectionCmd.class.getName()); @@ -88,10 +87,20 @@ public boolean isPassive() { return passive; } + @Deprecated public Boolean getDisplay() { return display; } + @Override + public boolean isDisplay() { + if (display != null) { + return display; + } else { + return true; + } + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// diff --git a/api/src/org/apache/cloudstack/api/command/user/vpn/CreateVpnCustomerGatewayCmd.java b/api/src/org/apache/cloudstack/api/command/user/vpn/CreateVpnCustomerGatewayCmd.java index 5da46f0ada..6967ff4978 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vpn/CreateVpnCustomerGatewayCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vpn/CreateVpnCustomerGatewayCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.ApiErrorCode; @@ -32,7 +31,7 @@ import com.cloud.event.EventTypes; import com.cloud.network.Site2SiteCustomerGateway; -@APICommand(name = "createVpnCustomerGateway", description = "Creates site to site vpn customer gateway", responseObject = Site2SiteCustomerGatewayResponse.class, entityType = {IAMEntityType.Site2SiteCustomerGateway}, +@APICommand(name = "createVpnCustomerGateway", description = "Creates site to site vpn customer gateway", responseObject = Site2SiteCustomerGatewayResponse.class, entityType = {Site2SiteCustomerGateway.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class CreateVpnCustomerGatewayCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(CreateVpnCustomerGatewayCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/vpn/CreateVpnGatewayCmd.java b/api/src/org/apache/cloudstack/api/command/user/vpn/CreateVpnGatewayCmd.java index 12abfb6e35..3043edcb04 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vpn/CreateVpnGatewayCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vpn/CreateVpnGatewayCmd.java @@ -16,26 +16,26 @@ // under the License. package org.apache.cloudstack.api.command.user.vpn; -import org.apache.log4j.Logger; - -import org.apache.cloudstack.acl.IAMEntityType; +import com.cloud.event.EventTypes; +import com.cloud.exception.ResourceAllocationException; +import com.cloud.network.Site2SiteVpnGateway; +import com.cloud.network.vpc.Vpc; import org.apache.cloudstack.acl.RoleType; 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.BaseAsyncCreateCmd; import org.apache.cloudstack.api.Parameter; import org.apache.cloudstack.api.ServerApiException; import org.apache.cloudstack.api.response.Site2SiteVpnGatewayResponse; import org.apache.cloudstack.api.response.VpcResponse; +import org.apache.cloudstack.context.CallContext; +import org.apache.log4j.Logger; -import com.cloud.event.EventTypes; -import com.cloud.network.Site2SiteVpnGateway; -import com.cloud.network.vpc.Vpc; - -@APICommand(name = "createVpnGateway", description = "Creates site to site vpn local gateway", responseObject = Site2SiteVpnGatewayResponse.class, entityType = { IAMEntityType.Site2SiteVpnGateway }, +@APICommand(name = "createVpnGateway", description = "Creates site to site vpn local gateway", responseObject = Site2SiteVpnGatewayResponse.class, entityType = {Site2SiteVpnGateway.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) -public class CreateVpnGatewayCmd extends BaseAsyncCmd { +public class CreateVpnGatewayCmd extends BaseAsyncCreateCmd { public static final Logger s_logger = Logger.getLogger(CreateVpnGatewayCmd.class.getName()); private static final String s_name = "createvpngatewayresponse"; @@ -61,10 +61,20 @@ public Long getVpcId() { return vpcId; } + @Deprecated public Boolean getDisplay() { return display; } + @Override + public boolean isDisplay() { + if (display != null) { + return display; + } else { + return true; + } + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// @@ -92,8 +102,8 @@ public String getEventType() { @Override public void execute() { - Site2SiteVpnGateway result; - result = _s2sVpnService.createVpnGateway(this); + CallContext.current().setEventDetails("VPN gateway Id: " + getEntityId()); + Site2SiteVpnGateway result = _s2sVpnService.getVpnGateway(getEntityId()); if (result != null) { Site2SiteVpnGatewayResponse response = _responseGenerator.createSite2SiteVpnGatewayResponse(result); response.setResponseName(getCommandName()); @@ -112,4 +122,15 @@ public String getSyncObjType() { public Long getSyncObjId() { return getVpcId(); } + + @Override + public void create() throws ResourceAllocationException { + Site2SiteVpnGateway result = _s2sVpnService.createVpnGateway(this); + if (result != null) { + setEntityId(result.getId()); + setEntityUuid(result.getUuid()); + } else { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create VPN gateway"); + } + } } diff --git a/api/src/org/apache/cloudstack/api/command/user/vpn/DeleteRemoteAccessVpnCmd.java b/api/src/org/apache/cloudstack/api/command/user/vpn/DeleteRemoteAccessVpnCmd.java index 7d0c5aa5a4..37b7b5aaa3 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vpn/DeleteRemoteAccessVpnCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vpn/DeleteRemoteAccessVpnCmd.java @@ -18,9 +18,10 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.ApiErrorCode; +import org.apache.cloudstack.api.ServerApiException; import org.apache.cloudstack.api.BaseAsyncCmd; import org.apache.cloudstack.api.Parameter; import org.apache.cloudstack.api.response.AccountResponse; @@ -33,7 +34,7 @@ import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.RemoteAccessVpn; -@APICommand(name = "deleteRemoteAccessVpn", description = "Destroys a l2tp/ipsec remote access vpn", responseObject = SuccessResponse.class, entityType = {IAMEntityType.RemoteAccessVpn}, +@APICommand(name = "deleteRemoteAccessVpn", description = "Destroys a l2tp/ipsec remote access vpn", responseObject = SuccessResponse.class, entityType = {RemoteAccessVpn.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class DeleteRemoteAccessVpnCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(DeleteRemoteAccessVpnCmd.class.getName()); @@ -92,7 +93,9 @@ public String getEventType() { @Override public void execute() throws ResourceUnavailableException { - _ravService.destroyRemoteAccessVpnForIp(publicIpId, CallContext.current().getCallingAccount()); + if (! _ravService.destroyRemoteAccessVpnForIp(publicIpId, CallContext.current().getCallingAccount())) { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to delete remote access vpn"); + } } @Override diff --git a/api/src/org/apache/cloudstack/api/command/user/vpn/DeleteVpnConnectionCmd.java b/api/src/org/apache/cloudstack/api/command/user/vpn/DeleteVpnConnectionCmd.java index 6034bcb0de..a76b0c804e 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vpn/DeleteVpnConnectionCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vpn/DeleteVpnConnectionCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.ApiErrorCode; @@ -33,7 +32,7 @@ import com.cloud.network.Site2SiteVpnConnection; import com.cloud.user.Account; -@APICommand(name = "deleteVpnConnection", description = "Delete site to site vpn connection", responseObject = SuccessResponse.class, entityType = {IAMEntityType.Site2SiteVpnConnection}, +@APICommand(name = "deleteVpnConnection", description = "Delete site to site vpn connection", responseObject = SuccessResponse.class, entityType = {Site2SiteVpnConnection.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class DeleteVpnConnectionCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(DeleteVpnConnectionCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/vpn/DeleteVpnCustomerGatewayCmd.java b/api/src/org/apache/cloudstack/api/command/user/vpn/DeleteVpnCustomerGatewayCmd.java index 3faf5fd201..aad69ce0a9 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vpn/DeleteVpnCustomerGatewayCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vpn/DeleteVpnCustomerGatewayCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ACL; import org.apache.cloudstack.api.APICommand; @@ -34,7 +33,7 @@ import com.cloud.network.Site2SiteCustomerGateway; import com.cloud.user.Account; -@APICommand(name = "deleteVpnCustomerGateway", description = "Delete site to site vpn customer gateway", responseObject = SuccessResponse.class, entityType = {IAMEntityType.Site2SiteCustomerGateway}, +@APICommand(name = "deleteVpnCustomerGateway", description = "Delete site to site vpn customer gateway", responseObject = SuccessResponse.class, entityType = {Site2SiteCustomerGateway.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class DeleteVpnCustomerGatewayCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(DeleteVpnCustomerGatewayCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/vpn/DeleteVpnGatewayCmd.java b/api/src/org/apache/cloudstack/api/command/user/vpn/DeleteVpnGatewayCmd.java index 66fd55bba2..ff927408a2 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vpn/DeleteVpnGatewayCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vpn/DeleteVpnGatewayCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.ApiErrorCode; @@ -32,7 +31,7 @@ import com.cloud.network.Site2SiteVpnGateway; import com.cloud.user.Account; -@APICommand(name = "deleteVpnGateway", description = "Delete site to site vpn gateway", responseObject = SuccessResponse.class, entityType = {IAMEntityType.Site2SiteVpnGateway}, +@APICommand(name = "deleteVpnGateway", description = "Delete site to site vpn gateway", responseObject = SuccessResponse.class, entityType = {Site2SiteVpnGateway.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class DeleteVpnGatewayCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(DeleteVpnGatewayCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/vpn/ListRemoteAccessVpnsCmd.java b/api/src/org/apache/cloudstack/api/command/user/vpn/ListRemoteAccessVpnsCmd.java index 61a3a2993b..492eaccefa 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vpn/ListRemoteAccessVpnsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vpn/ListRemoteAccessVpnsCmd.java @@ -21,7 +21,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; @@ -35,7 +34,7 @@ import com.cloud.network.RemoteAccessVpn; import com.cloud.utils.Pair; -@APICommand(name = "listRemoteAccessVpns", description = "Lists remote access vpns", responseObject = RemoteAccessVpnResponse.class, entityType = { IAMEntityType.RemoteAccessVpn }, +@APICommand(name = "listRemoteAccessVpns", description = "Lists remote access vpns", responseObject = RemoteAccessVpnResponse.class, entityType = {RemoteAccessVpn.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class ListRemoteAccessVpnsCmd extends BaseListProjectAndAccountResourcesCmd { public static final Logger s_logger = Logger.getLogger(ListRemoteAccessVpnsCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/vpn/ListVpnConnectionsCmd.java b/api/src/org/apache/cloudstack/api/command/user/vpn/ListVpnConnectionsCmd.java index f8e81c2f01..74b9325eb2 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vpn/ListVpnConnectionsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vpn/ListVpnConnectionsCmd.java @@ -21,7 +21,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; @@ -34,7 +33,7 @@ import com.cloud.network.Site2SiteVpnConnection; import com.cloud.utils.Pair; -@APICommand(name = "listVpnConnections", description = "Lists site to site vpn connection gateways", responseObject = Site2SiteVpnConnectionResponse.class, entityType = { IAMEntityType.Site2SiteVpnConnection }, +@APICommand(name = "listVpnConnections", description = "Lists site to site vpn connection gateways", responseObject = Site2SiteVpnConnectionResponse.class, entityType = {Site2SiteVpnConnection.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class ListVpnConnectionsCmd extends BaseListProjectAndAccountResourcesCmd { public static final Logger s_logger = Logger.getLogger(ListVpnConnectionsCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/vpn/ListVpnCustomerGatewaysCmd.java b/api/src/org/apache/cloudstack/api/command/user/vpn/ListVpnCustomerGatewaysCmd.java index fed96a72b3..6b870be138 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vpn/ListVpnCustomerGatewaysCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vpn/ListVpnCustomerGatewaysCmd.java @@ -21,7 +21,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseListProjectAndAccountResourcesCmd; @@ -32,7 +31,7 @@ import com.cloud.network.Site2SiteCustomerGateway; import com.cloud.utils.Pair; -@APICommand(name = "listVpnCustomerGateways", description = "Lists site to site vpn customer gateways", responseObject = Site2SiteCustomerGatewayResponse.class, entityType = {IAMEntityType.Site2SiteCustomerGateway}, +@APICommand(name = "listVpnCustomerGateways", description = "Lists site to site vpn customer gateways", responseObject = Site2SiteCustomerGatewayResponse.class, entityType = {Site2SiteCustomerGateway.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class ListVpnCustomerGatewaysCmd extends BaseListProjectAndAccountResourcesCmd { public static final Logger s_logger = Logger.getLogger(ListVpnCustomerGatewaysCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/vpn/ListVpnGatewaysCmd.java b/api/src/org/apache/cloudstack/api/command/user/vpn/ListVpnGatewaysCmd.java index 17702252e8..3eade02880 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vpn/ListVpnGatewaysCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vpn/ListVpnGatewaysCmd.java @@ -21,7 +21,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; @@ -34,7 +33,7 @@ import com.cloud.network.Site2SiteVpnGateway; import com.cloud.utils.Pair; -@APICommand(name = "listVpnGateways", description = "Lists site 2 site vpn gateways", responseObject = Site2SiteVpnGatewayResponse.class, entityType = { IAMEntityType.Site2SiteVpnGateway }, +@APICommand(name = "listVpnGateways", description = "Lists site 2 site vpn gateways", responseObject = Site2SiteVpnGatewayResponse.class, entityType = {Site2SiteVpnGateway.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class ListVpnGatewaysCmd extends BaseListProjectAndAccountResourcesCmd { public static final Logger s_logger = Logger.getLogger(ListVpnGatewaysCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/vpn/ListVpnUsersCmd.java b/api/src/org/apache/cloudstack/api/command/user/vpn/ListVpnUsersCmd.java index 1d8ea85cbb..9af060ac00 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vpn/ListVpnUsersCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vpn/ListVpnUsersCmd.java @@ -21,7 +21,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseListProjectAndAccountResourcesCmd; @@ -32,7 +31,7 @@ import com.cloud.network.VpnUser; import com.cloud.utils.Pair; -@APICommand(name = "listVpnUsers", description = "Lists vpn users", responseObject = VpnUsersResponse.class, entityType = {IAMEntityType.VpnUser}, +@APICommand(name = "listVpnUsers", description = "Lists vpn users", responseObject = VpnUsersResponse.class, entityType = {VpnUser.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class ListVpnUsersCmd extends BaseListProjectAndAccountResourcesCmd { public static final Logger s_logger = Logger.getLogger(ListVpnUsersCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/vpn/RemoveVpnUserCmd.java b/api/src/org/apache/cloudstack/api/command/user/vpn/RemoveVpnUserCmd.java index 068746945c..f552b14fbf 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vpn/RemoveVpnUserCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vpn/RemoveVpnUserCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.ApiErrorCode; @@ -31,9 +30,10 @@ import org.apache.cloudstack.context.CallContext; import com.cloud.event.EventTypes; +import com.cloud.network.VpnUser; import com.cloud.user.Account; -@APICommand(name = "removeVpnUser", description = "Removes vpn user", responseObject = SuccessResponse.class, entityType = {IAMEntityType.VpnUser}, +@APICommand(name = "removeVpnUser", description = "Removes vpn user", responseObject = SuccessResponse.class, entityType = {VpnUser.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class RemoveVpnUserCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(RemoveVpnUserCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/vpn/ResetVpnConnectionCmd.java b/api/src/org/apache/cloudstack/api/command/user/vpn/ResetVpnConnectionCmd.java index 21eb182d0b..75e74adcda 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vpn/ResetVpnConnectionCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vpn/ResetVpnConnectionCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.ApiErrorCode; @@ -34,7 +33,7 @@ import com.cloud.network.Site2SiteVpnConnection; import com.cloud.user.Account; -@APICommand(name = "resetVpnConnection", description = "Reset site to site vpn connection", responseObject = Site2SiteVpnConnectionResponse.class, entityType = {IAMEntityType.Site2SiteVpnConnection}, +@APICommand(name = "resetVpnConnection", description = "Reset site to site vpn connection", responseObject = Site2SiteVpnConnectionResponse.class, entityType = {Site2SiteVpnConnection.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class ResetVpnConnectionCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(ResetVpnConnectionCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/vpn/UpdateVpnCustomerGatewayCmd.java b/api/src/org/apache/cloudstack/api/command/user/vpn/UpdateVpnCustomerGatewayCmd.java index 9e178efc0e..ceb67d510a 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vpn/UpdateVpnCustomerGatewayCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vpn/UpdateVpnCustomerGatewayCmd.java @@ -18,7 +18,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.ApiErrorCode; @@ -32,7 +31,7 @@ import com.cloud.event.EventTypes; import com.cloud.network.Site2SiteCustomerGateway; -@APICommand(name = "updateVpnCustomerGateway", description = "Update site to site vpn customer gateway", responseObject = Site2SiteCustomerGatewayResponse.class, entityType = {IAMEntityType.Site2SiteCustomerGateway}, +@APICommand(name = "updateVpnCustomerGateway", description = "Update site to site vpn customer gateway", responseObject = Site2SiteCustomerGatewayResponse.class, entityType = {Site2SiteCustomerGateway.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class UpdateVpnCustomerGatewayCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(UpdateVpnCustomerGatewayCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/response/AccountResponse.java b/api/src/org/apache/cloudstack/api/response/AccountResponse.java index 991b162ac1..2e50c51858 100644 --- a/api/src/org/apache/cloudstack/api/response/AccountResponse.java +++ b/api/src/org/apache/cloudstack/api/response/AccountResponse.java @@ -240,7 +240,7 @@ public class AccountResponse extends BaseResponse implements ResourceLimitAndCou private Boolean isDefault; @SerializedName(ApiConstants.IAM_GROUPS) - @Param(description = "the list of acl groups that account belongs to") + @Param(description = "the list of acl groups that account belongs to", since = "4.4") private List groups; @Override diff --git a/api/src/org/apache/cloudstack/api/response/CapabilitiesResponse.java b/api/src/org/apache/cloudstack/api/response/CapabilitiesResponse.java index c8de587336..f7fdb95fb6 100644 --- a/api/src/org/apache/cloudstack/api/response/CapabilitiesResponse.java +++ b/api/src/org/apache/cloudstack/api/response/CapabilitiesResponse.java @@ -49,6 +49,10 @@ public class CapabilitiesResponse extends BaseResponse { @Param(description = "true if regular user is allowed to create projects") private Boolean allowUsersCreateProjects; + @SerializedName(ApiConstants.CUSTOM_DISK_OFF_MIN_SIZE) + @Param(description = "minimum size that can be specified when " + "create disk from disk offering with custom size") + private Long diskOffMinSize; + @SerializedName(ApiConstants.CUSTOM_DISK_OFF_MAX_SIZE) @Param(description = "maximum size that can be specified when " + "create disk from disk offering with custom size") private Long diskOffMaxSize; @@ -93,6 +97,10 @@ public void setAllowUsersCreateProjects(Boolean allowUsersCreateProjects) { this.allowUsersCreateProjects = allowUsersCreateProjects; } + public void setDiskOffMinSize(Long diskOffMinSize) { + this.diskOffMinSize = diskOffMinSize; + } + public void setDiskOffMaxSize(Long diskOffMaxSize) { this.diskOffMaxSize = diskOffMaxSize; } diff --git a/api/src/org/apache/cloudstack/api/response/DiskOfferingResponse.java b/api/src/org/apache/cloudstack/api/response/DiskOfferingResponse.java index 0894eeced3..91bd441353 100644 --- a/api/src/org/apache/cloudstack/api/response/DiskOfferingResponse.java +++ b/api/src/org/apache/cloudstack/api/response/DiskOfferingResponse.java @@ -74,7 +74,7 @@ public class DiskOfferingResponse extends BaseResponse { private Long maxIops; @SerializedName(ApiConstants.HYPERVISOR_SNAPSHOT_RESERVE) - @Param(description = "Hypervisor snapshot reserve space as a percent of a volume (for managed storage using Xen or VMware)") + @Param(description = "Hypervisor snapshot reserve space as a percent of a volume (for managed storage using Xen or VMware)", since = "4.4") private Integer hypervisorSnapshotReserve; @SerializedName(ApiConstants.TAGS) @@ -102,7 +102,7 @@ public class DiskOfferingResponse extends BaseResponse { private Long iopsWriteRate; @SerializedName("cacheMode") - @Param(description = "the cache mode to use for this disk offering. none, writeback or writethrough") + @Param(description = "the cache mode to use for this disk offering. none, writeback or writethrough", since = "4.4") private String cacheMode; @SerializedName("displayoffering") diff --git a/api/src/org/apache/cloudstack/api/response/GetVMPasswordResponse.java b/api/src/org/apache/cloudstack/api/response/GetVMPasswordResponse.java index c72031b822..7a4543d437 100644 --- a/api/src/org/apache/cloudstack/api/response/GetVMPasswordResponse.java +++ b/api/src/org/apache/cloudstack/api/response/GetVMPasswordResponse.java @@ -25,7 +25,7 @@ public class GetVMPasswordResponse extends BaseResponse { @SerializedName("encryptedpassword") - @Param(description = "The encrypted password of the VM") + @Param(description = "The base64 encoded encrypted password of the VM") private String encryptedPassword; public GetVMPasswordResponse() { diff --git a/api/src/org/apache/cloudstack/api/response/GuestOSResponse.java b/api/src/org/apache/cloudstack/api/response/GuestOSResponse.java index 9737d6073a..6822288a86 100644 --- a/api/src/org/apache/cloudstack/api/response/GuestOSResponse.java +++ b/api/src/org/apache/cloudstack/api/response/GuestOSResponse.java @@ -39,6 +39,10 @@ public class GuestOSResponse extends BaseResponse { @Param(description = "the name/description of the OS type") private String description; + @SerializedName(ApiConstants.IS_USER_DEFINED) + @Param(description = "is the guest OS user defined") + private String isUserDefined; + public String getId() { return id; } @@ -62,4 +66,13 @@ public String getDescription() { public void setDescription(String description) { this.description = description; } + + public String getIsUserDefined() { + return isUserDefined; + } + + public void setIsUserDefined(String isUserDefined) { + this.isUserDefined = isUserDefined; + } + } diff --git a/api/src/org/apache/cloudstack/api/response/GuestOsMappingResponse.java b/api/src/org/apache/cloudstack/api/response/GuestOsMappingResponse.java index a0f7d1d0ed..583768d47b 100644 --- a/api/src/org/apache/cloudstack/api/response/GuestOsMappingResponse.java +++ b/api/src/org/apache/cloudstack/api/response/GuestOsMappingResponse.java @@ -52,6 +52,18 @@ public class GuestOsMappingResponse extends BaseResponse { @Param(description = "hypervisor specific name for the Guest OS") private String osNameForHypervisor; + @SerializedName(ApiConstants.IS_USER_DEFINED) + @Param(description = "is the mapping user defined") + private String isUserDefined; + + public String getIsUserDefined() { + return isUserDefined; + } + + public void setIsUserDefined(String isUserDefined) { + this.isUserDefined = isUserDefined; + } + public String getId() { return id; } diff --git a/api/src/org/apache/cloudstack/api/response/HostResponse.java b/api/src/org/apache/cloudstack/api/response/HostResponse.java index 1fbc6684e1..d7638dee0f 100644 --- a/api/src/org/apache/cloudstack/api/response/HostResponse.java +++ b/api/src/org/apache/cloudstack/api/response/HostResponse.java @@ -137,7 +137,7 @@ public class HostResponse extends BaseResponse { private Long memoryUsed; @SerializedName(ApiConstants.GPUGROUP) - @Param(description = "GPU cards present in the host", responseObject = GpuResponse.class) + @Param(description = "GPU cards present in the host", responseObject = GpuResponse.class, since = "4.4") private List gpuGroup; @SerializedName("disksizetotal") @@ -328,6 +328,7 @@ public void setMemoryUsed(Long memoryUsed) { public void setGpuGroups(List gpuGroup) { this.gpuGroup = gpuGroup; } + public void setDiskSizeTotal(Long diskSizeTotal) { this.diskSizeTotal = diskSizeTotal; } diff --git a/api/src/org/apache/cloudstack/api/response/LBHealthCheckPolicyResponse.java b/api/src/org/apache/cloudstack/api/response/LBHealthCheckPolicyResponse.java index 406a8dab0d..8ce7b3d219 100644 --- a/api/src/org/apache/cloudstack/api/response/LBHealthCheckPolicyResponse.java +++ b/api/src/org/apache/cloudstack/api/response/LBHealthCheckPolicyResponse.java @@ -16,12 +16,13 @@ // under the License. package org.apache.cloudstack.api.response; -import com.google.gson.annotations.SerializedName; - +import org.apache.cloudstack.acl.RoleType; +import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseResponse; import com.cloud.network.rules.HealthCheckPolicy; import com.cloud.serializer.Param; +import com.google.gson.annotations.SerializedName; public class LBHealthCheckPolicyResponse extends BaseResponse { @SerializedName("id") @@ -56,6 +57,10 @@ public class LBHealthCheckPolicyResponse extends BaseResponse { @Param(description = "Number of consecutive health check failures before declaring an instance unhealthy.") private int unhealthcheckthresshold; + @SerializedName(ApiConstants.FOR_DISPLAY) + @Param(description = "is policy for display to the regular user", since = "4.4", authorized = {RoleType.Admin}) + private Boolean forDisplay; + public void setId(String id) { this.id = id; } @@ -95,6 +100,11 @@ public LBHealthCheckPolicyResponse(HealthCheckPolicy healthcheckpolicy) { this.responseTime = healthcheckpolicy.getResponseTime(); this.healthcheckthresshold = healthcheckpolicy.getHealthcheckThresshold(); this.unhealthcheckthresshold = healthcheckpolicy.getUnhealthThresshold(); + this.forDisplay = healthcheckpolicy.isDisplay(); setObjectName("healthcheckpolicy"); } + + public void setForDisplay(Boolean forDisplay) { + this.forDisplay = forDisplay; + } } diff --git a/api/src/org/apache/cloudstack/api/response/LBStickinessPolicyResponse.java b/api/src/org/apache/cloudstack/api/response/LBStickinessPolicyResponse.java index 76c54cd4cd..8fa884982b 100644 --- a/api/src/org/apache/cloudstack/api/response/LBStickinessPolicyResponse.java +++ b/api/src/org/apache/cloudstack/api/response/LBStickinessPolicyResponse.java @@ -22,6 +22,8 @@ import com.google.gson.annotations.SerializedName; +import org.apache.cloudstack.acl.RoleType; +import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseResponse; import com.cloud.network.rules.StickinessPolicy; @@ -49,6 +51,10 @@ public class LBStickinessPolicyResponse extends BaseResponse { @Param(description = "the state of the policy") private String state; + @SerializedName(ApiConstants.FOR_DISPLAY) + @Param(description = "is policy for display to the regular user", since = "4.4", authorized = {RoleType.Admin}) + private Boolean forDisplay; + // FIXME : if prams with the same name exists more then once then value are concatinated with ":" as delimitor . // Reason: Map does not support duplicate keys, need to look for the alernate data structure // Example: {indirect=null, name=testcookie, nocache=null, domain=www.yahoo.com:www.google.com, postonly=null} @@ -98,6 +104,7 @@ public LBStickinessPolicyResponse(StickinessPolicy stickinesspolicy) { List> paramsList = stickinesspolicy.getParams(); this.methodName = stickinesspolicy.getMethodName(); this.description = stickinesspolicy.getDescription(); + this.forDisplay = stickinesspolicy.isDisplay(); if (stickinesspolicy.isRevoke()) { this.setState("Revoked"); } @@ -126,4 +133,8 @@ public LBStickinessPolicyResponse(StickinessPolicy stickinesspolicy) { this.params = tempParamList; setObjectName("stickinesspolicy"); } + + public void setForDisplay(Boolean forDisplay) { + this.forDisplay = forDisplay; + } } diff --git a/api/src/org/apache/cloudstack/api/response/LoadBalancerRuleVmMapResponse.java b/api/src/org/apache/cloudstack/api/response/LoadBalancerRuleVmMapResponse.java new file mode 100644 index 0000000000..57c45e6432 --- /dev/null +++ b/api/src/org/apache/cloudstack/api/response/LoadBalancerRuleVmMapResponse.java @@ -0,0 +1,54 @@ +// 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.cloud.network.router.VirtualRouter; +import com.cloud.uservm.UserVm; +import com.cloud.vm.VirtualMachine; +import com.google.gson.annotations.SerializedName; + +import org.apache.cloudstack.api.BaseResponse; +import org.apache.cloudstack.api.EntityReference; + +import com.cloud.serializer.Param; + +import java.util.List; + +@EntityReference(value = {VirtualMachine.class, UserVm.class, VirtualRouter.class}) +@SuppressWarnings("unused") +public class LoadBalancerRuleVmMapResponse extends BaseResponse { + + + @SerializedName("loadbalancerruleinstance") + @Param(description = "the user vm set for lb rule") + private UserVmResponse UserVmResponse; + + @SerializedName("lbvmipaddresses") + @Param(description = "IP addresses of the vm set of lb rule") + private List ipAddr; + + public void setIpAddr(List ipAddr) { + this.ipAddr = ipAddr; + } + + public void setUserVmResponse(UserVmResponse userVmResponse) { + this.UserVmResponse = userVmResponse; + } + + + +} diff --git a/api/src/org/apache/cloudstack/api/response/NetworkOfferingResponse.java b/api/src/org/apache/cloudstack/api/response/NetworkOfferingResponse.java index 8219147726..775c9a8fdd 100644 --- a/api/src/org/apache/cloudstack/api/response/NetworkOfferingResponse.java +++ b/api/src/org/apache/cloudstack/api/response/NetworkOfferingResponse.java @@ -109,13 +109,17 @@ public class NetworkOfferingResponse extends BaseResponse { private Map details; @SerializedName(ApiConstants.EGRESS_DEFAULT_POLICY) - @Param(description = "true if network offering supports persistent networks, false otherwise") + @Param(description = "true if guest network default egress policy is allow; false if default egress policy is deny") private Boolean egressDefaultPolicy; @SerializedName(ApiConstants.MAX_CONNECTIONS) @Param(description = "maximum number of concurrents connections to be handled by lb") private Integer concurrentConnections; + @SerializedName(ApiConstants.SUPPORTS_STRECHED_L2_SUBNET) + @Param(description = "true if network offering supports network that span multiple zones", since = "4.4") + private Boolean supportsStrechedL2Subnet; + public void setId(String id) { this.id = id; } @@ -200,4 +204,7 @@ public void setConcurrentConnections(Integer concurrentConnections) { this.concurrentConnections = concurrentConnections; } + public void setSupportsStrechedL2Subnet(Boolean supportsStrechedL2Subnet) { + this.supportsStrechedL2Subnet = supportsStrechedL2Subnet; + } } diff --git a/api/src/org/apache/cloudstack/api/response/NetworkResponse.java b/api/src/org/apache/cloudstack/api/response/NetworkResponse.java index bf92aa4f78..40c90729cd 100644 --- a/api/src/org/apache/cloudstack/api/response/NetworkResponse.java +++ b/api/src/org/apache/cloudstack/api/response/NetworkResponse.java @@ -18,6 +18,7 @@ import java.util.List; +import java.util.Set; import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseResponse; @@ -216,6 +217,14 @@ public class NetworkResponse extends BaseResponse implements ControlledEntityRes @Param(description = "ACL Id associated with the VPC network") private String aclId; + @SerializedName(ApiConstants.STRECHED_L2_SUBNET) + @Param(description = "true if network can span multiple zones", since = "4.4") + private Boolean strechedL2Subnet; + + @SerializedName(ApiConstants.NETWORK_SPANNED_ZONES) + @Param(description = "If a network is enabled for 'streched l2 subnet' then represents zones on which network currently spans", since = "4.4") + private Set networkSpannedZones; + public Boolean getDisplayNetwork() { return displayNetwork; } @@ -412,4 +421,12 @@ public String getAclId() { public void setAclId(String aclId) { this.aclId = aclId; } + + public void setStrechedL2Subnet(Boolean strechedL2Subnet) { + this.strechedL2Subnet = strechedL2Subnet; + } + + public void setNetworkSpannedZones(Set networkSpannedZones) { + this.networkSpannedZones = networkSpannedZones; + } } diff --git a/api/src/org/apache/cloudstack/api/response/NicResponse.java b/api/src/org/apache/cloudstack/api/response/NicResponse.java index 3dd8b297a2..2f79d7ff47 100644 --- a/api/src/org/apache/cloudstack/api/response/NicResponse.java +++ b/api/src/org/apache/cloudstack/api/response/NicResponse.java @@ -98,6 +98,14 @@ public class NicResponse extends BaseResponse { @Param(description = "device id for the network when plugged into the virtual machine", since = "4.4") private String deviceId; + @SerializedName(ApiConstants.VIRTUAL_MACHINE_ID) + @Param(description = "Id of the vm to which the nic belongs") + private String vmId; + + public void setVmId(String vmId) { + this.vmId = vmId; + } + public String getId() { return id; } diff --git a/api/src/org/apache/cloudstack/api/response/ServiceOfferingResponse.java b/api/src/org/apache/cloudstack/api/response/ServiceOfferingResponse.java index d371f9a925..764ade510a 100644 --- a/api/src/org/apache/cloudstack/api/response/ServiceOfferingResponse.java +++ b/api/src/org/apache/cloudstack/api/response/ServiceOfferingResponse.java @@ -107,19 +107,19 @@ public class ServiceOfferingResponse extends BaseResponse { private Integer networkRate; @SerializedName("iscustomizediops") - @Param(description = "true if disk offering uses custom iops, false otherwise") + @Param(description = "true if disk offering uses custom iops, false otherwise", since = "4.4") private Boolean customizedIops; @SerializedName(ApiConstants.MIN_IOPS) - @Param(description = "the min iops of the disk offering") + @Param(description = "the min iops of the disk offering", since = "4.4") private Long minIops; @SerializedName(ApiConstants.MAX_IOPS) - @Param(description = "the max iops of the disk offering") + @Param(description = "the max iops of the disk offering", since = "4.4") private Long maxIops; @SerializedName(ApiConstants.HYPERVISOR_SNAPSHOT_RESERVE) - @Param(description = "Hypervisor snapshot reserve space as a percent of a volume (for managed storage using Xen or VMware)") + @Param(description = "Hypervisor snapshot reserve space as a percent of a volume (for managed storage using Xen or VMware)", since = "4.4") private Integer hypervisorSnapshotReserve; @SerializedName("diskBytesReadRate") diff --git a/api/src/org/apache/cloudstack/api/response/SnapshotPolicyResponse.java b/api/src/org/apache/cloudstack/api/response/SnapshotPolicyResponse.java index 913d2349d0..39178a3afd 100644 --- a/api/src/org/apache/cloudstack/api/response/SnapshotPolicyResponse.java +++ b/api/src/org/apache/cloudstack/api/response/SnapshotPolicyResponse.java @@ -18,6 +18,8 @@ import com.google.gson.annotations.SerializedName; +import org.apache.cloudstack.acl.RoleType; +import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseResponse; import org.apache.cloudstack.api.EntityReference; @@ -50,6 +52,10 @@ public class SnapshotPolicyResponse extends BaseResponse { @Param(description = "the time zone of the snapshot policy") private String timezone; + @SerializedName(ApiConstants.FOR_DISPLAY) + @Param(description = "is this policy for display to the regular user", since = "4.4", authorized = {RoleType.Admin}) + private Boolean forDisplay; + public String getId() { return id; } @@ -97,4 +103,12 @@ public String getTimezone() { public void setTimezone(String timezone) { this.timezone = timezone; } + + public Boolean getForDisplay() { + return forDisplay; + } + + public void setForDisplay(Boolean forDisplay) { + this.forDisplay = forDisplay; + } } diff --git a/api/src/org/apache/cloudstack/api/response/StoragePoolResponse.java b/api/src/org/apache/cloudstack/api/response/StoragePoolResponse.java index 98c90e2fd3..3571866fe7 100644 --- a/api/src/org/apache/cloudstack/api/response/StoragePoolResponse.java +++ b/api/src/org/apache/cloudstack/api/response/StoragePoolResponse.java @@ -108,8 +108,8 @@ public class StoragePoolResponse extends BaseResponse { private String scope; @SerializedName("overprovisionfactor") - @Param(description = "the overprovisionfactor for the storage pool") - private String overprovisionfactor; + @Param(description = "the overprovisionfactor for the storage pool", since = "4.4") + private String overProvisionFactor; @SerializedName(ApiConstants.HYPERVISOR) @Param(description = "the hypervisor type of the storage pool") @@ -307,6 +307,6 @@ public void setSuitableForMigration(Boolean suitableForMigration) { } public void setOverProvisionFactor(String overProvisionFactor) { - this.overprovisionfactor = overProvisionFactor; + this.overProvisionFactor = overProvisionFactor; } } diff --git a/api/src/org/apache/cloudstack/api/response/UsageRecordResponse.java b/api/src/org/apache/cloudstack/api/response/UsageRecordResponse.java index 5e2e85dea4..87a085c2a5 100644 --- a/api/src/org/apache/cloudstack/api/response/UsageRecordResponse.java +++ b/api/src/org/apache/cloudstack/api/response/UsageRecordResponse.java @@ -101,6 +101,18 @@ public class UsageRecordResponse extends BaseResponse implements ControlledEntit @Param(description = "virtual size of resource") private Long virtualSize; + @SerializedName(ApiConstants.CPU_NUMBER) + @Param(description = "number of cpu of resource") + private Long cpuNumber; + + @SerializedName(ApiConstants.CPU_SPEED) + @Param(description = "speed of each cpu of resource") + private Long cpuSpeed; + + @SerializedName(ApiConstants.MEMORY) + @Param(description = "memory allocated for the resource") + private Long memory; + @SerializedName(ApiConstants.START_DATE) @Param(description = "start date of the usage record") private String startDate; @@ -229,4 +241,16 @@ public void setDefault(Boolean isDefault) { public void setVirtualSize(Long virtualSize) { this.virtualSize = virtualSize; } + + public void setCpuNumber(Long cpuNumber) { + this.cpuNumber = cpuNumber; + } + + public void setCpuSpeed(Long cpuSpeed) { + this.cpuSpeed = cpuSpeed; + } + + public void setMemory(Long memory) { + this.memory = memory; + } } diff --git a/api/src/org/apache/cloudstack/api/response/UserVmResponse.java b/api/src/org/apache/cloudstack/api/response/UserVmResponse.java index d6ce84f495..9fe3475f57 100644 --- a/api/src/org/apache/cloudstack/api/response/UserVmResponse.java +++ b/api/src/org/apache/cloudstack/api/response/UserVmResponse.java @@ -141,11 +141,11 @@ public class UserVmResponse extends BaseResponse implements ControlledEntityResp private String serviceOfferingName; @SerializedName(ApiConstants.DISK_OFFERING_ID) - @Param(description = "the ID of the disk offering of the virtual machine") + @Param(description = "the ID of the disk offering of the virtual machine", since = "4.4") private String diskOfferingId; @SerializedName("diskofferingname") - @Param(description = "the name of the disk offering of the virtual machine") + @Param(description = "the name of the disk offering of the virtual machine", since = "4.4") private String diskOfferingName; @SerializedName("forvirtualnetwork") @@ -165,7 +165,7 @@ public class UserVmResponse extends BaseResponse implements ControlledEntityResp private Integer memory; @SerializedName(ApiConstants.VGPU) - @Param(description = "the vgpu type used by the virtual machine") + @Param(description = "the vgpu type used by the virtual machine", since = "4.4") private String vgpu; @SerializedName("cpuused") diff --git a/api/src/org/apache/cloudstack/api/response/VgpuResponse.java b/api/src/org/apache/cloudstack/api/response/VgpuResponse.java index 17e194be5b..c51dc8d0f6 100644 --- a/api/src/org/apache/cloudstack/api/response/VgpuResponse.java +++ b/api/src/org/apache/cloudstack/api/response/VgpuResponse.java @@ -29,24 +29,63 @@ public class VgpuResponse extends BaseResponse { @Param(description = "Model Name of vGPU") private String name; + @SerializedName(ApiConstants.VIDEORAM) + @Param(description = "Video RAM for this vGPU type") + private Long videoRam; + + @SerializedName(ApiConstants.MAXHEADS) + @Param(description = "Maximum displays per user") + private Long maxHeads; + + @SerializedName(ApiConstants.MAXRESOLUTIONX) + @Param(description = "Maximum X resolution per display") + private Long maxResolutionX; + + @SerializedName(ApiConstants.MAXRESOLUTIONY) + @Param(description = "Maximum Y resolution per display") + private Long maxResolutionY; + + @SerializedName(ApiConstants.MAXVGPUPERPGPU) + @Param(description = "Maximum no. of vgpu per gpu card (pgpu)") + private Long maxVgpuPerPgpu; + @SerializedName(ApiConstants.REMAININGCAPACITY) - @Param(description = "No. of more VMs can be deployped with this vGPU type") - private Long capacity; + @Param(description = "Remaining capacity in terms of no. of more VMs that can be deployped with this vGPU type") + private Long remainingCapacity; - public String getName() { - return name; - } + @SerializedName(ApiConstants.MAXCAPACITY) + @Param(description = "Maximum vgpu can be created with this vgpu type on the given gpu group") + private Long maxCapacity; public void setName(String name) { this.name = name; } - public Long getCapacity() { - return capacity; + public void setVideoRam(Long videoRam) { + this.videoRam = videoRam; + } + + public void setMaxHeads(Long maxHeads) { + this.maxHeads = maxHeads; } - public void setCapacity(Long capacity) { - this.capacity = capacity; + public void setMaxResolutionX(Long maxResolutionX) { + this.maxResolutionX = maxResolutionX; } + public void setMaxResolutionY(Long maxResolutionY) { + this.maxResolutionY = maxResolutionY; + } + + public void setMaxVgpuPerPgpu(Long maxVgpuPerPgpu) { + this.maxVgpuPerPgpu = maxVgpuPerPgpu; + } + + public void setRemainingCapacity(Long remainingCapacity) { + this.remainingCapacity = remainingCapacity; + } + + public void setmaxCapacity(Long maxCapacity) { + this.maxCapacity = maxCapacity; + } } diff --git a/api/src/org/apache/cloudstack/api/response/VolumeResponse.java b/api/src/org/apache/cloudstack/api/response/VolumeResponse.java index 27e95def02..c3e214fb10 100644 --- a/api/src/org/apache/cloudstack/api/response/VolumeResponse.java +++ b/api/src/org/apache/cloudstack/api/response/VolumeResponse.java @@ -60,6 +60,30 @@ public class VolumeResponse extends BaseResponse implements ControlledViewEntity @Param(description = "id of the virtual machine") private String virtualMachineId; + @SerializedName("isoid") + @Param(description = "the ID of the ISO attached to the virtual machine") + private String isoId; + + @SerializedName("isoname") + @Param(description = "the name of the ISO attached to the virtual machine") + private String isoName; + + @SerializedName("isodisplaytext") + @Param(description = "an alternate display text of the ISO attached to the virtual machine") + private String isoDisplayText; + + @SerializedName(ApiConstants.TEMPLATE_ID) + @Param(description = "the ID of the template for the virtual machine. A -1 is returned if the virtual machine was created from an ISO file.") + private String templateId; + + @SerializedName("templatename") + @Param(description = "the name of the template for the virtual machine") + private String templateName; + + @SerializedName("templatedisplaytext") + @Param(description = " an alternate display text of the template for the virtual machine") + private String templateDisplayText; + @SerializedName("vmname") @Param(description = "name of the virtual machine") private String virtualMachineName; @@ -204,6 +228,11 @@ public class VolumeResponse extends BaseResponse implements ControlledViewEntity @Param(description = "the chain info of the volume", since = "4.4") String chainInfo; + @SerializedName(ApiConstants.SNAPSHOT_QUIESCEVM) + @Param(description = "need quiesce vm or not when taking snapshot", since="4.3") + private boolean needQuiescevm; + + public String getPath() { return path; } @@ -425,4 +454,64 @@ public String getChainInfo() { public void setChainInfo(String chainInfo) { this.chainInfo = chainInfo; } + + public String getStoragePoolId() { + return storagePoolId; + } + + public void setNeedQuiescevm(boolean quiescevm) { + this.needQuiescevm = quiescevm; + } + + public boolean isNeedQuiescevm() { + return this.needQuiescevm; + } + + public String getIsoId() { + return isoId; + } + + public void setIsoId(String isoId) { + this.isoId = isoId; + } + + public String getIsoName() { + return isoName; + } + + public void setIsoName(String isoName) { + this.isoName = isoName; + } + + public String getIsoDisplayText() { + return isoDisplayText; + } + + public void setIsoDisplayText(String isoDisplayText) { + this.isoDisplayText = isoDisplayText; + } + + public String getTemplateId() { + return templateId; + } + + public void setTemplateId(String templateId) { + this.templateId = templateId; + } + + public String getTemplateName() { + return templateName; + } + + public void setTemplateName(String templateName) { + this.templateName = templateName; + } + + public String getTemplateDisplayText() { + return templateDisplayText; + } + + public void setTemplateDisplayText(String templateDisplayText) { + this.templateDisplayText = templateDisplayText; + } } diff --git a/api/src/org/apache/cloudstack/api/response/VpcOfferingResponse.java b/api/src/org/apache/cloudstack/api/response/VpcOfferingResponse.java index 89697f04ad..512746fb6a 100644 --- a/api/src/org/apache/cloudstack/api/response/VpcOfferingResponse.java +++ b/api/src/org/apache/cloudstack/api/response/VpcOfferingResponse.java @@ -60,9 +60,13 @@ public class VpcOfferingResponse extends BaseResponse { private List services; @SerializedName(ApiConstants.DISTRIBUTED_VPC_ROUTER) - @Param(description = " indicates if the vpc offering supports distributed router for one-hop forwarding") + @Param(description = " indicates if the vpc offering supports distributed router for one-hop forwarding", since = "4.4") private Boolean supportsDistributedRouter; + @SerializedName((ApiConstants.SUPPORTS_REGION_LEVEL_VPC)) + @Param(description = " indicated if the offering can support region level vpc", since = "4.4") + private Boolean supportsRegionLevelVpc; + public void setId(String id) { this.id = id; } @@ -94,4 +98,8 @@ public void setState(String state) { public void setSupportsDistributedRouter(Boolean supportsDistributedRouter) { this.supportsDistributedRouter = supportsDistributedRouter; } + + public void setSupportsRegionLevelVpc(Boolean supports) { + this.supportsRegionLevelVpc = supports; + } } diff --git a/api/src/org/apache/cloudstack/api/response/VpcResponse.java b/api/src/org/apache/cloudstack/api/response/VpcResponse.java index e3b44f2113..d1afdfb816 100644 --- a/api/src/org/apache/cloudstack/api/response/VpcResponse.java +++ b/api/src/org/apache/cloudstack/api/response/VpcResponse.java @@ -111,11 +111,14 @@ public class VpcResponse extends BaseResponse implements ControlledEntityRespons @Param(description = "is vpc for display to the regular user", since = "4.4", authorized = {RoleType.Admin}) private Boolean forDisplay; - @SerializedName(ApiConstants.DISTRIBUTED_VPC_ROUTER) - @Param(description = "is VPC uses distributed router for one hop forwarding and host based network ACL's") + @Param(description = "is VPC uses distributed router for one hop forwarding and host based network ACL's", since = "4.4") private boolean usesDistributedRouter; + @SerializedName((ApiConstants.REGION_LEVEL_VPC)) + @Param(description = "true if VPC is region level", since = "4.4") + private Boolean regionLevelVpc; + public void setId(String id) { this.id = id; } @@ -205,6 +208,10 @@ public void setForDisplay(Boolean forDisplay) { this.forDisplay = forDisplay; } + public void setRegionLevelVpc(Boolean regionLevelVpc) { + this.regionLevelVpc = regionLevelVpc; + } + public void setUsesDistributedRouter(Boolean usesDistributedRouter) { this.usesDistributedRouter = usesDistributedRouter; } diff --git a/api/src/org/apache/cloudstack/context/CallContext.java b/api/src/org/apache/cloudstack/context/CallContext.java index 661b01dd55..bf4818b37c 100644 --- a/api/src/org/apache/cloudstack/context/CallContext.java +++ b/api/src/org/apache/cloudstack/context/CallContext.java @@ -114,7 +114,20 @@ public Account getCallingAccount() { } public static CallContext current() { - return s_currentContext.get(); + CallContext context = s_currentContext.get(); + + // TODO other than async job and api dispatches, there are many system background running threads + // that do not setup CallContext at all, however, many places in code that are touched by these background tasks + // assume not-null CallContext. Following is a fix to address therefore caused NPE problems + // + // There are security implications with this. It assumes that all system background running threads are + // indeed have no problem in running under system context. + // + if (context == null) { + context = registerSystemCallContextOnceOnly(); + } + + return context; } /** @@ -316,6 +329,17 @@ public void setEventDisplayEnabled(boolean eventDisplayEnabled) { isEventDisplayEnabled = eventDisplayEnabled; } + public Map getContextParameters() { + return context; + } + + public void putContextParameters(Map details){ + if (details == null) return; + for(Object key : details.keySet()){ + putContextParameter(key, details.get(key)); + } + } + public static void setActionEventInfo(String eventType, String description) { CallContext context = CallContext.current(); if (context != null) { diff --git a/api/src/org/apache/cloudstack/usage/Usage.java b/api/src/org/apache/cloudstack/usage/Usage.java index 20dc189ae1..fe35390dd4 100644 --- a/api/src/org/apache/cloudstack/usage/Usage.java +++ b/api/src/org/apache/cloudstack/usage/Usage.java @@ -40,6 +40,12 @@ public interface Usage { public String getVmName(); + public Long getCpuCores(); + + public Long getCpuSpeed(); + + public Long getMemory(); + public Long getOfferingId(); public Long getTemplateId(); diff --git a/awsapi/pom.xml b/awsapi/pom.xml index 601e6959a5..32ec2c4466 100644 --- a/awsapi/pom.xml +++ b/awsapi/pom.xml @@ -126,94 +126,6 @@ CAStorSDK 1.3.1-CS40 - - org.apache.rampart - rahas - ${cs.rampart.version} - mar - - - bouncycastle - bcprov-jdk14 - - - org.apache.xalan - xalan - - - org.opensaml - opensaml1 - - - - - org.apache.rampart - rampart - ${cs.rampart.version} - mar - - - bouncycastle - bcprov-jdk14 - - - org.apache.xalan - xalan - - - org.opensaml - opensaml1 - - - - - org.apache.rampart - rampart-core - ${cs.rampart.version} - runtime - - - org.apache.xalan - xalan - - - org.opensaml - opensaml1 - - - - - org.apache.rampart - rampart-policy - ${cs.rampart.version} - runtime - - - org.apache.xalan - xalan - - - org.opensaml - opensaml1 - - - - - org.apache.rampart - rampart-trust - ${cs.rampart.version} - runtime - - - org.apache.xalan - xalan - - - org.opensaml - opensaml1 - - - org.slf4j slf4j-jdk14 diff --git a/client/WEB-INF/classes/resources/messages.properties b/client/WEB-INF/classes/resources/messages.properties index c46361a12e..eff2c3ee81 100644 --- a/client/WEB-INF/classes/resources/messages.properties +++ b/client/WEB-INF/classes/resources/messages.properties @@ -14,6 +14,12 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. +message.listView.subselect.multi=(Ctrl/Cmd-click) +label.use.vm.ips=Use VM IPs +label.reinstall.vm=Reinstall VM +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. +label.recover.vm=Recover VM +message.recover.vm=Please confirm that you would like to recover this VM. label.port=Port label.remove.ldap=Remove LDAP label.configure.ldap=Configure LDAP @@ -1277,6 +1283,18 @@ label.assign.instance.another=Assign Instance to Another Account label.network.addVM=Add network to VM label.set.default.NIC=Set default NIC label.Xenserver.Tools.Version61plus=XenServer Tools Version 6.1\+ +label.supportsstrechedl2subnet=Supports Streched L2 Subnet +label.menu.vpc.offerings=VPC Offerings +label.vpc.offering=VPC Offering +label.regionlevelvpc=Region Level VPC +label.add.vpc.offering=Add VPC Offering +label.distributedrouter=DistributedRouter +label.vpc.offering.details=VPC offering details +label.disable.vpc.offering=Disable VPC offering +label.enable.vpc.offering=Enable VPC offering +label.remove.vpc.offering=Remove VPC offering +label.vpc.distributedvpcrouter=Distributed VPC Router +label.vpc.supportsregionlevelvpc=Supports Region Level VPC label.dynamically.scalable=Dynamically Scalable label.instance.scaled.up=Instance Scaled Up label.tag.key=Tag Key @@ -1395,7 +1413,7 @@ label.addes.new.f5=Added new F5 label.f5.details=F5 details label.srx.details=SRX details label.palo.alto.details=Palo Alto details -label.added.nicira.nvp.controller=Added new Nicira NVP Controller\ +label.added.nicira.nvp.controller=Added new Nicira NVP Controller label.nicira.nvp.details=Nicira NVP details label.added.new.bigswitch.vns.controller=Added new BigSwitch VNS Controller label.bigswitch.vns.details=BigSwitch VNS details @@ -1481,6 +1499,12 @@ label.allow=Allow label.deny=Deny label.default.egress.policy=Default egress policy label.xenserver.tools.version.61.plus=XenServer Tools Version 6.1\+ +label.gpu=GPU +label.vgpu.type=vGPU type +label.vgpu.video.ram=Video RAM +label.vgpu.max.resolution=Max resolution +label.vgpu.max.vgpu.per.gpu=vGPUs per GPU +label.vgpu.remaining.capacity=Remaining capacity managed.state=Managed State message.acquire.new.ip.vpc=Please confirm that you would like to acquire a new IP for this VPC. message.acquire.new.ip=Please confirm that you would like to acquire a new IP for this network. @@ -1780,7 +1804,7 @@ message.tooltip.reserved.system.netmask=The network prefix that defines the pod message.tooltip.zone.name=A name for the zone. message.update.os.preference=Please choose a OS preference for this host. All virtual instances with similar preferences will be first allocated to this host before choosing another. message.update.resource.count=Please confirm that you want to update resource counts for this account. -message.update.ssl=Please submit a new X.509 compliant SSL certificate to be updated to each console proxy virtual instance\: +message.update.ssl=Please submit a new X.509 compliant SSL certificate to be updated to each console proxy and secondary storage virtual instance\: message.validate.instance.name=Instance name can not be longer than 63 characters. Only ASCII letters a~z, A~Z, digits 0~9, hyphen are allowed. Must start with a letter and end with a letter or a digit. message.virtual.network.desc=A dedicated virtualized network for your account. The broadcast domain is contained within a VLAN and all public network access is routed out by a virtual router. message.vm.create.template.confirm=Create Template will reboot the VM automatically. @@ -1793,7 +1817,7 @@ message.zone.no.network.selection=The zone you selected does not have any choice message.zone.step.1.desc=Please select a network model for your zone. message.zone.step.2.desc=Please enter the following info to add a new zone message.zone.step.3.desc=Please enter the following info to add a new pod -message.zoneWizard.enable.local.storage=WARNING\: If you enable local storage for this zone, you must do the following, depending on where you would like your system VMs to launch\:

1. If system VMs need to be launched in primary storage, primary storage needs to be added to the zone after creation. You must also start the zone in a disabled state.

2. If system VMs need to be launched in local storage, system.vm.use.local.storage needs to be set to true before you enable the zone.


Would you like to continue? +message.zoneWizard.enable.local.storage=WARNING\: If you enable local storage for this zone, you must do the following, depending on where you would like your system VMs to launch\:

1. If system VMs need to be launched in shared primary storage, shared primary storage needs to be added to the zone after creation. You must also start the zone in a disabled state.

2. If system VMs need to be launched in local primary storage, system.vm.use.local.storage needs to be set to true before you enable the zone.


Would you like to continue? message.validate.fieldrequired=This field is required. message.validate.fixfield=Please fix this field. message.validate.email.address=Please enter a valid email address. @@ -1878,6 +1902,11 @@ message.confirm.enable.network.offering=Are you sure you want to enable this net message.enabling.network.offering=Enabling network offering message.confirm.remove.network.offering=Are you sure you want to remove this network offering? message.confirm.disable.network.offering=Are you sure you want to disable this network offering? +message.disabling.vpc.offering=Disabling VPC offering +message.confirm.enable.vpc.offering=Are you sure you want to enable this VPC offering? +message.enabling.vpc.offering=Enabling VPC offering +message.confirm.remove.vpc.offering=Are you sure you want to remove this VPC offering? +message.confirm.disable.vpc.offering=Are you sure you want to disable this VPC offering? mode=Mode network.rate=Network Rate notification.reboot.instance=Reboot instance diff --git a/client/WEB-INF/classes/resources/messages_ar.properties b/client/WEB-INF/classes/resources/messages_ar.properties index bb3fe83643..4f65118820 100644 --- a/client/WEB-INF/classes/resources/messages_ar.properties +++ b/client/WEB-INF/classes/resources/messages_ar.properties @@ -83,6 +83,7 @@ label.endpoint=\u0646\u0642\u0637\u0629 \u0627\u0644\u0646\u0647\u0627\u064a\u06 label.error=\u062e\u0637\u0623 label.ESP.lifetime=\u0639\u0645\u0631 ESP (\u062b\u0627\u0646\u064a\u0629) label.ESP.policy=\u0633\u064a\u0627\u0633\u0629 ESP +label.failed=\u062e\u0637\u0623 label.filterBy=\u062a\u0635\u0641\u064a\u0629 \u062d\u0633\u0628 label.full.path=\u0645\u0633\u0627\u0631 \u0643\u0627\u0645\u0644 label.guest.type=\u0646\u0648\u0639 \u0627\u0644\u0636\u064a\u0641 @@ -262,7 +263,6 @@ message.step.3.desc= message.suspend.project=\u0647\u0644 \u0623\u0646\u062a \u0645\u062a\u0623\u0643\u062f \u0645\u0646 \u0623\u0646\u0643 \u062a\u0631\u064a\u062f \u0625\u064a\u0642\u0627\u0641 \u0647\u0630\u0627 \u0627\u0644\u0645\u0634\u0631\u0648\u0639 \u061f message.update.resource.count=\u0627\u0644\u0631\u062c\u0627\u0621 \u0627\u0644\u062a\u0623\u0643\u064a\u062f \u0628\u0623\u0646\u0643 \u062a\u0631\u063a\u0628 \u0628\u062a\u062d\u062f\u064a\u062b \u0645\u0635\u0627\u062f\u0631 \u0627\u0644\u062d\u0633\u0627\u0628\u0627\u062a \u0644\u0647\u0630\u0627 \u0627\u0644\u062d\u0633\u0627\u0628 message.vm.review.launch=\u064a\u0631\u062c\u0649 \u0645\u0631\u0627\u062c\u0639\u0629 \u0627\u0644\u0645\u0639\u0644\u0648\u0645\u0627\u062a \u0627\u0644\u062a\u0627\u0644\u064a\u0629 \u0648\u062a\u0623\u0643\u062f \u0623\u0646 \u0645\u062b\u0627\u0644\u0643 \u0627\u0644\u0625\u0641\u062a\u0631\u0627\u0636\u064a \u0635\u062d\u064a\u062d \u0642\u0628\u0644 \u0627\u0644\u0625\u0646\u0637\u0644\u0627\u0642 -message.zoneWizard.enable.local.storage=\u062a\u062d\u0630\u064a\u0631\\\: \u0625\u0630\u0627 \u0642\u0645\u062a \u0628\u062a\u0645\u0643\u064a\u0646 \u0627\u0644\u0630\u0627\u0643\u0631\u0629 \u0627\u0644\u0645\u062d\u0644\u064a\u0629 \u0644\u0647\u0630\u0627 \u0627\u0644\u0646\u0637\u0627\u0642 \u064a\u062c\u0628 \u0639\u0644\u064a\u0643 \u0639\u0645\u0644 \u0627\u0644\u0622\u062a\u064a \u060c \u0625\u0639\u062a\u0645\u0627\u062f\u0627 \u0639\u0644\u0649 \u0627\u0644\u0645\u0643\u0627\u0646 \u0627\u0644\u0630\u064a \u062a\u0631\u063a\u0628 \u0623\u0646 \u064a\u0646\u0637\u0644\u0642 \u0645\u0646\u0647 \u0646\u0638\u0627\u0645\u0643 \u0627\u0644\u0625\u0641\u062a\u0631\u0627\u0636\u064a \\\:

1.\u0625\u0630\u0627 \u0643\u0627\u0646 \u0646\u0638\u0627\u0645\u0643 \u0627\u0644\u0625\u0641\u062a\u0631\u0627\u0636\u064a \u064a\u062d\u062a\u0627\u062c \u0625\u0644\u0649 \u062a\u0634\u063a\u064a\u0644 \u0627\u0644\u0630\u0627\u0643\u0631\u0629 \u0627\u0644\u0625\u0628\u062a\u062f\u0627\u0626\u064a\u0629 notification.reboot.instance=\u0625\u0639\u0627\u062f\u0629 \u062a\u0634\u063a\u064a\u0644 \u0627\u0644\u0646\u0645\u0648\u0630\u062c notification.start.instance=\u0628\u062f\u0621 \u0627\u0644\u0646\u0645\u0648\u0630\u062c notification.stop.instance=\u0625\u064a\u0642\u0627\u0641 \u0627\u0644\u0646\u0645\u0648\u0630\u062c diff --git a/client/WEB-INF/classes/resources/messages_ca.properties b/client/WEB-INF/classes/resources/messages_ca.properties index 2d8e953419..3a9c77cd05 100644 --- a/client/WEB-INF/classes/resources/messages_ca.properties +++ b/client/WEB-INF/classes/resources/messages_ca.properties @@ -136,6 +136,7 @@ label.migrate.instance.to.host=Migrar inst\u00e0ncia a un altre amfitri\u00f3 "H label.migrate.instance.to.ps=Migrar inst\u00e0ncia a un altra emmagatzematge primari label.migrate.router.to=Migrar router a label.migrate.systemvm.to=Migrar MV de sistema a\: +label.mode=Mode label.move.down.row=Moure una fila cap a baix label.move.to.top=Moure a dalt label.move.up.row=Moure una fla cap a dalt diff --git a/client/WEB-INF/classes/resources/messages_de_DE.properties b/client/WEB-INF/classes/resources/messages_de_DE.properties index 2f164609d0..4d5852c3c4 100644 --- a/client/WEB-INF/classes/resources/messages_de_DE.properties +++ b/client/WEB-INF/classes/resources/messages_de_DE.properties @@ -224,8 +224,8 @@ label.add.system.service.offering=System-Service-Angebot hinzuf\u00fcgen label.add.template=Vorlage hinzuf\u00fcgen label.add.user=Benutzer hinzuf\u00fcgen label.add.vlan=VLAN hinzuf\u00fcgen -label.add.vxlan=VXLAN hinzuf\u00fcgen label.add.volume=Volume hinzuf\u00fcgen +label.add.vxlan=VXLAN hinzuf\u00fcgen label.add.zone=Zone hinzuf\u00fcgen label.admin.accounts=Administrator-Konten label.admin=Administrator @@ -274,6 +274,7 @@ label.close=Schliessen label.cloud.console=Cloud Management Konsole label.cloud.managed=Geleitet von cloud.com label.cluster=Cluster +label.clusters=Cluster label.cluster.type=Cluster-Typ label.code=Code label.configuration=Konfiguration @@ -341,6 +342,7 @@ label.full=Voll label.gateway=Schnittstelle label.general.alerts=Allgemeine Warnungen label.generating.url=Generieren der URL +label.gluster.volume=Volume label.go.step.2=Gehe zu Schritt 2 label.go.step.3=Weiter zu Schritt 3 label.go.step.4=Weiter mit Schritt 4 @@ -506,6 +508,7 @@ label.PING.dir=PING-Verzeichnis label.PING.storage.IP=IP des externen Speichers anpingen label.please.wait=Bitte warten label.pod=Pod +label.pods=Pod label.PreSetup=Voreinstellung label.primary.allocated=Zugewiesener Hauptspeicher label.primary.network=Hauptnetzwerk @@ -551,6 +554,7 @@ label.sent=Versendet label.server=Server label.service.offering=Service-Angebot label.session.expired=Sitzung abgelaufen +label.setup=Konfiguration label.shared=Gemeinsame label.SharedMountPoint=Geteilter Einh\u00e4ngepunkt label.show.ingress.rule=Zeige Regeln, die den Zutritt steuern @@ -622,9 +626,7 @@ label.virtual.network=Virtuelles Netzwerk label.vlan.id=VLAN ID label.vlan.range=VLAN Reichweite label.vlan=VLAN -label.vxlan.id=VXLAN ID -label.vxlan.range=VXLAN Reichweite -label.vxlan=VXLAN +label.vlan.vni.range=VLAN Reichweite label.vm.add=Instanz hinzuf\u00fcgen label.vm.destroy=Zerst\u00f6ren label.VMFS.datastore=VMFS Datenspeicher @@ -634,11 +636,16 @@ label.vmsnapshot.type=Typ label.vm.start=Start label.vm.stop=Stopp label.vms=VMs +label.vnet.id=VLAN ID +label.vnet=VLAN label.volume.limits=Volume Grenzen label.volume.name=Volume Name label.volumes=Volumes label.volume=Volume label.vpn=VPN +label.vxlan.id=VXLAN ID +label.vxlan.range=VXLAN Reichweite +label.vxlan=VXLAN label.waiting=Warten label.warn=Warnen label.wednesday=Mittwoch @@ -646,6 +653,7 @@ label.weekly=W\u00f6chentlich label.welcome=Willkommen label.yes=Ja label.zone.id=Zone ID +label.zones=Zone label.zone=Zone message.acquire.public.ip=Bitte w\u00e4hlen Sie eine Zone, von der Sie Ihre neue IP erlangen m\u00f6chten. message.action.cancel.maintenance=Ihr Host ist erfolgreich f\u00fcr die Wartung abgebrochen. Dieser Prozess kann ein paar Minuten dauern. diff --git a/client/WEB-INF/classes/resources/messages_es.properties b/client/WEB-INF/classes/resources/messages_es.properties index 6d6e4860cf..f2d754ebc0 100644 --- a/client/WEB-INF/classes/resources/messages_es.properties +++ b/client/WEB-INF/classes/resources/messages_es.properties @@ -15,22 +15,15 @@ # specific language governing permissions and limitations # under the License. -error.installWizard.message=Algo salio mal, debes ir para atr\u00e1s y corregir los error. -error.login=Su nombre de usuario / contrase\u00c3\u00b1a no coincide con nuestros registros. +changed.item.properties=Propiedades del elemento cambiados +error.installWizard.message=Algo salio mal, debes ir para atr\u00e1s y corregir los errores. +error.login=Su nombre de usuario / contrase\u00f1a no coinciden con nuestros registros. error.mgmt.server.inaccessible=El Servidor de Gesti\u00c3\u00b3n es inaccesible. Por favor, int\u00c3\u00a9ntelo de nuevo m\u00c3\u00a1s tarde. +error.password.not.match=Los campos de contrase\u00f1a no coinciden error.session.expired=Su sesi\u00c3\u00b3n ha caducado. error.unresolved.internet.name=El nombre de Internet no se puede resolver. extractable=extra\u00c3\u00adble force.delete.domain.warning=Advertencia\: Si elige esta opci\u00c3\u00b3n, la supresi\u00c3\u00b3n de todos los dominios secundarios y todas las cuentas asociadas y sus recursos. -force.delete=Fuerza Borrar -force.remove=Fuerza Retire -force.remove.host.warning=Advertencia\: Si elige esta opci\u00c3\u00b3n, CloudStack para detener la fuerza todas las m\u00c3\u00a1quinas virtuales en ejecuci\u00c3\u00b3n antes de retirar este host del cl\u00c3\u00baster. -force.stop=Grupo de Alto -force.stop.instance.warning=Advertencia\: Obligar a una parada en este caso deber\u00c3\u00ada ser su \u00c3\u00baltima opci\u00c3\u00b3n. Puede conducir a la p\u00c3\u00a9rdida de datos, as\u00c3\u00ad como un comportamiento incoherente del Estado de la m\u00c3\u00a1quina virtual. -ICMP.code=ICMP C\u00c3\u00b3digo -ICMP.type=Tipo ICMP -image.directory=Directorio de la imagen -inline=en l\u00c3\u00adnea force.delete=Forzar el borrado force.remove=Forzar el retiro force.remove.host.warning=Advertencia\: Si elige esta opci\u00f3n, CloudStack para detener la fuerza todas las m\u00e1quinas virtuales en ejecuci\u00f3n antes de retirar este host del cl\u00faster. @@ -42,6 +35,7 @@ image.directory=Directorio de im\u00e1genes inline=alineado label.about=Acerca de label.about.app=Acerca de CloudStack +label.accept.project.invitation=Aceptar invitaci\u00f3n al proyecto label.account=Cuenta label.account.id=ID de la cuenta label.account.name=Nombre de cuenta @@ -89,6 +83,7 @@ label.action.delete.load.balancer=Eliminar equilibrador de carga label.action.delete.load.balancer.processing=Eliminaci\u00c3\u00b3n del equilibrador de carga .... label.action.delete.network=Eliminar Red label.action.delete.network.processing=Eliminaci\u00c3\u00b3n de red .... +label.action.delete.nexusVswitch=Eliminar Nexus 1000v label.action.delete.pod=Eliminar Pod label.action.delete.pod.processing=Eliminar Pod .... label.action.delete.primary.storage=Almacenamiento primario Eliminar @@ -121,6 +116,7 @@ label.action.disable.account=Desactivar cuenta label.action.disable.account.processing=Deshabilitar cuenta .... label.action.disable.cluster=Deshabilitar cl\u00c3\u00baster label.action.disable.cluster.processing=Desactivaci\u00c3\u00b3n de Cluster Server .... +label.action.disable.nexusVswitch=Deshabilitar Nexus 1000v label.action.disable.pod=Deshabilitar Pod label.action.disable.pod.processing=Deshabilitar Pod .... label.action.disable.static.NAT=Deshabilitar NAT est\u00c3\u00a1tica @@ -155,6 +151,8 @@ label.action.enable.cluster=Habilitar cl\u00c3\u00baster label.action.enable.cluster.processing=Habilitar cl\u00c3\u00baster .... label.action.enable.maintenance.mode=Activar el modo de mantenimiento label.action.enable.maintenance.mode.processing=Habilitaci\u00c3\u00b3n del modo de mantenimiento .... +label.action.enable.nexusVswitch=Habilitar Nexus 1000v +label.action.enable.physical.network=Habilitar red f\u00edsica label.action.enable.pod=Habilitar Pod label.action.enable.pod.processing=Habilitaci\u00c3\u00b3n Pod .... label.action.enable.static.NAT=Habilitar NAT est\u00c3\u00a1tica @@ -167,6 +165,7 @@ label.action.force.reconnect=Fuerza Vuelva a conectar label.action.force.reconnect.processing=Reconectando .... label.action.generate.keys=Generar Claves label.action.generate.keys.processing=Generar claves .... +label.action.list.nexusVswitch=Listar Nexus 1000v label.action.lock.account=Bloqueo de cuenta label.action.lock.account.processing=Bloqueo de cuenta .... label.action.manage.cluster=gestionar racimo @@ -184,6 +183,8 @@ label.action.reboot.router=Reiniciar router label.action.reboot.systemvm.processing=reinicio del sistema VM .... label.action.reboot.systemvm=Reiniciar sistema VM label.action.recurring.snapshot=recurrente instant\u00c3\u00a1neas +label.action.register.iso=Registrar ISO +label.action.register.template=Registrar template label.action.release.ip=estreno IP label.action.release.ip.processing=Liberar IP .... label.action.remove.host.processing=Extracci\u00c3\u00b3n de host .... @@ -214,16 +215,24 @@ label.action.update.OS.preference=Actualizar OS Preferencia label.action.update.OS.preference.processing=Actualizaci\u00c3\u00b3n de sistema operativo preferencia .... label.action.update.resource.count=Actualizaci\u00c3\u00b3n de recursos Conde label.action.update.resource.count.processing=Actualizaci\u00c3\u00b3n de Conde de recursos .... +label.activate.project=Activar Proyecto label.active.sessions=Sesiones activas label.add.account=A\u00c3\u00b1adir cuenta +label.add.accounts=Agregar cuentas +label.add.accounts.to=Agregar cuentas a +label.add.ACL=Agregar ACL label.add=Agregar +label.add.by=A\u00f1adir por label.add.by.cidr=A\u00c3\u00b1adir Por CIDR label.add.by.group=A\u00c3\u00b1adir Por el Grupo de label.add.cluster=A\u00c3\u00b1adir Grupo label.add.direct.iprange=A\u00c3\u00b1adir Direct IP Gama label.add.disk.offering=A\u00c3\u00b1adir disco Ofrenda label.add.domain=Agregar dominio +label.add.egress.rule=Agregar regla de salida +label.add.F5.device=Agregar dispositivo F5 label.add.firewall=Agregar Servidor de seguridad +label.add.guest.network=Agregar red de invitado label.add.host=Agregar host label.adding=Agregar label.adding.cluster=Adici\u00c3\u00b3n de cl\u00c3\u00baster @@ -238,29 +247,48 @@ label.add.ip.range=A\u00c3\u00b1adir Rango de IP label.additional.networks=Redes adicional label.add.load.balancer=A\u00c3\u00b1adir equilibrador de carga label.add.more=A\u00c3\u00b1adir m\u00c3\u00a1s +label.add.netScaler.device=Agregar dispositivo Netscaler label.add.network=Agregar sitios de red label.add.network.device=A\u00c3\u00b1adir dispositivo de red +label.add.new.gateway=Agregar nuevo gateway +label.add.new.SRX=Agregar nuevo SRX label.add.pod=A\u00c3\u00b1adir Pod +label.add.port.forwarding.rule=Agregar regla port forwarding label.add.primary.storage=A\u00c3\u00b1adir Almacenamiento primario +label.add.route=Agregar ruta +label.add.rule=Agregar regla label.add.secondary.storage=A\u00c3\u00b1adir secundaria almacenamiento label.add.security.group=Agregar grupo de seguridad label.add.service.offering=A\u00c3\u00b1adir Servicio de Oferta +label.add.SRX.device=Agregar dispositivo SRX +label.add.static.nat.rule=Agregar regla NAT est\u00e1tica +label.add.static.route=Agregar ruta est\u00e1tica label.add.template=A\u00c3\u00b1adir plantilla label.add.to.group=Agregar al grupo label.add.user=Agregar usuario label.add.vlan=A\u00c3\u00b1adir VLAN -label.add.vxlan=A\u00c3\u00b1adir VXLAN +label.add.vm=Agregar VM +label.add.vms=Agregar VMs +label.add.vms.to.lb=Agregar VM(s) a el balanceador de carga label.add.volume=A\u00c3\u00b1adir volumen +label.add.vpc=Agregar VPC +label.add.VPN.gateway=Agregar Gateway VPN +label.add.vpn.user=Agregar usuario VPN +label.add.vxlan=A\u00c3\u00b1adir VXLAN label.add.zone=A\u00c3\u00b1adir Zona label.admin.accounts=Administrador de Cuentas label.admin=Admin label.advanced=Avanzado label.advanced.mode=Modo avanzado label.advanced.search=B\u00c3\u00basqueda Avanzada +label.agent.password=Password de Agente +label.agent.username=Usuario de Agente +label.agree=De-acuerdo label.alert=Alerta label.algorithm=Algoritmo label.allocated=Asignados label.api.key=clave de API +label.apply=Aplicar label.app.name=CloudStack label.archive.alerts=Archivar alertas label.archive.events=Archivar sucesos @@ -273,6 +301,7 @@ label.availability.zone=Disponibilidad de la zona label.available=Disponible label.available.public.ips=Disponible direcciones IP p\u00c3\u00bablicas label.back=Volver +label.bandwidth=Ancho de banda label.basic.mode=Modo b\u00c3\u00a1sico label.bootable=arranque label.broadcast.domain.type=Tipo de dominio de difusi\u00c3\u00b3n @@ -297,26 +326,46 @@ label.by.type=Por tipo label.by.zone=Por Zona label.cancel=Cancelar label.certificate=Certificado +label.change.value=Cambiar valor label.character=Personaje +label.checksum=suma de verificaci\u00f3n MD5 label.cidr.account=CIDR o de cuenta / Grupo de Seguridad label.cidr=CIDR label.cidr.list=fuente CIDR +label.CIDR.list=Lista CIDR +label.clean.up=Limpiar +label.clear.list=Limpiar lista label.close=Cerrar label.cloud.console=Cloud Management Console label.cloud.managed=Cloud.com Gestionado label.cluster=Grupo +label.cluster.name=Nombre del Cluster +label.clusters=Cluster label.cluster.type=Tipo de Cluster Server label.clvm=CLVM label.code=C\u00c3\u00b3digo +label.community=Comunidad +label.compute.and.storage=Computo y Almacenamiento label.configuration=Configuraci\u00c3\u00b3n +label.configure=Configurar +label.configure.vpc=Configurar VPC label.confirmation=Confirmation +label.confirm.password=Confirmar password label.congratulations=Felicitaciones \! +label.console.proxy=Consola proxy +label.continue.basic.install=Continuar con la instalaci\u00f3n b\u00e1sica +label.continue=Continuar +label.corrections.saved=Correcciones guardadas label.cpu.allocated=CPU asignado label.cpu.allocated.for.VMs=CPU asignado para m\u00c3\u00a1quinas virtuales label.CPU.cap=CPU Cap label.cpu=CPU +label.cpu.mhz=CPU (En MHz) label.cpu.utilized=CPU Utilizado label.created=creaci\u00c3\u00b3n +label.create.project=Crear proyecto +label.create.template=Crear template +label.create.VPN.connection=Crear Conexi\u00f3n VPN label.cross.zones=Cruz Zonas label.custom.disk.iops=IOPS personalizadas label.custom.disk.size=Personal Disk Size @@ -325,19 +374,29 @@ label.data.disk.offering=Datos Disco Offering label.date=Fecha label.day.of.month=D\u00c3\u00ada del mes label.day.of.week=d\u00c3\u00ada de la semana +label.decline.invitation=Declinar invitaci\u00f3n label.default.use=Usar por defecto label.delete.alerts=Eliminar alertas label.delete=Eliminar label.delete.events=Eliminar sucesos +label.delete.F5=Borrar F5 +label.delete.gateway=borrar gateway +label.delete.project=Eliminar proyecto +label.delete.VPN.connection=eliminar conexi\u00f3n VPN +label.delete.VPN.gateway=eliminar Gateway VPN +label.delete.vpn.user=Eliminar usuario VPN label.deleting.failed=No se pudo eliminar label.deleting.processing=Eliminar .... label.description=Descripci\u00c3\u00b3n +label.destination.zone=Zona de destino label.destroy=Destroy label.detaching.disk=Extracci\u00c3\u00b3n del disco label.details=Detalles label.device.id=ID de dispositivo +label.devices=Dispositivos label.DHCP.server.type=Tipo de servidor DHCP label.disabled=personas de movilidad reducida +label.disable.vpn=Deshabilitar VPN label.disabling.vpn.access=Desactivaci\u00c3\u00b3n de VPN de acceso label.disk.allocated=disco asignado label.disk.iops.max=IOPS m\u00e1ximas @@ -351,24 +410,41 @@ label.disk.volume=volumen de disco label.display.text=visualizaci\u00c3\u00b3n de texto label.dns.1=DNS 1 label.dns.2=DNS 2 +label.dns=DNS label.domain.admin=Administrador de dominio label.domain=dominio label.domain.id=ID de dominio label.domain.name=Nombre de dominio label.domain.suffix=DNS sufijo de dominio (es decir, xyz.com) +label.done=Listo label.double.quotes.are.not.allowed=comillas dobles no se permite label.download.progress=Progreso de la descarga label.edit=Editar +label.edit.lb.rule=Edite regla LB +label.edit.network.details=Editar detalles de red +label.edit.project.details=Editar detalles de proyecto +label.edit.tags=Editar etiquetas +label.edit.traffic.type=Edite el tipo de trafico +label.edit.vpc=Editar VPC label.egress.default.policy=Directiva de salida predeterminada +label.egress.rule=Regla de salida +label.egress.rules=Reglas de salida label.email=correo electr\u00c3\u00b3nico +label.enable.swift=Habilitar Swift +label.enable.vpn=Habilitar VPN label.enabling.vpn.access=Habilitaci\u00c3\u00b3n de Acceso VPN label.enabling.vpn=Habilitaci\u00c3\u00b3n VPN label.endpoint.or.operation=punto final o de Operaci\u00c3\u00b3n label.end.port=Puerto final +label.enter.token=Ingrese token label.error.code=C\u00c3\u00b3digo de error label.error=Error +label.ESP.encryption=Encriptaci\u00f3n ESP +label.ESP.hash=Hash +label.ESP.policy=Pol\u00edtica ESP label.esx.host=ESX / ESXi anfitri\u00c3\u00b3n label.example=Ejemplo +label.f5=F5 label.failed=Error label.featured=destacados label.firewall=Servidor de seguridad @@ -376,9 +452,11 @@ label.first.name=Nombre label.format=Formato label.friday=Viernes label.full=completo +label.full.path=Path completo label.gateway=puerta de enlace label.general.alerts=General de Alertas label.generating.url=Generar URL +label.gluster.volume=Volumen label.go.step.2=Ir al paso 2 label.go.step.3=Ir al paso 3 label.go.step.4=Ir al paso 4 @@ -390,32 +468,48 @@ label.guest.gateway=Habitaci\u00c3\u00b3n Gateway label.guest.ip=Habitaci\u00c3\u00b3n direcci\u00c3\u00b3n IP label.guest.ip.range=Habitaci\u00c3\u00b3n Rango de IP label.guest.netmask=Habitaci\u00c3\u00b3n m\u00c3\u00a1scara de red +label.guest.networks=Redes de invitado label.ha.enabled=HA Activado label.help=Ayuda label.hide.ingress.rule=Ocultar el art\u00c3\u00adculo ingreso +label.hints=Sugerencias label.host.alerts=Host Alertas label.host=Ej\u00c3\u00a9rcitos +label.host.MAC=MAC del Host label.host.name=nombre de host label.hosts=Ej\u00c3\u00a9rcitos +label.host.tags=Etiquetas de Host label.hourly=por hora label.hypervisor=Hypervisor label.hypervisors=Hipervisores label.hypervisor.snapshot.reserve=Reserva de instant\u00e1neas de hipervisores label.hypervisor.type=Tipo Hypervisor label.id=ID +label.IKE.DH=IKE DH +label.IKE.encryption=Encriptaci\u00f3n IKE +label.IKE.hash=Hash IKE +label.IKE.policy=Pol\u00edtica IKE label.info=Informaci\u00c3\u00b3n label.ingress.rule=ingreso Regla label.initiated.by=Iniciado por +label.installWizard.addSecondaryStorageIntro.subtitle=Que es almacenamiento secundario? +label.installWizard.addSecondaryStorageIntro.title=A\u00f1adir almacenamiento secundario +label.installWizard.addZone.title=Agregar zona label.installWizard.click.launch=Click en el bot\u00f3n de lanzar. +label.installWizard.title=Hola y Bienvenido a CloudStack&\#8482 label.instance=Instancia label.instance.limits=Instancia L\u00c3\u00admites label.instance.name=Nombre de instancia label.instances=Instancias label.internal.dns.1=DNS interno una label.internal.dns.2=DNS interno 2 +label.internal.name=Nombre interno label.interval.type=Tipo de intervalo +label.introduction.to.cloudstack=Introducci\u00f3n a CloudStack&\#8482 label.invalid.integer=entero no v\u00c3\u00a1lido label.invalid.number=N\u00c3\u00bamero no v\u00c3\u00a1lido +label.invitations=Invitaciones +label.invited.accounts=Cuentas de invitado label.invite=Invitar label.invite.to=Invitar a . label.ip.address=Direcci\u00c3\u00b3n IP @@ -425,35 +519,50 @@ label.ip=IP label.ip.limits=IP p\u00c3\u00bablica L\u00c3\u00admites label.ip.or.fqdn=IP o FQDN label.ip.range=Rango de IP +label.IPsec.preshared.key=IPsec Preshared-Key label.ips=IP label.iscsi=iSCSI label.is.default=Es por defecto label.iso.boot=ISO de arranque label.iso=ISO +label.isolation.method=M\u00e9todo de aislamiento label.isolation.mode=modo de aislamiento label.is.redundant.router=redundante label.is.shared=es compartido label.is.system=es el Sistema +label.item.listing=Listando art\u00edculos label.keep=Mantener +label.keyboard.type=Tipo de teclado +label.key=Llave +label.label=Etiqueta label.lang.chinese=Chino (simplificado) label.lang.english=Ingl\u00c3\u00a9s label.lang.japanese=japon\u00c3\u00a9s label.lang.spanish=Espa\u00c3\u00b1ol label.last.disconnected=\u00c3\u009altima Desconectado label.last.name=Apellido +label.latest.events=\u00daltimos eventos label.launch=Lanzar label.launch.vm=Lanzar maquina virtual label.level=Nivel label.load.balancer=equilibrador de carga +label.load.balancing=Balanceador de Carga +label.load.balancing.policies=Pol\u00edticas del balanceador de carga label.loading=Carga label.local=local +label.local.storage=Almacenamiento Local label.login=Login label.logout=Cerrar sesi\u00c3\u00b3n label.lun=LUN +label.LUN.number=LUN \# label.manage=Administrar +label.manage.resources=Administrar los Recursos label.maximum=m\u00c3\u00a1ximo +label.max.templates=Plantillas M\u00e1ximos label.max.volumes=Maxima cantidad de Volumes +label.may.continue=Ahora puede continuar. label.memory.allocated=memoria asignada +label.memory.mb=Memoria (En MB) label.memory=memoria (en MB) label.memory.total=Total de memoria label.memory.used=memoria usada @@ -472,6 +581,7 @@ label.menu.events=Eventos label.menu.featured.isos=destacados ISO label.menu.featured.templates=destacados plantillas label.menu.global.settings=Configuraci\u00c3\u00b3n global +label.menu.infrastructure=Infraestructura label.menu.instances=Instancias label.menu.ipaddresses=Direcciones IP label.menu.isos=ISO @@ -499,21 +609,31 @@ label.migrate.instance.to=Migraci\u00c3\u00b3n de ejemplo para label.migrate.instance.to.ps=Migrar instancia a otro primary storage. label.migrate.router.to=Router para migrar label.migrate.systemvm.to=Migrar m\u00c3\u00a1quina virtual del sistema para +label.migrate.to.host=Migrar a host +label.migrate.to.storage=Migrar a almacenamiento +label.migrate.volume=Migrar volumen a otro almacenamiento primario label.minimum=M\u00c3\u00adnimo label.minute.past.hour=Minuto (s) despu\u00c3\u00a9s de la hora +label.mode=modo label.monday=lunes label.monthly=mensual label.more.templates=plantillas \= M\u00c3\u00a1s +label.move.down.row=Mover abajo una fila +label.move.to.top=Mover al principio +label.move.up.row=Mover una fila arriba label.my.account=Mi Cuenta +label.my.network=Mi red label.my.templates=Mis plantillas label.name=Nombre label.name.optional=Nombre (Opcional) +label.nat.port.range=Rango puertos NAT label.netmask=m\u00c3\u00a1scara de red label.network.desc=Red de Desc label.network.device=De dispositivos de red label.network.device.type=Tipo de red de dispositivos label.network.domain=red de dominio label.network.id=ID de red +label.networking.and.security=Redes y Seguridad label.network.name=Nombre de red label.network.offering.display.text=Red ofrece visualizaci\u00c3\u00b3n de texto label.network.offering.id=Red ofrece ID @@ -527,14 +647,17 @@ label.network.type=Tipo de red label.network.write=Escribir en la red label.new=Nuevo label.new.password=Nueva contrase\u00c3\u00b1a +label.new.project=Nuevo Proyecto label.new.vm=Nueva maquina virtual label.next=Siguiente label.nfs=NFS label.nfs.server=servidor NFS label.nfs.storage=NFS Almacenamiento +label.nic.adapter.type=Tipo de adaptador NIC label.nics=NIC label.no.actions=No Acciones disponibles label.no.alerts=No alertas recientes +label.no.data=No hay informaci\u00f3n que mostrar label.no.errors=No recientes errores label.no.isos=No ISOs disponibles label.no.items=No art\u00c3\u00adculos disponibles @@ -543,11 +666,18 @@ label.no=No label.no.security.groups=No hay grupos disponibles de Seguridad label.not.found=No se ha encontrado label.no.thanks=No, gracias +label.number.of.clusters=N\u00famero de Clusters +label.number.of.hosts=N\u00famero de Hosts +label.number.of.pods=N\u00famero de Pods +label.number.of.system.vms=N\u00famero de VM\\'s del Systema +label.number.of.virtual.routers=N\u00famero de Routers Virtuales +label.number.of.zones=N\u00famero de Zonas label.num.cpu.cores=n\u00c3\u00bamero de n\u00c3\u00bacleos de CPU label.numretries=N\u00c3\u00bamero de reintentos label.ocfs2=OCFS2 label.offer.ha=Oferta HA label.optional=Opcional +label.order=Ordenar label.os.preference=OS Preferencia label.os.type=tipo de Sistema Operativo label.owned.public.ips=propiedad p\u00c3\u00bablica Direcciones IP @@ -562,6 +692,8 @@ label.PING.dir=PING Directorio label.PING.storage.IP=PING almacenamiento IP label.please.wait=Por favor espere label.pod=Pod +label.pods=Pod +label.port.forwarding.policies=Pol\u00edticas de Port forwarding label.port.forwarding=Port Forwarding label.port.range=rango de puertos label.PreSetup=PreSetup @@ -570,30 +702,47 @@ label.previous=Previo label.primary.allocated=primaria asignado de almacenamiento label.primary.network=Red Primaria label.primary.storage=Almacenamiento Primario +label.primary.storage.count=Pool Almacenamiento Primario label.primary.used=Primaria Almacenado +label.private.Gateway=Gateway Privado label.private.interface=Interfaz privada label.private.ip=direcci\u00c3\u00b3n IP privada label.private.ip.range=IP privada Gama label.private.ips=direcciones IP privadas label.privatekey=PKCS\#8 la clave privada +label.private.network=Red privada label.private.port=Puerto privado label.private.zone=Zona Privada +label.project.dashboard=Tablero del Proyecto +label.project.id=ID proyecto label.project.name=Nombre del Proyecto +label.project=proyecto +label.projects=proyectos label.protocol=Protocolo label.public.interface=interfaz p\u00c3\u00bablica label.public.ip=direcci\u00c3\u00b3n IP p\u00c3\u00bablica label.public.ips=direcciones IP p\u00c3\u00bablicas +label.public.network=Red P\u00fablica label.public.port=Puerto P\u00c3\u00bablico label.public=P\u00c3\u00bablica label.public.zone=Zona P\u00c3\u00bablica label.Pxe.server.type=Tipo de servidor Pxe +label.quickview=Vista R\u00e1pida label.reboot=Reiniciar label.recent.errors=recientes errores label.redundant.router=enrutador redundante label.refresh=Actualizar label.related=relacionados label.remind.later=Recordar mas tarde +label.remove.ACL=Remover ACL +label.remove.egress.rule=Eliminar regla de salida label.remove.from.load.balancer=ejemplo Eliminaci\u00c3\u00b3n de equilibrador de carga +label.remove.ingress.rule=Eliminar regla de entrada +label.remove.pf=Remover regla de port forwarding +label.remove.rule=Remover regla +label.remove.static.nat.rule=Remover regla NAT est\u00e1tica +label.remove.static.route=Remover ruta est\u00e1tica +label.remove.vpc=Remover VPC label.removing=Borrando. label.removing.user=Eliminar usuario label.required=Requerido @@ -601,35 +750,55 @@ label.reserved.system.ip=Reservados sistema de PI label.resource.limits=L\u00c3\u00admites de Recursos label.resource=Recursos label.resources=Recursos +label.resource.state=Estado del recurso +label.restart.network=Reiniciar red +label.restart.required=Reiniciado requerido +label.restart.vpc=Reiniciar VPC +label.restore=Restaurar label.role=Papel label.root.disk.offering=Root Disco Offering +label.round.robin=Round-robin label.routing=Enrutamiento +label.rules=Reglas label.running.vms=Ejecuci\u00c3\u00b3n de m\u00c3\u00a1quinas virtuales +label.s3.access_key=Llave de Acceso +label.s3.connection_timeout=Tiempo de conexi\u00f3n agotado label.s3.nfs.path=Ruta NFS S3 label.s3.nfs.server=Servidor NFS S3 label.s3.secret_key=clave secreta +label.s3.use_https=Use HTTPS label.saturday=s\u00c3\u00a1bado +label.save.and.continue=Guardar y continuar label.save=Guardar label.saving.processing=ahorro .... label.scope=Alcance label.search=Buscar label.secondary.storage=Almacenamiento secundario +label.secondary.storage.count=Pools del Almacenamiento Secundario label.secondary.used=Secundaria Almacenado label.secret.key=clave secreta label.security.group=Grupo de Seguridad label.security.group.name=Nombre de grupo de seguridad label.security.groups.enabled=Los grupos de seguridad habilitado label.security.groups=Grupos de seguridad +label.select.a.template=Seleccione un template label.select.a.zone=Seleccione una zona. +label.select.instance=Seleccione instancia +label.select.iso.or.template=Seleccione una ISO o template +label.select=Seleccione +label.select-view=Seleccione vista +label.select.vm.for.static.nat=Seleccione VM para NAT est\u00e1tica label.sent=Enviados label.server=Servidor label.service.offering=Oferta de Servicio label.service.state=Estado del servicio label.session.expired=Session Caducado +label.setup=Configuraci\u00c3\u00b3n label.shared=compartidas label.SharedMountPoint=SharedMountPoint label.show.ingress.rule=Mostrar la regla del ingreso label.size=Tama\u00c3\u00b1o +label.skip.guide=He utilizado CloudStack anteriormente, saltar esta gu\u00eda label.snapshot=Instant\u00c3\u00a1nea label.snapshot.limits=instant\u00c3\u00a1neas L\u00c3\u00admites label.snapshot.name=Nombre de instant\u00c3\u00a1neas @@ -637,12 +806,15 @@ label.snapshot.schedule=Lista de instant\u00c3\u00a1neas label.snapshot.s=Instant\u00c3\u00a1nea (s) label.snapshots=instant\u00c3\u00a1neas label.sockets=Sockets +label.source=Fuente label.source.nat=NAT Fuente label.specify.vlan=Especifique VLAN label.specify.vxlan=Especifique VXLAN label.SR.name = SR Nombre de etiqueta +label.srx=SRX label.start.port=Iniciar Puerto label.state=Estado +label.static.nat.enabled=NAT est\u00e1tica habilitada label.static.nat=NAT est\u00c3\u00a1tica label.static.nat.to=est\u00c3\u00a1tico NAT para label.statistics=Estad\u00c3\u00adsticas @@ -657,8 +829,15 @@ label.step.4=Paso 4 label.step.4.title=Paso 4\: Red label.step.5=Paso 5 label.step.5.title=Paso 5\: Revisi\u00c3\u00b3n +label.sticky.cookie-name=Nombre de Cookie label.sticky.domain=dominio +label.sticky.expire=Expira +label.sticky.indirect=Indirecto +label.sticky.length=Longitud label.sticky.mode=modo +label.sticky.nocache=No Cache +label.sticky.prefix=Prefijo +label.sticky.tablesize=Tama\u00f1o de tabla label.stop=Detener label.stopped.vms=Detenido m\u00c3\u00a1quinas virtuales label.storage=Almacenamiento @@ -668,6 +847,7 @@ label.submit=Enviar label.submitted.by=[Enviado por\: ] label.succeeded=Sucesor label.sunday=domingo +label.suspend.project=Suspender Proyecto label.switch.type=Cambiar el tipo label.system.capacity=Capacidad de todo el sistema label.system.vm=Sistema de VM @@ -685,12 +865,20 @@ label.theme.grey=Personal - Gris label.theme.lightblue=Personal - Azul label.thursday=Jueves label.timeout.in.second = Tiempo de espera (segundos) +label.timeout=Tiempo de espera label.time=Tiempo label.time.zone=Zona horaria label.timezone=Zona horaria +label.token=Token label.total.cpu=Total CPU label.total.CPU=Total CPU +label.total.hosts=Total de Hosts +label.total.memory=Memoria Total +label.total.of.ip=Total de direcciones IP +label.total.of.vm=Total de VM +label.total.storage=Almacenamiento Total label.total.vms=Total de m\u00c3\u00a1quinas virtuales +label.traffic.label=Etiqueta de trafico label.traffic.type=Tipo de Tr\u00c3\u00a1fico label.tuesday=martes label.type.id=Tipo de identificaci\u00c3\u00b3n @@ -698,7 +886,10 @@ label.type=Tipo label.unavailable=no disponible label.unlimited=Unlimited label.untagged=sin etiquetar +label.update.project.resources=Actualizar recurso del proyecto label.updating=Actualizar +label.upload=Subir +label.upload.volume=Subir volumen label.url=URL label.usage.interface=Interfaz de uso label.used=Usado @@ -706,55 +897,75 @@ label.username=Nombre de usuario label.users=usuario label.user=Usuario label.value=Valor +label.vcdcname=nombre label.vcenter.cluster=vCenter cl\u00c3\u00baster label.vcenter.datacenter=vCenter de centros de datos label.vcenter.datastore=vCenter almac\u00c3\u00a9n de datos label.vcenter.host=vCenter anfitri\u00c3\u00b3n label.vcenter.password=vCenter Contrase\u00c3\u00b1a label.vcenter.username=vCenter Nombre de usuario +label.vcipaddress=Direcci\u00f3n IP de vCenter label.version=Versi\u00c3\u00b3n +label.view.all=Ver todo +label.view.more=Ver mas label.view.secondary.ips=Ver las IP secundarias label.virtual.appliances=Virtual Appliances label.virtual.appliance=Virtual Appliance label.virtual.machines=Maquinas virtuales label.virtual.network=Red Virtual +label.virtual.routers=Routers Virtuales label.vlan.id=ID de VLAN label.vlan.range=VLAN Gama label.vlan=VLAN -label.vxlan.id=ID de VXLAN -label.vxlan.range=VXLAN Gama -label.vxlan=VXLAN +label.vlan.vni.range=VLAN Gama label.vm.add=A\u00c3\u00b1adir Instancia label.vm.destroy=Destroy label.VMFS.datastore=VMFS de datos tienda label.vmfs=VMFS +label.vm.name=Nombre VM label.vm.reboot=Reiniciar label.vmsnapshot.type=Tipo label.vm.start=Inicio +label.vm.state=Estado de VM\\'s label.vm.stop=Detener label.vms=VM +label.vnet.id=ID de VLAN +label.vnet=VLAN label.volgroup=Volume Group label.volume.limits=l\u00c3\u00admites de volumen label.volume.name=Nombre de Volumen label.volumes=Vol\u00c3\u00bamenes label.volume=Volumen +label.vpc.id=ID VPC +label.vpc=VPC +label.VPN.connection=Conexi\u00f3n VPN +label.VPN.gateway=Gateway VPN label.vpn=VPN +label.vsmctrlvlanid=Control VLAN ID label.vsphere.managed=Gestionado \= vSphere +label.vxlan.id=ID de VXLAN +label.vxlan.range=VXLAN Gama +label.vxlan=VXLAN label.waiting=Esperando label.warn=Advertir label.wednesday=mi\u00c3\u00a9rcoles label.weekly=Semanal label.welcome=Bienvenido label.welcome.cloud.console=Bienvenido a la consola de administraci\u00c3\u00b3n +label.what.is.cloudstack=Que es CloudStack&\#8482? label.yes=S\u00c3\u00ad +label.zone.details=Detalles de Zona label.zone.id=Zona de identificaci\u00c3\u00b3n label.zone.step.1.title=Paso 1\: Seleccione una red label.zone.step.2.title=Paso 2\: A\u00c3\u00b1adir una zona label.zone.step.3.title=Paso 3\: A\u00c3\u00b1adir una vaina label.zone.step.4.title=Paso 4\: A\u00c3\u00b1adir un rango de IP +label.zones=Zona label.zone.wide=Zona para todo el label.zone=Zona managed.state=Estado logr\u00c3\u00b3 +message.acquire.new.ip=Por favor confirme que usted quiere adquirir una nueva IP para esta red +message.acquire.new.ip.vpc=Por favor confirme que usted desea adquirir una nueva IP para este VPC. message.acquire.public.ip=Por favor seleccione una zona de la que desea adquirir su nueva IP. message.action.cancel.maintenance.mode=Por favor, confirme que desea cancelar el mantenimiento message.action.cancel.maintenance=Su acogida ha sido cancelado con \u00c3\u00a9xito para el mantenimiento. Este proceso puede tardar hasta varios minutos. @@ -767,6 +978,7 @@ message.action.delete.ingress.rule=Por favor, confirme que desea eliminar la reg message.action.delete.ISO.for.all.zones=La ISO es utilizado por todas las zonas. Por favor, confirme que desea eliminar de todas las zonas. message.action.delete.ISO=Por favor, confirme que desea eliminar la norma ISO message.action.delete.network=Por favor, confirme que desea eliminar de la red +message.action.delete.nexusVswitch=Porfavor confirme que usted quiere eliminar el Nexus 1000v message.action.delete.pod=Por favor, confirme que desea eliminar de la vaina message.action.delete.primary.storage=Por favor, confirme que desea eliminar el almacenamiento primario message.action.delete.secondary.storage=Por favor, confirme que desea eliminar de almacenamiento secundario @@ -780,11 +992,17 @@ message.action.delete.zone=Por favor, confirme que desea eliminar la zona message.action.destroy.instance=Por favor, confirme que desea destruir ejemplo message.action.destroy.systemvm=Por favor, confirme que desea destruir la m\u00c3\u00a1quina virtual del sistema. message.action.disable.cluster=Por favor, confirme que desea desactivar este grupo. +message.action.disable.nexusVswitch=Por favor confirme que usted quiere deshabilitar este nexus 1000v +message.action.disable.physical.network=Por favor confirmar que usted quiere deshabilitar esta red f\u00edsica message.action.disable.pod=Por favor, confirme que desea desactivar esta vaina. message.action.disable.static.NAT=Por favor, confirme que desea desactivar NAT est\u00c3\u00a1tica message.action.disable.zone=Por favor, confirme que desea desactivar esta zona. +message.action.download.iso=Por favor confirme que usted quiere descargar esta ISO +message.action.download.template=Por favor confirme que usted quiere descargar este template message.action.enable.cluster=Por favor, confirme que desea habilitar este grupo. message.action.enable.maintenance=Su acogida ha sido preparado con \u00c3\u00a9xito para el mantenimiento. Este proceso puede tardar hasta varios minutos o m\u00c3\u00a1s dependiendo de c\u00c3\u00b3mo las m\u00c3\u00a1quinas virtuales se encuentran actualmente en este servidor. +message.action.enable.nexusVswitch=por favor confirme que usted quiere habilitar este nexus 1000v +message.action.enable.physical.network=Por favor confirmar que usted quiere habilitar esta red f\u00edsica message.action.enable.pod=Por favor, confirme que desea habilitar esta vaina. message.action.enable.zone=Por favor, confirme que desea habilitar esta zona. message.action.force.reconnect=Por favor, confirme que desea forzar una reconexi\u00c3\u00b3n para el anfitri\u00c3\u00b3n @@ -804,9 +1022,11 @@ message.action.stop.instance=Por favor, confirme que desea detener la instancia message.action.stop.systemvm=Por favor, confirme que desea detener sistema VM message.action.take.snapshot=Por favor, confirme que desea tomar instant\u00c3\u00a1neas message.action.unmanage.cluster=Por favor, confirme que desea unmanage del cl\u00c3\u00baster. +message.activate.project=Usted esta seguro que quiere activar este proyecto? message.add.cluster=A\u00c3\u00b1adir un hipervisor administradas por cl\u00c3\u00baster de zona , la consola de message.add.cluster.zone=A\u00c3\u00b1adir un hipervisor administradas por cl\u00c3\u00baster de zona message.add.disk.offering=Por favor, especifique los par\u00c3\u00a1metros siguientes para agregar un nuevo disco que ofrece +message.add.domain=por favor especifique el subdominio que usted quiere crear bajo este dominio message.add.firewall=A\u00c3\u00b1adir un servidor de seguridad a la zona message.add.host=Por favor, especifique los par\u00c3\u00a1metros siguientes para agregar un nuevo host message.add.ip.range=A\u00c3\u00b1adir un rango de IP a la red p\u00c3\u00bablica en la zona @@ -822,6 +1042,7 @@ message.add.secondary.storage=A\u00c3\u00b1adir un nuevo almacenamiento de z message.add.service.offering=Por favor, rellene los siguientes datos para agregar una nueva oferta de servicio. message.add.template=Por favor ingrese los siguientes datos para crear la nueva plantilla message.add.volume=Por favor, rellene los siguientes datos para agregar un nuevo volumen. +message.add.VPN.gateway=Por favor confirme que usted quiere agregar un VPN Gateway message.advanced.mode.desc=Seleccione este modelo de red si desea habilitar soporte VLAN. Este modelo de red proporciona la m\u00c3\u00a1xima flexibilidad al permitir a los administradores proporcionar ofertas personalizadas de la red como el suministro de firewall, VPN, o el apoyo equilibrador de carga, as\u00c3\u00ad como permitir vs directa de redes virtuales. message.advanced.security.group=Elija esta opci\u00c3\u00b3n si desea utilizar grupos de seguridad para proporcionar resultados de aislamiento VM. message.advanced.virtual=Elija esta opci\u00c3\u00b3n si desea utilizar VLAN toda la zona para proporcionar el aislamiento VM invitado. @@ -831,40 +1052,67 @@ message.attach.iso.confirm=Por favor, confirme que desea conectar el ISO a la in message.attach.volume=Por favor, rellene los siguientes datos para fijar un nuevo volumen. Si est\u00c3\u00a1 colocando un volumen de disco a una m\u00c3\u00a1quina virtual de Windows basado, usted tendr\u00c3\u00a1 que reiniciar la instancia para ver el disco adjunto. message.basic.mode.desc=Seleccione este modelo de red si lo haces * no * desea habilitar cualquier soporte VLAN. Todas las instancias virtuales creados en virtud de este modelo de red se le asignar\u00c3\u00a1 una direcci\u00c3\u00b3n IP directamente desde la red y grupos de seguridad se utilizan para proporcionar la seguridad y la segregaci\u00c3\u00b3n. message.change.offering.confirm=Por favor, confirme que desea cambiar la oferta de servicio de la instancia virtual. +message.change.password=Por favor cambie la contrase\u00f1a. +message.confirm.delete.F5=Por favor confirme que ud quiere eliminar el F5 +message.confirm.join.project=por favor confirme que usted desea unirse a este proyecto. message.copy.iso.confirm=Por favor, confirme que desea copiar el ISO a message.copy.template=Copia plantilla XXX de la zona +message.create.template=Esta seguro que quiere crear un template? message.create.template.vm=Crear VM de la plantilla message.create.template.volume=Por favor, especifique la siguiente informaci\u00c3\u00b3n antes de crear una plantilla de su volumen de disco\: . Creaci\u00c3\u00b3n de la plantilla puede oscilar entre varios minutos m\u00c3\u00a1s, dependiendo del tama\u00c3\u00b1o del volumen. message.delete.account=Por favor, confirme que desea eliminar esta cuenta. +message.delete.gateway=Por favor confirme que usted quiere eliminar este gateway +message.delete.project=Esta seguro que quiere eliminar este proyecto? +message.delete.user=Por favor confirme que usted quiere eliminar este usuario +message.delete.VPN.connection=Por favor confirme que usted quiere eliminar la conexi\u00f3n VPN +message.delete.VPN.gateway=Por favor confirme que usted quiere eliminar este VPN Gateway message.detach.iso.confirm=Por favor, confirme que desea quitar el ISO de la instancia virtual message.disable.snapshot.policy=Ha desactivado su pol\u00c3\u00adtica instant\u00c3\u00a1nea actual. +message.disable.user=Por favor confirme que usted quiere deshabilitar este usuario message.disable.vpn.access=Por favor, confirme que desea desactivar VPN de acceso. +message.disable.vpn=Esta seguro que usted quiere deshabilitar la VPN? +message.download.volume.confirm=Por favor confirme que desea descargar este volumen message.download.volume=Por favor, haga clic 00000 para bajar el volumen +message.edit.account=Editar ("-1" indica que no hay limite a la cantidad de recursos creados) message.edit.confirm=Por favor confirmar los cambios antes de hacer clic en "Guardar" message.edit.limits=Por favor, especifique los l\u00c3\u00admites de los recursos siguientes. A "-1" indica que no hay l\u00c3\u00admite a la cantidad de los recursos de crear. message.enable.account=Por favor, confirme que desea habilitar esta cuenta. message.enabled.vpn.ip.sec=La clave pre-compartida IPSec es message.enabled.vpn=Su acceso a la VPN est\u00c3\u00a1 habilitado y se puede acceder a trav\u00c3\u00a9s de la IP +message.enable.user=Por favor confirme que usted quiere habilitar este usuario message.enable.vpn.access=VPN \= est\u00c3\u00a1 desactivado para esta direcci\u00c3\u00b3n IP. \u00c2\u00bfTe gustar\u00c3\u00ada que permitan el acceso VPN? message.enable.vpn=VPN de acceso actualmente no est\u00c3\u00a1 habilitado. Por favor, haga clic aqu\u00c3\u00ad para habilitar VPN. +message.generate.keys=Por favor confirme que usted quiere generar nueva llave para este usuario. message.installWizard.click.retry=Haz click en el bot\u00f3n para re-intentar el lanzamiento de la instancia. +message.installWizard.copy.whatIsSecondaryStorage=El almacenamiento secundario est\u00e1 asociado a una zona, y almacena lo siguiente\:
  • Plantillas - im\u00e1genes del sistema operativo que se pueden utilizar para arrancar VMs, pueden incluir informaci\u00f3n de configuraci\u00f3n adicional, como las aplicaciones instaladas
  • Im\u00e1genes ISO - im\u00e1genes del Sistema Operativo que pueden ser boteables o no boteables
  • Disco instant\u00e1neas de vol\u00famenes - copias de datos guardadas de VM que se pueden utilizar para la recuperaci\u00f3n de datos o para crear nuevas plantillas
+message.installWizard.now.building=Ahora construyendo su nube... message.installWizard.tooltip.addCluster.name=Nombre del Cluster. Puede ser alfanum\u00e9rico .Este no es usado por CloudStack message.installWizard.tooltip.addHost.hostname=El nombre DNS o direcci\u00f3n IP del host +message.installWizard.tooltip.addHost.password=Este es el password para el nombre de usuario mencionado anteriormente (Desde su Instalaci\u00f3n XenServer) message.installWizard.tooltip.addHost.username=Generalmente root message.installWizard.tooltip.addPod.name=Nombre del POD +message.installWizard.tooltip.addPod.reservedSystemEndIp=Este es el rango de direcciones IP en la red privada que la CloudStack utiliza para administrar las VMs del Almacenamiento Secundario y consola Proxy.\nEstas direcciones IP se han tomado de la misma subred que los servidores inform\u00e1ticos. message.installWizard.tooltip.addPod.reservedSystemGateway=El gateway ,puerta de enlace, para los host en ese pod. +message.installWizard.tooltip.addPod.reservedSystemNetmask=La m\u00e1scara de red en uso en la subred de los hu\u00e9spedes ser\u00e1. +message.installWizard.tooltip.addPod.reservedSystemStartIp=Este es el rango de direcciones IP en la red privada que la CloudStack utiliza para administrar las VMs del Almacenamiento Secundario y consola Proxy.\nEstas direcciones IP se han tomado de la misma subred que los servidores inform\u00e1ticos. message.installWizard.tooltip.addPrimaryStorage.name=\ Nombre para el storage +message.installWizard.tooltip.addPrimaryStorage.path=(para NFS) En NFS este es el directorio exportado desde el servidor. Directorio (por SharedMountPoint). Con KVM este es el directorio de cada host en donde se monta el almacenamiento primario. Por ejemplo, "/mnt/primary". +message.installWizard.tooltip.addPrimaryStorage.server=(para NFS, iSCSI, o PreSetup) La direcci\u00f3n IP o el nombre DNS del dispositivo de almacenamiento. message.installWizard.tooltip.addSecondaryStorage.nfsServer=Direcci\u00f3n IP del servidor NFS que contiene el secondary storage +message.installWizard.tooltip.addSecondaryStorage.path=El path exportado, ubicado en el servidor especificado anteriormente message.installWizard.tooltip.addZone.name=Nombre de la zona. message.installWizard.tooltip.configureGuestTraffic.description=Una breve descripci\u00f3n para su red. message.installWizard.tooltip.configureGuestTraffic.guestGateway=El gatway, puerta de enlace, que las maquinas guest deben usar. +message.installWizard.tooltip.configureGuestTraffic.guestNetmask=La m\u00e1scara de red en uso en la subred que los clientes deben utilizar message.installWizard.tooltip.configureGuestTraffic.name=Nombre de su RED +message.ip.address.changed=Su direcci\u00f3n IP pudo haber cambiado. Le gustar\u00eda actualizar el listado? Tenga en cuenta que en este caso el panel de detalles se cerrar\u00e1. message.lock.account=Por favor, confirme que desea bloquear esta cuenta. Al bloquear la cuenta, todos los usuarios de esta cuenta ya no ser\u00c3\u00a1 capaz de gestionar sus recursos de la nube. Los recursos existentes todav\u00c3\u00ada se puede acceder. message.migrate.instance.confirm=Por favor, confirme el anfitri\u00c3\u00b3n desea migrar la instancia virtual. message.migrate.instance.to.host=Por favor, confirmar que desea mover la instancia a otro host. message.migrate.instance.to.ps=Por favor, confirmar que desea mover la instancia a otro primary storage. message.migrate.router.confirm=Por favor, confirme el hu\u00c3\u00a9sped que desea migrar el router\: message.migrate.systemvm.confirm=Por favor, confirme el hu\u00c3\u00a9sped que desea migrar la m\u00c3\u00a1quina virtual de sistema\: +message.migrate.volume=Por favor confirme que usted quiere migrar el volumen a otro almacenamiento primario message.no.network.support.configuration.not.true=Usted no tiene ninguna zona que ha permitido a grupo de seguridad. Por lo tanto, no hay funciones de red adicionales. Por favor, contin\u00c3\u00bae con el paso 5. message.no.network.support=El hipervisor seleccionado, vSphere, no tiene funciones de red adicionales. Por favor, contin\u00c3\u00bae con el paso 5. message.number.clusters=

\# de Grupos

@@ -872,12 +1120,20 @@ message.number.hosts=

\# de Anfitri\u00c3\u00b3n

message.number.pods=

\# de Las vainas

message.number.storage=

\# de Almacenamiento primario

message.number.zones=

\# de Zonas

+message.please.proceed=Por favor proceda a el siguiente paso. +message.please.select.networks=Por favor seleccione la red para su maquina virtual. +message.remove.vpc=Por favor confirme que usted quiere eliminar el VPC message.remove.vpn.access=Por favor, confirme que desea eliminar el acceso VPN desde el siguiente usuario message.restart.mgmt.server=Por favor, reinicie el servidor de administraci\u00c3\u00b3n (s) para la nueva configuraci\u00c3\u00b3n surta efecto. +message.restart.vpc=Por favor confirme que usted quiere reiniciar el VPC message.security.group.usage=(Uso pulse Ctrl para seleccionar todos los grupos de seguridad se aplica) +message.select.instance=Por favor seleccione una instancia +message.select.iso=Por favor seleccione un ISO para su nueva instancia virtual message.select.item=Por favor, seleccionar un item . +message.select.template=Por favor seleccione un template para su nueva instancia virtual message.setup.successful=La configuraci\u00f3n de la cloud finalizo satisfactoriamente. message.snapshot.schedule=Puede horarios de configuraci\u00c3\u00b3n recurrente instant\u00c3\u00a1neas mediante la selecci\u00c3\u00b3n de las opciones disponibles a continuaci\u00c3\u00b3n y la aplicaci\u00c3\u00b3n de su preferencia pol\u00c3\u00adtica +message.specify.url=Por favor especifique la URL message.step.1.continue=Por favor seleccione una plantilla o ISO para continuar message.step.1.desc=Por favor seleccione una plantilla para la instancia virtual. Tambi\u00c3\u00a9n puede optar por seleccionar una plantilla en blanco desde el que puede ser una imagen ISO instalado en. message.step.2.continue=Por favor seleccione una oferta de servicio para continuar @@ -887,6 +1143,7 @@ message.step.3.desc= message.step.4.continue=Por favor seleccione al menos una red social para continuar message.step.4.desc=Por favor, seleccione la red primaria que la instancia virtual estar\u00c3\u00a1 conectado. message.update.os.preference=Por favor seleccione un sistema operativo de preferencia para este equipo. Todas las instancias virtuales con preferencias similares ser\u00c3\u00a1n los primeros asignados a este equipo antes de elegir otro. +message.update.resource.count=Por favor confirme que usted quiere actualizar los conteos para esta cuenta message.update.ssl=Por favor, env\u00c3\u00ade una nueva X.509 compatible con certificado SSL que se actualizar\u00c3\u00a1 a cada instancia virtual de la consola del servidor proxy\: message.validate.invalid.characters=Se han hallado caracteres no v\u00e1lidos. Por favor, corr\u00edjalos. message.virtual.network.desc=Una red dedicada virtualizados para su cuenta. El dominio de difusi\u00c3\u00b3n est\u00c3\u00a1 contenida dentro de una VLAN y todos los acceso a la red p\u00c3\u00bablica se encamina a cabo por un router virtual. @@ -896,6 +1153,22 @@ message.zone.step.1.desc=Por favor seleccione un modelo de red para su zona. mode=modo network.rate=Tasa de Red side.by.side=Juntos +state.Accepted=Aceptado +state.Active=Activo state.Allocated=Asignados +state.BackedUp=Respaldado +state.BackingUp=Realizando Backup +state.Completed=Completado +state.Creating=Creando +state.Declined=Declinado state.Disabled=personas de movilidad reducida +state.enabled=Habilitado +state.Enabled=Habilitado state.Error=Error +state.Migrating=Migrando +state.Pending=pendiente +state.ready=Listo +state.Ready=Listo +state.Starting=Iniciando +state.Stopping=Parando +state.Suspended=Suspendido diff --git a/client/WEB-INF/classes/resources/messages_fr_FR.properties b/client/WEB-INF/classes/resources/messages_fr_FR.properties index 42335bc7b4..004187f69b 100644 --- a/client/WEB-INF/classes/resources/messages_fr_FR.properties +++ b/client/WEB-INF/classes/resources/messages_fr_FR.properties @@ -18,6 +18,7 @@ changed.item.properties=Propri\u00e9t\u00e9s de l\\'\u00e9l\u00e9ment modifi\u00e9es 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\u00e9. error.could.not.enable.zone=Impossible d\\'activer la zone error.installWizard.message=Une erreur s\\'est produite ; vous pouvez retourner en arri\u00e8re et corriger les erreurs error.invalid.username.password=Utilisateur ou mot de passe invalide @@ -42,15 +43,20 @@ ICMP.type=Type ICMP image.directory=R\u00e9pertoire d\\'images inline=Align\u00e9 instances.actions.reboot.label=Red\u00e9marrer l\\'instance +label.about.app=A propos de CloudStack +label.about=A propos de label.accept.project.invitation=Accepter l\\'invitation au projet label.account.and.security.group=Compte, groupe de s\u00e9curit\u00e9 label.account=Compte label.account.id=ID du Compte +label.account.lower=compte label.account.name=Nom du compte label.accounts=Comptes label.account.specific=Sp\u00e9cifique au compte +label.acl=ACL label.acquire.new.ip=Acqu\u00e9rir une nouvelle adresse IP label.acquire.new.secondary.ip=Acqu\u00e9rir une nouvelle IP secondaire +label.action=Action label.action.attach.disk.processing=Rattachement du Disque... label.action.attach.disk=Rattacher un disque label.action.attach.iso.processing=Rattachement de l\\'image ISO @@ -77,7 +83,7 @@ label.action.delete.account=Supprimer un compte label.action.delete.cluster.processing=Suppression du Cluster... label.action.delete.cluster=Supprimer le Cluster label.action.delete.disk.offering.processing=Suppression de l\\'offre Disque... -label.action.delete.disk.offering=Supprimer l\\'offre Disque +label.action.delete.disk.offering=Supprimer Offre Disque label.action.delete.domain.processing=Suppression du domaine... label.action.delete.domain=Supprimer le domaine label.action.delete.firewall.processing=Suppression du Pare-feu... @@ -97,17 +103,17 @@ label.action.delete.nic=Supprimer carte NIC label.action.delete.physical.network=Supprimer le r\u00e9seau physique label.action.delete.pod.processing=Suppression du pod... label.action.delete.pod=Supprimer le Pod -label.action.delete.primary.storage.processing=Suppression du stockage principal... -label.action.delete.primary.storage=Supprimer le stockage principal +label.action.delete.primary.storage.processing=Suppression du stockage primaire... +label.action.delete.primary.storage=Supprimer le stockage primaire label.action.delete.secondary.storage.processing=Suppression du stockage secondaire... label.action.delete.secondary.storage=Supprimer le stockage secondaire label.action.delete.security.group.processing=Suppression du groupe de s\u00e9curit\u00e9 label.action.delete.security.group=Supprimer le groupe de s\u00e9curit\u00e9 label.action.delete.service.offering.processing=Suppression de l\\'offre de service... -label.action.delete.service.offering=Supprimer l\\'offre de service +label.action.delete.service.offering=Supprimer Offre Service label.action.delete.snapshot.processing=Suppression de l\\'instantan\u00e9... label.action.delete.snapshot=Supprimer l\\'instantan\u00e9 -label.action.delete.system.service.offering=Supprimer l\\'offre syst\u00e8me +label.action.delete.system.service.offering=Supprimer Offre de Service Syst\u00e8me label.action.delete.template.processing=Suppression du mod\u00e8le... label.action.delete.template=Supprimer le mod\u00e8le label.action.delete.user.processing=Suppression de l\\'utilisateur... @@ -119,7 +125,7 @@ label.action.delete.zone=Supprimer la zone label.action.destroy.instance.processing=Suppression de l\\'instance... label.action.destroy.instance=Supprimer l\\'instance label.action.destroy.systemvm.processing=Suppression de la VM Syst\u00e8me... -label.action.destroy.systemvm=Supprimer la VM Syst\u00e8me +label.action.destroy.systemvm=Supprimer VM Syst\u00e8me label.action.detach.disk=D\u00e9tacher le disque label.action.detach.disk.processing=D\u00e9tachement du disque... label.action.detach.iso=D\u00e9tacher l\\'image ISO @@ -143,19 +149,19 @@ label.action.download.template=T\u00e9l\u00e9charger un mod\u00e8le label.action.download.volume.processing=T\u00e9l\u00e9chargement du volume... label.action.download.volume=T\u00e9l\u00e9charger un volume label.action.edit.account=Modifier le Compte -label.action.edit.disk.offering=Modifier l\\'offre de disque +label.action.edit.disk.offering=Modifier Offre Disque label.action.edit.domain=Modifier le domaine label.action.edit.global.setting=Modifier la configuration globale label.action.edit.host=Modifier l\\'h\u00f4te label.action.edit.instance=Modifier l\\'instance label.action.edit.ISO=Modifier l\\'image ISO label.action.edit.network=Modifier le r\u00e9seau -label.action.edit.network.offering=Modifier l\\'offre de service r\u00e9seau +label.action.edit.network.offering=Modifier Offre R\u00e9seau label.action.edit.network.processing=Modification du R\u00e9seau... label.action.edit.pod=Modifier le pod -label.action.edit.primary.storage=Modifier le stockage principal +label.action.edit.primary.storage=Modifier le stockage primaire label.action.edit.resource.limits=Modifier les limites de ressources -label.action.edit.service.offering=Modifier l\\'offre de service +label.action.edit.service.offering=Modifier Offre Service label.action.edit.template=Modifier le mod\u00e8le label.action.edit.user=Modifier l\\'utilisateur label.action.edit.zone=Modifier la zone @@ -175,6 +181,8 @@ label.action.enable.user=Activer l\\'utilisateur label.action.enable.user.processing=Activation de l\\'utilisateur... label.action.enable.zone=Activer la zone label.action.enable.zone.processing=Activation de la zone... +label.action.expunge.instance.processing=Purge de l\\'Instance... +label.action.expunge.instance=Purger Instance label.action.force.reconnect=Forcer la reconnexion label.action.force.reconnect.processing=Reconnexion en cours... label.action.generate.keys=G\u00e9n\u00e9rer les cl\u00e9s @@ -188,14 +196,14 @@ label.action.migrate.instance=Migrer l\\'instance label.action.migrate.instance.processing=Migration de l\\'instance... label.action.migrate.router=Migration routeur label.action.migrate.router.processing=Migration routeur en cours... -label.action.migrate.systemvm=Migration VM syst\u00e8me +label.action.migrate.systemvm=Migrer VM Syst\u00e8me label.action.migrate.systemvm.processing=Migration VM syst\u00e8me en cours ... label.action.reboot.instance.processing=Red\u00e9marrage de l\\'instance... label.action.reboot.instance=Red\u00e9marrer l\\'instance label.action.reboot.router.processing=Red\u00e9marrage du routeur... label.action.reboot.router=Red\u00e9marrer le routeur label.action.reboot.systemvm.processing=Red\u00e9marrage de la VM Syst\u00e8me... -label.action.reboot.systemvm=Red\u00e9marrer la VM Syst\u00e8me +label.action.reboot.systemvm=Red\u00e9marrer VM Syst\u00e8me label.action.recurring.snapshot=Instantan\u00e9s r\u00e9currents label.action.register.iso=Enregistrer ISO label.action.register.template=Enregistrer mod\u00e8le @@ -210,6 +218,8 @@ label.action.resize.volume=Redimensionner Volume label.action.resource.limits=Limites de ressources label.action.restore.instance.processing=Restauration de l\\'instance... label.action.restore.instance=Restaurer l\\'instance +label.action.revert.snapshot.processing=Retour \u00e0 l\\'instantan\u00e9... +label.action.revert.snapshot=R\u00e9tablir Instantan\u00e9 label.actions=Actions label.action.start.instance=D\u00e9marrer l\\'instance label.action.start.instance.processing=D\u00e9marrage de l\\'instance... @@ -221,7 +231,7 @@ label.action.stop.instance=Arr\u00eater l\\'Instance label.action.stop.instance.processing=Arr\u00eat de l\\'Instance... label.action.stop.router=Arr\u00eater le routeur label.action.stop.router.processing=Arr\u00eat du routeur... -label.action.stop.systemvm=Arr\u00eater la VM syst\u00e8me +label.action.stop.systemvm=Arr\u00eater VM Syst\u00e8me label.action.stop.systemvm.processing=Arr\u00eat de la VM syst\u00e8me... label.action.take.snapshot=Prendre un instantan\u00e9 label.action.take.snapshot.processing=Prise de l\\'instantan\u00e9... @@ -233,7 +243,7 @@ label.action.update.resource.count=Mettre \u00e0 jour le compteur des ressources label.action.update.resource.count.processing=Mise \u00e0 jour du compteur... label.action.vmsnapshot.create=Prendre un instantan\u00e9 VM label.action.vmsnapshot.delete=Supprimer l\\'instantan\u00e9 VM -label.action.vmsnapshot.revert=Revenir \u00e0 un instantan\u00e9 VM +label.action.vmsnapshot.revert=R\u00e9tablir Instantan\u00e9 VM label.activate.project=Activer projet label.active.sessions=Sessions actives label.add.account=Ajouter un compte @@ -243,18 +253,23 @@ label.add.account.to.project=Ajouter un compte au projet label.add.ACL=Ajouter r\u00e8gle ACL label.add.affinity.group=Ajouter nouveau groupe d\\'affinit\u00e9 label.add=Ajouter +label.add.baremetal.dhcp.device=Ajouter un DHCP Baremetal label.add.BigSwitchVns.device=Ajouter contr\u00f4leur BigSwitch Vns label.add.by=Ajout\u00e9 par label.add.by.cidr=Ajouter par CIDR label.add.by.group=Ajouter par groupe label.add.cluster=Ajouter un cluster -label.add.compute.offering=Ajouter une offre de calcul +label.add.compute.offering=Ajouter Offre Calcul label.add.direct.iprange=Ajouter une plage d\\'adresse IP directe -label.add.disk.offering=Ajouter une offre disque +label.add.disk.offering=Ajouter Offre Disque label.add.domain=Ajouter un domaine +label.added.new.bigswitch.vns.controller=Ajout du nouveau contr\u00f4leur BigSwitch VNS +label.added.nicira.nvp.controller=Ajout d\\'un nouveau contr\u00f4leur Nicira NVP label.add.egress.rule=Ajouter la r\u00e8gle sortante +label.addes.new.f5=Ajout d\\'un nouveau F5 label.add.F5.device=Ajouter un F5 label.add.firewall=Ajouter une r\u00e8gle de pare-feu +label.add.gslb=Ajouter GSLB label.add.guest.network=Ajouter un r\u00e9seau d\\'invit\u00e9 label.add.host=Ajouter un h\u00f4te label.adding=Ajout @@ -267,6 +282,7 @@ label.adding.succeeded=Ajout r\u00e9ussi label.adding.user=Ajout de l\\'utilisateur label.adding.zone=Ajout de la zone label.add.ip.range=Ajouter une plage IP +label.add.isolated.network=Ajouter un r\u00e9seau isol\u00e9 label.additional.networks=R\u00e9seaux additionnels label.add.load.balancer=Ajouter un r\u00e9partiteur de charge label.add.more=Ajouter plus @@ -274,42 +290,52 @@ label.add.netScaler.device=Ajouter un Netscaler label.add.network.ACL=Ajouter une r\u00e8gle d\\'acc\u00e8s r\u00e9seau ACL label.add.network=Ajouter un r\u00e9seau label.add.network.device=Ajouter un \u00e9quipement r\u00e9seau -label.add.network.offering=Ajouter une offre r\u00e9seau +label.add.network.offering=Ajouter Offre R\u00e9seau label.add.new.F5=Ajouter un F5 label.add.new.gateway=Ajouter une nouvelle passerelle label.add.new.NetScaler=Ajouter un Netscaler +label.add.new.PA=Ajouter nouveau Palo Alto label.add.new.SRX=Ajouter un SRX label.add.new.tier=Ajouter un nouveau tiers +label.add.nfs.secondary.staging.store=Ajouter un Stockage Secondaire Interm\u00e9diaire NFS label.add.NiciraNvp.device=Ajouter un contr\u00f4leur Nvp +label.add.OpenDaylight.device=Ajouter contr\u00f4leur OpenDaylight +label.add.PA.device=Ajouter p\u00e9riph\u00e9rique Palo Alto label.add.physical.network=Ajouter un r\u00e9seau physique label.add.pod=Ajouter un pod +label.add.portable.ip.range=Ajouter Plage IP portable label.add.port.forwarding.rule=Ajouter une r\u00e8gle de transfert de port -label.add.primary.storage=Ajouter un stockage principal +label.add.primary.storage=Ajouter un stockage primaire label.add.region=Ajouter R\u00e9gion label.add.resources=Ajouter ressources label.add.route=Ajouter route label.add.rule=Ajouter r\u00e8gle label.add.secondary.storage=Ajouter un stockage secondaire label.add.security.group=Ajouter un groupe de s\u00e9curit\u00e9 -label.add.service.offering=Ajouter une offre de service +label.add.service.offering=Ajouter Offre Service label.add.SRX.device=Ajouter un SRX label.add.static.nat.rule=Ajouter une r\u00e8gle de NAT statique label.add.static.route=Ajouter une route statique -label.add.system.service.offering=Ajouter une offre de service syst\u00e8me +label.add.system.service.offering=Ajouter Offre Service Syst\u00e8me label.add.template=Ajouter un mod\u00e8le label.add.to.group=Ajouter au groupe +label.add.ucs.manager=Ajouter Gestionnaire UCS label.add.user=Ajouter un utilisateur label.add.vlan=Ajouter un VLAN -label.add.vxlan=Ajouter un VXLAN label.add.vm=Ajouter VM label.add.vms=Ajouter VMs label.add.vms.to.lb=Ajouter une/des VM(s) \u00e0 la r\u00e8gle de r\u00e9partition de charge label.add.VM.to.tier=Ajouter une machine virtuelle au tiers +label.add.vmware.datacenter=Ajouter un datacenter VMware +label.add.vnmc.device=Ajouter un VNMC +label.add.vnmc.provider=Ajouter fournisseur VNMC label.add.volume=Ajouter un volume label.add.vpc=Ajouter un VPC +label.add.vpc.offering=Ajouter Offre VPC label.add.vpn.customer.gateway=Ajouter une passerelle VPN cliente label.add.VPN.gateway=Ajouter une passerelle VPN label.add.vpn.user=Ajouter un utilisateur VPN +label.add.vxlan=Ajouter un VXLAN label.add.zone=Ajouter une zone label.admin.accounts=Comptes Administrateur label.admin=Administrateur @@ -326,35 +352,57 @@ label.alert=Alerte label.algorithm=Algorithme label.allocated=Allou\u00e9 label.allocation.state=\u00c9tat +label.allow=Autoriser label.anti.affinity=Anti-affinit\u00e9 label.anti.affinity.group=Groupe d\\'Anti-affinit\u00e9 label.anti.affinity.groups=Groupes d\\'Anti-affinit\u00e9 label.api.key=Cl\u00e9 d\\'API label.apply=Appliquer +label.app.name=CloudStack +label.archive.alerts=Archiver alertes +label.archive.events=Archiver \u00e9v\u00e9nements label.assign=Assigner +label.assign.instance.another=Assigner l\\'instance \u00e0 un autre compte label.assign.to.load.balancer=Assigner l\\'instance au r\u00e9partiteur de charge label.associated.network.id=ID du r\u00e9seau associ\u00e9 label.associated.network=R\u00e9seau associ\u00e9 +label.associated.profile=Profil associ\u00e9 +label.associate.public.ip=Associer IP Publique label.attached.iso=Image ISO attach\u00e9e label.author.email=Email auteur label.author.name=Nom auteur +label.autoscale=AutoScale label.availability=Disponibilit\u00e9 label.availability.zone=Zone de disponibilit\u00e9 label.available=Disponible label.available.public.ips=Adresses IP publiques disponibles label.back=Retour label.bandwidth=Bande passante +label.baremetal.dhcp.devices=\u00c9quipements DHCP Baremetal +label.baremetal.dhcp.provider=Fournisseur DHCP Baremetal +label.baremetal.pxe.device=Ajouter un PXE Baremetal +label.baremetal.pxe.devices=\u00c9quipements PXE Baremetal +label.baremetal.pxe.provider=Fournisseur PXE Baremetal label.basic=Basique label.basic.mode=Mode basique label.bigswitch.controller.address=Adresse du contr\u00f4leur BigSwitch Vns +label.bigswitch.vns.details=D\u00e9tails BigSwitch VNS +label.blade.id=ID Lame +label.blades=Lames label.bootable=Amor\u00e7able label.broadcast.domain.range=Plage du domaine multi-diffusion label.broadcast.domain.type=Type de domaine de multi-diffusion +label.broadcasturi=broadcasturi label.broadcast.uri=URI multi-diffusion +label.broadcat.uri=URI multi-diffusion label.by.account=Par compte +label.by.alert.type=Par type d\\'alerte label.by.availability=Par disponibilit\u00e9 +label.by.date.end=par date (fin) +label.by.date.start=Par date (d\u00e9but) label.by.domain=Par domaine label.by.end.date=Par date de fin +label.by.event.type=Par type d\\'\u00e9v\u00e9nement label.by.level=Par niveau label.by.pod=Par Pod label.by.role=Par r\u00f4le @@ -366,18 +414,25 @@ label.by.traffic.type=Par type de trafic label.by.type.id=Par type d\\'ID label.by.type=Par type label.by.zone=Par zone +label.cache.mode=Type Write-cache label.cancel=Annuler label.capacity=Capacit\u00e9 label.certificate=Certificat -label.change.service.offering=Modifier l\\'offre de service +label.change.affinity=Changer Affinit\u00e9 +label.change.service.offering=Modifier Offre Service label.change.value=Modifier la valeur label.character=Caract\u00e8re +label.chassis=Ch\u00e2ssis label.checksum=Somme de contr\u00f4le MD5 label.cidr.account=CIDR ou Compte/Groupe de s\u00e9curit\u00e9 label.cidr=CIDR label.cidr.list=CIDR Source label.CIDR.list=Liste CIDR label.CIDR.of.destination.network=CIDR du r\u00e9seau de destination +label.cisco.nexus1000v.ip.address=Adresse IP Nexus 1000v +label.cisco.nexus1000v.password=Mot de passe Nexus 1000v +label.cisco.nexus1000v.username=Identifiant Nexus 1000v +label.ciscovnmc.resource.details=D\u00e9tails ressource CiscoVNMC label.clean.up=Nettoyage label.clear.list=Purger la liste label.close=Fermer @@ -392,9 +447,11 @@ label.code=Code label.community=Communaut\u00e9 label.compute.and.storage=Calcul et Stockage label.compute.offering=Offre de calcul +label.compute.offerings=Offres de Calcul label.compute=Processeur label.configuration=Configuration label.configure=Configurer +label.configure.ldap=Configurer LDAP label.configure.network.ACLs=Configurer les r\u00e8gles d\\'acc\u00e8s r\u00e9seau ACL label.configure.vpc=Configurer le VPC label.confirmation=Confirmation @@ -402,6 +459,7 @@ label.confirm.password=Confirmer le mot de passe label.congratulations=F\u00e9licitations \! label.conserve.mode=Conserver le mode label.console.proxy=Console proxy +label.console.proxy.vm=VM Console Proxy label.continue.basic.install=Continuer avec l\\'installation basique label.continue=Continuer label.corrections.saved=Modifications enregistr\u00e9es @@ -414,42 +472,67 @@ label.cpu.mhz=CPU (en MHz) label.cpu.utilized=CPU utilis\u00e9e label.created.by.system=Cr\u00e9\u00e9 par le syst\u00e8me label.created=Cr\u00e9\u00e9 +label.create.nfs.secondary.staging.storage=Cr\u00e9er le Stockage Secondaire Interm\u00e9diaire NFS +label.create.nfs.secondary.staging.store=Cr\u00e9er le stockage secondaire interm\u00e9diaire NFS label.create.project=Cr\u00e9er un projet label.create.template=Cr\u00e9er un mod\u00e8le label.create.VPN.connection=Cr\u00e9er une connexion VPN label.cross.zones=Multi Zones +label.custom.disk.iops=IOPS personnalis\u00e9s label.custom.disk.size=Taille de disque personnalis\u00e9e +label.custom=Personnalis\u00e9 label.daily=Quotidien label.data.disk.offering=Offre de disque de donn\u00e9es label.date=Date label.day.of.month=Jour du mois label.day.of.week=Jour de la semaine +label.dc.name=Nom DC label.dead.peer.detection=D\u00e9tection de pair mort label.decline.invitation=Refuser l\\'invitation +label.dedicate.cluster=D\u00e9dier Cluster label.dedicated=D\u00e9di\u00e9 +label.dedicate=D\u00e9dier +label.dedicated.vlan.vni.ranges=Plages VLAN/VNI d\u00e9di\u00e9es +label.dedicate.host=D\u00e9dier H\u00f4te +label.dedicate.pod=D\u00e9dier Pod +label.dedicate.vlan.vni.range=Plage VLAN/VNI d\u00e9di\u00e9e +label.dedicate.zone=D\u00e9dier Zone +label.default.egress.policy=Politique Egress par d\u00e9faut label.default=Par d\u00e9faut label.default.use=Utilisation par d\u00e9faut label.default.view=Vue par d\u00e9faut label.delete.affinity.group=Supprimer le groupe d\\'affinit\u00e9 +label.delete.alerts=Supprimer alertes label.delete.BigSwitchVns=Supprimer contr\u00f4leur BigSwitch Vns +label.delete.ciscovnmc.resource=Supprimer ressource CiscoVNMC +label.delete.events=Supprimer \u00e9v\u00e9nements label.delete.F5=Supprimer F5 label.delete.gateway=Supprimer la passerelle label.delete.NetScaler=Supprimer Netscaler label.delete.NiciraNvp=Supprimer un contr\u00f4leur Nvp +label.delete.OpenDaylight.device=Supprimer contr\u00f4leur OpenDaylight +label.delete.PA=Supprimer Palo Alto +label.delete.portable.ip.range=Supprimer Plage IP portable +label.delete.profile=Supprimer Profil label.delete.project=Supprimer projet +label.delete.secondary.staging.store=Supprimer Stockage Secondaire Interm\u00e9diaire label.delete.SRX=Supprimer SRX label.delete=Supprimer +label.delete.ucs.manager=Supprimer Gestionnaire UCS label.delete.VPN.connection=Supprimer la connexion VPN label.delete.VPN.customer.gateway=Supprimer la passerelle VPN client label.delete.VPN.gateway=Supprimer la passerelle VPN label.delete.vpn.user=Supprimer l\\'utilisateur VPN label.deleting.failed=Suppression \u00e9chou\u00e9e label.deleting.processing=Suppression... +label.deny=Interdire +label.deployment.planner=Planning d\u00e9ploiement label.description=Description label.destination.physical.network.id=Identifiant du r\u00e9seau physique de destination label.destination.zone=Zone de destination label.destroy=D\u00e9truire label.destroy.router=Supprimer le routeur +label.destroy.vm.graceperiod=D\u00e9truire P\u00e9riode de gr\u00e2ce VM label.detaching.disk=D\u00e9tacher le disque label.details=D\u00e9tails label.device.id=ID du p\u00e9riph\u00e9rique @@ -457,11 +540,24 @@ label.devices=Machines label.dhcp=DHCP label.DHCP.server.type=Serveur DHCP label.direct.ips=Adresses IP du r\u00e9seau partag\u00e9 +label.disable.autoscale=D\u00e9sactiver Autoscale label.disabled=D\u00e9sactiv\u00e9 +label.disable.network.offering=D\u00e9sactiver Offre de r\u00e9seau label.disable.provider=D\u00e9sactiver ce fournisseur +label.disable.vnmc.provider=D\u00e9sactiver fournisseur VNMC +label.disable.vpc.offering=D\u00e9sactiver offre VPC label.disable.vpn=D\u00e9sactiver le VPN label.disabling.vpn.access=D\u00e9sactiver l\\'acc\u00e8s VPN +label.disassociate.profile.blade=D\u00e9-associer le Profil de la Lame +label.disbale.vnmc.device=D\u00e9sactiver VNMC label.disk.allocated=Disque Allou\u00e9 +label.disk.bytes.read.rate=D\u00e9bit lecture disque (BPS) +label.disk.bytes.write.rate=D\u00e9bit \u00e9criture disque (BPS) +label.disk.iops.max=IOPS maximum +label.disk.iops.min=IOPS minimum +label.disk.iops.read.rate=D\u00e9bit lecture disque (IOPS) +label.disk.iops.total=IOPS Total +label.disk.iops.write.rate=D\u00e9bit \u00e9criture disque (IOPS) label.disk.offering=Offre de Disque label.disk.read.bytes=Lecture Disque (Octets) label.disk.read.io=Lecture Disque (IO) @@ -473,6 +569,7 @@ label.disk.write.bytes=\u00c9criture Disque (Octets) label.disk.write.io=\u00c9criture Disque (IO) label.display.name=Nom commun label.display.text=Texte affich\u00e9 +label.distributedrouter=Routeur Distribu\u00e9 label.dns.1=DNS 1 label.dns.2=DNS 2 label.dns=DNS @@ -480,6 +577,7 @@ label.DNS.domain.for.guest.networks=Domaine DNS pour les r\u00e9seaux invit\u00e label.domain.admin=Administrateur du domaine label.domain=Domaine label.domain.id=ID du domaine +label.domain.lower=domaine label.domain.name=Nom de domaine label.domain.router=Routeur du domaine label.domain.suffix=Suffixe de domaine DNS (i.e., xyz.com) @@ -487,23 +585,32 @@ label.done=Termin\u00e9 label.double.quotes.are.not.allowed=Les guillemets ne sont pas autoris\u00e9es label.download.progress=Progression du t\u00e9l\u00e9chargement label.drag.new.position=D\u00e9placer sur une autre position +label.dynamically.scalable=Dimensionnement dynamique label.edit.affinity.group=Modifier le groupe d\\'affinit\u00e9 label.edit.lb.rule=Modifier la r\u00e8gle LB label.edit=Modifier label.edit.network.details=Modifier les param\u00e8tres r\u00e9seau label.edit.project.details=Modifier les d\u00e9tails du projet +label.edit.region=\u00c9diter R\u00e9gion label.edit.tags=Modifier les balises label.edit.traffic.type=Modifier le type de trafic label.edit.vpc=Modifier le VPC +label.egress.default.policy=Politique par d\u00e9faut Egress label.egress.rule=R\u00e8gle sortante label.egress.rules=R\u00e8gles de sortie label.elastic.IP=IP extensible label.elastic.LB=R\u00e9partition de charge extensible label.elastic=\u00c9lastique label.email=Email +label.email.lower=email +label.enable.autoscale=Activer Autoscale +label.enable.network.offering=Activer Offre de r\u00e9seau label.enable.provider=Activer le fournisseur label.enable.s3=Activer le stockage secondaire de type S3 label.enable.swift=Activer Swift +label.enable.vnmc.device=Activer VNMC +label.enable.vnmc.provider=Activer fournisseur VNMC +label.enable.vpc.offering=Activer offre VPC label.enable.vpn=Activer VPN label.enabling.vpn.access=Activation de l\\'acc\u00e8s VPN label.enabling.vpn=Activation du VPN @@ -523,13 +630,16 @@ label.ESP.lifetime=Dur\u00e9e de vie ESP (secondes) label.ESP.policy=Mode ESP label.esx.host=H\u00f4te ESX/ESXi label.example=Exemple +label.expunge=Purger label.external.link=Lien externe +label.f5.details=D\u00e9tails F5 label.f5=F5 label.failed=\u00c9chou\u00e9 label.featured=Sponsoris\u00e9 label.fetch.latest=Rafra\u00eechir label.filterBy=Filtre label.firewall=Pare-feu +label.firstname.lower=pr\u00e9nom label.first.name=Pr\u00e9nom label.format=Format label.friday=Vendredi @@ -538,12 +648,30 @@ label.full.path=Chemin complet label.gateway=Passerelle label.general.alerts=Alertes g\u00e9n\u00e9rales label.generating.url=G\u00e9n\u00e9ration de l\\'URL +label.gluster.volume=Volume label.go.step.2=Aller \u00e0 l\\'\u00e9tape 2 label.go.step.3=Aller \u00e0 l\\'\u00e9tape 3 label.go.step.4=Aller \u00e0 l\\'\u00e9tape 4 label.go.step.5=Aller \u00e0 l\\'\u00e9tape 5 +label.gpu=GPU +label.group.by.account=Regrouper par compte +label.group.by.cluster=Regrouper par cluster +label.group.by.pod=Regrouper par pod +label.group.by.zone=Regrouper par zone label.group=Groupe label.group.optional=Groupe (optionnel) +label.gslb.assigned.lb.more=Assigner plus de r\u00e9partition de charge +label.gslb.assigned.lb=R\u00e9partition de charge assign\u00e9e +label.gslb.delete=Supprimer GSLB +label.gslb.details=D\u00e9tails GSLB +label.gslb.domain.name=Nom de domaine GSLB +label.gslb.lb.details=D\u00e9tails r\u00e9partition de charge +label.gslb.lb.remove=Supprimer r\u00e9partition de charge depuis ce GSLB +label.gslb.lb.rule=R\u00e8gle de r\u00e9partition de charge +label.gslb.service.private.ip=IP priv\u00e9e service GSLB +label.gslb.service.public.ip=IP publique service GSLB +label.gslb.service=Service GSLB +label.gslb.servicetype=Type service label.guest.cidr=CIDR invit\u00e9 label.guest.end.ip=Adresse IP de fin pour les invit\u00e9s label.guest.gateway=Passerelle pour les invit\u00e9s @@ -551,14 +679,19 @@ label.guest=Invit\u00e9 label.guest.ip=Adresse IP des invit\u00e9s label.guest.ip.range=Plage d\\'adresses IP des invit\u00e9s label.guest.netmask=Masque de r\u00e9seau des invit\u00e9s +label.guest.network.details=D\u00e9tails r\u00e9seau invit\u00e9 label.guest.networks=R\u00e9seaux d\\'invit\u00e9 label.guest.start.ip=Adresse IP de d\u00e9but pour les invit\u00e9s label.guest.traffic=Trafic invit\u00e9 +label.guest.traffic.vswitch.name=Nom Trafic Invit\u00e9 vSwitch +label.guest.traffic.vswitch.type=Type Trafic Invit\u00e9 vSwitch label.guest.type=Type d\\'invit\u00e9 label.ha.enabled=Haute disponibilit\u00e9 activ\u00e9e +label.health.check=V\u00e9rification statut label.help=Aide label.hide.ingress.rule=Cacher la r\u00e8gle d\\'entr\u00e9e label.hints=Astuces +label.home=Accueil label.host.alerts=Alertes des h\u00f4tes label.host=H\u00f4te label.host.MAC=Adresse MAC h\u00f4te @@ -568,8 +701,11 @@ label.host.tags=\u00c9tiquettes d\\'h\u00f4te label.hourly=Chaque heure label.hypervisor.capabilities=Fonctions hyperviseur label.hypervisor=Hyperviseur +label.hypervisors=Hyperviseurs +label.hypervisor.snapshot.reserve=R\u00e9serve d\\'instantan\u00e9e de l\\'Hyperviseur label.hypervisor.type=Type d\\'hyperviseur label.hypervisor.version=Version hyperviseur +label.hyperv.traffic.label=Libell\u00e9 trafic HyperV label.id=ID label.IKE.DH=DH IKE label.IKE.encryption=Chiffrement IKE @@ -585,8 +721,8 @@ label.installWizard.addHostIntro.subtitle=Qu\\'est ce qu\\'un h\u00f4te ? label.installWizard.addHostIntro.title=Ajoutons un h\u00f4te label.installWizard.addPodIntro.subtitle=Qu\\'est ce qu\\'un pod ? label.installWizard.addPodIntro.title=Ajoutons un pod -label.installWizard.addPrimaryStorageIntro.subtitle=Qu\\'est ce que le stockage principal ? -label.installWizard.addPrimaryStorageIntro.title=Ajoutons du stockage principal +label.installWizard.addPrimaryStorageIntro.subtitle=Qu\\'est ce que le stockage primaire ? +label.installWizard.addPrimaryStorageIntro.title=Ajoutons du stockage primaire label.installWizard.addSecondaryStorageIntro.subtitle=Qu\\'est ce que le stockage secondaire ? label.installWizard.addSecondaryStorageIntro.title=Ajoutons du stockage secondaire label.installWizard.addZoneIntro.subtitle=Qu\\'est ce qu\\'une zone ? @@ -598,7 +734,9 @@ label.installWizard.title=Bonjour et bienvenue dans CloudStack&\#8482; label.instance=Instance label.instance.limits=Limites des instances label.instance.name=Nom de l\\'instance +label.instance.scaled.up=Instance agrandie label.instances=Instances +label.instanciate.template.associate.profile.blade=Instancier Mod\u00e8le et Profil associ\u00e9 \u00e0 la Lame label.internal.dns.1=DNS interne 1 label.internal.dns.2=DNS interne 2 label.internal.name=Nom interne @@ -620,6 +758,18 @@ label.ip.range=Plage IP label.ip.ranges=Plages IP label.IPsec.preshared.key=Cl\u00e9 partag\u00e9e IPsec label.ips=IPs +label.ipv4.cidr=CIDR IPv4 +label.ipv4.end.ip=IP fin IPv4 +label.ipv4.gateway=Passerelle IPv4 +label.ipv4.netmask=Masque de r\u00e9seau IPv4 +label.ipv4.start.ip=IP d\u00e9but IPv4 +label.ipv6.address=Adresse IPv6 +label.ipv6.CIDR=CIDR IPv6 +label.ipv6.dns1=DNS1 IPv6 +label.ipv6.dns2=DNS2 IPv6 +label.ipv6.end.ip=IP fin IPv6 +label.ipv6.gateway=Passerelle IPv6 +label.ipv6.start.ip=IP d\u00e9but IPv6 label.iscsi=iSCSI label.is.default=Est par d\u00e9faut label.iso.boot=D\u00e9marrage par ISO @@ -635,7 +785,7 @@ label.item.listing=Liste des \u00e9l\u00e9ments label.keep=Conserver label.keyboard.type=Type de clavier label.key=Clef -label.kvm.traffic.label=Libell\u00e9 pour le trafic KVM +label.kvm.traffic.label=Libell\u00e9 trafic KVM label.label=Libell\u00e9 label.lang.arabic=Arabe label.lang.brportugese=Portuguais Br\u00e9sil @@ -653,14 +803,19 @@ label.lang.polish=Polonais label.lang.russian=Russe label.lang.spanish=Espagnol label.last.disconnected=Derni\u00e8re D\u00e9connexion +label.lastname.lower=nom label.last.name=Nom label.latest.events=Derniers \u00e9v\u00e9nements label.launch=D\u00e9marrer label.launch.vm=D\u00e9marrer VM label.launch.zone=D\u00e9marrer la zone label.LB.isolation=R\u00e9partition de charge isol\u00e9e +label.ldap.configuration=Configuration LDAP +label.ldap.group.name=Groupe LDAP +label.ldap.port=Port LDAP label.least.connections=Le moins de connexions label.level=Niveau +label.linklocal.ip=Adresse IP lien local label.load.balancer=R\u00e9partiteur de charge label.load.balancing.policies=R\u00e8gles de r\u00e9partition de charge label.load.balancing=R\u00e9partition de charge @@ -672,6 +827,7 @@ label.login=Connexion label.logout=D\u00e9connexion label.lun=LUN label.LUN.number=N\u00b0 LUN +label.lxc.traffic.label=Libell\u00e9 trafic LXC label.make.project.owner=Devenir propri\u00e9taire du projet label.manage=G\u00e9r\u00e9 label.management=Administration @@ -680,6 +836,7 @@ label.manage.resources=G\u00e9rer les ressources label.max.cpus=Nombre coeurs CPU max. label.max.guest.limit=Nombre maximum d\\'invit\u00e9s label.maximum=Maximum +label.max.instances=Instance Max. label.max.memory=M\u00e9moire max. (Mo) label.max.networks=R\u00e9seaux Max. label.max.primary.storage=Principal max. (Go) @@ -706,7 +863,7 @@ label.menu.community.templates=Mod\u00e8les de la communaut\u00e9 label.menu.configuration=Configuration label.menu.dashboard=Tableau de bord label.menu.destroyed.instances=Instances d\u00e9truites -label.menu.disk.offerings=Offres de disque +label.menu.disk.offerings=Offres de Disque label.menu.domains=Domaines label.menu.events=\u00c9v\u00e9nements label.menu.featured.isos=ISOs Sponsoris\u00e9es @@ -720,7 +877,7 @@ label.menu.my.accounts=Mes comptes label.menu.my.instances=Mes instances label.menu.my.isos=Mes ISOs label.menu.my.templates=Mes mod\u00e8les -label.menu.network.offerings=Offres de Service R\u00e9seau +label.menu.network.offerings=Offres de R\u00e9seau label.menu.network=R\u00e9seau label.menu.physical.resources=Ressources physiques label.menu.regions=R\u00e9gions @@ -730,23 +887,27 @@ label.menu.service.offerings=Offres de Service label.menu.snapshots=Instantan\u00e9s label.menu.stopped.instances=Instances Arr\u00eat\u00e9es label.menu.storage=Stockage -label.menu.system.service.offerings=Offres syst\u00e8me +label.menu.system.service.offerings=Offres Syst\u00e8me label.menu.system=Syst\u00e8me label.menu.system.vms=\ VMs Syst\u00e8mes label.menu.templates=Mod\u00e8les label.menu.virtual.appliances=Appliances Virtuelles label.menu.virtual.resources=Ressources Virtuelles label.menu.volumes=Volumes +label.menu.vpc.offerings=Offres VPC label.migrate.instance.to.host=Migration de l\\'instance sur un autre h\u00f4te label.migrate.instance.to=Migrer l\\'instance vers -label.migrate.instance.to.ps=Migration de l\\'instance sur un autre stockage principal +label.migrate.instance.to.ps=Migration de l\\'instance sur un autre stockage primaire +label.migrate.lb.vm=Migrer LB VM label.migrate.router.to=Migrer le routeur vers label.migrate.systemvm.to=Migrer la VM syst\u00e8me vers label.migrate.to.host=Migrer vers un h\u00f4te label.migrate.to.storage=Migrer vers un stockage -label.migrate.volume=Migration du volume vers un autre stockage principal +label.migrate.volume=Migration du volume vers un autre stockage primaire label.minimum=Minimum +label.min.instances=Instances Min. label.minute.past.hour=minute(s) +label.mode=Mode label.monday=Lundi label.monthly=Mensuel label.more.templates=Plus de mod\u00e8les @@ -757,14 +918,18 @@ label.move.up.row=Monter d\\'un cran label.my.account=Mon compte label.my.network=Mon r\u00e9seau label.my.templates=Mes mod\u00e8les +label.name.lower=name label.name=Nom label.name.optional=Nom (optionnel) label.nat.port.range=Plage de port NAT label.netmask=Masque de r\u00e9seau +label.netscaler.details=D\u00e9tails NetScaler label.netScaler=NetScaler label.network.ACL=R\u00e8gles d\\'acc\u00e8s r\u00e9seau ACL label.network.ACLs=R\u00e8gles d\\'acc\u00e8s r\u00e9seau label.network.ACL.total=Total R\u00e8gles d\\'acc\u00e8s r\u00e9seau +label.network.addVM=Ajouter r\u00e9seau \u00e0 la VM +label.network.cidr=CIDR r\u00e9seau label.network.desc=Description r\u00e9seau label.network.device.type=Type d\\'\u00e9quipement r\u00e9seau label.network.device=\u00c9quipement R\u00e9seau @@ -773,11 +938,12 @@ label.network.domain.text=Domaine r\u00e9seau label.network.id=ID r\u00e9seau label.networking.and.security=R\u00e9seau et s\u00e9curit\u00e9 label.network.label.display.for.blank.value=Utiliser la passerelle par d\u00e9faut +label.network.limits=Limites r\u00e9seau label.network.name=Nom du r\u00e9seau -label.network.offering.display.text=Texte affich\u00e9 d\\'Offre de R\u00e9seau -label.network.offering.id=ID de l\\'Offre de Service R\u00e9seau -label.network.offering.name=Nom de l\\'Offre de Service R\u00e9seau -label.network.offering=Offre de Service R\u00e9seau +label.network.offering.display.text=Texte affich\u00e9 Offre R\u00e9seau +label.network.offering.id=ID Offre R\u00e9seau +label.network.offering.name=Nom Offre R\u00e9seau +label.network.offering=Offre de R\u00e9seau label.network.rate=D\u00e9bit R\u00e9seau label.network.rate.megabytes=D\u00e9bit r\u00e9seau (Mo/s) label.network.read=Lecture r\u00e9seau @@ -798,12 +964,14 @@ label.nfs.storage=Stockage NFS label.nic.adapter.type=Type de carte r\u00e9seau label.nicira.controller.address=Adresse du contr\u00f4leur label.nicira.l3gatewayserviceuuid=Uuid du service passerelle L3 +label.nicira.nvp.details=D\u00e9tails Nicira NVP label.nicira.transportzoneuuid=Uuid de la Zone Transport label.nics=Cartes NIC label.no.actions=Aucune action disponible label.no.alerts=Aucune alerte r\u00e9cente label.no.data=Aucune donn\u00e9e label.no.errors=Aucune erreur r\u00e9cente +label.no.grouping=(pas de groupement) label.no.isos=Aucun ISOs disponible label.no.items=Aucun \u00e9l\u00e9ment disponible label.none=Aucun @@ -813,6 +981,7 @@ label.not.found=Introuvable label.no.thanks=Non merci label.notifications=Messages label.number.of.clusters=Nombre de clusters +label.number.of.cpu.sockets=Le nombre de sockets CPU label.number.of.hosts=Nombre d\\'H\u00f4tes label.number.of.pods=Nombre de Pods label.number.of.system.vms=Nombre de VM Syst\u00e8me @@ -823,43 +992,65 @@ label.numretries=Nombre de tentatives label.ocfs2=OCFS2 label.offer.ha=Offrir la haute disponibilit\u00e9 label.ok=OK +label.opendaylight.controller=Contr\u00f4leur OpenDaylight +label.opendaylight.controllerdetail=D\u00e9tails Contr\u00f4leur OpenDaylight +label.opendaylight.controllers=Contr\u00f4leurs OpenDaylight +label.openDaylight=OpenDaylight label.optional=Facultatif label.order=Ordre label.os.preference=Pr\u00e9f\u00e9rence OS label.os.type=Type du OS +label.override.guest.traffic=Remplacer Trafic-invit\u00e9 +label.override.public.traffic=Remplacer Trafic-public +label.ovm.traffic.label=Libell\u00e9 trafic OVM +label.ovs=OVS label.owned.public.ips=Adresses IP Publiques d\u00e9tenues label.owner.account=Propri\u00e9taire label.owner.domain=Propri\u00e9taire +label.palo.alto.details=D\u00e9tails Palo Alto +label.PA.log.profile=Profil Journal Palo Alto +label.PA=Palo Alto label.parent.domain=Parent du Domaine label.password.enabled=Mot de passe activ\u00e9 +label.password.lower=mot de passe label.password=Mot de passe +label.password.reset.confirm=Le mot de passe a \u00e9t\u00e9 r\u00e9-initialis\u00e9 en label.path=Chemin +label.PA.threat.profile=Profil menace Palo Alto label.perfect.forward.secrecy=Confidentialit\u00e9 persistante +label.persistent=Persistant label.physical.network.ID=Identifiant du r\u00e9seau physique label.physical.network=R\u00e9seau physique label.PING.CIFS.password=Mot de passe CIFS PING label.PING.CIFS.username=Identifiant CIFS PING label.PING.dir=R\u00e9pertoire PING label.PING.storage.IP=IP stockage PING +label.planner.mode=Mode planification label.please.specify.netscaler.info=Renseigner les informations sur le Netscaler label.please.wait=Patientez s\\'il vous plait label.plugin.details=D\u00e9tails extension label.plugins=Extensions +label.pod.dedicated=Pod D\u00e9di\u00e9 label.pod.name=Nom du pod label.pod=Pod label.pods=Pods +label.polling.interval.sec=Intervalle d\\'appel (en sec) +label.portable.ip.range.details=D\u00e9tails Plages IP portables +label.portable.ip.ranges=Plages IP portables +label.portable.ips=IPs portables label.port.forwarding.policies=R\u00e8gles de transfert de port label.port.forwarding=Redirection de port +label.port=Port label.port.range=Plage de ports label.PreSetup=PreSetup label.previous=Retour label.prev=Pr\u00e9c\u00e9dent -label.primary.allocated=Stockage principal allou\u00e9 +label.primary.allocated=Stockage primaire allou\u00e9 label.primary.network=R\u00e9seau principal -label.primary.storage.count=Groupes de stockage principal -label.primary.storage.limits=Limites stockage principal (Go) -label.primary.storage=Premier stockage -label.primary.used=Stockage principal utilis\u00e9 +label.primary.storage.count=Groupes de stockage primaire +label.primary.storage.limits=Limites stockage primaire (Go) +label.primary.storage=Stockages primaires +label.primary.used=Stockage primaire utilis\u00e9 label.private.Gateway=Passerelle priv\u00e9e label.private.interface=Interface priv\u00e9e label.private.ip=Adresse IP Priv\u00e9e @@ -869,6 +1060,7 @@ label.privatekey=Cl\u00e9 priv\u00e9e PKCS\#8 label.private.network=R\u00e9seau priv\u00e9 label.private.port=Port priv\u00e9 label.private.zone=Zone Priv\u00e9e +label.profile=Profil label.project.dashboard=Tableau de bord projet label.project.id=ID projet label.project.invite=Inviter sur le projet @@ -877,32 +1069,57 @@ label.project=Projet label.projects=Projets label.project.view=Vue projet label.protocol=Protocole +label.provider=Fournisseur label.providers=Fournisseurs label.public.interface=Interface publique label.public.ip=Adresse IP publique label.public.ips=Adresses IP publiques +label.public.load.balancer.provider=Fournisseur r\u00e9partition de charge public label.public.network=R\u00e9seau public label.public.port=Port public label.public=Publique label.public.traffic=Trafic public +label.public.traffic.vswitch.name=Nom Trafic Public vSwitch +label.public.traffic.vswitch.type=Type Trafic Public vSwitch label.public.zone=Zone publique label.purpose=R\u00f4le label.Pxe.server.type=Serveur PXE +label.qos.type=Type de QoS label.quickview=Aper\u00e7u +label.quiesce.vm=Mettre en veille VM +label.quiet.time.sec=Quiet Time (en sec) +label.rbd.id=Utilisateur Cephx +label.rbd.monitor=Superviseur Ceph +label.rbd.pool=Pool Ceph +label.rbd=RBD +label.rbd.secret=Secret Cephx label.reboot=Red\u00e9marrer label.recent.errors=Erreurs r\u00e9centes +label.recover.vm=Restaurer VM label.redundant.router.capability=Router redondant label.redundant.router=Routeur redondant label.redundant.state=\u00c9tat de la redondance label.refresh=Actualiser +label.refresh.blades=Rafra\u00eechir Lames +label.regionlevelvpc=VPC niveau r\u00e9gion label.region=R\u00e9gion +label.reinstall.vm=R\u00e9-installer VM label.related=Connexes +label.release.account=Lib\u00e9rer compte +label.release.account.lowercase=lib\u00e9rer compte +label.release.dedicated.cluster=Lib\u00e9ration du cluster d\u00e9die +label.release.dedicated.host=Lib\u00e9ration de l\\'h\u00f4te d\u00e9di\u00e9 +label.release.dedicated.pod=Lib\u00e9ration du pod d\u00e9di\u00e9 +label.release.dedicated.vlan.range=Lib\u00e9rer plage VLAN d\u00e9di\u00e9e +label.release.dedicated.zone=Lib\u00e9rer la zone d\u00e9di\u00e9e label.remind.later=Rappeler moi plus tard label.remove.ACL=Supprimer une r\u00e8gle ACL label.remove.egress.rule=Supprimer la r\u00e8gle sortante label.remove.from.load.balancer=Supprimer l\\'instance du r\u00e9partiteur de charge label.remove.ingress.rule=Supprimer la r\u00e8gle entrante label.remove.ip.range=Supprimer la plage IP +label.remove.ldap=Supprimer LDAP +label.remove.network.offering=Supprimer Offre de r\u00e9seau label.remove.pf=Supprimer la r\u00e8gle de transfert de port label.remove.project.account=Supprimer le compte projet label.remove.region=Supprimer r\u00e9gion @@ -911,18 +1128,25 @@ label.remove.static.nat.rule=Supprimer le NAT statique label.remove.static.route=Supprimer une route statique label.remove.tier=Supprimer le tiers label.remove.vm.from.lb=Supprimer la VM de la r\u00e8gle de r\u00e9partition de charge +label.remove.vmware.datacenter=Supprimer un datacenter VMware +label.remove.vpc.offering=Supprimer offre VPC label.remove.vpc=Supprimer le VPC label.removing=Suppression label.removing.user=Retrait de l\\'utilisateur +label.reource.id=ID Ressource label.required=Requis +label.requires.upgrade=Mise \u00e0 niveau n\u00e9cessaire +label.reserved.ip.range=Plage IP r\u00e9serv\u00e9e label.reserved.system.gateway=Passerelle r\u00e9serv\u00e9e Syst\u00e8me label.reserved.system.ip=Adresse IP Syst\u00e8me r\u00e9serv\u00e9e label.reserved.system.netmask=Masque de sous-r\u00e9seau r\u00e9serv\u00e9 Syst\u00e8me +label.resetVM=R\u00e9-initialiser VM label.reset.VPN.connection=R\u00e9-initialiser la connexion VPN label.resize.new.offering.id=Nouvelle Offre label.resize.new.size=Nouvelle Taille (Go) label.resize.shrink.ok=R\u00e9duction OK label.resource.limits=Limite des ressources +label.resource.name=Nom Ressource label.resource=Ressource label.resources=Ressources label.resource.state=\u00c9tat des ressources @@ -935,7 +1159,11 @@ label.revoke.project.invite=R\u00e9voquer l\\'invitation label.role=R\u00f4le label.root.disk.controller=Contr\u00f4leur de disque principal label.root.disk.offering=Offre de disque racine +label.root.disk.size=Taille disque principal label.round.robin=Al\u00e9atoire +label.router.vm.scaled.up=VM Routeur agrandi +label.routing=Routage +label.rule.number=Num\u00e9ro r\u00e8gle label.rules=R\u00e8gles label.running.vms=VMs actives label.s3.access_key=Cl\u00e9 d\\'Acc\u00e8s @@ -943,6 +1171,8 @@ label.s3.bucket=Seau label.s3.connection_timeout=D\u00e9lai d\\'expiration de connexion label.s3.endpoint=Terminaison label.s3.max_error_retry=Nombre d\\'essai en erreur max. +label.s3.nfs.path=S3 Chemin NFS +label.s3.nfs.server=S3 Serveur NFS label.s3.secret_key=Cl\u00e9 Priv\u00e9e label.s3.socket_timeout=D\u00e9lai d\\'expiration de la socket label.s3.use_https=Utiliser HTTPS @@ -952,9 +1182,13 @@ label.save=Sauvegarder label.saving.processing=Sauvegarde en cours... label.scope=Port\u00e9e label.search=Rechercher +label.secondary.isolated.vlan.id=VLAN ID isol\u00e9 secondaire +label.secondary.staging.store.details=D\u00e9tails Stockage Secondaire Interm\u00e9diaire +label.secondary.staging.store=Stockage Secondaire Interm\u00e9diaire label.secondary.storage.count=Groupes de stockage secondaire +label.secondary.storage.details=D\u00e9tails Stockage Secondaire label.secondary.storage.limits=Limites stockage secondaire (Go) -label.secondary.storage=Stockage secondaire +label.secondary.storage=Stockages secondaires label.secondary.storage.vm=VM stockage secondaire label.secondary.used=Stockage secondaire utilis\u00e9 label.secret.key=Cl\u00e9 priv\u00e9e @@ -970,6 +1204,7 @@ label.select.iso.or.template=S\u00e9lectionner un ISO ou un mod\u00e8le label.select.offering=S\u00e9lectionner une offre label.select.project=S\u00e9lectionner un projet label.select=S\u00e9lectionner +label.select.template=S\u00e9lectionner Mod\u00e8le label.select.tier=S\u00e9lectionner le tiers label.select-view=S\u00e9lectionner la vue label.select.vm.for.static.nat=S\u00e9lectionner une VM pour le NAT statique @@ -977,32 +1212,45 @@ label.sent=Envoy\u00e9 label.server=Serveur label.service.capabilities=Fonctions disponibles label.service.offering=Offre de Service +label.services=Services +label.service.state=\u00c9tat du service label.session.expired=Session expir\u00e9e +label.set.default.NIC=D\u00e9finir NIC par d\u00e9faut +label.settings=Param\u00e8tres label.setup=Configuration label.setup.network=Configurer le r\u00e9seau label.setup.zone=Configurer la zone label.set.up.zone.type=Configurer le type de zone label.shared=En partage label.SharedMountPoint=Point de montage partag\u00e9 +label.show.advanced.settings=Voir param\u00e8tres avanc\u00e9s label.show.ingress.rule=Montrer la r\u00e8gle d\\'entr\u00e9e label.shutdown.provider=\u00c9teindre ce fournisseur label.site.to.site.VPN=VPN Site-\u00e0-Site label.size=Taille label.skip.guide=J\\'ai d\u00e9j\u00e0 utilis\u00e9 CloudStack avant, passer ce tutoriel +label.smb.domain=Domaine SMB +label.smb.password=Mot de passe SMB +label.smb.username=Identifiant SMB label.snapshot=Instantan\u00e9 label.snapshot.limits=Limites d\\'instantan\u00e9s label.snapshot.name=Nom Instantan\u00e9 label.snapshot.schedule=Configurer un instantan\u00e9 r\u00e9current label.snapshot.s=Instantan\u00e9(s) label.snapshots=Instantan\u00e9s +label.SNMP.community=Communaut\u00e9 SNMP +label.SNMP.port=Port SNMP +label.sockets=Sockets label.source.nat=NAT Source label.source=Origine label.specify.IP.ranges=Sp\u00e9cifier des plages IP label.specify.vlan=Pr\u00e9ciser le VLAN label.specify.vxlan=Pr\u00e9ciser le VXLAN label.SR.name = Nom du point de montage +label.srx.details=D\u00e9tails SRX label.srx=SRX label.start.IP=Plage de d\u00e9but IP +label.start.lb.vm=D\u00e9marrer LB VM label.start.port=Port de d\u00e9but label.start.reserved.system.IP=Adresse IP de d\u00e9but r\u00e9serv\u00e9e Syst\u00e8me label.start.vlan=VLAN de d\u00e9part @@ -1038,6 +1286,7 @@ label.sticky.prefix=Pr\u00e9fixe label.sticky.request-learn=Apprendre la requ\u00eate label.sticky.tablesize=Taille du tableau label.stop=Arr\u00eater +label.stop.lb.vm=Arr\u00eater LB VM label.stopped.vms=VMs arr\u00eat\u00e9es label.storage=Stockage label.storage.tags=\u00c9tiquettes de stockage @@ -1051,21 +1300,29 @@ label.sunday=Dimanche label.super.cidr.for.guest.networks=Super CIDR pour les r\u00e9seaux invit\u00e9s label.supported.services=Services support\u00e9s label.supported.source.NAT.type=Type de NAT support\u00e9 +label.supportsstrechedl2subnet=Sous-r\u00e9seau Streched L2 support\u00e9 label.suspend.project=Suspendre projet +label.switch.type=Type commutateur label.system.capacity=Capacit\u00e9 syst\u00e8me +label.system.offering.for.router=Offre Syst\u00e8me pour Routeur label.system.offering=Offre de syst\u00e8me label.system.service.offering=Offre de Service Syst\u00e8me +label.system.vm.details=D\u00e9tails VM Syst\u00e8me +label.system.vm.scaled.up=VM Syst\u00e8me agrandie label.system.vms=\ VMs Syst\u00e8mes label.system.vm.type=Type de VM syst\u00e8me label.system.vm=VM Syst\u00e8me label.system.wide.capacity=Capacit\u00e9 globale label.tagged=\u00c9tiquet\u00e9 +label.tag.key=Cl\u00e9 Tag label.tags=\u00c9tiquette +label.tag.value=Valeur Tag label.target.iqn=Cible IQN label.task.completed=T\u00e2che termin\u00e9e label.template.limits=Limites de mod\u00e8le label.template=Mod\u00e8le label.TFTP.dir=R\u00e9pertoire TFTP +label.tftp.root.directory=R\u00e9pertoire racine TFTP label.theme.default=Th\u00e8me par d\u00e9faut label.theme.grey=Personnalis\u00e9 - Gris label.theme.lightblue=Personnalis\u00e9 - Bleu clair @@ -1085,13 +1342,17 @@ label.total.memory=Total m\u00e9moire label.total.of.ip=Total adresses IP label.total.of.vm=Total VM label.total.storage=Total stockage +label.total.virtual.routers=Total des Routeurs virtuels +label.total.virtual.routers.upgrade=Total des routeurs virtuels avec mise \u00e0 niveau n\u00e9cessaire label.total.vms=Nombre total de VMs -label.traffic.label=Libell\u00e9 de trafic +label.traffic.label=Libell\u00e9 trafic label.traffic.types=Types de trafic -label.traffic.type=Type de Trafic +label.traffic.type=Type Trafic label.tuesday=Mardi label.type.id=ID du Type +label.type.lower=type label.type=Type +label.ucs=UCS label.unavailable=Indisponible label.unlimited=Illimit\u00e9 label.untagged=Non Tagg\u00e9 @@ -1099,14 +1360,19 @@ label.update.project.resources=Mettre \u00e0 jour les ressources du projet label.update.ssl.cert= Certificat SSL label.update.ssl= Certificat SSL label.updating=Mise \u00e0 jour +label.upgrade.required=Mise \u00e0 niveau n\u00e9cessaire +label.upgrade.router.newer.template=Mette \u00e0 jour le routeur pour utiliser le mod\u00e8le le plus r\u00e9cent label.upload=Charger label.upload.volume=Charger un volume label.url=URL label.usage.interface=Interface Utilisation label.used=Utilis\u00e9 +label.user.data=Donn\u00e9es utilisateur +label.username.lower=nom d\\'utilisateur label.username=Nom d\\'Utilisateur label.users=Utilisateurs label.user=Utilisateur +label.use.vm.ips=Utiliser IP VMs label.use.vm.ip=Utiliser IP VM \: label.value=Valeur label.vcdcname=Nom du DC vCenter @@ -1116,8 +1382,14 @@ label.vcenter.datastore=Datastore vCenter label.vcenter.host=H\u00f4te vCenter label.vcenter.password=Mot de passe vCenter label.vcenter.username=Nom d\\'utilisateur vCenter +label.vcenter=vcenter label.vcipaddress=Adresse IP vCenter label.version=Version +label.vgpu.max.resolution=R\u00e9solution Max. +label.vgpu.max.vgpu.per.gpu=vGPUs par GPU +label.vgpu.remaining.capacity=Capacit\u00e9 restante +label.vgpu.type=vGPU type +label.vgpu.video.ram=M\u00e9moire Vid\u00e9o label.view.all=Voir tout label.view.console=Voir la console label.viewing=Consultation en cours @@ -1125,23 +1397,31 @@ label.view.more=Voir plus label.view.secondary.ips=Voir IPs secondaires label.view=Voir label.virtual.appliance=Appliance Virtuelle +label.virtual.appliance.details=D\u00e9tails Appliance Virtuelle label.virtual.appliances=Appliances Virtuelles label.virtual.machines=Machines virtuelles +label.virtual.networking=Mise en r\u00e9seau virtuelle label.virtual.network=R\u00e9seau virtuel label.virtual.router=Routeur Virtuel +label.virtual.routers.group.account=Routeurs virtuels group\u00e9s par compte +label.virtual.routers.group.cluster=Routeurs virtuels group\u00e9s par cluster +label.virtual.routers.group.pod=Routeurs virtuels group\u00e9s par pod +label.virtual.routers.group.zone=Routeurs virtuels group\u00e9s par zone label.virtual.routers=Routeurs virtuels label.vlan.id=ID du VLAN +label.vlan.range.details=D\u00e9tails plage VLAN label.vlan.range=Plage du VLAN +label.vlan.ranges=Plage(s) VLAN label.vlan=VLAN -label.vxlan.id=VXLAN ID -label.vxlan.range=Plage du VXLAN -label.vxlan=VXLAN +label.vlan.vni.range=Plage du VLAN +label.vlan.vni.ranges=Plage(s) VLAN/VNI label.vm.add=Ajouter une instance label.vm.destroy=D\u00e9truire label.vm.display.name=Nom commun VM label.VMFS.datastore=Magasin de donn\u00e9es VMFS label.vmfs=VMFS label.vm.name=Nom de la VM +label.vm.password=Le mot de passe de cette VM est label.vm.reboot=Red\u00e9marrer label.VMs.in.tier=Machines virtuelles dans le tiers label.vmsnapshot.current=estCourant @@ -1153,14 +1433,27 @@ label.vm.start=D\u00e9marrer label.vm.state=\u00c9tat VM label.vm.stop=Arr\u00eater label.vms=VMs -label.vmware.traffic.label=Libell\u00e9 pour le trafic VMware +label.vmware.datacenter.id=ID datacenter VMware +label.vmware.datacenter.name=Nom datacenter VMware +label.vmware.datacenter.vcenter=vcenter datacenter VMware +label.vmware.traffic.label=Libell\u00e9 trafic VMware +label.vnet.id=ID VLAN/VNI +label.vnet=VLAN/VNI +label.vnmc.devices=\u00c9quipement VNMC +label.volatile=Volatile label.volgroup=Groupe de Volume label.volume.limits=Limites des volumes label.volume.name=Nom du volume label.volumes=Volumes label.volume=Volume +label.vpc.distributedvpcrouter=Routeur VPC Distribu\u00e9 label.vpc.id=ID VPC +label.VPC.limits=Limites VPC +label.vpc.offering.details=D\u00e9tails offre VPC +label.vpc.offering=Offre VPC label.VPC.router.details=D\u00e9tails routeur VPC +label.vpc.supportsregionlevelvpc=VPC niveau R\u00e9gion support\u00e9 +label.vpc.virtual.router=Routeur virtuel VPC label.vpc=VPC label.VPN.connection=Connexion VPN label.vpn.customer.gateway=Passerelle VPN client @@ -1171,6 +1464,9 @@ label.vsmctrlvlanid=\ ID VLAN Contr\u00f4le label.vsmpktvlanid=ID VLAN Paquet label.vsmstoragevlanid=VLAN ID Stockage label.vsphere.managed=G\u00e9r\u00e9e par vSphere +label.vxlan.id=VXLAN ID +label.vxlan.range=Plage du VXLAN +label.vxlan=VXLAN label.waiting=En attente label.warn=Avertissement label.wednesday=Mercredi @@ -1178,10 +1474,14 @@ label.weekly=Hebdomadaire label.welcome=Bienvenue label.welcome.cloud.console=Bienvenue dans la Console d\\'Administration label.what.is.cloudstack=Qu\\'est-ce-que CloudStack&\#8482; ? -label.xen.traffic.label=Libell\u00e9 pour le trafic XenServer +label.xenserver.tools.version.61.plus=XenServer Tools Version 6.1\\+ +label.Xenserver.Tools.Version61plus=XenServer Tools Version 6.1\\+ +label.xen.traffic.label=Libell\u00e9 trafic XenServer label.yes=Oui +label.zone.dedicated=Zone d\u00e9di\u00e9e label.zone.details=D\u00e9tails de la zone label.zone.id=ID de la zone +label.zone.lower=zone label.zone.name=Nom de zone label.zone.step.1.title=\u00c9tape 1 \: S\u00e9lectionnez un r\u00e9seau label.zone.step.2.title=\u00c9tape 2 \: Ajoutez une zone @@ -1191,7 +1491,7 @@ label.zones=Zones label.zone.type=Type de zone label.zone.wide=Transverse \u00e0 la zone label.zoneWizard.trafficType.guest=Invit\u00e9 \: Trafic entre les machines virtuelles utilisateurs -label.zoneWizard.trafficType.management=Administration \: Trafic entre les ressources internes de CloudStack, incluant tous les composants qui communiquent avec le serveur d\\'administration, tels que les h\u00f4tes and les machines virtuelles Syst\u00e8mes CloudStack +label.zoneWizard.trafficType.management=Administration \: Trafic entre les ressources internes de CloudStack, incluant tous les composants qui communiquent avec le serveur d\\'administration, tels que les h\u00f4tes et les machines virtuelles Syst\u00e8mes CloudStack label.zoneWizard.trafficType.public=Public \: Trafic entre Internet et les machines virtuelles dans le nuage label.zoneWizard.trafficType.storage=Stockage \: Trafic entre les serveurs de stockages principaux et secondaires, tel que le transfert de machines virtuelles mod\u00e8les et des instantan\u00e9s de disques label.zone=Zone @@ -1205,68 +1505,71 @@ message.action.cancel.maintenance=Votre h\u00f4te a quitt\u00e9 la maintenance. message.action.change.service.warning.for.instance=Votre instance doit \u00eatre arr\u00eat\u00e9e avant d\\'essayer de changer son offre de service. message.action.change.service.warning.for.router=Votre routeur doit \u00eatre arr\u00eat\u00e9 avant d\\'essayer de changer son offre de service. message.action.delete.cluster=\u00cates-vous s\u00fbr que vous voulez supprimer ce cluster. -message.action.delete.disk.offering=\u00cates-vous s\u00fbr que vous souhaitez supprimer cette offre de disque. +message.action.delete.disk.offering=Supprimer cette offre de disque ? message.action.delete.domain=\u00cates-vous s\u00fbr que vous voulez supprimer ce domaine. -message.action.delete.external.firewall=\u00cates-vous s\u00fbr que vous souhaitez supprimer ce pare-feu externe. Attention \: Si vous pr\u00e9voyez de rajouter le m\u00eame pare-feu externe de nouveau, vous devez r\u00e9-initialiser les donn\u00e9es d\\'utilisation sur l\\'appareil. -message.action.delete.external.load.balancer=\u00cates-vous s\u00fbr que vous souhaitez supprimer ce r\u00e9partiteur de charge externe. Attention \: Si vous pensez ajouter le m\u00eame r\u00e9partiteur de charge plus tard, vous devez remettre \u00e0 z\u00e9ro les statistiques d\\'utilisation de cet \u00e9quipement. -message.action.delete.ingress.rule=\u00cates-vous s\u00fbr que vous souhaitez supprimer cette r\u00e8gle d\\'entr\u00e9e. +message.action.delete.external.firewall=Supprimer ce pare-feu externe ? Attention \: Si vous pr\u00e9voyez de rajouter le m\u00eame pare-feu externe de nouveau, vous devez r\u00e9-initialiser les donn\u00e9es d\\'utilisation sur l\\'appareil. +message.action.delete.external.load.balancer=Supprimer ce r\u00e9partiteur de charge externe ? Attention \: Si vous pensez ajouter le m\u00eame r\u00e9partiteur de charge plus tard, vous devez remettre \u00e0 z\u00e9ro les statistiques d\\'utilisation de cet \u00e9quipement. +message.action.delete.ingress.rule=Supprimer cette r\u00e8gle de flux entrant ? message.action.delete.ISO.for.all.zones=L\\'ISO est utilis\u00e9 par toutes les zones. S\\'il vous pla\u00eet confirmer que vous voulez le supprimer de toutes les zones. -message.action.delete.ISO=\u00cates-vous s\u00fbr que vous souhaitez supprimer cette ISO. +message.action.delete.ISO=Supprimer cet ISO ? message.action.delete.network=\u00cates-vous s\u00fbr que vous voulez supprimer ce r\u00e9seau. message.action.delete.nexusVswitch=Confirmer la suppession de ce Nexus 1000v message.action.delete.nic=Veuillez confirmer que vous souhaitez supprimer cette carte NIC, ce qui supprimera \u00e9galement le r\u00e9seau associ\u00e9 sur la machine virtuelle. message.action.delete.physical.network=Confirmer la suppression du r\u00e9seau physique -message.action.delete.pod=\u00cates-vous s\u00fbr que vous souhaitez supprimer ce pod. -message.action.delete.primary.storage=\u00cates-vous s\u00fbr que vous voulez supprimer ce stockage principal. -message.action.delete.secondary.storage=\u00cates-vous s\u00fbr que vous souhaitez supprimer ce stockage secondaire. -message.action.delete.security.group=\u00cates-vous s\u00fbr que vous souhaitez supprimer ce groupe de s\u00e9curit\u00e9. -message.action.delete.service.offering=\u00cates-vous s\u00fbr que vous souhaitez supprimer cette offre de service. -message.action.delete.snapshot=\u00cates-vous s\u00fbr que vous souhaitez supprimer cet instantan\u00e9 +message.action.delete.pod=Supprimer ce pod ? +message.action.delete.primary.storage=\u00cates-vous s\u00fbr que vous voulez supprimer ce stockage primaire. +message.action.delete.secondary.storage=Supprimer ce stockage secondaire ? +message.action.delete.security.group=Supprimer ce groupe de s\u00e9curit\u00e9 ? +message.action.delete.service.offering=Supprimer cette offre de service ? +message.action.delete.snapshot=Supprimer cet instantan\u00e9 ? message.action.delete.system.service.offering=\u00cates-vous s\u00fbr que vous voulez supprimer l\\'offre syst\u00e8me. -message.action.delete.template.for.all.zones=Ce mod\u00e8le est utilis\u00e9 par toutes les zones. \u00cates-vous s\u00fbr que vous souhaitez le supprimer de toutes les zones. -message.action.delete.template=\u00cates-vous s\u00fbr que vous souhaitez supprimer ce mod\u00e8le. -message.action.delete.volume=\u00cates-vous s\u00fbr que vous souhaitez supprimer ce volume. -message.action.delete.zone=\u00cates-vous s\u00fbr que vous souhaitez supprimer cette zone. -message.action.destroy.instance=\u00cates-vous s\u00fbr que vous souhaitez supprimer cette instance. -message.action.destroy.systemvm=\u00cates-vous s\u00fbr que vous souhaitez supprimer cette VM Syst\u00e8me. -message.action.disable.cluster=\u00cates-vous s\u00fbr que vous souhaitez d\u00e9sactiver ce cluster +message.action.delete.template.for.all.zones=Ce mod\u00e8le est utilis\u00e9 par toutes les zones. Supprimer de toutes les zones ? +message.action.delete.template=Supprimer ce mod\u00e8le ? +message.action.delete.volume=Supprimer ce volume ? +message.action.delete.zone=Supprimer cette zone ? +message.action.destroy.instance=Supprimer cette instance ? +message.action.destroy.systemvm=Supprimer cette VM Syst\u00e8me ? +message.action.disable.cluster=D\u00e9sactiver ce cluster ? message.action.disable.nexusVswitch=Confirmer la d\u00e9sactivation de ce Nexus 1000v message.action.disable.physical.network=Confirmer l\\'activation de ce r\u00e9seau physique. -message.action.disable.pod=\u00cates-vous s\u00fbr que vous souhaitez d\u00e9sactiver ce Pod -message.action.disable.static.NAT=\u00cates-vous s\u00fbr que vous souhaitez d\u00e9sactiver le NAT statique. -message.action.disable.zone=\u00cates-vous s\u00fbr que vous souhaitez d\u00e9sactiver cette zone +message.action.disable.pod=D\u00e9sactiver ce pod ? +message.action.disable.static.NAT=D\u00e9sactiver le NAT statique ? +message.action.disable.zone=D\u00e9sactiver cette zone ? +message.action.downloading.template=T\u00e9l\u00e9chargement mod\u00e8le. message.action.download.iso=Confirmer le t\u00e9l\u00e9chargement de cet ISO message.action.download.template=Confirmer le t\u00e9l\u00e9chargement de ce mod\u00e8le -message.action.enable.cluster=\u00cates-vous s\u00fbr que vous souhaitez activer ce cluster +message.action.enable.cluster=Activer ce cluster ? message.action.enable.maintenance=Votre h\u00f4te a \u00e9t\u00e9 mis en mode maintenance avec succ\u00e8s. Ce processus peut durer plusieurs minutes ou plus, suivant le nombre de VMs actives sur cet h\u00f4te. message.action.enable.nexusVswitch=Confirmer l\\'activation de ce Nexus 1000v message.action.enable.physical.network=Confirmer l\\'activation de ce r\u00e9seau physique. -message.action.enable.pod=\u00cates-vous s\u00fbr que vous souhaitez activer ce Pod -message.action.enable.zone=\u00cates-vous s\u00fbr que vous souhaitez activer cette zone +message.action.enable.pod=Activer ce pod ? +message.action.enable.zone=Activer cette zone ? +message.action.expunge.instance=Confirmez que vous souhaitez oruger cette instance. message.action.force.reconnect=Votre h\u00f4te a \u00e9t\u00e9 forc\u00e9e \u00e0 se reconnecter avec succ\u00e8s. Ce processus peut prendre jusqu\\'\u00e0 plusieurs minutes. message.action.host.enable.maintenance.mode=Activer le mode maintenance va causer la migration \u00e0 chaud de l\\'ensemble des instances de cet h\u00f4te sur les autres h\u00f4tes disponibles. message.action.instance.reset.password=Confirmer le changement du mot de passe ROOT pour cette machine virtuelle. -message.action.manage.cluster=\u00cates-vous s\u00fbr que vous souhaitez g\u00e9rer le cluster -message.action.primarystorage.enable.maintenance.mode=Attention \: placer ce stockage principal en mode maintenance va provoquer l\\'arr\u00eat de l\\'ensemble des VMs utilisant des volumes sur ce stockage. Souhaitez-vous continuer ? -message.action.reboot.instance=\u00cates-vous s\u00fbr que vous souhaitez red\u00e9marrer cette instance. +message.action.manage.cluster=G\u00e9rer le cluster ? +message.action.primarystorage.enable.maintenance.mode=Attention \: placer ce stockage primaire en mode maintenance va provoquer l\\'arr\u00eat de l\\'ensemble des VMs utilisant des volumes sur ce stockage. Souhaitez-vous continuer ? +message.action.reboot.instance=Red\u00e9marrer cette instance ? message.action.reboot.router=Tous les services fournit par ce routeur virtuel vont \u00eatre interrompus. Confirmer le r\u00e9-amor\u00e7age de ce routeur. -message.action.reboot.systemvm=\u00cates-vous s\u00fbr que vous souhaitez red\u00e9marrer cette VM Syst\u00e8me -message.action.release.ip=\u00cates-vous s\u00fbr que vous souhaitez lib\u00e9rer cette IP. +message.action.reboot.systemvm=Red\u00e9marrer cette VM Syst\u00e8me ? +message.action.release.ip=Lib\u00e9rer cette adresse IP ? message.action.remove.host=\u00cates-vous s\u00fbr que vous voulez supprimer cet h\u00f4te. message.action.reset.password.off=Votre instance ne supporte pas pour le moment cette fonctionnalit\u00e9. message.action.reset.password.warning=Votre instance doit \u00eatre arr\u00eat\u00e9e avant d\\'essayer de changer son mot de passe. -message.action.restore.instance=\u00cates-vous s\u00fbr que vous souhaitez restaurer cette instance. -message.action.start.instance=\u00cates-vous s\u00fbr que vous souhaitez d\u00e9marrer cette instance. -message.action.start.router=\u00cates-vous s\u00fbr que vous souhaitez d\u00e9marrer ce routeur. -message.action.start.systemvm=\u00cates-vous s\u00fbr que vous souhaitez red\u00e9marrer cette VM syst\u00e8me. -message.action.stop.instance=\u00cates-vous s\u00fbr que vous souhaitez arr\u00eater cette instance. +message.action.restore.instance=Restaurer cette instance ? +message.action.revert.snapshot=Confirmez que vous souhaitez r\u00e9tablir ce volume pour cet instantan\u00e9 +message.action.start.instance=D\u00e9marrer cette instance ? +message.action.start.router=D\u00e9marrer ce routeur ? +message.action.start.systemvm=Red\u00e9marrer cette VM syst\u00e8me ? +message.action.stop.instance=Arr\u00eater cette instance ? message.action.stop.router=Tous les services fournit par ce routeur virtuel vont \u00eatre interrompus. Confirmer l\\'arr\u00eat de ce routeur. -message.action.stop.systemvm=\u00cates-vous s\u00fbr que vous souhaitez arr\u00eater cette VM. +message.action.stop.systemvm=Arr\u00eater cette VM ? message.action.take.snapshot=Confirmer la prise d\\'un instantan\u00e9 pour ce volume. message.action.unmanage.cluster=Confirmez que vous ne voulez plus g\u00e9rer le cluster message.action.vmsnapshot.delete=Confirmez que vous souhaitez supprimer cet instantan\u00e9 VM. -message.action.vmsnapshot.revert=Revenir \u00e0 un instantan\u00e9 VM -message.activate.project=\u00cates-vous s\u00fbr de vouloir activer ce projet ? +message.action.vmsnapshot.revert=R\u00e9tablir l\\'instantan\u00e9 VM +message.activate.project=Voulez-vous activer ce projet ? message.add.cluster=Ajouter un cluster d\\'hyperviseurs g\u00e9r\u00e9 pour cette zone , pod message.add.cluster.zone=Ajouter un cluster d\\'hyperviseurs g\u00e9r\u00e9 pour cette zone message.add.disk.offering=Renseignez les param\u00e8tres suivants pour ajouter un offre de service de disques @@ -1287,8 +1590,8 @@ message.add.network=Ajouter un nouveau r\u00e9seau \u00e0 la zone\: message.add.pod.during.zone.creation=Chaque zone doit contenir un ou plusieurs pods, et le premier pod sera ajout\u00e9 maintenant. Une pod contient les h\u00f4tes et les serveurs de stockage primaire, qui seront ajout\u00e9s dans une \u00e9tape ult\u00e9rieure. Configurer une plage d\\'adresses IP r\u00e9serv\u00e9es pour le trafic de gestion interne de CloudStack. La plage d\\'IP r\u00e9serv\u00e9e doit \u00eatre unique pour chaque zone dans le nuage. -message.add.primary=Renseignez les param\u00e8tres suivants pour ajouter un stockage principal -message.add.primary.storage=Ajouter un nouveau stockage principal \u00e0 la zone , pod +message.add.primary=Renseignez les param\u00e8tres suivants pour ajouter un stockage primaire +message.add.primary.storage=Ajouter un nouveau stockage primaire \u00e0 la zone , pod message.add.region=Renseigner les informations suivantes pour ajouter une nouvelle r\u00e9gion. message.add.secondary.storage=Ajouter un nouveau stockage pour la zone message.add.service.offering=Renseigner les informations suivantes pour ajouter une nouvelle offre de service de calcul. @@ -1296,6 +1599,7 @@ message.add.system.service.offering=Ajouter les informations suivantes pour cr\u message.add.template=Renseignez les informations suivantes pour cr\u00e9er votre nouveau mod\u00e8le message.add.volume=Renseignez les informations suivantes pour ajouter un nouveau volume message.add.VPN.gateway=Confirmer l\\'ajout d\\'une passerelle VPN +message.admin.guide.read=Pour les VMs VMware, veuillez lire le paragraphe "dynamic scaling" dans le guide d\\'administration avant d\\'op\u00e9rer un dimensionnement. Voulez-vous continuer ?\\, message.advanced.mode.desc=Choisissez ce mod\u00e8le de r\u00e9seau si vous souhaitez b\u00e9n\u00e9ficier du support des VLANs. Ce mode de r\u00e9seau donne le plus de flexibilit\u00e9 aux administrateurs pour fournir des offres de service r\u00e9seau personnalis\u00e9es comme fournir des pare-feux, VPN, r\u00e9partiteurs de charge ou \u00e9galement activer des r\u00e9seaux virtuels ou directs. message.advanced.security.group=Choisissez ceci si vous souhaitez utiliser les groupes de s\u00e9curit\u00e9 pour fournir l\\'isolation des VMs invit\u00e9es. message.advanced.virtual=Choisissez ceci si vous souhaitez utiliser des VLANs pour fournir l\\'isolation des VMs invit\u00e9es. @@ -1304,61 +1608,104 @@ message.after.enable.swift=Swift configur\u00e9. Remarque \: une fois que vous q message.alert.state.detected=\u00c9tat d\\'alerte d\u00e9tect\u00e9 message.allow.vpn.access=Entrez un nom d\\'utilisateur et un mot de passe pour l\\'utilisateur que vous souhaitez autoriser \u00e0 utiliser l\\'acc\u00e8s VPN. message.apply.snapshot.policy=Vous avez mis \u00e0 jour votre politique d\\'instantan\u00e9s avec succ\u00e8s. -message.attach.iso.confirm=\u00cates-vous s\u00fbr que vous souhaitez attacher l\\'image ISO \u00e0 cette instance. +message.attach.iso.confirm=Attacher l\\'image ISO \u00e0 cette instance ? message.attach.volume=Renseignez les donn\u00e9es suivantes pour attacher un nouveau volume. Si vous attachez un volume disque \u00e0 une machine virtuelle sous Windows, vous aurez besoin de red\u00e9marrer l\\'instance pour voir le nouveau disque. message.basic.mode.desc=Choisissez ce mod\u00e8le de r\u00e9seau si vous *ne voulez pas* activer le support des VLANs. Toutes les instances cr\u00e9\u00e9es avec ce mod\u00e8le de r\u00e9seau se verront assigner une adresse IP et les groupes de s\u00e9curit\u00e9 seront utilis\u00e9s pour fournir l\\'isolation entre les VMs. -message.change.offering.confirm=\u00cates-vous s\u00fbr que vous souhaitez changer l\\'offre de service de cette instance. +message.change.offering.confirm=Changer l\\'offre de service de cette instance ? message.change.password=Merci de modifier votre mot de passe. +message.cluster.dedicated=Cluster d\u00e9di\u00e9e +message.cluster.dedication.released=Lib\u00e9ration de cluster d\u00e9di\u00e9 message.configure.all.traffic.types=Vous avez de multiples r\u00e9seaux physiques ; veuillez configurer les libell\u00e9s pour chaque type de trafic en cliquant sur le bouton Modifier. +message.configure.ldap=Confirmer la configuration LDAP message.configuring.guest.traffic=Configuration du r\u00e9seau VM message.configuring.physical.networks=Configuration des r\u00e9seaux physiques message.configuring.public.traffic=Configuration du r\u00e9seau public message.configuring.storage.traffic=Configuration du r\u00e9seau de stockage message.confirm.action.force.reconnect=Confirmer la re-connexion forc\u00e9e de cet h\u00f4te. +message.confirm.add.vnmc.provider=Confirmer l\\'ajout du fournisseur VNMC. +message.confirm.dedicate.cluster.domain.account=D\u00e9dier ce cluster \u00e0 un domaine/compte ? +message.confirm.dedicate.host.domain.account=D\u00e9dier cet h\u00f4te \u00e0 un domaine/compte ? +message.confirm.dedicate.pod.domain.account=D\u00e9dier ce pod \u00e0 un domaine/compte ? +message.confirm.dedicate.zone=\u00cates-vous s\u00fbr de d\u00e9dier cette zone \u00e0 un domaine/compte ? +message.confirm.delete.ciscovnmc.resource=Confirmer la suppression de la ressource CiscoVNMC message.confirm.delete.F5=Confirmer la suppression du F5 message.confirm.delete.NetScaler=Confirmer la suppression du Netscaler +message.confirm.delete.PA=Confirmer la suppression du Palo Alto +message.confirm.delete.secondary.staging.store=Confirmer que vous voulez supprimer le Stockage Secondaire Interm\u00e9diaire. message.confirm.delete.SRX=Confirmer la suppression du SRX +message.confirm.delete.ucs.manager=Confirmez que vous voulez supprimer le gestionnaire UCS message.confirm.destroy.router=\u00cates-vous s\u00fbr que vous voulez supprimer ce routeur +message.confirm.disable.network.offering=Voulez-vous d\u00e9sactiver cette offre r\u00e9seau ? message.confirm.disable.provider=Confirmer la d\u00e9sactivation de ce fournisseur +message.confirm.disable.vnmc.provider=Confirmer la d\u00e9sactivation du fournisseur VNMC. +message.confirm.disable.vpc.offering=Voulez-vous d\u00e9sactiver cette offre VPC ? +message.confirm.enable.network.offering=Voulez-vous activer cette offre r\u00e9seau ? message.confirm.enable.provider=Confirmer l\\'activation de ce fournisseur -message.confirm.join.project=\u00cates-vous s\u00fbr que vous souhaitez rejoindre ce projet. +message.confirm.enable.vnmc.provider=Confirmer l\\'activation du fournisseur VNMC. +message.confirm.enable.vpc.offering=Voulez-vous activer cette offre VPC ? +message.confirm.join.project=Rejoindre ce projet ? +message.confirm.refresh.blades=Confirmer que vous voulez rafra\u00eechr les lames. +message.confirm.release.dedicated.cluster=Lib\u00e9rer ce cluster d\u00e9di\u00e9 ? +message.confirm.release.dedicated.host=Lib\u00e9rer cet h\u00f4te d\u00e9di\u00e9e ? +message.confirm.release.dedicated.pod=Lib\u00e9rer ce pod d\u00e9di\u00e9 ? +message.confirm.release.dedicated.zone=Lib\u00e9rer cette zone d\u00e9di\u00e9e ? +message.confirm.release.dedicate.vlan.range=Confirmez que vous souhaitez lib\u00e9rer cette plage VLAN d\u00e9di\u00e9e. message.confirm.remove.IP.range=\u00cates-vous s\u00fbr que vous voulez supprimer cette plage d\\'adresses IP +message.confirm.remove.network.offering=Voulez-vous supprimer cette offre r\u00e9seau ? +message.confirm.remove.vmware.datacenter=Veuillez confirmer que vous voulez supprimer le datacenter VMware +message.confirm.remove.vpc.offering=Voulez-vous supprimer cette offre VPC ? +message.confirm.scale.up.router.vm=Agrandir la VM Routeur ? +message.confirm.scale.up.system.vm=Agrandir la VM Syst\u00e8me ? message.confirm.shutdown.provider=Confirmer l\\'arr\u00eat de ce fournisseur -message.copy.iso.confirm=\u00cates-vous s\u00fbr que vous souhaitez copier votre image ISO vers +message.confirm.start.lb.vm=Confirmez que vous souhaitez d\u00e9marrer ce LB VM. +message.confirm.stop.lb.vm=Confirmez que vous souhaitez arr\u00eater ce LB VM. +message.confirm.upgrade.router.newer.template=Confirmez que vous souhaitez mettre \u00e0 jour le routeur avec un mod\u00e8le plus r\u00e9cent. +message.confirm.upgrade.routers.account.newtemplate=Confirmez que vous souhaitez mettre \u00e0 jour tous les routeurs dans ce compte avec un mod\u00e8le plus r\u00e9cent. +message.confirm.upgrade.routers.cluster.newtemplate=Confirmez que vous souhaitez mettre \u00e0 jour tous les routeurs dans ce cluster avec un mod\u00e8le plus r\u00e9cent. +message.confirm.upgrade.routers.newtemplate=Confirmez que vous souhaitez mettre \u00e0 jour tous les routeurs dans cette zone avec un mod\u00e8le plus r\u00e9cent. +message.confirm.upgrade.routers.pod.newtemplate=Confirmez que vous souhaitez mettre \u00e0 jour tous les routeurs dans ce pod avec un mod\u00e8le plus r\u00e9cent. +message.copy.iso.confirm=Copier votre image ISO vers +message.copy.template.confirm=Voulez-vous copier le mod\u00e8le ? message.copy.template=Copier le mod\u00e8le XXX de la zone vers message.create.template.vm=Cr\u00e9er la VM depuis le mod\u00e8le message.create.template.volume=Renseignez les informations suivantes avec de cr\u00e9er un mod\u00e8le \u00e0 partir de votre volume de disque\:. La cr\u00e9ation du mod\u00e8le peut prendre plusieurs minutes suivant la taille du volume. -message.create.template=Voulez vous cr\u00e9er un mod\u00e8le ? +message.create.template=Voulez-vous cr\u00e9er un mod\u00e8le ? message.creating.cluster=Cr\u00e9ation du cluster message.creating.guest.network=Cr\u00e9ation du r\u00e9seau pour les invit\u00e9s message.creating.physical.networks=Cr\u00e9ation des r\u00e9seaux physiques message.creating.pod=Cr\u00e9ation d\\'un pod -message.creating.primary.storage=Cr\u00e9ation du stockage principal +message.creating.primary.storage=Cr\u00e9ation du stockage primaire message.creating.secondary.storage=Cr\u00e9ation du stockage secondaire +message.creating.systemVM=Cr\u00e9ation des VMs Syst\u00e8mes (peut prendre du temps)... message.creating.zone=Cr\u00e9ation de la zone message.decline.invitation=Voulez-vous refuser cette invitation au projet ? -message.delete.account=\u00cates-vous s\u00fbr que vous souhaitez supprimer ce compte. +message.dedicated.zone.released=Lib\u00e9ration de zone d\u00e9di\u00e9e +message.dedicate.zone=Zone d\u00e9di\u00e9e +message.delete.account=Supprimer ce compte ? message.delete.affinity.group=Confirmer la supression de ce groupe d\\'affinit\u00e9. message.delete.gateway=\u00cates-vous s\u00fbr que vous voulez supprimer cette passerelle -message.delete.project=\u00cates-vous s\u00fbr de vouloir supprimer ce projet ? +message.delete.project=Voulez-vous supprimer ce projet ? message.delete.user=\u00cates-vous s\u00fbr que vous voulez supprimer cet utilisateur. message.delete.VPN.connection=\u00cates-vous s\u00fbr que vous voulez supprimer la connexion VPN message.delete.VPN.customer.gateway=\u00cates-vous s\u00fbr que vous voulez supprimer cette passerelle VPN client message.delete.VPN.gateway=\u00cates-vous s\u00fbr que vous voulez supprimer cette passerelle VPN message.desc.advanced.zone=Pour des topologies de r\u00e9seau plus sophistiqu\u00e9es. Ce mod\u00e8le de r\u00e9seau permet plus de flexibilit\u00e9 dans la d\u00e9finition des r\u00e9seaux d\\'invit\u00e9s et propose des offres personnalis\u00e9es telles que le support de pare-feu, VPN ou d\\'\u00e9quilibrage de charge. message.desc.basic.zone=Fournit un r\u00e9seau unique o\u00f9 chaque instance de machine virtuelle se voit attribuer une adresse IP directement depuis le r\u00e9seau. L\\'isolation des invit\u00e9s peut \u00eatre assur\u00e9 au niveau de la couche r\u00e9seau-3 tels que les groupes de s\u00e9curit\u00e9 (filtrage d\\'adresse IP source). -message.desc.cluster=Chaque pod doit contenir un ou plusieurs clusters, et le premier cluster sera ajout\u00e9 tout de suite. Un cluster est un regroupement pour h\u00f4tes. Les h\u00f4tes d\\'un cluster ont tous un mat\u00e9riel identique, ex\u00e9cutent le m\u00eame hyperviseur, sont dans le m\u00eame sous-r\u00e9seau, et acc\u00e8dent au m\u00eame stockage partag\u00e9. Chaque cluster comprend une ou plusieurs h\u00f4tes et un ou plusieurs serveurs de stockage principal. +message.desc.cluster=Chaque pod doit contenir un ou plusieurs clusters, et le premier cluster sera ajout\u00e9 tout de suite. Un cluster est un regroupement pour h\u00f4tes. Les h\u00f4tes d\\'un cluster ont tous un mat\u00e9riel identique, ex\u00e9cutent le m\u00eame hyperviseur, sont dans le m\u00eame sous-r\u00e9seau, et acc\u00e8dent au m\u00eame stockage partag\u00e9. Chaque cluster comprend une ou plusieurs h\u00f4tes et un ou plusieurs serveurs de stockage primaire. message.desc.host=Chaque cluster doit contenir au moins un h\u00f4te (machine) pour ex\u00e9ctuer des machines virtuelles invit\u00e9es, et le premier h\u00f4te sera ajout\u00e9e maintenant. Pour un h\u00f4te fonctionnant dans CloudStack, vous devez installer un logiciel hyperviseur sur l\\'h\u00f4te, attribuer une adresse IP \u00e0 l\\'h\u00f4te, et s\\'assurer que l\\'h\u00f4te est connect\u00e9 au serveur d\\'administration CloudStack.

Indiquer le nom de l\\'h\u00f4te ou son adresse IP, l\\'identifiant de connexion (g\u00e9n\u00e9ralement root) et le mot de passe ainsi que toutes les \u00e9tiquettes permettant de classer les h\u00f4tes. -message.desc.primary.storage=Chaque cluster doit contenir un ou plusieurs serveurs de stockage principal, et le premier sera ajout\u00e9 tout de suite. Le stockage principal contient les volumes de disque pour les machines virtuelles s\\'ex\u00e9cutant sur les h\u00f4tes dans le cluster. Utiliser les protocoles standards pris en charge par l\\'hyperviseur sous-jacent. +message.desc.primary.storage=Chaque cluster doit contenir un ou plusieurs serveurs de stockage primaire, et le premier sera ajout\u00e9 tout de suite. Le stockage principal contient les volumes de disque pour les machines virtuelles s\\'ex\u00e9cutant sur les h\u00f4tes dans le cluster. Utiliser les protocoles standards pris en charge par l\\'hyperviseur sous-jacent. message.desc.secondary.storage=Chaque zone doit avoir au moins un serveur NFS ou un serveur de stockage secondaire, et sera ajout\u00e9 en premier tout de suite. Le stockage secondaire entrepose les mod\u00e8les de machines virtuelles, les images ISO et les images disques des volumes des machines virtuelles. Ce serveur doit \u00eatre accessible pour toutes les machines h\u00f4tes dans la zone.

Saisir l\\'adresse IP et le chemin d\\'export. -message.desc.zone=Une zone est la plus grande unit\u00e9 organisationnelle dans CloudStack, et correspond typiquement \u00e0 un centre de donn\u00e9es. Les zones fournissent un isolement physique et de la redondance. Une zone est constitu\u00e9e d\\'un ou plusieurs pods (dont chacun contient les h\u00f4tes et les serveurs de stockage principal) et un serveur de stockage secondaire qui est partag\u00e9e par tous les pods dans la zone. +message.desc.zone=Une zone est la plus grande unit\u00e9 organisationnelle dans CloudStack, et correspond typiquement \u00e0 un centre de donn\u00e9es. Les zones fournissent un isolement physique et de la redondance. Une zone est constitu\u00e9e d\\'un ou plusieurs pods (dont chacun contient les h\u00f4tes et les serveurs de stockage primaire) et un serveur de stockage secondaire qui est partag\u00e9e par tous les pods dans la zone. message.detach.disk=Voulez-vous d\u00e9tacher ce disque ? -message.detach.iso.confirm=\u00cates-vous s\u00fbr que vous souhaitez d\u00e9tacher l\\'image ISO de cette instance. +message.detach.iso.confirm=D\u00e9tacher l\\'image ISO de cette instance ? message.disable.account=Veuillez confirmer que vous voulez d\u00e9sactiver ce compte. En d\u00e9sactivant le compte, tous les utilisateurs pour ce compte n\\'auront plus acc\u00e8s \u00e0 leurs ressources sur le cloud. Toutes les machines virtuelles vont \u00eatre arr\u00eat\u00e9es imm\u00e9diatement. message.disable.snapshot.policy=Vous avez d\u00e9sactiv\u00e9 votre politique d\\'instantan\u00e9 avec succ\u00e8s. message.disable.user=Confirmer la d\u00e9sactivation de cet utilisateur. -message.disable.vpn.access=\u00cates-vous s\u00fbr que vous souhaitez d\u00e9sactiver l\\'acc\u00e8s VPN. -message.disable.vpn=\u00cates-vous s\u00fbr de vouloir d\u00e9sactiver le VPN ? +message.disable.vpn.access=D\u00e9sactiver l\\'acc\u00e8s VPN ? +message.disable.vpn=Voulez-vous d\u00e9sactiver le VPN ? +message.disabling.network.offering=D\u00e9sactivation de l\\'offre r\u00e9seau +message.disabling.vpc.offering=D\u00e9sactivation de l\\'offre VPC +message.disallowed.characters=Caract\u00e8res non autoris\u00e9s \: \\<\\,\\> message.download.ISO=Cliquer 00000 pour t\u00e9l\u00e9charger une image ISO message.download.template=Cliquer sur 00000 pour t\u00e9l\u00e9charger le mod\u00e8le message.download.volume=Cliquer sur 00000 pour t\u00e9l\u00e9charger le volume @@ -1367,25 +1714,33 @@ message.edit.account=Modifier ("-1" signifie pas de limite de ressources) message.edit.confirm=Confirmer les changements avant de cliquer sur "Enregistrer". message.edit.limits=Renseignez les limites pour les ressources suivantes. "-1" indique qu\\'il n\\'y a pas de limites pour la cr\u00e9ation de ressources. message.edit.traffic.type=Sp\u00e9cifier le libell\u00e9 de trafic associ\u00e9 avec ce type de trafic. -message.enable.account=\u00cates-vous s\u00fbr que vous souhaitez activer ce compte. +message.enable.account=Activer ce compte ? message.enabled.vpn.ip.sec=Votre cl\u00e9 partag\u00e9e IPSec est message.enabled.vpn=Votre acc\u00e8s VPN est activ\u00e9 et peut \u00eatre acc\u00e9d\u00e9 par l\\'IP message.enable.user=Confirmer l\\'activation de cet utilisateur. message.enable.vpn.access=Le VPN est d\u00e9sactiv\u00e9 pour cette adresse IP. Voulez vous activer l\\'acc\u00e8s VPN ? message.enable.vpn=Confirmer l\\'activation de l\\'acc\u00e8s VPN pour cette adresse IP. +message.enabling.network.offering=Activation de l\\'offre r\u00e9seau message.enabling.security.group.provider=Activation du fournisseur de groupe de s\u00e9curit\u00e9 +message.enabling.vpc.offering=Activation de l\\'offre VPC message.enabling.zone=Activation de la zone +message.enabling.zone.dots=Activation de la zone... +message.enter.seperated.list.multiple.cidrs=Veuillez entrer une liste de CIDRs s\u00e9par\u00e9s par des virgules si plusieurs message.enter.token=Entrer le jeton unique re\u00e7u dans le message d\\'invitation. message.generate.keys=Confirmer la g\u00e9n\u00e9ration de nouvelles clefs pour cet utilisateur. +message.gslb.delete.confirm=Confirmer la suppression de ce GSLB +message.gslb.lb.remove.confirm=Enlever la r\u00e9partition de charge du GSLB ? message.guest.traffic.in.advanced.zone=Le trafic r\u00e9seau d\\'invit\u00e9 est la communication entre les machines virtuelles utilisateur. Sp\u00e9cifier une plage d\\'identifiant VLAN pour le trafic des invit\u00e9s pour chaque r\u00e9seau physique. message.guest.traffic.in.basic.zone=Le trafic r\u00e9seau d\\'invit\u00e9 est la communication entre les machines virtuelles utilisateur. Sp\u00e9cifier une plage d\\'adresses IP que CloudStack peut assigner aux machines virtuelles Invit\u00e9. S\\'assurer que cette plage n\\'empi\u00e8te pas sur la plage r\u00e9serv\u00e9e aux adresses IP Syst\u00e8me. +message.host.dedicated=H\u00f4te d\u00e9di\u00e9e +message.host.dedication.released=Lib\u00e9ration de l\\'h\u00f4te d\u00e9di\u00e9 message.installWizard.click.retry=Appuyer sur le bouton pour essayer \u00e0 nouveau le d\u00e9marrage. message.installWizard.copy.whatIsACluster=Un cluster permet de grouper les h\u00f4tes. Les h\u00f4tes d\\'un cluster ont un mat\u00e9riel identique, ex\u00e9cutent le m\u00eame hyperviseur, sont sur le m\u00eame sous-r\u00e9seau, et acc\u00e8dent au m\u00eame stockage partag\u00e9. Les instances de machines virtuelles (VM) peuvent \u00eatre migr\u00e9es \u00e0 chaud d\\'un h\u00f4te \u00e0 un autre au sein du m\u00eame groupe, sans interrompre les services utilisateur. Un cluster est la trois \u00e8me plus large unit\u00e9 organisationnelle dans un d\u00e9ploiement CloudStack&\#8482;. Les clusters sont contenus dans les pods et les pods sont contenus dans les zones.

CloudStack&\#8482; permet d\\'avoir plusieurs clusters dans un d\u00e9ploiement en nuage, mais pour une installation basique, il n\\'y a qu\\'un seul cluster. message.installWizard.copy.whatIsAHost=Un h\u00f4te est une machine. Les h\u00f4tes fournissent les ressources informatiques qui ex\u00e9cutent les machines virtuelles invit\u00e9es. Chaque h\u00f4te a un logiciel hyperviseur install\u00e9 pour g\u00e9rer les machines virtuelles invit\u00e9es (sauf pour les h\u00f4tes de type \\'bare-metal\\', qui sont un cas particulier d\u00e9taill\u00e9 dans le Guide d\\'installation avanc\u00e9e). Par exemple, un serveur Linux avec KVM, un serveur Citrix XenServer, et un serveur ESXi sont des h\u00f4tes. Dans une installation basique, un seul h\u00f4te ex\u00e9cutant XenServer ou KVM est utilis\u00e9.

L\\'h\u00f4te est la plus petite unit\u00e9 organisation au sein d\\'un d\u00e9ploiement CloudStack&\#8482;. Les h\u00f4tes sont contenus dans les clusters, les clusters sont contenus dans les pods et les pods sont contenus dans les zones. message.installWizard.copy.whatIsAPod=Un pod repr\u00e9sente souvent un seul rack. Les h\u00f4tes dans le m\u00eame pod sont dans le m\u00eame sous-r\u00e9seau.
Un pod est la deuxi\u00e8me plus grande unit\u00e9 organisationnelle au sein d\\'un d\u00e9ploiement CloudStack&\#8482;. Les pods sont contenus dans les zones. Chaque zone peut contenir un ou plusieurs pods ; dans l\\'Installation Basique, vous aurez juste un pod dans votre zone. message.installWizard.copy.whatIsAZone=Une zone est la plus grande unit\u00e9 organisationnelle au sein d\\'un d\u00e9ploiement CloudStack&\#8482;. Une zone correspond typiquement \u00e0 un centre de donn\u00e9es, mais il est permis d\\'avoir plusieurs zones dans un centre de donn\u00e9es. L\\'avantage d\\'organiser une infrastructure en zones est de fournir une isolation physique et de la redondance. Par exemple, chaque zone peut avoir sa propre alimentation et de liaison avec le r\u00e9seau, et les zones peuvent \u00eatre tr\u00e8s \u00e9loign\u00e9es g\u00e9ographiquement (m\u00eame si ce n\\'est pas une obligation). message.installWizard.copy.whatIsCloudStack=CloudStack&\#8482; est une plate-forme logicielle de pools de ressources informatiques pour construire des infrastructures publiques, priv\u00e9es et hybrides en tant que services (IaaS) dans les nuages. CloudStack&\#8482; g\u00e8re le r\u00e9seau, le stockage et les noeuds de calcul qui composent une infrastructure dans les nuages. Utilisez CloudStack&\#8482; pour d\u00e9ployer, g\u00e9rer et configurer les environnements d\\'informatiques dans les nuages.

S\\'\u00e9tendant au-del\u00e0 des machines virtuelles individuelles fonctionnant sur du mat\u00e9riel standard, CloudStack&\#8482; offre une solution d\\'informatique en nuage cl\u00e9 en main pour fournir des centres de donn\u00e9es virtuels comme service - fournissant tous les composants essentiels pour construire, d\u00e9ployer et g\u00e9rer des applications \\'cloud\\' multi-niveaux et multi-locataire. Les versions libre et Premium sont disponibles, la version Libre offrant des caract\u00e9ristiques presque identiques. -message.installWizard.copy.whatIsPrimaryStorage=Une infrastructure CloudStack&\#8482; utilise deux types de stockage \: stockage principal et stockage secondaire. Les deux peuvent \u00eatre des serveurs iSCSI ou NFS, ou sur disque local.

Le stockage principal est associ\u00e9 \u00e0 un cluster, et stocke les volumes disques de chaque machine virtuelle pour toutes les VMs s\\'ex\u00e9cutant sur les h\u00f4tes dans le cluster. Le serveur de stockage principal est typiquement proche des h\u00f4tes. +message.installWizard.copy.whatIsPrimaryStorage=Une infrastructure CloudStack&\#8482; utilise deux types de stockage \: stockage primaire et stockage secondaire. Les deux peuvent \u00eatre des serveurs iSCSI ou NFS, ou sur disque local.

Le stockage principal est associ\u00e9 \u00e0 un cluster, et stocke les volumes disques de chaque machine virtuelle pour toutes les VMs s\\'ex\u00e9cutant sur les h\u00f4tes dans le cluster. Le serveur de stockage primaire est typiquement proche des h\u00f4tes. message.installWizard.copy.whatIsSecondaryStorage=Le stockage secondaire est associ\u00e9 \u00e0 une zone, et il stocke les \u00e9l\u00e9ments suivants\:
  • Mod\u00e8les - images de syst\u00e8mes d\\'exploitation qui peuvent \u00eatre utilis\u00e9es pour d\u00e9marrer les machines virtuelles et peuvent inclure des informations de configuration suppl\u00e9mentaires, telles que les applications pr\u00e9-install\u00e9es
  • Images ISO - images de syst\u00e8me d\\'exploitation ou d\\'installation d\\'OS qui peuvent \u00eatre amor\u00e7able ou non-amor\u00e7able
  • Images de volume disque - capture des donn\u00e9es de machines virtuelles qui peuvent \u00eatre utilis\u00e9es pour la r\u00e9cup\u00e9ration des donn\u00e9es ou cr\u00e9er des mod\u00e8les
message.installWizard.now.building=Construction de votre Cloud en cours message.installWizard.tooltip.addCluster.name=Un nom pour le cluster. Ce choix est libre et n\\'est pas utilis\u00e9 par CloudStack. @@ -1398,7 +1753,7 @@ message.installWizard.tooltip.addPod.reservedSystemGateway=Passerelle pour les s message.installWizard.tooltip.addPod.reservedSystemNetmask=Le masque r\u00e9seau que les instances utiliseront sur le r\u00e9seau message.installWizard.tooltip.addPod.reservedSystemStartIp=Ceci est la plage d\\'adresses IP dans le r\u00e9seau priv\u00e9 que CloudStack utilise la gestion des VMs du stockage secondaire et les VMs Console Proxy. Ces adresses IP sont prises dans le m\u00eame sous-r\u00e9seau que les serveurs h\u00f4tes. message.installWizard.tooltip.addPrimaryStorage.name=Nom pour ce stockage -message.installWizard.tooltip.addPrimaryStorage.path=(pour NFS) Dans NFS, ceci est le chemin d\\'export depuis le serveur. (pour SharedMountPoint) Le chemin. Avec KVM, c\\'est le chemin sur chaque h\u00f4te o\u00f9 ce stockage principal est mont\u00e9. Par exemple, "/mnt/primary". +message.installWizard.tooltip.addPrimaryStorage.path=(pour NFS) Dans NFS, ceci est le chemin d\\'export depuis le serveur. (pour SharedMountPoint) Le chemin. Avec KVM, c\\'est le chemin sur chaque h\u00f4te o\u00f9 ce stockage primaire est mont\u00e9. Par exemple, "/mnt/primary". message.installWizard.tooltip.addPrimaryStorage.server=(pour NFS, iSCSI ou PreSetup) Adresse IP ou nom DNS du stockage message.installWizard.tooltip.addSecondaryStorage.nfsServer=Adresse IP du serveur NFS supportant le stockage secondaire message.installWizard.tooltip.addSecondaryStorage.path=Le chemin export\u00e9, situ\u00e9 sur le serveur sp\u00e9cifi\u00e9 pr\u00e9c\u00e9demment @@ -1413,21 +1768,26 @@ message.installWizard.tooltip.configureGuestTraffic.guestGateway=La passerelle q message.installWizard.tooltip.configureGuestTraffic.guestNetmask=Le masque r\u00e9seau que les instances devrait utiliser sur le r\u00e9seau message.installWizard.tooltip.configureGuestTraffic.guestStartIp=La plage d\\'adresses IP qui sera disponible en allocation pour les machines invit\u00e9es dans cette zone. Si une carte r\u00e9seau est utilis\u00e9e, ces adresses IP peuvent \u00eatre dans le m\u00eame CIDR que le CIDR du pod. message.installWizard.tooltip.configureGuestTraffic.name=Nom pour ce r\u00e9seau +message.instance.scaled.up.confirm=\u00cates-vous s\u00fbr de vouloir agrandir votre instance ? message.instanceWizard.noTemplates=Vous n\\'avez pas de image disponible ; Ajouter un mod\u00e8le compatible puis relancer l\\'assistant de cr\u00e9ation d\\'instance. message.ip.address.changed=Vos adresses IP ont peut \u00eatre chang\u00e9es ; Voulez vous rafra\u00eechir la liste ? Dans ce cas, le panneau de d\u00e9tail se fermera. message.iso.desc=Image disque contenant des donn\u00e9es ou un support amor\u00e7able pour OS message.join.project=Vous avez rejoint un projet. S\u00e9lectionnez la vue Projet pour le voir. message.launch.vm.on.private.network=Souhaitez vous d\u00e9marrer cette instance sur votre propre r\u00e9seau priv\u00e9 ? message.launch.zone=La zone est pr\u00eate \u00e0 d\u00e9marrer ; passer \u00e0 l\\'\u00e9tape suivante. -message.lock.account=\u00cates-vous s\u00fbr que vous souhaitez verrouiller ce compte. En le verrouillant, les utilisateurs de ce compte ne seront plus capables de g\u00e9rer leurs ressources. Les ressources existantes resteront toutefois accessibles. +message.listView.subselect.multi=(Ctrl/Cmd-clic) +message.lock.account=Verrouiller ce compte ? En le verrouillant, les utilisateurs de ce compte ne seront plus capables de g\u00e9rer leurs ressources. Les ressources existantes resteront toutefois accessibles. message.migrate.instance.confirm=Confirmez l\\'h\u00f4te vers lequel vous souhaitez migrer cette instance message.migrate.instance.to.host=Confirmer la migration de l\\'instance vers un autre h\u00f4te -message.migrate.instance.to.ps=Confirmer la migration de l\\'instance vers un autre stockage principal +message.migrate.instance.to.ps=Confirmer la migration de l\\'instance vers un autre stockage primaire message.migrate.router.confirm=Confirmer la migration du routeur vers \: message.migrate.systemvm.confirm=Confirmer la migration de la VM syst\u00e8me vers \: -message.migrate.volume=Confirmer la migration du volume vers un autre stockage principal. +message.migrate.volume=Confirmer la migration du volume vers un autre stockage primaire. +message.network.addVM.desc=Veuillez sp\u00e9cifier le r\u00e9seau que vous souhaitez ajouter \u00e0 cette VM. Une nouvelle interface NIC sera ajout\u00e9e pour ce r\u00e9seau. +message.network.addVMNIC=Confirmer l\\'ajout d\\'une nouvelle NIC VM pour ce r\u00e9seau. message.new.user=Renseigner les informations suivantes pour ajouter un nouveau compte utilisateur message.no.affinity.groups=Vous n\\'avez pas de groupes d\\'affinit\u00e9. Continuer vers la prochaine \u00e9tape. +message.no.host.available=Aucun h\u00f4te n\\'est disponible pour la migration message.no.network.support.configuration.not.true=Il n\\'y a pas de zone avec la fonction groupe de s\u00e9curit\u00e9 active. D\u00e8s lors, pas de fonction r\u00e9seau suppl\u00e9mentaires disponibles. Continuer \u00e0 l\\'\u00e9tape 5. message.no.network.support=S\u00e9lectionnez l\\'hyperviseur. vSphere, n\\'a pas de fonctionnalit\u00e9s suppl\u00e9mentaires pour le r\u00e9seau. Continuez \u00e0 l\\'\u00e9tape 5. message.no.projects.adminOnly=Vous n\\'avez pas de projet.
Contacter votre administrateur pour ajouter un projet. @@ -1435,7 +1795,7 @@ message.no.projects=Vous n\\'avez pas de projet.
Vous pouvez en cr\u00e9er u message.number.clusters=

\# de Clusters

message.number.hosts=

\# d\\' H\u00f4tes

message.number.pods=

\# de Pods

-message.number.storage=

\# de Volumes de Stockage Principal

+message.number.storage=

\# de Volumes de Stockage Primaire

message.number.zones=

\# de Zones

message.pending.projects.1=Vous avez des invitations projet en attente \: message.pending.projects.2=Pour les visualiser, aller dans la section projets, puis s\u00e9lectionner invitation dans la liste d\u00e9roulante. @@ -1445,13 +1805,19 @@ message.please.select.a.configuration.for.your.zone=S\u00e9lectionner une config message.please.select.a.different.public.and.management.network.before.removing=S\u00e9lectionner un r\u00e9seau public et d\\'administration diff\u00e9rent avant de supprimer message.please.select.networks=S\u00e9lectionner les r\u00e9seaux pour votre machine virtuelle. message.please.wait.while.zone.is.being.created=Patienter pendant la cr\u00e9ation de la zone, cela peut prendre du temps... +message.pod.dedication.released=Lib\u00e9ration du pod d\u00e9di\u00e9 +message.portable.ip.delete.confirm=Supprimer la plage IP portable ? message.project.invite.sent=Invitation envoy\u00e9e ; les utilisateurs seront ajout\u00e9s apr\u00e8s acceptation de l\\'invitation message.public.traffic.in.advanced.zone=Le trafic public est g\u00e9n\u00e9r\u00e9 lorsque les machines virtuelles dans le nuage acc\u00e8dent \u00e0 Internet. Des adresses IP publiquement accessibles doivent \u00eatre pr\u00e9vues \u00e0 cet effet. Les utilisateurs peuvent utiliser l\\'interface d\\'administration de CloudStack pour acqu\u00e9rir ces adresses IP qui impl\u00e9menteront une translation d\\'adresse NAT entre le r\u00e9seau d\\'invit\u00e9 et le r\u00e9seau public.

Fournir au moins une plage d\\'adresses IP pour le trafic Internet. message.public.traffic.in.basic.zone=Le trafic public est g\u00e9n\u00e9r\u00e9 lorsque les machines virtuelles dans le nuage acc\u00e8dent \u00e0 Internet ou fournissent des services \u00e0 des utilisateurs sur Internet. Des adresses IP publiquement accessibles doivent \u00eatre pr\u00e9vus \u00e0 cet effet. Quand une instance est cr\u00e9\u00e9e, une adresse IP publique depuis un ensemble d\\'adresses IP publiques sera allou\u00e9e \u00e0 l\\'instance, en plus de l\\'adresse IP de l\\'invit\u00e9. La translation d\\'adresses statique NAT 1-1 sera mises en place automatiquement entre l\\'adresse IP publique et l\\'adresse IP de l\\'invit\u00e9. Les utilisateurs peuvent \u00e9galement utiliser l\\'interface d\\'administration CloudStack pour acqu\u00e9rir des adresses IP suppl\u00e9mentaires pour ajouter une translation d\\'adresse statique NAT entre leurs instances et le r\u00e9seau d\\'adresses IP publiques. +message.read.admin.guide.scaling.up=Veuillez lire le paragraphe "dynamic scaling" dans le guide d\\'administration avant d\\'op\u00e9rer un dimensionnement dynamique. +message.recover.vm=Confirmer la restauration de cette VM. message.redirecting.region=Redirection vers r\u00e9gion... -message.remove.region=Confirmer que vous souhaitez supprimer cette r\u00e9gion depuis ce serveur d\\'administration ? +message.reinstall.vm=NOTE\: Proc\u00e9dez avec prudence. Cela entra\u00eenera la r\u00e9-installation de la VM \u00e0 partir du mod\u00e8le; les donn\u00e9es sur le disque ROOT seront perdues. Les volumes de donn\u00e9es suppl\u00e9mentaires, le cas \u00e9ch\u00e9ant, ne seront pas touch\u00e9s. +message.remove.ldap=Voulez-vous supprimer la configuration LDAP ? +message.remove.region=Voulez-vous supprimer cette r\u00e9gion depuis ce serveur d\\'administration ? message.remove.vpc=Confirmer la suppression du VPC -message.remove.vpn.access=\u00cates-vous s\u00fbr que vous souhaitez supprimer l\\'acc\u00e8s VPN \u00e0 l\\'utilisateur suivant. +message.remove.vpn.access=Supprimer l\\'acc\u00e8s VPN de cet utilisateur ? message.reset.password.warning.notPasswordEnabled=Le mod\u00e8le de cette instance a \u00e9t\u00e9 cr\u00e9\u00e9 sans la gestion de mot de passe message.reset.password.warning.notStopped=Votre instance doit \u00eatre arr\u00eat\u00e9e avant de changer son mot de passe message.reset.VPN.connection=Confirmer le r\u00e9-initialisation de la connexion VPN @@ -1459,6 +1825,7 @@ message.restart.mgmt.server=Red\u00e9marrez votre(vos) serveur(s) de management message.restart.mgmt.usage.server=Red\u00e9marrer le ou les serveur(s) de gestion et le ou les serveur(s) de consommation pour que les nouveaux param\u00e8tres soient pris en compte. message.restart.network=Tous les services fournit par ce routeur virtuel vont \u00eatre interrompus. Confirmer le red\u00e9marrage de ce routeur. message.restart.vpc=Confirmer le red\u00e9marrage du VPC +message.restoreVM=Voulez-vous restaurer la VM ? message.security.group.usage=(Utilisez Ctrl-clic pour s\u00e9lectionner les groupes de s\u00e9curit\u00e9 vis\u00e9s) message.select.affinity.groups=S\u00e9lectionner les groupes d\\'affinit\u00e9 qui appartiendront \u00e0 cette machine virtuelle \: message.select.a.zone=Une zone correspond typiquement \u00e0 un seul centre de donn\u00e9es. Des zones multiples peuvent permettre de rendre votre cloud plus fiable en apportant une isolation physique et de la redondance. @@ -1467,10 +1834,14 @@ message.select.iso=S\u00e9lectionner un ISO pour votre nouvelle instance virtuel message.select.item=Merci de s\u00e9lectionner un \u00e9l\u00e9ment. message.select.security.groups=Merci de s\u00e9lectionner un(des) groupe(s) de s\u00e9curit\u00e9 pour la nouvelle VM message.select.template=S\u00e9lectionner un mod\u00e8le pour votre nouvelle instance virtuelle. +message.select.tier=Veuillez selectionner un tiers +message.set.default.NIC=Confirmer la mise par d\u00e9faut de cette NIC pour cette VM. +message.set.default.NIC.manual=Veuillez mettre \u00e0 jour manuellement la NIC par d\u00e9faut sur la VM maintenant. message.setup.physical.network.during.zone.creation.basic=Quand vous ajoutez une zone basique, vous pouvez param\u00e9trer un seul r\u00e9seau physique, correspondant \u00e0 une carte r\u00e9seau sur l\\'hyperviseur. Ce r\u00e9seau comportera plusieurs types de trafic.

Vous pouvez \u00e9galement glisser et d\u00e9poser d\\'autres types de trafic sur le r\u00e9seau physique. message.setup.physical.network.during.zone.creation=Lorsque vous ajoutez une zone avanc\u00e9e, vous avez besoin de d\u00e9finir un ou plusieurs r\u00e9seaux physiques. Chaque r\u00e9seau correspond \u00e0 une carte r\u00e9seau sur l\\'hyperviseur. Chaque r\u00e9seau physique peut supporter un ou plusieurs types de trafic, avec certaines restrictions sur la fa\u00e7on dont ils peuvent \u00eatre combin\u00e9s.

Glisser et d\u00e9poser un ou plusieurs types de trafic sur chaque r\u00e9seau physique. message.setup.successful=Installation du Cloud r\u00e9ussie \! message.snapshot.schedule=Vous pouvez mettre en place les politiques de g\u00e9n\u00e9ration d\\'instantan\u00e9s en s\u00e9lectionnant les options disponibles ci-dessous et en appliquant votre politique. +message.specifiy.tag.key.value=Sp\u00e9cifier une cl\u00e9 et valeur de tag message.specify.url=Renseigner l\\'URL message.step.1.continue=S\u00e9lectionnez un mod\u00e8le ou une image ISO pour continuer message.step.1.desc=S\u00e9lectionnez un mod\u00e8le pour votre nouvelle instance virtuelle. Vous pouvez \u00e9galement choisir un mod\u00e8le vierge sur lequel une image ISO pourra \u00eatre install\u00e9e. @@ -1481,8 +1852,11 @@ message.step.3.desc= message.step.4.continue=S\u00e9lectionnez au moins un r\u00e9seau pour continuer message.step.4.desc=S\u00e9lectionnez le r\u00e9seau principal auquel votre instance va \u00eatre connect\u00e9. message.storage.traffic=Trafic entre les ressources internes de CloudStack, incluant tous les composants qui communiquent avec le serveur d\\'administration, tels que les h\u00f4tes et les machines virtuelles Syst\u00e8mes CloudStack. Veuillez configurer le trafic de stockage ici. -message.suspend.project=\u00cates-vous s\u00fbr de vouloir suspendre ce projet ? +message.suspend.project=Voulez-vous suspendre ce projet ? +message.systems.vms.ready=VMs Syst\u00e8mes pr\u00eats. +message.template.copying=Le mod\u00e8le est copi\u00e9. message.template.desc=Image OS pouvant \u00eatre utilis\u00e9e pour d\u00e9marrer une VM +message.tier.required=Le tiers est obligatoire message.tooltip.dns.1=Nom d\\'un serveur DNS utilis\u00e9 par les VM de la zone. Les adresses IP publiques de cette zone doivent avoir une route vers ce serveur. message.tooltip.dns.2=Nom d\\'un serveur DNS secondaire utilis\u00e9 par les VM de la zone. Les adresses IP publiques de cette zone doivent avoir une route vers ce serveur. message.tooltip.internal.dns.1=Nom d\\'un serveur DNS que CloudStack peut utiliser pour les VM syst\u00e8me dans cette zone. Les adresses IP priv\u00e9es des pods doivent avoir une route vers ce serveur. @@ -1494,20 +1868,43 @@ message.tooltip.reserved.system.netmask=Le pr\u00e9fixe r\u00e9seau utilis\u00e9 message.tooltip.zone.name=Nom pour cette zone. message.update.os.preference=Choisissez votre OS pr\u00e9f\u00e9r\u00e9 pour cet h\u00f4te. Toutes les instances avec des pr\u00e9f\u00e9rences similaires seront d\\'abord allou\u00e9es \u00e0 cet h\u00f4te avant d\\'en choisir un autre. message.update.resource.count=Confirmer la mise \u00e0 jour des ressources pour ce compte. -message.update.ssl=Soumettez un nouveau certificat SSL compatible X.509 qui sera mis \u00e0 jour sur l\\'ensemble de instance de proxy console. +message.update.ssl=Soumettez un nouveau certificat SSL compatible X.509 qui sera mis \u00e0 jour sur chaque VM console proxy et VM sockage secondaire \: +message.validate.accept=Veuillez entrer une valeur avec une extension valide. +message.validate.creditcard=Veuillez entrer un num\u00e9ro de carte de cr\u00e9dit valide. +message.validate.date.ISO=Veuillez entrer une date (ISO) valide. +message.validate.date=Veuillez entrer une date valide. +message.validate.digits=Veuillez entrer uniquement des chiffres. +message.validate.email.address=Veuillez entrer une adresse email valide. +message.validate.equalto=Veuillez entrer de nouveau la m\u00eame valeur. +message.validate.fieldrequired=Ce champ est obligatoire. +message.validate.fixfield=Veuillez corriger ce champ. message.validate.instance.name=Le nom de l\\'instance ne peut d\u00e9passer 63 caract\u00e8res. Seuls les lettres de a \u00e0 z, les chiffres de 0 \u00e0 9 et les tirets sont accept\u00e9s. Le nom doit commencer par une lettre et se terminer par une lettre ou un chiffre. +message.validate.invalid.characters=Caract\u00e8res invalides trouv\u00e9s ; veuillez corriger. +message.validate.maxlength=Veuillez entrer uniquement {0} caract\u00e8res. +message.validate.max=Veuillez entrer une valeur inf\u00e9rieure ou \u00e9gale \u00e0 {0}. +message.validate.minlength=Veuillez entrer au moins {0} caract\u00e8res. +message.validate.number=Veuillez entrer un nombre valide. +message.validate.range.length=Veuillez entrer une valeur de {0} \u00e0 {1} caract\u00e8res. +message.validate.range=Veuillez entrer une valeur de {0} \u00e0 {1}. +message.validate.URL=Veuillez entrer une URL valide. message.virtual.network.desc=Un r\u00e9seau virtuel d\u00e9di\u00e9 pour votre compte. Ce domaine de multi-diffusion est contenu dans un VLAN et l\\'ensemble des r\u00e9seaux d\\'acc\u00e8s publique sont rout\u00e9s par un routeur virtuel. message.vm.create.template.confirm=Cr\u00e9er un mod\u00e8le va red\u00e9marrer la VM automatiquement message.vm.review.launch=Merci de v\u00e9rifier les informations suivantes et de confirmer que votre instance virtuelle est correcte avant de la d\u00e9marrer. -message.volume.create.template.confirm=\u00cates-vous s\u00fbr que vous souhaitez cr\u00e9er un mod\u00e8le pour ce disque. La cr\u00e9ation peut prendre plusieurs minutes, voire plus, selon la taille du volume. +message.vnmc.available.list=VNMC n\\'est pas disponible dans la liste des fournisseurs. +message.vnmc.not.available.list=VNMC n\\'est pas disponible dans la liste des fournisseurs. +message.volume.create.template.confirm=Cr\u00e9er un mod\u00e8le pour ce disque ? La cr\u00e9ation peut prendre plusieurs minutes, voir plus, selon la taille du volume. +message.waiting.for.builtin.templates.to.load=Attendre le chargement des mod\u00e8les pr\u00e9-construit... +message.XSTools61plus.update.failed=\u00c9chec de mise \u00e0 jour champ XenServer Tools Version 6.1\\+. Erreur \: message.you.must.have.at.least.one.physical.network=Vous devez avoir au moins un r\u00e9seau physique +message.your.cloudstack.is.ready=Votre CloudStack est pr\u00eat \! message.Zone.creation.complete=Cr\u00e9ation de la zone termin\u00e9e message.zone.creation.complete.would.you.like.to.enable.this.zone=Cr\u00e9ation de la zone termin\u00e9e. Voulez-vous l\\'activer ? message.zone.no.network.selection=La zone s\u00e9lectionn\u00e9e ne propose pas le r\u00e9seau choisi message.zone.step.1.desc=S\u00e9lectionnez un mod\u00e8le de r\u00e9seau pour votre zone. message.zone.step.2.desc=Renseigner les informations suivantes pour ajouter une nouvelle zone message.zone.step.3.desc=Renseigner les informations suivantes pour ajouter un nouveau pod -message.zoneWizard.enable.local.storage=ATTENTION \: si vous activez le stockage local pour cette zone, vous devez effectuer les op\u00e9rations suivantes, selon l\\'endroit o\u00f9 vous souhaitez lancer vos machines virtuelles Syst\u00e8mes \:

1. Si les machines virtuelles Syst\u00e8mes doivent \u00eatre lanc\u00e9es depuis le stockage principal, ce dernier doit \u00eatre ajout\u00e9 \u00e0 la zone apr\u00e8s la cr\u00e9ation. Vous devez \u00e9galement d\u00e9marrer la zone dans un \u00e9tat d\u00e9sactiv\u00e9.

2. Si les machines virtuelles Syst\u00e8mes doivent \u00eatre lanc\u00e9es depuis le stockage local, le param\u00e8tre system.vm.use.local.storage doit \u00eatre d\u00e9fini \u00e0 \\'true\\' avant d\\'activer la zone.


Voulez-vous continuer ? +message.zoneWizard.enable.local.storage=ATTENTION \: si vous activez le stockage local pour cette zone, vous devez effectuer les op\u00e9rations suivantes, selon l\\'endroit o\u00f9 vous souhaitez lancer vos machines virtuelles Syst\u00e8mes \:

1. Si les machines virtuelles Syst\u00e8mes doivent \u00eatre lanc\u00e9es depuis le stockage primaire, ce dernier doit \u00eatre ajout\u00e9 \u00e0 la zone apr\u00e8s la cr\u00e9ation. Vous devez \u00e9galement d\u00e9marrer la zone dans un \u00e9tat d\u00e9sactiv\u00e9.

2. Si les machines virtuelles Syst\u00e8mes doivent \u00eatre lanc\u00e9es depuis le stockage local, le param\u00e8tre system.vm.use.local.storage doit \u00eatre d\u00e9fini \u00e0 \\'true\\' avant d\\'activer la zone.


Voulez-vous continuer ? +messgae.validate.min=Veuillez entrer une valeur sup\u00e9rieure ou \u00e9gale \u00e0 {0}. mode=Mode network.rate=D\u00e9bit R\u00e9seau notification.reboot.instance=Red\u00e9marrer l\\'instance diff --git a/client/WEB-INF/classes/resources/messages_it_IT.properties b/client/WEB-INF/classes/resources/messages_it_IT.properties index eab29b9b99..e2f3f0b5aa 100644 --- a/client/WEB-INF/classes/resources/messages_it_IT.properties +++ b/client/WEB-INF/classes/resources/messages_it_IT.properties @@ -354,6 +354,7 @@ label.ESP.encryption=Encryption di ESP label.ESP.hash=Hash di ESP label.ESP.policy=Policy di ESP label.f5=F5 +label.failed=Errore label.full.path=Path completo label.guest.end.ip=Indirizzo IP guest finale label.guest=Guest @@ -435,6 +436,7 @@ label.migrate.instance.to.ps=Migrare instance verso un altro primary storage label.migrate.to.host=Migrare verso un host label.migrate.to.storage=Migrare verso uno storage label.migrate.volume=Migrare un volume verso un altro primary storage +label.mode=Modalit\u00e0 label.move.down.row=Sposta gi\u00f9 di una riga label.move.to.bottom=Sposta gi\u00f9 alla fine label.move.to.top=Sposta in su all\\'inizio @@ -606,6 +608,7 @@ label.VMs.in.tier=VM nei livelli label.vm.state=Stato VM label.vm.stop=Stop label.vmware.traffic.label=Etichetta del traffico via VMware +label.vnet=VLAN label.vpc.id=ID del VPC label.VPC.router.details=Dettagli del router VPC label.vpc=VPC @@ -783,7 +786,6 @@ message.you.must.have.at.least.one.physical.network=E\\' necessario disporre di message.Zone.creation.complete=Creazione zona completata message.zone.creation.complete.would.you.like.to.enable.this.zone=Creazione zona completata. Si desidera abilitare questa zona? message.zone.no.network.selection=La zona selezionata non contiene opzioni per la selezione della rete. -message.zoneWizard.enable.local.storage=ATTENZIONE\: Se si abilita lo storage locale per questa zona, \u00e8 necessario procedere come segue, a seconda di dove si intende avviare le VM di sistema\:

1. Se le VM di sistema devono essere avviate dal primary storage, questo deve essere aggiunto alla zona dopo la sua creazione. E\\' anche necessario avviare la zona in uno stato disabilitato.

2. Se le VM di sistema devono essere avviate dallo storage locale, system.vm.use.local.storage deve essere impostato a true prima di abilitare la zona.


Si intende procedere? mode=Modalit\u00e0 notification.reboot.instance=Riavviare una instanza notification.start.instance=Avviare una instanza diff --git a/client/WEB-INF/classes/resources/messages_ja_JP.properties b/client/WEB-INF/classes/resources/messages_ja_JP.properties index d3d50f0e88..2fa3cb641a 100644 --- a/client/WEB-INF/classes/resources/messages_ja_JP.properties +++ b/client/WEB-INF/classes/resources/messages_ja_JP.properties @@ -14,56 +14,11 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -label.port=\u30dd\u30fc\u30c8 -label.remove.ldap=LDAP \u306e\u524a\u9664 -label.configure.ldap=LDAP \u306e\u69cb\u6210 -label.ldap.configuration=LDAP \u69cb\u6210 -label.ldap.port=LDAP \u30dd\u30fc\u30c8 -label.create.nfs.secondary.staging.store=NFS \u30bb\u30ab\u30f3\u30c0\u30ea \u30b9\u30c6\u30fc\u30b8\u30f3\u30b0 \u30b9\u30c8\u30a2\u3092\u4f5c\u6210\u3059\u308b -label.volatile=\u63ee\u767a\u6027 -label.planner.mode=\u30d7\u30e9\u30f3\u30ca\u30fc \u30e2\u30fc\u30c9 -label.deployment.planner=\u5c55\u958b\u30d7\u30e9\u30f3\u30ca\u30fc -label.quiesce.vm=VM \u3092\u4f11\u6b62\u3059\u308b -label.smb.username=SMB \u30e6\u30fc\u30b6\u30fc\u540d -label.smb.password=SMB \u30d1\u30b9\u30ef\u30fc\u30c9 -label.smb.domain=SMB \u30c9\u30e1\u30a4\u30f3 -label.hypervisors=\u30cf\u30a4\u30d1\u30fc\u30d0\u30a4\u30b6\u30fc -label.home=\u30db\u30fc\u30e0 -label.sockets=CPU \u30bd\u30b1\u30c3\u30c8 -label.root.disk.size=\u30eb\u30fc\u30c8 \u30c7\u30a3\u30b9\u30af \u30b5\u30a4\u30ba -label.s3.nfs.server=S3 NFS \u30b5\u30fc\u30d0\u30fc -label.s3.nfs.path=S3 NFS \u30d1\u30b9 -label.delete.events=\u30a4\u30d9\u30f3\u30c8\u306e\u524a\u9664 -label.delete.alerts=\u30a2\u30e9\u30fc\u30c8\u306e\u524a\u9664 -label.archive.alerts=\u30a2\u30e9\u30fc\u30c8\u306e\u30a2\u30fc\u30ab\u30a4\u30d6 -label.archive.events=\u30a4\u30d9\u30f3\u30c8\u306e\u30a2\u30fc\u30ab\u30a4\u30d6 -label.by.alert.type=\u30a2\u30e9\u30fc\u30c8\u306e\u7a2e\u985e -label.by.event.type=\u30a4\u30d9\u30f3\u30c8\u306e\u7a2e\u985e -label.by.date.start=\u65e5\u4ed8 (\u958b\u59cb) -label.by.date.end=\u65e5\u4ed8 (\u7d42\u4e86) -label.switch.type=\u30b9\u30a4\u30c3\u30c1\u306e\u7a2e\u985e -label.service.state=\u30b5\u30fc\u30d3\u30b9\u306e\u72b6\u614b -label.egress.default.policy=\u9001\u4fe1\u306e\u30c7\u30d5\u30a9\u30eb\u30c8 \u30dd\u30ea\u30b7\u30fc -label.routing=\u30eb\u30fc\u30c6\u30a3\u30f3\u30b0 -label.about=\u30d0\u30fc\u30b8\u30e7\u30f3\u60c5\u5831 -label.app.name=CloudStack -label.about.app=CloudStack \u306b\u3064\u3044\u3066 -label.custom.disk.iops=\u30ab\u30b9\u30bf\u30e0 IOPS -label.disk.iops.min=\u6700\u5c0f IOPS -label.disk.iops.max=\u6700\u5927 IOPS -label.disk.iops.total=IOPS \u5408\u8a08 -label.hypervisor.snapshot.reserve=\u30cf\u30a4\u30d1\u30fc\u30d0\u30a4\u30b6\u30fc \u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8\u4e88\u7d04 -label.view.secondary.ips=\u30bb\u30ab\u30f3\u30c0\u30ea IP \u30a2\u30c9\u30ec\u30b9\u306e\u8868\u793a -message.validate.invalid.characters=\u7121\u52b9\u306a\u6587\u5b57\u304c\u898b\u3064\u304b\u308a\u307e\u3057\u305f\u3002\u4fee\u6574\u3057\u3066\u304f\u3060\u3055\u3044\u3002 -message.acquire.ip.nic=\u3053\u306e NIC \u306e\u305f\u3081\u306b\u65b0\u3057\u3044\u30bb\u30ab\u30f3\u30c0\u30ea IP \u30a2\u30c9\u30ec\u30b9\u3092\u53d6\u5f97\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b?
\u6ce8: \u65b0\u3057\u304f\u53d6\u5f97\u3057\u305f\u30bb\u30ab\u30f3\u30c0\u30ea IP \u30a2\u30c9\u30ec\u30b9\u306f\u4eee\u60f3\u30de\u30b7\u30f3\u5185\u3067\u624b\u52d5\u3067\u69cb\u6210\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002 -message.select.affinity.groups=\u3053\u306e VM \u3092\u8ffd\u52a0\u3059\u308b\u30a2\u30d5\u30a3\u30cb\u30c6\u30a3 \u30b0\u30eb\u30fc\u30d7\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044\u3002 -message.no.affinity.groups=\u30a2\u30d5\u30a3\u30cb\u30c6\u30a3 \u30b0\u30eb\u30fc\u30d7\u304c\u3042\u308a\u307e\u305b\u3093\u3002\u6b21\u306e\u624b\u9806\u306b\u9032\u3093\u3067\u304f\u3060\u3055\u3044\u3002 -label.action.delete.nic=NIC \u306e\u524a\u9664 -message.action.delete.nic=\u3053\u306e NIC \u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? \u95a2\u9023\u4ed8\u3051\u3089\u308c\u305f\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3082 VM \u304b\u3089\u524a\u9664\u3055\u308c\u307e\u3059\u3002 + changed.item.properties=\u9805\u76ee\u306e\u30d7\u30ed\u30d1\u30c6\u30a3\u306e\u5909\u66f4 confirm.enable.s3=S3 \u30d9\u30fc\u30b9\u306e\u30bb\u30ab\u30f3\u30c0\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8\u306e\u30b5\u30dd\u30fc\u30c8\u3092\u6709\u52b9\u306b\u3059\u308b\u306b\u306f\u3001\u6b21\u306e\u60c5\u5831\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002 confirm.enable.swift=Swift \u306e\u30b5\u30dd\u30fc\u30c8\u3092\u6709\u52b9\u306b\u3059\u308b\u306b\u306f\u3001\u6b21\u306e\u60c5\u5831\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002 -error.could.not.change.your.password.because.ldap.is.enabled=\u30a8\u30e9\u30fc\u3002LDAP \u304c\u6709\u52b9\u306a\u305f\u3081\u30d1\u30b9\u30ef\u30fc\u30c9\u3092\u5909\u66f4\u3067\u304d\u307e\u305b\u3093\u3002 +error.could.not.change.your.password.because.ldap.is.enabled=LDAP \u304c\u6709\u52b9\u306a\u305f\u3081\u3001\u30a8\u30e9\u30fc\u306b\u3088\u3063\u3066\u30d1\u30b9\u30ef\u30fc\u30c9\u306f\u5909\u66f4\u3055\u308c\u307e\u305b\u3093\u3067\u3057\u305f\u3002 error.could.not.enable.zone=\u30be\u30fc\u30f3\u3092\u6709\u52b9\u306b\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f error.installWizard.message=\u554f\u984c\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002\u623b\u3063\u3066\u30a8\u30e9\u30fc\u3092\u4fee\u6b63\u3067\u304d\u307e\u3059\u3002 error.invalid.username.password=\u7121\u52b9\u306a\u30e6\u30fc\u30b6\u30fc\u540d\u307e\u305f\u306f\u30d1\u30b9\u30ef\u30fc\u30c9\u3067\u3059\u3002 @@ -88,26 +43,30 @@ ICMP.type=ICMP \u306e\u7a2e\u985e image.directory=\u753b\u50cf\u30c7\u30a3\u30ec\u30af\u30c8\u30ea inline=\u76f4\u5217 instances.actions.reboot.label=\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u306e\u518d\u8d77\u52d5 +label.about.app=CloudStack \u306b\u3064\u3044\u3066 +label.about=\u30d0\u30fc\u30b8\u30e7\u30f3\u60c5\u5831 label.accept.project.invitation=\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u3078\u306e\u62db\u5f85\u306e\u627f\u8afe label.account.and.security.group=\u30a2\u30ab\u30a6\u30f3\u30c8\u3001\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3 \u30b0\u30eb\u30fc\u30d7 label.account.id=\u30a2\u30ab\u30a6\u30f3\u30c8 ID +label.account.lower=\u30a2\u30ab\u30a6\u30f3\u30c8 label.account.name=\u30a2\u30ab\u30a6\u30f3\u30c8\u540d label.account.specific=\u30a2\u30ab\u30a6\u30f3\u30c8\u56fa\u6709 -label.account=\u30a2\u30ab\u30a6\u30f3\u30c8 label.accounts=\u30a2\u30ab\u30a6\u30f3\u30c8 +label.account=\u30a2\u30ab\u30a6\u30f3\u30c8 +label.acl=ACL label.acquire.new.ip=\u65b0\u3057\u3044 IP \u30a2\u30c9\u30ec\u30b9\u306e\u53d6\u5f97 label.acquire.new.secondary.ip=\u30bb\u30ab\u30f3\u30c0\u30ea IP \u30a2\u30c9\u30ec\u30b9\u306e\u53d6\u5f97 label.action.attach.disk.processing=\u30c7\u30a3\u30b9\u30af\u3092\u30a2\u30bf\u30c3\u30c1\u3057\u3066\u3044\u307e\u3059... label.action.attach.disk=\u30c7\u30a3\u30b9\u30af\u306e\u30a2\u30bf\u30c3\u30c1 -label.action.attach.iso.processing=ISO \u3092\u30a2\u30bf\u30c3\u30c1\u3057\u3066\u3044\u307e\u3059... label.action.attach.iso=ISO \u306e\u30a2\u30bf\u30c3\u30c1 +label.action.attach.iso.processing=ISO \u3092\u30a2\u30bf\u30c3\u30c1\u3057\u3066\u3044\u307e\u3059... label.action.cancel.maintenance.mode.processing=\u4fdd\u5b88\u30e2\u30fc\u30c9\u3092\u30ad\u30e3\u30f3\u30bb\u30eb\u3057\u3066\u3044\u307e\u3059... label.action.cancel.maintenance.mode=\u4fdd\u5b88\u30e2\u30fc\u30c9\u306e\u30ad\u30e3\u30f3\u30bb\u30eb label.action.change.password=\u30d1\u30b9\u30ef\u30fc\u30c9\u306e\u5909\u66f4 label.action.change.service.processing=\u30b5\u30fc\u30d3\u30b9\u3092\u5909\u66f4\u3057\u3066\u3044\u307e\u3059... label.action.change.service=\u30b5\u30fc\u30d3\u30b9\u306e\u5909\u66f4 -label.action.copy.ISO.processing=ISO \u3092\u30b3\u30d4\u30fc\u3057\u3066\u3044\u307e\u3059... label.action.copy.ISO=ISO \u306e\u30b3\u30d4\u30fc +label.action.copy.ISO.processing=ISO \u3092\u30b3\u30d4\u30fc\u3057\u3066\u3044\u307e\u3059... label.action.copy.template.processing=\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u3092\u30b3\u30d4\u30fc\u3057\u3066\u3044\u307e\u3059... label.action.copy.template=\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u306e\u30b3\u30d4\u30fc label.action.create.template.from.vm=VM \u304b\u3089\u306e\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u4f5c\u6210 @@ -130,15 +89,16 @@ label.action.delete.firewall.processing=\u30d5\u30a1\u30a4\u30a2\u30a6\u30a9\u30 label.action.delete.firewall=\u30d5\u30a1\u30a4\u30a2\u30a6\u30a9\u30fc\u30eb\u898f\u5247\u306e\u524a\u9664 label.action.delete.ingress.rule.processing=\u53d7\u4fe1\u898f\u5247\u3092\u524a\u9664\u3057\u3066\u3044\u307e\u3059... label.action.delete.ingress.rule=\u53d7\u4fe1\u898f\u5247\u306e\u524a\u9664 -label.action.delete.IP.range.processing=IP \u30a2\u30c9\u30ec\u30b9\u306e\u7bc4\u56f2\u3092\u524a\u9664\u3057\u3066\u3044\u307e\u3059... label.action.delete.IP.range=IP \u30a2\u30c9\u30ec\u30b9\u306e\u7bc4\u56f2\u306e\u524a\u9664 -label.action.delete.ISO.processing=ISO \u3092\u524a\u9664\u3057\u3066\u3044\u307e\u3059... +label.action.delete.IP.range.processing=IP \u30a2\u30c9\u30ec\u30b9\u306e\u7bc4\u56f2\u3092\u524a\u9664\u3057\u3066\u3044\u307e\u3059... label.action.delete.ISO=ISO \u306e\u524a\u9664 +label.action.delete.ISO.processing=ISO \u3092\u524a\u9664\u3057\u3066\u3044\u307e\u3059... label.action.delete.load.balancer.processing=\u8ca0\u8377\u5206\u6563\u88c5\u7f6e\u3092\u524a\u9664\u3057\u3066\u3044\u307e\u3059... label.action.delete.load.balancer=\u8ca0\u8377\u5206\u6563\u898f\u5247\u306e\u524a\u9664 label.action.delete.network.processing=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3092\u524a\u9664\u3057\u3066\u3044\u307e\u3059... label.action.delete.network=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306e\u524a\u9664 label.action.delete.nexusVswitch=Nexus 1000V \u306e\u524a\u9664 +label.action.delete.nic=NIC \u306e\u524a\u9664 label.action.delete.physical.network=\u7269\u7406\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306e\u524a\u9664 label.action.delete.pod.processing=\u30dd\u30c3\u30c9\u3092\u524a\u9664\u3057\u3066\u3044\u307e\u3059... label.action.delete.pod=\u30dd\u30c3\u30c9\u306e\u524a\u9664 @@ -167,8 +127,8 @@ label.action.destroy.systemvm.processing=\u30b7\u30b9\u30c6\u30e0 VM \u3092\u783 label.action.destroy.systemvm=\u30b7\u30b9\u30c6\u30e0 VM \u306e\u7834\u68c4 label.action.detach.disk.processing=\u30c7\u30a3\u30b9\u30af\u3092\u30c7\u30bf\u30c3\u30c1\u3057\u3066\u3044\u307e\u3059... label.action.detach.disk=\u30c7\u30a3\u30b9\u30af\u306e\u30c7\u30bf\u30c3\u30c1 -label.action.detach.iso.processing=ISO \u3092\u30c7\u30bf\u30c3\u30c1\u3057\u3066\u3044\u307e\u3059... label.action.detach.iso=ISO \u306e\u30c7\u30bf\u30c3\u30c1 +label.action.detach.iso.processing=ISO \u3092\u30c7\u30bf\u30c3\u30c1\u3057\u3066\u3044\u307e\u3059... label.action.disable.account.processing=\u30a2\u30ab\u30a6\u30f3\u30c8\u3092\u7121\u52b9\u306b\u3057\u3066\u3044\u307e\u3059... label.action.disable.account=\u30a2\u30ab\u30a6\u30f3\u30c8\u306e\u7121\u52b9\u5316 label.action.disable.cluster.processing=\u30af\u30e9\u30b9\u30bf\u30fc\u3092\u7121\u52b9\u306b\u3057\u3066\u3044\u307e\u3059... @@ -220,8 +180,8 @@ label.action.enable.user.processing=\u30e6\u30fc\u30b6\u30fc\u3092\u6709\u52b9\u label.action.enable.user=\u30e6\u30fc\u30b6\u30fc\u306e\u6709\u52b9\u5316 label.action.enable.zone.processing=\u30be\u30fc\u30f3\u3092\u6709\u52b9\u306b\u3057\u3066\u3044\u307e\u3059... label.action.enable.zone=\u30be\u30fc\u30f3\u306e\u6709\u52b9\u5316 -label.action.expunge.instance=\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u306e\u62b9\u6d88 label.action.expunge.instance.processing=\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u3092\u62b9\u6d88\u3057\u3066\u3044\u307e\u3059... +label.action.expunge.instance=\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u306e\u62b9\u6d88 label.action.force.reconnect.processing=\u518d\u63a5\u7d9a\u3057\u3066\u3044\u307e\u3059... label.action.force.reconnect=\u5f37\u5236\u518d\u63a5\u7d9a label.action.generate.keys.processing=\u30ad\u30fc\u3092\u751f\u6210\u3057\u3066\u3044\u307e\u3059... @@ -246,8 +206,8 @@ label.action.reboot.systemvm=\u30b7\u30b9\u30c6\u30e0 VM \u306e\u518d\u8d77\u52d label.action.recurring.snapshot=\u5b9a\u671f\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8 label.action.register.iso=ISO \u306e\u767b\u9332 label.action.register.template=\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u306e\u767b\u9332 -label.action.release.ip.processing=IP \u30a2\u30c9\u30ec\u30b9\u3092\u89e3\u653e\u3057\u3066\u3044\u307e\u3059... label.action.release.ip=IP \u30a2\u30c9\u30ec\u30b9\u306e\u89e3\u653e +label.action.release.ip.processing=IP \u30a2\u30c9\u30ec\u30b9\u3092\u89e3\u653e\u3057\u3066\u3044\u307e\u3059... label.action.remove.host.processing=\u30db\u30b9\u30c8\u3092\u524a\u9664\u3057\u3066\u3044\u307e\u3059... label.action.remove.host=\u30db\u30b9\u30c8\u306e\u524a\u9664 label.action.reset.password.processing=\u30d1\u30b9\u30ef\u30fc\u30c9\u3092\u30ea\u30bb\u30c3\u30c8\u3057\u3066\u3044\u307e\u3059... @@ -257,6 +217,8 @@ label.action.resize.volume=\u30dc\u30ea\u30e5\u30fc\u30e0 \u30b5\u30a4\u30ba\u30 label.action.resource.limits=\u30ea\u30bd\u30fc\u30b9\u5236\u9650 label.action.restore.instance.processing=\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u3092\u5fa9\u5143\u3057\u3066\u3044\u307e\u3059... label.action.restore.instance=\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u306e\u5fa9\u5143 +label.action.revert.snapshot.processing=\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8\u306b\u623b\u3057\u3066\u3044\u307e\u3059... +label.action.revert.snapshot=\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8\u306b\u623b\u3059 label.action.start.instance.processing=\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u3092\u8d77\u52d5\u3057\u3066\u3044\u307e\u3059... label.action.start.instance=\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u306e\u8d77\u52d5 label.action.start.router.processing=\u30eb\u30fc\u30bf\u30fc\u3092\u8d77\u52d5\u3057\u3066\u3044\u307e\u3059... @@ -269,28 +231,28 @@ label.action.stop.router.processing=\u30eb\u30fc\u30bf\u30fc\u3092\u505c\u6b62\u label.action.stop.router=\u30eb\u30fc\u30bf\u30fc\u306e\u505c\u6b62 label.action.stop.systemvm.processing=\u30b7\u30b9\u30c6\u30e0 VM \u3092\u505c\u6b62\u3057\u3066\u3044\u307e\u3059... label.action.stop.systemvm=\u30b7\u30b9\u30c6\u30e0 VM \u306e\u505c\u6b62 +label.actions=\u64cd\u4f5c label.action.take.snapshot.processing=\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8\u3092\u4f5c\u6210\u3057\u3066\u3044\u307e\u3059.... label.action.take.snapshot=\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8\u306e\u4f5c\u6210 -label.action.revert.snapshot.processing=\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8\u306b\u623b\u3057\u3066\u3044\u307e\u3059... -label.action.revert.snapshot=\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8\u306b\u623b\u3059 +label.action=\u64cd\u4f5c label.action.unmanage.cluster.processing=\u30af\u30e9\u30b9\u30bf\u30fc\u3092\u975e\u7ba1\u7406\u5bfe\u8c61\u306b\u3057\u3066\u3044\u307e\u3059... label.action.unmanage.cluster=\u30af\u30e9\u30b9\u30bf\u30fc\u306e\u975e\u7ba1\u7406\u5bfe\u8c61\u5316 -label.action.update.OS.preference.processing=OS \u57fa\u672c\u8a2d\u5b9a\u3092\u66f4\u65b0\u3057\u3066\u3044\u307e\u3059... label.action.update.OS.preference=OS \u57fa\u672c\u8a2d\u5b9a\u306e\u66f4\u65b0 +label.action.update.OS.preference.processing=OS \u57fa\u672c\u8a2d\u5b9a\u3092\u66f4\u65b0\u3057\u3066\u3044\u307e\u3059... label.action.update.resource.count.processing=\u30ea\u30bd\u30fc\u30b9\u6570\u3092\u66f4\u65b0\u3057\u3066\u3044\u307e\u3059... label.action.update.resource.count=\u30ea\u30bd\u30fc\u30b9\u6570\u306e\u66f4\u65b0 label.action.vmsnapshot.create=VM \u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8\u306e\u4f5c\u6210 label.action.vmsnapshot.delete=VM \u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8\u306e\u524a\u9664 label.action.vmsnapshot.revert=VM \u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8\u306b\u623b\u3059 -label.actions=\u64cd\u4f5c label.activate.project=\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u306e\u30a2\u30af\u30c6\u30a3\u30d6\u5316 label.active.sessions=\u30a2\u30af\u30c6\u30a3\u30d6\u306a\u30bb\u30c3\u30b7\u30e7\u30f3 +label.add.accounts.to=\u30a2\u30ab\u30a6\u30f3\u30c8\u306e\u8ffd\u52a0\u5148\: +label.add.accounts=\u30a2\u30ab\u30a6\u30f3\u30c8\u306e\u8ffd\u52a0 label.add.account.to.project=\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u3078\u306e\u30a2\u30ab\u30a6\u30f3\u30c8\u306e\u8ffd\u52a0 label.add.account=\u30a2\u30ab\u30a6\u30f3\u30c8\u306e\u8ffd\u52a0 -label.add.accounts.to=\u30a2\u30ab\u30a6\u30f3\u30c8\u306e\u8ffd\u52a0\u5148: -label.add.accounts=\u30a2\u30ab\u30a6\u30f3\u30c8\u306e\u8ffd\u52a0 label.add.ACL=ACL \u306e\u8ffd\u52a0 label.add.affinity.group=\u65b0\u3057\u3044\u30a2\u30d5\u30a3\u30cb\u30c6\u30a3 \u30b0\u30eb\u30fc\u30d7\u306e\u8ffd\u52a0 +label.add.baremetal.dhcp.device=\u30d9\u30a2\u30e1\u30bf\u30eb DHCP \u30c7\u30d0\u30a4\u30b9\u306e\u8ffd\u52a0 label.add.BigSwitchVns.device=Big Switch VNS \u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u306e\u8ffd\u52a0 label.add.by.cidr=CIDR \u3067\u8ffd\u52a0 label.add.by.group=\u30b0\u30eb\u30fc\u30d7\u3067\u8ffd\u52a0 @@ -300,13 +262,26 @@ label.add.compute.offering=\u30b3\u30f3\u30d4\u30e5\u30fc\u30c6\u30a3\u30f3\u30b label.add.direct.iprange=\u76f4\u63a5 IP \u30a2\u30c9\u30ec\u30b9\u306e\u7bc4\u56f2\u306e\u8ffd\u52a0 label.add.disk.offering=\u30c7\u30a3\u30b9\u30af \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0\u306e\u8ffd\u52a0 label.add.domain=\u30c9\u30e1\u30a4\u30f3\u306e\u8ffd\u52a0 +label.added.new.bigswitch.vns.controller=\u65b0\u3057\u3044 Big Switch VNS \u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u3092\u8ffd\u52a0\u3057\u307e\u3057\u305f label.add.egress.rule=\u9001\u4fe1\u898f\u5247\u306e\u8ffd\u52a0 +label.addes.new.f5=\u65b0\u3057\u3044 F5 \u3092\u8ffd\u52a0\u3057\u307e\u3057\u305f label.add.F5.device=F5 \u30c7\u30d0\u30a4\u30b9\u306e\u8ffd\u52a0 label.add.firewall=\u30d5\u30a1\u30a4\u30a2\u30a6\u30a9\u30fc\u30eb\u898f\u5247\u306e\u8ffd\u52a0 +label.add.gslb=GSLB \u306e\u8ffd\u52a0 label.add.guest.network=\u30b2\u30b9\u30c8 \u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306e\u8ffd\u52a0 label.add.host=\u30db\u30b9\u30c8\u306e\u8ffd\u52a0 +label.adding.cluster=\u30af\u30e9\u30b9\u30bf\u30fc\u3092\u8ffd\u52a0\u3057\u3066\u3044\u307e\u3059 +label.adding.failed=\u8ffd\u52a0\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f +label.adding.pod=\u30dd\u30c3\u30c9\u3092\u8ffd\u52a0\u3057\u3066\u3044\u307e\u3059 +label.adding.processing=\u8ffd\u52a0\u3057\u3066\u3044\u307e\u3059... label.add.ingress.rule=\u53d7\u4fe1\u898f\u5247\u306e\u8ffd\u52a0 +label.adding.succeeded=\u8ffd\u52a0\u3057\u307e\u3057\u305f +label.adding=\u8ffd\u52a0\u3057\u3066\u3044\u307e\u3059 +label.adding.user=\u30e6\u30fc\u30b6\u30fc\u3092\u8ffd\u52a0\u3057\u3066\u3044\u307e\u3059 +label.adding.zone=\u30be\u30fc\u30f3\u3092\u8ffd\u52a0\u3057\u3066\u3044\u307e\u3059 label.add.ip.range=IP \u30a2\u30c9\u30ec\u30b9\u306e\u7bc4\u56f2\u306e\u8ffd\u52a0 +label.add.isolated.network=\u5206\u96e2\u3055\u308c\u305f\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306e\u8ffd\u52a0 +label.additional.networks=\u8ffd\u52a0\u306e\u30cd\u30c3\u30c8\u30ef\u30fc\u30af label.add.load.balancer=\u8ca0\u8377\u5206\u6563\u88c5\u7f6e\u306e\u8ffd\u52a0 label.add.more=\u305d\u306e\u307b\u304b\u306e\u9805\u76ee\u306e\u8ffd\u52a0 label.add.netScaler.device=Netscaler \u30c7\u30d0\u30a4\u30b9\u306e\u8ffd\u52a0 @@ -317,15 +292,19 @@ label.add.network=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306e\u8ffd\u52a0 label.add.new.F5=\u65b0\u3057\u3044 F5 \u306e\u8ffd\u52a0 label.add.new.gateway=\u65b0\u3057\u3044\u30b2\u30fc\u30c8\u30a6\u30a7\u30a4\u306e\u8ffd\u52a0 label.add.new.NetScaler=\u65b0\u3057\u3044 NetScaler \u306e\u8ffd\u52a0 -label.add.new.SRX=\u65b0\u3057\u3044 SRX \u306e\u8ffd\u52a0 label.add.new.PA=\u65b0\u3057\u3044 Palo Alto \u306e\u8ffd\u52a0 +label.add.new.SRX=\u65b0\u3057\u3044 SRX \u306e\u8ffd\u52a0 label.add.new.tier=\u65b0\u3057\u3044\u968e\u5c64\u306e\u8ffd\u52a0 +label.add.nfs.secondary.staging.store=NFS \u30bb\u30ab\u30f3\u30c0\u30ea \u30b9\u30c6\u30fc\u30b8\u30f3\u30b0 \u30b9\u30c8\u30a2\u306e\u8ffd\u52a0 label.add.NiciraNvp.device=NVP \u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u306e\u8ffd\u52a0 +label.add.OpenDaylight.device=OpenDaylight \u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u306e\u8ffd\u52a0 +label.add.PA.device=Palo Alto \u30c7\u30d0\u30a4\u30b9\u306e\u8ffd\u52a0 label.add.physical.network=\u7269\u7406\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306e\u8ffd\u52a0 label.add.pod=\u30dd\u30c3\u30c9\u306e\u8ffd\u52a0 +label.add.portable.ip.range=\u30dd\u30fc\u30bf\u30d6\u30eb IP \u30a2\u30c9\u30ec\u30b9\u306e\u7bc4\u56f2\u306e\u8ffd\u52a0 label.add.port.forwarding.rule=\u30dd\u30fc\u30c8\u8ee2\u9001\u898f\u5247\u306e\u8ffd\u52a0 label.add.primary.storage=\u30d7\u30e9\u30a4\u30de\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8\u306e\u8ffd\u52a0 -label.add.region=\u9818\u57df\u306e\u8ffd\u52a0 +label.add.region=\u30ea\u30fc\u30b8\u30e7\u30f3\u306e\u8ffd\u52a0 label.add.resources=\u30ea\u30bd\u30fc\u30b9\u306e\u8ffd\u52a0 label.add.route=\u30eb\u30fc\u30c8\u306e\u8ffd\u52a0 label.add.rule=\u898f\u5247\u306e\u8ffd\u52a0 @@ -333,42 +312,37 @@ label.add.secondary.storage=\u30bb\u30ab\u30f3\u30c0\u30ea \u30b9\u30c8\u30ec\u3 label.add.security.group=\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3 \u30b0\u30eb\u30fc\u30d7\u306e\u8ffd\u52a0 label.add.service.offering=\u30b5\u30fc\u30d3\u30b9 \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0\u306e\u8ffd\u52a0 label.add.SRX.device=SRX \u30c7\u30d0\u30a4\u30b9\u306e\u8ffd\u52a0 -label.add.PA.device=Palo Alto \u30c7\u30d0\u30a4\u30b9\u306e\u8ffd\u52a0 label.add.static.nat.rule=\u9759\u7684 NAT \u898f\u5247\u306e\u8ffd\u52a0 label.add.static.route=\u9759\u7684\u30eb\u30fc\u30c8\u306e\u8ffd\u52a0 label.add.system.service.offering=\u30b7\u30b9\u30c6\u30e0 \u30b5\u30fc\u30d3\u30b9 \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0\u306e\u8ffd\u52a0 label.add.template=\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u306e\u8ffd\u52a0 label.add.to.group=\u8ffd\u52a0\u5148\u30b0\u30eb\u30fc\u30d7 +label.add=\u8ffd\u52a0 +label.add.ucs.manager=UCS Manager \u306e\u8ffd\u52a0 label.add.user=\u30e6\u30fc\u30b6\u30fc\u306e\u8ffd\u52a0 label.add.vlan=VLAN \u306e\u8ffd\u52a0 -label.add.vxlan=VXLAN \u306e\u8ffd\u52a0 -label.add.VM.to.tier=\u968e\u5c64\u3078\u306e VM \u306e\u8ffd\u52a0 -label.add.vm=VM \u306e\u8ffd\u52a0 label.add.vms.to.lb=\u8ca0\u8377\u5206\u6563\u898f\u5247\u3078\u306e VM \u306e\u8ffd\u52a0 label.add.vms=VM \u306e\u8ffd\u52a0 +label.add.VM.to.tier=\u968e\u5c64\u3078\u306e VM \u306e\u8ffd\u52a0 +label.add.vm=VM \u306e\u8ffd\u52a0 +label.add.vmware.datacenter=VMware \u30c7\u30fc\u30bf\u30bb\u30f3\u30bf\u30fc\u306e\u8ffd\u52a0 +label.add.vnmc.device=VNMC \u30c7\u30d0\u30a4\u30b9\u306e\u8ffd\u52a0 +label.add.vnmc.provider=VNMC \u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u306e\u8ffd\u52a0 label.add.volume=\u30dc\u30ea\u30e5\u30fc\u30e0\u306e\u8ffd\u52a0 +label.add.vpc.offering=VPC \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0\u306e\u8ffd\u52a0 label.add.vpc=VPC \u306e\u8ffd\u52a0 label.add.vpn.customer.gateway=VPN \u30ab\u30b9\u30bf\u30de\u30fc \u30b2\u30fc\u30c8\u30a6\u30a7\u30a4\u306e\u8ffd\u52a0 label.add.VPN.gateway=VPN \u30b2\u30fc\u30c8\u30a6\u30a7\u30a4\u306e\u8ffd\u52a0 label.add.vpn.user=VPN \u30e6\u30fc\u30b6\u30fc\u306e\u8ffd\u52a0 +label.add.vxlan=VXLAN \u306e\u8ffd\u52a0 label.add.zone=\u30be\u30fc\u30f3\u306e\u8ffd\u52a0 -label.add=\u8ffd\u52a0 -label.adding.cluster=\u30af\u30e9\u30b9\u30bf\u30fc\u3092\u8ffd\u52a0\u3057\u3066\u3044\u307e\u3059 -label.adding.failed=\u8ffd\u52a0\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f -label.adding.pod=\u30dd\u30c3\u30c9\u3092\u8ffd\u52a0\u3057\u3066\u3044\u307e\u3059 -label.adding.processing=\u8ffd\u52a0\u3057\u3066\u3044\u307e\u3059... -label.adding.succeeded=\u8ffd\u52a0\u3057\u307e\u3057\u305f -label.adding.user=\u30e6\u30fc\u30b6\u30fc\u3092\u8ffd\u52a0\u3057\u3066\u3044\u307e\u3059 -label.adding.zone=\u30be\u30fc\u30f3\u3092\u8ffd\u52a0\u3057\u3066\u3044\u307e\u3059 -label.adding=\u8ffd\u52a0\u3057\u3066\u3044\u307e\u3059 -label.additional.networks=\u8ffd\u52a0\u306e\u30cd\u30c3\u30c8\u30ef\u30fc\u30af label.admin.accounts=\u7ba1\u7406\u8005\u30a2\u30ab\u30a6\u30f3\u30c8 label.admin=\u7ba1\u7406\u8005 label.advanced.mode=\u62e1\u5f35\u30e2\u30fc\u30c9 label.advanced.search=\u9ad8\u5ea6\u306a\u691c\u7d22 label.advanced=\u62e1\u5f35 -label.affinity.group=\u30a2\u30d5\u30a3\u30cb\u30c6\u30a3 \u30b0\u30eb\u30fc\u30d7 label.affinity.groups=\u30a2\u30d5\u30a3\u30cb\u30c6\u30a3 \u30b0\u30eb\u30fc\u30d7 +label.affinity.group=\u30a2\u30d5\u30a3\u30cb\u30c6\u30a3 \u30b0\u30eb\u30fc\u30d7 label.affinity=\u30a2\u30d5\u30a3\u30cb\u30c6\u30a3 label.agent.password=\u30a8\u30fc\u30b8\u30a7\u30f3\u30c8 \u30d1\u30b9\u30ef\u30fc\u30c9 label.agent.username=\u30a8\u30fc\u30b8\u30a7\u30f3\u30c8 \u30e6\u30fc\u30b6\u30fc\u540d @@ -377,152 +351,211 @@ label.alert=\u30a2\u30e9\u30fc\u30c8 label.algorithm=\u30a2\u30eb\u30b4\u30ea\u30ba\u30e0 label.allocated=\u5272\u308a\u5f53\u3066\u6e08\u307f label.allocation.state=\u5272\u308a\u5f53\u3066\u72b6\u614b -label.anti.affinity.group=\u30a2\u30f3\u30c1\u30a2\u30d5\u30a3\u30cb\u30c6\u30a3 \u30b0\u30eb\u30fc\u30d7 +label.allow=\u8a31\u53ef label.anti.affinity.groups=\u30a2\u30f3\u30c1\u30a2\u30d5\u30a3\u30cb\u30c6\u30a3 \u30b0\u30eb\u30fc\u30d7 +label.anti.affinity.group=\u30a2\u30f3\u30c1\u30a2\u30d5\u30a3\u30cb\u30c6\u30a3 \u30b0\u30eb\u30fc\u30d7 label.anti.affinity=\u30a2\u30f3\u30c1\u30a2\u30d5\u30a3\u30cb\u30c6\u30a3 label.api.key=API \u30ad\u30fc label.apply=\u9069\u7528 +label.app.name=CloudStack +label.archive.alerts=\u30a2\u30e9\u30fc\u30c8\u306e\u30a2\u30fc\u30ab\u30a4\u30d6 +label.archive.events=\u30a4\u30d9\u30f3\u30c8\u306e\u30a2\u30fc\u30ab\u30a4\u30d6 +label.assign.instance.another=\u307b\u304b\u306e\u30a2\u30ab\u30a6\u30f3\u30c8\u3078\u306e\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u306e\u5272\u308a\u5f53\u3066 label.assign.to.load.balancer=\u8ca0\u8377\u5206\u6563\u88c5\u7f6e\u306b\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u3092\u5272\u308a\u5f53\u3066\u3066\u3044\u307e\u3059 label.assign=\u5272\u308a\u5f53\u3066 -label.associated.network.id=\u95a2\u9023\u4ed8\u3051\u3089\u308c\u305f\u30cd\u30c3\u30c8\u30ef\u30fc\u30af ID -label.associated.network=\u95a2\u9023\u4ed8\u3051\u3089\u308c\u305f\u30cd\u30c3\u30c8\u30ef\u30fc\u30af +label.associated.network.id=\u95a2\u9023\u3065\u3051\u3089\u308c\u305f\u30cd\u30c3\u30c8\u30ef\u30fc\u30af ID +label.associated.network=\u95a2\u9023\u3065\u3051\u3089\u308c\u305f\u30cd\u30c3\u30c8\u30ef\u30fc\u30af +label.associated.profile=\u95a2\u9023\u4ed8\u3051\u3089\u308c\u305f\u30d7\u30ed\u30d5\u30a1\u30a4\u30eb +label.associate.public.ip=\u30d1\u30d6\u30ea\u30c3\u30af IP \u30a2\u30c9\u30ec\u30b9\u306e\u95a2\u9023\u4ed8\u3051 label.attached.iso=\u30a2\u30bf\u30c3\u30c1\u3055\u308c\u305f ISO label.author.email=\u4f5c\u6210\u8005\u306e\u96fb\u5b50\u30e1\u30fc\u30eb label.author.name=\u4f5c\u6210\u8005\u306e\u540d\u524d -label.availability.zone=\u30a2\u30d9\u30a4\u30e9\u30d3\u30ea\u30c6\u30a3 \u30be\u30fc\u30f3 +label.autoscale=\u81ea\u52d5\u30b5\u30a4\u30ba\u8a2d\u5b9a label.availability=\u53ef\u7528\u6027 +label.availability.zone=\u5229\u7528\u53ef\u80fd\u30be\u30fc\u30f3 label.available.public.ips=\u4f7f\u7528\u3067\u304d\u308b\u30d1\u30d6\u30ea\u30c3\u30af IP \u30a2\u30c9\u30ec\u30b9 label.available=\u4f7f\u7528\u53ef\u80fd label.back=\u623b\u308b label.bandwidth=\u5e2f\u57df\u5e45 +label.baremetal.dhcp.devices=\u30d9\u30a2\u30e1\u30bf\u30eb DHCP \u30c7\u30d0\u30a4\u30b9 +label.baremetal.dhcp.provider=\u30d9\u30a2\u30e1\u30bf\u30eb DHCP \u30d7\u30ed\u30d0\u30a4\u30c0\u30fc +label.baremetal.pxe.devices=\u30d9\u30a2\u30e1\u30bf\u30eb PXE \u30c7\u30d0\u30a4\u30b9 +label.baremetal.pxe.device=\u30d9\u30a2\u30e1\u30bf\u30eb PXE \u30c7\u30d0\u30a4\u30b9\u306e\u8ffd\u52a0 +label.baremetal.pxe.provider=\u30d9\u30a2\u30e1\u30bf\u30eb PXE \u30d7\u30ed\u30d0\u30a4\u30c0\u30fc label.basic.mode=\u57fa\u672c\u30e2\u30fc\u30c9 label.basic=\u57fa\u672c label.bigswitch.controller.address=Big Switch VNS \u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u306e\u30a2\u30c9\u30ec\u30b9 +label.bigswitch.vns.details=Big Switch VNS \u306e\u8a73\u7d30 +label.blade.id=\u30d6\u30ec\u30fc\u30c9 ID +label.blades=\u30d6\u30ec\u30fc\u30c9 label.bootable=\u8d77\u52d5\u53ef\u80fd label.broadcast.domain.range=\u30d6\u30ed\u30fc\u30c9\u30ad\u30e3\u30b9\u30c8 \u30c9\u30e1\u30a4\u30f3\u306e\u7bc4\u56f2 label.broadcast.domain.type=\u30d6\u30ed\u30fc\u30c9\u30ad\u30e3\u30b9\u30c8 \u30c9\u30e1\u30a4\u30f3\u306e\u7a2e\u985e label.broadcast.uri=\u30d6\u30ed\u30fc\u30c9\u30ad\u30e3\u30b9\u30c8 URI +label.broadcasturi=\u30d6\u30ed\u30fc\u30c9\u30ad\u30e3\u30b9\u30c8 URI +label.broadcat.uri=\u30d6\u30ed\u30fc\u30c9\u30ad\u30e3\u30b9\u30c8 URI label.by.account=\u30a2\u30ab\u30a6\u30f3\u30c8 +label.by.alert.type=\u30a2\u30e9\u30fc\u30c8\u306e\u7a2e\u985e label.by.availability=\u53ef\u7528\u6027 +label.by.date.end=\u65e5\u4ed8 (\u7d42\u4e86) +label.by.date.start=\u65e5\u4ed8 (\u958b\u59cb) label.by.domain=\u30c9\u30e1\u30a4\u30f3 label.by.end.date=\u7d42\u4e86\u65e5 +label.by.event.type=\u30a4\u30d9\u30f3\u30c8\u306e\u7a2e\u985e label.by.level=\u30ec\u30d9\u30eb label.by.pod=\u30dd\u30c3\u30c9 label.by.role=\u5f79\u5272 label.by.start.date=\u958b\u59cb\u65e5 label.by.state=\u72b6\u614b +label.bytes.received=\u53d7\u4fe1\u30d0\u30a4\u30c8 +label.bytes.sent=\u9001\u4fe1\u30d0\u30a4\u30c8 label.by.traffic.type=\u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u306e\u7a2e\u985e label.by.type.id=\u7a2e\u985e ID label.by.type=\u7a2e\u985e label.by.zone=\u30be\u30fc\u30f3 -label.bytes.received=\u53d7\u4fe1\u30d0\u30a4\u30c8 -label.bytes.sent=\u9001\u4fe1\u30d0\u30a4\u30c8 +label.cache.mode=\u66f8\u304d\u8fbc\u307f\u30ad\u30e3\u30c3\u30b7\u30e5\u306e\u7a2e\u985e label.cancel=\u30ad\u30e3\u30f3\u30bb\u30eb label.capacity=\u51e6\u7406\u80fd\u529b label.certificate=\u8a3c\u660e\u66f8 +label.change.affinity=\u30a2\u30d5\u30a3\u30cb\u30c6\u30a3\u306e\u5909\u66f4 label.change.service.offering=\u30b5\u30fc\u30d3\u30b9 \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0\u306e\u5909\u66f4 label.change.value=\u5024\u306e\u5909\u66f4 label.character=\u6587\u5b57 +label.chassis=\u30b7\u30e3\u30fc\u30b7 label.checksum=MD5 \u30c1\u30a7\u30c3\u30af\u30b5\u30e0 label.cidr.account=CIDR \u307e\u305f\u306f\u30a2\u30ab\u30a6\u30f3\u30c8/\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3 \u30b0\u30eb\u30fc\u30d7 +label.cidr=CIDR label.CIDR.list=CIDR \u4e00\u89a7 label.cidr.list=\u9001\u4fe1\u5143 CIDR label.CIDR.of.destination.network=\u5b9b\u5148\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306e CIDR -label.cidr=CIDR +label.cisco.nexus1000v.ip.address=Nexus 1000V \u306e IP \u30a2\u30c9\u30ec\u30b9 +label.cisco.nexus1000v.password=Nexus 1000V \u306e\u30d1\u30b9\u30ef\u30fc\u30c9 +label.cisco.nexus1000v.username=Nexus 1000V \u306e\u30e6\u30fc\u30b6\u30fc\u540d +label.ciscovnmc.resource.details=Cisco VNMC \u30ea\u30bd\u30fc\u30b9\u306e\u8a73\u7d30 label.clean.up=\u30af\u30ea\u30fc\u30f3 \u30a2\u30c3\u30d7\u3059\u308b label.clear.list=\u4e00\u89a7\u306e\u6d88\u53bb label.close=\u9589\u3058\u308b label.cloud.console=\u30af\u30e9\u30a6\u30c9\u7ba1\u7406\u30b3\u30f3\u30bd\u30fc\u30eb label.cloud.managed=Cloud.com \u306b\u3088\u308b\u7ba1\u7406 label.cluster.name=\u30af\u30e9\u30b9\u30bf\u30fc\u540d +label.clusters=\u30af\u30e9\u30b9\u30bf\u30fc label.cluster.type=\u30af\u30e9\u30b9\u30bf\u30fc\u306e\u7a2e\u985e label.cluster=\u30af\u30e9\u30b9\u30bf\u30fc -label.clusters=\u30af\u30e9\u30b9\u30bf\u30fc label.clvm=CLVM -label.rbd=RBD -label.rbd.monitor=Ceph \u30e2\u30cb\u30bf\u30fc -label.rbd.pool=Ceph \u30d7\u30fc\u30eb -label.rbd.id=Cephx \u30e6\u30fc\u30b6\u30fc -label.rbd.secret=Cephx \u30b7\u30fc\u30af\u30ec\u30c3\u30c8 label.code=\u30b3\u30fc\u30c9 label.community=\u30b3\u30df\u30e5\u30cb\u30c6\u30a3 label.compute.and.storage=\u30b3\u30f3\u30d4\u30e5\u30fc\u30c6\u30a3\u30f3\u30b0\u3068\u30b9\u30c8\u30ec\u30fc\u30b8 -label.compute.offering=\u30b3\u30f3\u30d4\u30e5\u30fc\u30c6\u30a3\u30f3\u30b0 \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0 label.compute.offerings=\u30b3\u30f3\u30d4\u30e5\u30fc\u30c6\u30a3\u30f3\u30b0 \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0 +label.compute.offering=\u30b3\u30f3\u30d4\u30e5\u30fc\u30c6\u30a3\u30f3\u30b0 \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0 label.compute=\u30b3\u30f3\u30d4\u30e5\u30fc\u30c6\u30a3\u30f3\u30b0 label.configuration=\u69cb\u6210 +label.configure.ldap=LDAP \u306e\u69cb\u6210 label.configure.network.ACLs=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af ACL \u306e\u69cb\u6210 -label.configure.vpc=VPC \u306e\u69cb\u6210 label.configure=\u69cb\u6210 -label.confirm.password=\u30d1\u30b9\u30ef\u30fc\u30c9\u306e\u78ba\u8a8d\u5165\u529b +label.configure.vpc=VPC \u306e\u69cb\u6210 label.confirmation=\u78ba\u8a8d +label.confirm.password=\u30d1\u30b9\u30ef\u30fc\u30c9\u306e\u78ba\u8a8d\u5165\u529b label.congratulations=\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7\u306f\u3053\u308c\u3067\u5b8c\u4e86\u3067\u3059\u3002 label.conserve.mode=\u7bc0\u7d04\u30e2\u30fc\u30c9 label.console.proxy=\u30b3\u30f3\u30bd\u30fc\u30eb \u30d7\u30ed\u30ad\u30b7 +label.console.proxy.vm=\u30b3\u30f3\u30bd\u30fc\u30eb \u30d7\u30ed\u30ad\u30b7 VM label.continue.basic.install=\u57fa\u672c\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3092\u7d9a\u884c\u3059\u308b label.continue=\u7d9a\u884c label.corrections.saved=\u63a5\u7d9a\u304c\u4fdd\u5b58\u3055\u308c\u307e\u3057\u305f label.cpu.allocated.for.VMs=VM \u306b\u5272\u308a\u5f53\u3066\u6e08\u307f\u306e CPU label.cpu.allocated=\u5272\u308a\u5f53\u3066\u6e08\u307f\u306e CPU -label.CPU.cap=CPU \u30ad\u30e3\u30c3\u30d7 +label.CPU.cap=CPU \u4e0a\u9650 +label.cpu=CPU label.cpu.limits=CPU \u5236\u9650 label.cpu.mhz=CPU (MHz) label.cpu.utilized=CPU \u4f7f\u7528\u7387 -label.cpu=CPU +label.created.by.system=\u30b7\u30b9\u30c6\u30e0\u4f5c\u6210 +label.created=\u4f5c\u6210\u65e5\u6642 +label.create.nfs.secondary.staging.storage=NFS \u30bb\u30ab\u30f3\u30c0\u30ea \u30b9\u30c6\u30fc\u30b8\u30f3\u30b0 \u30b9\u30c8\u30a2\u3092\u4f5c\u6210\u3059\u308b +label.create.nfs.secondary.staging.store=NFS \u30bb\u30ab\u30f3\u30c0\u30ea \u30b9\u30c6\u30fc\u30b8\u30f3\u30b0 \u30b9\u30c8\u30a2\u3092\u4f5c\u6210\u3059\u308b label.create.project=\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u306e\u4f5c\u6210 label.create.template=\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u306e\u4f5c\u6210 label.create.VPN.connection=VPN \u63a5\u7d9a\u306e\u4f5c\u6210 -label.created.by.system=\u30b7\u30b9\u30c6\u30e0\u4f5c\u6210 -label.created=\u4f5c\u6210\u65e5\u6642 label.cross.zones=\u30af\u30ed\u30b9 \u30be\u30fc\u30f3 +label.custom.disk.iops=\u30ab\u30b9\u30bf\u30e0 IOPS label.custom.disk.size=\u30ab\u30b9\u30bf\u30e0 \u30c7\u30a3\u30b9\u30af \u30b5\u30a4\u30ba +label.custom=\u30ab\u30b9\u30bf\u30e0 label.daily=\u6bce\u65e5 label.data.disk.offering=\u30c7\u30fc\u30bf \u30c7\u30a3\u30b9\u30af \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0 label.date=\u65e5\u6642 label.day.of.month=\u6bce\u6708\u6307\u5b9a\u65e5 label.day.of.week=\u6bce\u9031\u6307\u5b9a\u65e5 +label.dc.name=DC \u540d label.dead.peer.detection=\u505c\u6b62\u30d4\u30a2\u3092\u691c\u51fa\u3059\u308b label.decline.invitation=\u62db\u5f85\u306e\u8f9e\u9000 +label.dedicate.cluster=\u30af\u30e9\u30b9\u30bf\u30fc\u3092\u5c02\u7528\u306b\u8a2d\u5b9a label.dedicated=\u5c02\u7528 +label.dedicated.vlan.vni.ranges=\u5c02\u7528 VLAN/VNI \u306e\u7bc4\u56f2 +label.dedicate.host=\u30db\u30b9\u30c8\u3092\u5c02\u7528\u306b\u8a2d\u5b9a +label.dedicate.pod=\u30dd\u30c3\u30c9\u3092\u5c02\u7528\u306b\u8a2d\u5b9a +label.dedicate=\u5c02\u7528\u306b\u8a2d\u5b9a +label.dedicate.vlan.vni.range=VLAN/VNI \u306e\u7bc4\u56f2\u3092\u5c02\u7528\u306b\u8a2d\u5b9a +label.dedicate.zone=\u30be\u30fc\u30f3\u3092\u5c02\u7528\u306b\u8a2d\u5b9a +label.default.egress.policy=\u30c7\u30d5\u30a9\u30eb\u30c8\u306e\u9001\u4fe1\u30dd\u30ea\u30b7\u30fc +label.default=\u30c7\u30d5\u30a9\u30eb\u30c8 label.default.use=\u30c7\u30d5\u30a9\u30eb\u30c8\u4f7f\u7528 label.default.view=\u30c7\u30d5\u30a9\u30eb\u30c8 \u30d3\u30e5\u30fc -label.default=\u30c7\u30d5\u30a9\u30eb\u30c8 label.delete.affinity.group=\u30a2\u30d5\u30a3\u30cb\u30c6\u30a3 \u30b0\u30eb\u30fc\u30d7\u306e\u524a\u9664 +label.delete.alerts=\u30a2\u30e9\u30fc\u30c8\u306e\u524a\u9664 label.delete.BigSwitchVns=Big Switch VNS \u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u306e\u524a\u9664 +label.delete.ciscovnmc.resource=Cisco VNMC \u30ea\u30bd\u30fc\u30b9\u306e\u524a\u9664 +label.delete.events=\u30a4\u30d9\u30f3\u30c8\u306e\u524a\u9664 label.delete.F5=F5 \u306e\u524a\u9664 label.delete.gateway=\u30b2\u30fc\u30c8\u30a6\u30a7\u30a4\u306e\u524a\u9664 label.delete.NetScaler=NetScaler \u306e\u524a\u9664 label.delete.NiciraNvp=NVP \u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u306e\u524a\u9664 +label.delete.OpenDaylight.device=OpenDaylight \u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u306e\u524a\u9664 +label.delete.PA=Palo Alto \u306e\u524a\u9664 +label.delete.portable.ip.range=\u30dd\u30fc\u30bf\u30d6\u30eb IP \u30a2\u30c9\u30ec\u30b9\u306e\u7bc4\u56f2\u306e\u524a\u9664 +label.delete.profile=\u30d7\u30ed\u30d5\u30a1\u30a4\u30eb\u306e\u524a\u9664 label.delete.project=\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u306e\u524a\u9664 +label.delete.secondary.staging.store=\u30bb\u30ab\u30f3\u30c0\u30ea \u30b9\u30c6\u30fc\u30b8\u30f3\u30b0 \u30b9\u30c8\u30a2\u306e\u524a\u9664 label.delete.SRX=SRX \u306e\u524a\u9664 -label.delete.PA=Palo Alto \u306e\u524a\u9664 +label.delete=\u524a\u9664 +label.delete.ucs.manager=UCS Manager \u306e\u524a\u9664 label.delete.VPN.connection=VPN \u63a5\u7d9a\u306e\u524a\u9664 label.delete.VPN.customer.gateway=VPN \u30ab\u30b9\u30bf\u30de\u30fc \u30b2\u30fc\u30c8\u30a6\u30a7\u30a4\u306e\u524a\u9664 label.delete.VPN.gateway=VPN \u30b2\u30fc\u30c8\u30a6\u30a7\u30a4\u306e\u524a\u9664 label.delete.vpn.user=VPN \u30e6\u30fc\u30b6\u30fc\u306e\u524a\u9664 -label.delete=\u524a\u9664 label.deleting.failed=\u524a\u9664\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f label.deleting.processing=\u524a\u9664\u3057\u3066\u3044\u307e\u3059... +label.deny=\u62d2\u5426 +label.deployment.planner=\u5c55\u958b\u30d7\u30e9\u30f3\u30ca\u30fc label.description=\u8aac\u660e label.destination.physical.network.id=\u30d6\u30ea\u30c3\u30b8\u5148\u7269\u7406\u30cd\u30c3\u30c8\u30ef\u30fc\u30af ID label.destination.zone=\u30b3\u30d4\u30fc\u5148\u30be\u30fc\u30f3 label.destroy.router=\u30eb\u30fc\u30bf\u30fc\u306e\u7834\u68c4 label.destroy=\u7834\u68c4 +label.destroy.vm.graceperiod=VM \u7834\u68c4\u306e\u7336\u4e88\u671f\u9593 label.detaching.disk=\u30c7\u30a3\u30b9\u30af\u3092\u30c7\u30bf\u30c3\u30c1\u3057\u3066\u3044\u307e\u3059 label.details=\u8a73\u7d30 label.device.id=\u30c7\u30d0\u30a4\u30b9 ID label.devices=\u30c7\u30d0\u30a4\u30b9 -label.DHCP.server.type=DHCP \u30b5\u30fc\u30d0\u30fc\u306e\u7a2e\u985e label.dhcp=DHCP +label.DHCP.server.type=DHCP \u30b5\u30fc\u30d0\u30fc\u306e\u7a2e\u985e label.direct.ips=\u5171\u6709\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306e IP \u30a2\u30c9\u30ec\u30b9 +label.disable.autoscale=\u81ea\u52d5\u30b5\u30a4\u30ba\u8a2d\u5b9a\u306e\u7121\u52b9\u5316 +label.disabled=\u7121\u52b9 +label.disable.network.offering=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0\u306e\u7121\u52b9\u5316 label.disable.provider=\u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u306e\u7121\u52b9\u5316 +label.disable.vnmc.provider=VNMC \u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u306e\u7121\u52b9\u5316 +label.disable.vpc.offering=VPC \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0\u306e\u7121\u52b9\u5316 label.disable.vpn=VPN \u306e\u7121\u52b9\u5316 -label.disabled=\u7121\u52b9 label.disabling.vpn.access=VPN \u30a2\u30af\u30bb\u30b9\u3092\u7121\u52b9\u306b\u3057\u3066\u3044\u307e\u3059 +label.disassociate.profile.blade=\u30d7\u30ed\u30d5\u30a1\u30a4\u30eb\u3068\u30d6\u30ec\u30fc\u30c9\u306e\u95a2\u9023\u4ed8\u3051\u306e\u89e3\u9664 +label.disbale.vnmc.device=VNMC \u30c7\u30d0\u30a4\u30b9\u306e\u7121\u52b9\u5316 label.disk.allocated=\u5272\u308a\u5f53\u3066\u6e08\u307f\u306e\u30c7\u30a3\u30b9\u30af label.disk.bytes.read.rate=\u30c7\u30a3\u30b9\u30af\u8aad\u307f\u53d6\u308a\u901f\u5ea6 (BPS) label.disk.bytes.write.rate=\u30c7\u30a3\u30b9\u30af\u66f8\u304d\u8fbc\u307f\u901f\u5ea6 (BPS) +label.disk.iops.max=\u6700\u5927 IOPS +label.disk.iops.min=\u6700\u5c0f IOPS label.disk.iops.read.rate=\u30c7\u30a3\u30b9\u30af\u8aad\u307f\u53d6\u308a\u901f\u5ea6 (IOPS) +label.disk.iops.total=IOPS \u5408\u8a08 label.disk.iops.write.rate=\u30c7\u30a3\u30b9\u30af\u66f8\u304d\u8fbc\u307f\u901f\u5ea6 (IOPS) label.disk.offering=\u30c7\u30a3\u30b9\u30af \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0 label.disk.read.bytes=\u30c7\u30a3\u30b9\u30af\u8aad\u307f\u53d6\u308a (\u30d0\u30a4\u30c8) @@ -535,47 +568,58 @@ label.disk.write.bytes=\u30c7\u30a3\u30b9\u30af\u66f8\u304d\u8fbc\u307f (\u30d0\ label.disk.write.io=\u30c7\u30a3\u30b9\u30af\u66f8\u304d\u8fbc\u307f (IO) label.display.name=\u8868\u793a\u540d label.display.text=\u8868\u793a\u30c6\u30ad\u30b9\u30c8 +label.distributedrouter=\u5206\u6563\u30eb\u30fc\u30bf\u30fc label.dns.1=DNS 1 label.dns.2=DNS 2 -label.DNS.domain.for.guest.networks=\u30b2\u30b9\u30c8 \u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306e DNS \u30c9\u30e1\u30a4\u30f3 label.dns=DNS +label.DNS.domain.for.guest.networks=\u30b2\u30b9\u30c8 \u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306e DNS \u30c9\u30e1\u30a4\u30f3 label.domain.admin=\u30c9\u30e1\u30a4\u30f3\u7ba1\u7406\u8005 label.domain.id=\u30c9\u30e1\u30a4\u30f3 ID +label.domain.lower=\u30c9\u30e1\u30a4\u30f3 label.domain.name=\u30c9\u30e1\u30a4\u30f3\u540d label.domain.router=\u30c9\u30e1\u30a4\u30f3 \u30eb\u30fc\u30bf\u30fc -label.domain.suffix=DNS \u30c9\u30e1\u30a4\u30f3 \u30b5\u30d5\u30a3\u30c3\u30af\u30b9 (\u4f8b: xyz.com) +label.domain.suffix=DNS \u30c9\u30e1\u30a4\u30f3 \u30b5\u30d5\u30a3\u30c3\u30af\u30b9 (\u4f8b\: xyz.com) label.domain=\u30c9\u30e1\u30a4\u30f3 label.done=\u5b8c\u4e86 label.double.quotes.are.not.allowed=\u4e8c\u91cd\u5f15\u7528\u7b26\u306f\u4f7f\u7528\u3067\u304d\u307e\u305b\u3093 label.download.progress=\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u306e\u9032\u6357\u72b6\u6cc1 label.drag.new.position=\u65b0\u3057\u3044\u4f4d\u7f6e\u306b\u30c9\u30e9\u30c3\u30b0 +label.dynamically.scalable=\u52d5\u7684\u306b\u30b5\u30a4\u30ba\u8a2d\u5b9a\u3059\u308b label.edit.affinity.group=\u30a2\u30d5\u30a3\u30cb\u30c6\u30a3 \u30b0\u30eb\u30fc\u30d7\u306e\u7de8\u96c6 label.edit.lb.rule=\u8ca0\u8377\u5206\u6563\u898f\u5247\u306e\u7de8\u96c6 label.edit.network.details=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306e\u8a73\u7d30\u306e\u7de8\u96c6 label.edit.project.details=\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u306e\u8a73\u7d30\u306e\u7de8\u96c6 +label.edit.region=\u30ea\u30fc\u30b8\u30e7\u30f3\u306e\u7de8\u96c6 label.edit.tags=\u30bf\u30b0\u306e\u7de8\u96c6 label.edit.traffic.type=\u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u306e\u7a2e\u985e\u306e\u7de8\u96c6 -label.edit.vpc=VPC \u306e\u7de8\u96c6 label.edit=\u7de8\u96c6 -label.egress.rule=\u9001\u4fe1\u898f\u5247 +label.edit.vpc=VPC \u306e\u7de8\u96c6 +label.egress.default.policy=\u9001\u4fe1\u306e\u30c7\u30d5\u30a9\u30eb\u30c8 \u30dd\u30ea\u30b7\u30fc label.egress.rules=\u9001\u4fe1\u898f\u5247 +label.egress.rule=\u9001\u4fe1\u898f\u5247 label.elastic.IP=\u30a8\u30e9\u30b9\u30c6\u30a3\u30c3\u30af IP \u30a2\u30c9\u30ec\u30b9 label.elastic.LB=\u30a8\u30e9\u30b9\u30c6\u30a3\u30c3\u30af\u8ca0\u8377\u5206\u6563 label.elastic=\u30a8\u30e9\u30b9\u30c6\u30a3\u30c3\u30af +label.email.lower=\u96fb\u5b50\u30e1\u30fc\u30eb label.email=\u96fb\u5b50\u30e1\u30fc\u30eb +label.enable.autoscale=\u81ea\u52d5\u30b5\u30a4\u30ba\u8a2d\u5b9a\u306e\u6709\u52b9\u5316 +label.enable.network.offering=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0\u306e\u6709\u52b9\u5316 label.enable.provider=\u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u306e\u6709\u52b9\u5316 label.enable.s3=S3 \u30d9\u30fc\u30b9\u306e\u30bb\u30ab\u30f3\u30c0\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8\u306e\u6709\u52b9\u5316 label.enable.swift=Swift \u306e\u6709\u52b9\u5316 +label.enable.vnmc.device=VNMC \u30c7\u30d0\u30a4\u30b9\u306e\u6709\u52b9\u5316 +label.enable.vnmc.provider=VNMC \u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u306e\u6709\u52b9\u5316 +label.enable.vpc.offering=VPC \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0\u306e\u6709\u52b9\u5316 label.enable.vpn=VPN \u306e\u6709\u52b9\u5316 label.enabling.vpn.access=VPN \u30a2\u30af\u30bb\u30b9\u3092\u6709\u52b9\u306b\u3057\u3066\u3044\u307e\u3059 label.enabling.vpn=VPN \u3092\u6709\u52b9\u306b\u3057\u3066\u3044\u307e\u3059 label.end.IP=\u7d42\u4e86 IP \u30a2\u30c9\u30ec\u30b9 +label.endpoint.or.operation=\u30a8\u30f3\u30c9\u30dd\u30a4\u30f3\u30c8\u307e\u305f\u306f\u64cd\u4f5c +label.endpoint=\u30a8\u30f3\u30c9\u30dd\u30a4\u30f3\u30c8 label.end.port=\u7d42\u4e86\u30dd\u30fc\u30c8 label.end.reserved.system.IP=\u4e88\u7d04\u6e08\u307f\u7d42\u4e86\u30b7\u30b9\u30c6\u30e0 IP \u30a2\u30c9\u30ec\u30b9 label.end.vlan=\u7d42\u4e86 VLAN label.end.vxlan=\u7d42\u4e86 VXLAN -label.endpoint.or.operation=\u30a8\u30f3\u30c9\u30dd\u30a4\u30f3\u30c8\u307e\u305f\u306f\u64cd\u4f5c -label.endpoint=\u30a8\u30f3\u30c9\u30dd\u30a4\u30f3\u30c8 label.enter.token=\u30c8\u30fc\u30af\u30f3\u306e\u5165\u529b label.error.code=\u30a8\u30e9\u30fc \u30b3\u30fc\u30c9 label.error=\u30a8\u30e9\u30fc @@ -587,12 +631,14 @@ label.esx.host=ESX/ESXi \u30db\u30b9\u30c8 label.example=\u4f8b label.expunge=\u62b9\u6d88 label.external.link=\u5916\u90e8\u30ea\u30f3\u30af +label.f5.details=F5 \u306e\u8a73\u7d30 label.f5=F5 label.failed=\u5931\u6557 label.featured=\u304a\u3059\u3059\u3081 label.fetch.latest=\u6700\u65b0\u60c5\u5831\u306e\u53d6\u5f97 label.filterBy=\u30d5\u30a3\u30eb\u30bf\u30fc label.firewall=\u30d5\u30a1\u30a4\u30a2\u30a6\u30a9\u30fc\u30eb +label.firstname.lower=\u540d label.first.name=\u540d label.format=\u5f62\u5f0f label.friday=\u91d1\u66dc\u65e5 @@ -606,34 +652,59 @@ label.go.step.2=\u624b\u9806 2 \u306b\u9032\u3080 label.go.step.3=\u624b\u9806 3 \u306b\u9032\u3080 label.go.step.4=\u624b\u9806 4 \u306b\u9032\u3080 label.go.step.5=\u624b\u9806 5 \u306b\u9032\u3080 +label.gpu=GPU +label.group.by.account=\u30a2\u30ab\u30a6\u30f3\u30c8\u5225\u30b0\u30eb\u30fc\u30d7 +label.group.by.cluster=\u30af\u30e9\u30b9\u30bf\u30fc\u5225\u30b0\u30eb\u30fc\u30d7 +label.group.by.pod=\u30dd\u30c3\u30c9\u5225\u30b0\u30eb\u30fc\u30d7 +label.group.by.zone=\u30be\u30fc\u30f3\u5225\u30b0\u30eb\u30fc\u30d7 label.group.optional=\u30b0\u30eb\u30fc\u30d7 (\u30aa\u30d7\u30b7\u30e7\u30f3) label.group=\u30b0\u30eb\u30fc\u30d7 +label.gslb.assigned.lb.more=\u8ca0\u8377\u5206\u6563\u306e\u8ffd\u52a0\u5272\u308a\u5f53\u3066 +label.gslb.assigned.lb=\u5272\u308a\u5f53\u3066\u6e08\u307f\u8ca0\u8377\u5206\u6563 +label.gslb.delete=GSLB \u306e\u524a\u9664 +label.gslb.details=GSLB \u306e\u8a73\u7d30 +label.gslb.domain.name=GSLB \u30c9\u30e1\u30a4\u30f3\u540d +label.gslb.lb.details=\u8ca0\u8377\u5206\u6563\u306e\u8a73\u7d30 +label.gslb.lb.remove=\u3053\u306e GSLB \u304b\u3089\u8ca0\u8377\u5206\u6563\u3092\u524a\u9664 +label.gslb.lb.rule=\u8ca0\u8377\u5206\u6563\u898f\u5247 +label.gslb.service=GSLB \u30b5\u30fc\u30d3\u30b9 +label.gslb.service.private.ip=GSLB \u30b5\u30fc\u30d3\u30b9\u306e\u30d7\u30e9\u30a4\u30d9\u30fc\u30c8 IP \u30a2\u30c9\u30ec\u30b9 +label.gslb.service.public.ip=GSLB \u30b5\u30fc\u30d3\u30b9\u306e\u30d1\u30d6\u30ea\u30c3\u30af IP \u30a2\u30c9\u30ec\u30b9 +label.gslb.servicetype=\u30b5\u30fc\u30d3\u30b9\u306e\u7a2e\u985e label.guest.cidr=\u30b2\u30b9\u30c8 CIDR label.guest.end.ip=\u30b2\u30b9\u30c8\u306e\u7d42\u4e86 IP \u30a2\u30c9\u30ec\u30b9 label.guest.gateway=\u30b2\u30b9\u30c8 \u30b2\u30fc\u30c8\u30a6\u30a7\u30a4 label.guest.ip.range=\u30b2\u30b9\u30c8 IP \u30a2\u30c9\u30ec\u30b9\u306e\u7bc4\u56f2 label.guest.ip=\u30b2\u30b9\u30c8 IP \u30a2\u30c9\u30ec\u30b9 label.guest.netmask=\u30b2\u30b9\u30c8 \u30cd\u30c3\u30c8\u30de\u30b9\u30af +label.guest.network.details=\u30b2\u30b9\u30c8 \u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306e\u8a73\u7d30 label.guest.networks=\u30b2\u30b9\u30c8 \u30cd\u30c3\u30c8\u30ef\u30fc\u30af label.guest.start.ip=\u30b2\u30b9\u30c8\u306e\u958b\u59cb IP \u30a2\u30c9\u30ec\u30b9 label.guest.traffic=\u30b2\u30b9\u30c8 \u30c8\u30e9\u30d5\u30a3\u30c3\u30af +label.guest.traffic.vswitch.name=\u30b2\u30b9\u30c8 \u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u306e vSwitch \u540d +label.guest.traffic.vswitch.type=\u30b2\u30b9\u30c8 \u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u306e vSwitch \u306e\u7a2e\u985e label.guest.type=\u30b2\u30b9\u30c8\u306e\u7a2e\u985e label.guest=\u30b2\u30b9\u30c8 label.ha.enabled=\u9ad8\u53ef\u7528\u6027\u6709\u52b9 +label.health.check=\u30d8\u30eb\u30b9 \u30c1\u30a7\u30c3\u30af label.help=\u30d8\u30eb\u30d7 label.hide.ingress.rule=\u53d7\u4fe1\u898f\u5247\u3092\u96a0\u3059 label.hints=\u30d2\u30f3\u30c8 +label.home=\u30db\u30fc\u30e0 label.host.alerts=\u30db\u30b9\u30c8 \u30a2\u30e9\u30fc\u30c8 label.host.MAC=\u30db\u30b9\u30c8\u306e MAC label.host.name=\u30db\u30b9\u30c8\u540d +label.hosts=\u30db\u30b9\u30c8 label.host.tags=\u30db\u30b9\u30c8 \u30bf\u30b0 label.host=\u30db\u30b9\u30c8 -label.hosts=\u30db\u30b9\u30c8 label.hourly=\u6bce\u6642 label.hypervisor.capabilities=\u30cf\u30a4\u30d1\u30fc\u30d0\u30a4\u30b6\u30fc\u306e\u6a5f\u80fd +label.hypervisor.snapshot.reserve=\u30cf\u30a4\u30d1\u30fc\u30d0\u30a4\u30b6\u30fc \u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8\u4e88\u7d04 +label.hypervisors=\u30cf\u30a4\u30d1\u30fc\u30d0\u30a4\u30b6\u30fc label.hypervisor.type=\u30cf\u30a4\u30d1\u30fc\u30d0\u30a4\u30b6\u30fc\u306e\u7a2e\u985e -label.hypervisor.version=\u30cf\u30a4\u30d1\u30fc\u30d0\u30a4\u30b6\u30fc\u306e\u30d0\u30fc\u30b8\u30e7\u30f3 label.hypervisor=\u30cf\u30a4\u30d1\u30fc\u30d0\u30a4\u30b6\u30fc +label.hypervisor.version=\u30cf\u30a4\u30d1\u30fc\u30d0\u30a4\u30b6\u30fc\u306e\u30d0\u30fc\u30b8\u30e7\u30f3 +label.hyperv.traffic.label=Hyper-V \u306e\u30c8\u30e9\u30d5\u30a3\u30c3\u30af \u30e9\u30d9\u30eb label.id=ID label.IKE.DH=IKE DH label.IKE.encryption=IKE \u6697\u53f7\u5316 @@ -653,16 +724,18 @@ label.installWizard.addPrimaryStorageIntro.subtitle=\u30d7\u30e9\u30a4\u30de\u30 label.installWizard.addPrimaryStorageIntro.title=\u30d7\u30e9\u30a4\u30de\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8\u3092\u8ffd\u52a0\u3057\u307e\u3057\u3087\u3046 label.installWizard.addSecondaryStorageIntro.subtitle=\u30bb\u30ab\u30f3\u30c0\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8\u306b\u3064\u3044\u3066 label.installWizard.addSecondaryStorageIntro.title=\u30bb\u30ab\u30f3\u30c0\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8\u3092\u8ffd\u52a0\u3057\u307e\u3057\u3087\u3046 -label.installWizard.addZone.title=\u30be\u30fc\u30f3\u306e\u8ffd\u52a0 label.installWizard.addZoneIntro.subtitle=\u30be\u30fc\u30f3\u306b\u3064\u3044\u3066 label.installWizard.addZoneIntro.title=\u30be\u30fc\u30f3\u3092\u8ffd\u52a0\u3057\u307e\u3057\u3087\u3046 +label.installWizard.addZone.title=\u30be\u30fc\u30f3\u306e\u8ffd\u52a0 label.installWizard.click.launch=[\u8d77\u52d5] \u3092\u30af\u30ea\u30c3\u30af\u3057\u3066\u304f\u3060\u3055\u3044\u3002 label.installWizard.subtitle=\u3053\u306e\u30ac\u30a4\u30c9 \u30c4\u30a2\u30fc\u306f CloudStack&\#8482; \u74b0\u5883\u306e\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7\u306b\u5f79\u7acb\u3061\u307e\u3059 label.installWizard.title=CloudStack&\#8482; \u3078\u3088\u3046\u3053\u305d label.instance.limits=\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u5236\u9650 label.instance.name=\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u540d -label.instance=\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9 +label.instance.scaled.up=\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u306e\u30b5\u30a4\u30ba\u304c\u62e1\u5927\u3055\u308c\u307e\u3057\u305f label.instances=\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9 +label.instance=\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9 +label.instanciate.template.associate.profile.blade=\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u306e\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u4f5c\u6210\u304a\u3088\u3073\u30d7\u30ed\u30d5\u30a1\u30a4\u30eb\u3068\u30d6\u30ec\u30fc\u30c9\u306e\u95a2\u9023\u4ed8\u3051 label.internal.dns.1=\u5185\u90e8 DNS 1 label.internal.dns.2=\u5185\u90e8 DNS 2 label.internal.name=\u5185\u90e8\u540d @@ -671,34 +744,46 @@ label.introduction.to.cloudstack=CloudStack&\#8482; \u306e\u7d39\u4ecb label.invalid.integer=\u7121\u52b9\u306a\u6574\u6570 label.invalid.number=\u7121\u52b9\u306a\u6570 label.invitations=\u62db\u5f85\u72b6 -label.invite.to=\u62db\u5f85\u3059\u308b\u30d7\u30ed\u30b8\u30a7\u30af\u30c8: -label.invite=\u62db\u5f85 label.invited.accounts=\u62db\u5f85\u6e08\u307f\u30a2\u30ab\u30a6\u30f3\u30c8 +label.invite.to=\u62db\u5f85\u3059\u308b\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\: +label.invite=\u62db\u5f85 label.ip.address=IP \u30a2\u30c9\u30ec\u30b9 +label.ipaddress=IP \u30a2\u30c9\u30ec\u30b9 label.ip.allocations=IP \u30a2\u30c9\u30ec\u30b9\u306e\u5272\u308a\u5f53\u3066 +label.ip=IP label.ip.limits=\u30d1\u30d6\u30ea\u30c3\u30af IP \u30a2\u30c9\u30ec\u30b9\u306e\u5236\u9650 label.ip.or.fqdn=IP \u30a2\u30c9\u30ec\u30b9\u307e\u305f\u306f FQDN label.ip.range=IP \u30a2\u30c9\u30ec\u30b9\u306e\u7bc4\u56f2 label.ip.ranges=IP \u30a2\u30c9\u30ec\u30b9\u306e\u7bc4\u56f2 -label.ip=IP -label.ipaddress=IP \u30a2\u30c9\u30ec\u30b9 -label.ips=IP \u30a2\u30c9\u30ec\u30b9 label.IPsec.preshared.key=IPsec \u4e8b\u524d\u5171\u6709\u30ad\u30fc -label.is.default=\u30c7\u30d5\u30a9\u30eb\u30c8 -label.is.redundant.router=\u5197\u9577 -label.is.shared=\u5171\u6709 -label.is.system=\u30b7\u30b9\u30c6\u30e0 +label.ips=IP \u30a2\u30c9\u30ec\u30b9 +label.ipv4.cidr=IPv4 CIDR +label.ipv4.end.ip=IPv4 \u7d42\u4e86 IP \u30a2\u30c9\u30ec\u30b9 +label.ipv4.gateway=IPv4 \u30b2\u30fc\u30c8\u30a6\u30a7\u30a4 +label.ipv4.netmask=IPv4 \u30cd\u30c3\u30c8\u30de\u30b9\u30af +label.ipv4.start.ip=IPv4 \u958b\u59cb IP \u30a2\u30c9\u30ec\u30b9 +label.ipv6.address=IPv6 IP \u30a2\u30c9\u30ec\u30b9 +label.ipv6.CIDR=IPv6 CIDR +label.ipv6.dns1=IPv6 DNS 1 +label.ipv6.dns2=IPv6 DNS 2 +label.ipv6.end.ip=IPv6 \u7d42\u4e86 IP \u30a2\u30c9\u30ec\u30b9 +label.ipv6.gateway=IPv6 \u30b2\u30fc\u30c8\u30a6\u30a7\u30a4 +label.ipv6.start.ip=IPv6 \u958b\u59cb IP \u30a2\u30c9\u30ec\u30b9 label.iscsi=iSCSI +label.is.default=\u30c7\u30d5\u30a9\u30eb\u30c8 label.iso.boot=ISO \u8d77\u52d5 label.iso=ISO label.isolated.networks=\u5206\u96e2\u3055\u308c\u305f\u30cd\u30c3\u30c8\u30ef\u30fc\u30af label.isolation.method=\u5206\u96e2\u65b9\u6cd5 label.isolation.mode=\u5206\u96e2\u30e2\u30fc\u30c9 label.isolation.uri=\u5206\u96e2 URI +label.is.redundant.router=\u5197\u9577 +label.is.shared=\u5171\u6709 +label.is.system=\u30b7\u30b9\u30c6\u30e0 label.item.listing=\u9805\u76ee\u4e00\u89a7 label.keep=\u7dad\u6301 -label.key=\u30ad\u30fc label.keyboard.type=\u30ad\u30fc\u30dc\u30fc\u30c9\u306e\u7a2e\u985e +label.key=\u30ad\u30fc label.kvm.traffic.label=KVM \u306e\u30c8\u30e9\u30d5\u30a3\u30c3\u30af \u30e9\u30d9\u30eb label.label=\u30e9\u30d9\u30eb label.lang.arabic=\u30a2\u30e9\u30d3\u30a2\u8a9e @@ -717,12 +802,16 @@ label.lang.polish=\u30dd\u30fc\u30e9\u30f3\u30c9\u8a9e label.lang.russian=\u30ed\u30b7\u30a2\u8a9e label.lang.spanish=\u30b9\u30da\u30a4\u30f3\u8a9e label.last.disconnected=\u6700\u7d42\u5207\u65ad\u65e5\u6642 +label.lastname.lower=\u59d3 label.last.name=\u59d3 label.latest.events=\u6700\u65b0\u30a4\u30d9\u30f3\u30c8 +label.launch=\u8d77\u52d5 label.launch.vm=VM \u306e\u8d77\u52d5 label.launch.zone=\u30be\u30fc\u30f3\u306e\u8d77\u52d5 -label.launch=\u8d77\u52d5 label.LB.isolation=\u8ca0\u8377\u5206\u6563\u5206\u96e2 +label.ldap.configuration=LDAP \u69cb\u6210 +label.ldap.group.name=LDAP \u30b0\u30eb\u30fc\u30d7 +label.ldap.port=LDAP \u30dd\u30fc\u30c8 label.least.connections=\u6700\u5c0f\u63a5\u7d9a label.level=\u30ec\u30d9\u30eb label.linklocal.ip=\u30ea\u30f3\u30af \u30ed\u30fc\u30ab\u30eb IP \u30a2\u30c9\u30ec\u30b9 @@ -735,15 +824,18 @@ label.local.storage=\u30ed\u30fc\u30ab\u30eb \u30b9\u30c8\u30ec\u30fc\u30b8 label.local=\u30ed\u30fc\u30ab\u30eb label.login=\u30ed\u30b0\u30aa\u30f3 label.logout=\u30ed\u30b0\u30aa\u30d5 -label.LUN.number=LUN \u756a\u53f7 label.lun=LUN +label.LUN.number=LUN \u756a\u53f7 +label.lxc.traffic.label=LXC \u306e\u30c8\u30e9\u30d5\u30a3\u30c3\u30af \u30e9\u30d9\u30eb label.make.project.owner=\u30a2\u30ab\u30a6\u30f3\u30c8\u306e\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u6240\u6709\u8005\u5316 -label.manage.resources=\u30ea\u30bd\u30fc\u30b9\u306e\u7ba1\u7406 -label.manage=\u7ba1\u7406 label.management.ips=\u7ba1\u7406 IP \u30a2\u30c9\u30ec\u30b9 label.management=\u7ba1\u7406 +label.manage.resources=\u30ea\u30bd\u30fc\u30b9\u306e\u7ba1\u7406 +label.manage=\u7ba1\u7406 label.max.cpus=\u6700\u5927 CPU \u30b3\u30a2\u6570 label.max.guest.limit=\u6700\u5927\u30b2\u30b9\u30c8\u5236\u9650 +label.maximum=\u6700\u5927 +label.max.instances=\u6700\u5927\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u6570 label.max.memory=\u6700\u5927\u30e1\u30e2\u30ea (MiB) label.max.networks=\u6700\u5927\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u6570 label.max.primary.storage=\u6700\u5927\u30d7\u30e9\u30a4\u30de\u30ea (GiB) @@ -754,14 +846,13 @@ label.max.templates=\u6700\u5927\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u6570 label.max.vms=\u6700\u5927\u30e6\u30fc\u30b6\u30fc VM \u6570 label.max.volumes=\u6700\u5927\u30dc\u30ea\u30e5\u30fc\u30e0\u6570 label.max.vpcs=\u6700\u5927 VPC \u6570 -label.maximum=\u6700\u5927 label.may.continue=\u7d9a\u884c\u3067\u304d\u307e\u3059\u3002 label.memory.allocated=\u5272\u308a\u5f53\u3066\u6e08\u307f\u306e\u30e1\u30e2\u30ea label.memory.limits=\u30e1\u30e2\u30ea\u5236\u9650 (MiB) label.memory.mb=\u30e1\u30e2\u30ea (MB) label.memory.total=\u30e1\u30e2\u30ea\u5408\u8a08 -label.memory.used=\u30e1\u30e2\u30ea\u4f7f\u7528\u91cf label.memory=\u30e1\u30e2\u30ea +label.memory.used=\u30e1\u30e2\u30ea\u4f7f\u7528\u91cf label.menu.accounts=\u30a2\u30ab\u30a6\u30f3\u30c8 label.menu.alerts=\u30a2\u30e9\u30fc\u30c8 label.menu.all.accounts=\u3059\u3079\u3066\u306e\u30a2\u30ab\u30a6\u30f3\u30c8 @@ -788,7 +879,7 @@ label.menu.my.templates=\u30de\u30a4 \u30c6\u30f3\u30d7\u30ec\u30fc\u30c8 label.menu.network.offerings=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0 label.menu.network=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af label.menu.physical.resources=\u7269\u7406\u30ea\u30bd\u30fc\u30b9 -label.menu.regions=\u9818\u57df +label.menu.regions=\u30ea\u30fc\u30b8\u30e7\u30f3 label.menu.running.instances=\u5b9f\u884c\u4e2d\u306e\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9 label.menu.security.groups=\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3 \u30b0\u30eb\u30fc\u30d7 label.menu.service.offerings=\u30b5\u30fc\u30d3\u30b9 \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0 @@ -796,22 +887,26 @@ label.menu.snapshots=\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8 label.menu.stopped.instances=\u505c\u6b62\u3055\u308c\u305f\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9 label.menu.storage=\u30b9\u30c8\u30ec\u30fc\u30b8 label.menu.system.service.offerings=\u30b7\u30b9\u30c6\u30e0 \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0 -label.menu.system.vms=\u30b7\u30b9\u30c6\u30e0 VM label.menu.system=\u30b7\u30b9\u30c6\u30e0 +label.menu.system.vms=\u30b7\u30b9\u30c6\u30e0 VM label.menu.templates=\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8 label.menu.virtual.appliances=\u4eee\u60f3\u30a2\u30d7\u30e9\u30a4\u30a2\u30f3\u30b9 label.menu.virtual.resources=\u4eee\u60f3\u30ea\u30bd\u30fc\u30b9 label.menu.volumes=\u30dc\u30ea\u30e5\u30fc\u30e0 +label.menu.vpc.offerings=VPC \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0 label.migrate.instance.to.host=\u5225\u306e\u30db\u30b9\u30c8\u3078\u306e\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u306e\u79fb\u884c label.migrate.instance.to.ps=\u5225\u306e\u30d7\u30e9\u30a4\u30de\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8\u3078\u306e\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u306e\u79fb\u884c -label.migrate.instance.to=\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u306e\u79fb\u884c\u5148: -label.migrate.router.to=\u30eb\u30fc\u30bf\u30fc\u306e\u79fb\u884c\u5148: -label.migrate.systemvm.to=\u30b7\u30b9\u30c6\u30e0 VM \u306e\u79fb\u884c\u5148: +label.migrate.instance.to=\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u306e\u79fb\u884c\u5148\: +label.migrate.lb.vm=LB VM \u306e\u79fb\u884c +label.migrate.router.to=\u30eb\u30fc\u30bf\u30fc\u306e\u79fb\u884c\u5148\: +label.migrate.systemvm.to=\u30b7\u30b9\u30c6\u30e0 VM \u306e\u79fb\u884c\u5148\: label.migrate.to.host=\u30db\u30b9\u30c8\u3078\u79fb\u884c label.migrate.to.storage=\u30b9\u30c8\u30ec\u30fc\u30b8\u3078\u79fb\u884c label.migrate.volume=\u5225\u306e\u30d7\u30e9\u30a4\u30de\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8\u3078\u306e\u30dc\u30ea\u30e5\u30fc\u30e0\u306e\u79fb\u884c label.minimum=\u6700\u5c0f +label.min.instances=\u6700\u5c0f\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u6570 label.minute.past.hour=\u5206 (\u6bce\u6642) +label.mode=\u30e2\u30fc\u30c9 label.monday=\u6708\u66dc\u65e5 label.monthly=\u6bce\u6708 label.more.templates=\u305d\u306e\u307b\u304b\u306e\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8 @@ -822,20 +917,25 @@ label.move.up.row=1 \u884c\u4e0a\u306b\u79fb\u52d5 label.my.account=\u30de\u30a4 \u30a2\u30ab\u30a6\u30f3\u30c8 label.my.network=\u30de\u30a4 \u30cd\u30c3\u30c8\u30ef\u30fc\u30af label.my.templates=\u30de\u30a4 \u30c6\u30f3\u30d7\u30ec\u30fc\u30c8 +label.name.lower=\u540d\u524d label.name.optional=\u540d\u524d (\u30aa\u30d7\u30b7\u30e7\u30f3) label.name=\u540d\u524d label.nat.port.range=NAT \u30dd\u30fc\u30c8\u306e\u7bc4\u56f2 label.netmask=\u30cd\u30c3\u30c8\u30de\u30b9\u30af +label.netscaler.details=NetScaler \u306e\u8a73\u7d30 label.netScaler=NetScaler +label.network.ACLs=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af ACL label.network.ACL.total=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af ACL \u5408\u8a08 label.network.ACL=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af ACL -label.network.ACLs=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af ACL +label.network.addVM=VM \u3078\u306e\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306e\u8ffd\u52a0 +label.network.cidr=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af CIDR label.network.desc=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306e\u8aac\u660e label.network.device.type=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af \u30c7\u30d0\u30a4\u30b9\u306e\u7a2e\u985e label.network.device=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af \u30c7\u30d0\u30a4\u30b9 label.network.domain.text=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af \u30c9\u30e1\u30a4\u30f3 label.network.domain=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af \u30c9\u30e1\u30a4\u30f3 label.network.id=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af ID +label.networking.and.security=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3068\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3 label.network.label.display.for.blank.value=\u30c7\u30d5\u30a9\u30eb\u30c8 \u30b2\u30fc\u30c8\u30a6\u30a7\u30a4\u3092\u4f7f\u7528 label.network.limits=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u5236\u9650 label.network.name=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u540d @@ -847,20 +947,19 @@ label.network.rate.megabytes=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u901f\u5ea6 (M label.network.rate=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u901f\u5ea6 (MB/\u79d2) label.network.read=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u8aad\u307f\u53d6\u308a label.network.service.providers=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af \u30b5\u30fc\u30d3\u30b9 \u30d7\u30ed\u30d0\u30a4\u30c0\u30fc +label.networks=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af label.network.type=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306e\u7a2e\u985e -label.network.write=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u66f8\u304d\u8fbc\u307f label.network=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af -label.networking.and.security=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3068\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3 -label.networks=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af +label.network.write=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u66f8\u304d\u8fbc\u307f label.new.password=\u65b0\u3057\u3044\u30d1\u30b9\u30ef\u30fc\u30c9 label.new.project=\u65b0\u3057\u3044\u30d7\u30ed\u30b8\u30a7\u30af\u30c8 -label.new.vm=\u65b0\u3057\u3044 VM label.new=\u65b0\u898f +label.new.vm=\u65b0\u3057\u3044 VM label.next=\u6b21\u3078 label.nexusVswitch=Nexus 1000V +label.nfs=NFS label.nfs.server=NFS \u30b5\u30fc\u30d0\u30fc label.nfs.storage=NFS \u30b9\u30c8\u30ec\u30fc\u30b8 -label.nfs=NFS label.nic.adapter.type=NIC \u30a2\u30c0\u30d7\u30bf\u30fc\u306e\u7a2e\u985e label.nicira.controller.address=\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc \u30a2\u30c9\u30ec\u30b9 label.nicira.l3gatewayserviceuuid=L3 \u30b2\u30fc\u30c8\u30a6\u30a7\u30a4 \u30b5\u30fc\u30d3\u30b9\u306e UUID @@ -870,58 +969,80 @@ label.no.actions=\u5b9f\u884c\u3067\u304d\u308b\u64cd\u4f5c\u306f\u3042\u308a\u3 label.no.alerts=\u6700\u8fd1\u306e\u30a2\u30e9\u30fc\u30c8\u306f\u3042\u308a\u307e\u305b\u3093 label.no.data=\u8868\u793a\u3059\u308b\u30c7\u30fc\u30bf\u304c\u3042\u308a\u307e\u305b\u3093 label.no.errors=\u6700\u8fd1\u306e\u30a8\u30e9\u30fc\u306f\u3042\u308a\u307e\u305b\u3093 +label.no.grouping=(\u30b0\u30eb\u30fc\u30d7\u306a\u3057) label.no.isos=\u4f7f\u7528\u3067\u304d\u308b ISO \u306f\u3042\u308a\u307e\u305b\u3093 label.no.items=\u4f7f\u7528\u3067\u304d\u308b\u9805\u76ee\u306f\u3042\u308a\u307e\u305b\u3093 -label.no.security.groups=\u4f7f\u7528\u3067\u304d\u308b\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3 \u30b0\u30eb\u30fc\u30d7\u306f\u3042\u308a\u307e\u305b\u3093 -label.no.thanks=\u8a2d\u5b9a\u3057\u306a\u3044 -label.no=\u3044\u3044\u3048 label.none=\u306a\u3057 +label.no.security.groups=\u4f7f\u7528\u3067\u304d\u308b\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3 \u30b0\u30eb\u30fc\u30d7\u306f\u3042\u308a\u307e\u305b\u3093 label.not.found=\u898b\u3064\u304b\u308a\u307e\u305b\u3093 +label.no.thanks=\u8a2d\u5b9a\u3057\u306a\u3044 label.notifications=\u901a\u77e5 -label.num.cpu.cores=CPU \u30b3\u30a2\u6570 +label.no=\u3044\u3044\u3048 label.number.of.clusters=\u30af\u30e9\u30b9\u30bf\u30fc\u6570 +label.number.of.cpu.sockets=CPU \u30bd\u30b1\u30c3\u30c8\u6570 label.number.of.hosts=\u30db\u30b9\u30c8\u6570 label.number.of.pods=\u30dd\u30c3\u30c9\u6570 label.number.of.system.vms=\u30b7\u30b9\u30c6\u30e0 VM \u6570 label.number.of.virtual.routers=\u4eee\u60f3\u30eb\u30fc\u30bf\u30fc\u6570 label.number.of.zones=\u30be\u30fc\u30f3\u6570 +label.num.cpu.cores=CPU \u30b3\u30a2\u6570 label.numretries=\u518d\u8a66\u884c\u56de\u6570 label.ocfs2=OCFS2 label.offer.ha=\u9ad8\u53ef\u7528\u6027\u3092\u63d0\u4f9b\u3059\u308b label.ok=OK +label.opendaylight.controllerdetail=OpenDaylight \u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u306e\u8a73\u7d30 +label.opendaylight.controller=OpenDaylight \u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc +label.opendaylight.controllers=OpenDaylight \u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc +label.openDaylight=OpenDaylight label.optional=\u30aa\u30d7\u30b7\u30e7\u30f3 label.order=\u9806\u5e8f label.os.preference=OS \u57fa\u672c\u8a2d\u5b9a label.os.type=OS \u306e\u7a2e\u985e +label.override.guest.traffic=\u30b2\u30b9\u30c8 \u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u3092\u30aa\u30fc\u30d0\u30fc\u30e9\u30a4\u30c9\u3059\u308b +label.override.public.traffic=\u30d1\u30d6\u30ea\u30c3\u30af \u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u3092\u30aa\u30fc\u30d0\u30fc\u30e9\u30a4\u30c9\u3059\u308b +label.ovm.traffic.label=OVM \u306e\u30c8\u30e9\u30d5\u30a3\u30c3\u30af \u30e9\u30d9\u30eb +label.ovs=OVS label.owned.public.ips=\u6240\u6709\u3059\u308b\u30d1\u30d6\u30ea\u30c3\u30af IP \u30a2\u30c9\u30ec\u30b9 label.owner.account=\u6240\u6709\u8005\u30a2\u30ab\u30a6\u30f3\u30c8 label.owner.domain=\u6240\u6709\u8005\u30c9\u30e1\u30a4\u30f3 +label.palo.alto.details=Palo Alto \u306e\u8a73\u7d30 label.PA.log.profile=Palo Alto \u30ed\u30b0 \u30d7\u30ed\u30d5\u30a1\u30a4\u30eb -label.PA.threat.profile=Palo Alto \u8105\u5a01\u30d7\u30ed\u30d5\u30a1\u30a4\u30eb +label.PA=Palo Alto label.parent.domain=\u89aa\u30c9\u30e1\u30a4\u30f3 label.password.enabled=\u30d1\u30b9\u30ef\u30fc\u30c9\u7ba1\u7406\u6709\u52b9 +label.password.lower=\u30d1\u30b9\u30ef\u30fc\u30c9 +label.password.reset.confirm=\u6b21\u306e\u30d1\u30b9\u30ef\u30fc\u30c9\u306b\u30ea\u30bb\u30c3\u30c8\u3055\u308c\u307e\u3057\u305f\: label.password=\u30d1\u30b9\u30ef\u30fc\u30c9 +label.PA.threat.profile=Palo Alto \u8105\u5a01\u30d7\u30ed\u30d5\u30a1\u30a4\u30eb label.path=\u30d1\u30b9 label.perfect.forward.secrecy=Perfect Forward Secrecy +label.persistent=\u6c38\u7d9a label.physical.network.ID=\u7269\u7406\u30cd\u30c3\u30c8\u30ef\u30fc\u30af ID label.physical.network=\u7269\u7406\u30cd\u30c3\u30c8\u30ef\u30fc\u30af label.PING.CIFS.password=PING CIFS \u30d1\u30b9\u30ef\u30fc\u30c9 label.PING.CIFS.username=PING CIFS \u30e6\u30fc\u30b6\u30fc\u540d label.PING.dir=PING \u30c7\u30a3\u30ec\u30af\u30c8\u30ea label.PING.storage.IP=PING \u5bfe\u8c61\u306e\u30b9\u30c8\u30ec\u30fc\u30b8 IP \u30a2\u30c9\u30ec\u30b9 +label.planner.mode=\u30d7\u30e9\u30f3\u30ca\u30fc \u30e2\u30fc\u30c9 label.please.specify.netscaler.info=Netscaler \u60c5\u5831\u3092\u6307\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044 label.please.wait=\u304a\u5f85\u3061\u304f\u3060\u3055\u3044 label.plugin.details=\u30d7\u30e9\u30b0\u30a4\u30f3\u306e\u8a73\u7d30 label.plugins=\u30d7\u30e9\u30b0\u30a4\u30f3 +label.pod.dedicated=\u30dd\u30c3\u30c9\u3092\u5c02\u7528\u306b\u8a2d\u5b9a\u3057\u307e\u3057\u305f label.pod.name=\u30dd\u30c3\u30c9\u540d -label.pod=\u30dd\u30c3\u30c9 label.pods=\u30dd\u30c3\u30c9 +label.pod=\u30dd\u30c3\u30c9 +label.polling.interval.sec=\u30dd\u30fc\u30ea\u30f3\u30b0\u9593\u9694 (\u79d2) +label.portable.ip.range.details=\u30dd\u30fc\u30bf\u30d6\u30eb IP \u30a2\u30c9\u30ec\u30b9\u306e\u7bc4\u56f2\u306e\u8a73\u7d30 +label.portable.ip.ranges=\u30dd\u30fc\u30bf\u30d6\u30eb IP \u30a2\u30c9\u30ec\u30b9\u306e\u7bc4\u56f2 +label.portable.ips=\u30dd\u30fc\u30bf\u30d6\u30eb IP \u30a2\u30c9\u30ec\u30b9 label.port.forwarding.policies=\u30dd\u30fc\u30c8\u8ee2\u9001\u30dd\u30ea\u30b7\u30fc label.port.forwarding=\u30dd\u30fc\u30c8\u8ee2\u9001 label.port.range=\u30dd\u30fc\u30c8\u306e\u7bc4\u56f2 +label.port=\u30dd\u30fc\u30c8 label.PreSetup=PreSetup -label.prev=\u623b\u308b label.previous=\u623b\u308b +label.prev=\u623b\u308b label.primary.allocated=\u5272\u308a\u5f53\u3066\u6e08\u307f\u306e\u30d7\u30e9\u30a4\u30de\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8 label.primary.network=\u30d7\u30e9\u30a4\u30de\u30ea \u30cd\u30c3\u30c8\u30ef\u30fc\u30af label.primary.storage.count=\u30d7\u30e9\u30a4\u30de\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8 \u30d7\u30fc\u30eb @@ -931,69 +1052,102 @@ label.primary.used=\u30d7\u30e9\u30a4\u30de\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8 label.private.Gateway=\u30d7\u30e9\u30a4\u30d9\u30fc\u30c8 \u30b2\u30fc\u30c8\u30a6\u30a7\u30a4 label.private.interface=\u30d7\u30e9\u30a4\u30d9\u30fc\u30c8 \u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30a4\u30b9 label.private.ip.range=\u30d7\u30e9\u30a4\u30d9\u30fc\u30c8 IP \u30a2\u30c9\u30ec\u30b9\u306e\u7bc4\u56f2 -label.private.ip=\u30d7\u30e9\u30a4\u30d9\u30fc\u30c8 IP \u30a2\u30c9\u30ec\u30b9 label.private.ips=\u30d7\u30e9\u30a4\u30d9\u30fc\u30c8 IP \u30a2\u30c9\u30ec\u30b9 +label.private.ip=\u30d7\u30e9\u30a4\u30d9\u30fc\u30c8 IP \u30a2\u30c9\u30ec\u30b9 +label.privatekey=PKCS\#8 \u79d8\u5bc6\u30ad\u30fc label.private.network=\u30d7\u30e9\u30a4\u30d9\u30fc\u30c8 \u30cd\u30c3\u30c8\u30ef\u30fc\u30af label.private.port=\u30d7\u30e9\u30a4\u30d9\u30fc\u30c8 \u30dd\u30fc\u30c8 label.private.zone=\u30d7\u30e9\u30a4\u30d9\u30fc\u30c8 \u30be\u30fc\u30f3 -label.privatekey=PKCS\#8 \u79d8\u5bc6\u30ad\u30fc +label.profile=\u30d7\u30ed\u30d5\u30a1\u30a4\u30eb label.project.dashboard=\u30d7\u30ed\u30b8\u30a7\u30af\u30c8 \u30c0\u30c3\u30b7\u30e5\u30dc\u30fc\u30c9 label.project.id=\u30d7\u30ed\u30b8\u30a7\u30af\u30c8 ID label.project.invite=\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u3078\u306e\u62db\u5f85 label.project.name=\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u540d -label.project.view=\u30d7\u30ed\u30b8\u30a7\u30af\u30c8 \u30d3\u30e5\u30fc -label.project=\u30d7\u30ed\u30b8\u30a7\u30af\u30c8 label.projects=\u30d7\u30ed\u30b8\u30a7\u30af\u30c8 +label.project=\u30d7\u30ed\u30b8\u30a7\u30af\u30c8 +label.project.view=\u30d7\u30ed\u30b8\u30a7\u30af\u30c8 \u30d3\u30e5\u30fc label.protocol=\u30d7\u30ed\u30c8\u30b3\u30eb label.providers=\u30d7\u30ed\u30d0\u30a4\u30c0\u30fc +label.provider=\u30d7\u30ed\u30d0\u30a4\u30c0\u30fc label.public.interface=\u30d1\u30d6\u30ea\u30c3\u30af \u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30a4\u30b9 -label.public.ip=\u30d1\u30d6\u30ea\u30c3\u30af IP \u30a2\u30c9\u30ec\u30b9 label.public.ips=\u30d1\u30d6\u30ea\u30c3\u30af IP \u30a2\u30c9\u30ec\u30b9 +label.public.ip=\u30d1\u30d6\u30ea\u30c3\u30af IP \u30a2\u30c9\u30ec\u30b9 +label.public.load.balancer.provider=\u30d1\u30d6\u30ea\u30c3\u30af\u8ca0\u8377\u5206\u6563\u88c5\u7f6e\u30d7\u30ed\u30d0\u30a4\u30c0\u30fc label.public.network=\u30d1\u30d6\u30ea\u30c3\u30af \u30cd\u30c3\u30c8\u30ef\u30fc\u30af label.public.port=\u30d1\u30d6\u30ea\u30c3\u30af \u30dd\u30fc\u30c8 label.public.traffic=\u30d1\u30d6\u30ea\u30c3\u30af \u30c8\u30e9\u30d5\u30a3\u30c3\u30af -label.public.zone=\u30d1\u30d6\u30ea\u30c3\u30af \u30be\u30fc\u30f3 +label.public.traffic.vswitch.name=\u30d1\u30d6\u30ea\u30c3\u30af \u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u306e vSwitch \u540d +label.public.traffic.vswitch.type=\u30d1\u30d6\u30ea\u30c3\u30af \u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u306e vSwitch \u306e\u7a2e\u985e label.public=\u30d1\u30d6\u30ea\u30c3\u30af +label.public.zone=\u30d1\u30d6\u30ea\u30c3\u30af \u30be\u30fc\u30f3 label.purpose=\u76ee\u7684 label.Pxe.server.type=PXE \u30b5\u30fc\u30d0\u30fc\u306e\u7a2e\u985e +label.qos.type=QoS \u306e\u7a2e\u985e label.quickview=\u30af\u30a4\u30c3\u30af\u30d3\u30e5\u30fc +label.quiesce.vm=VM \u3092\u4f11\u6b62\u3059\u308b +label.quiet.time.sec=\u5f85\u3061\u6642\u9593 (\u79d2) +label.rbd.id=Cephx \u30e6\u30fc\u30b6\u30fc +label.rbd.monitor=Ceph \u30e2\u30cb\u30bf\u30fc +label.rbd.pool=Ceph \u30d7\u30fc\u30eb +label.rbd=RBD +label.rbd.secret=Cephx \u30b7\u30fc\u30af\u30ec\u30c3\u30c8 label.reboot=\u518d\u8d77\u52d5 label.recent.errors=\u6700\u8fd1\u306e\u30a8\u30e9\u30fc +label.recover.vm=VM \u3092\u4fee\u5fa9\u3059\u308b label.redundant.router.capability=\u5197\u9577\u30eb\u30fc\u30bf\u30fc\u6a5f\u80fd label.redundant.router=\u5197\u9577\u30eb\u30fc\u30bf\u30fc label.redundant.state=\u5197\u9577\u72b6\u614b +label.refresh.blades=\u30d6\u30ec\u30fc\u30c9\u306e\u66f4\u65b0 label.refresh=\u66f4\u65b0 -label.region=\u9818\u57df +label.regionlevelvpc=\u30ea\u30fc\u30b8\u30e7\u30f3\u30ec\u30d9\u30eb VPC +label.region=\u30ea\u30fc\u30b8\u30e7\u30f3 +label.reinstall.vm=VM \u3092\u518d\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3059\u308b label.related=\u95a2\u9023 +label.release.account.lowercase=\u30a2\u30ab\u30a6\u30f3\u30c8\u304b\u3089\u89e3\u653e +label.release.account=\u30a2\u30ab\u30a6\u30f3\u30c8\u304b\u3089\u89e3\u653e +label.release.dedicated.cluster=\u5c02\u7528\u30af\u30e9\u30b9\u30bf\u30fc\u306e\u89e3\u653e +label.release.dedicated.host=\u5c02\u7528\u30db\u30b9\u30c8\u306e\u89e3\u653e +label.release.dedicated.pod=\u5c02\u7528\u30dd\u30c3\u30c9\u306e\u89e3\u653e +label.release.dedicated.vlan.range=\u5c02\u7528 VLAN \u306e\u7bc4\u56f2\u306e\u89e3\u653e +label.release.dedicated.zone=\u5c02\u7528\u30be\u30fc\u30f3\u306e\u89e3\u653e label.remind.later=\u30a2\u30e9\u30fc\u30e0\u3092\u8868\u793a\u3059\u308b label.remove.ACL=ACL \u306e\u524a\u9664 label.remove.egress.rule=\u9001\u4fe1\u898f\u5247\u306e\u524a\u9664 label.remove.from.load.balancer=\u8ca0\u8377\u5206\u6563\u88c5\u7f6e\u304b\u3089\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u3092\u524a\u9664\u3057\u3066\u3044\u307e\u3059 label.remove.ingress.rule=\u53d7\u4fe1\u898f\u5247\u306e\u524a\u9664 label.remove.ip.range=IP \u30a2\u30c9\u30ec\u30b9\u306e\u7bc4\u56f2\u306e\u524a\u9664 +label.remove.ldap=LDAP \u306e\u524a\u9664 +label.remove.network.offering=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0\u306e\u524a\u9664 label.remove.pf=\u30dd\u30fc\u30c8\u8ee2\u9001\u898f\u5247\u306e\u524a\u9664 label.remove.project.account=\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u304b\u3089\u306e\u30a2\u30ab\u30a6\u30f3\u30c8\u306e\u524a\u9664 -label.remove.region=\u9818\u57df\u306e\u524a\u9664 +label.remove.region=\u30ea\u30fc\u30b8\u30e7\u30f3\u306e\u524a\u9664 label.remove.rule=\u898f\u5247\u306e\u524a\u9664 label.remove.static.nat.rule=\u9759\u7684 NAT \u898f\u5247\u306e\u524a\u9664 label.remove.static.route=\u9759\u7684\u30eb\u30fc\u30c8\u306e\u524a\u9664 label.remove.tier=\u968e\u5c64\u306e\u524a\u9664 label.remove.vm.from.lb=\u8ca0\u8377\u5206\u6563\u898f\u5247\u304b\u3089\u306e VM \u306e\u524a\u9664 +label.remove.vmware.datacenter=VMware \u30c7\u30fc\u30bf\u30bb\u30f3\u30bf\u30fc\u306e\u524a\u9664 +label.remove.vpc.offering=VPC \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0\u306e\u524a\u9664 label.remove.vpc=VPC \u306e\u524a\u9664 -label.removing.user=\u30e6\u30fc\u30b6\u30fc\u3092\u524a\u9664\u3057\u3066\u3044\u307e\u3059 label.removing=\u524a\u9664\u3057\u3066\u3044\u307e\u3059 +label.removing.user=\u30e6\u30fc\u30b6\u30fc\u3092\u524a\u9664\u3057\u3066\u3044\u307e\u3059 +label.reource.id=\u30ea\u30bd\u30fc\u30b9 ID label.required=\u5fc5\u9808\u3067\u3059 +label.requires.upgrade=\u30a2\u30c3\u30d7\u30b0\u30ec\u30fc\u30c9\u304c\u5fc5\u8981 +label.reserved.ip.range=\u4e88\u7d04\u6e08\u307f IP \u30a2\u30c9\u30ec\u30b9\u306e\u7bc4\u56f2 label.reserved.system.gateway=\u4e88\u7d04\u6e08\u307f\u30b7\u30b9\u30c6\u30e0 \u30b2\u30fc\u30c8\u30a6\u30a7\u30a4 label.reserved.system.ip=\u4e88\u7d04\u6e08\u307f\u30b7\u30b9\u30c6\u30e0 IP \u30a2\u30c9\u30ec\u30b9 label.reserved.system.netmask=\u4e88\u7d04\u6e08\u307f\u30b7\u30b9\u30c6\u30e0 \u30cd\u30c3\u30c8\u30de\u30b9\u30af +label.resetVM=VM \u306e\u30ea\u30bb\u30c3\u30c8 label.reset.VPN.connection=VPN \u63a5\u7d9a\u306e\u30ea\u30bb\u30c3\u30c8 label.resize.new.offering.id=\u65b0\u3057\u3044\u30aa\u30d5\u30a1\u30ea\u30f3\u30b0 label.resize.new.size=\u65b0\u3057\u3044\u30b5\u30a4\u30ba (GB) label.resize.shrink.ok=\u7e2e\u5c0f\u53ef\u80fd\u306b\u3059\u308b label.resource.limits=\u30ea\u30bd\u30fc\u30b9\u5236\u9650 +label.resource.name=\u30ea\u30bd\u30fc\u30b9\u540d label.resource.state=\u30ea\u30bd\u30fc\u30b9\u306e\u72b6\u614b -label.resource=\u30ea\u30bd\u30fc\u30b9 label.resources=\u30ea\u30bd\u30fc\u30b9 +label.resource=\u30ea\u30bd\u30fc\u30b9 label.restart.network=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306e\u518d\u8d77\u52d5 label.restart.required=\u518d\u8d77\u52d5\u304c\u5fc5\u8981 label.restart.vpc=VPC \u306e\u518d\u8d77\u52d5 @@ -1003,7 +1157,11 @@ label.revoke.project.invite=\u62db\u5f85\u306e\u53d6\u308a\u6d88\u3057 label.role=\u5f79\u5272 label.root.disk.controller=\u30eb\u30fc\u30c8 \u30c7\u30a3\u30b9\u30af \u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc label.root.disk.offering=\u30eb\u30fc\u30c8 \u30c7\u30a3\u30b9\u30af \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0 +label.root.disk.size=\u30eb\u30fc\u30c8 \u30c7\u30a3\u30b9\u30af \u30b5\u30a4\u30ba label.round.robin=\u30e9\u30a6\u30f3\u30c9\u30ed\u30d3\u30f3 +label.router.vm.scaled.up=\u30eb\u30fc\u30bf\u30fc VM \u306e\u30b5\u30a4\u30ba\u304c\u62e1\u5927\u3055\u308c\u307e\u3057\u305f +label.routing=\u30eb\u30fc\u30c6\u30a3\u30f3\u30b0 +label.rule.number=\u898f\u5247\u756a\u53f7 label.rules=\u898f\u5247 label.running.vms=\u5b9f\u884c\u4e2d\u306e VM label.s3.access_key=\u30a2\u30af\u30bb\u30b9 \u30ad\u30fc @@ -1011,26 +1169,31 @@ label.s3.bucket=\u30d0\u30b1\u30c3\u30c8 label.s3.connection_timeout=\u63a5\u7d9a\u30bf\u30a4\u30e0\u30a2\u30a6\u30c8 label.s3.endpoint=\u30a8\u30f3\u30c9\u30dd\u30a4\u30f3\u30c8 label.s3.max_error_retry=\u6700\u5927\u30a8\u30e9\u30fc\u518d\u8a66\u884c\u6570 +label.s3.nfs.path=S3 NFS \u30d1\u30b9 +label.s3.nfs.server=S3 NFS \u30b5\u30fc\u30d0\u30fc label.s3.secret_key=\u79d8\u5bc6\u30ad\u30fc label.s3.socket_timeout=\u30bd\u30b1\u30c3\u30c8 \u30bf\u30a4\u30e0\u30a2\u30a6\u30c8 -label.s3.use_https=HTTPS \u3092\u4f7f\u7528\u3059\u308b +label.s3.use_https=HTTPS \u3092\u4f7f\u7528 label.saturday=\u571f\u66dc\u65e5 label.save.and.continue=\u4fdd\u5b58\u3057\u3066\u7d9a\u884c label.save=\u4fdd\u5b58 label.saving.processing=\u4fdd\u5b58\u3057\u3066\u3044\u307e\u3059... label.scope=\u30b9\u30b3\u30fc\u30d7 label.search=\u691c\u7d22 +label.secondary.isolated.vlan.id=\u5206\u96e2\u3055\u308c\u305f\u30bb\u30ab\u30f3\u30c0\u30ea VLAN ID +label.secondary.staging.store.details=\u30bb\u30ab\u30f3\u30c0\u30ea \u30b9\u30c6\u30fc\u30b8\u30f3\u30b0 \u30b9\u30c8\u30a2\u306e\u8a73\u7d30 +label.secondary.staging.store=\u30bb\u30ab\u30f3\u30c0\u30ea \u30b9\u30c6\u30fc\u30b8\u30f3\u30b0 \u30b9\u30c8\u30a2 label.secondary.storage.count=\u30bb\u30ab\u30f3\u30c0\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8 \u30d7\u30fc\u30eb +label.secondary.storage.details=\u30bb\u30ab\u30f3\u30c0\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8\u306e\u8a73\u7d30 label.secondary.storage.limits=\u30bb\u30ab\u30f3\u30c0\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8\u5236\u9650 (GiB) -label.secondary.storage.vm=\u30bb\u30ab\u30f3\u30c0\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8 VM label.secondary.storage=\u30bb\u30ab\u30f3\u30c0\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8 +label.secondary.storage.vm=\u30bb\u30ab\u30f3\u30c0\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8 VM label.secondary.used=\u30bb\u30ab\u30f3\u30c0\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8\u4f7f\u7528\u91cf label.secret.key=\u79d8\u5bc6\u30ad\u30fc label.security.group.name=\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3 \u30b0\u30eb\u30fc\u30d7\u540d -label.security.group=\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3 \u30b0\u30eb\u30fc\u30d7 label.security.groups.enabled=\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3 \u30b0\u30eb\u30fc\u30d7\u6709\u52b9 label.security.groups=\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3 \u30b0\u30eb\u30fc\u30d7 -label.select-view=\u30d3\u30e5\u30fc\u306e\u9078\u629e +label.security.group=\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3 \u30b0\u30eb\u30fc\u30d7 label.select.a.template=\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u306e\u9078\u629e label.select.a.zone=\u30be\u30fc\u30f3\u306e\u9078\u629e label.select.instance.to.attach.volume.to=\u30dc\u30ea\u30e5\u30fc\u30e0\u3092\u30a2\u30bf\u30c3\u30c1\u3059\u308b\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044 @@ -1038,49 +1201,63 @@ label.select.instance=\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u306e\u9078\u629e label.select.iso.or.template=ISO \u307e\u305f\u306f\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u306e\u9078\u629e label.select.offering=\u30aa\u30d5\u30a1\u30ea\u30f3\u30b0\u306e\u9078\u629e label.select.project=\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u306e\u9078\u629e +label.select.template=\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u306e\u9078\u629e label.select.tier=\u968e\u5c64\u306e\u9078\u629e -label.select.vm.for.static.nat=\u9759\u7684 NAT \u7528 VM \u306e\u9078\u629e label.select=\u9078\u629e +label.select-view=\u30d3\u30e5\u30fc\u306e\u9078\u629e +label.select.vm.for.static.nat=\u9759\u7684 NAT \u7528 VM \u306e\u9078\u629e label.sent=\u9001\u4fe1\u6e08\u307f label.server=\u30b5\u30fc\u30d0\u30fc label.service.capabilities=\u30b5\u30fc\u30d3\u30b9\u306e\u6a5f\u80fd label.service.offering=\u30b5\u30fc\u30d3\u30b9 \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0 +label.service.state=\u30b5\u30fc\u30d3\u30b9\u306e\u72b6\u614b +label.services=\u30b5\u30fc\u30d3\u30b9 label.session.expired=\u30bb\u30c3\u30b7\u30e7\u30f3\u306e\u6709\u52b9\u671f\u9650\u304c\u5207\u308c\u307e\u3057\u305f -label.set.up.zone.type=\u30be\u30fc\u30f3\u306e\u7a2e\u985e\u306e\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7 +label.set.default.NIC=\u30c7\u30d5\u30a9\u30eb\u30c8 NIC \u306e\u8a2d\u5b9a +label.settings=\u8a2d\u5b9a label.setup.network=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306e\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7 -label.setup.zone=\u30be\u30fc\u30f3\u306e\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7 label.setup=\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7 -label.shared=\u5171\u6709 +label.set.up.zone.type=\u30be\u30fc\u30f3\u306e\u7a2e\u985e\u306e\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7 +label.setup.zone=\u30be\u30fc\u30f3\u306e\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7 label.SharedMountPoint=SharedMountPoint +label.shared=\u5171\u6709 +label.show.advanced.settings=\u8a73\u7d30\u8a2d\u5b9a\u306e\u8868\u793a label.show.ingress.rule=\u53d7\u4fe1\u898f\u5247\u306e\u8868\u793a label.shutdown.provider=\u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u306e\u30b7\u30e3\u30c3\u30c8\u30c0\u30a6\u30f3 label.site.to.site.VPN=\u30b5\u30a4\u30c8\u9593 VPN label.size=\u30b5\u30a4\u30ba label.skip.guide=CloudStack \u3092\u4f7f\u7528\u3057\u305f\u3053\u3068\u304c\u3042\u308b\u306e\u3067\u3001\u3053\u306e\u30ac\u30a4\u30c9\u3092\u30b9\u30ad\u30c3\u30d7\u3059\u308b +label.smb.domain=SMB \u30c9\u30e1\u30a4\u30f3 +label.smb.password=SMB \u30d1\u30b9\u30ef\u30fc\u30c9 +label.smb.username=SMB \u30e6\u30fc\u30b6\u30fc\u540d label.snapshot.limits=\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8\u5236\u9650 label.snapshot.name=\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8\u540d -label.snapshot.s=\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8 label.snapshot.schedule=\u5b9a\u671f\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8\u306e\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7 -label.snapshot=\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8 +label.snapshot.s=\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8 label.snapshots=\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8 +label.snapshot=\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8 +label.SNMP.community=SNMP \u30b3\u30df\u30e5\u30cb\u30c6\u30a3 +label.SNMP.port=SNMP \u30dd\u30fc\u30c8 +label.sockets=\u30bd\u30b1\u30c3\u30c8 label.source.nat=\u9001\u4fe1\u5143 NAT label.source=\u9001\u4fe1\u5143 label.specify.IP.ranges=IP \u30a2\u30c9\u30ec\u30b9\u306e\u7bc4\u56f2\u306e\u6307\u5b9a label.specify.vlan=VLAN \u3092\u6307\u5b9a\u3059\u308b label.specify.vxlan=VXLAN \u3092\u6307\u5b9a\u3059\u308b -label.SR.name=SR \u540d\u30e9\u30d9\u30eb +label.SR.name = SR \u540d\u30e9\u30d9\u30eb +label.srx.details=SRX \u306e\u8a73\u7d30 label.srx=SRX -label.PA=Palo Alto label.start.IP=\u958b\u59cb IP \u30a2\u30c9\u30ec\u30b9 +label.start.lb.vm=LB VM \u306e\u8d77\u52d5 label.start.port=\u958b\u59cb\u30dd\u30fc\u30c8 label.start.reserved.system.IP=\u4e88\u7d04\u6e08\u307f\u958b\u59cb\u30b7\u30b9\u30c6\u30e0 IP \u30a2\u30c9\u30ec\u30b9 label.start.vlan=\u958b\u59cb VLAN label.start.vxlan=\u958b\u59cb VXLAN label.state=\u72b6\u614b label.static.nat.enabled=\u9759\u7684 NAT \u6709\u52b9 -label.static.nat.to=\u9759\u7684 NAT \u306e\u8a2d\u5b9a\u5148: -label.static.nat.vm.details=\u9759\u7684 NAT VM \u306e\u8a73\u7d30 +label.static.nat.to=\u9759\u7684 NAT \u306e\u8a2d\u5b9a\u5148\: label.static.nat=\u9759\u7684 NAT +label.static.nat.vm.details=\u9759\u7684 NAT VM \u306e\u8a73\u7d30 label.statistics=\u7d71\u8a08 label.status=\u72b6\u6cc1 label.step.1.title=\u624b\u9806 1\: \u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u306e\u9078\u629e @@ -1106,79 +1283,95 @@ label.sticky.postonly=\u30dd\u30b9\u30c8\u306e\u307f label.sticky.prefix=\u30d7\u30ec\u30d5\u30a3\u30c3\u30af\u30b9 label.sticky.request-learn=\u30e9\u30fc\u30cb\u30f3\u30b0\u306e\u8981\u6c42 label.sticky.tablesize=\u30c6\u30fc\u30d6\u30eb \u30b5\u30a4\u30ba -label.stop=\u505c\u6b62 +label.stop.lb.vm=LB VM \u306e\u505c\u6b62 label.stopped.vms=\u505c\u6b62\u4e2d\u306e VM +label.stop=\u505c\u6b62 label.storage.tags=\u30b9\u30c8\u30ec\u30fc\u30b8 \u30bf\u30b0 label.storage.traffic=\u30b9\u30c8\u30ec\u30fc\u30b8 \u30c8\u30e9\u30d5\u30a3\u30c3\u30af label.storage.type=\u30b9\u30c8\u30ec\u30fc\u30b8\u306e\u7a2e\u985e -label.qos.type=QoS \u306e\u7a2e\u985e -label.cache.mode=\u66f8\u304d\u8fbc\u307f\u30ad\u30e3\u30c3\u30b7\u30e5\u306e\u7a2e\u985e label.storage=\u30b9\u30c8\u30ec\u30fc\u30b8 label.subdomain.access=\u30b5\u30d6\u30c9\u30e1\u30a4\u30f3 \u30a2\u30af\u30bb\u30b9 -label.submit=\u9001\u4fe1 label.submitted.by=[\u9001\u4fe1\u30e6\u30fc\u30b6\u30fc\: ] +label.submit=\u9001\u4fe1 label.succeeded=\u6210\u529f label.sunday=\u65e5\u66dc\u65e5 label.super.cidr.for.guest.networks=\u30b2\u30b9\u30c8 \u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306e\u30b9\u30fc\u30d1\u30fc CIDR label.supported.services=\u30b5\u30dd\u30fc\u30c8\u3055\u308c\u308b\u30b5\u30fc\u30d3\u30b9 label.supported.source.NAT.type=\u30b5\u30dd\u30fc\u30c8\u3055\u308c\u308b\u9001\u4fe1\u5143 NAT \u306e\u7a2e\u985e +label.supportsstrechedl2subnet=\u30b9\u30c8\u30ec\u30c3\u30c1\u30c9 L2 \u30b5\u30d6\u30cd\u30c3\u30c8\u306e\u30b5\u30dd\u30fc\u30c8 label.suspend.project=\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u306e\u4e00\u6642\u505c\u6b62 +label.switch.type=\u30b9\u30a4\u30c3\u30c1\u306e\u7a2e\u985e label.system.capacity=\u30b7\u30b9\u30c6\u30e0\u306e\u51e6\u7406\u80fd\u529b +label.system.offering.for.router=\u30eb\u30fc\u30bf\u30fc\u7528\u30b7\u30b9\u30c6\u30e0 \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0 label.system.offering=\u30b7\u30b9\u30c6\u30e0 \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0 label.system.service.offering=\u30b7\u30b9\u30c6\u30e0 \u30b5\u30fc\u30d3\u30b9 \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0 +label.system.vm.details=\u30b7\u30b9\u30c6\u30e0 VM \u306e\u8a73\u7d30 +label.system.vm.scaled.up=\u30b7\u30b9\u30c6\u30e0 VM \u306e\u30b5\u30a4\u30ba\u304c\u62e1\u5927\u3055\u308c\u307e\u3057\u305f +label.system.vms=\u30b7\u30b9\u30c6\u30e0 VM label.system.vm.type=\u30b7\u30b9\u30c6\u30e0 VM \u306e\u7a2e\u985e label.system.vm=\u30b7\u30b9\u30c6\u30e0 VM -label.system.vms=\u30b7\u30b9\u30c6\u30e0 VM label.system.wide.capacity=\u30b7\u30b9\u30c6\u30e0\u5168\u4f53\u306e\u51e6\u7406\u80fd\u529b label.tagged=\u30bf\u30b0\u3042\u308a +label.tag.key=\u30bf\u30b0 \u30ad\u30fc label.tags=\u30bf\u30b0 +label.tag.value=\u30bf\u30b0\u5024 label.target.iqn=\u30bf\u30fc\u30b2\u30c3\u30c8 IQN label.task.completed=\u30bf\u30b9\u30af\u304c\u5b8c\u4e86\u3057\u307e\u3057\u305f label.template.limits=\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u5236\u9650 label.template=\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8 label.TFTP.dir=TFTP \u30c7\u30a3\u30ec\u30af\u30c8\u30ea +label.tftp.root.directory=TFTP \u30eb\u30fc\u30c8 \u30c7\u30a3\u30ec\u30af\u30c8\u30ea label.theme.default=\u30c7\u30d5\u30a9\u30eb\u30c8 \u30c6\u30fc\u30de label.theme.grey=\u30ab\u30b9\u30bf\u30e0 - \u30b0\u30ec\u30fc label.theme.lightblue=\u30ab\u30b9\u30bf\u30e0 - \u30e9\u30a4\u30c8 \u30d6\u30eb\u30fc label.thursday=\u6728\u66dc\u65e5 label.tier.details=\u968e\u5c64\u306e\u8a73\u7d30 label.tier=\u968e\u5c64 -label.time.zone=\u30bf\u30a4\u30e0\u30be\u30fc\u30f3 -label.time=\u6642\u523b -label.timeout.in.second=\u30bf\u30a4\u30e0\u30a2\u30a6\u30c8 (\u79d2) +label.timeout.in.second = \u30bf\u30a4\u30e0\u30a2\u30a6\u30c8 (\u79d2) label.timeout=\u30bf\u30a4\u30e0\u30a2\u30a6\u30c8 +label.time=\u6642\u523b +label.time.zone=\u30bf\u30a4\u30e0\u30be\u30fc\u30f3 label.timezone=\u30bf\u30a4\u30e0\u30be\u30fc\u30f3 label.token=\u30c8\u30fc\u30af\u30f3 -label.total.CPU=CPU \u5408\u8a08 label.total.cpu=CPU \u5408\u8a08 +label.total.CPU=CPU \u5408\u8a08 label.total.hosts=\u30db\u30b9\u30c8\u5408\u8a08 label.total.memory=\u30e1\u30e2\u30ea\u5408\u8a08 label.total.of.ip=IP \u30a2\u30c9\u30ec\u30b9\u5408\u8a08 label.total.of.vm=VM \u5408\u8a08 label.total.storage=\u30b9\u30c8\u30ec\u30fc\u30b8\u5408\u8a08 +label.total.virtual.routers=\u4eee\u60f3\u30eb\u30fc\u30bf\u30fc\u5408\u8a08 +label.total.virtual.routers.upgrade=\u30a2\u30c3\u30d7\u30b0\u30ec\u30fc\u30c9\u304c\u5fc5\u8981\u306a\u4eee\u60f3\u30eb\u30fc\u30bf\u30fc\u5408\u8a08 label.total.vms=VM \u5408\u8a08 label.traffic.label=\u30c8\u30e9\u30d5\u30a3\u30c3\u30af \u30e9\u30d9\u30eb -label.traffic.type=\u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u306e\u7a2e\u985e label.traffic.types=\u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u306e\u7a2e\u985e +label.traffic.type=\u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u306e\u7a2e\u985e label.tuesday=\u706b\u66dc\u65e5 label.type.id=\u7a2e\u985e ID +label.type.lower=\u7a2e\u985e label.type=\u7a2e\u985e +label.ucs=UCS label.unavailable=\u4f7f\u7528\u4e0d\u80fd label.unlimited=\u7121\u5236\u9650 label.untagged=\u30bf\u30b0\u306a\u3057 label.update.project.resources=\u30d7\u30ed\u30b8\u30a7\u30af\u30c8 \u30ea\u30bd\u30fc\u30b9\u306e\u66f4\u65b0 -label.update.ssl.cert=SSL \u8a3c\u660e\u66f8 -label.update.ssl=SSL \u8a3c\u660e\u66f8 +label.update.ssl.cert= SSL \u8a3c\u660e\u66f8 +label.update.ssl= SSL \u8a3c\u660e\u66f8 label.updating=\u66f4\u65b0\u3057\u3066\u3044\u307e\u3059 -label.upload.volume=\u30dc\u30ea\u30e5\u30fc\u30e0\u306e\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9 +label.upgrade.required=\u30a2\u30c3\u30d7\u30b0\u30ec\u30fc\u30c9\u304c\u5fc5\u8981\u3067\u3059 +label.upgrade.router.newer.template=\u30eb\u30fc\u30bf\u30fc\u3092\u30a2\u30c3\u30d7\u30b0\u30ec\u30fc\u30c9\u3057\u3066\u65b0\u3057\u3044\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u3092\u4f7f\u7528\u3059\u308b label.upload=\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9 +label.upload.volume=\u30dc\u30ea\u30e5\u30fc\u30e0\u306e\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9 label.url=URL label.usage.interface=\u4f7f\u7528\u72b6\u6cc1\u6e2c\u5b9a\u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30a4\u30b9 -label.use.vm.ip=\u6b21\u306e VM IP \u30a2\u30c9\u30ec\u30b9\u3092\u4f7f\u7528\: label.used=\u4f7f\u7528\u4e2d -label.user=\u30e6\u30fc\u30b6\u30fc +label.user.data=\u30e6\u30fc\u30b6\u30fc \u30c7\u30fc\u30bf +label.username.lower=\u30e6\u30fc\u30b6\u30fc\u540d label.username=\u30e6\u30fc\u30b6\u30fc\u540d label.users=\u30e6\u30fc\u30b6\u30fc +label.user=\u30e6\u30fc\u30b6\u30fc +label.use.vm.ips=VM \u306e IP \u3092\u5229\u7528\u3059\u308b\u3002 +label.use.vm.ip=\u6b21\u306e VM IP \u30a2\u30c9\u30ec\u30b9\u3092\u4f7f\u7528\: label.value=\u5024 label.vcdcname=vCenter DC \u540d label.vcenter.cluster=vCenter \u30af\u30e9\u30b9\u30bf\u30fc @@ -1187,62 +1380,91 @@ label.vcenter.datastore=vCenter \u30c7\u30fc\u30bf\u30b9\u30c8\u30a2 label.vcenter.host=vCenter \u30db\u30b9\u30c8 label.vcenter.password=vCenter \u30d1\u30b9\u30ef\u30fc\u30c9 label.vcenter.username=vCenter \u30e6\u30fc\u30b6\u30fc\u540d +label.vcenter=vCenter label.vcipaddress=vCenter IP \u30a2\u30c9\u30ec\u30b9 label.version=\u30d0\u30fc\u30b8\u30e7\u30f3 +label.vgpu.max.resolution=\u6700\u5927\u89e3\u50cf\u5ea6 +label.vgpu.max.vgpu.per.gpu=GPU \u6bce\u306e vGPU\u6570 +label.vgpu.remaining.capacity=\u6b8b\u308a\u5bb9\u91cf +label.vgpu.type=vGPU \u30bf\u30a4\u30d7 +label.vgpu.video.ram=\u30d3\u30c7\u30aa RAM label.view.all=\u3059\u3079\u3066\u8868\u793a label.view.console=\u30b3\u30f3\u30bd\u30fc\u30eb\u306e\u8868\u793a +label.viewing=\u8868\u793a\u9805\u76ee\: label.view.more=\u8a73\u7d30\u8868\u793a +label.view.secondary.ips=\u30bb\u30ab\u30f3\u30c0\u30ea IP \u30a2\u30c9\u30ec\u30b9\u306e\u8868\u793a label.view=\u8868\u793a - -label.viewing=\u8868\u793a\u9805\u76ee: -label.virtual.appliance=\u4eee\u60f3\u30a2\u30d7\u30e9\u30a4\u30a2\u30f3\u30b9 +label.virtual.appliance.details=\u4eee\u60f3\u30a2\u30d7\u30e9\u30a4\u30a2\u30f3\u30b9\u306e\u8a73\u7d30 label.virtual.appliances=\u4eee\u60f3\u30a2\u30d7\u30e9\u30a4\u30a2\u30f3\u30b9 +label.virtual.appliance=\u4eee\u60f3\u30a2\u30d7\u30e9\u30a4\u30a2\u30f3\u30b9 label.virtual.machines=\u4eee\u60f3\u30de\u30b7\u30f3 +label.virtual.networking=\u4eee\u60f3\u30cd\u30c3\u30c8\u30ef\u30fc\u30af label.virtual.network=\u4eee\u60f3\u30cd\u30c3\u30c8\u30ef\u30fc\u30af -label.virtual.router=\u4eee\u60f3\u30eb\u30fc\u30bf\u30fc +label.virtual.routers.group.account=\u30a2\u30ab\u30a6\u30f3\u30c8\u5225\u306e\u4eee\u60f3\u30eb\u30fc\u30bf\u30fc \u30b0\u30eb\u30fc\u30d7 +label.virtual.routers.group.cluster=\u30af\u30e9\u30b9\u30bf\u30fc\u5225\u306e\u4eee\u60f3\u30eb\u30fc\u30bf\u30fc \u30b0\u30eb\u30fc\u30d7 +label.virtual.routers.group.pod=\u30dd\u30c3\u30c9\u5225\u306e\u4eee\u60f3\u30eb\u30fc\u30bf\u30fc \u30b0\u30eb\u30fc\u30d7 +label.virtual.routers.group.zone=\u30be\u30fc\u30f3\u5225\u306e\u4eee\u60f3\u30eb\u30fc\u30bf\u30fc \u30b0\u30eb\u30fc\u30d7 label.virtual.routers=\u4eee\u60f3\u30eb\u30fc\u30bf\u30fc +label.virtual.router=\u4eee\u60f3\u30eb\u30fc\u30bf\u30fc label.vlan.id=VLAN/VNI ID +label.vlan.range.details=VLAN \u306e\u7bc4\u56f2\u306e\u8a73\u7d30 +label.vlan.ranges=VLAN \u306e\u7bc4\u56f2 label.vlan.range=VLAN/VNI \u306e\u7bc4\u56f2 label.vlan=VLAN/VNI -label.vnet=VLAN/VNI -label.vnet.id=VLAN/VNI ID -label.vxlan.id=VXLAN ID -label.vxlan.range=VXLAN \u306e\u7bc4\u56f2 -label.vxlan=VXLAN +label.vlan.vni.ranges=VLAN/VNI \u306e\u7bc4\u56f2 +label.vlan.vni.range=VLAN/VNI \u306e\u7bc4\u56f2 label.vm.add=\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u306e\u8ffd\u52a0 label.vm.destroy=\u7834\u68c4 label.vm.display.name=VM \u8868\u793a\u540d -label.vm.name=VM \u540d -label.vm.reboot=\u518d\u8d77\u52d5 -label.vm.start=\u8d77\u52d5 -label.vm.state=VM \u306e\u72b6\u614b -label.vm.stop=\u505c\u6b62 label.VMFS.datastore=VMFS \u30c7\u30fc\u30bf\u30b9\u30c8\u30a2 label.vmfs=VMFS +label.vm.name=VM \u540d +label.vm.password=VM \u306e\u30d1\u30b9\u30ef\u30fc\u30c9\: +label.vm.reboot=\u518d\u8d77\u52d5 label.VMs.in.tier=\u968e\u5c64\u5185\u306e VM -label.vms=VM label.vmsnapshot.current=\u4f7f\u7528\u4e2d label.vmsnapshot.memory=\u30e1\u30e2\u30ea\u3082\u542b\u3081\u308b label.vmsnapshot.parentname=\u89aa label.vmsnapshot.type=\u7a2e\u985e label.vmsnapshot=VM \u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8 +label.vm.start=\u8d77\u52d5 +label.vm.state=VM \u306e\u72b6\u614b +label.vm.stop=\u505c\u6b62 +label.vms=VM +label.vmware.datacenter.id=VMware \u30c7\u30fc\u30bf\u30bb\u30f3\u30bf\u30fc ID +label.vmware.datacenter.name=VMware \u30c7\u30fc\u30bf\u30bb\u30f3\u30bf\u30fc\u540d +label.vmware.datacenter.vcenter=VMware \u30c7\u30fc\u30bf\u30bb\u30f3\u30bf\u30fc\u306e vCenter label.vmware.traffic.label=VMware \u306e\u30c8\u30e9\u30d5\u30a3\u30c3\u30af \u30e9\u30d9\u30eb +label.vnet.id=VLAN/VNI ID +label.vnet=VLAN/VNI +label.vnmc.devices=VNMC \u30c7\u30d0\u30a4\u30b9 +label.volatile=\u63ee\u767a\u6027 label.volgroup=\u30dc\u30ea\u30e5\u30fc\u30e0 \u30b0\u30eb\u30fc\u30d7 label.volume.limits=\u30dc\u30ea\u30e5\u30fc\u30e0\u5236\u9650 label.volume.name=\u30dc\u30ea\u30e5\u30fc\u30e0\u540d -label.volume=\u30dc\u30ea\u30e5\u30fc\u30e0 label.volumes=\u30dc\u30ea\u30e5\u30fc\u30e0 +label.volume=\u30dc\u30ea\u30e5\u30fc\u30e0 +label.vpc.distributedvpcrouter=\u5206\u6563 VPC \u30eb\u30fc\u30bf\u30fc label.vpc.id=VPC ID +label.VPC.limits=VPC \u5236\u9650 +label.vpc.offering.details=VPC \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0\u306e\u8a73\u7d30 +label.vpc.offering=VPC \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0 label.VPC.router.details=VPC \u30eb\u30fc\u30bf\u30fc\u306e\u8a73\u7d30 +label.vpc.supportsregionlevelvpc=\u30ea\u30fc\u30b8\u30e7\u30f3\u30ec\u30d9\u30eb VPC \u3092\u30b5\u30dd\u30fc\u30c8\u3059\u308b +label.vpc.virtual.router=VPC \u4eee\u60f3\u30eb\u30fc\u30bf\u30fc label.vpc=VPC label.VPN.connection=VPN \u63a5\u7d9a -label.VPN.customer.gateway=VPN \u30ab\u30b9\u30bf\u30de\u30fc \u30b2\u30fc\u30c8\u30a6\u30a7\u30a4 label.vpn.customer.gateway=VPN \u30ab\u30b9\u30bf\u30de\u30fc \u30b2\u30fc\u30c8\u30a6\u30a7\u30a4 +label.VPN.customer.gateway=VPN \u30ab\u30b9\u30bf\u30de\u30fc \u30b2\u30fc\u30c8\u30a6\u30a7\u30a4 label.VPN.gateway=VPN \u30b2\u30fc\u30c8\u30a6\u30a7\u30a4 label.vpn=VPN label.vsmctrlvlanid=\u30b3\u30f3\u30c8\u30ed\u30fc\u30eb VLAN ID label.vsmpktvlanid=\u30d1\u30b1\u30c3\u30c8 VLAN ID label.vsmstoragevlanid=\u30b9\u30c8\u30ec\u30fc\u30b8 VLAN ID label.vsphere.managed=vSphere \u306b\u3088\u308b\u7ba1\u7406 +label.vxlan.id=VXLAN ID +label.vxlan.range=VXLAN \u306e\u7bc4\u56f2 +label.vxlan=VXLAN label.waiting=\u5f85\u6a5f\u3057\u3066\u3044\u307e\u3059 label.warn=\u8b66\u544a label.wednesday=\u6c34\u66dc\u65e5 @@ -1250,239 +1472,31 @@ label.weekly=\u6bce\u9031 label.welcome.cloud.console=\u7ba1\u7406\u30b3\u30f3\u30bd\u30fc\u30eb\u3078\u3088\u3046\u3053\u305d label.welcome=\u3088\u3046\u3053\u305d label.what.is.cloudstack=CloudStack&\#8482; \u306b\u3064\u3044\u3066 +label.xenserver.tools.version.61.plus=XenServer Tools Version 6.1 \u4ee5\u964d +label.Xenserver.Tools.Version61plus=XenServer Tools Version 6.1 \u4ee5\u964d label.xen.traffic.label=XenServer \u306e\u30c8\u30e9\u30d5\u30a3\u30c3\u30af \u30e9\u30d9\u30eb label.yes=\u306f\u3044 +label.zone.dedicated=\u5c02\u7528\u30be\u30fc\u30f3 label.zone.details=\u30be\u30fc\u30f3\u306e\u8a73\u7d30 label.zone.id=\u30be\u30fc\u30f3 ID +label.zone.lower=\u30be\u30fc\u30f3 label.zone.name=\u30be\u30fc\u30f3\u540d label.zone.step.1.title=\u624b\u9806 1\: \u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306e\u9078\u629e label.zone.step.2.title=\u624b\u9806 2\: \u30be\u30fc\u30f3\u306e\u8ffd\u52a0 label.zone.step.3.title=\u624b\u9806 3\: \u30dd\u30c3\u30c9\u306e\u8ffd\u52a0 label.zone.step.4.title=\u624b\u9806 4\: IP \u30a2\u30c9\u30ec\u30b9\u7bc4\u56f2\u306e\u8ffd\u52a0 +label.zones=\u30be\u30fc\u30f3 label.zone.type=\u30be\u30fc\u30f3\u306e\u7a2e\u985e -label.zone.wide=\u30be\u30fc\u30f3\u5168\u4f53 label.zone=\u30be\u30fc\u30f3 -label.zones=\u30be\u30fc\u30f3 +label.zone.wide=\u30be\u30fc\u30f3\u5168\u4f53 label.zoneWizard.trafficType.guest=\u30b2\u30b9\u30c8\: \u30a8\u30f3\u30c9 \u30e6\u30fc\u30b6\u30fc\u306e\u4eee\u60f3\u30de\u30b7\u30f3\u306e\u9593\u306e\u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u3067\u3059\u3002 label.zoneWizard.trafficType.management=\u7ba1\u7406\: \u30db\u30b9\u30c8\u3084 CloudStack \u30b7\u30b9\u30c6\u30e0 VM \u306a\u3069\u3001\u7ba1\u7406\u30b5\u30fc\u30d0\u30fc\u3068\u901a\u4fe1\u3059\u308b CloudStack \u306e\u5185\u90e8\u30ea\u30bd\u30fc\u30b9\u9593\u306e\u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u3067\u3059\u3002 label.zoneWizard.trafficType.public=\u30d1\u30d6\u30ea\u30c3\u30af\: \u30a4\u30f3\u30bf\u30fc\u30cd\u30c3\u30c8\u3068\u30af\u30e9\u30a6\u30c9\u5185\u306e\u4eee\u60f3\u30de\u30b7\u30f3\u306e\u9593\u306e\u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u3067\u3059\u3002 label.zoneWizard.trafficType.storage=\u30b9\u30c8\u30ec\u30fc\u30b8\: VM \u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u3084\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8\u306a\u3069\u3001\u30d7\u30e9\u30a4\u30de\u30ea\u304a\u3088\u3073\u30bb\u30ab\u30f3\u30c0\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8 \u30b5\u30fc\u30d0\u30fc\u9593\u306e\u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u3067\u3059\u3002 -label.ldap.group.name=LDAP \u30b0\u30eb\u30fc\u30d7 -label.password.reset.confirm=\u6b21\u306e\u30d1\u30b9\u30ef\u30fc\u30c9\u306b\u30ea\u30bb\u30c3\u30c8\u3055\u308c\u307e\u3057\u305f: -label.provider=\u30d7\u30ed\u30d0\u30a4\u30c0\u30fc -label.resetVM=VM \u306e\u30ea\u30bb\u30c3\u30c8 -label.openDaylight=OpenDaylight -label.assign.instance.another=\u307b\u304b\u306e\u30a2\u30ab\u30a6\u30f3\u30c8\u3078\u306e\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u306e\u5272\u308a\u5f53\u3066 -label.network.addVM=VM \u3078\u306e\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306e\u8ffd\u52a0 -label.set.default.NIC=\u30c7\u30d5\u30a9\u30eb\u30c8 NIC \u306e\u8a2d\u5b9a -label.Xenserver.Tools.Version61plus=XenServer Tools Version 6.1 \u4ee5\u964d -label.dynamically.scalable=\u52d5\u7684\u306b\u30b5\u30a4\u30ba\u8a2d\u5b9a\u3059\u308b -label.instance.scaled.up=\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u306e\u30b5\u30a4\u30ba\u304c\u62e1\u5927\u3055\u308c\u307e\u3057\u305f -label.tag.key=\u30bf\u30b0 \u30ad\u30fc -label.tag.value=\u30bf\u30b0\u5024 -label.ipv6.address=IPv6 IP \u30a2\u30c9\u30ec\u30b9 -label.ipv6.gateway=IPv6 \u30b2\u30fc\u30c8\u30a6\u30a7\u30a4 -label.ipv6.CIDR=IPv6 CIDR -label.VPC.limits=VPC \u5236\u9650 -label.edit.region=\u9818\u57df\u306e\u7de8\u96c6 -label.gslb.domain.name=GSLB \u30c9\u30e1\u30a4\u30f3\u540d -label.add.gslb=GSLB \u306e\u8ffd\u52a0 -label.gslb.servicetype=\u30b5\u30fc\u30d3\u30b9\u306e\u7a2e\u985e -label.gslb.details=GSLB \u306e\u8a73\u7d30 -label.gslb.delete=GSLB \u306e\u524a\u9664 -label.opendaylight.controller=OpenDaylight \u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc -label.opendaylight.controllers=OpenDaylight \u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc -label.portable.ip.ranges=\u30dd\u30fc\u30bf\u30d6\u30eb IP \u30a2\u30c9\u30ec\u30b9\u306e\u7bc4\u56f2 -label.add.portable.ip.range=\u30dd\u30fc\u30bf\u30d6\u30eb IP \u30a2\u30c9\u30ec\u30b9\u306e\u7bc4\u56f2\u306e\u8ffd\u52a0 -label.delete.portable.ip.range=\u30dd\u30fc\u30bf\u30d6\u30eb IP \u30a2\u30c9\u30ec\u30b9\u306e\u7bc4\u56f2\u306e\u524a\u9664 -label.opendaylight.controllerdetail=OpenDaylight \u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u306e\u8a73\u7d30 -label.portable.ip.range.details=\u30dd\u30fc\u30bf\u30d6\u30eb IP \u30a2\u30c9\u30ec\u30b9\u306e\u7bc4\u56f2\u306e\u8a73\u7d30 -label.portable.ips=\u30dd\u30fc\u30bf\u30d6\u30eb IP \u30a2\u30c9\u30ec\u30b9 -label.gslb.assigned.lb=\u5272\u308a\u5f53\u3066\u6e08\u307f\u8ca0\u8377\u5206\u6563 -label.gslb.assigned.lb.more=\u8ca0\u8377\u5206\u6563\u306e\u8ffd\u52a0\u5272\u308a\u5f53\u3066 -label.gslb.lb.rule=\u8ca0\u8377\u5206\u6563\u898f\u5247 -label.gslb.lb.details=\u8ca0\u8377\u5206\u6563\u306e\u8a73\u7d30 -label.gslb.lb.remove=\u3053\u306e GSLB \u304b\u3089\u8ca0\u8377\u5206\u6563\u3092\u524a\u9664 -label.enable.autoscale=\u81ea\u52d5\u30b5\u30a4\u30ba\u8a2d\u5b9a\u306e\u6709\u52b9\u5316 -label.disable.autoscale=\u81ea\u52d5\u30b5\u30a4\u30ba\u8a2d\u5b9a\u306e\u7121\u52b9\u5316 -label.min.instances=\u6700\u5c0f\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u6570 -label.max.instances=\u6700\u5927\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u6570 -label.add.OpenDaylight.device=OpenDaylight \u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u306e\u8ffd\u52a0 -label.show.advanced.settings=\u8a73\u7d30\u8a2d\u5b9a\u306e\u8868\u793a -label.delete.OpenDaylight.device=OpenDaylight \u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u306e\u524a\u9664 -label.polling.interval.sec=\u30dd\u30fc\u30ea\u30f3\u30b0\u9593\u9694 (\u79d2) -label.quiet.time.sec=\u5f85\u3061\u6642\u9593 (\u79d2) -label.destroy.vm.graceperiod=VM \u7834\u68c4\u306e\u7336\u4e88\u671f\u9593 -label.SNMP.community=SNMP \u30b3\u30df\u30e5\u30cb\u30c6\u30a3 -label.SNMP.port=SNMP \u30dd\u30fc\u30c8 -label.add.ucs.manager=UCS Manager \u306e\u8ffd\u52a0 -label.ovm.traffic.label=OVM \u306e\u30c8\u30e9\u30d5\u30a3\u30c3\u30af \u30e9\u30d9\u30eb -label.lxc.traffic.label=LXC \u306e\u30c8\u30e9\u30d5\u30a3\u30c3\u30af \u30e9\u30d9\u30eb -label.hyperv.traffic.label=Hyper-V \u306e\u30c8\u30e9\u30d5\u30a3\u30c3\u30af \u30e9\u30d9\u30eb -label.resource.name=\u30ea\u30bd\u30fc\u30b9\u540d -label.reource.id=\u30ea\u30bd\u30fc\u30b9 ID -label.vnmc.devices=VNMC \u30c7\u30d0\u30a4\u30b9 -label.add.vnmc.provider=VNMC \u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u306e\u8ffd\u52a0 -label.enable.vnmc.provider=VNMC \u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u306e\u6709\u52b9\u5316 -label.add.vnmc.device=VNMC \u30c7\u30d0\u30a4\u30b9\u306e\u8ffd\u52a0 -label.ciscovnmc.resource.details=Cisco VNMC \u30ea\u30bd\u30fc\u30b9\u306e\u8a73\u7d30 -label.delete.ciscovnmc.resource=Cisco VNMC \u30ea\u30bd\u30fc\u30b9\u306e\u524a\u9664 -label.enable.vnmc.device=VNMC \u30c7\u30d0\u30a4\u30b9\u306e\u6709\u52b9\u5316 -label.disbale.vnmc.device=VNMC \u30c7\u30d0\u30a4\u30b9\u306e\u7121\u52b9\u5316 -label.disable.vnmc.provider=VNMC \u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u306e\u7121\u52b9\u5316 -label.services=\u30b5\u30fc\u30d3\u30b9 -label.secondary.staging.store=\u30bb\u30ab\u30f3\u30c0\u30ea \u30b9\u30c6\u30fc\u30b8\u30f3\u30b0 \u30b9\u30c8\u30a2 -label.release.account=\u30a2\u30ab\u30a6\u30f3\u30c8\u304b\u3089\u89e3\u653e -label.release.account.lowercase=\u30a2\u30ab\u30a6\u30f3\u30c8\u304b\u3089\u89e3\u653e -label.vlan.vni.ranges=VLAN/VNI \u306e\u7bc4\u56f2 -label.dedicated.vlan.vni.ranges=\u5c02\u7528 VLAN/VNI \u306e\u7bc4\u56f2 -label.dedicate.vlan.vni.range=VLAN/VNI \u306e\u7bc4\u56f2\u3092\u5c02\u7528\u306b\u8a2d\u5b9a -label.vlan.vni.range=VLAN/VNI \u306e\u7bc4\u56f2 -label.vlan.range.details=VLAN \u306e\u7bc4\u56f2\u306e\u8a73\u7d30 -label.release.dedicated.vlan.range=\u5c02\u7528 VLAN \u306e\u7bc4\u56f2\u306e\u89e3\u653e -label.broadcat.uri=\u30d6\u30ed\u30fc\u30c9\u30ad\u30e3\u30b9\u30c8 URI -label.ipv4.cidr=IPv4 CIDR -label.guest.network.details=\u30b2\u30b9\u30c8 \u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306e\u8a73\u7d30 -label.ipv4.gateway=IPv4 \u30b2\u30fc\u30c8\u30a6\u30a7\u30a4 -label.release.dedicated.vlan.range=\u5c02\u7528 VLAN \u306e\u7bc4\u56f2\u3092\u89e3\u653e -label.vlan.ranges=VLAN \u306e\u7bc4\u56f2 -label.virtual.appliance.details=\u4eee\u60f3\u30a2\u30d7\u30e9\u30a4\u30a2\u30f3\u30b9\u306e\u8a73\u7d30 -label.start.lb.vm=LB VM \u306e\u8d77\u52d5 -label.stop.lb.vm=LB VM \u306e\u505c\u6b62 -label.migrate.lb.vm=LB VM \u306e\u79fb\u884c -label.vpc.virtual.router=VPC \u4eee\u60f3\u30eb\u30fc\u30bf\u30fc -label.ovs=OVS -label.gslb.service=GSLB \u30b5\u30fc\u30d3\u30b9 -label.gslb.service.public.ip=GSLB \u30b5\u30fc\u30d3\u30b9\u306e\u30d1\u30d6\u30ea\u30c3\u30af IP \u30a2\u30c9\u30ec\u30b9 -label.gslb.service.private.ip=GSLB \u30b5\u30fc\u30d3\u30b9\u306e\u30d7\u30e9\u30a4\u30d9\u30fc\u30c8 IP \u30a2\u30c9\u30ec\u30b9 -label.baremetal.dhcp.provider=\u30d9\u30a2\u30e1\u30bf\u30eb DHCP \u30d7\u30ed\u30d0\u30a4\u30c0\u30fc -label.add.baremetal.dhcp.device=\u30d9\u30a2\u30e1\u30bf\u30eb DHCP \u30c7\u30d0\u30a4\u30b9\u306e\u8ffd\u52a0 -label.baremetal.pxe.provider=\u30d9\u30a2\u30e1\u30bf\u30eb PXE \u30d7\u30ed\u30d0\u30a4\u30c0\u30fc -label.baremetal.pxe.device=\u30d9\u30a2\u30e1\u30bf\u30eb PXE \u30c7\u30d0\u30a4\u30b9\u306e\u8ffd\u52a0 -label.tftp.root.directory=TFTP \u30eb\u30fc\u30c8 \u30c7\u30a3\u30ec\u30af\u30c8\u30ea -label.add.vmware.datacenter=VMware \u30c7\u30fc\u30bf\u30bb\u30f3\u30bf\u30fc\u306e\u8ffd\u52a0 -label.remove.vmware.datacenter=VMware \u30c7\u30fc\u30bf\u30bb\u30f3\u30bf\u30fc\u306e\u524a\u9664 -label.dc.name=DC \u540d -label.vcenter=vCenter -label.dedicate.zone=\u30be\u30fc\u30f3\u3092\u5c02\u7528\u306b\u8a2d\u5b9a -label.zone.dedicated=\u5c02\u7528\u30be\u30fc\u30f3 -label.release.dedicated.zone=\u5c02\u7528\u30be\u30fc\u30f3\u306e\u89e3\u653e -label.ipv6.dns1=IPv6 DNS 1 -label.ipv6.dns2=IPv6 DNS 2 -label.vmware.datacenter.name=VMware \u30c7\u30fc\u30bf\u30bb\u30f3\u30bf\u30fc\u540d -label.vmware.datacenter.vcenter=VMware \u30c7\u30fc\u30bf\u30bb\u30f3\u30bf\u30fc\u306e vCenter -label.vmware.datacenter.id=VMware \u30c7\u30fc\u30bf\u30bb\u30f3\u30bf\u30fc ID -label.system.vm.details=\u30b7\u30b9\u30c6\u30e0 VM \u306e\u8a73\u7d30 -label.system.vm.scaled.up=\u30b7\u30b9\u30c6\u30e0 VM \u306e\u30b5\u30a4\u30ba\u304c\u62e1\u5927\u3055\u308c\u307e\u3057\u305f -label.console.proxy.vm=\u30b3\u30f3\u30bd\u30fc\u30eb \u30d7\u30ed\u30ad\u30b7 VM -label.settings=\u8a2d\u5b9a -label.requires.upgrade=\u30a2\u30c3\u30d7\u30b0\u30ec\u30fc\u30c9\u304c\u5fc5\u8981 -label.upgrade.router.newer.template=\u30eb\u30fc\u30bf\u30fc\u3092\u30a2\u30c3\u30d7\u30b0\u30ec\u30fc\u30c9\u3057\u3066\u65b0\u3057\u3044\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u3092\u4f7f\u7528\u3059\u308b -label.router.vm.scaled.up=\u30eb\u30fc\u30bf\u30fc VM \u306e\u30b5\u30a4\u30ba\u304c\u62e1\u5927\u3055\u308c\u307e\u3057\u305f -label.total.virtual.routers=\u4eee\u60f3\u30eb\u30fc\u30bf\u30fc\u5408\u8a08 -label.upgrade.required=\u30a2\u30c3\u30d7\u30b0\u30ec\u30fc\u30c9\u304c\u5fc5\u8981\u3067\u3059 -label.virtual.routers.group.zone=\u30be\u30fc\u30f3\u5225\u306e\u4eee\u60f3\u30eb\u30fc\u30bf\u30fc \u30b0\u30eb\u30fc\u30d7 -label.total.virtual.routers.upgrade=\u30a2\u30c3\u30d7\u30b0\u30ec\u30fc\u30c9\u304c\u5fc5\u8981\u306a\u4eee\u60f3\u30eb\u30fc\u30bf\u30fc\u5408\u8a08 -label.virtual.routers.group.pod=\u30dd\u30c3\u30c9\u5225\u306e\u4eee\u60f3\u30eb\u30fc\u30bf\u30fc \u30b0\u30eb\u30fc\u30d7 -label.virtual.routers.group.cluster=\u30af\u30e9\u30b9\u30bf\u30fc\u5225\u306e\u4eee\u60f3\u30eb\u30fc\u30bf\u30fc \u30b0\u30eb\u30fc\u30d7 -label.zone.lower=\u30be\u30fc\u30f3 -label.virtual.routers.group.account=\u30a2\u30ab\u30a6\u30f3\u30c8\u5225\u306e\u4eee\u60f3\u30eb\u30fc\u30bf\u30fc \u30b0\u30eb\u30fc\u30d7 -label.netscaler.details=NetScaler \u306e\u8a73\u7d30 -label.baremetal.dhcp.devices=\u30d9\u30a2\u30e1\u30bf\u30eb DHCP \u30c7\u30d0\u30a4\u30b9 -label.baremetal.pxe.devices=\u30d9\u30a2\u30e1\u30bf\u30eb PXE \u30c7\u30d0\u30a4\u30b9 -label.addes.new.f5=\u65b0\u3057\u3044 F5 \u3092\u8ffd\u52a0\u3057\u307e\u3057\u305f -label.f5.details=F5 \u306e\u8a73\u7d30 -label.srx.details=SRX \u306e\u8a73\u7d30 -label.palo.alto.details=Palo Alto \u306e\u8a73\u7d30 -label.added.nicira.nvp.controller=\u65b0\u3057\u3044 Nicira NVP Controller \u3092\u8ffd\u52a0\u3057\u307e\u3057\u305f\ -label.nicira.nvp.details=Nicira NVP \u306e\u8a73\u7d30 -label.added.new.bigswitch.vns.controller=\u65b0\u3057\u3044 Big Switch VNS \u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u3092\u8ffd\u52a0\u3057\u307e\u3057\u305f -label.bigswitch.vns.details=Big Switch VNS \u306e\u8a73\u7d30 -label.dedicate=\u5c02\u7528\u306b\u8a2d\u5b9a -label.dedicate.pod=\u30dd\u30c3\u30c9\u3092\u5c02\u7528\u306b\u8a2d\u5b9a -label.pod.dedicated=\u30dd\u30c3\u30c9\u3092\u5c02\u7528\u306b\u8a2d\u5b9a\u3057\u307e\u3057\u305f -label.release.dedicated.pod=\u5c02\u7528\u30dd\u30c3\u30c9\u306e\u89e3\u653e -label.override.public.traffic=\u30d1\u30d6\u30ea\u30c3\u30af \u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u3092\u30aa\u30fc\u30d0\u30fc\u30e9\u30a4\u30c9\u3059\u308b -label.public.traffic.vswitch.type=\u30d1\u30d6\u30ea\u30c3\u30af \u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u306e vSwitch \u306e\u7a2e\u985e -label.public.traffic.vswitch.name=\u30d1\u30d6\u30ea\u30c3\u30af \u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u306e vSwitch \u540d -label.override.guest.traffic=\u30b2\u30b9\u30c8 \u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u3092\u30aa\u30fc\u30d0\u30fc\u30e9\u30a4\u30c9\u3059\u308b -label.guest.traffic.vswitch.type=\u30b2\u30b9\u30c8 \u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u306e vSwitch \u306e\u7a2e\u985e -label.guest.traffic.vswitch.name=\u30b2\u30b9\u30c8 \u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u306e vSwitch \u540d -label.cisco.nexus1000v.ip.address=Nexus 1000V \u306e IP \u30a2\u30c9\u30ec\u30b9 -label.cisco.nexus1000v.username=Nexus 1000V \u306e\u30e6\u30fc\u30b6\u30fc\u540d -label.cisco.nexus1000v.password=Nexus 1000V \u306e\u30d1\u30b9\u30ef\u30fc\u30c9 -label.dedicate.cluster=\u30af\u30e9\u30b9\u30bf\u30fc\u3092\u5c02\u7528\u306b\u8a2d\u5b9a -label.release.dedicated.cluster=\u5c02\u7528\u30af\u30e9\u30b9\u30bf\u30fc\u306e\u89e3\u653e -label.dedicate.host=\u30db\u30b9\u30c8\u3092\u5c02\u7528\u306b\u8a2d\u5b9a -label.release.dedicated.host=\u5c02\u7528\u30db\u30b9\u30c8\u306e\u89e3\u653e -label.number.of.cpu.sockets=CPU \u30bd\u30b1\u30c3\u30c8\u6570 -label.delete.ucs.manager=UCS Manager \u306e\u524a\u9664 -label.blades=\u30d6\u30ec\u30fc\u30c9 -label.chassis=\u30b7\u30e3\u30fc\u30b7 -label.blade.id=\u30d6\u30ec\u30fc\u30c9 ID -label.associated.profile=\u95a2\u9023\u4ed8\u3051\u3089\u308c\u305f\u30d7\u30ed\u30d5\u30a1\u30a4\u30eb -label.refresh.blades=\u30d6\u30ec\u30fc\u30c9\u306e\u66f4\u65b0 -label.instanciate.template.associate.profile.blade=\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u306e\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u4f5c\u6210\u304a\u3088\u3073\u30d7\u30ed\u30d5\u30a1\u30a4\u30eb\u3068\u30d6\u30ec\u30fc\u30c9\u306e\u95a2\u9023\u4ed8\u3051 -label.select.template=\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u306e\u9078\u629e -label.profile=\u30d7\u30ed\u30d5\u30a1\u30a4\u30eb -label.delete.profile=\u30d7\u30ed\u30d5\u30a1\u30a4\u30eb\u306e\u524a\u9664 -label.disassociate.profile.blade=\u30d7\u30ed\u30d5\u30a1\u30a4\u30eb\u3068\u30d6\u30ec\u30fc\u30c9\u306e\u95a2\u9023\u4ed8\u3051\u306e\u89e3\u9664 -label.secondary.storage.details=\u30bb\u30ab\u30f3\u30c0\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8\u306e\u8a73\u7d30 -label.secondary.staging.store.details=\u30bb\u30ab\u30f3\u30c0\u30ea \u30b9\u30c6\u30fc\u30b8\u30f3\u30b0 \u30b9\u30c8\u30a2\u306e\u8a73\u7d30 -label.add.nfs.secondary.staging.store=NFS \u30bb\u30ab\u30f3\u30c0\u30ea \u30b9\u30c6\u30fc\u30b8\u30f3\u30b0 \u30b9\u30c8\u30a2\u306e\u8ffd\u52a0 -label.delete.secondary.staging.store=\u30bb\u30ab\u30f3\u30c0\u30ea \u30b9\u30c6\u30fc\u30b8\u30f3\u30b0 \u30b9\u30c8\u30a2\u306e\u524a\u9664 -label.ipv4.start.ip=IPv4 \u958b\u59cb IP \u30a2\u30c9\u30ec\u30b9 -label.ipv4.end.ip=IPv4 \u7d42\u4e86 IP \u30a2\u30c9\u30ec\u30b9 -label.ipv6.start.ip=IPv6 \u958b\u59cb IP \u30a2\u30c9\u30ec\u30b9 -label.ipv6.end.ip=IPv6 \u7d42\u4e86 IP \u30a2\u30c9\u30ec\u30b9 -label.vm.password=VM \u306e\u30d1\u30b9\u30ef\u30fc\u30c9: -label.group.by.zone=\u30be\u30fc\u30f3\u5225\u30b0\u30eb\u30fc\u30d7 -label.group.by.pod=\u30dd\u30c3\u30c9\u5225\u30b0\u30eb\u30fc\u30d7 -label.group.by.cluster=\u30af\u30e9\u30b9\u30bf\u30fc\u5225\u30b0\u30eb\u30fc\u30d7 -label.group.by.account=\u30a2\u30ab\u30a6\u30f3\u30c8\u5225\u30b0\u30eb\u30fc\u30d7 -label.no.grouping=(\u30b0\u30eb\u30fc\u30d7\u306a\u3057) -label.create.nfs.secondary.staging.storage=NFS \u30bb\u30ab\u30f3\u30c0\u30ea \u30b9\u30c6\u30fc\u30b8\u30f3\u30b0 \u30b9\u30c8\u30a2\u3092\u4f5c\u6210\u3059\u308b -label.username.lower=\u30e6\u30fc\u30b6\u30fc\u540d -label.password.lower=\u30d1\u30b9\u30ef\u30fc\u30c9 -label.email.lower=\u96fb\u5b50\u30e1\u30fc\u30eb -label.firstname.lower=\u540d -label.lastname.lower=\u59d3 -label.domain.lower=\u30c9\u30e1\u30a4\u30f3 -label.account.lower=\u30a2\u30ab\u30a6\u30f3\u30c8 -label.type.lower=\u7a2e\u985e -label.rule.number=\u898f\u5247\u756a\u53f7 -label.action=\u64cd\u4f5c -label.name.lower=\u540d\u524d -label.ucs=UCS -label.change.affinity=\u30a2\u30d5\u30a3\u30cb\u30c6\u30a3\u306e\u5909\u66f4 -label.persistent=\u6c38\u7d9a -label.broadcasturi=\u30d6\u30ed\u30fc\u30c9\u30ad\u30e3\u30b9\u30c8 URI -label.network.cidr=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af CIDR -label.reserved.ip.range=\u4e88\u7d04\u6e08\u307f IP \u30a2\u30c9\u30ec\u30b9\u306e\u7bc4\u56f2 -label.autoscale=\u81ea\u52d5\u30b5\u30a4\u30ba\u8a2d\u5b9a -label.health.check=\u30d8\u30eb\u30b9 \u30c1\u30a7\u30c3\u30af -label.public.load.balancer.provider=\u30d1\u30d6\u30ea\u30c3\u30af\u8ca0\u8377\u5206\u6563\u88c5\u7f6e\u30d7\u30ed\u30d0\u30a4\u30c0\u30fc -label.add.isolated.network=\u5206\u96e2\u3055\u308c\u305f\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306e\u8ffd\u52a0 -label.vlan=VLAN -label.secondary.isolated.vlan.id=\u5206\u96e2\u3055\u308c\u305f\u30bb\u30ab\u30f3\u30c0\u30ea VLAN ID -label.ipv4.netmask=IPv4 \u30cd\u30c3\u30c8\u30de\u30b9\u30af -label.custom=\u30ab\u30b9\u30bf\u30e0 -label.disable.network.offering=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0\u306e\u7121\u52b9\u5316 -label.enable.network.offering=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0\u306e\u6709\u52b9\u5316 -label.remove.network.offering=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0\u306e\u524a\u9664 -label.system.offering.for.router=\u30eb\u30fc\u30bf\u30fc\u7528\u30b7\u30b9\u30c6\u30e0 \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0 -label.mode=\u30e2\u30fc\u30c9 -label.associate.public.ip=\u30d1\u30d6\u30ea\u30c3\u30af IP \u30a2\u30c9\u30ec\u30b9\u306e\u95a2\u9023\u4ed8\u3051 -label.acl=ACL -label.user.data=\u30e6\u30fc\u30b6\u30fc \u30c7\u30fc\u30bf -label.virtual.networking=\u4eee\u60f3\u30cd\u30c3\u30c8\u30ef\u30fc\u30af -label.allow=\u8a31\u53ef -label.deny=\u62d2\u5426 -label.default.egress.policy=\u30c7\u30d5\u30a9\u30eb\u30c8\u306e\u9001\u4fe1\u30dd\u30ea\u30b7\u30fc -label.xenserver.tools.version.61.plus=XenServer Tools Version 6.1 \u4ee5\u964d managed.state=\u7ba1\u7406\u5bfe\u8c61\u72b6\u614b -message.acquire.new.ip.vpc=\u3053\u306e VPC \u306e\u65b0\u3057\u3044 IP \u30a2\u30c9\u30ec\u30b9\u3092\u53d6\u5f97\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +message.acquire.ip.nic=\u3053\u306e NIC \u306e\u305f\u3081\u306b\u65b0\u3057\u3044\u30bb\u30ab\u30f3\u30c0\u30ea IP \u30a2\u30c9\u30ec\u30b9\u3092\u53d6\u5f97\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b?
\u6ce8\: \u65b0\u3057\u304f\u53d6\u5f97\u3057\u305f\u30bb\u30ab\u30f3\u30c0\u30ea IP \u30a2\u30c9\u30ec\u30b9\u306f\u4eee\u60f3\u30de\u30b7\u30f3\u5185\u3067\u624b\u52d5\u3067\u69cb\u6210\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002 message.acquire.new.ip=\u3053\u306e\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306e\u65b0\u3057\u3044 IP \u30a2\u30c9\u30ec\u30b9\u3092\u53d6\u5f97\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +message.acquire.new.ip.vpc=\u3053\u306e VPC \u306e\u65b0\u3057\u3044 IP \u30a2\u30c9\u30ec\u30b9\u3092\u53d6\u5f97\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.acquire.public.ip=\u65b0\u3057\u3044 IP \u30a2\u30c9\u30ec\u30b9\u3092\u53d6\u5f97\u3059\u308b\u30be\u30fc\u30f3\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044\u3002 message.action.cancel.maintenance.mode=\u3053\u306e\u4fdd\u5b88\u3092\u30ad\u30e3\u30f3\u30bb\u30eb\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.action.cancel.maintenance=\u30db\u30b9\u30c8\u306e\u4fdd\u5b88\u306f\u6b63\u5e38\u306b\u30ad\u30e3\u30f3\u30bb\u30eb\u3055\u308c\u307e\u3057\u305f\u3002\u3053\u306e\u51e6\u7406\u306b\u306f\u6570\u5206\u304b\u304b\u308b\u53ef\u80fd\u6027\u304c\u3042\u308a\u307e\u3059\u3002 @@ -1498,6 +1512,7 @@ message.action.delete.ISO.for.all.zones=\u305d\u306e ISO \u306f\u3059\u3079\u306 message.action.delete.ISO=\u3053\u306e ISO \u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.action.delete.network=\u3053\u306e\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.action.delete.nexusVswitch=\u3053\u306e Nexus 1000V \u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +message.action.delete.nic=\u3053\u306e NIC \u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? \u95a2\u9023\u4ed8\u3051\u3089\u308c\u305f\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3082 VM \u304b\u3089\u524a\u9664\u3055\u308c\u307e\u3059\u3002 message.action.delete.physical.network=\u3053\u306e\u7269\u7406\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.action.delete.pod=\u3053\u306e\u30dd\u30c3\u30c9\u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.action.delete.primary.storage=\u3053\u306e\u30d7\u30e9\u30a4\u30de\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8\u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? @@ -1518,6 +1533,7 @@ message.action.disable.physical.network=\u3053\u306e\u7269\u7406\u30cd\u30c3\u30 message.action.disable.pod=\u3053\u306e\u30dd\u30c3\u30c9\u3092\u7121\u52b9\u306b\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.action.disable.static.NAT=\u9759\u7684 NAT \u3092\u7121\u52b9\u306b\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.action.disable.zone=\u3053\u306e\u30be\u30fc\u30f3\u3092\u7121\u52b9\u306b\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +message.action.downloading.template=\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u3092\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3057\u3066\u3044\u307e\u3059\u3002 message.action.download.iso=\u3053\u306e ISO \u3092\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.action.download.template=\u3053\u306e\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u3092\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.action.enable.cluster=\u3053\u306e\u30af\u30e9\u30b9\u30bf\u30fc\u3092\u6709\u52b9\u306b\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? @@ -1540,6 +1556,7 @@ message.action.remove.host=\u3053\u306e\u30db\u30b9\u30c8\u3092\u524a\u9664\u305 message.action.reset.password.off=\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u306f\u73fe\u5728\u3053\u306e\u6a5f\u80fd\u3092\u30b5\u30dd\u30fc\u30c8\u3057\u3066\u3044\u307e\u305b\u3093\u3002 message.action.reset.password.warning=\u73fe\u5728\u306e\u30d1\u30b9\u30ef\u30fc\u30c9\u3092\u5909\u66f4\u3059\u308b\u524d\u306b\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u3092\u505c\u6b62\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002 message.action.restore.instance=\u3053\u306e\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u3092\u5fa9\u5143\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +message.action.revert.snapshot=\u6240\u6709\u30dc\u30ea\u30e5\u30fc\u30e0\u3092\u3053\u306e\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8\u306b\u623b\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.action.start.instance=\u3053\u306e\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u3092\u8d77\u52d5\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.action.start.router=\u3053\u306e\u30eb\u30fc\u30bf\u30fc\u3092\u8d77\u52d5\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.action.start.systemvm=\u3053\u306e\u30b7\u30b9\u30c6\u30e0 VM \u3092\u8d77\u52d5\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? @@ -1547,40 +1564,40 @@ message.action.stop.instance=\u3053\u306e\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u3 message.action.stop.router=\u3053\u306e\u4eee\u60f3\u30eb\u30fc\u30bf\u30fc\u3067\u63d0\u4f9b\u3059\u308b\u3059\u3079\u3066\u306e\u30b5\u30fc\u30d3\u30b9\u304c\u4e2d\u65ad\u3055\u308c\u307e\u3059\u3002\u3053\u306e\u30eb\u30fc\u30bf\u30fc\u3092\u505c\u6b62\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.action.stop.systemvm=\u3053\u306e\u30b7\u30b9\u30c6\u30e0 VM \u3092\u505c\u6b62\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.action.take.snapshot=\u3053\u306e\u30dc\u30ea\u30e5\u30fc\u30e0\u306e\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8\u3092\u4f5c\u6210\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? -message.action.revert.snapshot=\u6240\u6709\u30dc\u30ea\u30e5\u30fc\u30e0\u3092\u3053\u306e\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8\u306b\u623b\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.action.unmanage.cluster=\u30af\u30e9\u30b9\u30bf\u30fc\u3092\u975e\u7ba1\u7406\u5bfe\u8c61\u306b\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.action.vmsnapshot.delete=\u3053\u306e VM \u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8\u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.action.vmsnapshot.revert=VM \u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8\u3092\u5143\u306b\u623b\u3059 message.activate.project=\u3053\u306e\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u3092\u30a2\u30af\u30c6\u30a3\u30d6\u306b\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? -message.add.cluster.zone=\u30be\u30fc\u30f3 \u306b\u30cf\u30a4\u30d1\u30fc\u30d0\u30a4\u30b6\u30fc\u3067\u7ba1\u7406\u3055\u308c\u308b\u30af\u30e9\u30b9\u30bf\u30fc\u3092\u8ffd\u52a0\u3057\u307e\u3059 message.add.cluster=\u30be\u30fc\u30f3 \u306e\u30dd\u30c3\u30c9 \u306b\u30cf\u30a4\u30d1\u30fc\u30d0\u30a4\u30b6\u30fc\u3067\u7ba1\u7406\u3055\u308c\u308b\u30af\u30e9\u30b9\u30bf\u30fc\u3092\u8ffd\u52a0\u3057\u307e\u3059 +message.add.cluster.zone=\u30be\u30fc\u30f3 \u306b\u30cf\u30a4\u30d1\u30fc\u30d0\u30a4\u30b6\u30fc\u3067\u7ba1\u7406\u3055\u308c\u308b\u30af\u30e9\u30b9\u30bf\u30fc\u3092\u8ffd\u52a0\u3057\u307e\u3059 message.add.disk.offering=\u65b0\u3057\u3044\u30c7\u30a3\u30b9\u30af \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0\u3092\u8ffd\u52a0\u3059\u308b\u305f\u3081\u306b\u3001\u6b21\u306e\u30d1\u30e9\u30e1\u30fc\u30bf\u30fc\u3092\u6307\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044\u3002 message.add.domain=\u3053\u306e\u30c9\u30e1\u30a4\u30f3\u306b\u4f5c\u6210\u3059\u308b\u30b5\u30d6\u30c9\u30e1\u30a4\u30f3\u3092\u6307\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044\u3002 message.add.firewall=\u30be\u30fc\u30f3\u306b\u30d5\u30a1\u30a4\u30a2\u30a6\u30a9\u30fc\u30eb\u3092\u8ffd\u52a0\u3057\u307e\u3059 message.add.guest.network=\u30b2\u30b9\u30c8 \u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3092\u8ffd\u52a0\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.add.host=\u65b0\u3057\u3044\u30db\u30b9\u30c8\u3092\u8ffd\u52a0\u3059\u308b\u305f\u3081\u306b\u3001\u6b21\u306e\u30d1\u30e9\u30e1\u30fc\u30bf\u30fc\u3092\u6307\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044\u3002 +message.adding.host=\u30db\u30b9\u30c8\u3092\u8ffd\u52a0\u3057\u3066\u3044\u307e\u3059 +message.adding.Netscaler.device=Netscaler \u30c7\u30d0\u30a4\u30b9\u3092\u8ffd\u52a0\u3057\u3066\u3044\u307e\u3059 +message.adding.Netscaler.provider=Netscaler \u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u3092\u8ffd\u52a0\u3057\u3066\u3044\u307e\u3059 message.add.ip.range.direct.network=\u30be\u30fc\u30f3 \u306e\u76f4\u63a5\u30cd\u30c3\u30c8\u30ef\u30fc\u30af \u306b IP \u30a2\u30c9\u30ec\u30b9\u306e\u7bc4\u56f2\u3092\u8ffd\u52a0\u3057\u307e\u3059 message.add.ip.range.to.pod=

\u30dd\u30c3\u30c9 \u306b IP \u30a2\u30c9\u30ec\u30b9\u306e\u7bc4\u56f2\u3092\u8ffd\u52a0\u3057\u307e\u3059

message.add.ip.range=\u30be\u30fc\u30f3\u306e\u30d1\u30d6\u30ea\u30c3\u30af \u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306b IP \u30a2\u30c9\u30ec\u30b9\u306e\u7bc4\u56f2\u3092\u8ffd\u52a0\u3057\u307e\u3059 -message.add.load.balancer.under.ip=\u8ca0\u8377\u5206\u6563\u898f\u5247\u304c\u6b21\u306e IP \u30a2\u30c9\u30ec\u30b9\u306b\u5bfe\u3057\u3066\u8ffd\u52a0\u3055\u308c\u307e\u3057\u305f\: +message.additional.networks.desc=\u4eee\u60f3\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u304c\u63a5\u7d9a\u3059\u308b\u8ffd\u52a0\u306e\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044\u3002 message.add.load.balancer=\u30be\u30fc\u30f3\u306b\u8ca0\u8377\u5206\u6563\u88c5\u7f6e\u3092\u8ffd\u52a0\u3057\u307e\u3059 +message.add.load.balancer.under.ip=\u8ca0\u8377\u5206\u6563\u898f\u5247\u304c\u6b21\u306e IP \u30a2\u30c9\u30ec\u30b9\u306b\u5bfe\u3057\u3066\u8ffd\u52a0\u3055\u308c\u307e\u3057\u305f\: message.add.network=\u30be\u30fc\u30f3 \u306b\u65b0\u3057\u3044\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3092\u8ffd\u52a0\u3057\u307e\u3059 message.add.new.gateway.to.vpc=\u3053\u306e VPC \u306b\u65b0\u3057\u3044\u30b2\u30fc\u30c8\u30a6\u30a7\u30a4\u3092\u8ffd\u52a0\u3059\u308b\u305f\u3081\u306e\u60c5\u5831\u3092\u6307\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044\u3002 message.add.pod.during.zone.creation=\u5404\u30be\u30fc\u30f3\u306b\u306f 1 \u3064\u4ee5\u4e0a\u306e\u30dd\u30c3\u30c9\u304c\u5fc5\u8981\u3067\u3059\u3002\u4eca\u3053\u3053\u3067\u6700\u521d\u306e\u30dd\u30c3\u30c9\u3092\u8ffd\u52a0\u3057\u307e\u3059\u3002\u30dd\u30c3\u30c9\u306f\u30db\u30b9\u30c8\u3068\u30d7\u30e9\u30a4\u30de\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8 \u30b5\u30fc\u30d0\u30fc\u304b\u3089\u69cb\u6210\u3055\u308c\u307e\u3059\u304c\u3001\u3053\u308c\u3089\u306f\u5f8c\u306e\u624b\u9806\u3067\u8ffd\u52a0\u3057\u307e\u3059\u3002\u6700\u521d\u306b\u3001CloudStack \u306e\u5185\u90e8\u7ba1\u7406\u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u306e\u305f\u3081\u306b IP \u30a2\u30c9\u30ec\u30b9\u306e\u7bc4\u56f2\u3092\u4e88\u7d04\u3057\u307e\u3059\u3002IP \u30a2\u30c9\u30ec\u30b9\u306e\u7bc4\u56f2\u306f\u3001\u30af\u30e9\u30a6\u30c9\u5185\u306e\u5404\u30be\u30fc\u30f3\u3067\u91cd\u8907\u3057\u306a\u3044\u3088\u3046\u306b\u4e88\u7d04\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002 message.add.pod=\u30be\u30fc\u30f3 \u306b\u65b0\u3057\u3044\u30dd\u30c3\u30c9\u3092\u8ffd\u52a0\u3057\u307e\u3059 message.add.primary.storage=\u30be\u30fc\u30f3 \u306e\u30dd\u30c3\u30c9 \u306b\u65b0\u3057\u3044\u30d7\u30e9\u30a4\u30de\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8\u3092\u8ffd\u52a0\u3057\u307e\u3059 message.add.primary=\u65b0\u3057\u3044\u30d7\u30e9\u30a4\u30de\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8\u3092\u8ffd\u52a0\u3059\u308b\u305f\u3081\u306b\u3001\u6b21\u306e\u30d1\u30e9\u30e1\u30fc\u30bf\u30fc\u3092\u6307\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044\u3002 -message.add.region=\u65b0\u3057\u3044\u9818\u57df\u3092\u8ffd\u52a0\u3059\u308b\u305f\u3081\u306b\u5fc5\u8981\u306a\u60c5\u5831\u3092\u6307\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044\u3002 +message.add.region=\u65b0\u3057\u3044\u30ea\u30fc\u30b8\u30e7\u30f3\u3092\u8ffd\u52a0\u3059\u308b\u305f\u3081\u306b\u5fc5\u8981\u306a\u60c5\u5831\u3092\u6307\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044\u3002 message.add.secondary.storage=\u30be\u30fc\u30f3 \u306b\u65b0\u3057\u3044\u30b9\u30c8\u30ec\u30fc\u30b8\u3092\u8ffd\u52a0\u3057\u307e\u3059 message.add.service.offering=\u65b0\u3057\u3044\u30b3\u30f3\u30d4\u30e5\u30fc\u30c6\u30a3\u30f3\u30b0 \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0\u3092\u8ffd\u52a0\u3059\u308b\u305f\u3081\u306b\u3001\u6b21\u306e\u30c7\u30fc\u30bf\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002 message.add.system.service.offering=\u65b0\u3057\u3044\u30b7\u30b9\u30c6\u30e0 \u30b5\u30fc\u30d3\u30b9 \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0\u3092\u8ffd\u52a0\u3059\u308b\u305f\u3081\u306b\u3001\u6b21\u306e\u30c7\u30fc\u30bf\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002 message.add.template=\u65b0\u3057\u3044\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u3092\u4f5c\u6210\u3059\u308b\u305f\u3081\u306b\u3001\u6b21\u306e\u30c7\u30fc\u30bf\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002 message.add.volume=\u65b0\u3057\u3044\u30dc\u30ea\u30e5\u30fc\u30e0\u3092\u8ffd\u52a0\u3059\u308b\u305f\u3081\u306b\u3001\u6b21\u306e\u30c7\u30fc\u30bf\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002 message.add.VPN.gateway=VPN \u30b2\u30fc\u30c8\u30a6\u30a7\u30a4\u3092\u8ffd\u52a0\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? -message.adding.host=\u30db\u30b9\u30c8\u3092\u8ffd\u52a0\u3057\u3066\u3044\u307e\u3059 -message.adding.Netscaler.device=Netscaler \u30c7\u30d0\u30a4\u30b9\u3092\u8ffd\u52a0\u3057\u3066\u3044\u307e\u3059 -message.adding.Netscaler.provider=Netscaler \u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u3092\u8ffd\u52a0\u3057\u3066\u3044\u307e\u3059 -message.additional.networks.desc=\u4eee\u60f3\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u304c\u63a5\u7d9a\u3059\u308b\u8ffd\u52a0\u306e\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044\u3002 +message.admin.guide.read=VMware \u30d9\u30fc\u30b9\u306e VM \u306b\u3064\u3044\u3066\u306f\u3001\u30b5\u30a4\u30ba\u5909\u66f4\u306e\u524d\u306b\u7ba1\u7406\u8005\u30ac\u30a4\u30c9\u306e\u52d5\u7684\u306a\u30b5\u30a4\u30ba\u5909\u66f4\u306e\u30bb\u30af\u30b7\u30e7\u30f3\u3092\u304a\u8aad\u307f\u304f\u3060\u3055\u3044\u3002\u7d9a\u884c\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b?\\, message.advanced.mode.desc=VLAN \u30b5\u30dd\u30fc\u30c8\u3092\u6709\u52b9\u306b\u3059\u308b\u5834\u5408\u306f\u3001\u3053\u306e\u30cd\u30c3\u30c8\u30ef\u30fc\u30af \u30e2\u30c7\u30eb\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044\u3002\u3053\u306e\u30e2\u30c7\u30eb\u3067\u306f\u6700\u3082\u67d4\u8edf\u306b\u30ab\u30b9\u30bf\u30e0 \u30cd\u30c3\u30c8\u30ef\u30fc\u30af \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0\u3092\u63d0\u4f9b\u3067\u304d\u3001\u30d5\u30a1\u30a4\u30a2\u30a6\u30a9\u30fc\u30eb\u3001VPN\u3001\u8ca0\u8377\u5206\u6563\u88c5\u7f6e\u306e\u30b5\u30dd\u30fc\u30c8\u306e\u307b\u304b\u306b\u3001\u76f4\u63a5\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3068\u4eee\u60f3\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3082\u6709\u52b9\u306b\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002 message.advanced.security.group=\u30b2\u30b9\u30c8 VM \u3092\u5206\u96e2\u3059\u308b\u305f\u3081\u306b\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3 \u30b0\u30eb\u30fc\u30d7\u3092\u4f7f\u7528\u3059\u308b\u5834\u5408\u306f\u3001\u3053\u306e\u30aa\u30d7\u30b7\u30e7\u30f3\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044\u3002 message.advanced.virtual=\u30b2\u30b9\u30c8 VM \u3092\u5206\u96e2\u3059\u308b\u305f\u3081\u306b\u30be\u30fc\u30f3\u5168\u4f53\u306e VLAN \u3092\u4f7f\u7528\u3059\u308b\u5834\u5408\u306f\u3001\u3053\u306e\u30aa\u30d7\u30b7\u30e7\u30f3\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044\u3002 @@ -1594,36 +1611,74 @@ message.attach.volume=\u65b0\u3057\u3044\u30dc\u30ea\u30e5\u30fc\u30e0\u3092\u30 message.basic.mode.desc=VLAN \u30b5\u30dd\u30fc\u30c8\u304c\u4e0d\u8981\u3067\u3042\u308b\u5834\u5408\u306f\u3001\u3053\u306e\u30cd\u30c3\u30c8\u30ef\u30fc\u30af \u30e2\u30c7\u30eb\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044\u3002\u3053\u306e\u30cd\u30c3\u30c8\u30ef\u30fc\u30af \u30e2\u30c7\u30eb\u3067\u4f5c\u6210\u3055\u308c\u308b\u3059\u3079\u3066\u306e\u4eee\u60f3\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u306b\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u304b\u3089\u76f4\u63a5 IP \u30a2\u30c9\u30ec\u30b9\u304c\u5272\u308a\u5f53\u3066\u3089\u308c\u3001\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3 \u30b0\u30eb\u30fc\u30d7\u3092\u4f7f\u7528\u3057\u3066\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u3068\u5206\u96e2\u304c\u63d0\u4f9b\u3055\u308c\u307e\u3059\u3002 message.change.offering.confirm=\u3053\u306e\u4eee\u60f3\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u306e\u30b5\u30fc\u30d3\u30b9 \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0\u3092\u5909\u66f4\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.change.password=\u30d1\u30b9\u30ef\u30fc\u30c9\u3092\u5909\u66f4\u3057\u3066\u304f\u3060\u3055\u3044\u3002 +message.cluster.dedicated=\u30af\u30e9\u30b9\u30bf\u30fc\u3092\u5c02\u7528\u306b\u8a2d\u5b9a\u3057\u307e\u3057\u305f +message.cluster.dedication.released=\u5c02\u7528\u30af\u30e9\u30b9\u30bf\u30fc\u304c\u89e3\u653e\u3055\u308c\u307e\u3057\u305f message.configure.all.traffic.types=\u8907\u6570\u306e\u7269\u7406\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u304c\u3042\u308a\u307e\u3059\u3002[\u7de8\u96c6] \u3092\u30af\u30ea\u30c3\u30af\u3057\u3066\u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u306e\u7a2e\u985e\u3054\u3068\u306b\u30e9\u30d9\u30eb\u3092\u69cb\u6210\u3057\u3066\u304f\u3060\u3055\u3044\u3002 +message.configure.ldap=LDAP \u3092\u69cb\u6210\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.configuring.guest.traffic=\u30b2\u30b9\u30c8 \u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u3092\u69cb\u6210\u3057\u3066\u3044\u307e\u3059 message.configuring.physical.networks=\u7269\u7406\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3092\u69cb\u6210\u3057\u3066\u3044\u307e\u3059 message.configuring.public.traffic=\u30d1\u30d6\u30ea\u30c3\u30af \u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u3092\u69cb\u6210\u3057\u3066\u3044\u307e\u3059 message.configuring.storage.traffic=\u30b9\u30c8\u30ec\u30fc\u30b8 \u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u3092\u69cb\u6210\u3057\u3066\u3044\u307e\u3059 message.confirm.action.force.reconnect=\u3053\u306e\u30db\u30b9\u30c8\u3092\u5f37\u5236\u518d\u63a5\u7d9a\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +message.confirm.add.vnmc.provider=VNMC \u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u3092\u8ffd\u52a0\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +message.confirm.dedicate.cluster.domain.account=\u3053\u306e\u30af\u30e9\u30b9\u30bf\u30fc\u3092\u30c9\u30e1\u30a4\u30f3/\u30a2\u30ab\u30a6\u30f3\u30c8\u5c02\u7528\u306b\u8a2d\u5b9a\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +message.confirm.dedicate.host.domain.account=\u3053\u306e\u30db\u30b9\u30c8\u3092\u30c9\u30e1\u30a4\u30f3/\u30a2\u30ab\u30a6\u30f3\u30c8\u5c02\u7528\u306b\u8a2d\u5b9a\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +message.confirm.dedicate.pod.domain.account=\u3053\u306e\u30dd\u30c3\u30c9\u3092\u30c9\u30e1\u30a4\u30f3/\u30a2\u30ab\u30a6\u30f3\u30c8\u5c02\u7528\u306b\u8a2d\u5b9a\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +message.confirm.dedicate.zone=\u3053\u306e\u30be\u30fc\u30f3\u3092\u30c9\u30e1\u30a4\u30f3/\u30a2\u30ab\u30a6\u30f3\u30c8\u5c02\u7528\u306b\u8a2d\u5b9a\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +message.confirm.delete.ciscovnmc.resource=Cisco VNMC \u30ea\u30bd\u30fc\u30b9\u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.confirm.delete.F5=F5 \u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.confirm.delete.NetScaler=NetScaler \u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? -message.confirm.delete.SRX=SRX \u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.confirm.delete.PA=Palo Alto \u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +message.confirm.delete.secondary.staging.store=\u30bb\u30ab\u30f3\u30c0\u30ea \u30b9\u30c6\u30fc\u30b8\u30f3\u30b0 \u30b9\u30c8\u30a2\u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +message.confirm.delete.SRX=SRX \u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +message.confirm.delete.ucs.manager=UCS Manager \u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.confirm.destroy.router=\u3053\u306e\u30eb\u30fc\u30bf\u30fc\u3092\u7834\u68c4\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +message.confirm.disable.network.offering=\u3053\u306e\u30cd\u30c3\u30c8\u30ef\u30fc\u30af \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0\u3092\u7121\u52b9\u306b\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.confirm.disable.provider=\u3053\u306e\u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u3092\u7121\u52b9\u306b\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +message.confirm.disable.vnmc.provider=VNMC \u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u3092\u7121\u52b9\u306b\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +message.confirm.disable.vpc.offering=\u3053\u306e VPC \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0\u3092\u7121\u52b9\u5316\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +message.confirm.enable.network.offering=\u3053\u306e\u30cd\u30c3\u30c8\u30ef\u30fc\u30af \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0\u3092\u6709\u52b9\u306b\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.confirm.enable.provider=\u3053\u306e\u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u3092\u6709\u52b9\u306b\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +message.confirm.enable.vnmc.provider=VNMC \u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u3092\u6709\u52b9\u306b\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +message.confirm.enable.vpc.offering=\u3053\u306e VPC \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0\u3092\u6709\u52b9\u5316\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.confirm.join.project=\u3053\u306e\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u306b\u53c2\u52a0\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +message.confirm.refresh.blades=\u30d6\u30ec\u30fc\u30c9\u3092\u66f4\u65b0\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +message.confirm.release.dedicated.cluster=\u3053\u306e\u5c02\u7528\u30af\u30e9\u30b9\u30bf\u30fc\u3092\u89e3\u653e\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +message.confirm.release.dedicated.host=\u3053\u306e\u5c02\u7528\u30db\u30b9\u30c8\u3092\u89e3\u653e\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +message.confirm.release.dedicated.pod=\u3053\u306e\u5c02\u7528\u30dd\u30c3\u30c9\u3092\u89e3\u653e\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +message.confirm.release.dedicated.zone=\u3053\u306e\u5c02\u7528\u30be\u30fc\u30f3\u3092\u89e3\u653e\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +message.confirm.release.dedicate.vlan.range=\u5c02\u7528 VLAN \u306e\u7bc4\u56f2\u3092\u89e3\u653e\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.confirm.remove.IP.range=\u3053\u306e IP \u30a2\u30c9\u30ec\u30b9\u306e\u7bc4\u56f2\u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +message.confirm.remove.network.offering=\u3053\u306e\u30cd\u30c3\u30c8\u30ef\u30fc\u30af \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0\u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +message.confirm.remove.vmware.datacenter=VMware \u30c7\u30fc\u30bf\u30bb\u30f3\u30bf\u30fc\u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +message.confirm.remove.vpc.offering=\u3053\u306e VPC \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0\u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +message.confirm.scale.up.router.vm=\u30eb\u30fc\u30bf\u30fc VM \u306e\u30b5\u30a4\u30ba\u3092\u62e1\u5927\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +message.confirm.scale.up.system.vm=\u30b7\u30b9\u30c6\u30e0 VM \u306e\u30b5\u30a4\u30ba\u3092\u62e1\u5927\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.confirm.shutdown.provider=\u3053\u306e\u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u3092\u30b7\u30e3\u30c3\u30c8\u30c0\u30a6\u30f3\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +message.confirm.start.lb.vm=LB VM \u3092\u8d77\u52d5\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +message.confirm.stop.lb.vm=LB VM \u3092\u505c\u6b62\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +message.confirm.upgrade.router.newer.template=\u30eb\u30fc\u30bf\u30fc\u3092\u30a2\u30c3\u30d7\u30b0\u30ec\u30fc\u30c9\u3057\u3066\u65b0\u3057\u3044\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u3092\u4f7f\u7528\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +message.confirm.upgrade.routers.account.newtemplate=\u3053\u306e\u30a2\u30ab\u30a6\u30f3\u30c8\u306e\u3059\u3079\u3066\u306e\u30eb\u30fc\u30bf\u30fc\u3092\u30a2\u30c3\u30d7\u30b0\u30ec\u30fc\u30c9\u3057\u3066\u65b0\u3057\u3044\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u3092\u4f7f\u7528\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +message.confirm.upgrade.routers.cluster.newtemplate=\u3053\u306e\u30af\u30e9\u30b9\u30bf\u30fc\u306e\u3059\u3079\u3066\u306e\u30eb\u30fc\u30bf\u30fc\u3092\u30a2\u30c3\u30d7\u30b0\u30ec\u30fc\u30c9\u3057\u3066\u65b0\u3057\u3044\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u3092\u4f7f\u7528\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +message.confirm.upgrade.routers.newtemplate=\u3053\u306e\u30be\u30fc\u30f3\u306e\u3059\u3079\u3066\u306e\u30eb\u30fc\u30bf\u30fc\u3092\u30a2\u30c3\u30d7\u30b0\u30ec\u30fc\u30c9\u3057\u3066\u65b0\u3057\u3044\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u3092\u4f7f\u7528\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +message.confirm.upgrade.routers.pod.newtemplate=\u3053\u306e\u30dd\u30c3\u30c9\u306e\u3059\u3079\u3066\u306e\u30eb\u30fc\u30bf\u30fc\u3092\u30a2\u30c3\u30d7\u30b0\u30ec\u30fc\u30c9\u3057\u3066\u65b0\u3057\u3044\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u3092\u4f7f\u7528\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.copy.iso.confirm=ISO \u3092\u6b21\u306e\u5834\u6240\u306b\u30b3\u30d4\u30fc\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +message.copy.template.confirm=\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u3092\u30b3\u30d4\u30fc\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.copy.template=\u30be\u30fc\u30f3 \u304b\u3089\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8 XXX \u3092\u6b21\u306e\u5834\u6240\u306b\u30b3\u30d4\u30fc\u3057\u307e\u3059\: +message.create.template=\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u3092\u4f5c\u6210\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.create.template.vm=\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8 \u304b\u3089 VM \u3092\u4f5c\u6210\u3057\u307e\u3059 message.create.template.volume=\u30c7\u30a3\u30b9\u30af \u30dc\u30ea\u30e5\u30fc\u30e0 \u306e\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u3092\u4f5c\u6210\u3059\u308b\u524d\u306b\u3001\u6b21\u306e\u60c5\u5831\u3092\u6307\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044\u3002\u30dc\u30ea\u30e5\u30fc\u30e0 \u30b5\u30a4\u30ba\u306b\u3088\u3063\u3066\u306f\u3001\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u306e\u4f5c\u6210\u306b\u306f\u6570\u5206\u4ee5\u4e0a\u304b\u304b\u308b\u53ef\u80fd\u6027\u304c\u3042\u308a\u307e\u3059\u3002 -message.create.template=\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u3092\u4f5c\u6210\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.creating.cluster=\u30af\u30e9\u30b9\u30bf\u30fc\u3092\u4f5c\u6210\u3057\u3066\u3044\u307e\u3059 message.creating.guest.network=\u30b2\u30b9\u30c8 \u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3092\u4f5c\u6210\u3057\u3066\u3044\u307e\u3059 message.creating.physical.networks=\u7269\u7406\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3092\u4f5c\u6210\u3057\u3066\u3044\u307e\u3059 message.creating.pod=\u30dd\u30c3\u30c9\u3092\u4f5c\u6210\u3057\u3066\u3044\u307e\u3059 message.creating.primary.storage=\u30d7\u30e9\u30a4\u30de\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8\u3092\u4f5c\u6210\u3057\u3066\u3044\u307e\u3059 message.creating.secondary.storage=\u30bb\u30ab\u30f3\u30c0\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8\u3092\u4f5c\u6210\u3057\u3066\u3044\u307e\u3059 +message.creating.systemVM=\u30b7\u30b9\u30c6\u30e0 VM \u3092\u4f5c\u6210\u3057\u3066\u3044\u307e\u3059 (\u3057\u3070\u3089\u304f\u304a\u5f85\u3061\u304f\u3060\u3055\u3044) message.creating.zone=\u30be\u30fc\u30f3\u3092\u4f5c\u6210\u3057\u3066\u3044\u307e\u3059 message.decline.invitation=\u3053\u306e\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u3078\u306e\u62db\u5f85\u3092\u8f9e\u9000\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? -message.dedicate.zone=\u30be\u30fc\u30f3\u3092\u5c02\u7528\u306b\u8a2d\u5b9a\u3057\u3066\u3044\u307e\u3059 +message.dedicated.zone.released=\u5c02\u7528\u30be\u30fc\u30f3\u304c\u89e3\u653e\u3055\u308c\u307e\u3057\u305f +message.dedicate.zone=\u30be\u30fc\u30f3\u3092\u5c02\u7528\u5316\u3057\u3066\u3044\u307e\u3059 message.delete.account=\u3053\u306e\u30a2\u30ab\u30a6\u30f3\u30c8\u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.delete.affinity.group=\u3053\u306e\u30a2\u30d5\u30a3\u30cb\u30c6\u30a3 \u30b0\u30eb\u30fc\u30d7\u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.delete.gateway=\u3053\u306e\u30b2\u30fc\u30c8\u30a6\u30a7\u30a4\u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? @@ -1646,6 +1701,9 @@ message.disable.snapshot.policy=\u73fe\u5728\u306e\u30b9\u30ca\u30c3\u30d7\u30b7 message.disable.user=\u3053\u306e\u30e6\u30fc\u30b6\u30fc\u3092\u7121\u52b9\u306b\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.disable.vpn.access=VPN \u30a2\u30af\u30bb\u30b9\u3092\u7121\u52b9\u306b\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.disable.vpn=VPN \u3092\u7121\u52b9\u306b\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +message.disabling.network.offering=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0\u3092\u7121\u52b9\u306b\u3057\u3066\u3044\u307e\u3059 +message.disabling.vpc.offering=VPC \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0\u306e\u7121\u52b9\u5316 +message.disallowed.characters=\u8a31\u53ef\u3055\u308c\u306a\u3044\u6587\u5b57\: \\<\\,\\> message.download.ISO=ISO \u3092\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3059\u308b\u306b\u306f 00000 \u3092\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059 message.download.template=\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u3092\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3059\u308b\u306b\u306f 00000 \u3092\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059 message.download.volume.confirm=\u3053\u306e\u30dc\u30ea\u30e5\u30fc\u30e0\u3092\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? @@ -1655,17 +1713,25 @@ message.edit.confirm=[\u4fdd\u5b58] \u3092\u30af\u30ea\u30c3\u30af\u3059\u308b\u message.edit.limits=\u6b21\u306e\u30ea\u30bd\u30fc\u30b9\u306b\u5236\u9650\u3092\u6307\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044\u3002\u300c-1\u300d\u306f\u3001\u30ea\u30bd\u30fc\u30b9\u4f5c\u6210\u306b\u5236\u9650\u304c\u306a\u3044\u3053\u3068\u3092\u793a\u3057\u307e\u3059\u3002 message.edit.traffic.type=\u3053\u306e\u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u306e\u7a2e\u985e\u306b\u95a2\u9023\u4ed8\u3051\u308b\u30c8\u30e9\u30d5\u30a3\u30c3\u30af \u30e9\u30d9\u30eb\u3092\u6307\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044\u3002 message.enable.account=\u3053\u306e\u30a2\u30ab\u30a6\u30f3\u30c8\u3092\u6709\u52b9\u306b\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +message.enabled.vpn.ip.sec=IPSec \u4e8b\u524d\u5171\u6709\u30ad\u30fc\: +message.enabled.vpn=\u73fe\u5728\u3001VPN \u30a2\u30af\u30bb\u30b9\u304c\u6709\u52b9\u306b\u306a\u3063\u3066\u3044\u307e\u3059\u3002\u6b21\u306e IP \u30a2\u30c9\u30ec\u30b9\u7d4c\u7531\u3067\u30a2\u30af\u30bb\u30b9\u3067\u304d\u307e\u3059\u3002 message.enable.user=\u3053\u306e\u30e6\u30fc\u30b6\u30fc\u3092\u6709\u52b9\u306b\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.enable.vpn.access=\u73fe\u5728\u3053\u306e IP \u30a2\u30c9\u30ec\u30b9\u306b\u5bfe\u3059\u308b VPN \u306f\u7121\u52b9\u3067\u3059\u3002VPN \u30a2\u30af\u30bb\u30b9\u3092\u6709\u52b9\u306b\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.enable.vpn=\u3053\u306e IP \u30a2\u30c9\u30ec\u30b9\u306b\u5bfe\u3059\u308b VPN \u30a2\u30af\u30bb\u30b9\u3092\u6709\u52b9\u306b\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? -message.enabled.vpn.ip.sec=IPSec \u4e8b\u524d\u5171\u6709\u30ad\u30fc: -message.enabled.vpn=\u73fe\u5728\u3001VPN \u30a2\u30af\u30bb\u30b9\u304c\u6709\u52b9\u306b\u306a\u3063\u3066\u3044\u307e\u3059\u3002\u6b21\u306e IP \u30a2\u30c9\u30ec\u30b9\u7d4c\u7531\u3067\u30a2\u30af\u30bb\u30b9\u3067\u304d\u307e\u3059\u3002 +message.enabling.network.offering=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0\u3092\u6709\u52b9\u306b\u3057\u3066\u3044\u307e\u3059 message.enabling.security.group.provider=\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3 \u30b0\u30eb\u30fc\u30d7 \u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u3092\u6709\u52b9\u306b\u3057\u3066\u3044\u307e\u3059 +message.enabling.vpc.offering=VPC \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0\u306e\u6709\u52b9\u5316 +message.enabling.zone.dots=\u30be\u30fc\u30f3\u3092\u6709\u52b9\u306b\u3057\u3066\u3044\u307e\u3059... message.enabling.zone=\u30be\u30fc\u30f3\u3092\u6709\u52b9\u306b\u3057\u3066\u3044\u307e\u3059 +message.enter.seperated.list.multiple.cidrs=CIDR \u304c\u8907\u6570\u3042\u308b\u5834\u5408\u306f\u3001\u30b3\u30f3\u30de\u533a\u5207\u308a\u306e\u4e00\u89a7\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044 message.enter.token=\u96fb\u5b50\u30e1\u30fc\u30eb\u306e\u62db\u5f85\u72b6\u306b\u8a18\u8f09\u3055\u308c\u3066\u3044\u308b\u30c8\u30fc\u30af\u30f3\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002 message.generate.keys=\u3053\u306e\u30e6\u30fc\u30b6\u30fc\u306b\u65b0\u3057\u3044\u30ad\u30fc\u3092\u751f\u6210\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +message.gslb.delete.confirm=\u3053\u306e GSLB \u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +message.gslb.lb.remove.confirm=GSLB \u304b\u3089\u8ca0\u8377\u5206\u6563\u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.guest.traffic.in.advanced.zone=\u30b2\u30b9\u30c8 \u30cd\u30c3\u30c8\u30ef\u30fc\u30af \u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u306f\u3001\u30a8\u30f3\u30c9 \u30e6\u30fc\u30b6\u30fc\u306e\u4eee\u60f3\u30de\u30b7\u30f3\u9593\u306e\u901a\u4fe1\u3067\u3059\u3002\u5404\u7269\u7406\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306e\u30b2\u30b9\u30c8 \u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u3092\u901a\u4fe1\u3059\u308b\u305f\u3081\u306e VLAN ID \u306e\u7bc4\u56f2\u3092\u6307\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044\u3002 message.guest.traffic.in.basic.zone=\u30b2\u30b9\u30c8 \u30cd\u30c3\u30c8\u30ef\u30fc\u30af \u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u306f\u3001\u30a8\u30f3\u30c9 \u30e6\u30fc\u30b6\u30fc\u306e\u4eee\u60f3\u30de\u30b7\u30f3\u9593\u306e\u901a\u4fe1\u3067\u3059\u3002CloudStack \u3067\u30b2\u30b9\u30c8 VM \u306b\u5272\u308a\u5f53\u3066\u3089\u308c\u308b IP \u30a2\u30c9\u30ec\u30b9\u306e\u7bc4\u56f2\u3092\u6307\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044\u3002\u3053\u306e\u7bc4\u56f2\u304c\u4e88\u7d04\u6e08\u307f\u306e\u30b7\u30b9\u30c6\u30e0 IP \u30a2\u30c9\u30ec\u30b9\u306e\u7bc4\u56f2\u3068\u91cd\u8907\u3057\u306a\u3044\u3088\u3046\u306b\u6ce8\u610f\u3057\u3066\u304f\u3060\u3055\u3044\u3002 +message.host.dedicated=\u30db\u30b9\u30c8\u3092\u5c02\u7528\u306b\u8a2d\u5b9a\u3057\u307e\u3057\u305f +message.host.dedication.released=\u5c02\u7528\u30db\u30b9\u30c8\u304c\u89e3\u653e\u3055\u308c\u307e\u3057\u305f message.installWizard.click.retry=\u8d77\u52d5\u3092\u518d\u8a66\u884c\u3059\u308b\u306b\u306f\u30dc\u30bf\u30f3\u3092\u30af\u30ea\u30c3\u30af\u3057\u3066\u304f\u3060\u3055\u3044\u3002 message.installWizard.copy.whatIsACluster=\u30af\u30e9\u30b9\u30bf\u30fc\u306f\u30db\u30b9\u30c8\u3092\u30b0\u30eb\u30fc\u30d7\u5316\u3059\u308b\u65b9\u6cd5\u3067\u3059\u30021 \u3064\u306e\u30af\u30e9\u30b9\u30bf\u30fc\u5185\u306e\u30db\u30b9\u30c8\u306f\u3059\u3079\u3066\u540c\u4e00\u306e\u30cf\u30fc\u30c9\u30a6\u30a7\u30a2\u304b\u3089\u69cb\u6210\u3055\u308c\u3001\u540c\u3058\u30cf\u30a4\u30d1\u30fc\u30d0\u30a4\u30b6\u30fc\u3092\u5b9f\u884c\u3057\u3001\u540c\u3058\u30b5\u30d6\u30cd\u30c3\u30c8\u4e0a\u306b\u3042\u308a\u3001\u540c\u3058\u5171\u6709\u30b9\u30c8\u30ec\u30fc\u30b8\u306b\u30a2\u30af\u30bb\u30b9\u3057\u307e\u3059\u3002\u540c\u3058\u30af\u30e9\u30b9\u30bf\u30fc\u5185\u306e\u30db\u30b9\u30c8\u9593\u3067\u306f\u3001\u30e6\u30fc\u30b6\u30fc\u3078\u306e\u30b5\u30fc\u30d3\u30b9\u3092\u4e2d\u65ad\u305b\u305a\u306b\u3001\u4eee\u60f3\u30de\u30b7\u30f3 \u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u3092\u30e9\u30a4\u30d6 \u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002\u30af\u30e9\u30b9\u30bf\u30fc\u306f CloudStack&\#8482; \u74b0\u5883\u5185\u306e 3 \u756a\u76ee\u306b\u5927\u304d\u306a\u7d44\u7e54\u5358\u4f4d\u3067\u3059\u3002\u30af\u30e9\u30b9\u30bf\u30fc\u306f\u30dd\u30c3\u30c9\u306b\u542b\u307e\u308c\u3001\u30dd\u30c3\u30c9\u306f\u30be\u30fc\u30f3\u306b\u542b\u307e\u308c\u307e\u3059\u3002

CloudStack&\#8482; \u3067\u306f 1 \u3064\u306e\u30af\u30e9\u30a6\u30c9\u74b0\u5883\u306b\u8907\u6570\u306e\u30af\u30e9\u30b9\u30bf\u30fc\u3092\u8a2d\u5b9a\u3067\u304d\u307e\u3059\u304c\u3001\u57fa\u672c\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3067\u306f\u30af\u30e9\u30b9\u30bf\u30fc\u306f 1 \u3064\u3067\u3059\u3002 message.installWizard.copy.whatIsAHost=\u30db\u30b9\u30c8\u306f\u5358\u4e00\u306e\u30b3\u30f3\u30d4\u30e5\u30fc\u30bf\u30fc\u3067\u3001\u30b2\u30b9\u30c8\u4eee\u60f3\u30de\u30b7\u30f3\u3092\u5b9f\u884c\u3059\u308b\u30b3\u30f3\u30d4\u30e5\u30fc\u30c6\u30a3\u30f3\u30b0 \u30ea\u30bd\u30fc\u30b9\u3092\u63d0\u4f9b\u3057\u307e\u3059\u3002\u30d9\u30a2 \u30e1\u30bf\u30eb \u30db\u30b9\u30c8\u3092\u9664\u3044\u3066\u3001\u5404\u30db\u30b9\u30c8\u306b\u306f\u30b2\u30b9\u30c8\u4eee\u60f3\u30de\u30b7\u30f3\u3092\u7ba1\u7406\u3059\u308b\u305f\u3081\u306e\u30cf\u30a4\u30d1\u30fc\u30d0\u30a4\u30b6\u30fc \u30bd\u30d5\u30c8\u30a6\u30a7\u30a2\u3092\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3057\u307e\u3059\u3002\u30d9\u30a2 \u30e1\u30bf\u30eb \u30db\u30b9\u30c8\u306b\u3064\u3044\u3066\u306f\u3001\u300e\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u30ac\u30a4\u30c9\u4e0a\u7d1a\u7de8\u300f\u3067\u7279\u6b8a\u4f8b\u3068\u3057\u3066\u8aac\u660e\u3057\u307e\u3059\u3002\u305f\u3068\u3048\u3070\u3001KVM \u304c\u6709\u52b9\u306a Linux \u30b5\u30fc\u30d0\u30fc\u3001Citrix XenServer \u304c\u52d5\u4f5c\u3059\u308b\u30b5\u30fc\u30d0\u30fc\u3001\u304a\u3088\u3073 ESXi \u30b5\u30fc\u30d0\u30fc\u304c\u30db\u30b9\u30c8\u3067\u3059\u3002\u57fa\u672c\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3067\u306f\u3001XenServer \u307e\u305f\u306f KVM \u3092\u5b9f\u884c\u3059\u308b\u5358\u4e00\u306e\u30db\u30b9\u30c8\u3092\u4f7f\u7528\u3057\u307e\u3059\u3002

\u30db\u30b9\u30c8\u306f CloudStack&\#8482; \u74b0\u5883\u5185\u306e\u6700\u5c0f\u306e\u7d44\u7e54\u5358\u4f4d\u3067\u3059\u3002\u30db\u30b9\u30c8\u306f\u30af\u30e9\u30b9\u30bf\u30fc\u306b\u542b\u307e\u308c\u3001\u30af\u30e9\u30b9\u30bf\u30fc\u306f\u30dd\u30c3\u30c9\u306b\u542b\u307e\u308c\u3001\u30dd\u30c3\u30c9\u306f\u30be\u30fc\u30f3\u306b\u542b\u307e\u308c\u307e\u3059\u3002 @@ -1700,12 +1766,14 @@ message.installWizard.tooltip.configureGuestTraffic.guestGateway=\u30b2\u30b9\u3 message.installWizard.tooltip.configureGuestTraffic.guestNetmask=\u30b2\u30b9\u30c8\u306e\u4f7f\u7528\u3059\u308b\u30b5\u30d6\u30cd\u30c3\u30c8\u4e0a\u3067\u4f7f\u7528\u3055\u308c\u308b\u30cd\u30c3\u30c8\u30de\u30b9\u30af\u3067\u3059\u3002 message.installWizard.tooltip.configureGuestTraffic.guestStartIp=\u3053\u306e\u30be\u30fc\u30f3\u306e\u30b2\u30b9\u30c8\u306b\u5272\u308a\u5f53\u3066\u308b\u3053\u3068\u304c\u3067\u304d\u308b IP \u30a2\u30c9\u30ec\u30b9\u306e\u7bc4\u56f2\u3067\u3059\u3002\u4f7f\u7528\u3059\u308b NIC \u304c 1 \u3064\u306e\u5834\u5408\u306f\u3001\u3053\u308c\u3089\u306e IP \u30a2\u30c9\u30ec\u30b9\u306f\u30dd\u30c3\u30c9\u306e CIDR \u3068\u540c\u3058 CIDR \u306b\u542b\u307e\u308c\u3066\u3044\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002 message.installWizard.tooltip.configureGuestTraffic.name=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306e\u540d\u524d\u3067\u3059\u3002 +message.instance.scaled.up.confirm=\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u306e\u30b5\u30a4\u30ba\u3092\u62e1\u5927\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.instanceWizard.noTemplates=\u4f7f\u7528\u53ef\u80fd\u306a\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u304c\u3042\u308a\u307e\u305b\u3093\u3002\u4e92\u63db\u6027\u306e\u3042\u308b\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u3092\u8ffd\u52a0\u3057\u3066\u3001\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9 \u30a6\u30a3\u30b6\u30fc\u30c9\u3092\u518d\u8d77\u52d5\u3057\u3066\u304f\u3060\u3055\u3044\u3002 message.ip.address.changed=\u304a\u4f7f\u3044\u306e IP \u30a2\u30c9\u30ec\u30b9\u304c\u5909\u66f4\u3055\u308c\u3066\u3044\u308b\u53ef\u80fd\u6027\u304c\u3042\u308a\u307e\u3059\u3002\u4e00\u89a7\u3092\u66f4\u65b0\u3057\u307e\u3059\u304b? \u305d\u306e\u5834\u5408\u306f\u3001\u8a73\u7d30\u30da\u30a4\u30f3\u304c\u9589\u3058\u308b\u3053\u3068\u306b\u6ce8\u610f\u3057\u3066\u304f\u3060\u3055\u3044\u3002 message.iso.desc=\u30c7\u30fc\u30bf\u307e\u305f\u306f OS \u8d77\u52d5\u53ef\u80fd\u30e1\u30c7\u30a3\u30a2\u3092\u542b\u3080\u30c7\u30a3\u30b9\u30af \u30a4\u30e1\u30fc\u30b8 message.join.project=\u3053\u308c\u3067\u3001\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u306b\u53c2\u52a0\u3057\u307e\u3057\u305f\u3002\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u3092\u53c2\u7167\u3059\u308b\u306b\u306f\u30d7\u30ed\u30b8\u30a7\u30af\u30c8 \u30d3\u30e5\u30fc\u306b\u5207\u308a\u66ff\u3048\u3066\u304f\u3060\u3055\u3044\u3002 message.launch.vm.on.private.network=\u30d7\u30e9\u30a4\u30d9\u30fc\u30c8\u306a\u5c02\u7528\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3067\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u3092\u8d77\u52d5\u3057\u307e\u3059\u304b? message.launch.zone=\u30be\u30fc\u30f3\u3092\u8d77\u52d5\u3059\u308b\u6e96\u5099\u304c\u3067\u304d\u307e\u3057\u305f\u3002\u6b21\u306e\u624b\u9806\u306b\u9032\u3093\u3067\u304f\u3060\u3055\u3044\u3002 +message.listView.subselect.multi=(Ctrl/Cmd-click) message.lock.account=\u3053\u306e\u30a2\u30ab\u30a6\u30f3\u30c8\u3092\u30ed\u30c3\u30af\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? \u3053\u306e\u30a2\u30ab\u30a6\u30f3\u30c8\u306e\u3059\u3079\u3066\u306e\u30e6\u30fc\u30b6\u30fc\u304c\u30af\u30e9\u30a6\u30c9 \u30ea\u30bd\u30fc\u30b9\u3092\u7ba1\u7406\u3067\u304d\u306a\u304f\u306a\u308a\u307e\u3059\u3002\u305d\u306e\u5f8c\u3082\u65e2\u5b58\u306e\u30ea\u30bd\u30fc\u30b9\u306b\u306f\u30a2\u30af\u30bb\u30b9\u3067\u304d\u307e\u3059\u3002 message.migrate.instance.confirm=\u4eee\u60f3\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u306e\u79fb\u884c\u5148\u306f\u6b21\u306e\u30db\u30b9\u30c8\u3067\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.migrate.instance.to.host=\u5225\u306e\u30db\u30b9\u30c8\u306b\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u3092\u79fb\u884c\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? @@ -1713,7 +1781,11 @@ message.migrate.instance.to.ps=\u5225\u306e\u30d7\u30e9\u30a4\u30de\u30ea \u30b9 message.migrate.router.confirm=\u30eb\u30fc\u30bf\u30fc\u306e\u79fb\u884c\u5148\u306f\u6b21\u306e\u30db\u30b9\u30c8\u3067\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.migrate.systemvm.confirm=\u30b7\u30b9\u30c6\u30e0 VM \u306e\u79fb\u884c\u5148\u306f\u6b21\u306e\u30db\u30b9\u30c8\u3067\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.migrate.volume=\u5225\u306e\u30d7\u30e9\u30a4\u30de\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8\u306b\u30dc\u30ea\u30e5\u30fc\u30e0\u3092\u79fb\u884c\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +message.network.addVM.desc=\u3053\u306e VM \u3092\u8ffd\u52a0\u3059\u308b\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3092\u6307\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044\u3002\u3053\u306e\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306e\u305f\u3081\u306e\u65b0\u3057\u3044 NIC \u304c\u8ffd\u52a0\u3055\u308c\u307e\u3059\u3002 +message.network.addVMNIC=\u3053\u306e\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306e\u65b0\u3057\u3044 VM NIC \u3092\u8ffd\u52a0\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.new.user=\u30a2\u30ab\u30a6\u30f3\u30c8\u306b\u65b0\u3057\u3044\u30e6\u30fc\u30b6\u30fc\u3092\u8ffd\u52a0\u3059\u308b\u305f\u3081\u306b\u3001\u6b21\u306e\u60c5\u5831\u3092\u6307\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044\u3002 +message.no.affinity.groups=\u30a2\u30d5\u30a3\u30cb\u30c6\u30a3 \u30b0\u30eb\u30fc\u30d7\u304c\u3042\u308a\u307e\u305b\u3093\u3002\u6b21\u306e\u624b\u9806\u306b\u9032\u3093\u3067\u304f\u3060\u3055\u3044\u3002 +message.no.host.available=\u79fb\u884c\u306b\u4f7f\u7528\u3067\u304d\u308b\u30db\u30b9\u30c8\u306f\u3042\u308a\u307e\u305b\u3093 message.no.network.support.configuration.not.true=\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3 \u30b0\u30eb\u30fc\u30d7\u304c\u6709\u52b9\u306a\u30be\u30fc\u30f3\u304c\u7121\u3044\u305f\u3081\u3001\u8ffd\u52a0\u306e\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u6a5f\u80fd\u306f\u3042\u308a\u307e\u305b\u3093\u3002\u624b\u9806 5. \u306b\u9032\u3093\u3067\u304f\u3060\u3055\u3044\u3002 message.no.network.support=\u30cf\u30a4\u30d1\u30fc\u30d0\u30a4\u30b6\u30fc\u3068\u3057\u3066 vSphere \u3092\u9078\u629e\u3057\u307e\u3057\u305f\u304c\u3001\u3053\u306e\u30cf\u30a4\u30d1\u30fc\u30d0\u30a4\u30b6\u30fc\u306b\u8ffd\u52a0\u306e\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u6a5f\u80fd\u306f\u3042\u308a\u307e\u305b\u3093\u3002\u624b\u9806 5. \u306b\u9032\u3093\u3067\u304f\u3060\u3055\u3044\u3002 message.no.projects.adminOnly=\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u304c\u3042\u308a\u307e\u305b\u3093\u3002
\u7ba1\u7406\u8005\u306b\u65b0\u3057\u3044\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u306e\u4f5c\u6210\u3092\u4f9d\u983c\u3057\u3066\u304f\u3060\u3055\u3044\u3002 @@ -1731,11 +1803,17 @@ message.please.select.a.configuration.for.your.zone=\u30be\u30fc\u30f3\u306e\u69 message.please.select.a.different.public.and.management.network.before.removing=\u524a\u9664\u306e\u524d\u306b\u7570\u306a\u308b\u30d1\u30d6\u30ea\u30c3\u30af\u304a\u3088\u3073\u7ba1\u7406\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044\u3002 message.please.select.networks=\u4eee\u60f3\u30de\u30b7\u30f3\u306e\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044\u3002 message.please.wait.while.zone.is.being.created=\u30be\u30fc\u30f3\u304c\u4f5c\u6210\u3055\u308c\u308b\u307e\u3067\u3057\u3070\u3089\u304f\u304a\u5f85\u3061\u304f\u3060\u3055\u3044... +message.pod.dedication.released=\u5c02\u7528\u30dd\u30c3\u30c9\u304c\u89e3\u653e\u3055\u308c\u307e\u3057\u305f +message.portable.ip.delete.confirm=\u3053\u306e\u30dd\u30fc\u30bf\u30d6\u30eb IP \u30a2\u30c9\u30ec\u30b9\u306e\u7bc4\u56f2\u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.project.invite.sent=\u30e6\u30fc\u30b6\u30fc\u306b\u62db\u5f85\u72b6\u304c\u9001\u4fe1\u3055\u308c\u307e\u3057\u305f\u3002\u30e6\u30fc\u30b6\u30fc\u304c\u62db\u5f85\u3092\u627f\u8afe\u3059\u308b\u3068\u3001\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u306b\u8ffd\u52a0\u3055\u308c\u307e\u3059\u3002 message.public.traffic.in.advanced.zone=\u30af\u30e9\u30a6\u30c9\u5185\u306e VM \u304c\u30a4\u30f3\u30bf\u30fc\u30cd\u30c3\u30c8\u306b\u30a2\u30af\u30bb\u30b9\u3059\u308b\u3068\u3001\u30d1\u30d6\u30ea\u30c3\u30af \u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u304c\u751f\u6210\u3055\u308c\u307e\u3059\u3002\u3053\u306e\u305f\u3081\u306b\u3001\u4e00\u822c\u306b\u30a2\u30af\u30bb\u30b9\u53ef\u80fd\u306a IP \u30a2\u30c9\u30ec\u30b9\u3092\u5272\u308a\u5f53\u3066\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002\u30a8\u30f3\u30c9 \u30e6\u30fc\u30b6\u30fc\u306f CloudStack \u306e\u30e6\u30fc\u30b6\u30fc \u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30a4\u30b9\u3092\u4f7f\u7528\u3057\u3066\u3053\u308c\u3089\u306e IP \u30a2\u30c9\u30ec\u30b9\u3092\u53d6\u5f97\u3057\u3001\u30b2\u30b9\u30c8 \u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3068\u30d1\u30d6\u30ea\u30c3\u30af \u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306e\u9593\u306b NAT \u3092\u5b9f\u88c5\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002

\u30a4\u30f3\u30bf\u30fc\u30cd\u30c3\u30c8 \u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u306e\u305f\u3081\u306b\u3001\u5c11\u306a\u304f\u3068\u3082 1 \u3064 IP \u30a2\u30c9\u30ec\u30b9\u306e\u7bc4\u56f2\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002 message.public.traffic.in.basic.zone=\u30af\u30e9\u30a6\u30c9\u5185\u306e VM \u304c\u30a4\u30f3\u30bf\u30fc\u30cd\u30c3\u30c8\u306b\u30a2\u30af\u30bb\u30b9\u3059\u308b\u304b\u30a4\u30f3\u30bf\u30fc\u30cd\u30c3\u30c8\u7d4c\u7531\u3067\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u306b\u30b5\u30fc\u30d3\u30b9\u3092\u63d0\u4f9b\u3059\u308b\u3068\u3001\u30d1\u30d6\u30ea\u30c3\u30af \u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u304c\u751f\u6210\u3055\u308c\u307e\u3059\u3002\u3053\u306e\u305f\u3081\u306b\u3001\u4e00\u822c\u306b\u30a2\u30af\u30bb\u30b9\u53ef\u80fd\u306a IP \u30a2\u30c9\u30ec\u30b9\u3092\u5272\u308a\u5f53\u3066\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u3092\u4f5c\u6210\u3059\u308b\u3068\u3001\u30b2\u30b9\u30c8 IP \u30a2\u30c9\u30ec\u30b9\u306e\u307b\u304b\u306b\u3053\u306e\u30d1\u30d6\u30ea\u30c3\u30af IP \u30a2\u30c9\u30ec\u30b9\u306e\u7bc4\u56f2\u304b\u3089\u30a2\u30c9\u30ec\u30b9\u304c 1 \u3064\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u306b\u5272\u308a\u5f53\u3066\u3089\u308c\u307e\u3059\u3002\u30d1\u30d6\u30ea\u30c3\u30af IP \u30a2\u30c9\u30ec\u30b9\u3068\u30b2\u30b9\u30c8 IP \u30a2\u30c9\u30ec\u30b9\u306e\u9593\u306b\u3001\u9759\u7684\u306a 1 \u5bfe 1 \u306e NAT \u304c\u81ea\u52d5\u7684\u306b\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7\u3055\u308c\u307e\u3059\u3002\u30a8\u30f3\u30c9 \u30e6\u30fc\u30b6\u30fc\u306f CloudStack \u306e\u30e6\u30fc\u30b6\u30fc \u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30a4\u30b9\u3092\u4f7f\u7528\u3057\u3066\u8ffd\u52a0\u306e IP \u30a2\u30c9\u30ec\u30b9\u3092\u53d6\u5f97\u3057\u3001\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u3068\u30d1\u30d6\u30ea\u30c3\u30af IP \u30a2\u30c9\u30ec\u30b9\u306e\u9593\u306b\u9759\u7684 NAT \u3092\u5b9f\u88c5\u3059\u308b\u3053\u3068\u3082\u3067\u304d\u307e\u3059\u3002 -message.redirecting.region=\u9818\u57df\u306b\u30ea\u30c0\u30a4\u30ec\u30af\u30c8\u3057\u3066\u3044\u307e\u3059... -message.remove.region=\u3053\u306e\u7ba1\u7406\u30b5\u30fc\u30d0\u30fc\u304b\u3089\u3053\u306e\u9818\u57df\u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +message.read.admin.guide.scaling.up=\u30b5\u30a4\u30ba\u3092\u62e1\u5927\u3059\u308b\u524d\u306b\u7ba1\u7406\u8005\u30ac\u30a4\u30c9\u306e\u52d5\u7684\u306a\u30b5\u30a4\u30ba\u5909\u66f4\u306e\u30bb\u30af\u30b7\u30e7\u30f3\u3092\u304a\u8aad\u307f\u304f\u3060\u3055\u3044\u3002 +message.recover.vm=\u3053\u306e VM \u3092\u5fa9\u65e7\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +message.redirecting.region=\u30ea\u30fc\u30b8\u30e7\u30f3\u306b\u30ea\u30c0\u30a4\u30ec\u30af\u30c8\u3057\u3066\u3044\u307e\u3059... +message.reinstall.vm=\u6ce8\: \u6ce8\u610f\u3057\u3066\u7d9a\u884c\u3057\u3066\u304f\u3060\u3055\u3044\u3002\u3053\u306e\u51e6\u7406\u306f\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u304b\u3089 VM \u304c\u518d\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3055\u308c\u307e\u3059\u3002\u30eb\u30fc\u30c8\u30c7\u30a3\u30b9\u30af\u4e0a\u306e\u30c7\u30fc\u30bf\u306f\u5931\u308f\u308c\u3001\u8ffd\u52a0\u30dc\u30ea\u30e5\u30fc\u30e0\u306e\u30c7\u30fc\u30bf\u306f\u4f55\u3082\u51e6\u7406\u3055\u308c\u307e\u305b\u3093\u3002 +message.remove.ldap=LDAP \u69cb\u6210\u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +message.remove.region=\u7ba1\u7406\u30b5\u30fc\u30d0\u30fc\u304b\u3089\u3053\u306e\u30ea\u30fc\u30b8\u30e7\u30f3\u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.remove.vpc=VPC \u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.remove.vpn.access=\u6b21\u306e\u30e6\u30fc\u30b6\u30fc\u304b\u3089 VPN \u30a2\u30af\u30bb\u30b9\u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.reset.password.warning.notPasswordEnabled=\u3053\u306e\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u306e\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u306f\u3001\u30d1\u30b9\u30ef\u30fc\u30c9\u7ba1\u7406\u3092\u6709\u52b9\u306b\u305b\u305a\u306b\u4f5c\u6210\u3055\u308c\u307e\u3057\u305f\u3002 @@ -1745,17 +1823,23 @@ message.restart.mgmt.server=\u65b0\u3057\u3044\u8a2d\u5b9a\u3092\u6709\u52b9\u30 message.restart.mgmt.usage.server=\u65b0\u3057\u3044\u8a2d\u5b9a\u3092\u6709\u52b9\u306b\u3059\u308b\u305f\u3081\u306b\u3001\u7ba1\u7406\u30b5\u30fc\u30d0\u30fc\u3068\u4f7f\u7528\u72b6\u6cc1\u6e2c\u5b9a\u30b5\u30fc\u30d0\u30fc\u3092\u518d\u8d77\u52d5\u3057\u3066\u304f\u3060\u3055\u3044\u3002 message.restart.network=\u3053\u306e\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3067\u63d0\u4f9b\u3059\u308b\u3059\u3079\u3066\u306e\u30b5\u30fc\u30d3\u30b9\u304c\u4e2d\u65ad\u3055\u308c\u307e\u3059\u3002\u3053\u306e\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3092\u518d\u8d77\u52d5\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.restart.vpc=VPC \u3092\u518d\u8d77\u52d5\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +message.restoreVM=VM \u3092\u5fa9\u5143\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.security.group.usage=(\u8a72\u5f53\u3059\u308b\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3 \u30b0\u30eb\u30fc\u30d7\u3092\u3059\u3079\u3066\u9078\u629e\u3059\u308b\u306b\u306f\u3001Ctrl \u30ad\u30fc\u3092\u62bc\u3057\u306a\u304c\u3089\u30af\u30ea\u30c3\u30af\u3057\u3066\u304f\u3060\u3055\u3044) +message.select.affinity.groups=\u3053\u306e VM \u3092\u8ffd\u52a0\u3059\u308b\u30a2\u30d5\u30a3\u30cb\u30c6\u30a3 \u30b0\u30eb\u30fc\u30d7\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044\u3002 message.select.a.zone=\u30be\u30fc\u30f3\u306f\u901a\u5e38\u3001\u5358\u4e00\u306e\u30c7\u30fc\u30bf\u30bb\u30f3\u30bf\u30fc\u306b\u76f8\u5f53\u3057\u307e\u3059\u3002\u8907\u6570\u306e\u30be\u30fc\u30f3\u3092\u8a2d\u5b9a\u3057\u3001\u7269\u7406\u7684\u306b\u5206\u96e2\u3057\u3066\u5197\u9577\u6027\u3092\u6301\u305f\u305b\u308b\u3053\u3068\u306b\u3088\u308a\u3001\u30af\u30e9\u30a6\u30c9\u306e\u4fe1\u983c\u6027\u3092\u9ad8\u3081\u307e\u3059\u3002 message.select.instance=\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044\u3002 message.select.iso=\u65b0\u3057\u3044\u4eee\u60f3\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u306e ISO \u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044\u3002 message.select.item=\u9805\u76ee\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044\u3002 message.select.security.groups=\u65b0\u3057\u3044\u4eee\u60f3\u30de\u30b7\u30f3\u306e\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3 \u30b0\u30eb\u30fc\u30d7\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044\u3002 message.select.template=\u65b0\u3057\u3044\u4eee\u60f3\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u306e\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044\u3002 +message.select.tier=\u968e\u5c64\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044\u3002 +message.set.default.NIC.manual=\u4eca\u3059\u3050\u306b\u3053\u306e VM \u306e\u30c7\u30d5\u30a9\u30eb\u30c8 NIC \u3092\u624b\u52d5\u3067\u66f4\u65b0\u3057\u3066\u304f\u3060\u3055\u3044\u3002 +message.set.default.NIC=\u3053\u306e NIC \u3092\u3053\u306e VM \u306e\u30c7\u30d5\u30a9\u30eb\u30c8\u306b\u8a2d\u5b9a\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.setup.physical.network.during.zone.creation.basic=\u57fa\u672c\u30be\u30fc\u30f3\u3092\u8ffd\u52a0\u3059\u308b\u3068\u304d\u306f\u3001\u30cf\u30a4\u30d1\u30fc\u30d0\u30a4\u30b6\u30fc\u4e0a\u306e NIC \u306b\u5bfe\u5fdc\u3059\u308b 1 \u3064\u306e\u7269\u7406\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3092\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7\u3067\u304d\u307e\u3059\u3002\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306f\u3044\u304f\u3064\u304b\u306e\u7a2e\u985e\u306e\u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u3092\u4f1d\u9001\u3057\u307e\u3059\u3002

\u7269\u7406\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306b\u307b\u304b\u306e\u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u306e\u7a2e\u985e\u3092\u30c9\u30e9\u30c3\u30b0 \u30a2\u30f3\u30c9 \u30c9\u30ed\u30c3\u30d7\u3059\u308b\u3053\u3068\u3082\u3067\u304d\u307e\u3059\u3002 message.setup.physical.network.during.zone.creation=\u62e1\u5f35\u30be\u30fc\u30f3\u3092\u8ffd\u52a0\u3059\u308b\u3068\u304d\u306f\u30011 \u3064\u4ee5\u4e0a\u306e\u7269\u7406\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3092\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002\u5404\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306f\u30cf\u30a4\u30d1\u30fc\u30d0\u30a4\u30b6\u30fc\u4e0a\u306e 1 \u3064\u306e NIC \u306b\u5bfe\u5fdc\u3057\u307e\u3059\u3002\u5404\u7269\u7406\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3067\u306f\u3001\u7d44\u307f\u5408\u308f\u305b\u306b\u5236\u9650\u304c\u3042\u308a\u307e\u3059\u304c\u30011 \u3064\u4ee5\u4e0a\u306e\u7a2e\u985e\u306e\u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u3092\u901a\u4fe1\u3067\u304d\u307e\u3059\u3002

\u5404\u7269\u7406\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306b\u5bfe\u3057\u3066\u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u306e\u7a2e\u985e\u3092\u30c9\u30e9\u30c3\u30b0 \u30a2\u30f3\u30c9 \u30c9\u30ed\u30c3\u30d7\u3057\u3066\u304f\u3060\u3055\u3044\u3002 message.setup.successful=\u30af\u30e9\u30a6\u30c9\u304c\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7\u3055\u308c\u307e\u3057\u305f\u3002 message.snapshot.schedule=\u6b21\u306e\u30aa\u30d7\u30b7\u30e7\u30f3\u304b\u3089\u9078\u629e\u3057\u3066\u30dd\u30ea\u30b7\u30fc\u306e\u57fa\u672c\u8a2d\u5b9a\u3092\u9069\u7528\u3059\u308b\u3053\u3068\u306b\u3088\u308a\u3001\u5b9a\u671f\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8\u306e\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u3092\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7\u3067\u304d\u307e\u3059\u3002 +message.specifiy.tag.key.value=\u30bf\u30b0 \u30ad\u30fc\u304a\u3088\u3073\u5024\u3092\u6307\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044 message.specify.url=URL \u3092\u6307\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044 message.step.1.continue=\u7d9a\u884c\u3059\u308b\u306b\u306f\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u307e\u305f\u306f ISO \u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044 message.step.1.desc=\u65b0\u3057\u3044\u4eee\u60f3\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u7528\u306e\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044\u3002ISO \u3092\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3067\u304d\u308b\u7a7a\u767d\u306e\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u3092\u9078\u629e\u3059\u308b\u3053\u3068\u3082\u3067\u304d\u307e\u3059\u3002 @@ -1767,7 +1851,10 @@ message.step.4.continue=\u7d9a\u884c\u3059\u308b\u306b\u306f\u30cd\u30c3\u30c8\u message.step.4.desc=\u4eee\u60f3\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u304c\u63a5\u7d9a\u3059\u308b\u30d7\u30e9\u30a4\u30de\u30ea \u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044\u3002 message.storage.traffic=\u30db\u30b9\u30c8\u3084 CloudStack \u30b7\u30b9\u30c6\u30e0 VM \u306a\u3069\u3001\u7ba1\u7406\u30b5\u30fc\u30d0\u30fc\u3068\u901a\u4fe1\u3059\u308b CloudStack \u306e\u5185\u90e8\u30ea\u30bd\u30fc\u30b9\u9593\u306e\u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u3067\u3059\u3002\u3053\u3053\u3067\u30b9\u30c8\u30ec\u30fc\u30b8 \u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u3092\u69cb\u6210\u3057\u3066\u304f\u3060\u3055\u3044\u3002 message.suspend.project=\u3053\u306e\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u3092\u4e00\u6642\u505c\u6b62\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +message.systems.vms.ready=\u30b7\u30b9\u30c6\u30e0 VM \u306e\u6e96\u5099\u304c\u3067\u304d\u307e\u3057\u305f\u3002 +message.template.copying=\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u3092\u30b3\u30d4\u30fc\u3057\u3066\u3044\u307e\u3059\u3002 message.template.desc=VM \u306e\u8d77\u52d5\u306b\u4f7f\u7528\u3067\u304d\u308b OS \u30a4\u30e1\u30fc\u30b8 +message.tier.required=\u968e\u5c64\u306f\u5fc5\u9808\u3067\u3059 message.tooltip.dns.1=\u30be\u30fc\u30f3\u5185\u306e VM \u3067\u4f7f\u7528\u3059\u308b DNS \u30b5\u30fc\u30d0\u30fc\u306e\u540d\u524d\u3067\u3059\u3002\u30be\u30fc\u30f3\u306e\u30d1\u30d6\u30ea\u30c3\u30af IP \u30a2\u30c9\u30ec\u30b9\u304b\u3089\u3001\u3053\u306e\u30b5\u30fc\u30d0\u30fc\u306b\u901a\u4fe1\u3067\u304d\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002 message.tooltip.dns.2=\u30be\u30fc\u30f3\u5185\u306e VM \u3067\u4f7f\u7528\u3059\u308b 2 \u756a\u76ee\u306e DNS \u30b5\u30fc\u30d0\u30fc\u306e\u540d\u524d\u3067\u3059\u3002\u30be\u30fc\u30f3\u306e\u30d1\u30d6\u30ea\u30c3\u30af IP \u30a2\u30c9\u30ec\u30b9\u304b\u3089\u3001\u3053\u306e\u30b5\u30fc\u30d0\u30fc\u306b\u901a\u4fe1\u3067\u304d\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002 message.tooltip.internal.dns.1=\u30be\u30fc\u30f3\u5185\u306e CloudStack \u5185\u90e8\u30b7\u30b9\u30c6\u30e0 VM \u3067\u4f7f\u7528\u3059\u308b DNS \u30b5\u30fc\u30d0\u30fc\u306e\u540d\u524d\u3067\u3059\u3002\u30dd\u30c3\u30c9\u306e\u30d7\u30e9\u30a4\u30d9\u30fc\u30c8 IP \u30a2\u30c9\u30ec\u30b9\u304b\u3089\u3001\u3053\u306e\u30b5\u30fc\u30d0\u30fc\u306b\u901a\u4fe1\u3067\u304d\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002 @@ -1780,103 +1867,42 @@ message.tooltip.zone.name=\u30be\u30fc\u30f3\u306e\u540d\u524d\u3067\u3059\u3002 message.update.os.preference=\u3053\u306e\u30db\u30b9\u30c8\u306e OS \u57fa\u672c\u8a2d\u5b9a\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044\u3002\u540c\u69d8\u306e\u57fa\u672c\u8a2d\u5b9a\u3092\u6301\u3064\u3059\u3079\u3066\u306e\u4eee\u60f3\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u306f\u3001\u5225\u306e\u30db\u30b9\u30c8\u3092\u9078\u629e\u3059\u308b\u524d\u306b\u307e\u305a\u3053\u306e\u30db\u30b9\u30c8\u306b\u5272\u308a\u5f53\u3066\u3089\u308c\u307e\u3059\u3002 message.update.resource.count=\u3053\u306e\u30a2\u30ab\u30a6\u30f3\u30c8\u306e\u30ea\u30bd\u30fc\u30b9\u6570\u3092\u66f4\u65b0\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.update.ssl=\u5404\u30b3\u30f3\u30bd\u30fc\u30eb \u30d7\u30ed\u30ad\u30b7\u306e\u4eee\u60f3\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u3067\u66f4\u65b0\u3059\u308b\u3001X.509 \u6e96\u62e0\u306e\u65b0\u3057\u3044 SSL \u8a3c\u660e\u66f8\u3092\u9001\u4fe1\u3057\u3066\u304f\u3060\u3055\u3044\: +message.validate.accept=\u6709\u52b9\u306a\u62e1\u5f35\u5b50\u3092\u6301\u3064\u5024\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002 +message.validate.creditcard=\u30af\u30ec\u30b8\u30c3\u30c8 \u30ab\u30fc\u30c9\u756a\u53f7\u3092\u6b63\u3057\u304f\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002 +message.validate.date.ISO=\u65e5\u4ed8\u3092\u6b63\u3057\u304f\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044 (ISO)\u3002 +message.validate.date=\u65e5\u4ed8\u3092\u6b63\u3057\u304f\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002 +message.validate.digits=\u6570\u5b57\u306e\u307f\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002 +message.validate.email.address=\u30e1\u30fc\u30eb \u30a2\u30c9\u30ec\u30b9\u3092\u6b63\u3057\u304f\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002 +message.validate.equalto=\u540c\u3058\u5024\u3092\u518d\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002 +message.validate.fieldrequired=\u3053\u308c\u306f\u5fc5\u9808\u306e\u30d5\u30a3\u30fc\u30eb\u30c9\u3067\u3059\u3002 +message.validate.fixfield=\u3053\u306e\u30d5\u30a3\u30fc\u30eb\u30c9\u3092\u4fee\u6b63\u3057\u3066\u304f\u3060\u3055\u3044\u3002 message.validate.instance.name=\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u540d\u306f 63 \u6587\u5b57\u4ee5\u5185\u3067\u6307\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044\u3002ASCII \u6587\u5b57\u306e a\uff5ez\u3001A\uff5eZ\u3001\u6570\u5b57\u306e 0\uff5e9\u3001\u304a\u3088\u3073\u30cf\u30a4\u30d5\u30f3\u306e\u307f\u3092\u4f7f\u7528\u3067\u304d\u307e\u3059\u3002\u6587\u5b57\u3067\u59cb\u307e\u308a\u3001\u6587\u5b57\u307e\u305f\u306f\u6570\u5b57\u3067\u7d42\u308f\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002 +message.validate.invalid.characters=\u7121\u52b9\u306a\u6587\u5b57\u304c\u898b\u3064\u304b\u308a\u307e\u3057\u305f\u3002\u4fee\u6574\u3057\u3066\u304f\u3060\u3055\u3044\u3002 +message.validate.max={0} \u4ee5\u4e0b\u306e\u5024\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002 +message.validate.maxlength={0} \u6587\u5b57\u4ee5\u4e0b\u3067\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002 +message.validate.minlength={0} \u6587\u5b57\u4ee5\u4e0a\u3067\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002 +message.validate.number=\u6570\u5024\u3092\u6b63\u3057\u304f\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002 +message.validate.range={0} \uff5e {1} \u306e\u5024\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002 +message.validate.range.length={0} \uff5e {1} \u6587\u5b57\u3067\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002 +message.validate.URL=URL \u3092\u6b63\u3057\u304f\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002 message.virtual.network.desc=\u30a2\u30ab\u30a6\u30f3\u30c8\u306e\u5c02\u7528\u4eee\u60f3\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3067\u3059\u3002\u30d6\u30ed\u30fc\u30c9\u30ad\u30e3\u30b9\u30c8 \u30c9\u30e1\u30a4\u30f3\u306f VLAN \u5185\u306b\u914d\u7f6e\u3055\u308c\u3001\u30d1\u30d6\u30ea\u30c3\u30af \u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3078\u306e\u30a2\u30af\u30bb\u30b9\u306f\u3059\u3079\u3066\u4eee\u60f3\u30eb\u30fc\u30bf\u30fc\u306b\u3088\u3063\u3066\u30eb\u30fc\u30c6\u30a3\u30f3\u30b0\u3055\u308c\u307e\u3059\u3002 message.vm.create.template.confirm=\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u3092\u4f5c\u6210\u3059\u308b\u3068 VM \u304c\u81ea\u52d5\u7684\u306b\u518d\u8d77\u52d5\u3055\u308c\u307e\u3059\u3002 message.vm.review.launch=\u6b21\u306e\u60c5\u5831\u3092\u53c2\u7167\u3057\u3066\u3001\u4eee\u60f3\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u3092\u6b63\u3057\u304f\u8a2d\u5b9a\u3057\u305f\u3053\u3068\u3092\u78ba\u8a8d\u3057\u3066\u304b\u3089\u8d77\u52d5\u3057\u3066\u304f\u3060\u3055\u3044\u3002 +message.vnmc.available.list=\u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u4e00\u89a7\u3067 VNMC \u3092\u5229\u7528\u3067\u304d\u307e\u305b\u3093\u3002 +message.vnmc.not.available.list=\u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u4e00\u89a7\u3067 VNMC \u3092\u5229\u7528\u3067\u304d\u307e\u305b\u3093\u3002 message.volume.create.template.confirm=\u3053\u306e\u30c7\u30a3\u30b9\u30af \u30dc\u30ea\u30e5\u30fc\u30e0\u306e\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u3092\u4f5c\u6210\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? \u30dc\u30ea\u30e5\u30fc\u30e0 \u30b5\u30a4\u30ba\u306b\u3088\u3063\u3066\u306f\u3001\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u306e\u4f5c\u6210\u306b\u306f\u6570\u5206\u4ee5\u4e0a\u304b\u304b\u308b\u53ef\u80fd\u6027\u304c\u3042\u308a\u307e\u3059\u3002 +message.waiting.for.builtin.templates.to.load=\u7d44\u307f\u8fbc\u307f\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u306e\u30ed\u30fc\u30c9\u3092\u5f85\u6a5f\u3057\u3066\u3044\u307e\u3059... +message.XSTools61plus.update.failed=XenServer Tools Version 6.1 \u4ee5\u964d\u3078\u306e\u66f4\u65b0\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002\u30a8\u30e9\u30fc\: message.you.must.have.at.least.one.physical.network=\u5c11\u306a\u304f\u3068\u3082 1 \u3064\u7269\u7406\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u304c\u5fc5\u8981\u3067\u3059 -message.zone.creation.complete.would.you.like.to.enable.this.zone=\u30be\u30fc\u30f3\u304c\u4f5c\u6210\u3055\u308c\u307e\u3057\u305f\u3002\u3053\u306e\u30be\u30fc\u30f3\u3092\u6709\u52b9\u306b\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +message.your.cloudstack.is.ready=CloudStack \u306e\u6e96\u5099\u304c\u3067\u304d\u307e\u3057\u305f\! message.Zone.creation.complete=\u30be\u30fc\u30f3\u304c\u4f5c\u6210\u3055\u308c\u307e\u3057\u305f +message.zone.creation.complete.would.you.like.to.enable.this.zone=\u30be\u30fc\u30f3\u304c\u4f5c\u6210\u3055\u308c\u307e\u3057\u305f\u3002\u3053\u306e\u30be\u30fc\u30f3\u3092\u6709\u52b9\u306b\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.zone.no.network.selection=\u9078\u629e\u3057\u305f\u30be\u30fc\u30f3\u3067\u306f\u3001\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3092\u9078\u629e\u3067\u304d\u307e\u305b\u3093\u3002 message.zone.step.1.desc=\u30be\u30fc\u30f3\u306e\u30cd\u30c3\u30c8\u30ef\u30fc\u30af \u30e2\u30c7\u30eb\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044\u3002 message.zone.step.2.desc=\u65b0\u3057\u3044\u30be\u30fc\u30f3\u3092\u8ffd\u52a0\u3059\u308b\u305f\u3081\u306b\u3001\u6b21\u306e\u60c5\u5831\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002 message.zone.step.3.desc=\u65b0\u3057\u3044\u30dd\u30c3\u30c9\u3092\u8ffd\u52a0\u3059\u308b\u305f\u3081\u306b\u3001\u6b21\u306e\u60c5\u5831\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002 -message.zoneWizard.enable.local.storage=\u8b66\u544a\: \u3053\u306e\u30be\u30fc\u30f3\u306e\u30ed\u30fc\u30ab\u30eb \u30b9\u30c8\u30ec\u30fc\u30b8\u3092\u6709\u52b9\u306b\u3059\u308b\u5834\u5408\u306f\u3001\u30b7\u30b9\u30c6\u30e0 VM \u306e\u8d77\u52d5\u5834\u6240\u306b\u5fdc\u3058\u3066\u6b21\u306e\u64cd\u4f5c\u304c\u5fc5\u8981\u3067\u3059\u3002

1. \u30b7\u30b9\u30c6\u30e0 VM \u3092\u30d7\u30e9\u30a4\u30de\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8\u3067\u8d77\u52d5\u3059\u308b\u5fc5\u8981\u304c\u3042\u308b\u5834\u5408\u306f\u3001\u30d7\u30e9\u30a4\u30de\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8\u3092\u4f5c\u6210\u3057\u305f\u5f8c\u3067\u30be\u30fc\u30f3\u306b\u8ffd\u52a0\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002\u30be\u30fc\u30f3\u3092\u7121\u52b9\u72b6\u614b\u304b\u3089\u958b\u59cb\u3059\u308b\u5fc5\u8981\u3082\u3042\u308a\u307e\u3059\u3002

2. \u30b7\u30b9\u30c6\u30e0 VM \u3092\u30ed\u30fc\u30ab\u30eb \u30b9\u30c8\u30ec\u30fc\u30b8\u3067\u8d77\u52d5\u3059\u308b\u5fc5\u8981\u304c\u3042\u308b\u5834\u5408\u306f\u3001\u30be\u30fc\u30f3\u3092\u6709\u52b9\u306b\u3059\u308b\u524d\u306b system.vm.use.local.storage \u3092 true \u306b\u8a2d\u5b9a\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002


\u7d9a\u884c\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? -message.validate.fieldrequired=\u3053\u308c\u306f\u5fc5\u9808\u306e\u30d5\u30a3\u30fc\u30eb\u30c9\u3067\u3059\u3002 -message.validate.fixfield=\u3053\u306e\u30d5\u30a3\u30fc\u30eb\u30c9\u3092\u4fee\u6b63\u3057\u3066\u304f\u3060\u3055\u3044\u3002 -message.validate.email.address=\u30e1\u30fc\u30eb \u30a2\u30c9\u30ec\u30b9\u3092\u6b63\u3057\u304f\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002 -message.validate.URL=URL \u3092\u6b63\u3057\u304f\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002 -message.validate.date=\u65e5\u4ed8\u3092\u6b63\u3057\u304f\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002 -message.validate.date.ISO=\u65e5\u4ed8\u3092\u6b63\u3057\u304f\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044 (ISO)\u3002 -message.validate.number=\u6570\u5024\u3092\u6b63\u3057\u304f\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002 -message.validate.digits=\u6570\u5b57\u306e\u307f\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002 -message.validate.creditcard=\u30af\u30ec\u30b8\u30c3\u30c8 \u30ab\u30fc\u30c9\u756a\u53f7\u3092\u6b63\u3057\u304f\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002 -message.validate.equalto=\u540c\u3058\u5024\u3092\u518d\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002 -message.validate.accept=\u6709\u52b9\u306a\u62e1\u5f35\u5b50\u3092\u6301\u3064\u5024\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002 -message.validate.maxlength={0} \u6587\u5b57\u4ee5\u4e0b\u3067\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002 -message.validate.minlength={0} \u6587\u5b57\u4ee5\u4e0a\u3067\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002 -message.validate.range.length={0} \uff5e {1} \u6587\u5b57\u3067\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002 -message.validate.range={0} \uff5e {1} \u306e\u5024\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002 -message.validate.max={0} \u4ee5\u4e0b\u306e\u5024\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002 +message.zoneWizard.enable.local.storage=\u8b66\u544a\: \u3053\u306e\u30be\u30fc\u30f3\u3067\u30ed\u30fc\u30ab\u30eb\u30b9\u30c8\u30ec\u30fc\u30b8\u3092\u6709\u52b9\u5316\u3059\u308b\u3068\u3069\u3053\u306b\u30b7\u30b9\u30c6\u30e0 VM \u3092\u8d77\u52d5\u3059\u308b\u304b\u306b\u3088\u3063\u3066\u4ee5\u4e0b\u3092\u5b9f\u65bd\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\:

1. \u5171\u6709\u30d7\u30e9\u30a4\u30de\u30ea\u30b9\u30c8\u30ec\u30fc\u30b8\u3067\u30b7\u30b9\u30c6\u30e0 VM \u3092\u8d77\u52d5\u3055\u305b\u308b\u5834\u5408\u3001\u5171\u6709\u30d7\u30e9\u30a4\u30de\u30ea\u30b9\u30c8\u30ec\u30fc\u30b8\u3092\u4f5c\u6210\u3057\u305f\u5f8c\u30be\u30fc\u30f3\u306b\u8ffd\u52a0\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002\u307e\u305f\u3001\u7121\u52b9\u72b6\u614b\u306e\u30be\u30fc\u30f3\u3092\u8d77\u52d5\u3055\u305b\u306a\u3051\u308c\u3070\u306a\u308a\u307e\u305b\u3093\u3002

2. \u30ed\u30fc\u30ab\u30eb\u30d7\u30e9\u30a4\u30de\u30ea\u30b9\u30c8\u30ec\u30fc\u30b8\u3067\u30b7\u30b9\u30c6\u30e0 VM \u3092\u8d77\u52d5\u3055\u305b\u308b\u5834\u5408\u3001\u30be\u30fc\u30f3\u3092\u6709\u52b9\u5316\u3055\u305b\u308b\u524d\u306b system.vm.use.local.storage \u3092 true \u306b\u8a2d\u5b9a\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002


\u3053\u306e\u307e\u307e\u7d9a\u3051\u307e\u3059\u304b? messgae.validate.min={0} \u4ee5\u4e0a\u306e\u5024\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002 -message.creating.systemVM=\u30b7\u30b9\u30c6\u30e0 VM \u3092\u4f5c\u6210\u3057\u3066\u3044\u307e\u3059 (\u3057\u3070\u3089\u304f\u304a\u5f85\u3061\u304f\u3060\u3055\u3044) -message.enabling.zone.dots=\u30be\u30fc\u30f3\u3092\u6709\u52b9\u306b\u3057\u3066\u3044\u307e\u3059... -message.restoreVM=VM \u3092\u5fa9\u5143\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? -message.no.host.available=\u79fb\u884c\u306b\u4f7f\u7528\u3067\u304d\u308b\u30db\u30b9\u30c8\u306f\u3042\u308a\u307e\u305b\u3093 -message.network.addVM.desc=\u3053\u306e VM \u3092\u8ffd\u52a0\u3059\u308b\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3092\u6307\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044\u3002\u3053\u306e\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306e\u305f\u3081\u306e\u65b0\u3057\u3044 NIC \u304c\u8ffd\u52a0\u3055\u308c\u307e\u3059\u3002 -message.network.addVMNIC=\u3053\u306e\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306e\u65b0\u3057\u3044 VM NIC \u3092\u8ffd\u52a0\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? -message.set.default.NIC=\u3053\u306e NIC \u3092\u3053\u306e VM \u306e\u30c7\u30d5\u30a9\u30eb\u30c8\u306b\u8a2d\u5b9a\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? -message.set.default.NIC.manual=\u4eca\u3059\u3050\u306b\u3053\u306e VM \u306e\u30c7\u30d5\u30a9\u30eb\u30c8 NIC \u3092\u624b\u52d5\u3067\u66f4\u65b0\u3057\u3066\u304f\u3060\u3055\u3044\u3002 -message.instance.scaled.up.confirm=\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u306e\u30b5\u30a4\u30ba\u3092\u62e1\u5927\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? -message.copy.template.confirm=\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u3092\u30b3\u30d4\u30fc\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? -message.template.copying=\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u3092\u30b3\u30d4\u30fc\u3057\u3066\u3044\u307e\u3059\u3002 -message.XSTools61plus.update.failed=XenServer Tools Version 6.1 \u4ee5\u964d\u3078\u306e\u66f4\u65b0\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002\u30a8\u30e9\u30fc\: -message.gslb.delete.confirm=\u3053\u306e GSLB \u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? -message.portable.ip.delete.confirm=\u3053\u306e\u30dd\u30fc\u30bf\u30d6\u30eb IP \u30a2\u30c9\u30ec\u30b9\u306e\u7bc4\u56f2\u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? -message.gslb.lb.remove.confirm=GSLB \u304b\u3089\u8ca0\u8377\u5206\u6563\u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? -message.admin.guide.read=VMware \u30d9\u30fc\u30b9\u306e VM \u306b\u3064\u3044\u3066\u306f\u3001\u30b5\u30a4\u30ba\u5909\u66f4\u306e\u524d\u306b\u7ba1\u7406\u8005\u30ac\u30a4\u30c9\u306e\u52d5\u7684\u306a\u30b5\u30a4\u30ba\u5909\u66f4\u306e\u30bb\u30af\u30b7\u30e7\u30f3\u3092\u304a\u8aad\u307f\u304f\u3060\u3055\u3044\u3002\u7d9a\u884c\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b?\, -message.tier.required=\u968e\u5c64\u306f\u5fc5\u9808\u3067\u3059 -message.remove.ldap=LDAP \u69cb\u6210\u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? -message.action.downloading.template=\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u3092\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3057\u3066\u3044\u307e\u3059\u3002 -message.configure.ldap=LDAP \u3092\u69cb\u6210\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? -message.confirm.delete.ciscovnmc.resource=Cisco VNMC \u30ea\u30bd\u30fc\u30b9\u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? -message.confirm.add.vnmc.provider=VNMC \u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u3092\u8ffd\u52a0\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? -message.confirm.enable.vnmc.provider=VNMC \u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u3092\u6709\u52b9\u306b\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? -message.confirm.disable.vnmc.provider=VNMC \u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u3092\u7121\u52b9\u306b\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? -message.vnmc.available.list=\u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u4e00\u89a7\u3067 VNMC \u3092\u5229\u7528\u3067\u304d\u307e\u305b\u3093\u3002 -message.vnmc.not.available.list=\u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u4e00\u89a7\u3067 VNMC \u3092\u5229\u7528\u3067\u304d\u307e\u305b\u3093\u3002 -message.confirm.release.dedicate.vlan.range=\u5c02\u7528 VLAN \u306e\u7bc4\u56f2\u3092\u89e3\u653e\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? -message.confirm.start.lb.vm=LB VM \u3092\u8d77\u52d5\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? -message.confirm.stop.lb.vm=LB VM \u3092\u505c\u6b62\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? -message.confirm.remove.vmware.datacenter=VMware \u30c7\u30fc\u30bf\u30bb\u30f3\u30bf\u30fc\u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? -message.confirm.dedicate.zone=\u3053\u306e\u30be\u30fc\u30f3\u3092\u30c9\u30e1\u30a4\u30f3/\u30a2\u30ab\u30a6\u30f3\u30c8\u5c02\u7528\u306b\u8a2d\u5b9a\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? -message.confirm.release.dedicated.zone=\u3053\u306e\u5c02\u7528\u30be\u30fc\u30f3\u3092\u89e3\u653e\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? -message.dedicated.zone.released=\u5c02\u7528\u30be\u30fc\u30f3\u304c\u89e3\u653e\u3055\u308c\u307e\u3057\u305f -message.read.admin.guide.scaling.up=\u30b5\u30a4\u30ba\u3092\u62e1\u5927\u3059\u308b\u524d\u306b\u7ba1\u7406\u8005\u30ac\u30a4\u30c9\u306e\u52d5\u7684\u306a\u30b5\u30a4\u30ba\u5909\u66f4\u306e\u30bb\u30af\u30b7\u30e7\u30f3\u3092\u304a\u8aad\u307f\u304f\u3060\u3055\u3044\u3002 -message.confirm.scale.up.system.vm=\u30b7\u30b9\u30c6\u30e0 VM \u306e\u30b5\u30a4\u30ba\u3092\u62e1\u5927\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? -message.confirm.upgrade.router.newer.template=\u30eb\u30fc\u30bf\u30fc\u3092\u30a2\u30c3\u30d7\u30b0\u30ec\u30fc\u30c9\u3057\u3066\u65b0\u3057\u3044\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u3092\u4f7f\u7528\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? -message.confirm.scale.up.router.vm=\u30eb\u30fc\u30bf\u30fc VM \u306e\u30b5\u30a4\u30ba\u3092\u62e1\u5927\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? -message.confirm.upgrade.routers.newtemplate=\u3053\u306e\u30be\u30fc\u30f3\u306e\u3059\u3079\u3066\u306e\u30eb\u30fc\u30bf\u30fc\u3092\u30a2\u30c3\u30d7\u30b0\u30ec\u30fc\u30c9\u3057\u3066\u65b0\u3057\u3044\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u3092\u4f7f\u7528\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? -message.confirm.upgrade.routers.pod.newtemplate=\u3053\u306e\u30dd\u30c3\u30c9\u306e\u3059\u3079\u3066\u306e\u30eb\u30fc\u30bf\u30fc\u3092\u30a2\u30c3\u30d7\u30b0\u30ec\u30fc\u30c9\u3057\u3066\u65b0\u3057\u3044\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u3092\u4f7f\u7528\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? -message.confirm.upgrade.routers.cluster.newtemplate=\u3053\u306e\u30af\u30e9\u30b9\u30bf\u30fc\u306e\u3059\u3079\u3066\u306e\u30eb\u30fc\u30bf\u30fc\u3092\u30a2\u30c3\u30d7\u30b0\u30ec\u30fc\u30c9\u3057\u3066\u65b0\u3057\u3044\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u3092\u4f7f\u7528\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? -message.confirm.upgrade.routers.account.newtemplate=\u3053\u306e\u30a2\u30ab\u30a6\u30f3\u30c8\u306e\u3059\u3079\u3066\u306e\u30eb\u30fc\u30bf\u30fc\u3092\u30a2\u30c3\u30d7\u30b0\u30ec\u30fc\u30c9\u3057\u3066\u65b0\u3057\u3044\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u3092\u4f7f\u7528\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? -message.confirm.dedicate.pod.domain.account=\u3053\u306e\u30dd\u30c3\u30c9\u3092\u30c9\u30e1\u30a4\u30f3/\u30a2\u30ab\u30a6\u30f3\u30c8\u5c02\u7528\u306b\u8a2d\u5b9a\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? -message.confirm.release.dedicated.pod=\u3053\u306e\u5c02\u7528\u30dd\u30c3\u30c9\u3092\u89e3\u653e\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? -message.pod.dedication.released=\u5c02\u7528\u30dd\u30c3\u30c9\u304c\u89e3\u653e\u3055\u308c\u307e\u3057\u305f -message.confirm.dedicate.cluster.domain.account=\u3053\u306e\u30af\u30e9\u30b9\u30bf\u30fc\u3092\u30c9\u30e1\u30a4\u30f3/\u30a2\u30ab\u30a6\u30f3\u30c8\u5c02\u7528\u306b\u8a2d\u5b9a\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? -message.cluster.dedicated=\u30af\u30e9\u30b9\u30bf\u30fc\u3092\u5c02\u7528\u306b\u8a2d\u5b9a\u3057\u307e\u3057\u305f -message.confirm.release.dedicated.cluster=\u3053\u306e\u5c02\u7528\u30af\u30e9\u30b9\u30bf\u30fc\u3092\u89e3\u653e\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? -message.cluster.dedication.released=\u5c02\u7528\u30af\u30e9\u30b9\u30bf\u30fc\u304c\u89e3\u653e\u3055\u308c\u307e\u3057\u305f -message.confirm.dedicate.host.domain.account=\u3053\u306e\u30db\u30b9\u30c8\u3092\u30c9\u30e1\u30a4\u30f3/\u30a2\u30ab\u30a6\u30f3\u30c8\u5c02\u7528\u306b\u8a2d\u5b9a\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? -message.host.dedicated=\u30db\u30b9\u30c8\u3092\u5c02\u7528\u306b\u8a2d\u5b9a\u3057\u307e\u3057\u305f -message.confirm.release.dedicated.host=\u3053\u306e\u5c02\u7528\u30db\u30b9\u30c8\u3092\u89e3\u653e\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? -message.host.dedication.released=\u5c02\u7528\u30db\u30b9\u30c8\u304c\u89e3\u653e\u3055\u308c\u307e\u3057\u305f -message.confirm.delete.ucs.manager=UCS Manager \u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? -message.confirm.refresh.blades=\u30d6\u30ec\u30fc\u30c9\u3092\u66f4\u65b0\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? -message.confirm.delete.secondary.staging.store=\u30bb\u30ab\u30f3\u30c0\u30ea \u30b9\u30c6\u30fc\u30b8\u30f3\u30b0 \u30b9\u30c8\u30a2\u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? -message.select.tier=\u968e\u5c64\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044\u3002 -message.disallowed.characters=\u8a31\u53ef\u3055\u308c\u306a\u3044\u6587\u5b57: \<\,\> -message.waiting.for.builtin.templates.to.load=\u7d44\u307f\u8fbc\u307f\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u306e\u30ed\u30fc\u30c9\u3092\u5f85\u6a5f\u3057\u3066\u3044\u307e\u3059... -message.systems.vms.ready=\u30b7\u30b9\u30c6\u30e0 VM \u306e\u6e96\u5099\u304c\u3067\u304d\u307e\u3057\u305f\u3002 -message.your.cloudstack.is.ready=CloudStack \u306e\u6e96\u5099\u304c\u3067\u304d\u307e\u3057\u305f\! -message.specifiy.tag.key.value=\u30bf\u30b0 \u30ad\u30fc\u304a\u3088\u3073\u5024\u3092\u6307\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044 -message.enter.seperated.list.multiple.cidrs=CIDR \u304c\u8907\u6570\u3042\u308b\u5834\u5408\u306f\u3001\u30b3\u30f3\u30de\u533a\u5207\u308a\u306e\u4e00\u89a7\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044 -message.disabling.network.offering=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0\u3092\u7121\u52b9\u306b\u3057\u3066\u3044\u307e\u3059 -message.confirm.enable.network.offering=\u3053\u306e\u30cd\u30c3\u30c8\u30ef\u30fc\u30af \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0\u3092\u6709\u52b9\u306b\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? -message.enabling.network.offering=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0\u3092\u6709\u52b9\u306b\u3057\u3066\u3044\u307e\u3059 -message.confirm.remove.network.offering=\u3053\u306e\u30cd\u30c3\u30c8\u30ef\u30fc\u30af \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0\u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? -message.confirm.disable.network.offering=\u3053\u306e\u30cd\u30c3\u30c8\u30ef\u30fc\u30af \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0\u3092\u7121\u52b9\u306b\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? mode=\u30e2\u30fc\u30c9 network.rate=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u901f\u5ea6 notification.reboot.instance=\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u306e\u518d\u8d77\u52d5 @@ -1894,14 +1920,14 @@ state.Creating=\u4f5c\u6210\u4e2d state.Declined=\u8f9e\u9000 state.Destroyed=\u7834\u68c4\u6e08\u307f state.Disabled=\u7121\u52b9 -state.Enabled=\u6709\u52b9 state.enabled=\u6709\u52b9 +state.Enabled=\u6709\u52b9 state.Error=\u30a8\u30e9\u30fc state.Expunging=\u62b9\u6d88\u4e2d state.Migrating=\u79fb\u884c\u4e2d state.Pending=\u4fdd\u7559 -state.Ready=\u6e96\u5099\u5b8c\u4e86 state.ready=\u6e96\u5099\u5b8c\u4e86 +state.Ready=\u6e96\u5099\u5b8c\u4e86 state.Running=\u5b9f\u884c\u4e2d state.Starting=\u958b\u59cb\u4e2d state.Stopped=\u505c\u6b62\u6e08\u307f diff --git a/client/WEB-INF/classes/resources/messages_ko_KR.properties b/client/WEB-INF/classes/resources/messages_ko_KR.properties index b755072d61..ce79d2e5b2 100644 --- a/client/WEB-INF/classes/resources/messages_ko_KR.properties +++ b/client/WEB-INF/classes/resources/messages_ko_KR.properties @@ -16,6 +16,7 @@ # under the License. changed.item.properties=\ud56d\ubaa9 \uc18d\uc131 \ubcc0\uacbd +confirm.enable.s3=S3 \uae30\ubc18 2\ucc28 \uc800\uc7a5\uc18c \uc9c0\uc6d0\uc744 \ud558\ub824\uba74 \uc544\ub798 \uc815\ubcf4\ub97c \uc785\ub825\ud574 \uc8fc\uc2ed\uc2dc\uc624. confirm.enable.swift=Swift \uae30\uc220 \uc9c0\uc6d0\ub97c \uc0ac\uc6a9 \ud558\ub824\uba74 \ub2e4\uc74c \uc815\ubcf4\ub97c \uc785\ub825\ud574 \uc8fc\uc2ed\uc2dc\uc624. error.could.not.enable.zone=Zone\uc744 \uc0ac\uc6a9 \ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4. error.installWizard.message=\ubb38\uc81c\uac00 \ubc1c\uc0dd\ud588\uc2b5\ub2c8\ub2e4. \ub2e4\uc2dc \uc624\ub958\ub97c \uc218\uc815\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4. @@ -28,6 +29,7 @@ error.please.specify.physical.network.tags=\ud604\uc7ac \ubb3c\ub9ac \ub124\ud2b error.session.expired=\uc138\uc158 \uc720\ud6a8\uae30\uac04\uc774 \ub04a\uc5b4\uc84c\uc2b5\ub2c8\ub2e4. error.something.went.wrong.please.correct.the.following=\ubb38\uc81c\uac00 \ubc1c\uc0dd\ud588\uc2b5\ub2c8\ub2e4. \ub2e4\uc74c \ub0b4\uc6a9\uc744 \uc218\uc815\ud574 \uc8fc\uc2ed\uc2dc\uc624 error.unable.to.reach.management.server=\uad00\ub9ac \uc11c\ubc84\uc640 \ud1b5\uc2e0\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4. +error.unresolved.internet.name=\uc778\ud130\ub137 \uc8fc\uc18c\ub97c \uc54c\uc218 \uc5c6\uc2b5\ub2c8\ub2e4. extractable=\ucd94\ucd9c \uac00\ub2a5 force.delete.domain.warning=\uacbd\uace0\:\uc774 \uc635\uc158\uc744 \uc120\ud0dd\ud558\uba74, \ubaa8\ub4e0 \ub0b4\ubd80 \ub3c4\uba54\uc778 \ubc0f \uad00\ub828\ud558\ub294 \ubaa8\ub4e0 \uacc4\uc815 \uc815\ubcf4\uc640 \uadf8 \uc790\uc6d0\uc774 \uc0ad\uc81c\ub429\ub2c8\ub2e4. force.delete=\uac15\uc81c \uc0ad\uc81c @@ -40,6 +42,8 @@ ICMP.type=ICMP \uc885\ub958 image.directory=\uc774\ubbf8\uc9c0 \ub514\ub809\ud1a0\ub9ac inline=\uc9c1\ub82c instances.actions.reboot.label=\uc778\uc2a4\ud134\uc2a4 \uc7ac\uc2dc\uc791 +label.about.app=CloudStack \uc18c\uac1c +label.about=\uc18c\uac1c label.accept.project.invitation=\ud504\ub85c\uc81d\ud2b8 \ucd08\ub300 \uc2b9\uc778 label.account.and.security.group=\uacc4\uc815 \uc815\ubcf4, \ubcf4\uc548 \uadf8\ub8f9 label.account.id=\uacc4\uc815 \uc815\ubcf4 ID @@ -227,6 +231,9 @@ label.action.update.OS.preference=OS \uae30\ubcf8 \uc124\uc815 \uc5c5\ub370\uc77 label.action.update.OS.preference.processing=OS \uae30\ubcf8 \uc124\uc815\uc744 \uc5c5\ub370\uc774\ud2b8\ud558\ub294 \uc911... label.action.update.resource.count.processing=\uc790\uc6d0 \uc218\ub97c \uc5c5\ub370\uc774\ud2b8\ud558\ub294 \uc911... label.action.update.resource.count=\uc790\uc6d0 \uc218 \uc5c5\ub370\uc774\ud2b8 +label.action.vmsnapshot.create=VM \uc2a4 +label.action.vmsnapshot.delete=VM +label.action.vmsnapshot.revert=VM \uc2a4\ub0c5\uc0f7 label.activate.project=\ud504\ub85c\uc81d\ud2b8 \ud65c\uc131\ud654 label.active.sessions=\ud65c\uc131 \uc138\uc158 label.add.accounts.to=\uacc4\uc815 \uc815\ubcf4 \ucd94\uac00\: @@ -234,6 +241,7 @@ label.add.accounts=\uacc4\uc815 \uc815\ubcf4 \ucd94\uac00 label.add.account.to.project=\uacc4\uc815 \uc815\ubcf4 \ud504\ub85c\uc81d\ud2b8\uc5d0 \ucd94\uac00 label.add.account=\uacc4\uc815 \uc815\ubcf4 \ucd94\uac00 label.add.ACL=\uad8c\ud55c \uad00\ub9ac(ACL) \ucd94\uac00 +label.add.BigSwitchVns.device=BigSwitch Vns \ucf58\ud2b8\ub864\ub7ec label.add.by.cidr=CIDR \ub85c \ucd94\uac00 label.add.by.group=\uadf8\ub8f9\uc5d0\uc11c \ucd94\uac00 label.add.by=\ucd94\uac00 \ub2e8\uc704 @@ -270,10 +278,12 @@ label.add.new.gateway=\uc0c8 \uac8c\uc774\ud2b8\uc6e8\uc774 \ucd94\uac00\ud558\u label.add.new.NetScaler=\uc0c8\ub85c\uc6b4 NetScaler \ucd94\uac00 label.add.new.SRX=\uc0c8\ub85c\uc6b4 SRX \ucd94\uac00 label.add.new.tier=\uc0c8 \uacc4\uce35 \ucd94\uac00 +label.add.NiciraNvp.device=Nvp \ucf58\ud2b8\ub864\ub7ec label.add.physical.network=\ubb3c\ub9ac \ub124\ud2b8\uc6cc\ud06c \ucd94\uac00 label.add.pod=Pod \ucd94\uac00 label.add.port.forwarding.rule=\ud3ec\ud1a0 \uc804\uc1a1 \uaddc\uce59\uc758 \ucd94\uac00 label.add.primary.storage=\uae30\ubcf8 \uc2a4\ud1a0\ub9ac\uc9c0 \ucd94\uac00 +label.add.region=\uc9c0\uc5ed label.add.resources=\uc790\uc6d0 \ucd94\uac00 label.add.route=\ub77c\uc6b0\ud2b8 \ucd94\uac00 label.add.rule=\uaddc\uce59 \ucd94\uac00 @@ -289,7 +299,6 @@ label.add.to.group=\uadf8\ub8f9\uc5d0 \ucd94\uac00 label.add=\ucd94\uac00 label.add.user=\uc0ac\uc6a9\uc790 \ucd94\uac00 label.add.vlan=VLAN \ucd94\uac00 -label.add.vxlan=VXLAN \ucd94\uac00 label.add.vms.to.lb=\ub124\ud2b8\uc6cc\ud06c \ub85c\ub4dc \uacf5\uc720 \uaddc\uce59\uc5d0 VM \ucd94\uac00 label.add.vms=VM \ucd94\uac00 label.add.VM.to.tier=\uacc4\uce35\uc5d0 VM \ucd94\uac00 @@ -299,6 +308,7 @@ label.add.vpc=VPC \ucd94\uac00 label.add.vpn.customer.gateway=VPN \uace0\uac1d \uac8c\uc774\ud2b8\uc6e8\uc774 \ucd94\uac00 label.add.VPN.gateway=VPN \uac8c\uc774\ud2b8\uc6e8\uc774 \ucd94\uac00 label.add.vpn.user=VPN \uc0ac\uc6a9\uc790 \ucd94\uac00 +label.add.vxlan=VXLAN \ucd94\uac00 label.add.zone=Zone \ucd94\uac00 label.admin.accounts=\uad00\ub9ac\uc790 \uacc4\uc815 \uc815\ubcf4 label.admin=\uad00\ub9ac\uc790 @@ -314,11 +324,15 @@ label.allocated=\ud560\ub2f9 \uc644\ub8cc \uc0c1\ud0dc label.allocation.state=\ud560\ub2f9 \uc0c1\ud0dc label.api.key=API \ud0a4 label.apply=\uc801\uc6a9 +label.app.name=CloudStack +label.archive.alerts=\uc54c\ub9bc +label.archive.events=\uc774\ubca4\ud2b8 label.assign.to.load.balancer=\ub124\ud2b8\uc6cc\ud06c \ub85c\ub4dc \uacf5\uc720 \uc7a5\uce58\uc5d0 \uc778\uc2a4\ud134\uc2a4\ub97c \ud560\ub2f9 label.assign=\ud560\ub2f9 label.associated.network.id=\uad00\ub828 \ub124\ud2b8\uc6cc\ud06c ID label.associated.network=\uad00\ub828 \ub124\ud2b8\uc6cc\ud06c label.attached.iso=\uc5f0\uacb0 ISO +label.author.email=\uc81c\uc791\uc790 label.availability=\uac00\uc6a9\uc131 label.availability.zone=\uc774\uc6a9 \uac00\ub2a5 Zone label.available.public.ips=\uc0ac\uc6a9 \uac00\ub2a5 \uacf5\uac1c IP \uc8fc\uc18c @@ -331,9 +345,13 @@ label.bootable=\ubd80\ud305 \uac00\ub2a5 label.broadcast.domain.range=\ube0c\ub85c\ub4dc\uce90\uc2a4\ud2b8 \ub3c4\uba54\uc778 \ubc94\uc704 label.broadcast.domain.type=\ube0c\ub85c\ub4dc\uce90\uc2a4\ud2b8 \ub3c4\uba54\uc778 \uc885\ub958 label.by.account=\uacc4\uc815 \uc815\ubcf4 +label.by.alert.type=\uc54c\ub9bc label.by.availability=\uac00\uc6a9\uc131 +label.by.date.end=\ub0a0\uc9dc(\uc885\ub8cc\uc77c) +label.by.date.start=\ub0a0\uc9dc(\uc2dc\uc791\uc77c) label.by.domain=\ub3c4\uba54\uc778 label.by.end.date=\uc885\ub8cc\uc77c +label.by.event.type=\uc774\ubca4\ud2b8 label.by.level=\ub808\ubca8 label.by.pod=Pod label.by.role=\uc5ed\ud560 @@ -408,6 +426,8 @@ label.dedicated=\uc804\uc6a9 label.default=\uae30\ubcf8 label.default.use=\uae30\ubcf8 \uc0ac\uc6a9 label.default.view=\uae30\ubcf8 \ubcf4\uae30 +label.delete.alerts=\uc54c\ub9bc +label.delete.events=\uc774\ubca4\ud2b8 label.delete.F5=F5 \uc0ad\uc81c label.delete.gateway=\uac8c\uc774\ud2b8\uc6e8\uc774 \uc0ad\uc81c label.delete.NetScaler=NetScaler \uc0ad\uc81c @@ -465,6 +485,7 @@ label.edit.tags=\ud0dc\uadf8 \ud3b8\uc9d1 label.edit.traffic.type=\ud2b8\ub798\ud53d \uc885\ub958 \ud3b8\uc9d1 label.edit=\ud3b8\uc9d1 label.edit.vpc=VPC \ud3b8\uc9d1 +label.egress.default.policy=Egress \uae30\ubcf8 label.egress.rule=\uc804\uc1a1 \uaddc\uce59 label.elastic.IP=\ud0c4\ub825\uc801 IP \uc8fc\uc18c label.elastic.LB=\ud0c4\ub825\uc801 \ub124\ud2b8\uc6cc\ud06c \ub85c\ub4dc \uacf5\uc720 @@ -504,6 +525,7 @@ label.full=\uc804\uccb4 label.gateway=\uac8c\uc774\ud2b8\uc6e8\uc774 label.general.alerts=\uc77c\ubc18 \uc54c\ub9bc \uccb4\uc81c label.generating.url=URL\ub97c \uc0dd\uc131\ud558\uace0 \uc788\uc74c +label.gluster.volume=\ubcfc\ub968 label.go.step.2=\ub2e8\uacc4 2\uc73c\ub85c label.go.step.3=\ub2e8\uacc4 3\uc73c\ub85c label.go.step.4=\ub2e8\uacc4 4\uc73c\ub85c @@ -533,6 +555,7 @@ label.host.tags=\ud638\uc2a4\ud2b8 \ud0dc\uadf8 label.host=\ud638\uc2a4\ud2b8 label.hourly=\ub9e4\uc2dc\uac04 label.hypervisor.capabilities=\ud558\uc774\ud37c \ubc14\uc774\uc800 \uae30\ub2a5 +label.hypervisors=\ud558\uc774\ud37c\ubc14\uc774\uc800 label.hypervisor.type=\ud558\uc774\ud37c \ubc14\uc774\uc800 \uc885\ub958 label.hypervisor=\ud558\uc774\ud37c \ubc14\uc774\uc800 label.hypervisor.version=\ud558\uc774\ud37c \ubc14\uc774\uc800 \ubc84\uc804 @@ -693,6 +716,7 @@ label.migrate.systemvm.to=\uc2dc\uc2a4\ud15c VM \uc774\uc804 \uc704\uce58\: label.migrate.volume=\ub2e4\ub978 \uae30\ubcf8 \uc2a4\ud1a0\ub9ac\uc9c0\uc5d0 \ubcfc\ub968 \uc774\uc804 label.minimum=\ucd5c\uc18c label.minute.past.hour=\ubd84(\ub9e4\uc2dc) +label.mode=\ubaa8\ub4dc label.monday=\uc6d4\uc694\uc77c label.monthly=\ub9e4\uc6d4 label.more.templates=\ub2e4\ub978 \ud15c\ud50c\ub9bf @@ -834,6 +858,7 @@ label.redundant.router.capability=\uc911\ubcf5 \ub77c\uc6b0\ud130 \uae30\ub2a5 label.redundant.router=\uc911\ubcf5 \ub77c\uc6b0\ud130 label.redundant.state=\uc911\ubcf5 \uc0c1\ud0dc label.refresh=\uc5c5\ub370\uc774\ud2b8 +label.reinstall.vm=VM \uc7ac\uc124\uce58 label.related=\uad00\ub828 label.remind.later=\uc54c\ub9bc \ud45c\uc2dc label.remove.ACL=\uad8c\ud55c \uad00\ub9ac(ACL) \uc0ad\uc81c @@ -871,9 +896,13 @@ label.revoke.project.invite=\ucd08\ub300 \ucde8\uc18c label.role=\uc5ed\ud560 label.root.disk.controller=\ub8e8\ud2b8 \ub514\uc2a4\ud06c \ucf58\ud2b8\ub864\ub7ec label.root.disk.offering=\ub8e8\ud2b8 \ub514\uc2a4\ud06c\uc81c\uacf5 +label.root.disk.size=\ub8e8\ud2b8 \ub514\uc2a4\ud06c label.round.robin=\ub77c\uc6b4\ub4dc \ub85c\ube48 +label.routing=\ub77c\uc6b0\ud305 label.rules=\uaddc\uce59 label.running.vms=\uc2e4\ud589\uc911 VM +label.s3.nfs.path=S3 NFS +label.s3.nfs.server=S3 NFS label.s3.secret_key=\ube44\ubc00 \ud0a4 label.saturday=\ud1a0\uc694\uc77c label.save.and.continue=\uc800\uc7a5\ud558\uae30 @@ -905,6 +934,7 @@ label.sent=\uc804\uc1a1\ub41c \uc0c1\ud0dc label.server=\uc11c\ubc84 label.service.capabilities=\uc11c\ube44\uc2a4 \uae30\ub2a5 label.service.offering=\uc11c\ube44\uc2a4\uc81c\uacf5 +label.service.state=\uc11c\ube44\uc2a4 label.session.expired=\uc138\uc158 \uc720\ud6a8\uae30\uac04\uc774 \ub04a\uc5b4\uc9d0 label.setup.network=\ub124\ud2b8\uc6cc\ud06c \uc124\uc815 label.setup=\uc124\uc815 @@ -980,6 +1010,7 @@ label.super.cidr.for.guest.networks=\uc190\ub2d8 \ub124\ud2b8\uc6cc\ud06c \uc288 label.supported.services=\uae30\uc220 \uc9c0\uc6d0\ub418\ub294 \uc11c\ube44\uc2a4 label.supported.source.NAT.type=\uae30\uc220 \uc9c0\uc6d0\ub418\ub294 \uc804\uc1a1 NAT \uc885\ub958 label.suspend.project=\ud504\ub85c\uc81d\ud2b8 \uc77c\uc2dc\uc815\uc9c0 +label.switch.type=\ud615\uc2dd label.system.capacity=\uc2dc\uc2a4\ud15c \ucc98\ub9ac \ub2a5\ub825 label.system.offering=\uc2dc\uc2a4\ud15c \uc81c\uacf5 label.system.service.offering=\uc2dc\uc2a4\ud15c \uc11c\ube44\uc2a4 \uc81c\uacf5 @@ -1059,9 +1090,7 @@ label.virtual.router=\uac00\uc0c1 \ub77c\uc6b0\ud130 label.vlan.id=VLAN ID label.vlan.range=VLAN \ubc94\uc704 label.vlan=\uac00\uc0c1 \ub124\ud2b8\uc6cc\ud06c(VLAN) -label.vxlan.id=VXLAN ID -label.vxlan.range=VXLAN \ubc94\uc704 -label.vxlan=VXLAN +label.vlan.vni.range=VLAN \ubc94\uc704 label.vm.add=\uc778\uc2a4\ud134\uc2a4 \ucd94\uac00 label.vm.destroy=\ud30c\uae30 label.vm.display.name=VM \ud45c\uc2dc\uba85 @@ -1076,6 +1105,8 @@ label.vm.state=VM \uc0c1\ud0dc label.vm.stop=\uc815\uc9c0 label.vms=VM label.vmware.traffic.label=VMware \ud2b8\ub798\ud53d \ub77c\ubca8 +label.vnet.id=VLAN ID +label.vnet=\uac00\uc0c1 \ub124\ud2b8\uc6cc\ud06c(VLAN) label.volgroup=\ubcfc\ub968 \uadf8\ub8f9 label.volume.limits=\ubcfc\ub968 \uc81c\ud55c label.volume.name=\ubcfc\ub968\uba85 @@ -1093,6 +1124,9 @@ label.vsmctrlvlanid=\uc81c\uc5b4 VLAN ID label.vsmpktvlanid=\ud328\ud0b7 VLAN ID label.vsmstoragevlanid=\uc2a4\ud1a0\ub9ac\uc9c0 VLAN ID label.vsphere.managed=vSphere \uad00\ub9ac +label.vxlan.id=VXLAN ID +label.vxlan.range=VXLAN \ubc94\uc704 +label.vxlan=VXLAN label.waiting=\ub300\uae30\ud558\ub294 \uc911 label.warn=\uacbd\uace0 label.wednesday=\uc218\uc694\uc77c @@ -1413,7 +1447,6 @@ message.zone.no.network.selection=\uc120\ud0dd\ud55c Zone\uc5d0\uc11c\ub294 \ub1 message.zone.step.1.desc=Zone \ub124\ud2b8\uc6cc\ud06c \ubaa8\ub378\uc744 \uc120\ud0dd\ud574 \uc8fc\uc2ed\uc2dc\uc624. message.zone.step.2.desc=\uc0c8 Zone\uc744 \ucd94\uac00\ud558\uae30 \uc704\ud574 \uc544\ub798 \uc815\ubcf4\ub97c \uc785\ub825\ud574 \uc8fc\uc2ed\uc2dc\uc624. message.zone.step.3.desc=\uc0c8 Pod\ub97c \ucd94\uac00\ud558\uae30 \uc704\ud574 \uc544\ub798 \uc815\ubcf4\ub97c \uc785\ub825\ud574 \uc8fc\uc2ed\uc2dc\uc624. -message.zoneWizard.enable.local.storage=\uacbd\uace0\:\ud604\uc7ac Zone\uc758 \ub85c\uceec \uc2a4\ud1a0\ub9ac\uc9c0\ub97c \uc0ac\uc6a9 \ud558\ub294 \uacbd\uc6b0\ub294 \uc2dc\uc2a4\ud15c VM\uc758 \uc2dc\uc791 \uc7a5\uc18c\uc5d0 \ub530\ub77c \ub2e4\uc74c \uc791\uc5c5\uc774 \ud544\uc694\ud569\ub2c8\ub2e4.

1. \uc2dc\uc2a4\ud15c VM\uc744 \uae30\ubcf8 \uc2a4\ud1a0\ub9ac\uc9c0\ub85c \uc2dc\uc791\ud574\uc57c \ud558\ub294 \uacbd\uc6b0 \uae30\ubcf8 \uc2a4\ud1a0\ub9ac\uc9c0\ub97c \ub9cc\ub4e4\uae30\ud55c \ub2e4\uc74c\uc5d0 Zone\uc5d0 \ucd94\uac00\ud574\uc57c \ud569\ub2c8\ub2e4. \ub610\ud55c, \uc720\ud6a8\ud558\uc9c0 \uc54a\uc740 \uc0c1\ud0dc\uc758 Zone\uc744 \uc2dc\uc791\ud574\uc57c \ud569\ub2c8\ub2e4.

2. \uc2dc\uc2a4\ud15c VM\ub97c \ub85c\uceec \uc2a4\ud1a0\ub9ac\uc9c0\ub85c \uc2dc\uc791\ud560 \ud544\uc694\uac00 \uc788\ub294 \uacbd\uc6b0 system.vm.use.local.storage\ub97c true \ub85c \uc124\uc815\ud558\uace0 \ub098\uc11c Zone\uc744 \uc0ac\uc6a9\ud574\uc57c \ud569\ub2c8\ub2e4.


\uc9c4\ud589 \ud558\uc2dc\uaca0\uc2b5\ub2c8\uae4c? mode=\ubaa8\ub4dc network.rate=\ub124\ud2b8\uc6cc\ud06c \uc18d\ub3c4 notification.reboot.instance=\uc778\uc2a4\ud134\uc2a4 \uc7ac\uc2dc\uc791 diff --git a/client/WEB-INF/classes/resources/messages_nb_NO.properties b/client/WEB-INF/classes/resources/messages_nb_NO.properties index be41244939..c169112222 100644 --- a/client/WEB-INF/classes/resources/messages_nb_NO.properties +++ b/client/WEB-INF/classes/resources/messages_nb_NO.properties @@ -16,103 +16,466 @@ # under the License. changed.item.properties=Endrede egenskaper +confirm.enable.swift=Vennligst fyll inn f\u00f8lgende informasjon for \u00e5 aktivere st\u00f8tte 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.enable.zone=Kunne ikke aktivere sonen error.installWizard.message=Noe gikk galt. G\u00e5 tilbake og korriger feilene. +error.invalid.username.password=Ugyldig brukernavn eller passord +error.mgmt.server.inaccessible=Administrasjonsserver er utilgjengelig. Vennligst pr\u00f8v igjen senere. error.password.not.match=Passordfeltene sammensvarer ikke +error.session.expired=Din sesjon har utl\u00f8pt. error.something.went.wrong.please.correct.the.following=Noe gikk galt. Vennligst korrig\u00e9r f\u00f8lgende +error.unable.to.reach.management.server=Kan ikke oppn\u00e5 kontakt med administrasjonsserveren +extractable=Utpakkbar force.delete=Tving sletting force.remove=Tving fjerning force.stop=Tving stopp +ICMP.code=ICMP-kode +ICMP.type=ICMP-type +image.directory=Bilde-katalog instances.actions.reboot.label=Omstart av instans +label.about.app=Om CloudStack +label.about=Om label.accept.project.invitation=Aksepter prosjektinvitasjon +label.account.and.security.group=Konto, Sikkerhetsgruppe +label.account.id=Konto ID +label.account=Konto +label.account.name=Kontonavn +label.accounts=Kontoer +label.action.attach.disk.processing=Tilknytter Disk.... +label.action.attach.disk=Tilknytt Disk +label.action.attach.iso.processing=Tilknytter ISO.... +label.action.attach.iso=Tilknytt ISO +label.action.change.password=Endre passord +label.action.change.service=Endre Tjeneste +label.action.change.service.processing=Endrer Tjeneste.... +label.action.copy.ISO=Kopier ISO +label.action.copy.ISO.processing=Kopierer ISO.... +label.action.copy.template=Kopier mal +label.action.copy.template.processing=Kopier mal.... +label.action.create.template.from.vm=Lag Mal fra VM +label.action.create.template.from.volume=Lag Mal fra Volum +label.action.create.template=Opprett mal +label.action.create.template.processing=Oppretter mal.... +label.action.create.vm=Opprett VM +label.action.create.vm.processing=Oppretter VM.... +label.action.create.volume=Opprett volum +label.action.create.volume.processing=Oppretter volum.... +label.action.delete.account.processing=Sletter konto.... +label.action.delete.account=Slett konto +label.action.delete.cluster.processing=Sletter klynge.... +label.action.delete.cluster=Slett klynge +label.action.delete.disk.offering.processing=Sletter disktilbud.... +label.action.delete.disk.offering=Slett disktilbud +label.action.delete.domain.processing=Sletter domene.... +label.action.delete.domain=Slett domene +label.action.delete.firewall.processing=Sletter brannmur.... +label.action.delete.firewall=Slett brannmurregel +label.action.delete.ingress.rule.processing=Sletter inng\u00e5ende regel.... +label.action.delete.ingress.rule=Slett inng\u00e5ende regel +label.action.delete.IP.range.processing=Sletter IP-rekke.... +label.action.delete.IP.range=Slett IP-rekke +label.action.delete.ISO.processing=Sletter ISO.... +label.action.delete.ISO=Slett ISO +label.action.delete.load.balancer.processing=Sletter Lastbalanserer +label.action.delete.load.balancer=Slett lastbalanseringsregel +label.action.delete.network.processing=Sletter nettverk.... +label.action.delete.network=Slett nettverk +label.action.delete.nexusVswitch=Slett Nexus 1000v +label.action.delete.nic=Fjern NIC +label.action.delete.physical.network=Slett fysisk nettverk +label.action.delete.pod.processing=Sletter pod.... +label.action.delete.pod=Slett pod +label.action.delete.primary.storage.processing=Sletter prim\u00e6rlagring.... +label.action.delete.primary.storage=Slett prim\u00e6rlagring +label.action.delete.secondary.storage.processing=Sletter sekund\u00e6rlagring.... +label.action.delete.secondary.storage=Slett sekund\u00e6rlagring +label.action.delete.security.group.processing=Slett Sikkerhetsgruppe.... +label.action.delete.security.group=Slett Sikkerhetsgruppe +label.action.delete.service.offering.processing=Sletter tjenestetilbud.... +label.action.delete.service.offering=Slett tjenestetilbud +label.action.delete.system.service.offering=Slett system-tjenestetilbud +label.action.delete.template.processing=Sletter mal.... +label.action.delete.template=Slett mal +label.action.delete.user.processing=Sletter bruker.... +label.action.delete.user=Slett bruker +label.action.delete.volume.processing=Sletter volum.... +label.action.delete.volume=Slett volum +label.action.delete.zone.processing=Sletter sone.... +label.action.delete.zone=Slett sone +label.action.destroy.instance.processing=\u00d8delegge instans.... +label.action.destroy.instance=\u00d8delegg Instans +label.action.destroy.systemvm.processing=Sletter system VM.... +label.action.destroy.systemvm=Slett system VM +label.action.disable.account=Deaktiver konto +label.action.disable.account.processing=Deaktiverer konto.... label.action.disable.cluster=Deaktiver klyngen label.action.disable.cluster.processing=Deaktiverer klyngen... +label.action.disable.nexusVswitch=Deaktiver Nexus 1000v +label.action.disable.physical.network=Deaktiver fysisk nettverk label.action.disable.pod=Deaktiver pod label.action.disable.pod.processing=Deaktiverer pod... +label.action.disable.static.NAT=Deaktiver statisk NAT +label.action.disable.static.NAT.processing=Deaktiverer statisk NAT.... +label.action.disable.user=Deaktivert bruker +label.action.disable.user.processing=Deaktiverer bruker.... label.action.disable.zone=Deaktiver sonen label.action.disable.zone.processing=Deaktiverer sonen... +label.action.download.ISO=Last ned ISO +label.action.download.template=Laster ned mal +label.action.download.volume=Last ned volum +label.action.download.volume.processing=Laster ned volum.... +label.action.edit.account=Rediger konto +label.action.edit.disk.offering=Editer disktilbud +label.action.edit.domain=Editer domene +label.action.edit.global.setting=Editer global innstilling +label.action.edit.host=Editer vert +label.action.edit.instance=Rediger instans +label.action.edit.ISO=Rediger ISO +label.action.edit.network=Editer Nettverk +label.action.edit.network.processing=Editerer Nettverk.... +label.action.edit.pod=Editer Pod +label.action.edit.primary.storage=Editer Prim\u00e6rlagring +label.action.edit.service.offering=Editer tjenestetilbud +label.action.edit.template=Editer mal +label.action.edit.user=Rediger bruker +label.action.edit.zone=Rediger Sone +label.action.enable.account=Aktiver konto +label.action.enable.account.processing=Aktiverer konto.... label.action.enable.cluster=Aktiver klynge label.action.enable.cluster.processing=Aktiverer klyngen... +label.action.enable.nexusVswitch=Aktiver Nexus 1000v +label.action.enable.physical.network=Aktiver fysisk nettverk label.action.enable.pod=Aktiver pod label.action.enable.pod.processing=Aktiverer pod... +label.action.enable.static.NAT=Aktiver statisk NAT +label.action.enable.static.NAT.processing=Aktiverer statisk NAT.... +label.action.enable.user=Aktiver Bruker +label.action.enable.user.processing=Aktiverer Bruker.... label.action.enable.zone=Aktiver sone label.action.enable.zone.processing=Aktiverer sone... +label.action.generate.keys=Generer n\u00f8kler +label.action.generate.keys.processing=Genererer n\u00f8kler.... +label.action.list.nexusVswitch=Liste Nexus 1000v +label.action.lock.account=L\u00e5s konto +label.action.lock.account.processing=L\u00e5ser konto.... +label.action.manage.cluster=Administrer klynge +label.action.manage.cluster.processing=Administrerer klynge.... +label.action.migrate.instance=Migrer Instans +label.action.migrate.instance.processing=Migrerer Instans.... +label.action.migrate.router=Migrer ruter +label.action.migrate.router.processing=Migrerer Ruter.... +label.action.migrate.systemvm=Migrer System VM +label.action.migrate.systemvm.processing=Migrerer System VM.... +label.action.reboot.instance=Omstart Instans +label.action.reboot.instance.processing=Starter om Instans.... +label.action.reboot.router=Omstart Ruter +label.action.reboot.router.processing=Omstaer Instans.... +label.action.reboot.systemvm=Omstart System VM +label.action.reboot.systemvm.processing=Omstarter System VM +label.action.register.iso=Registrer ISO +label.action.register.template=Registrer mal +label.action.remove.host=Fjern Vert +label.action.remove.host.processing=Fjerner Vest.... +label.action.reset.password.processing=Tilbakestiller passord.... +label.action.reset.password=Tilbakestill passord +label.action.resize.volume=Endre st\u00f8rrelse p\u00e5 volum +label.action.resize.volume.processing=Endrer st\u00f8rrelse p\u00e5 volum.... +label.action.resource.limits=Ressursbegrensninger +label.action.restore.instance=Gjenopprett Instans +label.action.restore.instance.processing=Gjenoppretter Instans.... +label.actions=Handlinger +label.action.start.instance.processing=Starter instans.... +label.action.start.instance=Start instans +label.action.start.router.processing=Stopper ruter +label.action.start.router=Start ruter +label.action.start.systemvm.processing=Starter System VM.... +label.action.start.systemvm=Start System VM +label.action.stop.instance.processing=Stopper instans.... +label.action.stop.instance=Stopp instans +label.action.stop.router.processing=Stopper ruter.... +label.action.stop.router=Stopp ruter +label.action.stop.systemvm.processing=Stopper System VM.... +label.action.stop.systemvm=Stopp System VM label.action.unmanage.cluster.processing=Fjerner administrasjon av klynge... label.activate.project=Aktiver prosjekt +label.active.sessions=Aktive sesjoner +label.add.account=Legg til konto label.add.accounts=Legg til kontoer label.add.accounts.to=Legg kontoer til label.add.account.to.project=Legg kontoen til prosjektet +label.add.ACL=Legg til ACL label.add.by=Legg til ved +label.add.cluster=Legg til klynge +label.add.compute.offering=Legg til systemtilbud +label.add.domain=Legg til domene +label.add.F5.device=Legg til F5 enhet +label.add.firewall=Legg til brannmurregel label.add.guest.network=Legg til gjestenettverk +label.add.host=Legg til vert +label.adding.cluster=Legger til klynge +label.adding.failed=Tillegging feilet +label.adding.pod=Legger til pod +label.adding.processing=Legger til +label.adding.succeeded=Tillegging vellykket +label.adding=Tillegger +label.adding.user=Legger til bruker +label.adding.zone=Legger til sone +label.add.ip.range=Legg til IP-rekke +label.add=Legg til +label.add.load.balancer=Legg til lastbalanserer +label.add.more=Legg til mer +label.add.netScaler.device=Legg til Netscaler enhet +label.add.network.ACL=Legg til nettverk ACL label.add.network.device=Legg til nettverksenhet +label.add.network=Legg til nettverk +label.add.network.offering=Legg til nettverkstilbud label.add.new.F5=Legg til ny F5 +label.add.new.gateway=Legg til ny gateway label.add.new.NetScaler=Legg til ny NetScaler +label.add.new.PA=Legg til ny Palo Alto label.add.new.SRX=Legg til ny SRX +label.add.PA.device=Legg til Palo Alto enhet label.add.physical.network=Legg til fysisk nettverk +label.add.pod=Legg til pod +label.add.port.forwarding.rule=Legg til portvideresendingsregel +label.add.primary.storage=Legg til prim\u00e6rlagring +label.add.region=Legg til region label.add.resources=Legg til ressurser +label.add.route=Legg til rute +label.add.rule=Legg til regel +label.add.secondary.storage=Legg til sekund\u00e6rlagring +label.add.security.group=Legg til sikkerhetsgruppe +label.add.service.offering=Legg til tjenestetilbud +label.add.SRX.device=Legg til SRX enhet +label.add.static.nat.rule=Legg til statisk NAT-regel +label.add.static.route=Legg til statisk rute label.add.system.service.offering=Legg til et systemtilbud +label.add.template=Legg til mal label.add.to.group=Legg til gruppe +label.add.user=Legg til bruker +label.add.vlan=Legg til VLAN +label.add.vm=Legg til VM label.add.vms=Legg til VMer +label.add.vms.to.lb=Legg til VM(er) til lastbalanseringsregel +label.add.volume=Legg til volum +label.add.vpc=Legg til VPC +label.add.VPN.gateway=Legg til VPN Gateway +label.add.vpn.user=Legg til VPN-bruker +label.add.vxlan=Legg til VXLAN +label.add.zone=Legg til sone +label.admin.accounts=Adminkontoer +label.admin=Admin label.advanced=Avansert +label.advanced.mode=Avansermodus +label.advanced.search=Avansert s\u00f8k +label.agent.password=Agentpassord label.agree=Godtar +label.alert=Varsel label.allocated=Allokert label.allocation.state=Allokeringsstatus +label.api.key=API-n\u00f8kkel label.apply=Bruk +label.app.name=CloudStack +label.archive.alerts=Arkiver varsler +label.archive.events=Arkiver hendelser +label.assign=Tildel +label.attached.iso=Tilknyttet ISO +label.author.email=Forfatter e-post +label.author.name=Forfatternavn +label.availability=Tilgjengelighet +label.availability.zone=Tilgjengelighetssone +label.available.public.ips=Tilgjengelig offentlige IP-adresser +label.available=Tilgjengelig +label.back=Tilbake label.bandwidth=B\u00e5ndbredde label.basic=Basis +label.basic.mode=Basismodus +label.by.account=Etter Konto +label.by.alert.type=Etter varseltype +label.by.availability=Etter Tilgjengelighet +label.by.date.end=Etter dato (slutt) +label.by.date.start=Etter dato (start) +label.by.domain=Etter Domene +label.by.event.type=Etter hendelsestype +label.by.pod=Etter Pod +label.by.role=Etter Rolle +label.by.start.date=Etter Startdato +label.by.traffic.type=Etter Trafikktype +label.by.type=Etter Type +label.by.type.id=Etter Type ID +label.by.zone=Etter Sone +label.cancel=Avbryt label.capacity=Kapasitet +label.certificate=Sertifikat label.change.service.offering=Endre tjenestetilbud label.change.value=Endre verdi +label.character=Karakter +label.checksum=MD5 sjekksum label.cidr=CIDR +label.CIDR.list=CIDR liste label.cidr.list=Kilde-CIDR label.clean.up=Rydd opp +label.clear.list=T\u00f8m liste +label.close=Lukk +label.cloud.console=Cloud +label.cluster=Klynge +label.cluster.name=Klyngenavn +label.clusters=Klynger +label.cluster.type=Klyngetype label.clvm=CLVM label.compute.and.storage=Regnekraft og lagring label.compute=Beregne +label.compute.offering=Regnekraftstilbud +label.compute.offerings=Regnekraftstilbud +label.configuration=Konfigurering label.configure=Konfigurer +label.configure.vpc=Konfigurer VPC +label.confirmation=Bekreftelse label.confirm.password=Bekreft passord label.congratulations=Gratulerer\! +label.conserve.mode=Konserveringsmodus +label.console.proxy=Konsollproxy label.continue.basic.install=Fortsett med enkelt oppsett label.continue=Fortsett label.corrections.saved=Endringer lagret +label.cpu.allocated=CPU allokert +label.cpu.allocated.for.VMs=CPU Allokert for VMer label.CPU.cap=CPU begrensning +label.cpu=CPU +label.cpu.limits=CPU-begrensninger +label.cpu.mhz=CPU (i MHz) +label.cpu.utilized=CPU-utnyttelse label.created.by.system=Opprettet av systemet +label.created=Opprettet label.create.project=Opprett prosjekt label.create.template=Opprett mal +label.create.VPN.connection=Opprett VPN-tilkobling +label.custom.disk.size=Tilpasset Diskst\u00f8rrelse +label.daily=Daglig +label.data.disk.offering=Datadisktilbud +label.date=Dato label.decline.invitation=Avvis invitasjon label.dedicated=Dedikert label.default=Standardverdi label.default.use=Standard bruk label.default.view=Standardvisning +label.delete.alerts=Slette varsler +label.delete.events=Slett hendelser +label.delete.F5=Slett F5 +label.delete.gateway=slett gateway +label.delete.NetScaler=Slett Netscaler +label.delete.PA=Slett Palo Alto label.delete.project=Slett prosjekt +label.delete=Slett +label.delete.SRX=Slett SRX +label.delete.VPN.connection=Slett VPN-tilkobling +label.delete.VPN.gateway=Slett VPN-gateway +label.delete.vpn.user=Slett VPN-bruker +label.deleting.failed=Sletting feilet +label.deleting.processing=Sletter.... +label.description=Beskrivelse label.destination.physical.network.id=Fysisk nettverksid-destinasjon +label.destination.zone=Destinasjonssone +label.destroy=Destruer label.destroy.router=Slett ruter +label.details=Detaljer +label.device.id=Enhets ID +label.devices=Enheter label.dhcp=DHCP label.DHCP.server.type=DHCP servertype label.disabled=Inaktiv label.disable.provider=Deaktiver tilbyder +label.disable.vpn=Dekativer VPN +label.disabling.vpn.access=Deaktiverer VPN Tilgang +label.disk.allocated=Disk allokert +label.disk.iops.max=Maks IOPS +label.disk.iops.min=Min IOPS +label.disk.iops.total=IOPS Totalt +label.disk.offering=Disktilbud +label.disk.read.bytes=Disk lese (Bytes) +label.disk.read.io=Disk lese (IO) +label.disk.size=Diskst\u00f8rrelse +label.disk.size.gb=Diskst\u00f8rrelse (i GB) +label.disk.total=Disk Totalt +label.disk.volume=Disk Volum +label.disk.write.bytes=Disk skrive (Bytes) +label.disk.write.io=Disk skrive (IO) label.display.name=Visningsnavn +label.display.text=Visningstekst +label.dns.1=DNS 1 +label.dns.2=DNS 2 +label.dns=DNS +label.DNS.domain.for.guest.networks=DNS domene for gjestenettverk +label.domain.admin=Domeneadministrator +label.domain=Domene +label.domain.id=Domene ID +label.domain.name=Domenenavn +label.domain.router=Domeneruter label.done=Utf\u00f8rt label.drag.new.position=Dra til ny posisjon +label.edit=Editer +label.edit.lb.rule=Endre LB-regel label.edit.network.details=Edit\u00e9r nettverksdetaljer label.edit.project.details=Editer prosjektdetaljer +label.edit.traffic.type=Endre trafikktype +label.edit.vpc=Rediger VPC label.elastic=Elastisk label.elastic.IP=Elastisk IP label.elastic.LB=Elastisk LB +label.email=E-post label.enable.provider=Aktiver tilbyder +label.enable.swift=Aktiver Swift label.enable.vpn=Aktiver VPN +label.enabling.vpn.access=Aktiverer VPN-tilgang +label.enabling.vpn=Aktiverer VPN label.end.IP=Slutt-IP +label.end.port=Sluttport label.end.vlan=Slutt-VLAN label.enter.token=Skriv inn koden label.error=Feil +label.esx.host=ESX/ESXi vert +label.example=Eksempel label.f5=F5 +label.failed=Feilet +label.fetch.latest=Hent siste label.filterBy=Filtrer etter +label.firewall=Brannmur +label.first.name=Fornavn +label.format=Format +label.friday=Fredag +label.full=Full +label.full.path=Full sti +label.general.alerts=Generelle varsler +label.gluster.volume=Volum +label.go.step.2=G\u00e5 til steg 2 +label.go.step.3=G\u00e5 til steg 3 +label.go.step.4=G\u00e5 til steg 4 +label.go.step.5=G\u00e5 til steg 5 +label.group=Gruppe +label.group.optional=Gruppe (Valgfritt) +label.guest.cidr=Gjest CIDR label.guest.end.ip=Gjest slutt-IP label.guest=Gjest +label.guest.ip=Gjest IP-adresse +label.guest.ip.range=Gjest IP-rekke +label.guest.netmask=Gjest nettmaske label.guest.networks=Gjestenettverk label.guest.start.ip=Gjest start-IP label.guest.traffic=Gjestetrafikk +label.guest.type=Gjestetype +label.ha.enabled=HA Aktivert +label.help=Hjelp label.hints=Hint +label.home=Hjem +label.host.alerts=Vertsvarsler +label.host.MAC=Verts MAC +label.host.name=Vertsnavn +label.hosts=Verter +label.host=Vert +label.hourly=Hver time +label.id=ID +label.info=Info label.installWizard.addClusterIntro.subtitle=Hva er en klynge? label.installWizard.addClusterIntro.title=La oss legge til en klynge label.installWizard.addHostIntro.subtitle=Hva er en vert? @@ -129,62 +492,206 @@ label.installWizard.addZone.title=Legg til sone label.installWizard.click.launch=Klikk startknappen. label.installWizard.subtitle=Denne veiviseren vil hjelpe deg i din installasjon av CloudStack&\#8482 label.installWizard.title=Hei og velkommen til CloudStack&\#8482 +label.instance=Instans +label.instance.limits=Instans Begrensninger +label.instance.name=Instans Navn +label.instances=Instanser +label.internal.dns.1=Intern DNS 1 +label.internal.dns.2=Intern DNS 2 +label.internal.name=Internt navn label.introduction.to.cloudstack=Introduksjon til CloudStack&\#8482 label.invitations=Invitasjoner label.invited.accounts=Inviterte kontoer label.invite=Inviter label.invite.to=Inviter til -label.ip.ranges=IP-rekke +label.ip.address=IP-adresse +label.ipaddress=IP-adresse +label.ip.allocations=IP Allokeringer +label.ip=IP +label.ip.or.fqdn=IP eller FQDN +label.ip.range=IP-rekke +label.ip.ranges=IP-rekker +label.ips=IPer +label.is.default=Er standard +label.iso=ISO +label.isolated.networks=Isolerte nettverk +label.isolation.method=Isolasjonsmetode +label.isolation.mode=Isolasjonsmetode label.is.redundant.router=Redundant +label.is.shared=Er delt +label.is.system=Er system label.item.listing=Elementlisting +label.keep=Behold +label.key=N\u00f8kkel label.kvm.traffic.label=KVM trafikketikett +label.lang.arabic=Arabisk +label.lang.brportugese=Brasiliansk Portugisisk +label.lang.catalan=Katalansk +label.lang.chinese=Kinesisk (Forenklet) +label.lang.english=Engelsk +label.lang.french=Fransk +label.lang.german=Tysk +label.lang.italian=Italiensk +label.lang.japanese=Japanesisk +label.lang.korean=Koreansk +label.lang.norwegian=Norsk +label.lang.russian=Russisk +label.lang.spanish=Spansk +label.last.name=Etternavn +label.latest.events=Siste hendelser label.launch=Start label.launch.vm=Start VM label.LB.isolation=LB-isolering label.least.connections=F\u00e6rrest tilkoblinger +label.load.balancer=Lastbalanserer label.load.balancing=Lastbalansering label.load.balancing.policies=Regler for lastbalansering +label.loading=Laster +label.local=Lokal label.local.storage=Lokal lagring +label.logout=Logg ut +label.lun=LUN +label.LUN.number=LUN \# label.make.project.owner=Gj\u00f8r konto prosjekteier +label.manage=Administrer label.management=Administrasjon +label.management.ips=Administrasjons IP-adresser label.manage.resources=Behandle ressurser +label.maximum=Maksimum label.max.public.ips=Maks offentlige IPer label.max.snapshots=Maks \u00f8yeblikksbilder label.max.templates=Maks maler label.max.vms=Maks bruker-VMer label.max.volumes=Maks volumer label.may.continue=Du kan n\u00e5 fortsette. +label.memory.allocated=Minne allokert +label.memory.mb=Minne (i MB) +label.memory=Minne +label.memory.total=Minne totalt +label.memory.used=Minne brukt +label.menu.accounts=Kontoer +label.menu.alerts=Varsler +label.menu.all.accounts=Alle kontoer +label.menu.all.instances=Alle instanser +label.menu.configuration=Konfigurering +label.menu.domains=Domener +label.menu.events=Hendelser +label.menu.infrastructure=Infrastruktur +label.menu.instances=Instanser +label.menu.ipaddresses=IP-adresser +label.menu.isos=ISOer +label.menu.my.accounts=Mine kontoer +label.menu.my.instances=Mine instanser +label.menu.my.isos=Mine ISOer +label.menu.my.templates=Mine maler +label.menu.network=Nettverk +label.menu.network.offerings=Nettverkstilbud +label.menu.physical.resources=Fysiske ressurser +label.menu.regions=Regioner +label.menu.running.instances=Kj\u00f8rende instanser +label.menu.security.groups=Sikkerhetsgrupper +label.menu.service.offerings=Tjenestetilbud +label.menu.stopped.instances=Stoppede instanser +label.menu.storage=Lagring label.menu.system.service.offerings=Systemtilbud +label.menu.system=System +label.menu.system.vms=System VMer +label.menu.templates=Maler +label.menu.virtual.resources=Virtuelle ressurser +label.menu.volumes=Volumer label.migrate.instance.to.host=Migrer instansen til en annen vert +label.migrate.instance.to=Migrer instans til label.migrate.instance.to.ps=Migrer instansen til en annen sekund\u00e6r lagring. +label.migrate.router.to=Migrer Ruter til +label.migrate.systemvm.to=Migrer System VM til +label.migrate.to.host=Migrer til vert +label.migrate.to.storage=Migrer til lagring label.migrate.volume=Migrer volumet til en annen prim\u00e6rlagring. +label.minimum=Minimum +label.monday=Mandag +label.monthly=M\u00e5nedlig +label.more.templates=Flere maler label.move.down.row=Flytt \u00e9n rad ned +label.move.to.bottom=Flytt til bunnen label.move.to.top=Flytt til toppen label.move.up.row=Flytt \u00e9n rad opp +label.my.account=Min konto label.my.network=Mitt nettverk label.my.templates=Mine maler +label.name=Navn +label.name.optional=Navn (Valgfritt) +label.nat.port.range=NAT portrekke +label.netmask=Nettmaske label.netScaler=NetScaler +label.network.ACL=Nettverk ACL +label.network.ACLs=Nettverk ACLer +label.network.desc=Nettverksbeskrivelse label.network.device=Nettverksenhet label.network.device.type=Type nettverksenhet +label.network.domain=Nettverksdomene +label.network.domain.text=Nettverksdomene +label.network.id=Nettverks ID label.networking.and.security=Nettverk og sikkerhet label.network.label.display.for.blank.value=Bruk standard gateway +label.network.name=Nettverksdame +label.network=Nettverk +label.network.offering=Nettverkstilbud label.networks=Nettverk label.new=Ny +label.new.password=Nytt passord label.new.project=Nytt prosjekt label.new.vm=Ny VM +label.next=Neste +label.nexusVswitch=Nexus 1000v +label.nfs=NFS +label.nfs.server=NFS Server +label.nfs.storage=NFS Lagring +label.nics=NICer label.no.data=Ingen data \u00e5 vise +label.no=Nei +label.none=Ingen +label.not.found=Ikke funnet label.no.thanks=Nei, takk label.notifications=Notifikasjoner +label.number.of.clusters=Antall klynger +label.number.of.pods=Antall pods +label.number.of.virtual.routers=Antall virtuelle rutere +label.number.of.zones=Antall soner +label.offer.ha=Tilby HA label.ok=OK +label.optional=Valgfritt label.order=Rekkef\u00f8lge +label.os.type=OS-type +label.PA=Palo Alto +label.password=Passord +label.path=Sti +label.physical.network=Fysisk nettverk label.physical.network.ID=Fysisk nettverksid label.PING.CIFS.password=PING CIFS passord label.PING.CIFS.username=PING CIFS brukernavn label.PING.dir=PING-mappe label.PING.storage.IP=PING lagrings-IP label.please.specify.netscaler.info=Vennligst spesifiser NetScaler-info +label.please.wait=Vennligst vent +label.pod.name=Pod navn +label.pod=Pod +label.pods=Pods label.port.forwarding.policies=Regler for portvideresending +label.port.forwarding=Portvideresending +label.port.range=Portrekke +label.prev=Forrige label.previous=Forrige +label.primary.allocated=Prim\u00e6rlagring allokert +label.primary.network=Prim\u00e6rnettverk +label.primary.storage=Prim\u00e6rlagring +label.primary.used=Prim\u00e6rlagring brukt +label.private.Gateway=Privat Gateway +label.private.ip=Privat IP-adresse +label.private.ip.range=Privat IP-rekke +label.private.ips=Private IP-adresser +label.private.network=Privat nettverk +label.private.port=Privat port +label.private.zone=Privat sone label.project.dashboard=Prosjektoversikt label.project.id=Prosjektid label.project.invite=Inviter til prosjekt @@ -192,82 +699,291 @@ label.project.name=Prosjektnavn label.project=Prosjekt label.projects=Prosjekter label.project.view=Prosjektvisning +label.protocol=Protokoll label.providers=Tilbydere +label.public.ip=Offentlig IP-adresse +label.public.ips=Offentlig IP-adresser label.public.network=Offentlig nettverk +label.public=Offentlig +label.public.port=Offentlig port +label.public.traffic=Offentlig trafikk +label.public.zone=Offentlig sone +label.purpose=Form\u00e5l label.Pxe.server.type=PXE Servertype +label.rbd=RBD +label.reboot=Restart label.redundant.router.capability=Redundant ruter label.redundant.router=Redundant ruter label.redundant.state=Redundant tilstand +label.refresh=Oppfrisk +label.region=Region +label.related=Relaterte label.remind.later=P\u00e5minn meg senere +label.remove.ACL=Fjern ACL +label.remove.from.load.balancer=Fjerner instans fra lastbalanserer label.remove.ip.range=Fjern IP-rekke +label.remove.pf=Fjern portvideresendingsregel +label.remove.region=Fjern region +label.remove.rule=Fjern regel +label.remove.static.nat.rule=Fjern statisk NAT-regel +label.remove.static.route=Fjern statisk rute +label.remove.vpc=fjern VPC label.removing=Fjerner +label.removing.user=Fjerner Bruker +label.required=P\u00e5krevd +label.reserved.system.ip=Reservert System IP +label.reset.VPN.connection=Resett VPN-tilkobling +label.resize.new.size=Ny st\u00f8rrelse(GB) +label.resource=Ressurs +label.resources=Ressurser label.restart.network=Nettverksomstart label.restart.required=Omstart p\u00e5krevd +label.restart.vpc=Omstart VPC +label.restore=Gjenopprett label.review=Gjennomg\u00e5 label.revoke.project.invite=Tilbakekall invitasjonen +label.role=Rolle +label.root.disk.size=Rotdiskst\u00f8rrelse label.round.robin=Ringdistribusjon +label.routing=Ruting +label.rules=Regler +label.running.vms=Kj\u00f8rende VMer +label.s3.nfs.path=S3 NFS Sti +label.s3.nfs.server=S3 NFS Server +label.s3.use_https=Bruk HTTPS +label.saturday=L\u00f8rdag label.save.and.continue=Lagre og fortsett +label.save=Lagre +label.saving.processing=Lagrer.... +label.search=S\u00f8k +label.secondary.storage=Sekund\u00e6rlagring +label.secondary.storage.vm=Sekund\u00e6rlagring VM +label.security.group.name=Sikkerhetsgruppenavn +label.security.group=Sikkerhetsgruppe +label.security.groups=Sikkerhetsgrupper label.select.a.template=Velg en mal label.select.a.zone=Velg en sone +label.select.instance.to.attach.volume.to=Velg instans for tildeling av volum +label.select.instance=Velg instans label.select.iso.or.template=Velg ISO eller mal +label.select.offering=Velg tilbud label.select.project=Velg prosjekt +label.select=Velg label.select-view=Velg visning +label.select.vm.for.static.nat=Velg instans for statisk NAT +label.sent=Sendt +label.server=Tjener +label.service.offering=Tjenestetilbud +label.service.state=Tjeneste Status +label.session.expired=Sesjon utl\u00f8pt label.setup.network=Nettverksoppsett label.setup=Oppsett label.setup.zone=Soneoppsett label.set.up.zone.type=Oppsett av sonetype +label.shared=Delt label.shutdown.provider=Steng tilbyder +label.size=St\u00f8rrelse label.skip.guide=Jeg har brukt CloudStack tidligere. Hopp over denne veiviseren label.source=Kilde +label.source.nat=Kilde NAT +label.specify.IP.ranges=Spesifiser IP-rekker +label.specify.vlan=Spesifiser VLAN +label.specify.vxlan=Spesifiser VXLAN label.SR.name = SR navnelapp label.srx=SRX label.start.IP=Start-IP +label.start.port=Start port label.start.vlan=Start-VLAN +label.start.vxlan=Start Vxlan label.static.nat.enabled=Statisk NAT aktivert +label.static.nat=Statistk NAT +label.static.nat.vm.details=Statisk NAT VM Detaljer +label.statistics=Statistikk +label.status=Status +label.step.1=Steg 1 +label.step.1.title=Steg 1\: Velg en mal +label.step.2=Steg 2 +label.step.2.title=Steg 2\: Tjenestetilbud +label.step.3=Steg 3 +label.step.3.title=Steg 3\: Velg et disktilbud +label.step.4=Steg 4 +label.step.4.title=Steg 4\: Nettverk +label.step.5=Steg 5 +label.step.5.title=Steg 5\: Repetere label.stickiness=Klebrighet +label.sticky.domain=Domene +label.sticky.expire=Utl\u00f8per +label.sticky.length=Lengde +label.stopped.vms=Stoppede VMer +label.stop=Stopp +label.storage=Lagring label.storage.tags=Merkelapper for lagring label.storage.traffic=Lagringstrafikk +label.storage.type=Lagringstype label.subdomain.access=Tilgang for underdomene +label.succeeded=Vellykket +label.sunday=S\u00f8ndag +label.supported.services=St\u00f8ttede Tjenester label.supported.source.NAT.type=Supporterte kilde-NAT typer label.suspend.project=Suspender prosjekt +label.switch.type=Svitsjtype +label.system.capacity=Systemkapasistet +label.system.offering=Systemtilbud +label.system.vms=System VMer +label.system.vm=System VM label.task.completed=Oppgave utf\u00f8rt +label.template=Mal label.TFTP.dir=TFTP-mappe +label.thursday=Torsdag label.timeout=Tidsavbrudd +label.time=Tid +label.time.zone=Tidssone +label.timezone=Tidssone label.token=Kode +label.total.cpu=Totalt CPU +label.total.CPU=Totalt CPU +label.total.hosts=Totalt Verter +label.total.memory=Totalt minne +label.total.of.ip=Totalt IP-adresser +label.total.of.vm=Totalt av VM +label.total.storage=Totalt lagring +label.traffic.label=Trafikketikett label.traffic.types=Trafikktyper +label.traffic.type=Trafikktype +label.tuesday=Tirsdag +label.type.id=Type ID +label.type=Type +label.unlimited=Ubegrenset label.update.project.resources=Oppdater prosjektressurser +label.update.ssl.cert= SSL-sertifikat +label.update.ssl= SSL-sertifikat +label.updating=Oppdaterer +label.upload=Last opp +label.upload.volume=Last opp volum +label.url=URL +label.used=Brukt +label.user=Bruker +label.username=Brukernavn +label.users=Brukere +label.use.vm.ip=Bruk VM IP\: +label.value=Verdi +label.vcdcname=vCenter DC navn +label.vcenter.cluster=vCenter Klynge +label.vcenter.host=vCenter Vert +label.vcenter.password=vCenter passord +label.vcenter.username=vCenter brukernavn +label.vcipaddress=vCenter IP-adresse +label.version=Versjon label.view.all=Vis alle label.view.console=Se konsoll label.viewing=Viser +label.view.more=Vis mer +label.view.secondary.ips=Se sekund\u00e6re IPer label.view=Vis label.virtual.machines=Virtuelle maskiner +label.virtual.network=Virtuelt-nettverk +label.virtual.routers=Virtuelle rutere label.virtual.router=Virtuell ruter +label.vlan.id=VLAN/VNI ID +label.vlan=VLAN/VNI +label.vm.add=Legg til Instans +label.vm.destroy=Destruer label.vm.display.name=Visningsnavn for VM label.VMFS.datastore=VMFS lagringsomr\u00e5de +label.vmfs=VMFS label.vm.name=VM-navn +label.vm.reboot=Restart +label.vmsnapshot.type=Type +label.vm.start=Start +label.vm.stop=Stopp +label.vms=VMer label.vmware.traffic.label=VMware trafikketikett +label.vnet.id=VLAN/VNI ID +label.vnet=VLAN/VNI label.volgroup=Volumgruppe +label.volume.limits=Volumbegrensninger +label.volume.name=Volumnavn +label.volumes=Volumer +label.volume=Volum +label.vpc.id=VPC ID +label.VPC.router.details=VPC ruterdetaljer +label.vpc=VPC +label.VPN.connection=VPN-tilkobling +label.VPN.gateway=VPN Gateway +label.vpn=VPN +label.vxlan.id=VXLAN ID +label.vxlan.range=VXLAN-rekke +label.vxlan=VXLAN +label.waiting=Venter +label.warn=Varsle +label.wednesday=Onsdag +label.weekly=Ukentlig +label.welcome.cloud.console=Velkommen til administrasjonskonsollet +label.welcome=Velkommen label.what.is.cloudstack=Hva er CloudStack&\#8482? label.xen.traffic.label=XenServer trafikketikett +label.yes=Ja label.zone.details=Sonedetaljer +label.zone.id=Sone ID label.zone.name=Sonenavn +label.zone=Sone +label.zones=Soner +label.zone.step.1.title=Steg 1\: Velg et nettverk +label.zone.step.2.title=Steg 2\: Legg til en sone +label.zone.step.3.title=Steg 3\: Legg til en pod +label.zone.step.4.title=Steg 4\: Legg til en IP-rekke label.zone.type=Sonetype +message.acquire.ip.nic=Vennligst bekreft at du vil allokere en ny sekund\u00e6r IP for dette nettverkskortet.
NB\: Du m\u00e5 manuelt konfigurere den nye sekund\u00e6r-IPen i den virtuelle maskinen. message.acquire.new.ip=Vennligst bekreft at du \u00f8nsker \u00e5 anskaffe en ny IP for dette nettverket +message.action.change.service.warning.for.router=Din ruter m\u00e5 v\u00e6re stoppet f\u00f8r du kan fors\u00f8ke \u00e5 endre n\u00e5v\u00e6rende servicetilbud. +message.action.delete.cluster=Vennligst bekreft at du vil slette denne klyngen. +message.action.delete.disk.offering=Vennligst bekreft at du \u00f8nsker \u00e5 slette dette disktilbudet. +message.action.delete.domain=Vennligst bekreft at du vil slette dette domenet. +message.action.delete.ingress.rule=Vennligst bekreft at du \u00f8nsker \u00e5 slette denne inng\u00e5ende regel. +message.action.delete.ISO.for.all.zones=Denne ISO er brukt av alle soner. Vennligst bekreft at du \u00f8nsker \u00e5 slette den fra alle soner. +message.action.delete.ISO=Vennligst bekreft at du vil slette denne ISO. +message.action.delete.network=Vennligst bekreft at du vil slette dette nettverket. +message.action.delete.nexusVswitch=Vennligst bekreft at du \u00f8nsker \u00e5 slette denne nexus 1000v +message.action.delete.physical.network=Vennligst bekreft at du \u00f8nsker \u00e5 slette dette fysiske nettverk +message.action.delete.pod=Vennligst bekreft at du vil slette denne pod. +message.action.delete.primary.storage=Vennligst bekreft at du \u00f8nsker \u00e5 slette denne prim\u00e6rlagring. +message.action.delete.secondary.storage=Vennligst bekreft at du \u00f8nsker \u00e5 slette denne sekund\u00e6rlagring. +message.action.delete.security.group=Vennligst bekreft at du \u00f8nsker \u00e5 slette denne sikkerhetsgruppe. +message.action.delete.service.offering=Vennligst bekreft at du \u00f8nsker \u00e5 slette dette servicetilbud. +message.action.delete.system.service.offering=Vennligst bekreft at du \u00f8nsker \u00e5 slette dette system-servicetilbud. +message.action.delete.template.for.all.zones=Denne mal er brukt av alle soner. Vennligst bekreft at du \u00f8nsker \u00e5 slette den fra alle soner. +message.action.delete.template=Vennligst bekreft at du vil slette denne mal. +message.action.delete.volume=Vennligst bekreft at du vil slette dette volumet. +message.action.delete.zone=Vennligst bekreft at du \u00f8nsker \u00e5 slette denne sone. +message.action.destroy.instance=Vennligst bekreft at du \u00f8nsker \u00e5 fjerne denne instansen. +message.action.disable.nexusVswitch=Vennligst bekreft at du \u00f8nsker \u00e5 deaktivere denne nexus 1000v +message.action.disable.physical.network=Vennligst bekreft at du \u00f8nsker \u00e5 deaktivere dette fysiske nettverket. message.action.disable.pod=Vennligst bekreft at du \u00f8nsker \u00e5 aktivere denne poden message.action.disable.zone=Vennligst bekreft at du \u00f8nsker \u00e5 deaktivere denne sonen. +message.action.download.iso=Vennligst bekreft at du \u00f8nsker \u00e5 laste ned denne ISO. +message.action.download.template=Vennligst bekreft at du \u00f8nsker \u00e5 laste ned denne malen. message.action.enable.cluster=Vennligst bekreft at du \u00f8nsker \u00e5 aktivere denne klyngen. +message.action.enable.nexusVswitch=Vennligst bekreft at du \u00f8nsker \u00e5 aktivere denne nexus 1000v +message.action.enable.physical.network=Vennligst bekreft at du \u00f8nsker \u00e5 aktivere dette fysiske nettverket. message.action.enable.pod=Vennligst bekreft at du \u00f8nsker \u00e5 aktivere denne poden. message.action.enable.zone=Vennligst bekreft at du \u00f8nsker \u00e5 aktivere denne sonen. +message.action.start.instance=Vennligst bekreft at du \u00f8nsker \u00e5 starte denne instansen. message.activate.project=Er du sikker p\u00e5 du \u00f8nsker \u00e5 aktivere dette prosjektet? +message.add.domain=Vennligst bekreft underdomenet du \u00f8nsker \u00e5 opprette under dette domenet message.add.guest.network=Vennligst bekreft at du \u00f8nsker \u00e5 legge til gjestenettverk message.adding.host=Legger til vert message.adding.Netscaler.device=Legg til NetScaler-enhet +message.add.load.balancer.under.ip=Lastbalanseringsregelen har blitt lagt til under IP\: +message.add.VPN.gateway=Vennligst bekreft at du \u00f8nsker \u00e5 legge til en VPN Gateway message.alert.state.detected=Alarm oppdaget message.change.password=Vennligst endre ditt passord message.configuring.guest.traffic=Konfigurerer gjestetrafikk message.configuring.physical.networks=Konfigurer fysisk nettverk message.configuring.public.traffic=Konfigurerer offentlig trafikk message.configuring.storage.traffic=Konfigurerer lagringstrafikk +message.confirm.delete.F5=Vennligst bekreft at du \u00f8nsker \u00e5 slette F5 +message.confirm.delete.NetScaler=Vennligst bekreft at du \u00f8nsker \u00e5 slette Netscaler +message.confirm.delete.SRX=Vennligst bekreft at du \u00f8nsker \u00e5 slette SRX message.confirm.destroy.router=Vennligst bekreft at du \u00f8nsker \u00e5 fjerne denne ruteren message.confirm.disable.provider=Vennligst bekreft at du \u00f8nsker \u00e5 deaktivere denne tilbyderen message.confirm.enable.provider=Vennligst bekreft at du \u00f8nsker \u00e5 aktivere denne tilbyderen @@ -275,16 +991,26 @@ message.confirm.join.project=Vennligst bekreft at du \u00f8nsker \u00e5 delta i message.confirm.shutdown.provider=Vennligst bekreft at du \u00f8nsker \u00e5 stenge denne tilbyderen message.create.template=Er du sikker p\u00e5 at du \u00f8nsker \u00e5 lage malen? message.creating.cluster=Oppretter klynge +message.creating.guest.network=Oppretter gjestenettverk +message.creating.physical.networks=Oppretter fysiske nettverk message.creating.pod=Oppretter pod message.creating.primary.storage=Oppretter prim\u00e6rlagring message.creating.secondary.storage=Oppretter sekund\u00e6rlagring +message.creating.zone=Oppretter sone message.decline.invitation=Er du sikker p\u00e5 du \u00f8nsker \u00e5 avvise denne prosjektinvitasjonen? +message.delete.gateway=Vennligst bekreft at du \u00f8nsker \u00e5 slette gateway message.delete.project=Er du sikker p\u00e5 du \u00f8nsker \u00e5 slette dette prosjektet? +message.delete.user=Vennligst bekreft at du \u00f8nsker \u00e5 slette denne bruker. +message.delete.VPN.connection=Vennligst bekreft at du \u00f8nsker \u00e5 slette VPN-tilkobling message.detach.disk=Er du sikker p\u00e5 at du \u00f8nsker \u00e5 frakoble denne disken? +message.disable.user=Vennligst bekreft at du \u00f8nsker \u00e5 deaktivere denne bruker. +message.disable.vpn=Er du sikker p\u00e5 at du vil deaktivere VPN? message.download.volume.confirm=Vennligst bekreft at du \u00f8nsker \u00e5 laste ned dette volumet +message.enable.user=Vennligst bekreft at du \u00f8nsker \u00e5 aktivere denne bruker. message.enable.vpn=Vennligst bekreft at du \u00f8nsker \u00e5 aktivere VPN-tilgang for denne IP-adressen message.enabling.zone=Aktiverer sonen message.enter.token=Vennligst skriv inn koden du fikk i invitasjonsmailen. +message.generate.keys=Vennligst bekreft at du \u00f8nsker \u00e5 generere nye n\u00f8kler for denne bruker. message.installWizard.click.retry=Klikk p\u00e5 knappen for \u00e5 pr\u00f8ve oppstart p\u00e5 nytt. message.installWizard.tooltip.addCluster.name=Klyngenavnet. Dette kan v\u00e6re hva som helst og er ikke benyttet av CloudStack. message.installWizard.tooltip.addHost.hostname=DNS-navnet eller IP-adressen til verten. @@ -311,6 +1037,8 @@ message.iso.desc=Diskimage som inneholder data etter oppstartsbar media for OS message.join.project=Du har n\u00e5 deltatt i et prosjekt. Vennligst bytt til prosjektvisning for \u00e5 se prosjektet. message.migrate.instance.to.host=Vennligst bekreft at du \u00f8nsker \u00e5 migrere instansen til en annen vert. message.migrate.instance.to.ps=Vennligst bekreft at du \u00f8nsker \u00e5 migrere instansen til en annen sekund\u00e6r lagring. +message.migrate.router.confirm=Vennligst bekreft verten du \u00f8nsker \u00e5 migrere ruteren til\: +message.migrate.systemvm.confirm=Vennligst bekreft verten du \u00f8nsker \u00e5 migrere system VM til\: message.migrate.volume=Vennligst bekreft at du \u00f8nsker \u00e5 migrere volumet til en annen prim\u00e6rlagring. message.no.projects.adminOnly=Du har ingen prosjekter.
Vennligst be din administrator om \u00e5 opprette et nytt prosjekt. message.no.projects=Du har ingen prosjekter.
Vennligst opprett et nytt fra prosjektseksjonen. @@ -323,17 +1051,28 @@ message.please.select.a.different.public.and.management.network.before.removing= message.please.select.networks=Vennligst velg nettverk for din VM message.please.wait.while.zone.is.being.created=Vennlist vent mens din sone opprettes. Dette kan ta noe tid... message.project.invite.sent=Invitasjon sendt til bruker. De vil bli lagt til prosjektet s\u00e5 snart de har akseptert invitasjonen +message.remove.region=Er du sikker p\u00e5 at du vil fjerne denne regionen fra denne administrasjonsserveren? +message.remove.vpc=Vennligst bekreft at du \u00f8nsker \u00e5 fjerne VPC message.reset.password.warning.notPasswordEnabled=Denne malen vil bli opprettet uten passord message.reset.password.warning.notStopped=Din instans m\u00e5 stoppes f\u00f8r man fors\u00f8ker \u00e5 bytte n\u00e5v\u00e6rende passord +message.reset.VPN.connection=Vennligst bekreft at du \u00f8nsker \u00e5 resette VPN-tilkobling +message.restart.mgmt.server=Vennlist restart administrajonsserveren(e) din(e) for at de nye innstillingene skal tr\u00e5 i kraft. +message.restart.vpc=Vennligst bekreft at du \u00f8nsker \u00e5 restarte VPC +message.select.instance=Vennligst velg en instans. message.select.iso=Vennligst velg en ISO for din nye virtuelle instans. message.select.item=Vennligst velg et element message.select.security.groups=Vennligst velg sikkerhetsgruppe(r) for din nye VM message.select.template=Vennligst velg en mal for din nye virtuelle instans. message.setup.successful=Oppsettet av nettskyen er vellykket\! +message.specify.url=Vennligst spesifiser URL message.step.2.desc= message.step.3.desc= message.suspend.project=Er du sikker du \u00f8nsker \u00e5 pause dette prosjektet? message.template.desc=OS-image som kan brukes til \u00e5 starte VMer +message.tooltip.pod.name=Et navn for denne pod. +message.tooltip.zone.name=Et navn for denne sonen. +message.validate.invalid.characters=Ugyldige tegn funnet; vennligst korriger. +message.vm.create.template.confirm=Oppretting av Mal vil restarte VM automatisk. message.vm.review.launch=Vennligst vurder f\u00f8lgende informasjon og bekreft at din virtuelle instans er korrekt f\u00f8r kj\u00f8ring message.you.must.have.at.least.one.physical.network=Du trenger minst ett fysisk nettverk message.Zone.creation.complete=Opprettelsen av sonen utf\u00f8rt @@ -345,6 +1084,7 @@ notification.stop.instance=Stopp instans state.Accepted=Akseptert state.Active=Aktiv state.Allocated=Allokert +state.Allocating=Allokerer state.BackedUp=Sikkerhetskopiert state.BackingUp=Sikkerhetskopierer state.Completed=Utf\u00f8rt @@ -352,14 +1092,18 @@ state.Creating=Oppretter state.Declined=Avvist state.Destroyed=Destruert state.Disabled=Inaktiv +state.enabled=Aktivert +state.Enabled=Aktivert state.Error=Feil state.Expunging=Fjerner +state.Migrating=Migrering state.Pending=Venter state.ready=Klar state.Ready=Klar state.Running=Kj\u00f8rer state.Starting=Starter state.Stopped=Stoppet +state.Stopping=Stopper state.Suspended=Pauset ui.listView.filters.all=Alle ui.listView.filters.mine=Mine diff --git a/client/WEB-INF/classes/resources/messages_nl_NL.properties b/client/WEB-INF/classes/resources/messages_nl_NL.properties index 5d666a4fb4..54c78e30e5 100644 --- a/client/WEB-INF/classes/resources/messages_nl_NL.properties +++ b/client/WEB-INF/classes/resources/messages_nl_NL.properties @@ -18,6 +18,7 @@ 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.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 @@ -42,14 +43,20 @@ ICMP.type=ICMP Type image.directory=Afbeelding Directory inline=Inline instances.actions.reboot.label=Herstart instantie +label.about.app=Over CloudStack +label.about=Over label.accept.project.invitation=Accepteer project uitnodiging label.account=Account label.account.and.security.group=Account, Security group label.account.id=Account ID +label.account.lower=account label.account.name=Account Naam label.accounts=Accounts label.account.specific=Account-specifiek +label.acl=ACL label.acquire.new.ip=Bemachtig nieuw IP +label.acquire.new.secondary.ip=Verkrijg nieuw secundair IP +label.action=Actie label.action.attach.disk.processing=Schijf wordt toegevoegd.... label.action.attach.disk=Schijf toevoegen label.action.attach.iso=ISO toevoegen @@ -92,6 +99,7 @@ label.action.delete.load.balancer=Verwijder load balancer regel label.action.delete.network.processing=Bezig met verwijderen van Netwerk.... label.action.delete.network=Verwijder Netwerk label.action.delete.nexusVswitch=Verwijder Nexus 1000v +label.action.delete.nic=Verwijder netwerkkaart label.action.delete.physical.network=Verwijder fysiek netwerk label.action.delete.pod.processing=Bezig met verwijderen van Pod.... label.action.delete.pod=Verwijder Pod @@ -173,6 +181,8 @@ label.action.enable.user=Activeer Gebruiker label.action.enable.user.processing=Bezig met activeren van Gebruiker.... label.action.enable.zone=Activeer Zone label.action.enable.zone.processing=Bezig met activeren van Zone.... +label.action.expunge.instance.processing=Opruimen Instantie.... +label.action.expunge.instance=Ruim instantie op label.action.force.reconnect=Forceer opnieuw verbinden label.action.force.reconnect.processing=Bezig met opnieuw verbinden.... label.action.generate.keys=Genereer Sleutels @@ -208,6 +218,8 @@ label.action.resize.volume=Wijzig de grootte van het volume label.action.resource.limits=Verbruikslimieten label.action.restore.instance=Herstel Instantie label.action.restore.instance.processing=Bezig met herstellen van Instantie.... +label.action.revert.snapshot=Draai terug naar snapshot +label.action.revert.snapshot.processing=Terugdraaien naar snapshot... label.actions=Acties label.action.start.instance.processing=Bezig met starten van Instantie.... label.action.start.instance=Start Instantie @@ -239,6 +251,8 @@ label.add.accounts=Voeg accounts toe label.add.account.to.project=Voeg account aan project toe label.add.account=Voeg Account toe label.add.ACL=Voeg ACL toe +label.add.affinity.group=Nieuwe affinity groep toevoegen +label.add.baremetal.dhcp.device=Voeg Baremetal DHCP Apparaat toe label.add.BigSwitchVns.device=Voeg BigSwitch Vns Controller toe label.add.by.cidr=Voeg toe door middel van CIDR label.add.by.group=Voeg toe door middel van Groep @@ -248,9 +262,12 @@ label.add.compute.offering=Voeg Compute aanbieding toe label.add.direct.iprange=Voeg Direct IP Range toe label.add.disk.offering=Voeg Schijf Aanbieding toe label.add.domain=Voeg Domein toe +label.added.new.bigswitch.vns.controller=Nieuwe BigSwitch VNS Controller toegevoegd label.add.egress.rule=Voeg uitgaande regel toe +label.addes.new.f5=Nieuwe F5 toegevoegd label.add.F5.device=Voeg F5 apparaat toe label.add.firewall=Voeg firewall regel toe +label.add.gslb=GSLB Toevoegen label.add.guest.network=Gast netwerk toevoegen label.add.host=Host toevoegen label.adding.cluster=Bezig met toevoegen van Cluster @@ -263,6 +280,7 @@ label.adding=Toevoegen label.adding.user=Bezig met toevoegen van Gebruiker label.adding.zone=Bezig met toevoegen van Zone label.add.ip.range=Voeg IP range toe +label.add.isolated.network=Geisoleerd Netwerk Toevoegen label.additional.networks=Additioneele Netwerken label.add.load.balancer=Voeg Load Balancer toe label.add.more=Voeg meer toe @@ -274,11 +292,16 @@ label.add.network=Voeg Netwerk toe label.add.new.F5=Voeg nieuwe F5 toe label.add.new.gateway=Voeg nieuwe gateway toe label.add.new.NetScaler=Voeg nieuwe Netscaler toe +label.add.new.PA=Nieuwe Palo Alto toevoegen label.add.new.SRX=Voeg nieuwe SRX toe label.add.new.tier=Voeg nieuwe Tier toe +label.add.nfs.secondary.staging.store=Secundaire Staging Opslag toevoegen label.add.NiciraNvp.device=Voeg NVP Controller toe +label.add.OpenDaylight.device=OpenDaylight Controller toevoegen +label.add.PA.device=Nieuw Palo Alto apparaat toevoegen label.add.physical.network=Voeg fysiek netwerk toe label.add.pod=Voeg Pod toe +label.add.portable.ip.range=Porteerbare IP Range toevoegen label.add.port.forwarding.rule=Voeg port forwarding regel toe label.add.primary.storage=Voeg Primaire Opslag toe label.add.region=Voeg Regio toe @@ -294,24 +317,33 @@ label.add.static.route=Statische route toevoegen label.add.system.service.offering=Systeem Service Aanbieding toevoegen label.add.template=Template toevoegen label.add.to.group=Toevoegen aan groep +label.add.ucs.manager=UCS Manager toevoegen label.add.user=Gebruiker toevoegen label.add.vlan=VLAN toevoegen label.add.vms.to.lb=Voeg VM(s) toe aan load balancer regel label.add.vms=VMs toevoegen label.add.VM.to.tier=Voeg VM toe aan tier label.add.vm=VM toevoegen +label.add.vmware.datacenter=VMware datacenter toevoegen +label.add.vnmc.device=VNMC apparaat toevoegen +label.add.vnmc.provider=VNMC provider toevoegen label.add=Voeg toe label.add.volume=Volume toevoegen +label.add.vpc.offering=VPC Aanbieding toevoegen label.add.vpc=VPC toevoegen label.add.vpn.customer.gateway=VPN Customer Gateway toevoegen label.add.VPN.gateway=VPN Gateway toevoegen label.add.vpn.user=VPN gebruiker toevoegen +label.add.vxlan=VXLAN toevoegen label.add.zone=Zone toevoegen label.admin.accounts=Beheer Accounts label.admin=Beheerder label.advanced=Geavanceerd label.advanced.mode=Geavanceerde Modus label.advanced.search=Geavanceerd zoeken +label.affinity=Affinity +label.affinity.group=Affinity Groep +label.affinity.groups=Affinity Groepen label.agent.password=Agent wachtwoord label.agent.username=Agent Gebruikersnaam label.agree=Accepteren @@ -319,32 +351,57 @@ label.alert=Alarm label.algorithm=Algoritme label.allocated=Gebruikt label.allocation.state=Verbruik Staat +label.allow=Toestaan +label.anti.affinity=Anti-affinity +label.anti.affinity.group=Anti-affinity Groep +label.anti.affinity.groups=Anti-affinity Groepen label.api.key=API Sleutel label.apply=Uitvoeren +label.app.name=CloudStack +label.archive.alerts=Archiveer waarschuwingen +label.archive.events=Archiveer evenementen +label.assign.instance.another=Wijs instantie toe aan een andere Account label.assign=Toevoegen label.assign.to.load.balancer=Voeg instantie toe aan load balancer label.associated.network=Bijbehorend Netwerk label.associated.network.id=Bijbehorend Netwerk ID +label.associated.profile=Bijbehorend Profiel +label.associate.public.ip=Associeers Publiek IP label.attached.iso=Gekoppelde ISO label.author.email=Auteur e-mail label.author.name=Auteur naam +label.autoscale=Automatisch Schalen label.availability=Beschikbaarheid label.availability.zone=Beschikbaarheids-zone label.available=Beschikbaar label.available.public.ips=Beschikbare Publieke IP adressen label.back=Terug label.bandwidth=Bandbreedte +label.baremetal.dhcp.devices=Baremetal DHCP Apparten +label.baremetal.dhcp.provider=Baremetal DHCP Provider +label.baremetal.pxe.devices=Baremetal DHCP Apparaten +label.baremetal.pxe.device=Voeg Baremetal PXE Apparaat toe +label.baremetal.pxe.provider=Baremetal PXE Provider label.basic=Basis label.basic.mode=Basis Modus label.bigswitch.controller.address=BigSwitch Vns Controller Adres +label.bigswitch.vns.details=BigSwitch VNS details +label.blade.id=Blade ID +label.blades=Blades label.bootable=Bootable label.broadcast.domain.range=Broadcast domain range label.broadcast.domain.type=Broadcast Domain Type label.broadcast.uri=Broadcast URI +label.broadcasturi=broadcasturi +label.broadcat.uri=broadcast URI label.by.account=Op Account +label.by.alert.type=Op alarm type label.by.availability=Op Beschikbaarheid +label.by.date.end=Op datum (eind) +label.by.date.start=Op datum (start) label.by.domain=Op Domein label.by.end.date=Op Eind Datum +label.by.event.type=Op gebeurtenis type label.by.level=Op Level label.by.pod=Op Pod label.by.role=Op Rol @@ -356,18 +413,25 @@ label.by.traffic.type=Op Verkeerstype label.by.type.id=Op Type ID label.by.type=Op Type label.by.zone=Op Zone +label.cache.mode=Schrijf cache Type label.cancel=Annuleer label.capacity=Capaciteit label.certificate=Certificaat +label.change.affinity=Wijzig Affinity label.change.service.offering=Wijzig service aanbieding label.change.value=Wijzig waarde label.character=Karakter +label.chassis=Chassis label.checksum=MD5 checksum label.cidr.account=CIDRN of Account/Security Group label.cidr=CIDR label.cidr.list=Bron CIDR label.CIDR.list=CIDR lijst label.CIDR.of.destination.network=CIDR van bestemmingsnetwerk +label.cisco.nexus1000v.ip.address=Nexus 1000v IP Adres +label.cisco.nexus1000v.password=Nexus 1000v Wachtwoord +label.cisco.nexus1000v.username=Nexus 1000v Gebruikersnaam +label.ciscovnmc.resource.details=CiscoVNMC resource details label.clean.up=Opschonen label.clear.list=Schoon lijst op label.close=Sluiten @@ -383,8 +447,10 @@ label.community=Community label.compute.and.storage=Compute en Opslag label.compute=Compute label.compute.offering=Compute aanbieding +label.compute.offerings=Compute aanbiedingen label.configuration=Configuratie label.configure=Configureer +label.configure.ldap=Configureer LDAP label.configure.network.ACLs=Configureer Netwerk ACLs label.configure.vpc=Configureer VPC label.confirmation=Bevestiging @@ -392,6 +458,7 @@ label.confirm.password=Bevestig wachtwoord label.congratulations=Gefeliciteerd\! label.conserve.mode=Conserveer modus label.console.proxy=Console proxy +label.console.proxy.vm=Console Proxy VM label.continue.basic.install=Ga door met basis installatie label.continue=Ga door label.corrections.saved=Correcties opgeslagen @@ -404,29 +471,52 @@ label.cpu.mhz=CPU (in MHz) label.cpu.utilized=CPU Verbruik label.created=Aangemaakt label.created.by.system=Aangemaakt door systeem +label.create.nfs.secondary.staging.storage=Creeer NFS staging secudaire opslag +label.create.nfs.secondary.staging.store=Creeer NFS staging secudaire opslag label.create.project=Nieuw project label.create.template=Nieuwe template label.create.VPN.connection=Nieuwe VPN connectie label.cross.zones=Over Zones +label.custom=Aangepast +label.custom.disk.iops=Aangepaste IOPS label.custom.disk.size=Vrije schijf grootte label.daily=Dagelijkse label.data.disk.offering=Data Schijf Aanbieding label.date=Datum label.day.of.month=Dag van de Maand label.day.of.week=Dag van de Week +label.dc.name=DC Naam label.dead.peer.detection=Dead Peer detectie label.decline.invitation=Sla uitnodiging af -label.dedicated=Dedicated +label.dedicate.cluster=Cluster toewijden +label.dedicated=Toegewijd +label.dedicated.vlan.vni.ranges=Toegewijde VLAN/VNI Ranges +label.dedicate.host=Host Toewijden +label.dedicate.pod=Pod toewijden +label.dedicate=Toewijden +label.dedicate.vlan.vni.range=Toegewijde VLAN/VNI Range +label.dedicate.zone=Zone toewijden +label.default.egress.policy=Standaard Uitgaande policy label.default=Standaard label.default.use=Standaard Gebruik label.default.view=Standaard Weergave +label.delete.affinity.group=Verwijder Affinity Groep +label.delete.alerts=Verwijder waarschuwingen label.delete.BigSwitchVns=Verwijder BigSwitch Vns Controller +label.delete.ciscovnmc.resource=CiscoVNMC resource verwijderen +label.delete.events=Verwijder gebeurtenissen label.delete.F5=Verwijder F5 label.delete.gateway=Verwijder gateway label.delete.NetScaler=Verwijder NetScaler label.delete.NiciraNvp=Verwijder Nvp Controller +label.delete.OpenDaylight.device=OpenDaylight Controller verwijderen +label.delete.PA=Verwijder Palo Alto +label.delete.portable.ip.range=Porteerbare IP Range verwijderen +label.delete.profile=Profiel Verwijderen label.delete.project=Verwijder project +label.delete.secondary.staging.store=Secundaire Staging Opslag verwijderen label.delete.SRX=Verwijder SRX +label.delete.ucs.manager=Verwijder UCS Manager label.delete=Verwijder label.delete.VPN.connection=Verwijder VPN connectie label.delete.VPN.customer.gateway=Verwijder VPN Customer Gateway @@ -434,11 +524,14 @@ label.delete.VPN.gateway=Verwijder VPN Gateway label.delete.vpn.user=Verwijder VPN gebruiker label.deleting.failed=Verwijderen Mislukt label.deleting.processing=Verwijderen.... +label.deny=Weigeren +label.deployment.planner=Deployment planner label.description=Beschrijving label.destination.physical.network.id=Bestemming fysiek netwerk ID label.destination.zone=Bestemmingszone label.destroy.router=Verwijder router label.destroy=Verwijder +label.destroy.vm.graceperiod=Respijt periode verwijderde VM label.detaching.disk=Ontkoppelen Schijf label.details=Details label.device.id=Apparaat ID @@ -446,18 +539,36 @@ label.devices=Apparaten label.dhcp=DHCP label.DHCP.server.type=DHCP Server Type label.direct.ips=Shared Netwerk IPs +label.disable.autoscale=Autoscale uitschakelen label.disabled=Uitgeschakeld +label.disable.network.offering=Netwerk Aanbieding Uitschakelen label.disable.provider=Provider uitschakelen +label.disable.vnmc.provider=VNMC provider uitschakelen +label.disable.vpc.offering=VPC aanbieding uitschakelen label.disable.vpn=VPN uitschakelen label.disabling.vpn.access=Uitschakelen van VPN Toegang +label.disassociate.profile.blade=Ontkoppel Profiel van Blade +label.disbale.vnmc.device=VNMC apparaat uitschakelen label.disk.allocated=Schijfruimte gealloceerd +label.disk.bytes.read.rate=Lees Snelheid Schijf (BPS) +label.disk.bytes.write.rate=Schrijf Snelheid Schijf (BPS) +label.disk.iops.max=Max IOPS +label.disk.iops.min=Min IOPS +label.disk.iops.read.rate=Lees Snelheid Schijf (IOPS) +label.disk.iops.total=IOPS Totaal +label.disk.iops.write.rate=Schrijf snelheid Schijf (IOPS) label.disk.offering=Schijf Aanbieding +label.disk.read.bytes=Schijf lezen (Bytes) +label.disk.read.io=Schijf Lezen (IO) label.disk.size.gb=Schijf Grootte (in GB) label.disk.size=Schijf Grootte label.disk.total=Schijf Totaal label.disk.volume=Schijf Volume +label.disk.write.bytes=Schijf Schrijven (Bytes) +label.disk.write.io=Schijf Schrijven (IO) label.display.name=Weergavenaam label.display.text=Weergavetekst +label.distributedrouter=Gedistribueerde Router label.dns.1=DNS 1 label.dns.2=DNS 2 label.dns=DNS @@ -465,6 +576,7 @@ label.DNS.domain.for.guest.networks=DNS domein voor Gast Netwerken label.domain.admin=Domein Beheerder label.domain=Domein label.domain.id=Domein ID +label.domain.lower=domein label.domain.name=Domeinnaam label.domain.router=Domein router label.domain.suffix=DNS domein achtervoegsel (v.b., xyz.com) @@ -472,22 +584,32 @@ label.done=Klaar label.double.quotes.are.not.allowed=Aanhalingstekens zijn hier niet toegestaan label.download.progress=Download Voortgang label.drag.new.position=Sleep naar nieuwe positie +label.dynamically.scalable=Dynamisch Schaalbaar +label.edit.affinity.group=Wijzig Affinity Groep label.edit.lb.rule=Wijzig LB regel label.edit.network.details=Wijzig netwerk details label.edit.project.details=Wijzig project details +label.edit.region=Wijzig Regio label.edit.tags=Wijzig tags label.edit.traffic.type=Wijzig traffic type label.edit.vpc=Wijzig VPC label.edit=Wijzig +label.egress.default.policy=Standaard uitgaande policy label.egress.rules=Uitgaande regels label.egress.rule=Uitgaande regel label.elastic=Elastisch label.elastic.IP=Elastisch IP label.elastic.LB=Elastisch LB label.email=Email +label.email.lower=email +label.enable.autoscale=Autoscale inschakelen +label.enable.network.offering=Netwerk Aanbieding Inschakelen label.enable.provider=Provider inschakelen label.enable.s3=S3-gebaseerde Secondary Storage inschakelen label.enable.swift=Swift inschakelen +label.enable.vnmc.device=VNMC appraat inschakelen +label.enable.vnmc.provider=VNMC provider inschakelen +label.enable.vpc.offering=VPC aanbieding inschakelen label.enable.vpn=VPN inschakelen label.enabling.vpn.access=VPN toegang inschakelen label.enabling.vpn=VPN inschakelen @@ -497,6 +619,7 @@ label.endpoint.or.operation=Endpoint or Operation label.end.port=Eind Poort label.end.reserved.system.IP=Einde gereserveerde systeem IP label.end.vlan=Einde Vlan +label.end.vxlan=Eind Vxlan label.enter.token=Voer token in label.error.code=Fout code label.error=Fout @@ -506,13 +629,16 @@ label.ESP.lifetime=ESP Lifetime (secondes) label.ESP.policy=ESP policy label.esx.host=ESX/ESXi Host label.example=Voorbeeld +label.expunge=Ruim op label.external.link=Externe link +label.f5.details=F5 details label.f5=F5 label.failed=Mislukt label.featured=Voorgesteld label.fetch.latest=Haal laatste op label.filterBy=Filter per label.firewall=Firewall +label.firstname.lower=voornaam label.first.name=Voornaam label.format=Formaat label.friday=Vrijdag @@ -521,12 +647,30 @@ label.full=Volledig label.gateway=Gateway label.general.alerts=Algemene Waarschuwingen label.generating.url=Generen van URL +label.gluster.volume=Volume label.go.step.2=Ga naar Stap 2 label.go.step.3=Ga naar Stap 3 label.go.step.4=Ga naar Stap 4 label.go.step.5=Ga naar Stap 5 +label.gpu=CPU +label.group.by.account=groepeer per account +label.group.by.cluster=groepeer per cluster +label.group.by.pod=groepeer per pod +label.group.by.zone=groepeer per zone label.group=Groep label.group.optional=Groep (Optioneel) +label.gslb.assigned.lb.more=Wijs meer load balancing toe +label.gslb.assigned.lb=toegewezen load balancing +label.gslb.delete=GSLB verwijderen +label.gslb.details=GSLB details +label.gslb.domain.name=GSLB Domein Naam +label.gslb.lb.details=load balancing details +label.gslb.lb.remove=verwijder load balancing van deze GSLB +label.gslb.lb.rule=load balancing regel +label.gslb.service=GSLB service +label.gslb.service.private.ip=GSLB service Private IP +label.gslb.service.public.ip=GSLB service Publiek IP +label.gslb.servicetype=Service Type label.guest.cidr=Gast CIDR label.guest.end.ip=Gast eind IP label.guest=Gast @@ -534,14 +678,19 @@ label.guest.gateway=Gast Gateway label.guest.ip=Gast IP Adres label.guest.ip.range=Gast IP range label.guest.netmask=Gast Netmask +label.guest.network.details=Gast netwerk details label.guest.networks=Gast netwerken label.guest.start.ip=Gast start IP label.guest.traffic=Gast verkeer +label.guest.traffic.vswitch.name=vSwitch Gast Verkeer Naam +label.guest.traffic.vswitch.type=vSwitch Gast Verkeer Type label.guest.type=Gast Type label.ha.enabled=HA ingeschakeld +label.health.check=Health Check label.help=Help label.hide.ingress.rule=Verberg Inkomende Regel label.hints=Tips +label.home=Home label.host.alerts=Host Waarschuwingen label.host=Host label.host.MAC=Host MAC @@ -551,8 +700,11 @@ label.host.tags=Host Tags label.hourly=Uurlijks label.hypervisor.capabilities=Hypervisor mogelijkheden label.hypervisor=Hypervisor +label.hypervisors=Hypervisors +label.hypervisor.snapshot.reserve=Hypervisor Snapshot Reserve label.hypervisor.type=Hypervisor Type label.hypervisor.version=Hypervisor versie +label.hyperv.traffic.label=HyperV verkeerslabel label.id=ID label.IKE.DH=IKE DH label.IKE.encryption=IKE Encryptie @@ -581,7 +733,9 @@ label.installWizard.title=Hallo en welkom bij CloudStack&\#8482 label.instance=Instantie label.instance.limits=Instantie Limieten label.instance.name=Instantie Naam +label.instance.scaled.up=Instantie Omhoog Geschaald label.instances=Instanties +label.instanciate.template.associate.profile.blade=Initieer Template en verbind Profiel met Blade label.internal.dns.1=Interne DNS 1 label.internal.dns.2=Interne DNS 2 label.internal.name=Interne naam @@ -603,6 +757,18 @@ label.ip.range=IP Range label.ip.ranges=IP Ranges label.IPsec.preshared.key=IPsec Preshared-Key label.ips=IPs +label.ipv4.cidr=IPv4 CIDR +label.ipv4.end.ip=IPv4 Eind IP +label.ipv4.gateway=IPv4 Gateway +label.ipv4.netmask=IPv4 Netmask +label.ipv4.start.ip=IPv4 Begin IP +label.ipv6.address=IPv6 IP Address +label.ipv6.CIDR=IPv6 CIDR +label.ipv6.dns1=IPv6 DNS1 +label.ipv6.dns2=IPv6 DNS2 +label.ipv6.end.ip=IPv6 Eind IP +label.ipv6.gateway=IPv6 Gateway +label.ipv6.start.ip=IPv6 Begin IP label.iscsi=iSCSI label.is.default=Is Standaard label.iso.boot=ISO Boot @@ -620,23 +786,35 @@ label.keyboard.type=Toetsenbord type label.key=Sleutel label.kvm.traffic.label=KVM verkeer label label.label=Label +label.lang.arabic=Arabisch label.lang.brportugese=Braziliaans Portgees +label.lang.catalan=Catalaans label.lang.chinese=Chinees (Simplified) +label.lang.dutch=Nederlands (Nederlands) label.lang.english=Engels label.lang.french=Frans +label.lang.german=Duits +label.lang.italian=Italiaans label.lang.japanese=Japans label.lang.korean=Koreans +label.lang.norwegian=Noors +label.lang.polish=Pools label.lang.russian=Russisch label.lang.spanish=Spaans label.last.disconnected=Laatse keer niet verbonden label.last.name=Achternaam +label.lastname.lower=achternaam label.latest.events=Laatste gebeurtenissen label.launch=Lanceer label.launch.vm=Lanceer VM label.launch.zone=Lanceer zone label.LB.isolation=LB isolatie +label.ldap.configuration=LDAP Configuratie +label.ldap.group.name=LDAP Groep +label.ldap.port=LDAP poort label.least.connections=Minste connecties label.level=Level +label.linklocal.ip=Link Local IP Adres label.load.balancer=Load Balancer label.load.balancing=Load Balancing label.load.balancing.policies=Load balancing policies @@ -648,6 +826,7 @@ label.login=Login label.logout=Log uit label.lun=LUN label.LUN.number=LUN \# +label.lxc.traffic.label=LXC verkeerslabel label.make.project.owner=Maak account project eigenaar label.manage=Beheer label.management=Beheer @@ -656,6 +835,7 @@ label.manage.resources=Beheer Resources label.max.cpus=Max. CPU cores label.max.guest.limit=Max. Instanties label.maximum=Maximaal +label.max.instances=Max Instances label.max.memory=Max. geheugen (MiB) label.max.networks=Max. netwerken label.max.primary.storage=Max. primare opslag (GiB) @@ -713,16 +893,20 @@ label.menu.templates=Templates label.menu.virtual.appliances=Virtueele Appliances label.menu.virtual.resources=Virtuele Resources label.menu.volumes=Volumes +label.menu.vpc.offerings=VPC Aanbiedingen label.migrate.instance.to.host=Migreer instantie naar andere host label.migrate.instance.to=Migreer instantie naar label.migrate.instance.to.ps=Migreer instantie naar andere primaire opslag +label.migrate.lb.vm=Migreer LB VM label.migrate.router.to=Migreer Router naar label.migrate.systemvm.to=Migreer Systeem VM naar label.migrate.to.host=Migreer naar host label.migrate.to.storage=Migreer naar opslag label.migrate.volume=Migreer volume naar andere primaire opslag label.minimum=Minimum +label.min.instances=Min Instances label.minute.past.hour=Minuten na het uur +label.mode=Modus label.monday=Maandag label.monthly=Maandelijks label.more.templates=Meer Templates @@ -733,14 +917,18 @@ label.move.up.row=Verplaats \u00e9\u00e9n regel naar boven label.my.account=Mijn Account label.my.network=Mijn netwerk label.my.templates=Mijn templates +label.name.lower=naam label.name=Naam label.name.optional=Naam (Optioneel) label.nat.port.range=NAT Poort Range label.netmask=Netmask +label.netscaler.details=NetScaler details label.netScaler=NetScaler label.network.ACL=Netwerk ACL label.network.ACLs=Netwerk ACLs label.network.ACL.total=Netwerk ACL Totaal +label.network.addVM=Voeg netwerk toe aan VM +label.network.cidr=Network CIDR label.network.desc=Netwerk Beschr. label.network.device=Netwerk Apparaat label.network.device.type=Netwerk Apparaat Type @@ -749,12 +937,15 @@ label.network.domain.text=Netwerk Domein label.network.id=Netwerk ID label.networking.and.security=Netwerken en beveiliging label.network.label.display.for.blank.value=Gebruik standaard gateway +label.network.limits=Netwerk limieten label.network.name=Netwerk Naam label.network=Netwerk label.network.offering.display.text=Netwerk Aanbieding Weergave Tekst label.network.offering.id=Netwerk Aanbieding ID label.network.offering.name=Netwerk Aanbieding Naam label.network.offering=Netwerk Aanbieding +label.network.rate.megabytes=Netwerk Snelheid (MB/s) +label.network.rate=Netwerk Snelheid (Mb/s) label.network.read=Netwerk gelezen label.network.service.providers=Netwerk Service Aanbieders label.networks=Netwerken @@ -778,6 +969,7 @@ label.no.actions=Geen Beschikbare Acties label.no.alerts=Geen Recente Waarschuwingen label.no.data=Geen data om weer te geven label.no.errors=Geen Recente Fouten +label.no.grouping=(Geen groepering) label.no.isos=Geen beschikbare ISOs label.no.items=Geen Beschikbare Items label.no=Nee @@ -787,6 +979,7 @@ label.not.found=Niet gevonden label.no.thanks=Nee bedankt label.notifications=Notificaties label.number.of.clusters=Aantal Clusters +label.number.of.cpu.sockets=Het aantal CPU sockets label.number.of.hosts=Aantal Hosts label.number.of.pods=Aantal Pods label.number.of.system.vms=Aantal Systeem VMs @@ -797,33 +990,55 @@ label.numretries=Keren opnieuw geprorbeerd label.ocfs2=OCFS2 label.offer.ha=HA aanbieden label.ok=OK +label.opendaylight.controllerdetail=OpenDaylight Controller Details +label.opendaylight.controller=OpenDaylight Controller +label.opendaylight.controllers=OpenDaylight Controllers +label.openDaylight=OpenDaylight label.optional=Optioneel label.order=Volgorde label.os.preference=OS Voorkeur label.os.type=OS Type +label.override.guest.traffic=Overschrijf Gast Verkeer +label.override.public.traffic=Overschrijf Publiek Verkeer +label.ovm.traffic.label=OVM verkeerslabel +label.ovs=OVS label.owned.public.ips=Publieke IP Adressen in beheer label.owner.account=Account Eigenaar label.owner.domain=Domein Eigenaar +label.palo.alto.details=Palo Alto details +label.PA.log.profile=Palo Alto Log Profiel +label.PA=Palo Alto label.parent.domain=Bovenliggend Domein label.password.enabled=Wachtwoord Ingeschakeld +label.password.lower=wachtwoord +label.password.reset.confirm=Het wachtwoord is gereset naar label.password=Wachtwoord label.path=Pad +label.PA.threat.profile=Palo Alto Threat Profiel label.perfect.forward.secrecy=Perfect Forward Secrecy +label.persistent=Persistent label.physical.network=Fysiek Netwerk label.physical.network.ID=Fysiek netwerk ID label.PING.CIFS.password=PING CIFS wachtwoord label.PING.CIFS.username=PING CIFS gebruikersnaam label.PING.dir=PING Directory label.PING.storage.IP=PING opslag IP +label.planner.mode=Planner modus label.please.specify.netscaler.info=Geef hier informatie van de Netscaler op label.please.wait=Een ogenblik geduld a.u.b. label.plugin.details=Plugin details label.plugins=Plugins +label.pod.dedicated=Pod toegewijd label.pod.name=Pod Naam label.pod=Pod label.pods=Pods +label.polling.interval.sec=Polling Interval (in sec) +label.portable.ip.range.details=Porteerbare IP Range details +label.portable.ip.ranges=Porteerbare IP Ranges +label.portable.ips=Porteerbare IPs label.port.forwarding.policies=Port forwarding policies label.port.forwarding=Port Forwarding +label.port=Poort label.port.range=Port Range label.PreSetup=PreSetup label.previous=Vorige @@ -843,6 +1058,7 @@ label.privatekey=PKCS\#8 Private Key label.private.network=Priv\u00e9 Netwerk label.private.port=Priv\u00e9 Port label.private.zone=Priv\u00e9 Zone +label.profile=Profiel label.project.dashboard=Project Dashboard label.project.id=Project ID label.project.invite=Nodig uit voor project @@ -851,32 +1067,57 @@ label.project=Project label.projects=Projecten label.project.view=Project Weergave label.protocol=Protocol +label.provider=Provider label.providers=Providers label.public.interface=Publieke Interface label.public.ip=Publiek IP Adres label.public.ips=Publieke IP Adressen +label.public.load.balancer.provider=Publieke Load Balancer Provider label.public.network=Publiek netwerk label.public.port=Publieke Poort label.public=Publiek label.public.traffic=Publiek verkeer +label.public.traffic.vswitch.name=vSwitch Publiek Verkeer Naam +label.public.traffic.vswitch.type=vSwitch Publiek Verkeer Type label.public.zone=Publieke Zone label.purpose=Doel label.Pxe.server.type=PXE Server Type +label.qos.type=QoS Type label.quickview=Sneloverzicht +label.quiesce.vm=Quiesce VM +label.quiet.time.sec=Quiet Time (in sec) +label.rbd.id=Cephx gebruiker +label.rbd.monitor=Ceph monitor +label.rbd.pool=Ceph pool +label.rbd=RBD +label.rbd.secret=Cephx secret label.reboot=Reboot label.recent.errors=Recente Fouten +label.recover.vm=Herstel VM label.redundant.router.capability=Redundante router mogelijkheden label.redundant.router=Redundante Router label.redundant.state=Redundante staat +label.refresh.blades=Ververs Blades label.refresh=Ververs +label.regionlevelvpc=Region Level VPC label.region=Regio +label.reinstall.vm=Herinstalleer VM label.related=Samenhangend +label.release.account.lowercase=ontkoppel van account +label.release.account=Ontkoppel van Account +label.release.dedicated.cluster=Toegewijd Cluster loskoppelen +label.release.dedicated.host=Toegewijde Host ontkoppelen +label.release.dedicated.pod=Toegewijde Pod loskoppelen +label.release.dedicated.vlan.range=Toegewijde VLAN range ontkoppelen +label.release.dedicated.zone=Toegewijde zone ontkoppelen label.remind.later=Herinner me later label.remove.ACL=Verwijder ACL label.remove.egress.rule=Verwijder uitgaande regel label.remove.from.load.balancer=Verwijder Instantie van load balancer label.remove.ingress.rule=Verwijder inkomende regel label.remove.ip.range=Verwijder IP range +label.remove.ldap=Verwijder LDAP +label.remove.network.offering=Netwerk Aanbieding Verwijderen label.remove.pf=Verwijder port forwarding regel label.remove.project.account=Verwijder account van project label.remove.region=Verwijder Regio @@ -885,18 +1126,25 @@ label.remove.static.nat.rule=Verwijder static NAT regel label.remove.static.route=Verwijder statische route label.remove.tier=Verwijder tier label.remove.vm.from.lb=Verwijder VM van load balancer regel +label.remove.vmware.datacenter=VMware datacenter verwijderen +label.remove.vpc.offering=VPC aanbieding verwijderen label.remove.vpc=verwijder VPC label.removing.user=Verwijderen Gebruiker label.removing=Verwijderen +label.reource.id=Verbruik ID label.required=Vereist +label.requires.upgrade=Upgrade Benodigd +label.reserved.ip.range=Gereserveerde IP Range label.reserved.system.gateway=Gereseveerde systeem gateway label.reserved.system.ip=Gereserveerd Systeem IP label.reserved.system.netmask=Gereserveerd systeem netmask +label.resetVM=Reset VM label.reset.VPN.connection=Reset VPN verbinding label.resize.new.offering.id=Nieuwe Aanbieding label.resize.new.size=Nieuwe Grootte(GB) label.resize.shrink.ok=Verklein OK label.resource.limits=Verbruikslimieten +label.resource.name=Verbruik Naam label.resource.state=Verbruik staat label.resources=Verbruiken label.resource=Verbruik @@ -909,7 +1157,11 @@ label.revoke.project.invite=Trek uitnodiging in label.role=Rol label.root.disk.controller=Root schijf controller label.root.disk.offering=Root Schijf Aanbieding +label.root.disk.size=Grootte root volume label.round.robin=Round-robin +label.router.vm.scaled.up=Router VM Omhoog Geschaald +label.routing=Routing +label.rule.number=Regel Nummer label.rules=Regels label.running.vms=Draaiende VMs label.s3.access_key=Toegangssleutel @@ -917,6 +1169,8 @@ label.s3.bucket=Bucket label.s3.connection_timeout=Connectie Timeout label.s3.endpoint=Endpoint label.s3.max_error_retry=Max. opnieuw proberen na Fout +label.s3.nfs.path=S3 NFS Pad +label.s3.nfs.server=S3 NFS Server label.s3.secret_key=Geheime sleutel label.s3.socket_timeout=Socket Timeout label.s3.use_https=Gebruik HTTPS @@ -926,7 +1180,11 @@ label.save=Opslaan label.saving.processing=Opslaan.... label.scope=Scope label.search=Zoeken +label.secondary.isolated.vlan.id=Secundair Geisoleerd VLAN ID +label.secondary.staging.store.details=Secundaire Staging Opslag details +label.secondary.staging.store=Secundaire Staging Opslag label.secondary.storage.count=Secundaire Opslag Pools +label.secondary.storage.details=Secundaire Opslag details label.secondary.storage.limits=Secundaire Opslag limieten (GiB) label.secondary.storage=Secundaire Opslag label.secondary.storage.vm=Secundaire Opslag VM @@ -944,6 +1202,7 @@ label.select.iso.or.template=Selecteer een ISO of template label.select.offering=Selecteer Aanbieding label.select.project=Selecteer Project label.select=Selecteer +label.select.template=Selecteer Template label.select.tier=Selecteer Tier label.select-view=Selecteer Weergave label.select.vm.for.static.nat=Selecteer VM voor static NAT @@ -951,34 +1210,49 @@ label.sent=Verstuurd label.server=Server label.service.capabilities=Service Mogelijkheden label.service.offering=Service Aanbieding +label.services=Diensten +label.service.state=Service Status label.session.expired=Sessie Verlopen +label.set.default.NIC=Stel standaard NIC in +label.settings=Instellingen label.setup=Instellen label.setup.network=Stel Netwerk in label.setup.zone=Stel Zone in label.set.up.zone.type=Stel zone type in label.shared=Gedeeld label.SharedMountPoint=SharedMountPoint +label.show.advanced.settings=Geavaceerde instellingen weergeven label.show.ingress.rule=Toon Inkomende Regel label.shutdown.provider=Schakel provider uit label.site.to.site.VPN=Site-to-site VPN label.size=Grootte label.skip.guide=Ik heb CloudStack al eerder gebruikt, sla deze stap over +label.smb.domain=SMB Domein +label.smb.password=SMB Wachtwoord +label.smb.username=SMB Gebruikersnaam label.snapshot.limits=Snapshot Limieten label.snapshot.name=Snapshot Naam label.snapshot.schedule=Stel herhalende Snapshot in label.snapshot=Snapshot label.snapshot.s=Snapshot (s) label.snapshots=Snapshots +label.SNMP.community=SNMP Community +label.SNMP.port=SNMP Poort +label.sockets=CPU Sockets label.source=Bron label.source.nat=Source NAT label.specify.IP.ranges=Specificeer IP ranges label.specify.vlan=Specificeer VLAN +label.specify.vxlan=Specificeer VXLAN label.SR.name = SR Name-Label +label.srx.details=SRX details label.srx=SRX label.start.IP=Start IP +label.start.lb.vm=Start LB VM label.start.port=Start Poort label.start.reserved.system.IP=Start gereseveerd systeem IP label.start.vlan=Start VLAN +label.start.vxlan=Start Vxlan label.state=Staat label.static.nat.enabled=Static NAT Ingeschakeld label.static.nat=Static NAT @@ -1009,6 +1283,7 @@ label.sticky.postonly=Alleen Post label.sticky.prefix=Prefix label.sticky.request-learn=Request learn label.sticky.tablesize=Tabel grootte +label.stop.lb.vm=Stop LB VM label.stopped.vms=Uitgeschakelde VMs label.stop=Stop label.storage=Opslag @@ -1023,21 +1298,29 @@ label.sunday=Zondag label.super.cidr.for.guest.networks=Super CIDR voor Gast Netwerken label.supported.services=Geondersteunde Diensten label.supported.source.NAT.type=Ondersteunde Source NAT type +label.supportsstrechedl2subnet=Ondersteund Streched L2 Subnet label.suspend.project=Pauzeer Project +label.switch.type=Switch Type label.system.capacity=Systeem Capaciteit +label.system.offering.for.router=Systeem Aanbieding voor Router label.system.offering=Systeem Aanbieding label.system.service.offering=Systeem Service Aanbieding +label.system.vm.details=Systeem VM details +label.system.vm.scaled.up=Systeem VM omhoog geschaald label.system.vms=Systeem VMs label.system.vm=Systeem VM label.system.vm.type=Systeem VM type label.system.wide.capacity=Systeembreede capaciteit label.tagged=Tagged +label.tag.key=Tag Sleutel label.tags=Tags +label.tag.value=Tag Waarde label.target.iqn=Doel IQN label.task.completed=Taak uitgevoerd label.template.limits=Template Limieten label.template=Template label.TFTP.dir=TFTP Directory +label.tftp.root.directory=TFTP root directory label.theme.default=Standaard Thema label.theme.grey=Aangepast - Grijs label.theme.lightblue=Aangepast - Licht Blauw @@ -1057,13 +1340,17 @@ label.total.memory=Totaal Geheugen label.total.of.ip=Totaal aantal IP Adressen label.total.of.vm=Totaal aantal VM label.total.storage=Totaal Opslag +label.total.virtual.routers=Totaal Virtual Routers +label.total.virtual.routers.upgrade=Totaal Virtueele Routers die een ugrade nodig hebben label.total.vms=Totaal VMs label.traffic.label=Verkeerslabel label.traffic.types=Verkeer Types label.traffic.type=Verkeer Type label.tuesday=Dinsdag label.type.id=Type ID +label.type.lower=type label.type=Type +label.ucs=UCS label.unavailable=Niet beschikbaar label.unlimited=Ongelimiteerd label.untagged=Untagged @@ -1071,15 +1358,20 @@ label.update.project.resources=Update project verbruik label.update.ssl.cert= SSL Certificaat label.update.ssl= SSL Certificaat label.updating=Bezig met updaten +label.upgrade.required=Upgrade is benodigd +label.upgrade.router.newer.template=Upgrade Router om nieuwe Template te gebruiken label.upload=Upload label.upload.volume=Upload Volume label.url=URL label.usage.interface=Verbruik Interface label.used=Gebruikt +label.user.data=Gebruiker Data label.user=Gebruiker label.username=Gebruikersnaam +label.username.lower=gebruikersnaam label.users=Gebruikers label.use.vm.ip=Gebruik VM IP\: +label.use.vm.ips=Gebruik VM IPs label.value=Waarde label.vcdcname=vCenter DC naam label.vcenter.cluster=vCenter Cluster @@ -1088,25 +1380,46 @@ label.vcenter.datastore=VCenter Datastore label.vcenter.host=vCenter Host label.vcenter.password=vCenter Wachtwoord label.vcenter.username=vCenter Gebruikersnaam +label.vcenter=vcenter label.vcipaddress=vCenter IP Adres label.version=Versie +label.vgpu.max.resolution=Maximale resolutie +label.vgpu.max.vgpu.per.gpu=vGPUs per GPU +label.vgpu.remaining.capacity=Overgebleven capaciteit +label.vgpu.type=vCPU type +label.vgpu.video.ram=Video RAM label.view.all=Toon alle label.view.console=Toon console label.viewing=Weergeven label.view.more=Toon meer +label.view.secondary.ips=Toon secundaire IPs label.view=Toon +label.virtual.appliance.details=Virtual applicance details label.virtual.appliances=Virtueele Appliances label.virtual.appliance=Virtuele Appliance label.virtual.machines=Virtuele machines +label.virtual.networking=Virtual Networking label.virtual.network=Virtueel Netwerk +label.virtual.routers.group.account=Groepeer Virtuele Routers op account +label.virtual.routers.group.cluster=Groepeer Virtuele Routers op cluster +label.virtual.routers.group.pod=Groepeer Virtuele Routers op pod +label.virtual.routers.group.zone=Groepeer Virtuele Routers op zone label.virtual.routers=Virtuele Routers label.virtual.router=Virtuele Router +label.vlan.id=VLAN/VNI ID +label.vlan.range.details=VLAN Range details +label.vlan.ranges=VLAN Range(s) +label.vlan.range=VLAN/VNI Reeks +label.vlan=VLAN/VNI +label.vlan.vni.ranges=VLAN/VNI Range(s) +label.vlan.vni.range=VLAN/VNI Reeks label.vm.add=Instantie Toevoegen label.vm.destroy=Verwijder label.vm.display.name=VM weergave naam label.VMFS.datastore=VMFS datastore label.vmfs=VMFS label.vm.name=VM naam +label.vm.password=Het wachtwoord van de VM is label.vm.reboot=Reboot label.VMs.in.tier=VMs in tier label.vmsnapshot.current=isHuidige @@ -1118,14 +1431,27 @@ label.vm.start=Start label.vm.state=VM staat label.vm.stop=Stop label.vms=VMs +label.vmware.datacenter.id=VMware datacenter ID +label.vmware.datacenter.name=VMware datacenter Naam +label.vmware.datacenter.vcenter=VMware datacenter vcenter label.vmware.traffic.label=VMware verkeerslabel +label.vnet.id=VLAN/VNI ID +label.vnet=VLAN/VNI +label.vnmc.devices=VNMC apparaten +label.volatile=Volatile label.volgroup=Volume Groep label.volume.limits=Volume Limieten label.volume.name=Volume Naam label.volumes=Volumes label.volume=Volume +label.vpc.distributedvpcrouter=Gedistribueerde VPC Router label.vpc.id=VPC ID +label.VPC.limits=VPC limieten +label.vpc.offering.details=VPC Aanbieding details +label.vpc.offering=VPC Aanbieding label.VPC.router.details=VPC router details +label.vpc.supportsregionlevelvpc=Ondersteund Region Level VPC +label.vpc.virtual.router=VPC Virtueele Router label.vpc=VPC label.VPN.connection=VPN Connectie label.vpn.customer.gateway=VPN Customer Gateway @@ -1136,6 +1462,9 @@ label.vsmctrlvlanid=Controle VLAN ID label.vsmpktvlanid=Pakket VLAN ID label.vsmstoragevlanid=Opslag VLAN ID label.vsphere.managed=vSphere beheerd +label.vxlan.id=VXLAN ID +label.vxlan.range=VXLAN Reeks +label.vxlan=VXLAN label.waiting=Wachten label.warn=Waarschuwing label.wednesday=Woensdag @@ -1143,10 +1472,14 @@ label.weekly=Wekelijks label.welcome.cloud.console=Welkom op de Management Console label.welcome=Welkom label.what.is.cloudstack=Wat is CloudStack&\#8482? +label.xenserver.tools.version.61.plus=XenServer Tools Versie 6.1\\+ +label.Xenserver.Tools.Version61plus=XenServer Tools Versie 6.1\\+ label.xen.traffic.label=XenServer verkeerslabel label.yes=Ja +label.zone.dedicated=Zone toegewijd label.zone.details=Zone details label.zone.id=Zone ID +label.zone.lower=zone label.zone.name=Zone naam label.zone.step.1.title=Stap 1\: Selecteer een Netwerk label.zone.step.2.title=Stap 2\: Zone toevoegen @@ -1156,10 +1489,12 @@ label.zones=Zones label.zone.type=Type Zone label.zone.wide=Zone breed label.zoneWizard.trafficType.guest=Gast\: Verkeer tussen virtuele machines van de eindgebruiker +label.zoneWizard.trafficType.management=Management\: Verkeer tussen CloudStack\\\\'s interne resources zoals componenten die communiceren met de Management Server zoals hosts en CloudStack systeem VMs label.zoneWizard.trafficType.public=Publiek\: Verkeer tussen het internet en virtueele machines in de cloud. label.zoneWizard.trafficType.storage=Opslag\: Verkeer tussen de primaire en secundaire opslag servers zoals VM templates en snapshots label.zone=Zone managed.state=Beheersstaat +message.acquire.ip.nic=Bevestig dat u een nieuw secundair IP voor deze netwerkkaart wilt verkrijgen. LET OP\: U dient het secundaire IP adres handmatig te configureren binnen de virtueele machine. message.acquire.new.ip=Bevestigen dat je een nieuw IP voor dit netwerk wilt verkrijgen. message.acquire.new.ip.vpc=Bevestig dat u een nieuw IP wilt verkrijgen voor deze VPC. message.acquire.public.ip=Selecteer de zone waarvan u een nieuw IP wenst te verkrijgen. @@ -1177,6 +1512,7 @@ message.action.delete.ISO=Bevestig dat u deze ISO wilt verwijderen. message.action.delete.ISO.for.all.zones=Deze ISO wordt gebruikt door alle zones. Bevestig dat u deze wilt verwijderen van alle zones. message.action.delete.network=Bevestig dat u dit netwerk wilt verwijderen. message.action.delete.nexusVswitch=Bevestig dat u deze nexus 1000v wilt verwijderen +message.action.delete.nic=Bevestig dat u deze netwerkkaart wilt verwijderen, de VM zal ontkoppeld worden van het netwerk wat aan de netwerkkaart aangesloten zit. message.action.delete.physical.network=Bevestig dat u dit fysieke netwerk wilt verwijderen. message.action.delete.pod=Bevestig dat u deze pod wilt verwijderen. message.action.delete.primary.storage=Bevestig dat u deze primaire opslag wilt verwijderen. @@ -1197,6 +1533,7 @@ message.action.disable.physical.network=Bevestig dat u dit fysieke netwerk wilt message.action.disable.pod=Bevestig dat u deze pod wilt uitschakelen. message.action.disable.static.NAT=Bevestig dat u static NAT wilt uitschakelen. message.action.disable.zone=Bevestig dat u deze zone wilt uitschakelen. +message.action.downloading.template=Downloaden template. message.action.download.iso=Bevestig dat u deze ISO wilt downloaden. message.action.download.template=Bevestig dat u deze template wilt downloaden. message.action.enable.cluster=Bevestig dat u dit cluster wilt inschakelen. @@ -1205,12 +1542,396 @@ message.action.enable.nexusVswitch=Bevestig dat u deze nexus 1000v wilt inschake message.action.enable.physical.network=Bevestig dat u dit fysieke netwerk wilt inschakelen. message.action.enable.pod=Bevestigd dat u deze pod wilt inschakelen. message.action.enable.zone=Bevestig dat u deze zone wilt inschakelen. +message.action.expunge.instance=Bevestig dat u deze instantie wilt opruimen message.action.force.reconnect=De host is succesvol geforceerd om opnieuw te verbinden. Dit proces kan echter enkele minuten duren. message.action.host.enable.maintenance.mode=Het inschakelen van de onderhoudsmodus zorgt ervoor dat alle draaiende instanties worden gemigreerd naar andere beschikbare hosts. +message.action.instance.reset.password=Bevestig dat u het ROOT wachtwoord van deze virtueele machine wilt aanpassen. +message.action.manage.cluster=Bevestig dat u dit cluster wilt beheren. +message.action.primarystorage.enable.maintenance.mode=Waarschuwing\: Wanneer u de primaire opslag in onderhoudsmodus plaatst, worden alle VMs die hier gebruik van maken gestopt. Weet u zeker dat u deze actie wilt uitvoeren? +message.action.reboot.instance=Bevestig dat u deze instantie wilt herstarten. +message.action.reboot.router=Als u deze router herstarten zullen de diensten op de router verstoord worden. Weet u zeker dat u deze actie wil uitvoeren? +message.action.reboot.systemvm=Bevestig dat u deze Systeem VM wilt herstarten. +message.action.release.ip=Bevestigd dat u dit IP adres wilt los koppelen. +message.action.remove.host=Bevestig dat u deze host wilt verwijderen. +message.action.reset.password.off=Uw instantie ondersteunt deze functie momenteel niet. +message.action.reset.password.warning=Uw instantie moet gestopt worden voordat u het wachtwoord kunt wijzigen. +message.action.restore.instance=Bevestig dat u deze instantie wilt herstellen. +message.action.revert.snapshot=Bevestig dat u het volume wilt terugdraaien naar dit snapshot. +message.action.start.instance=Bevestig dat u deze instantie wilt starten. +message.action.start.router=Bevestig dat uw deze router wilt starten. +message.action.start.systemvm=Bevestig dat u deze Systeem VM wilt starten. +message.action.stop.instance=Bevestig dat u deze instantie wilt stoppen. +message.action.stop.router=Als u deze router stopt zullen de diensten die gebruik maken van de router verstoord worden. Weet u zeker dat u deze actie wil uitvoeren? +message.action.stop.systemvm=Bevestig dat u deze systeem VM wilt stoppen. +message.action.take.snapshot=Bevestig dat u een snapshot wilt maken van dit volume. +message.action.unmanage.cluster=Bevestig dat u dit cluster niet langer wilt laten beheren door CloudStack. +message.action.vmsnapshot.delete=Bevestig dat u deze VM snapshot wilt verwijderen. +message.action.vmsnapshot.revert=Draai VM snapshot terug +message.activate.project=Weet u zeker dat u dit project wilt activeren? +message.add.cluster=Voeg een hypervisor beheerd cluster toe voor zone , pod
+message.add.disk.offering=Specificeer de volgende waardes om een nieuwe schijf aanbieding toe te voegen +message.add.domain=Specificeer het subdomein welke u onder dit domein wilt aanmaken +message.add.firewall=Voeg firewall toe aan zone +message.add.guest.network=Bevestig dat u een gast netwerk wilt toevoegen +message.add.host=Specificeer de volgende parameters om een nieuwe host toe te voegen +message.adding.host=Host toevoegen +message.adding.Netscaler.device=Netscaler toevoegen +message.adding.Netscaler.provider=Netscaler provider toevoegen +message.add.ip.range.direct.network=Voeg een IP range toe aan direct gekoppeld netwerk in zone +message.add.ip.range.to.pod=

Voeg een IP range toe aan pod\:

+message.add.ip.range=Voeg een IP range aan het publieke netwerk in de zone toe +message.additional.networks.desc=Selecteer additionele netwerk(en) waar uw virtuele instantie aan gekoppeld moet worden. +message.add.load.balancer.under.ip=De loadbalancer regel is toegeovegd onder IP adres\: +message.add.load.balancer=Voeg load balancer toe aan zone +message.add.network=Voeg nieuw netwerk toe aan zone\: +message.add.new.gateway.to.vpc=Specificeer de volgende informatie om een nieuwe gateway toe te voegen aan deze VPC. +message.add.pod.during.zone.creation=Elke zone moet \u00e9\u00e9n of meerdere pods hebben, de eerste pod gaan we nu toevoegen. Een pod bevat de hosts en primaire opslag servers welke we in een van de volgende stappen toevoegen. Allereerst dient u een reeks gereserveerde IP adressen te defini\u00ebren voor CloudStack&\#39s management verkeer. Deze gereserveerde IP reeks moet uniek zijn voor elke zone in de cloud. +message.add.pod=Voeg een nieuwe pod toe aan zone +message.add.primary=Specificeer de volgende parameters om nieuwe primaire opslag toe te voegen +message.add.primary.storage=Voeg nieuwe primaire opslag toe voor zone , pod +message.add.region=Specificeer de benodigde informatie om een nieuwe regio toe te voegen. +message.add.secondary.storage=Voeg nieuwe opslag toe voor zone +message.add.service.offering=Specificeer de volgende gegevens om een nieuwe service aanbieding aan te maken. +message.add.system.service.offering=Specificeer de volgende gegevens om een nieuwe systeem aanbieding toe te voegen. +message.add.template=Specificeer de volgende gegevens om een nieuwe template aan te maken +message.add.volume=Specificeer de volgende gegevens om een nieuw volume toe te voegen. +message.add.VPN.gateway=Bevestig dat u een VPN Gateway wilt toevoegen +message.admin.guide.read=Voor VMware-gebaseerde VMs, lees eerst de dynamic scaling sectie in de admin guide voordat u gaat schalen. Weet u zeker dat u verder wilt gaan? +message.advanced.mode.desc=Kies dit netwerk model als u VLAN ondersteuning wilt inschakelen. Dit netwerk model geeft u de meeste flexibiliteit en stelt beheerders in staat om aangepaste netwerk aanbiedingen aan te maken met firewall, vpn, of load balancer ondersteuning. Ook kunt u kiezen tussen direct en virtual networking. +message.advanced.security.group=Kies dit netwerk model als u security groups wilt gebruiken om virtueele machines te isoleren. +message.advanced.virtual=Kies deze optie als u zone breede VLANs wilt gebruiken om virtueele machines te isoleren. +message.after.enable.s3=S3-backed Secondary Storage is geconfigureerd. Let op\: Als u deze pagina verlaat zult u niet in staat zijn om S3 te (her)configureren. +message.after.enable.swift=Swift is geconfigureerd. Let op\: Als u deze pagina verlaat zult u niet in staat zijn om Swift te (her)configureren. +message.alert.state.detected=Probleem status gedetecteerd +message.allow.vpn.access=Specificeer een gebruikersnaam en wachtwoord voor de gebruiker die u toegang wilt geven tot de VPN. +message.apply.snapshot.policy=De huidige snapshot policy is succesvol gewijzigd. +message.attach.iso.confirm=Bevestig dat u deze ISO wilt koppelen aan de virtuele machine. +message.attach.volume=Specificeer de volgende gegevens om een nieuw volume te koppelen. Als u een schijf volume wilt toevoegen aan een Windows gebaseerde machine, dan dient u deze te rebooten om de schijf zichtbaar te maken. +message.basic.mode.desc=Kies dit netwerk model als u *geen* VLAN ondersteuning wilt inschakelen. Alle virtuele machines onder dit netwerk model zullen direct een IP gealloceerd krijgen vanuit het netwerk en security groups kunnen gebruikt worden om beveiliging en segmentering te realiseren. +message.change.offering.confirm=Bevestig dat u de service aanbieding van deze virtueele machine wilt wijzigen. +message.change.password=Wijzig a.u.b. uw wachtwoord. +message.cluster.dedicated=Zone toegewijd +message.cluster.dedication.released=Cluster toewijding losgekoppeld +message.configure.all.traffic.types=U heeft meerdere fysieke netwerken; Configureer labels voor elk verkeerstype door op de Wijzig knop te klikken. +message.configure.ldap=Bevestig dat u LDAP wilt configureren. +message.configuring.guest.traffic=Bezig met configureren guest traffic +message.configuring.physical.networks=Bezig met configureren fysieke netwerken +message.configuring.public.traffic=Bezig met configureren publiek verkeer +message.configuring.storage.traffic=Bezig met configureren opslag verkeer +message.confirm.action.force.reconnect=Bevestig dat u deze host geforceerd opnieuw wilt laten verbinden. +message.confirm.add.vnmc.provider=Bevestig dat u de VNMC provider wilt toevoegen. +message.confirm.dedicate.cluster.domain.account=Weet u zeker dat u dit cluster wilt toewijden aan een domein/account? +message.confirm.dedicate.host.domain.account=Weet u zeker dat u deze host wilt toewijden aan een domein/account? +message.confirm.dedicate.pod.domain.account=Weet u zeker dat u deze pod wilt toewijden aan een domein/account? +message.confirm.dedicate.zone=Weet u zeker dat u deze zone wilt toewijden aan een domein/account? +message.confirm.delete.ciscovnmc.resource=Bevestig dat u de CiscoVNMC resource wilt verwijderen. +message.confirm.delete.F5=Bevestig dat u deze F5 wilt verwijderen +message.confirm.delete.NetScaler=Bevestig dat u deze NetScaler wilt verwijderen +message.confirm.delete.PA=Bevestig dat u Palo Alto wilt verwijderen +message.confirm.delete.secondary.staging.store=Bevestig dat u de secudaire staging opslag wilt verwijderen. +message.confirm.delete.SRX=Bevestig dat u deze SRX wilt verwijderen +message.confirm.delete.ucs.manager=Bevestig dat u de UCS Manager wilt verwijderen +message.confirm.destroy.router=Bevestig dat u deze router wilt verwijderen +message.confirm.disable.network.offering=Weet u zeker dat u deze netwerk aanbieding wilt uitschakelen? +message.confirm.disable.provider=Bevestig dat u deze provider wilt uitschakelen +message.confirm.disable.vnmc.provider=Bevestig dat u de VNMC provider wilt uitschakelen. +message.confirm.disable.vpc.offering=Weet u zeker dat u deze VPC aanbieding wilt uitschakelen? +message.confirm.enable.network.offering=Weet u het zeker dat u deze netwerk aanbieding wilt inschakelen? +message.confirm.enable.provider=Bevestig dat u deze provider wilt inschakelen +message.confirm.enable.vnmc.provider=Bevestig dat u de VNMC provider wilt inschakelen. +message.confirm.enable.vpc.offering=Weet u zeker dat u deze VPC aanbieding wilt inschakelen? +message.confirm.join.project=Bevestig dat u aan dit project wilt bijdragen +message.confirm.refresh.blades=Bevestig dat u de blades wilt verversen. +message.confirm.release.dedicated.cluster=Weet u zeker dat u dit toegewijde cluster wilt loskoppelen? +message.confirm.release.dedicated.host=Weet u zeker dat u deze toegewijde host wilt loskoppelen? +message.confirm.release.dedicated.pod=Weet u zeker dat u deze toegewijde pod wilt loskoppelen? +message.confirm.release.dedicated.zone=Weet u zeker dat u deze toegewijde zone wilt loskoppelen? +message.confirm.release.dedicate.vlan.range=Bevestig dat u de toegewijde VLAN range wilt loskoppelen +message.confirm.remove.IP.range=Bevestig dat u deze IP range wilt verwijderen. +message.confirm.remove.network.offering=Weet u zeker dat u deze netwerk aanbieding wilt verwijderen? +message.confirm.remove.vmware.datacenter=Bevestig dat u VM datacenter wilt verwijderen +message.confirm.remove.vpc.offering=Weet u zeker dat u deze VPC aanbieding wilt verwijderen? +message.confirm.scale.up.router.vm=Weet u zeker dat u de Router VM wilt opschalen? +message.confirm.scale.up.system.vm=Weet u zeker dat u de Systeem VM wilt opschalen? +message.confirm.shutdown.provider=Bevestig dat u deze provider wilt afsluiten +message.confirm.start.lb.vm=Bevestig dat u de LB VM wilt starten +message.confirm.stop.lb.vm=Bevestig dat u de LB VM wilt stoppen +message.confirm.upgrade.router.newer.template=Bevestig dat u de router naar een nieuwere template versie wilt upgraden +message.confirm.upgrade.routers.account.newtemplate=Bevestig dat u alle routers onder deze account wilt upgraden naar een nieuwe template +message.confirm.upgrade.routers.cluster.newtemplate=Bevestig dat u alle routers in dit cluster wilt upgraden naar een nieuwe template +message.confirm.upgrade.routers.newtemplate=Bevestig dat u alle routers in deze zone wilt upgraden naar een nieuwe template +message.confirm.upgrade.routers.pod.newtemplate=Bevestig dat u alle routers in deze pod wilt upgraden naar een nieuwe template +message.copy.iso.confirm=Bevestig dat u deze ISO wilt kopieeren naar +message.copy.template.confirm=Weet u zeker dat u de template wilt kopieeren? +message.copy.template=Kopieer template XXX van zone naar +message.create.template.vm=Maak een VM aan vanaf een template +message.create.template.volume=Specificeer a.u.b. de volgende informatie voordat u een template van het schijf volume\: . Het maken van een template kan een paar minuten duren maar ook langer afhankelijk van de grote van het volume. +message.create.template=Weet u het zeker dat u een template wilt aanmaken? +message.creating.cluster=Cluster aanmaken +message.creating.guest.network=Gast netwerk aanmaken +message.creating.physical.networks=Fysieke netwerken aanmaken +message.creating.pod=Pod aanmaken +message.creating.primary.storage=Primaire opslag aanmaken +message.creating.secondary.storage=Secundaire opslag aanmaken +message.creating.systemVM=Bezig met aanmaken van systeem VMs (dit kan enige tijd duren) +message.creating.zone=Zone aanmaken +message.decline.invitation=Weet u zeker dat u deze project uitnodiging wilt afwijzen? +message.dedicated.zone.released=Zone toewijding losgekoppeld +message.dedicate.zone=Dedicating zone +message.delete.account=Bevestig dat u deze account wilt verwijderen. +message.delete.affinity.group=Bevestig dat u deze affinity groep wilt verwijderen +message.delete.gateway=Bevestig dat u deze gateway wilt verwijderen +message.delete.project=Weet u zeker dat u dit project wilt verwijderen? +message.delete.user=Bevestig dat u deze gebruiker wilt verwijderen +message.delete.VPN.connection=Bevestig dat u deze VPN verbinding wilt verwijderen +message.delete.VPN.customer.gateway=Bevestig dat u deze VPN Customer Gateway wilt verwijderen +message.delete.VPN.gateway=Bevestig dat u deze VPN Gateway wilt verwijderen +message.desc.advanced.zone=Voor ingewikkeldere netwerk topologie\u00ebn. Dit netwerk model geeft de meeste flexibiliteit en het definieren van gast netwerken en het aanbieden van speciale diensten zoals firewall, VPN of loadbalancer ondersteuning. +message.desc.basic.zone=Cre\u00ebert een enkel netwerk waar elke VM instantie direct een IP op krijgt. Het isoleren van instanties kunt op layer-3 niveau doen door middel van security groups. +message.desc.cluster=Elke pod moet \u00e9\u00e9n of meerdere cluster bevatten, en we gaan het eerste cluster nu toevoegen. Een cluster is een manier om hosts te groeperen. De hosts in een cluster hebben identieke hardware, gebruiken de zelfde hypervisor, zitten op hetzelfde subnet en kunnen bij dezelfde gedeelde opslag. Elk cluster bestaan uit \u00e9\u00e9n of meerdere hosts en \u00e9\u00e9n of meerdere primaire opslag systemen. +message.desc.host=Elke cluster moet een of meerdere hosts (servers) bevatten om gast VMs op te draaien. We gaan de eerste host nu toevoegen. Om een host met CloudStack te laten werken moet hij voorzien zijn van hypersvisor software, een werkend IP adres en in staat zijn de management server over het netwerk te bereiken.

Specificeer de DNS hostnaam of het IP adres van de host, de gebruikersnaam (meestal root) en het bijbehorende wachtwoord en als laatste eventuele labels om de host te categoriseren. +message.desc.primary.storage=Elk cluster moet over \u00e9\u00e9n of meerdere primaire opslag servers beschikken, de eerste gaan we nu aanmaken. Primaire opslag bevat de volumes van VMs draaiende op de hosts in het cluster. Gebruik een protocol dat is ondersteund door de hypervisor. +message.desc.secondary.storage=Elke zone moet minimaal \u00e9\u00e9n of meerdere secundaire opslag servers hebben, de eerste maken we nu aan. Secundaire opslag wordt gebruikt voor het opslaan van VM templates, ISO bestanden en snapshots. Deze server moet beschikbaar zijn aan alle hosts in de zone.

Specificeer het IP adres en het exporteerde pad. +message.desc.zone=Een zone is de grootste organisatorische unit binnen CloudStack en correspondeert normaliter met enkel datacenter. Zones geven fysieke isolatie en redundantie. Een zone bestaat uit een of meerdere pods (waarvan ieder eigen hosts en primaire opslag servers heeft) en een secundaire opslag server welke gedeeld wordt door alle pods in de zone. +message.detach.disk=Weet u zeker zeker dat u deze schijf wilt ontkoppelen? +message.detach.iso.confirm=Bevestig dat u deze ISO wilt ontkoppelen van de virtueele machine. +message.disable.account=Bevestig dat u deze account wilt uitschakelen. Als u deze account uitschakelt zullen de gebruikers niet langer toegang hebben tot hun cloud resources. Alle draaiende virtueele machines zullen direct afgesloten worden. +message.disable.snapshot.policy=De huidige snapshot policy is uitgeschakeld. +message.disable.user=Bevestig dat u deze gebruiker wilt uitschakelen. +message.disable.vpn.access=Bevestig dat u VPN toegang wilt uitschakelen. +message.disable.vpn=Weet u zeker dat u VPN wilt uitschakelen? +message.disabling.network.offering=Netwerk Aanbieding Uitschakelen +message.disabling.vpc.offering=VPC offering uitschakelen +message.disallowed.characters=Niet toegestane karakters\: \\<\\,\\> +message.download.ISO=Klik op 00000 om de ISO te downloaden +message.download.template=Klik op 00000 om de template te downloaden +message.download.volume.confirm=Bevestig dat u dit volume wilt downloaden +message.download.volume=Klik op 00000 om het volume te downloaden +message.edit.account=Wijzig ("-1" geeft aan dat er geen limiet is ingesteld) +message.edit.confirm=Controleer uw wijzigen voordat u op "Opslaan" klikt. +message.edit.limits=Specificeer de limieten voor de volgende resources. Met "-1" geeft u aan dat er geen limiet geld. +message.edit.traffic.type=Specificeer het verkeerslabel dat u met dit type verkeer wilt associeren. +message.enable.account=Bevestig dat u deze account wilt inschakelen. +message.enabled.vpn.ip.sec=Uw IPSec pre-shared key is +message.enabled.vpn=Uw VPN toegang is ingeschakeld en kan benaderd worden via het IP +message.enable.user=Bevestig dat u deze gebruiker wilt inschakelen. +message.enable.vpn.access=VPN is momenteel uitgeschakeld voor dit IP adres. Wilt u deze inschakelen? +message.enable.vpn=Bevestig dat u VPN toegang voor dit IP adres wilt inschakelen. +message.enabling.network.offering=Netwerk Aanbieding Inschakelen +message.enabling.security.group.provider=Inschakelen Security Group provider +message.enabling.vpc.offering=VPC aanbieding inschakelen +message.enabling.zone.dots=Bezig met activeren van Zone.... +message.enabling.zone=Inschakelen zone +message.enter.seperated.list.multiple.cidrs=Gelieve een met komma\\'s gescheiden lijst van CIDRs invoeren wanneer er meer dan een zijn +message.enter.token=Vul het token in dat vermeld staat in de e-mail uitnodiging. +message.generate.keys=Bevestig dat u nieuwe sleutels wilt genereren voor deze gebruiker. +message.gslb.delete.confirm=Bevestigd dat u deze GSLB wilt verwijderen +message.gslb.lb.remove.confirm=Bevestig dat u loadbalancing van GSLB wilt verwijderen +message.guest.traffic.in.advanced.zone=Gast netwerk verkeer is communicatie tussen virtuele machines van de eindgebruiker. Specificeer een range van VLAN IDs om gast verkeer te transporteren over het fysieke netwerk. +message.guest.traffic.in.basic.zone=Gast netwerk verkeer is communicatie tussen virtuele machines van de eindgebruiker. Specificeer een range van IP adressen welke CloudStack kan uitdelen aan gast VMs. Let erop dat deze range niet overlapt met de gereserveerde systeem IP range. +message.host.dedicated=Host toegewijd +message.host.dedication.released=Toegewijde host losgekoppeld +message.installWizard.click.retry=Druk op de knop om de lancering opnieuw te proberen +message.installWizard.copy.whatIsACluster=Een cluster is een manier om hosts te groeperen. De hosts in een cluster hebben ieder identieke hardware, draaien dezelfde hypervisor, zitten op hetzelfde subnet en kunnen dezelfde gedeelde opslag benaderen. Virtuele machines (VMs) kunnen live gemigreerd worden van tot ene naar de andere host in hetzelfde cluster zonder dat de gebruiker hier iets van merkt. Een cluster is de 3e grootste organisatorische unit binnen Cloudstack&\#8482;. Clusters worden ondergebracht in pods, en pods zijn op hun beurt ondergebracht in zones. CloudStack&\#8482; biedt te mogelijkheid tot meerdere clusters, maar voor een basis installatie hebben we maar \u00e9\u00e9n cluster nodig. +message.installWizard.copy.whatIsAHost=Een host een opzichzelfstaande computer. Hosts verzorgen de resources nodig om de gast virtuele machines te draaien. Elke host heeft eigen hypervisor software geinstalleerd om de virtuele machines erop te beheren (Afgezien van bare metal hosts, hierover is meer te vinden in de geavanceerde installatie handleiding). Om een paar voorbeelden te noemen\: een Linux server met KVM, een server met Citrix XenServer en servers met ESXi geinstalleerd zijn hosts. Bij de basis installatie gebruiken we een opzichzelfstaande host met XenServer of KVM geinstalleerd.

Een host is de kleinste organisatorische unit binnen een CloudStack&\#8482; omgeving. Hosts worden ondergebracht in clusters, cluster zijn ondergebracht in pods en pods zijn ongebracht in zones. +message.installWizard.copy.whatIsAPod=Een pod vertegenwoordigd meestal een rack. Hosts in dezelfde pod hebben hetzelfde subnet.

Een pod is de tweede grootste organisatorische unit binnen een CloudStack&\#8482; omgeving. Pods zijn ondergebracht in zones. Elke zone kan meerdere pods hebben, voor de basis installatie hebben we een enkele pod in de zone. +message.installWizard.copy.whatIsAZone=Een zone is de grootste organisatorische unit binnen een CloudStack&\#8482; omgeving. Een zone staat meestal voor een datacenter, al is het geen probleem om meerdere zones in hetzelfde datacenter te hebben. Het voordeel van infrastructuur onderbrengen in zones is om fysieke isolatie en redundantie te cre\u00ebren. Elke zone kan bijvoorbeeld zijn eigen stroom voorziening en netwerk uplinks hebben en kunnen geografisch verspreid worden (al is dit geen vereiste). +message.installWizard.copy.whatIsCloudStack=CloudStack&\#8482; is een software platform welke computer capaciteit herenigd om public, private en hybrid infrastructure as a Service (IaaS) clouds te bouwen. CloudStack&\#8482; beheert het netwerk, de opslag en de computer nodes welke de cloud infrastructuur vertegenwoordigen. Gebruik CloudStack&\#8482; om cloud computing omgevingen uit te rollen, te beheren en te configureren.

CloudStack&\#8482 gaat veel verder dan het draaien van virtuele machine bestanden op commodity hardware, het is een turnkey oplossing om virtuele datacenters (as a service) te realiseren. Daarbij levert het alle essenti\u00eble componenten om multi-tier en multi-tentant cloud applicaties te bouwen en te beheren. Er is een zowel een open-source als Premium versie beschikbaar, waarbij de open-source versie nagenoeg dezelfde functionaliteit biedt als de Premium versie. +message.installWizard.copy.whatIsPrimaryStorage=Een CloudStack&\#8482; cloud infrastructuur maakt gebruik van 2 type opslag, namelijk primaire en secundaire opslag. Primaire opslag kan iSCSI, NFS of lokale opslag zijn. Secundaire opslag werkt via NFS of een S3-compatible opslag systeem.

Primaire opslag is onderdeel van een cluster, en het bevat de schijf volumes van iedere gast VM in dat cluster. De primaire opslag server wordt meestal dicht bij de hosts geplaatst. +message.installWizard.copy.whatIsSecondaryStorage=Secundaire opslag is onderdeel van een zone, en biedt opslagruimte aan\:
  • Templates - kant-en-klare VMs die gebruikt kunnen worden zonder voorafgaande installatie.
  • ISO bestanden - Installatie mediums voor VMs.
  • Schijf volume snapshots - reservekopie\u00ebn van schijf volumes die later gebruikt kunnen worden tijdens recovery of het maken van nieuwe templates.
+message.installWizard.now.building=Bezig met het bouwen van je cloud... +message.installWizard.tooltip.addCluster.name=Een naam voor het cluster. U kunt deze tekst vrij invullen, en zal verder niet gebruikt worden door CloudStack. +message.installWizard.tooltip.addHost.hostname=De DNS naam of het IP adres van de host. +message.installWizard.tooltip.addHost.password=Dit is het wachtwoord voor de gebruiker die hierboven genoemd wordt (van uw Xenserver instllatie). +message.installWizard.tooltip.addHost.username=Meestal root. +message.installWizard.tooltip.addPod.name=Een naam voor de pod +message.installWizard.tooltip.addPod.reservedSystemEndIp=Dit is de IP range van het private netwerk dat CloudStack gebruikt om met Secundaire Opslag VMs en Console Proxy VMs te communiceren. Deze IP adressen komen uit hetzelfde subnet als de gast VMs. +message.installWizard.tooltip.addPod.reservedSystemGateway=De gateway voor de hosts in die pod. +message.installWizard.tooltip.addPod.reservedSystemNetmask=De netmask die gebruikt wordt op het subnet dat de gast VMs gaan gebruiken. +message.installWizard.tooltip.addPod.reservedSystemStartIp=Dit is de IP range van het private netwerk dat CloudStack gebruikt om met Secundaire Opslag VMs en Console Proxy VMs te communiceren. Deze IP adressen komen uit hetzelfde subnet als de gast VMs. +message.installWizard.tooltip.addPrimaryStorage.name=De naam voor het opslag apparaat. +message.installWizard.tooltip.addPrimaryStorage.path=(Voor NFS) Bij NFS dit is het ge\u00ebxporteerde pad van de server. Pad (Voor SharedMountPoint). Bij KVM is dit het pad waar op elke machine de primaire opslag is gekoppeld. Bijvoorbeeld, "/mnt/primary". +message.installWizard.tooltip.addPrimaryStorage.server=(Voor NFS, iSCSI of PreSetup) Het IP adres of DNS naam van het opslag apparaat. +message.installWizard.tooltip.addSecondaryStorage.nfsServer=Het IP adres van de NFS server welke de secundaire opslag serveert +message.installWizard.tooltip.addSecondaryStorage.path=Het ge\u00ebxporteerde pad, op de server die u hierboven heeft gespecificeerd +message.installWizard.tooltip.addZone.dns1=Deze DNS servers worden gebruik door gast VMs in de Zone. Deze DNS servers moeten toegankelijk zijn op het publieke netwerk wat we later gaan toevoegen. De publieke IP adressen voor de zone moeten een route hebben naar de DNS server hier vermeld. +message.installWizard.tooltip.addZone.dns2=Deze DNS servers worden gebruik door gast VMs in de Zone. Deze DNS servers moeten toegankelijk zijn op het publieke netwerk wat we later gaan toevoegen. De publieke IP adressen voor de zone moeten een route hebben naar de DNS server hier vermeld. +message.installWizard.tooltip.addZone.internaldns1=Deze DNS servers worden gebruik door gast VMs in de Zone. Deze DNS servers moeten toegankelijk zijn op het private netwerk wat we later gaan toevoegen. De private IP adressen voor de zone moeten een route hebben naar de DNS server hier vermeld. +message.installWizard.tooltip.addZone.internaldns2=Deze DNS servers worden gebruik door gast VMs in de Zone. Deze DNS servers moeten toegankelijk zijn op het private netwerk wat we later gaan toevoegen. De private IP adressen voor de zone moeten een route hebben naar de DNS server hier vermeld. +message.installWizard.tooltip.addZone.name=Een naam voor de zone +message.installWizard.tooltip.configureGuestTraffic.description=Een beschrijving voor het netwerk +message.installWizard.tooltip.configureGuestTraffic.guestEndIp=De IP reeks welke beschikbaar zal zijn voor gast VMs in de zone. Als \u00e9\u00e9n NIC gebruikt wordt, zouden deze IP adressen in hetzelfde CIDR moeten vallen als die van de pod. +message.installWizard.tooltip.configureGuestTraffic.guestGateway=De gateway welke gast VMs moeten gebruiken +message.installWizard.tooltip.configureGuestTraffic.guestNetmask=De netmask die gebruikt wordt op het subnet dat door gast VMs gebruikt wordt +message.installWizard.tooltip.configureGuestTraffic.guestStartIp=De IP reeks welke beschikbaar zal zijn voor gast VMs in de zone. Als \u00e9\u00e9n NIC gebruikt wordt, zouden deze IP adressen in hetzelfde CIDR moeten vallen als die van de pod. +message.installWizard.tooltip.configureGuestTraffic.name=Een naam voor het netwerk +message.instance.scaled.up.confirm=Weet u zeker dat u deze VM wilt opschalen? +message.instanceWizard.noTemplates=Er zijn geen templates beschikbaar. Voeg een geschikte template toe, en herstart deze instantie wizard. +message.ip.address.changed=Uw IP adres is mogelijk gewijzigd, wilt u de lijst verversen? Wanneer dit het geval is, zal het detail paneel gesloten worden. +message.iso.desc=Image bestand met data of bootable media voor besturingsysteem +message.join.project=U neemt nu deel aan een project. Klik op het project overzicht om het project te zien. +message.launch.vm.on.private.network=Wilt u de instantie starten op uw eigen private dedicated netwerk? +message.launch.zone=De zone is klaar om geactiveerd te worden, ga door naar de volgende stap. +message.listView.subselect.multi=(Ctrl/Cmd-click) +message.lock.account=Bevestig dat u deze account wilt vergrendelen. Wanneer u de account vergrendeld zullen alle gebruikers van deze account hun cloud resources niet meer kunnen beheren. Toegang tot bestaande producten blijft bestaan. +message.migrate.instance.confirm=Bevestig de host naar waar u de instantie toe wilt migreren. +message.migrate.instance.to.host=Bevestig dat u de instantie naar een andere host toe wilt migreren. +message.migrate.instance.to.ps=Bevestig dat u de instantie naar een andere primaire opslag toe wilt migreren. +message.migrate.router.confirm=Bevestig de host waar u de router naartoe wilt migreren\: +message.migrate.systemvm.confirm=Bevestig de host naar waar u de systeem VM toe wilt migreren\: +message.migrate.volume=Bevestig dat u het volume wilt migreren naar een andere primaire opslag. +message.network.addVM.desc=Specificeer het netwerk dat u aan deze VM wilt toevoegen. Een nieuwe netwerk interface zal worden toegevoegd aan de VM. +message.network.addVMNIC=Bevestig dat u een nieuwe netwerk interface voor dit netwerk wilt verkrijgen. +message.new.user=Sepecificeer de volgende waarden om een nieuwe gebruiker toe te voegen aan de account +message.no.affinity.groups=U heeft geen affinity groepen. Ga door naar de volgende stap. +message.no.host.available=Geen hosts beschikbaar voor Migratie +message.no.network.support.configuration.not.true=Er is geen zone waarin security groups zijn ingeschakeld. Om die reden zijn er geen additionele netwerk diensten beschikbaar. Ga door naar stap 5. +message.no.network.support=De geselecteerde hypervisor, vSphere, beschikt niet over additionele netwerk diensten. Ga door naar stap 5. +message.no.projects.adminOnly=U hebt momenteel geen projecten.
Uw beheerder kan een nieuw project aanmaken. +message.no.projects=U hebt momenteel geen projecten.
U kunt een nieuw project aanmaken vanuit de projecten sectie. +message.number.clusters=

Aantal Clusters

+message.number.hosts=

Aantal Hosts

+message.number.pods=

Aantal Pods

+message.number.storage=

Aantal Primaire Opslag Volumes

+message.number.zones=

Aantal Zones

+message.pending.projects.1=U heeft openstaande project uitnodigigingen\: +message.pending.projects.2=Ga naar de project sectie om deze te zien. Selecteer de uitnodiging vanuit het drop-down menu. +message.please.add.at.lease.one.traffic.range=U dient minimaal \u00e9\u00e9n traffic range toe te voegen. +message.please.proceed=Ga door naar de volgende stap. +message.please.select.a.configuration.for.your.zone=Selecteer een configuratie voor uw zone. +message.please.select.a.different.public.and.management.network.before.removing=Selecteer a.u.b. een ander publiek en beheer netwerk voordat u deze verwijderd +message.please.select.networks=Selecteer netwerken voor uw virtuele machine. +message.please.wait.while.zone.is.being.created=Even geduld, uw zone wordt aangemaakt; Dit kan enige tijd duren... +message.pod.dedication.released=Toegewijde pod losgekoppeld +message.portable.ip.delete.confirm=Bevestig dat u deze porteerbare IP reeks wilt verwijderen +message.project.invite.sent=Uitnodiging is verstuurd aan gebruiker. De gebruiker wordt toegevoegd aan het project wanneer hij de uitnodiging accepteert. +message.public.traffic.in.advanced.zone=Publiek verkeer wordt gegenereerd wanneer VMs in de cloud het internet bezoeken. Publiek toegankelijke IPs moeten om deze reden toegevoegd worden. Eindgebruikers kunnen deze IP adressen via de Cloudstack UI aanvragen om zo verkeer tussen het gast netwerk en publieke netwerk te realiseren.

Geef minimaal \u00e9\u00e9n IP range op voor internet verkeer. +message.public.traffic.in.basic.zone=Publiek verkeer wordt gegenereerd wanneer VMs in de cloud het internet bezoeken of diensten serveren aan het internet. Publiek toegankelijke IPs moeten om deze reden toegevoegd worden. Wanneer een instantie wordt aangemaakt, krijgt deze automatisch een van deze IP adressen toegewezen naast het gast IP adres. Static 1-1 NAT wordt automatisch geconfigureerd tussen het publieke IP en gast IP adres. Eindgebruikers kunnen via de CloudStack UI meerdere IP adressen aanvragen om static NAT tussen hun instanties en het publieke IP te realiseren. +message.read.admin.guide.scaling.up=Gelieve de dynamic scaling sectie te lezen in admin guide voordat u gaat opschalen. +message.recover.vm=Bevestig dat u deze VM wilt herstellen. +message.redirecting.region=U wordt doorverbonden met de regio... +message.reinstall.vm=LET OP\: Als u doorgaat zal de VM opnieuw geinstalleerd worden vanaf de template. Alle data op de root disk zal verwijderd worden. Eventuele data volumes blijven onaangeraakt. +message.remove.ldap=Weet u zeker dat u de LDAP configuratie wilt verwijderen? +message.remove.region=Weet u zeker dat u deze regio wilt verwijderen van deze management server? +message.remove.vpc=Bevestigd dat u de VPC wilt verwijderen +message.remove.vpn.access=Bevestig dat u VPN toegang wilt verwijderen van de volgende gebruiker. +message.reset.password.warning.notPasswordEnabled=De template van deze instantie was aangemaakt zonder wachtwoord functie +message.reset.password.warning.notStopped=Uw instantie moet gestopt worden voordat u het wachtwoord kunt wijzigen. +message.reset.VPN.connection=Bevestig dat u deze VPN verbinding wilt resetten +message.restart.mgmt.server=Gelieve uw management server(s) herstarten om deze wijziging actief te maken. +message.restart.mgmt.usage.server=Gelieve uw management server(s) en gebruik server(s) herstarten om deze wijziging actief te maken. +message.restart.network=Als u dit netwerk herstart zullen de diensten op het netwerk verstoord worden. Weet u zeker dat u deze actie wil uitvoeren? +message.restart.vpc=Bevestig dat u deze VPC wilt herstarten +message.restoreVM=Wilt u de VM herstellen? +message.security.group.usage=(Gebruik Ctrl-klik om meerdere security groups te selecteren) +message.select.affinity.groups=Selecteer welke affinity groepen u wilt gebruiken voor deze VM\: +message.select.a.zone=Een zone correspondeert meestal met een enkel datacenter. Meerdere zones maken de cloud betrouwbaarder door fysiek isolatie en redunatie te verzorgen. +message.select.instance=Selecteer een instantie. +message.select.iso=Gelieve een ISO te selecteren voor uw nieuwe instantie. +message.select.item=Gelieve een item te selecteren. +message.select.security.groups=Gelieve security group(s) te selecteren voor de nieuwe instantie +message.select.template=Gelieve een template te selecteren voor de nieuwe instantie +message.select.tier=Gelieve een tier te selecteren +message.set.default.NIC=Bevestig dat u dit netwerk apparaat standaard wilt maken voor deze VM. +message.set.default.NIC.manual=U dient nu manueel de netwerk interface op de VM updaten. +message.setup.physical.network.during.zone.creation.basic=Wanneer u een basis zone toevoegt bevat deze een fysiek netwerk welke correspondeert met de netwerkkaart op de hypervisor. Op dit netwerk zullen meerdere verkeerstypen gebruikt worden.

U kunt via drag & drop andere verkeerstypen toevoegen aan het fysieke netwerk. +message.setup.physical.network.during.zone.creation=Wanneer u een geavanceerde zone toevoegt, dient u meerdere fysiek netwerken te configureren. Een netwerk correspondeert met een netwerkkaart op de hypervisor. Elk fysiek netwerk kan een of meerdere traffic types bevatten, met bepaald geldende restricties hoe deze gecombineerd mogen worden. Drag & Drop een of meerdere verkeerstypen op het fysieke netwerk. +message.setup.successful=Cloud installatie is succesvol verlopen\! +message.snapshot.schedule=U kunt terugkerende snapshots schema&\#39s aanmaken door een van de beschikbare opties hieronder te selecteren. +message.specifiy.tag.key.value=Gelieve een tag sleutel en waarde te specificeren +message.specify.url=Gelieve een URL te specificeren +message.step.1.continue=Gelieve een template of ISO te selecteren om door te gaan +message.step.1.desc=Selecteer een template voor uw nieuwe instantie. U kunt ook een blanco template selecteren op welke een ISO bestand geinstalleerd kan worden. +message.step.2.continue=Selecteer een service aanbieding om verder te gaan. message.step.2.desc= +message.step.3.continue=Selecteer een schijf aanbieding om verder te gaan message.step.3.desc= +message.step.4.continue=Selecteer minimaal \u00e9\u00e9n netwerk om door te gaan +message.step.4.desc=Selecteer het primaire netwerk aan welke uw instantie verbonden moet worden +message.storage.traffic=Verkeer tussen CloudStack&\#39s interne diensten, inclusief componenten die communiceren met de management server zoals hosts en CloudStack systeem VMs. Configureer opslag verkeer hier. +message.suspend.project=Weet u zeker dat u dit project wilt pauzeren? +message.systems.vms.ready=Systeem VMs klaar. +message.template.copying=De template wordt gekopieerd. +message.template.desc=OS image bestand dat gebruikt kan worden om de VM op te starten +message.tier.required=Tier is benodigd +message.tooltip.dns.1=Naam van de DNS server die gebruikt mag worden door VMs in de zone. De publieke IP adressen in de zone moeten een route hebben naar deze server. +message.tooltip.dns.2=Naam van een secudaire DNS server die gebruikt mag worden door VMs in de zone. De publieke IP adressen in de zone moeten een route hebben naar deze server. +message.tooltip.internal.dns.1=Naam van de DNS server die gebruikt mag worden door interne systeem VMs van CloudStack in de zone. De priv\u00e9 IP adressen in de pod moeten een route hebben naar deze server. +message.tooltip.internal.dns.2=Naam van de DNS server die gebruikt mag worden door interne systeem VMs van CloudStack in de zone. De priv\u00e9 IP adressen in de pod moeten een route hebben naar deze server. +message.tooltip.network.domain=Een DNS toevoeging dat de domeinnaam zal zijn voor het netwerk wat toegangkelijk is voor gast VMs. +message.tooltip.pod.name=Een naam voor deze pod. +message.tooltip.reserved.system.gateway=De gateway voor hosts in deze pod. +message.tooltip.reserved.system.netmask=De netwerk prefix dat het pod subnet definieert. Gebruik de CIDR notatie. +message.tooltip.zone.name=Een naam voor de zone. +message.update.os.preference=Selecteer een OS voorkeur voor deze host. Alle virtueel instanties van gelijke voorkeur zullen eerst op deze machine gealloceerd worden voordat er gekeken wordt naar andere hosts. +message.update.resource.count=Bevestig dat u de verbruiksstatistieken voor deze account wilt bijwerken. +message.update.ssl=Geef een nieuw X.509 compliant SSL certificaat in waarmee elke console proxy en secundaire opslag instantie mee geupdate kunnen worden\: +message.validate.accept=Gelieve een waarde in te geven met een geldidge extensie. +message.validate.creditcard=Gelieve een geldig credit card nummer in te geven. +message.validate.date=Gelieve een geldige datum in te geven. +message.validate.date.ISO=Gelieve een geldige datum (ISO) in te geven. +message.validate.digits=Gelieve alleen cijfers in te geven. +message.validate.email.address=Gelieve een geldig email adres in te geven. +message.validate.equalto=Voer dezelfde waarde nogmaals in. +message.validate.fieldrequired=Dit veld is vereist +message.validate.fixfield=Gelieve dit veld te herstellen. +message.validate.instance.name=Namen van instantie kunnen niet langer zijn dan 63 karakters. Alleen ASCII letters a~z, A~Z, cijfers 0~9 zijn toegestaan. Moet beginnen met een letter en mag eindigen met een letter of cijfer. +message.validate.invalid.characters=Niet toegestane karakters gevonden, corrigeer deze. +message.validate.max=Gelieve een waarde kleiner of gelijk aan {0} in te geven. +message.validate.maxlength=Gelieve niet meer dan {0} karakters in te geven. +message.validate.minlength=Gelieve minimaal {0} karakters in te geven. +message.validate.number=Gelieve een geldig nummer in te geven. +message.validate.range=Gelieve een waarde tussen {0} en {1} in te geven. +message.validate.range.length=Gelieve een waarde tussen de {0} en {1} karakters lang in te geven. +message.validate.URL=Gelieve een geldige URL in te geven. +message.virtual.network.desc=Een dedicated gevirtualiseerd netwerk voor uw account. Het broadcast domein is ingesloten binnen een VLAN en toegang naar het publieke netwerk wordt gerouteerd door een virtueele router. +message.vm.create.template.confirm=Creer een template welke de VM atuomatisch laat opstarten. +message.vm.review.launch=Gelieve de volgende gegevens te verifi\u00ebren te bevestigen zodat uw instantie gestart kan worden. +message.vnmc.available.list=VNMC is niet beschikbaar van de provider lijst. +message.vnmc.not.available.list=VNMC is niet beschikbaar van de provider lijst. +message.volume.create.template.confirm=Bevestig dat u een template wilt maken van dit schijf volume. Het maken van een template kan meerdere minuten duren maar soms ook langer afhankelijk van de grootte van het volume. +message.waiting.for.builtin.templates.to.load=Wachten totdat ingebouwde templates zijn geladen... +message.XSTools61plus.update.failed=Kon XenServer Tools Version 6.1\\+ field niet updaten. Fout\: +message.you.must.have.at.least.one.physical.network=U moet minimaal \u00e9\u00e9n fysiek netwerk hebben +message.your.cloudstack.is.ready=Uw CloudStack is klaar\! +message.Zone.creation.complete=De installatie van de zone is compleet +message.zone.creation.complete.would.you.like.to.enable.this.zone=De installatie van de zone is compleet, wilt u deze zone meteen inschakelen? +message.zone.no.network.selection=De geselecteerde zone heeft geen meerdere netwerk selectie mogelijkheden. +message.zone.step.1.desc=Selecteer een netwerk model voor uw zone. +message.zone.step.2.desc=Specificeer de volgende gegevens om een nieuwe zone toe te voegen +message.zone.step.3.desc=Specificeer de volgende gegevens om een nieuwe pod toe te voegen +message.zoneWizard.enable.local.storage=WAARSCHUWING\: Als u lokale opslag activeert voor deze zone, moet u de volgende stappen ondernemen afhankelijk van het opslagsysteem waar u de systeem VMs vanaf wilt starten\:

1. Wanneer de systeem VMs gestart moeten worden van primaire (gedeelde) opslag moet deze nadat configuratie van de zone klaar is, toegevoegd worden.

2. Wanneer de systeem VMs gestart moeten worden vanaf lokale opslag, dient de parameter system.vm.use.local.storage gezet zijn voordat u de zone activeert.


Weet u zeker dat u verder wilt gaan? +messgae.validate.min=Gelieve een waarde groter of gelijk aan {0} in te geven. mode=Modus +network.rate=Netwerk Snelheid notification.reboot.instance=Herstart instantie +notification.start.instance=Start Instantie +notification.stop.instance=Stop Instantie +side.by.side=Zij aan Zij +state.Accepted=Geaccepteerd +state.Active=Actief state.Allocated=Gebruikt +state.Allocating=Alloceren +state.BackedUp=Geback-upt +state.BackingUp=Back-uppen +state.Completed=Uitgevoerd +state.Creating=Aanmaken +state.Declined=Geweigerd +state.Destroyed=Verwijderd state.Disabled=Uitgeschakeld +state.enabled=Geactiveerd +state.Enabled=Geactiveerd state.Error=Fout +state.Expunging=Opruimen +state.Migrating=MIgreren +state.Pending=In afwachting +state.ready=Klaar +state.Ready=Klaar +state.Running=Draaiend +state.Starting=Starten +state.Stopped=Gestopt +state.Stopping=Stoppen +state.Suspended=Gepauzeerd +ui.listView.filters.all=Alle +ui.listView.filters.mine=Eigen diff --git a/client/WEB-INF/classes/resources/messages_pl.properties b/client/WEB-INF/classes/resources/messages_pl.properties index 84808f818d..06d5ec2dbd 100644 --- a/client/WEB-INF/classes/resources/messages_pl.properties +++ b/client/WEB-INF/classes/resources/messages_pl.properties @@ -245,6 +245,7 @@ label.email=Poczta label.enable.vpn=W\u0142\u0105cz VPN label.error=B\u0142\u0105d label.f5=F5 +label.failed=B\u0142\u0105d label.featured=Polecane label.filterBy=Filtrowanie wg label.firewall=Zapora @@ -270,6 +271,7 @@ label.invited.accounts=Zaproszone konta label.invite.to=Zapro\u015b do label.invite=Zapro\u015b label.ip=IP +label.ips=IP label.iso=ISO label.keep=Zostaw label.key=Klucz @@ -280,6 +282,7 @@ label.lang.korean=Korea\u0144ski label.lang.russian=Rosyjski label.lang.spanish=Hiszpia\u0144ski label.last.name=Nazwisko +label.launch=Rozpocznij label.least.connections=Ostatnie po\u0142\u0105czenie label.level=Poziom label.loading=Wczytywanie @@ -313,6 +316,7 @@ label.menu.network=Sie\u0107 label.menu.regions=Regiony label.menu.system=System label.minimum=Minimum +label.mode=Tryb label.monday=Poniedzia\u0142ek label.monthly=Miesi\u0119cznie label.move.down.row=Jeden rz\u0105d na d\u00f3\u0142 @@ -382,6 +386,7 @@ label.select.project=Wybierz projekt label.select=Wybierz label.sent=Wys\u0142ano label.server=Serwer +label.setup=Konfiguracja label.size=Wielko\u015bc label.specify.IP.ranges=Wyszczeg\u00f3lnij zasi\u0119g adres\u00f3w IP label.srx=SRX diff --git a/client/WEB-INF/classes/resources/messages_pt_BR.properties b/client/WEB-INF/classes/resources/messages_pt_BR.properties index 1bcdc9ce1b..8ee08ba3cb 100644 --- a/client/WEB-INF/classes/resources/messages_pt_BR.properties +++ b/client/WEB-INF/classes/resources/messages_pt_BR.properties @@ -15,21 +15,23 @@ # specific language governing permissions and limitations # under the License. -changed.item.properties=Alteradas propriedades do item -confirm.enable.s3=Por favor preencha as informa\u00e7\u00f5es abaixo para habilitar suporte a storage secund\u00e1ria fornecida por S3 -confirm.enable.swift=Por favor preencha as informa\u00e7\u00f5es abaixo para habilitar suporte ao Swift +changed.item.properties=Propriedades do item alteradas +confirm.enable.s3=Por favor, preencha as informa\u00e7\u00f5es abaixo para habilitar suporte o Storage Secund\u00e1rio fornecido por S3 +confirm.enable.swift=Por favor, preencha as informa\u00e7\u00f5es abaixo para habilitar suporte ao Swift +error.could.not.change.your.password.because.ldap.is.enabled=Erro\: a nuvem n\u00e3o alterou sua senha porque o LDAP est\u00e1 ativo. error.could.not.enable.zone=N\u00e3o foi poss\u00edvel habilitar a zona error.installWizard.message=Alguma coisa est\u00e1 errada; voc\u00ea pode voltar e corrigir quaisquer erros error.invalid.username.password=Usu\u00e1rio ou senha inv\u00e1lidos -error.login=Usu\u00e1rio ou senha inv\u00e1lido. +error.login=O seu usu\u00e1rio/senha n\u00e3o coincidem com nossos registros. error.menu.select=N\u00e3o foi poss\u00edvel realizar a a\u00e7\u00e3o pois nenhum item foi selecionado. -error.mgmt.server.inaccessible=O servidor de gerenciamento est\u00e1 inacess\u00edvel. Tente novamente mais tarde. +error.mgmt.server.inaccessible=O Servidor de Gerenciamento est\u00e1 inacess\u00edvel. Tente novamente mais tarde. error.password.not.match=Os campos de senha n\u00e3o combinam -error.please.specify.physical.network.tags=Ofertas de Rede n\u00e3o estar\u00e3o dispon\u00edveis enquanto voc\u00ea n\u00e3o especificar tags para esta interface f\u00edsica. +error.please.specify.physical.network.tags=As Ofertas de Rede n\u00e3o estar\u00e3o dispon\u00edveis enquanto voc\u00ea n\u00e3o especificar tags para esta interface f\u00edsica. error.session.expired=Sua sess\u00e3o expirou. -error.something.went.wrong.please.correct.the.following=Algo deu errado; por favor corrija abaixo +error.something.went.wrong.please.correct.the.following=Alguma coisa est\u00e1 errada; por favor corrija abaixo error.unable.to.reach.management.server=N\u00e3o foi poss\u00edvel acessar o Servidor de Gerenciamento error.unresolved.internet.name=Imposs\u00edvel resolver DNS +extractable=Extra\u00edvel force.delete.domain.warning=Aten\u00e7\u00e3o\: Esta op\u00e7\u00e3o remover\u00e1 todos os dom\u00ednios, contas e recursos associados. force.delete=For\u00e7ar Exclus\u00e3o force.remove=For\u00e7ar Remo\u00e7\u00e3o @@ -39,7 +41,10 @@ force.stop.instance.warning=Aviso\: For\u00e7ar o desligamento desta inst\u00e2n ICMP.code=C\u00f3digo ICMP ICMP.type=Tipo ICMP image.directory=Diret\u00f3rio da Imagem +inline=Inline instances.actions.reboot.label=Reiniciar inst\u00e2ncia +label.about.app=Sobre o CloudStack +label.about=Sobre label.accept.project.invitation=Aceitar convite de projeto. label.account.and.security.group=Contas, grupos de Seguran\u00e7a label.account=Conta @@ -48,6 +53,7 @@ label.account.name=Nome da Conta label.accounts=Contas label.account.specific=Conta-Specific label.acquire.new.ip=Adquirir novo IP +label.acquire.new.secondary.ip=Adquira um novo IP secund\u00e1rio label.action.attach.disk=Anexar Disco label.action.attach.disk.processing=Anexando Disco.... label.action.attach.iso=Anexar ISO @@ -90,6 +96,7 @@ label.action.delete.load.balancer=Remover regra de balanceador de carga label.action.delete.network.processing=Removendo Rede.... label.action.delete.network=Remover Rede label.action.delete.nexusVswitch=Remover NexusVswitch +label.action.delete.nic=Remover Interface de Rede label.action.delete.physical.network=Deletar rede f\u00edsica label.action.delete.pod.processing=Removendo POD.... label.action.delete.pod=Remover POD @@ -112,8 +119,8 @@ label.action.delete.volume.processing=Removendo Disco.... label.action.delete.volume=Remover Disco label.action.delete.zone.processing=Removendo Zona.... label.action.delete.zone=Remover Zona -label.action.destroy.instance=Apagar Cloud Server -label.action.destroy.instance.processing=Apagando Cloud Server.... +label.action.destroy.instance=Apagar Inst\u00e2ncia +label.action.destroy.instance.processing=Apagando Inst\u00e2ncia.... label.action.destroy.systemvm=Apagar VM de Sistema label.action.destroy.systemvm.processing=Apagando VM de Sistema.... label.action.detach.disk=Desplugar Disco @@ -143,7 +150,7 @@ label.action.edit.disk.offering=Editar Oferta de Disco label.action.edit.domain=Editar Dom\u00ednio label.action.edit.global.setting=Editar Configura\u00e7\u00f5es Globais label.action.edit.host=Editar Host -label.action.edit.instance=Editar Cloud Server +label.action.edit.instance=Editar Inst\u00e2ncia label.action.edit.ISO=Editar ISO label.action.edit.network=Editar Rede label.action.edit.network.offering=Editar Oferta de Rede @@ -171,6 +178,8 @@ label.action.enable.user=Habilitar usu\u00e1rio label.action.enable.user.processing=Habilitando Usu\u00e1rio... label.action.enable.zone=Ativar Zona label.action.enable.zone.processing=Ativando Zona.... +label.action.expunge.instance=Eliminar Inst\u00e2ncia +label.action.expunge.instance.processing=Expurgando Inst\u00e2ncia.... label.action.force.reconnect=Force Reconnect label.action.force.reconnect.processing=Reconectando.... label.action.generate.keys=Gerar Chaves @@ -180,18 +189,19 @@ label.action.lock.account=Bloquear conta label.action.lock.account.processing=Bloqueando conta.... label.action.manage.cluster.processing=Vinculando o Cluster.... label.action.manage.cluster=Vincular Cluster -label.action.migrate.instance=Migrar Cloud Server -label.action.migrate.instance.processing=Migrando Cloud Server... +label.action.migrate.instance=Migrar Inst\u00e2ncia +label.action.migrate.instance.processing=Migrando Inst\u00e2ncia.... label.action.migrate.router=Migrar Roteador label.action.migrate.router.processing=Migrando Roteador... label.action.migrate.systemvm=Migrar VM de Sistema label.action.migrate.systemvm.processing=Migrando VM de Sistema... -label.action.reboot.instance.processing=Reiniciando Cloud Server... -label.action.reboot.instance=Reiniciar Cloud Server +label.action.reboot.instance.processing=Reiniciando Inst\u00e2ncia... +label.action.reboot.instance=Reiniciar Inst\u00e2ncia label.action.reboot.router.processing=Reiniciando Roteador.... label.action.reboot.router=Reiniciar Roteador label.action.reboot.systemvm.processing=Reiniciando VM de Sistema.... label.action.reboot.systemvm=Reiniciar VM de Sistema +label.action.recurring.snapshot=Snapshots recorrentes label.action.register.iso=Registrar ISO label.action.register.template=Registrar template label.action.release.ip=Liberar IP @@ -203,17 +213,19 @@ label.action.reset.password=Recuperar Senha label.action.resize.volume.processing=Resizing Volume.... label.action.resize.volume=Resize Volume label.action.resource.limits=Limite de Recursos -label.action.restore.instance.processing=Restaurando Cloud Server... -label.action.restore.instance=Restaurar Cloud Server -label.actions=A\u00c3\u00a7\u00c3\u00b5es -label.action.start.instance=Iniciar Cloud Server -label.action.start.instance.processing=Iniciando Cloud Server... +label.action.restore.instance.processing=Restaurando Inst\u00e2ncia... +label.action.restore.instance=Restaurar Inst\u00e2ncia +label.action.revert.snapshot.processing=Revertendo para Snapshot... +label.action.revert.snapshot=Reverter para Snapshot +label.actions=A\u00e7\u00f5es +label.action.start.instance=Iniciar Inst\u00e2ncia +label.action.start.instance.processing=Iniciando Inst\u00e2ncia... label.action.start.router=Iniciar Roteador label.action.start.router.processing=Iniciando Roteador.... label.action.start.systemvm=Iniciar VM de Sistema label.action.start.systemvm.processing=Iniciando VM de Sistema.... -label.action.stop.instance=Parar Cloud Server -label.action.stop.instance.processing=Parando Cloud Server... +label.action.stop.instance=Parar Inst\u00e2ncia +label.action.stop.instance.processing=Parando Inst\u00e2ncia... label.action.stop.router=Parar Roteador label.action.stop.router.processing=Parando Roteador.... label.action.stop.systemvm=Parar VM de Sistema @@ -226,6 +238,9 @@ label.action.update.OS.preference=Atualizar Prefer\u00eancia de SO label.action.update.OS.preference.processing=Atualizando Prefer\u00eancia de SO.... label.action.update.resource.count=Atualiza Contador de Recursos label.action.update.resource.count.processing=Atualizando Contador de Recursos.... +label.action.vmsnapshot.create=Fazer Snapshot de VM +label.action.vmsnapshot.delete=Remover snapshot de VM +label.action.vmsnapshot.revert=Reverter snapshot de VM label.activate.project=Ativar Projeto label.active.sessions=Sess\u00f5es Ativas label.add.account=Adicionar Conta @@ -234,6 +249,8 @@ label.add.accounts.to=Adicionar contas para label.add.account.to.project=Adicionar conta ao projeto label.add.ACL=Adicionar ACL label.add=Adicionar +label.add.affinity.group=Adicionar um grupo de afinidade +label.add.BigSwitchVns.device=Adicionar BigSwitch Vns Controller label.add.by=Adicionado por label.add.by.cidr=Adicionar por CIDR label.add.by.group=Adicionar por Grupo @@ -268,12 +285,16 @@ label.add.network.offering=Adicionar oferta de rede label.add.new.F5=Adicionar um novo F5 label.add.new.gateway=Adicionar novo gateway label.add.new.NetScaler=Adicionar um novo NetScaler +label.add.new.PA=Adicionar novo Palo Alto label.add.new.SRX=Adicionar um novo SRX label.add.new.tier=Adicionar nova camada +label.add.NiciraNvp.device=Adicionar Controlador Nvp +label.add.PA.device=Adicionar dispositivo Palo Alto label.add.physical.network=Adicionar rede f\u00edsica label.add.pod=Adicionar POD label.add.port.forwarding.rule=Adicionar regra de encaminhamento de porta label.add.primary.storage=Adicionar Storage Prim\u00e1rio +label.add.region=Adicionar Regi\u00e3o label.add.resources=Adicionar Recursos label.add.route=Adicionar rota label.add.rule=Adicionar regra @@ -288,7 +309,6 @@ label.add.template=Adicionar Template label.add.to.group=Adicionar ao grupo label.add.user=Adicionar Usu\u00e1rio label.add.vlan=Adicionar VLAN -label.add.vxlan=Adicionar VXLAN label.add.vm=Adicionar VM label.add.vms=Adicionar VMs label.add.vms.to.lb=Add VM(s) na regra de balanceamento de carga @@ -298,12 +318,16 @@ label.add.vpc=Adicionar VPC label.add.vpn.customer.gateway=Adicionar Gateway de VPN de usu\u00e1rio label.add.VPN.gateway=Adicionar gateway de VPN label.add.vpn.user=Adicionar usu\u00e1rio VPN +label.add.vxlan=Adicionar VXLAN label.add.zone=Adicionar Zona label.admin.accounts=Contas Administrativas label.admin=Administrador label.advanced=Avan\u00e7ado label.advanced.mode=Modo Avan\u00e7ado label.advanced.search=Busca Avan\u00e7ada +label.affinity=Afinidade +label.affinity.group=Grupo de Afinidade +label.affinity.groups=Grupos de Afinidade label.agent.password=Senha do Agente label.agent.username=Usu\u00e1rio do Agente label.agree=Concordo @@ -311,13 +335,21 @@ label.alert=Alerta label.algorithm=Algoritmo label.allocated=Alocado label.allocation.state=Status da Aloca\u00e7\u00e3o +label.anti.affinity=Anti-afinidade +label.anti.affinity.group=Grupo de Anti-afinidade +label.anti.affinity.groups=Grupos de Anti-afinidade label.api.key=API Key label.apply=Aplicar +label.app.name=CloudStack +label.archive.alerts=Guardar alertas +label.archive.events=Guardar eventos label.assign=Atribuir -label.assign.to.load.balancer=Atribuindo o Cloud Server ao Load Balancer +label.assign.to.load.balancer=Atribuindo Inst\u00e2ncia ao balanceador de carga label.associated.network.id=ID de Rede Associado label.associated.network=Rede associada label.attached.iso=Imagem ISO Plugada +label.author.email=E-mail do autor +label.author.name=Nome do autor label.availability=Availability label.availability.zone=Datacenter label.available=Dispon\u00edvel @@ -326,14 +358,19 @@ label.back=Voltar label.bandwidth=Bandwidth label.basic=B\u00e1sico label.basic.mode=Modo B\u00e1sico +label.bigswitch.controller.address=Endere\u00e7o do Controlador BigSwitch Vns label.bootable=Inicializ\u00e1vel label.broadcast.domain.range=Range do dom\u00ednio de Broadcast label.broadcast.domain.type=Tipo de Dom\u00ednio Broadcast label.broadcast.uri=URI de broadcast label.by.account=por Conta +label.by.alert.type=Por tipo de alerta label.by.availability=By Availability +label.by.date.end=Por data (final) +label.by.date.start=Por data (in\u00edcio) label.by.domain=por Dom\u00ednio label.by.end.date=por Data Final +label.by.event.type=Por tipo de evento label.by.level=por N\u00edvel label.by.pod=por Pod label.by.role=por Fun\u00e7\u00e3o @@ -370,7 +407,9 @@ label.clvm=CLVM label.code=C\u00f3digo label.community=Comunidade label.compute.and.storage=Processamento e Armazenamento +label.compute=Computa\u00e7\u00e3o label.compute.offering=Oferta de Computa\u00e7\u00e3o +label.compute.offerings=Oferta de Computa\u00e7\u00e3o label.configuration=Configura\u00e7\u00e3o label.configure=Configurar label.configure.ldap=Configurar LDAP @@ -379,6 +418,7 @@ label.configure.vpc=Configurar VPC label.confirmation=Confirma\u00e7\u00e3o label.confirm.password=Confirme a senha label.congratulations=Parab\u00e9ns\! +label.conserve.mode=Modo Conservativo label.console.proxy=Console proxy label.continue.basic.install=Continuar com a instala\u00e7\u00e3o b\u00e1sica label.continue=Continuar @@ -387,6 +427,7 @@ label.cpu.allocated=CPU Alocada label.cpu.allocated.for.VMs=CPU Alocada por VMs label.CPU.cap=CPU Cap label.cpu=CPU +label.cpu.limits=Limite de CPU label.cpu.mhz=CPU (em MHz) label.cpu.utilized=CPU Utilizada label.created.by.system=Criado pelo sistema @@ -396,6 +437,7 @@ label.create.project=Criar um projeto label.create.template=Criar template label.create.VPN.connection=Criar uma conex\u00e3o VPN label.cross.zones=Inter Zonas +label.custom.disk.iops=IOPS personalizado label.custom.disk.size=Tamanho Customizado label.daily=Di\u00e1rio label.data.disk.offering=Oferta de Disco Adicional @@ -408,9 +450,15 @@ label.dedicated=Dedicado label.default=Padr\u00e3o label.default.use=Uso padr\u00e3o label.default.view=Vis\u00e3o Padr\u00e3o +label.delete.affinity.group=Deletar Grupo de Afinidade +label.delete.alerts=Remover alertas +label.delete.BigSwitchVns=Remover Controlador BigSwitch Vns +label.delete.events=Remover eventos label.delete.F5=Remover F5 label.delete.gateway=delete gateway label.delete.NetScaler=Remover NetScaler +label.delete.NiciraNvp=Remover Controlador Nvp +label.delete.PA=Remover Palo Alto label.delete.project=Deletar projeto label.delete=Remover label.delete.SRX=Remover SRX @@ -438,11 +486,22 @@ label.disable.provider=Desabilitar Provider label.disable.vpn=Desabilitar VPN label.disabling.vpn.access=Desativando Acesso VPN label.disk.allocated=Disco Alocado +label.disk.bytes.read.rate=Taxa de Leitura do Disco (BPS) +label.disk.bytes.write.rate=Taxa de Escrita no Disco (BPS) +label.disk.iops.max=M\u00e1x IOPS +label.disk.iops.min=M\u00edn IOPS +label.disk.iops.read.rate=Taxa de Leitura do Disco (IOPS) +label.disk.iops.total=IOPS Total +label.disk.iops.write.rate=Taxa de Escrita no Disco (IOPS) label.disk.offering=Oferta de Disco +label.disk.read.bytes=Leitura do Disco (Bytes) +label.disk.read.io=Leitura do Disk (I/O) label.disk.size.gb=Tamanho (em GB) label.disk.size=Tamanho do Disco label.disk.total=Disco Total label.disk.volume=Disco +label.disk.write.bytes=Escrita no Disco (Bytes) +label.disk.write.io=Escrita no Disco (I/O) label.display.name=Nome de exibi\u00e7\u00e3o label.display.text=Descri\u00e7\u00e3o label.dns.1=DNS 1 @@ -459,6 +518,7 @@ label.done=Pronto label.double.quotes.are.not.allowed=Aspas duplas n\u00e3o s\u00e3o permitidas label.download.progress=Status do Download label.drag.new.position=Arrastar para uma nova posi\u00e7\u00e3o +label.edit.affinity.group=Editar Grupo de Afinidade label.edit=Editar label.edit.lb.rule=Editar regra de LB label.edit.network.details=Editar detalhes de rede @@ -466,6 +526,7 @@ label.edit.project.details=Editar detalhes do projeto label.edit.tags=Edite etiquetas label.edit.traffic.type=Editar tipo de tr\u00e1fego label.edit.vpc=Editar VPC +label.egress.default.policy=Pol\u00edtica de Entrada Padr\u00e3o label.egress.rule=Regra Egress label.egress.rules=Regras de sa\u00edda label.elastic=El\u00e1stico @@ -490,9 +551,12 @@ label.error.code=C\u00f3digo de Erro label.error=Erro label.ESP.encryption=Encripta\u00e7\u00e3o ESP label.ESP.hash=Hash ESP +label.ESP.lifetime=Tempo de vida do ESP (segundos) label.ESP.policy=Pol\u00edtica ESP label.esx.host=ESX/ESXi Host label.example=Examplo +label.expunge=Eliminar +label.external.link=Link externo label.f5=F5 label.failed=Falhou label.featured=Featured @@ -507,6 +571,7 @@ label.full.path=Path completo label.gateway=Gateway label.general.alerts=Alertas Gerais label.generating.url=Criando URL +label.gluster.volume=Disco label.go.step.2=V\u00e1 para passo 2 label.go.step.3=V\u00e1 para passo 3 label.go.step.4=V\u00e1 para passo 4 @@ -519,7 +584,7 @@ label.guest.gateway=Gateway de rede Convidado label.guest=Guest label.guest.ip=Endere\u00e7o IP Convidado label.guest.ip.range=Intervalo de rede convidado -label.guest.netmask=M\u00e1scara de rede Convidado +label.guest.netmask=M\u00e1scara de rede Guest label.guest.networks=Redes Guest label.guest.start.ip=IP de in\u00edcio do guest label.guest.traffic=Tr\u00e1fego de h\u00f3spedes @@ -528,6 +593,7 @@ label.ha.enabled=HA Ativado label.help=Ajuda label.hide.ingress.rule=Ocultar Regra de Entrada label.hints=Dicas +label.home=Home label.host.alerts=Alertas de Host label.host=Host label.host.MAC=Host MAC @@ -537,12 +603,15 @@ label.host.tags=Tags de Host label.hourly=A cada hora label.hypervisor.capabilities=Recursos de Virtualizador label.hypervisor=Hipervisor +label.hypervisors=Hypervisors +label.hypervisor.snapshot.reserve=Reserva de Snapshot do Hypervisor label.hypervisor.type=Tipo do Hypervisor label.hypervisor.version=Vers\u00e3o de Virtualizador label.id=ID label.IKE.DH=DH IKE label.IKE.encryption=Encripta\u00e7\u00e3o IKE label.IKE.hash=Hash IKE +label.IKE.lifetime=Tempo de vida IKE (segundos) label.IKE.policy=Pol\u00edtica IKE label.info=Info label.ingress.rule=Regra de Entrada @@ -563,10 +632,10 @@ label.installWizard.addZone.title=Adicionar zona label.installWizard.click.launch=Click no bot\u00e3o executar. label.installWizard.subtitle=Este tour vai auxiliar voc\u00ea na configura\u00e7\u00e3o da sua instala\u00e7\u00e3o de CloudStack&\#8482 label.installWizard.title=Ol\u00e1, seja bem vindo ao CloudStack&\#8482 -label.instance=Cloud Server -label.instance.limits=Limites do Cloud Server -label.instance.name=Nome do Cloud Server -label.instances=Cloud Servers +label.instance=Inst\u00e2ncia +label.instance.limits=Limites da Inst\u00e2ncia +label.instance.name=Nome da Inst\u00e2ncia +label.instances=Inst\u00e2ncias label.internal.dns.1=DNS 1 Interno label.internal.dns.2=DNS 2 Interno label.internal.name=Nome interno @@ -605,12 +674,19 @@ label.keyboard.type=Tipo de Teclado label.key=Chave label.kvm.traffic.label=Etiqueta de tr\u00e1fego KVM label.label=Etiqueta +label.lang.arabic=Arabe label.lang.brportugese=Portugu\u00eas brasileiro +label.lang.catalan=Catal\u00e3o label.lang.chinese=Chinese (Simplified) +label.lang.dutch=Holand\u00eas (Holanda) label.lang.english=English label.lang.french=Franc\u00eas +label.lang.german=Alem\u00e3o +label.lang.italian=Italiano label.lang.japanese=Japanese label.lang.korean=Coreano +label.lang.norwegian=Noruegu\u00eas +label.lang.polish=Polon\u00eas label.lang.russian=Russo label.lang.spanish=Spanish label.last.disconnected=Last Disconnected @@ -625,6 +701,7 @@ label.ldap.group.name=Grupo LDAP label.ldap.port=Porta do LDAP label.least.connections=Least connections label.level=N\u00edvel +label.linklocal.ip=Endere\u00e7o IP do Link Local label.load.balancer=Load Balancer label.load.balancing=Balanceamento de Carga label.load.balancing.policies=Pol\u00edticas de balanceamento de carga @@ -641,16 +718,22 @@ label.manage=Gerenciar label.management=Gerenciamento label.management.ips=Gerenciamento de Endere\u00e7os IP label.manage.resources=Gerenciar Recursos +label.max.cpus=M\u00e1ximo de cores de CPU label.max.guest.limit=Limite m\u00e1x. de guest label.maximum=M\u00e1ximo +label.max.memory=M\u00e1x. de mem\u00f3ria (MiB) label.max.networks=M\u00e1x. de redes +label.max.primary.storage=M\u00e1x. prim\u00e1rio (GiB) label.max.public.ips=M\u00e1x. IPs p\u00fablicos +label.max.secondary.storage=Max. Secund\u00e1rio (GiB) label.max.snapshots=Max. snapshots label.max.templates=M\u00e1x. templates label.max.vms=M\u00e1x. VMs de usu\u00e1rio label.max.volumes=M\u00e1x. volumes +label.max.vpcs=M\u00e1x. VPCs label.may.continue=Voc\u00ea pode continuar agora label.memory.allocated=Mem\u00f3ria Alocada +label.memory.limits=Limites de mem\u00f3ria (MiB) label.memory.mb=Mem\u00f3ria (em MB) label.memory=Mem\u00f3ria (em MB) label.memory.total=Mem\u00f3ria Total @@ -658,34 +741,35 @@ label.memory.used=Mem\u00f3ria Usada label.menu.accounts=Contas label.menu.alerts=Alertas label.menu.all.accounts=Todas as Contas -label.menu.all.instances=Todos Cloud Servers +label.menu.all.instances=Todas Inst\u00e2ncias label.menu.community.isos=ISOs P\u00fablicas label.menu.community.templates=Templates P\u00fablicos label.menu.configuration=Configura\u00e7\u00e3o label.menu.dashboard=Dashboard -label.menu.destroyed.instances=Cloud Servers Apagados +label.menu.destroyed.instances=Inst\u00e2ncias Apagadas label.menu.disk.offerings=Oferta de Discos -label.menu.domains=dom\u00ednios +label.menu.domains=Dom\u00ednios label.menu.events=Eventos label.menu.featured.isos=ISOs Customizada label.menu.featured.templates=Templates Customizados label.menu.global.settings=Configura\u00e7\u00f5es Globais label.menu.infrastructure=Infra-estrutura -label.menu.instances=Cloud Servers +label.menu.instances=Inst\u00e2ncias label.menu.ipaddresses=Endere\u00e7os IP label.menu.isos=ISOs label.menu.my.accounts=Minhas Contas -label.menu.my.instances=Meus Cloud Servers +label.menu.my.instances=Minhas Inst\u00e2ncias label.menu.my.isos=Minhas ISOs label.menu.my.templates=Meus Templates label.menu.network.offerings=Oferta de Rede label.menu.network=Rede label.menu.physical.resources=Recursos B\u00e1\u00adsicos -label.menu.running.instances=Cloud Servers Rodando +label.menu.regions=Regi\u00f5es +label.menu.running.instances=Inst\u00e2ncias Rodando label.menu.security.groups=Grupos de seguran\u00e7a -label.menu.service.offerings=Planos +label.menu.service.offerings=Oferta de Servi\u00e7os label.menu.snapshots=Snapshots -label.menu.stopped.instances=Cloud Servers Parados +label.menu.stopped.instances=Inst\u00e2ncias Paradas label.menu.storage=Storage label.menu.system.service.offerings=Ofertas do Sistema label.menu.system=Sistema @@ -695,18 +779,21 @@ label.menu.virtual.appliances=Appliance Virtual label.menu.virtual.resources=Recursos Virtuais label.menu.volumes=Discos label.migrate.instance.to.host=Migrar inst\u00e2ncia para outro host -label.migrate.instance.to=Migrar Cloud Server para +label.migrate.instance.to=Migrar Inst\u00e2ncia para label.migrate.instance.to.ps=Migrar inst\u00e2ncia para outro storage prim\u00e1rio label.migrate.router.to=Migrar Roteador para label.migrate.systemvm.to=Migrar VM de sistema para label.migrate.to.host=Migrar para outro host +label.migrate.to.storage=Migrar para storage label.migrate.volume=Migrar volume para outro storage prim\u00e1rio label.minimum=M\u00ed\u00adnimo label.minute.past.hour=minuto(s) \u00daltima hora +label.mode=Modo label.monday=Segunda label.monthly=Mensal label.more.templates=Mais Templates label.move.down.row=Mover uma c\u00e9lula para baixo +label.move.to.bottom=Mover para baixo label.move.to.top=Mover para o topo label.move.up.row=Mover uma c\u00e9lula para cima label.my.account=Minha Conta @@ -715,10 +802,11 @@ label.my.templates=Meus templates label.name=Nome label.name.optional=Nome (Opcional) label.nat.port.range=Range de Portas NAT -label.netmask=M\u00c3\u00a1srca de Rede +label.netmask=M\u00e1scara de Rede label.netScaler=NetScaler label.network.ACL=ACL de rede label.network.ACLs=Network ACLs +label.network.ACL.total=Total de rede ACL label.network.desc=Descri\u00e7\u00e3o de Rede label.network.device=Dispositivo de Rede label.network.device.type=Tipo de Dispositivo de Rede @@ -727,11 +815,13 @@ label.network.domain.text=Texto do dom\ufffdnio de rede label.network.id=ID de Rede label.networking.and.security=Rede e seguran\u00e7a label.network.label.display.for.blank.value=Utilizar gateway default +label.network.limits=Limites de rede label.network.name=Nome da Rede label.network.offering.display.text=Network Offering Display Text label.network.offering.id=Network Offering ID label.network.offering.name=Network Offering Name label.network.offering=Network Offering +label.network.rate.megabytes=Taxa de Rede (MB/s) label.network.rate=Taxa de Transfer\u00eancia label.network.read=Network Read label.network=Rede @@ -748,8 +838,11 @@ label.nexusVswitch=Nexus Vswitch label.nfs=NFS label.nfs.server=Servidor NFS label.nfs.storage=Storage NFS -label.nic.adapter.type=Tipo de adaptador NIC -label.nics=REDE +label.nic.adapter.type=Tipo de adaptador de Rede +label.nicira.controller.address=Endere\u00e7o do Controlador +label.nicira.l3gatewayserviceuuid=Uuid do Servi\u00e7o de Gateway L3 +label.nicira.transportzoneuuid=Uuid da Zona de Transporte +label.nics=Adaptadores de Rede label.no.actions=Sem A\u00e7\u00f5es Dispon\u00edveis label.no.alerts=Sem Alertas Recentes label.no.data=Sem dados para mostrar @@ -780,10 +873,14 @@ label.os.type=Tipo de SO label.owned.public.ips=IP P\u00fablico Utilizado label.owner.account=Dono da Conta label.owner.domain=Dono do Dom\u00ednio +label.PA.log.profile=Palo Alto Log Profile +label.PA=Palo Alto label.parent.domain=Dom\u00ednio Principal label.password.enabled=Senha Ativada label.password=Senha label.path=Caminho (Path) +label.PA.threat.profile=Palo Alto Threat Profile +label.perfect.forward.secrecy=Perfect Forward Secrecy label.physical.network.ID=ID da rede f\u00edsica label.physical.network=Rede F\u00edsica label.PING.CIFS.password=PING CIFS password @@ -793,6 +890,8 @@ label.PING.storage.IP=Disparar PING para IP do Storage label.planner.mode=Modo planejado label.please.specify.netscaler.info=Por favor especifique as informa\u00e7\u00f5es do Netscaler label.please.wait=Por Favor Aguarde +label.plugin.details=Detalhes do plugin +label.plugins=Plugins label.pod.name=Nome do Pod label.pod=POD label.pods=Pods @@ -806,6 +905,7 @@ label.prev=Prev label.primary.allocated=Aloca\u00e7\u00e3o do Storage Prim\u00e1rio label.primary.network=Rede Prim\u00e1ria label.primary.storage.count=Pools de Storage Prim\u00e1rios +label.primary.storage.limits=Limites do Storage Prim\u00e1rio (GiB) label.primary.storage=Storage Prim\u00e1rio label.primary.used=Uso do Storage Prim\u00e1rio label.private.Gateway=Gateway privado @@ -836,6 +936,7 @@ label.public.traffic=Tr\u00e1fego P\u00fablico label.public.zone=Zona P\u00fablica label.purpose=Prop\u00f3sito label.Pxe.server.type=Tipo de Servidor PXE +label.qos.type=Tipo de QoS label.quickview=Visualiza\u00e7\u00e3o r\u00e1pida label.quiesce.vm=Quiesce VM label.rbd.id=Usu\u00e1rio Ceph @@ -847,17 +948,20 @@ label.reboot=Reiniciar label.recent.errors=Erros Recentes label.redundant.router.capability=Recurso de roteador redundante label.redundant.router=Roteador Redundantee +label.redundant.state=Estado redundante label.refresh=Atualizar +label.region=Regi\u00e3o label.related=Relacionado label.remind.later=Me lembre depois label.remove.ACL=Remove ACL label.remove.egress.rule=Remover regra egress -label.remove.from.load.balancer=Removendo Cloud Server do Load Balancer +label.remove.from.load.balancer=Removendo Inst\u00e2ncia do balanceador de carga label.remove.ingress.rule=Remover regra ingress label.remove.ip.range=Remover range de IP label.remove.ldap=Remover LDAP label.remove.pf=Remover regra de redirecionamento de porta label.remove.project.account=Remover conta de projeto +label.remove.region=Remover Regi\u00e3o label.remove.rule=Remover regra label.remove.static.nat.rule=Remover regra de NAT est\u00e1tico label.remove.static.route=Remover rota est\u00e1tica @@ -869,7 +973,7 @@ label.removing.user=Removendo Usu\u00e1rio label.required=Obrigat\u00f3rio label.reserved.system.gateway=Gateway de sistema reservado label.reserved.system.ip=IP de Sistema Reservado -label.reserved.system.netmask=M\u00e1scara de rede do sistema reservado +label.reserved.system.netmask=M\u00e1scara de rede reservada do sistema label.reset.VPN.connection=Resetar a conex\u00e3o VPN label.resize.new.offering.id=New Offering label.resize.new.size=New Size(GB) @@ -887,7 +991,9 @@ label.revoke.project.invite=Revogar convite label.role=Fun\u00e7\u00e3o label.root.disk.controller=Controlador do disco Root label.root.disk.offering=Oferta de Disco ROOT +label.root.disk.size=Tamanho do disco root label.round.robin=Round-robin +label.routing=Roteamento label.rules=Regras label.running.vms=VMs Rodando label.s3.access_key=Chave de acesso @@ -895,6 +1001,8 @@ label.s3.bucket=Balde label.s3.connection_timeout=Tempo limite de conex\u00e3o label.s3.endpoint=Ponto de acesso label.s3.max_error_retry=Limite de tentativas de recupera\u00e7\u00e3o de erro +label.s3.nfs.path=Caminho NFS S3 +label.s3.nfs.server=Servidor NFS S3 label.s3.secret_key=Chave Secreta label.s3.socket_timeout=Tempo limite no socket label.s3.use_https=Use HTTPS @@ -905,6 +1013,7 @@ label.saving.processing=Salvando.... label.scope=Escopo label.search=Pesquisar label.secondary.storage.count=Pools de Storage secund\u00e1rios +label.secondary.storage.limits=Limites do Storage Secund\u00e1rio (GiB) label.secondary.storage=Storage Secund\u00e1rio label.secondary.storage.vm=VM de storage secund\u00e1rio label.secondary.used=Uso do Storage Secund\u00c3\u00a1rio @@ -928,6 +1037,7 @@ label.sent=Enviado label.server=Servidor label.service.capabilities=Recursos de servi\u00e7os label.service.offering=Plano +label.service.state=Estado do Servi\u00e7o label.session.expired=Sess\u00e3o Expirada label.setup=Configura\u00e7\u00e3o label.setup.network=Configurar Rede @@ -936,6 +1046,7 @@ label.set.up.zone.type=Configurar tipo de zona label.shared=Compatilhado label.SharedMountPoint=SharedMountPoint label.show.ingress.rule=Mostrar Regra de Entrada +label.shutdown.provider=Desabilitar provider label.site.to.site.VPN=Site-to-site VPN label.size=Tamanho label.skip.guide=Eu utilizei o CloudStack antes, pular este guia @@ -944,9 +1055,11 @@ label.smb.password=Senha SMB label.smb.username=Usu\u00e1rio SMB label.snapshot.limits=Limites de Snapshot label.snapshot.name=Nome do Snapshot +label.snapshot.schedule=Configure Snapshots recorrentes label.snapshot=Snapshot label.snapshot.s=Snapshot (s) label.snapshots=Snapshots +label.sockets=Sockets label.source.nat=Source NAT label.source=Origem label.specify.IP.ranges=Especifique range de IP @@ -976,6 +1089,7 @@ label.step.4=Passo 4 label.step.4.title=Passo 4\: Rede label.step.5=Passo 5 label.step.5.title=Passo 5\: Revisar +label.stickiness=Ader\u00eancia label.sticky.cookie-name=Nome do Cookie label.sticky.domain=Dom\u00ednio label.sticky.expire=Expires @@ -986,6 +1100,7 @@ label.sticky.mode=Modo label.sticky.nocache=Sem Cache label.sticky.postonly=Apenas publicar label.sticky.prefix=Prefixo +label.sticky.request-learn=Solicitar para aprender label.sticky.tablesize=Tamanho da Tabela label.stop=Parar label.stopped.vms=VMs Paradas @@ -1002,6 +1117,7 @@ label.super.cidr.for.guest.networks=Super CIDR para redes h\u00f3spedes label.supported.services=Servi\u00e7os Suportados label.supported.source.NAT.type=Tipo de Source NAT Suportado label.suspend.project=Suspender Projeto +label.switch.type=Tipo de Switch label.system.capacity=Capacidade do Sistema label.system.offering=Ofertas de Sistema label.system.service.offering=System Service Offering @@ -1057,6 +1173,7 @@ label.used=Usado label.username=Nome de usu\u00e1rio label.users=Usu\u00e1rios label.user=Usu\u00e1rio +label.use.vm.ip=Usar IP da VM\: label.value=Valor label.vcdcname=Nome do vCenter DC label.vcenter.cluster=vCenter Cluster @@ -1071,6 +1188,7 @@ label.view.all=Visualizar tudo label.view.console=Visualizar Console label.viewing=Visualizar label.view.more=Ver mais +label.view.secondary.ips=Visualizar os IPs secund\u00e1rios label.view=Visualizar label.virtual.appliance=Appliance Virtual label.virtual.appliances=Appliance Virtual @@ -1081,10 +1199,8 @@ label.virtual.routers=Roteadores Virtuais label.vlan.id=VLAN ID label.vlan.range=Intervalo de VLAN label.vlan=VLAN -label.vxlan.id=VXLAN ID -label.vxlan.range=Intervalo de VXLAN -label.vxlan=VXLAN -label.vm.add=Adicionar Cloud Server +label.vlan.vni.range=Intervalo de VLAN +label.vm.add=Adicionar Inst\u00e2ncia label.vm.destroy=Apagar label.vm.display.name=Nome de exibi\u00e7\u00e3o da VM label.VMFS.datastore=VMFS datastore @@ -1092,6 +1208,10 @@ label.vmfs=VMFS label.vm.name=Nome da VM label.vm.reboot=Reiniciar label.VMs.in.tier=M\u00e1quinas virtuais em camadas +label.vmsnapshot.current=isCurrent +label.vmsnapshot.memory=Snapshot da mem\u00f3ria +label.vmsnapshot.parentname=Pai +label.vmsnapshot=Snapshot da VM label.vmsnapshot.type=Tipo label.vm.start=In\u00edcio label.vm.state=Estado da VM @@ -1118,6 +1238,9 @@ label.vsmctrlvlanid=Control VLAN ID label.vsmpktvlanid=Packet VLAN ID label.vsmstoragevlanid=Storage VLAN ID label.vsphere.managed=vSphere Managed +label.vxlan.id=VXLAN ID +label.vxlan.range=Intervalo de VXLAN +label.vxlan=VXLAN label.waiting=Aguardando label.warn=Avisar label.wednesday=Quarta-Feira @@ -1138,17 +1261,18 @@ label.zones=Zonas label.zone.type=Tipo de Zona label.zone.wide=Zone-Wide label.zoneWizard.trafficType.guest=H\u00f3spede\: tr\u00e1fego entre m\u00e1quinas virtuais de usu\u00e1rios finais -label.zoneWizard.trafficType.management=Ger\u00eancia\: tr\u00e1fego entre recursos internos do CloudStack, incluindo quaisquer componentes que se comunicam com o servidor de gerenciamento, tais como hosts e m\u00e1quinas virtuais de sistema do CloudStack +label.zoneWizard.trafficType.management=Ger\u00eancia\: Tr\u00e1fego entre recursos internos do CloudStack incluindo quaisquer componentes que se comunicam com o servidor de gerenciamento tais como hosts e m\u00e1quinas virtuais de sistema do CloudStack label.zoneWizard.trafficType.public=P\u00fablico\: tr\u00e1fego entre a internet e m\u00e1quinas virtuais na nuvem. label.zoneWizard.trafficType.storage=Storage\: tr\u00e1fego entre servidores de storage prim\u00e1ria e secund\u00e1ria, tais como templates de m\u00e1quinas virtuais e snapshots label.zone=Zona managed.state=Status do Gerenciamento +message.acquire.ip.nic=Por favor, confirme que voc\u00ea deseja adquirir um novo IP secund\u00e1rio para esta Interface de Rede.
NOTA\: Voc\u00ea precisa configurar manualmente o novo IP secund\u00e1rio dentro da maquinas virtual. message.acquire.new.ip=Por favor confirme que voc\u00ea gostaria de adquirir um novo IP para esta rede. message.acquire.new.ip.vpc=Por favor confirme que voc\u00ea gostaria de adquirir um novo IP para esta VPC. message.acquire.public.ip=Selecione a zona de onde voc\u00ea deseja adquirir o novo IP message.action.cancel.maintenance=A Manuten\u00e7\u00e3o do seu HOST foi cancelada com sucesso message.action.cancel.maintenance.mode=Confirme que voc\u00ea deseja cancelar esta Manuten\u00e7\u00e3o -message.action.change.service.warning.for.instance=Para troca de plano \u00e9 necess\u00e1rio parar o Cloud Server. +message.action.change.service.warning.for.instance=Sua inst\u00e2ncia deve ser desligada antes de tentar alterar a oferta de servi\u00e7os utilizada. message.action.change.service.warning.for.router=O roteador precisa ser desligado antes de trocar o plano/tamanho. message.action.delete.cluster=Confirme que voc\u00ea deseja excluir este HOST message.action.delete.disk.offering=Confirme que voc\u00ea deseja excluir esta oferta de disco @@ -1160,6 +1284,7 @@ message.action.delete.ISO=Confirme que voc\u00ea deseja excluir esta ISO message.action.delete.ISO.for.all.zones=Esta ISO \u00e9 usada por todas as Zonas. Confirme se voc\u00ea deseja excluir a ISO de todas as Zonas message.action.delete.network=Confirme que voc\u00ea deseja remover esta rede. message.action.delete.nexusVswitch=Por favor confirme que voc\ufffd deseja remover este nexusVswitch. +message.action.delete.nic=Por favor, confirme que deseja remover esta Interface de Rede, esta a\u00e7\u00e3o tamb\u00e9m ir\u00e1 remover a rede associada \u00e0 VM. message.action.delete.physical.network=Por favor confirme que voc\u00ea deseja deletar esta rede f\u00edsica message.action.delete.pod=Confirme que voc\u00ea deseja remover este POD. message.action.delete.primary.storage=Confirme que voc\u00ea deseja remover este Storage Prim\u00e1rio. @@ -1172,7 +1297,7 @@ message.action.delete.template=Confirme que voc\u00ea deseja remover este Templa message.action.delete.template.for.all.zones=Este Template \u00e9 usado por todas as zonas. Confirme que voc\u00ea deseja remover o Template de todas as zonas. message.action.delete.volume=Confirme que voc\u00ea deseja remover este Disco. message.action.delete.zone=Confirme que voc\u00ea deseja remover esta Zona. -message.action.destroy.instance=Confirme que voc\u00ea deseja excluir este Cloud Server. +message.action.destroy.instance=Por favor, confirme que voc\u00ea deseja excluir esta Inst\u00e2ncia. message.action.destroy.systemvm=Confirme que voc\u00ea deseja excluir esta VM de Sistema. message.action.disable.cluster=Confirma a desativa\u00e7\u00e3o do cluster. message.action.disable.nexusVswitch=Por favor confirme que voc\ufffd deseja desabilitar este nexusVswitch @@ -1188,27 +1313,31 @@ message.action.enable.nexusVswitch=Por favor confirme que voc\ufffd deseja habil message.action.enable.physical.network=Por favor confirme que voc\u00ea deseja habilitar esta rede f\u00edsica. message.action.enable.pod=Confirma a ativa\u00e7\u00e3o do POD. message.action.enable.zone=Confirma a ativa\u00e7\u00e3o da zona. +message.action.expunge.instance=Por favor, confirme que voc\u00ea deseja eliminar esta inst\u00e2ncia. message.action.force.reconnect=O procedimento de reconex\u00e3o for\u00e7ada foi preparado com sucesso. Este processo poder\u00e1 levar alguns minutos. -message.action.host.enable.maintenance.mode=Ativar o modo de Manuten\u00e7\u00e3o ir\u00e1 causar o live migration de todos Cloud Server hospedados neste Host para o pr\u00f3ximo dispon\u00edvel. +message.action.host.enable.maintenance.mode=Ativar o modo de Manuten\u00e7\u00e3o ir\u00e1 causar o live migration de todas as Inst\u00e2ncias hospedadas neste Host para o pr\u00f3ximo dispon\u00edvel. message.action.instance.reset.password=Por favor confirme que voc\u00ea deseja alterar a senha de ROOT para est\u00e1 m\u00e1quina virtual. message.action.manage.cluster=Confirma a vincula\u00e7\u00e3o do cluster. message.action.primarystorage.enable.maintenance.mode=Aviso\: Colocar o Storage prim\u00e1rio em modo de Manuten\u00e7\u00e3o ir\u00e1 causar a parada de todas as VMs hospedadas nesta unidade. Deseja continuar? -message.action.reboot.instance=Confirme que voc\u00ea deseja reiniciar este Cloud Server. +message.action.reboot.instance=Por favor, confirme que voc\u00ea deseja reiniciar esta inst\u00e2ncia. message.action.reboot.router=Confirme que voc\ufffd deseja reiniciar este roteador. message.action.reboot.systemvm=Confirme que voc\u00ea deseja reiniciar esta VM de sistema. message.action.release.ip=Confirme que voc\u00ea deseja liberar este IP. message.action.remove.host=Favor confirmar que voc\u00ea deseja remover este host. -message.action.reset.password.off=Seu Cloud Server n\u00e3o suporta esta funcionalidade. -message.action.reset.password.warning=Para recuperar a senha \u00e9 necess\u00e1rio parar o Cloud Server. -message.action.restore.instance=Confirme que voc\u00ea deseja restaurar este Cloud Server. -message.action.start.instance=Confirme que voc\u00ea deseja iniciar este Cloud Server. +message.action.reset.password.off=Sua Inst\u00e2ncia n\u00e3o suporta esta funcionalidade. +message.action.reset.password.warning=Para recuperar a senha \u00e9 necess\u00e1rio parar a Inst\u00e2ncia. +message.action.restore.instance=Por favor, confirme que voc\u00ea deseja restaurar esta Inst\u00e2ncia. +message.action.revert.snapshot=Por favor, confirme que voc\u00ea deseja reverter o seu volume deste snapshot. +message.action.start.instance=Por favor, confirme que voc\u00ea deseja iniciar esta Inst\u00e2ncia. message.action.start.router=Confirme que voc\u00ea deseja inciar este roteador. message.action.start.systemvm=Confirme que voc\u00ea deseja iniciar esta VM de sistema. -message.action.stop.instance=Confirme que voc\u00ea deseja parar este Cloud Server. +message.action.stop.instance=Por favor, confirme que voc\u00ea deseja parar esta inst\u00e2ncia. message.action.stop.router=Confirme que voc\ufffd deseja parar este roteador. message.action.stop.systemvm=Confirme que voc\u00ea deseja parar esta VM de Sistema. message.action.take.snapshot=Por favor confirme que voc\u00ea deseja criar um snapshot deste volume. message.action.unmanage.cluster=Confirma a desvincula\u00e7\u00e3o do cluster. +message.action.vmsnapshot.delete=Por favor, confirme que voc\u00ea deseja excluir este snapshot da VM. +message.action.vmsnapshot.revert=Reverter snapshot da VM message.activate.project=Voc\u00ea tem certeza que deseja ativar este projeto ? message.add.cluster=Add a hypervisor managed cluster for zone , pod message.add.cluster.zone=Add a hypervisor managed cluster for zone @@ -1223,14 +1352,16 @@ message.adding.Netscaler.provider=Adicionando Netscaler provider message.add.ip.range=Add an IP range to public network in zone message.add.ip.range.direct.network=Add an IP range to direct network in zone message.add.ip.range.to.pod=

Add an IP range to pod\:

-message.additional.networks.desc=Selecione a(s) rede(s) adicionais que seu Cloud Server ter\u00c3\u00a1 acesso. +message.additional.networks.desc=Por favor, selecione a(s) rede(s) adicionais que sua inst\u00e2ncia virtual estar\u00e1 conectada. message.add.load.balancer=Add a load balancer to zone message.add.load.balancer.under.ip=A regra do balanceador de carga foi adicionada para o IP\: message.add.network=Add a new network for zone\: message.add.new.gateway.to.vpc=Favor especificar a informa\u00e7\u00e3o para adicionar um novo gateway a esta VPC. message.add.pod=Add a new pod for zone +message.add.pod.during.zone.creation=Cada zona deve conter um ou mais pods e iremos adicionar o primeiro pod agora. Um pod cont\u00e9m hosts e servidores de storage prim\u00e1rio que ser\u00e3o adicionados em uma etapa posterior. Inicialmente, configure um intervalo de endere\u00e7os IP reservados para o tr\u00e1fego de gerenciamento interno do CloudStack. A faixa de IP reservados devem ser \u00fanicos para cada zona na nuvem. message.add.primary=Especifique os seguintes par\u00e2metros para adicionar um novo Storage prim\u00e1rio. message.add.primary.storage=Adicionar novo Storage prim\u00e1rio \u00c3\u00a0 zona , pod +message.add.region=Por favor, especifique as informa\u00e7\u00f5es necess\u00e1rias para adicionar uma nova regi\u00e3o. message.add.secondary.storage=Add a new storage for zone message.add.service.offering=Por favor preencha os dados abaixo para adicionar uma nova oferta de computa\u00e7\u00e3o. message.add.system.service.offering=Por favor preencha os dados abaixo para adicionar uma nova oferta de servi\u00e7o de sistema. @@ -1245,10 +1376,10 @@ message.after.enable.swift=Swift Configurado. Nota\: Ap\u00f3s deixar esta p\u00 message.alert.state.detected=Alerta de estado detectado message.allow.vpn.access=Entre com nome de Usu\u00e1rio e senha do Usu\u00e1rio que ter\u00e1 acesso VPN. message.apply.snapshot.policy=Voc\u00ea atualizou com sucesso sua pol\u00edtica de Snapshot. -message.attach.iso.confirm=Confirme que voc\u00ea deseja conectar a ISO ao Cloud Server. -message.attach.volume=Preencha os seguintes dados para conectar o novo disco. Se voc\u00ea Est\u00e1 conectando um disco a um Cloud Server Windows, ser\u00e1 necess\u00e1rio reiniciar o Cloud Server para visualizar o novo disco. -message.basic.mode.desc=Escolha este modelo de rede se voc\u00ea *n\u00e3o* quer suporte a VLAN. Todo Cloud Server criado neste modelo de rede estar\u00e1 ligado diretamente a um IP da rede e ser\u00e1 usado Security Groups para prover seguran\u00e7a e separa\u00e7\u00e3o. -message.change.offering.confirm=Confirme que voc\u00ea deseja mudar o plano deste Cloud Server. +message.attach.iso.confirm=Por favor, confirme que voc\u00ea deseja conectar o ISO \u00e0 esta inst\u00e2ncia virtual. +message.attach.volume=Preencha os seguintes dados para conectar o novo disco. Se voc\u00ea Est\u00e1 conectando um disco a uma maquina virtual Windows, ser\u00e1 necess\u00e1rio reiniciar a Inst\u00e2ncia para visualizar o novo disco. +message.basic.mode.desc=Escolha este modelo de rede se voc\u00ea *n\u00e3o* quer suporte a VLAN. Toda Inst\u00e2ncia criada neste modelo de rede estar\u00e1 ligado diretamente a um IP da rede e ser\u00e1 usado Security Groups para prover seguran\u00e7a e segrega\u00e7\u00e3o. +message.change.offering.confirm=Por favor, confirme que voc\u00ea deseja mudar a oferta de servi\u00e7o desta inst\u00e2ncia virtual. message.change.password=Por favor, troque sua senha. message.configure.all.traffic.types=Voc\u00ea tem m\u00faltiplas redes f\u00edsicas; favor configurar etiquetas para cada tipo de tr\u00e1fego clicando no bot\u00e3o Edit. message.configure.ldap=Por favor, confirme que voc\u00ea deseja configurar o LDAP. @@ -1259,6 +1390,7 @@ message.configuring.storage.traffic=Configurando tr\u00e1fego de storage message.confirm.action.force.reconnect=Por favor confirme que voc\u00ea deseja for\u00e7ar a reconex\u00e3o com este host. message.confirm.delete.F5=Por favor confirme que voc\u00ea deseja remover o F5 message.confirm.delete.NetScaler=Por favor confirme que voc\u00ea deseja remover o NetScaler +message.confirm.delete.PA=Por favor, confirme que voc\u00ea deseja remover Palo Alto message.confirm.delete.SRX=Por favor confirme que voc\u00ea deseja remover o SRX message.confirm.destroy.router=Por favor confirme que voc\u00ea gostaria de destruir este roteador message.confirm.disable.provider=Por favor confirme que voc\u00ea gostaria de desabilitar este provider @@ -1279,15 +1411,24 @@ message.creating.primary.storage=Criando storage prim\u00e1rio message.creating.secondary.storage=Criando storage secund\u00e1rio message.creating.zone=Criando zona. message.decline.invitation=Voc\u00ea tem certeza que quer rejeitar este convite de projeto ? +message.dedicate.zone=Zona dedicada message.delete.account=Confirme se voc\u00ea deseja excluir esta conta. +message.delete.affinity.group=Por favor, confirme que voc\u00ea deseja remover este grupo de afinidade message.delete.gateway=Favor confirmar que voc\u00ea deseja deleta o gateway message.delete.project=Voc\u00ea tem certeza que deseja deletar este projeto ? message.delete.user=Por favor confirme que voc\u00ea deseja deletar este usu\u00e1rio. message.delete.VPN.connection=Favor confirmar que voc\u00ea deseja deletar esta conex\u00e3o VPN message.delete.VPN.customer.gateway=Favor confirmar que voc\u00ea deseja deletar este gateway de VPN de usu\u00e1rio message.delete.VPN.gateway=Favor confirmar que voc\u00ea deseja deletar este gateway de VPN +message.desc.advanced.zone=Para topologias de rede mais sofisticadas. Este modelo fornece maior flexibilidade na defini\u00e7\u00e3o de redes de clientes e fornece ofertas de rede personalizadas, tais como firewall, VPN ou de balanceamento de carga. +message.desc.basic.zone=Fornece uma \u00fanica rede onde em cada inst\u00e2ncia de VM \u00e9 atribu\u00eddo um IP diretamente na rede. O isolamento Guest podem ser fornecidos atrav\u00e9s de camada-3 da rede com grupos de seguran\u00e7a (filtragem da fonte de endere\u00e7os IP). +message.desc.cluster=Cada pod deve conter um ou mais clusters, e iremos adicionar o primeiro cluster agora. Um cluster fornece uma maneira de agrupamento de hosts. Os hosts de um cluster t\u00eam hardware id\u00eantico, executam o mesmo hypervisor, est\u00e3o na mesma sub-rede e acessam o mesmo storage compartilhado. Cada cluster \u00e9 constitu\u00eddo por um ou mais hosts e um ou mais servidores de storage prim\u00e1rio. +message.desc.host=Cada cluster deve conter pelo menos um host (computador) para as VMs guest serem executadas e iremos adicionar o primeira host agora. Para um host funcionar no CloudStack, voc\u00ea deve instalar um hypervisor no host, atribuir um endere\u00e7o IP e garantir que o host est\u00e1 conectado ao servidor de gerenciamento do CloudStack.

Forne\u00e7a o hostname ou o endere\u00e7o IP do host, o nome de usu\u00e1rio (geralmente root) e a senha e qualquer label que voc\u00ea utiliza para categorizar os hosts. +message.desc.primary.storage=Cada cluster deve conter um ou mais servidores de storage prim\u00e1rio e iremos adicionar o primeiro agora. Um storage prim\u00e1rio, cont\u00e9m os volumes de disco para todas as VMs em execu\u00e7\u00e3o nos hosts do cluster. Utiliza qualquer protocolo compat\u00edvel com os padr\u00f5es que \u00e9 suportado pelo hypervisor utilizado. +message.desc.secondary.storage=Cada zona deve ter pelo menos um NFS ou servidor de storage secund\u00e1rio e iremos adicionar o primeiro agora. Um storage secund\u00e1rios armazena templates de VM, imagens ISO e snapshots do volume de disco da VM. Esse servidor deve estar dispon\u00edvel para todos os hosts na zona.

Fornecer o endere\u00e7o IP e o caminho exportados. +message.desc.zone=Uma zona \u00e9 a maior unidade organizacional no CloudStack e normalmente corresponde \u00e0 um \u00fanico datacenter. As Zonas disponibilizam isolamento f\u00edsico e redund\u00e2ncia. Uma zona \u00e9 composta por um ou mais pods (cada um dos quais cont\u00e9m os hosts e servidores de storage prim\u00e1rio) e um servidor de storage secund\u00e1rio que \u00e9 compartilhado por todos os pods na zona. message.detach.disk=Voc\u00ea tem certeza que deseja desconectar este disco ? -message.detach.iso.confirm=Confirme se voc\u00ea deseja desconectar a ISO do Cloud Server. +message.detach.iso.confirm=Confirme se voc\u00ea deseja desconectar o ISO da inst\u00e2ncia virtual. message.disable.account=Por favor confirme que voc\u00ea deseja desabilitar esta conta. Ap\u00f3s desabilitar uma conta, todos os usu\u00e1rios desta conta n\u00e3o ir\u00e3o possuir mais acesso aos seus recursos da cloud. Todas as m\u00e1quinas virtuais ser\u00e3o automaticamente desligadas. message.disable.snapshot.policy=Voc\u00ea desativou com sucesso sua pol\u00edtica de Snapshot. message.disable.user=Por favor confirme que voc\u00ea deseja desabilitar este usu\u00e1rio. @@ -1311,6 +1452,8 @@ message.enabling.security.group.provider=Habilitar provider de grupo de seguran\ message.enabling.zone=Habilitando zona message.enter.token=Por favor entre o token que voc\u00ea recebeu no e-mail privado. message.generate.keys=Por favor confirme que voc\u00ea deseja gerar novas chaves para este usu\u00e1rio. +message.guest.traffic.in.advanced.zone=O tr\u00e1fego de rede guest \u00e9 para comunica\u00e7\u00e3o entre m\u00e1quinas virtuais do usu\u00e1rio final. Especifique um intervalo de IDs de VLAN para transportar o tr\u00e1fego do guest para cada rede f\u00edsica. +message.guest.traffic.in.basic.zone=O tr\u00e1fego de rede guest \u00e9 para comunica\u00e7\u00e3o entre m\u00e1quinas virtuais do usu\u00e1rio final. Especifique um intervalo de endere\u00e7os IP para que CloudStack possa atribuir \u00e0s VMs. Certifique-se que este intervalo n\u00e3o se sobreponha o range de IPs reservados do sistema. message.installWizard.click.retry=Click no bot\u00e3o para tentar executar novamente. message.installWizard.copy.whatIsACluster=Um cluster prov\u00ea uma maneira de agrupar hosts. Os hosts em um cluster tem hardware id\u00eantico, rodam o mesmo hypervisor, est\u00e3o na mesma subnet, acessam o mesmo storage compartilhado. Inst\u00e2ncias de m\u00e1quinas virtuais (VMs) podem ser migradas a quente - live migration - de um host para outro host no mesmo cluster, sem interromper o servi\u00e7o para o usu\u00e1rio. Um Cluster \u00e9 a terceira maior unidade organizacional em uma instala\u00e7\u00e3o CloudStack&\#8482; . Clusters est\u00e3o contidos em pods e pods est\u00e3o contidos em zonas.

O CloudStack&\#8482; permite m\u00faltiplos clusters em uma mesma cloud, entretanto para a instala\u00e7\u00e3o b\u00e1sica, n\u00f3s iremos precisar apenas de um cluster. message.installWizard.copy.whatIsAHost=Um host \u00e9 um \u00fanico computador. Os Hosts prov\u00eaem os recursos computacionais para executar as m\u00e1quinas virtuais. Cada host possu\u00ed o software do hypervisor instalado nele para gerenciar as guest VMs (Exceto os hosts bare metal, que s\u00e3o um caso especial discutido no Guia Avan\u00e7ado de Instala\u00e7\u00e3o). Por exemplo, um servidor Linux com KVM habilitado, um servidor Citrix XenServer e um servidor ESXi s\u00e3o hosts. Na Instala\u00e7\u00e3o B\u00e1sica, n\u00f3s utilizamos um \u00fanico host rodando XenServer ou KVM.

O host \u00e9 a menor unidade organizacional dentro de uma instala\u00e7\u00e3o CloudStack&\#8482; . Hosts est\u00e3o contidos dentro de Clusters, clusters est\u00e3o contidos dentro de pods e pods est\u00e3o contidos dentro de zonas. @@ -1340,25 +1483,26 @@ message.installWizard.tooltip.addZone.internaldns1=Estes s\u00e3o os servidores message.installWizard.tooltip.addZone.internaldns2=Estes s\u00e3o os servidores DNS utilizados pelas VMs de sistema nesta zona. Estes servidores DNS ser\u00e3o acessados atrav\u00e9s da interface de rede privada das VMs de sistema. O endere\u00e7o IP privado que voc\u00ea configurar para os pods deve possuir uma rota para os servidores DNS configurados aqui. message.installWizard.tooltip.addZone.name=Um nome para a zona message.installWizard.tooltip.configureGuestTraffic.description=Uma descri\u00e7\u00e3o da sua rede -message.installWizard.tooltip.configureGuestTraffic.guestEndIp=O range de endere\u00e7os IP que estar\u00e1 dispon\u00edvel para aloca\u00e7\u00e3o para os guests nesta zona. Caso uma NIC seja utilizada, estes IPs devem estar no mesmo CIDR que o CIDR do pod. +message.installWizard.tooltip.configureGuestTraffic.guestEndIp=O range de endere\u00e7os IP que estar\u00e1 dispon\u00edvel para aloca\u00e7\u00e3o para os guests nesta zona. Caso uma Interface de Rede seja utilizada, estes IPs devem estar no mesmo CIDR que o CIDR do pod. message.installWizard.tooltip.configureGuestTraffic.guestGateway=O gateway que os guests devem usar message.installWizard.tooltip.configureGuestTraffic.guestNetmask=A m\u00e1scara de rede da subrede que os guests devem usar -message.installWizard.tooltip.configureGuestTraffic.guestStartIp=O range de endere\u00e7os IP que estar\u00e1 dispon\u00edvel para aloca\u00e7\u00e3o para os guests nesta zona. Caso uma NIC seja utilizada, estes IPs devem estar no mesmo CIDR que o CIDR do pod. +message.installWizard.tooltip.configureGuestTraffic.guestStartIp=O range de endere\u00e7os IP que estar\u00e1 dispon\u00edvel para aloca\u00e7\u00e3o para os guests nesta zona. Caso uma Interface de Rede seja utilizada, estes IPs devem estar no mesmo CIDR que o CIDR do pod. message.installWizard.tooltip.configureGuestTraffic.name=Um nome para sua rede message.instanceWizard.noTemplates=Voc\u00ea n\u00e3o possui nenhum template dispon\u00edvel; por favor adicione um template compat\u00edvel e reinicie o wizard de inst\u00e2ncia. message.ip.address.changed=Seu endere\u00e7o IP pode ter mudado; voc\u00ea gostaria de atualizar a listagem ? Note que neste caso o painel de detalhes ir\u00e1 fechar. message.iso.desc=Imagem de disco contendo dados ou m\u00eddia de sistema operacional boot\u00e1vel message.join.project=Voc\u00ea agora entrou em um projeto. Por favor troque para a vis\u00e3o de Projeto para visualizar o projeto. -message.launch.vm.on.private.network=Voc\u00ea deseja executar sua inst\u00e2ncia na sua pr\u00f3pria rede privada dedicada ? -message.launch.zone=A zona est\u00e1 pronta para ser executada; por favor continue para o pr\u00f3ximo passo. +message.launch.vm.on.private.network=Voc\u00ea deseja executar a sua inst\u00e2ncia na sua pr\u00f3pria rede privada dedicada? +message.launch.zone=A zona est\u00e1 pronta para ser executada; por favor, v\u00e1 para o pr\u00f3ximo passo. message.lock.account=Confirme se voc\u00ea deseja bloquear esta conta. Bloqueando a conta, todos os Usu\u00e1rios desta conta n\u00e3o estar\u00e3o mais habilitados a gerenciar os recursos na nuvem. Os recursos existentes (Cloud Server) ainda poder\u00e3o ser acessados. -message.migrate.instance.confirm=Confirme o host que voc\u00ea deseja migrar o Cloud Server. +message.migrate.instance.confirm=Confirme o host que voc\u00ea deseja migrar a inst\u00e2ncia virtual. message.migrate.instance.to.host=Por favor confirme que voc\u00ea deseja migrar a inst\u00e2ncia para outro host. message.migrate.instance.to.ps=Por favor confirme que voc\u00ea deseja migrar a inst\u00e2ncia para outro storage prim\u00e1rio. message.migrate.router.confirm=Por favor confirme o host que voc\u00ea deseja migrar o roteador para\: message.migrate.systemvm.confirm=Por favor confirme o host para o qual voc\u00ea deseja migrar a VM de sistema\: message.migrate.volume=Por favor confirme que voc\u00ea deseja migrar o volume para outro storage prim\u00e1rio. message.new.user=Especifique abaixo para adicionar novos usu\u00e1rios para a conta +message.no.affinity.groups=Voc\u00ea n\u00e3o tem nenhum grupo de afinidade. Por favor, v\u00e1 para o pr\u00f3ximo passo. message.no.network.support.configuration.not.true=Voc\u00ea n\u00e3o possui nenhuma zona com grupos de seguran\u00e7a habilitado. Assim sendo, n\u00e3o possui recursos adicionais de rede. Por favor continue para o passo 5. message.no.network.support=O hypervisor escolhido, vSphere, n\u00e3o possui nenhum recurso de rede adicional. Por favor, v\u00e1 para o passo 5. message.no.projects.adminOnly=Voc\u00ea n\u00e3o possui nenhum projeto.
Por favor solicite ao seu administrador a cria\u00e7\u00e3o de um novo projeto. @@ -1371,7 +1515,7 @@ message.number.zones=

Zonas

message.pending.projects.1=Voc\u00ea possui convites de projetos pendentes\: message.pending.projects.2=Para visualizar, por favor acesse a se\u00e7\u00e3o de projetos, depois selecione os convites no menu drop-down. message.please.add.at.lease.one.traffic.range=Por favor adicione pelo menos um range de tr\u00e1fego. -message.please.proceed=Por favor continue para o pr\u00f3ximo passo. +message.please.proceed=Por favor, v\u00e1 para o pr\u00f3ximo passo. message.please.select.a.configuration.for.your.zone=Por favor selecione uma configuracao para sua zona. message.please.select.a.different.public.and.management.network.before.removing=Por favor selecione uma rede p\u00fablica e de gerenciamento diferente antes de remover message.please.select.networks=Por favor selecione as redes para sua m\u00e1quina virtual. @@ -1384,7 +1528,7 @@ message.remove.ldap=Voc\u00ea tem certeza que deseja deletar a configura\u00e7\u message.remove.region=Voc\u00ea tem certeza que deseja remover esta regi\u00e3o deste servidor de gerenciamento? message.remove.vpc=Favor confirmar que voc\u00ea deseja remover a VPC message.remove.vpn.access=Confirme se voc\u00ea deseja remover acesso VPN do seguinte Usu\u00e1rio. -message.reset.password.warning.notPasswordEnabled=O template desta inst\u00e2ncia foi criado sem senha habilitada +message.reset.password.warning.notPasswordEnabled=O template desta inst\u00e2ncia foi criado sem uma senha habilitada message.reset.password.warning.notStopped=Sua inst\u00e2ncia deve estar parada antes de tentar trocar sua senha atual message.reset.VPN.connection=Favor confirmar que voc\u00ea deseja resetar a conex\u00e3o VPN message.restart.mgmt.server=Reinicie o(s) servidor(es) de gerenciamento para que a nova configura\u00c3\u00a7\u00c3\u00a3o tenha efeito. @@ -1392,26 +1536,30 @@ message.restart.mgmt.usage.server=Por favor reinicie seu servidor(es) de gerenci message.restart.network=Por favor confirme que voc\ufffd deseja reiniciar a rede message.restart.vpc=Favor confirmar que voc\u00ea deseja reiniciar a VPC message.security.group.usage=(Use Ctrl-clique para selecionar todos os Security Groups) +message.select.affinity.groups=Por favor, selecione quaisquer grupos de afinidade que voc\u00ea deseja que esta VM perten\u00e7a\: message.select.a.zone=A zone tipicamente corresponde a um \u00fanico datacenter. M\u00faltiplas zonas auxiliam a cloud a ser mais confi\u00e1vel provendo isolamento f\u00edsico e redund\u00e2ncia. message.select.instance=Por favor selecione uma inst\u00e2ncia. message.select.iso=Por favor selecione um ISO para sua nova inst\u00e2ncia virtual message.select.item=Por favor selecione um item. message.select.security.groups=Por favor selecione o(s) grupo(s) de seguran\u00e7a para sua nova VM message.select.template=Por favor selecione um template para sua nova inst\u00e2ncia virtual. -message.setup.physical.network.during.zone.creation.basic=Quando adicionar uma zona b\u00e1sica, voc\u00ea pode configurar uma rede f\u00edsica, que corresponde a uma NIC no hypervisor. A rede carrega diversos tipos de tr\u00e1fego.

Voc\u00ea pode adicionar e remover outros tipos de tr\u00e1fego na mesma interface de rede f\u00edsica. +message.setup.physical.network.during.zone.creation=Ao adicionar uma zona avan\u00e7ada, voc\u00ea precisa configurar uma ou mais redes f\u00edsicas. Cada rede corresponde \u00e0 uma Interface de Rede no hypervisor. Cada rede f\u00edsica pode ser utilizada para transportar um ou mais tipos de tr\u00e1fego, com certas restri\u00e7\u00f5es sobre como eles podem ser combinados.
Arraste e solte um ou mais tipos de tr\u00e1fego em cada rede f\u00edsica. +message.setup.physical.network.during.zone.creation.basic=Quando adicionar uma zona b\u00e1sica, voc\u00ea pode configurar uma rede f\u00edsica, que corresponde a uma Interface de Rede no hypervisor. A rede carrega diversos tipos de tr\u00e1fego.

Voc\u00ea pode adicionar e remover outros tipos de tr\u00e1fego na mesma interface de rede f\u00edsica. message.setup.successful=Cloud configurada com sucesso\! message.snapshot.schedule=Voc\u00ea pode configurar Snapshots recorrentes agendados selecionando as op\u00e7\u00f5es Dispon\u00edveis abaixo message.specify.url=Por favor especifique a URL message.step.1.continue=Selecione o template ou ISO para continuar -message.step.1.desc=Selecione o template para o novo Cloud Server. +message.step.1.desc=Por favor, selecione um template para a sua nova inst\u00e2ncia virtual. Voc\u00ea pode tamb\u00e9m escolher um template limpo e instalar a partir de uma imagem ISO. message.step.2.continue=Selecione o plano message.step.2.desc= message.step.3.continue=Seleciona a oferta de disco message.step.3.desc= message.step.4.continue=Selecione pelo menos uma rede para continuar -message.step.4.desc=Selecione a rede principal que seu Cloud Server ser\u00e1 conectado. +message.step.4.desc=Selecione a rede principal que a sua inst\u00e2ncia virtual estar\u00e1 conectada. +message.storage.traffic=Tr\u00e1fego entre os recursos internos do CloudStack, incluindo todos os componentes que se comunicam com o servidor de gerenciamento tais como hosts e m\u00e1quinas virtuais de sistema CloudStack. Por favor, configure o tr\u00e1fego do storage aqui. message.suspend.project=Voc\u00ea tem certeza que deseja suspender este projeto ? message.template.desc=Imagem de SO que pode ser utilizada para bootar VMs +message.tooltip.dns.1=Endere\u00e7o de um servidor DNS que ser\u00e1 utilizado por todas as VMs da Zone. A faixa de IPs p\u00fablicos para essa Zone deve possuir uma rota para o servidor configurado. message.tooltip.dns.2=Um servidor DNS secund\u00e1rio para ser utilizado pelas VMs nesta zona. Os endere\u00e7os IP p\u00fablicos nesta zona devem ter rota para este servidor. message.tooltip.internal.dns.1=Nome de um servidor DNS que ser\u00e1 utilizado pelas VMs internas de sistema do CloudStack nesta zona. Os endere\u00e7os privados dos pods devem ter uma rota para este servidor. message.tooltip.internal.dns.2=Nome de um servidor DNS que ser\u00e1 utilizado pelas VMs internas de sistema do CloudStack nesta zona. Os endere\u00e7os privados dos pods devem ter uma rota para este servidor. @@ -1420,10 +1568,11 @@ message.tooltip.pod.name=Um nome para este pod. message.tooltip.reserved.system.gateway=O gateway para os hosts neste pod. message.tooltip.reserved.system.netmask=O prefixo de rede que define a subrede deste pod. Utilize a nota\u00e7\u00e3o CIDR. message.tooltip.zone.name=Um nome para a zona. -message.update.os.preference=Escolha o SO de preferencia para este host. Todos Cloud Server com preferencias similares ser\u00e3o alocados neste host antes de tentar em outro. +message.update.os.preference=Escolha o SO de preferencia para este host. Todas Inst\u00e2ncias com preferencias similares ser\u00e3o alocadas neste host antes de tentar em outro. message.update.resource.count=Por favor confirme que voc\u00ea quer atualizar a contagem de recursos para esta conta. message.update.ssl=Envie o novo certificado SSL X.509 para ser atualizado em cada console proxy\: message.validate.instance.name=Nomes de inst\u00e2ncias n\u00e3o podem ter mais de 63 caracteres. Somente letras ASCII a~z, A~Z, d\u00edgitos 0~9 e h\u00edfen s\u00e3o permitidos. Deve come\u00e7ar com uma letra e terminar com uma letra ou d\u00edgito. +message.validate.invalid.characters=Caracteres inv\u00e1lidos encontrados, por favor corrija. message.virtual.network.desc=Rede virtual dedicado para sua conta. O Dom\u00ednio de broadcast Est\u00e1 na VLAN e todo acesso a internet \u00e9 roteado atrav\u00e9s do virtual router. message.vm.create.template.confirm=Criar Template reiniciar\u00e1 a VM automaticamente. message.vm.review.launch=Por favor revise a informa\u00e7\u00e3o abaixo e confirme que sua inst\u00e2ncia virtual est\u00e1 correta antes de executa-la. @@ -1435,7 +1584,6 @@ message.zone.no.network.selection=A zona que voc\u00ea selecionou n\u00e3o possu message.zone.step.1.desc=Seleciona o modelo de rede para a zona. message.zone.step.2.desc=Entre a informa\u00e7\u00e3o a seguir para adicionar uma nova zona message.zone.step.3.desc=Entre a informa\u00e7\u00e3o a seguir para adicionar um novo pod -message.zoneWizard.enable.local.storage=ALERTA\: se voc\u00ea habilitar storage local para esta zona, voc\u00ea deve fazer o seguinte, dependendo se voc\u00ea quiser que suas m\u00e1quinas virtuais de sistema inicializem\:

1. Se m\u00e1quinas virtuais de sistema precisam ser iniciadas em storage prim\u00e1ria, storage prim\u00e1ria precisa ser adicionada \u00e0 zona ap\u00f3s a cria\u00e7\u00e3o. Voc\u00ea tamb\u00e9m deve ativar a zona em um estado desabilitado.

2. Se m\u00e1quinas virtuais de sistema precisam ser iniciadas em storage local, system.vm.use.local.storage precisa ser estabelecida como verdadeira antes de voc\u00ea habilitar a zona.


Voc\u00ea quer continuar? mode=Modo network.rate=Taxa de Transfer\u00eancia notification.reboot.instance=Reiniciar inst\u00e2ncia @@ -1446,6 +1594,8 @@ state.Accepted=Aceito state.Active=Ativo state.Allocated=Alocado state.Allocating=Alocando +state.BackedUp=Back up realizado com sucesso +state.BackingUp=Realizando Back up state.Completed=Completo state.Creating=Criando state.Declined=Recusado @@ -1454,6 +1604,7 @@ state.Disabled=Desativado state.enabled=Habilitado state.Enabled=Habilitado state.Error=Erro +state.Expunging=Removendo state.Migrating=Migrando state.Pending=Pendente state.ready=Pronto diff --git a/client/WEB-INF/classes/resources/messages_ru_RU.properties b/client/WEB-INF/classes/resources/messages_ru_RU.properties index 62c791f61b..ff68668e6f 100644 --- a/client/WEB-INF/classes/resources/messages_ru_RU.properties +++ b/client/WEB-INF/classes/resources/messages_ru_RU.properties @@ -16,6 +16,7 @@ # under the License. changed.item.properties=\u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u044b +confirm.enable.s3=\u0417\u0430\u043f\u043e\u043b\u043d\u0438\u0442\u0435 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u0434\u043b\u044f \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f S3-\u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u043e\u0433\u043e \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 confirm.enable.swift=\u0417\u0430\u043f\u043e\u043b\u043d\u0438\u0442\u0435 \u043d\u0438\u0436\u0435\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u0434\u043b\u044f \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438 Swift error.could.not.enable.zone=\u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0437\u043e\u043d\u0443 error.installWizard.message=\u0427\u0442\u043e-\u0442\u043e \u043d\u0435 \u0442\u0430\u043a. \u0412\u0435\u0440\u043d\u0438\u0442\u0435\u0441\u044c \u043d\u0430\u0437\u0430\u0434 \u0438 \u0438\u0441\u043f\u0440\u0430\u0432\u044c\u0442\u0435 \u043e\u0448\u0438\u0431\u043a\u0438. @@ -41,6 +42,8 @@ ICMP.type=\u0422\u0438\u043f ICMP image.directory=\u041a\u0430\u0442\u0430\u043b\u043e\u0433 \u0441 \u043e\u0431\u0440\u0430\u0437\u0430\u043c\u0438 inline=\u0412\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0439 instances.actions.reboot.label=\u041f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u043c\u0430\u0448\u0438\u043d\u0443 +label.about.app=\u041e CloudStack +label.about=\u041e label.accept.project.invitation=\u041f\u0440\u0438\u043d\u044f\u0442\u044c \u043f\u0440\u0438\u0433\u043b\u0430\u0448\u0435\u043d\u0438\u0435 \u043d\u0430 \u043f\u0440\u043e\u0435\u043a\u0442 label.account.and.security.group=\u0410\u043a\u043a\u0430\u0443\u043d\u0442, \u0433\u0440\u0443\u043f\u043f\u044b \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u0438 label.account.id=ID \u0443\u0447\u0451\u0442\u043d\u043e\u0439 \u0437\u0430\u043f\u0438\u0441\u0438 @@ -49,6 +52,7 @@ label.account.specific=\u0421\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430 \u label.accounts=\u0423\u0447\u0451\u0442\u043d\u044b\u0435 \u0437\u0430\u043f\u0438\u0441\u0438 label.account=\u0423\u0447\u0451\u0442\u043d\u0430\u044f \u0437\u0430\u043f\u0438\u0441\u044c label.acquire.new.ip=\u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043d\u043e\u0432\u044b\u0439 IP +label.acquire.new.secondary.ip=\u0417\u0430\u043f\u0440\u043e\u0441\u0438\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 IP-\u0430\u0434\u0440\u0435\u0441 label.action.attach.disk.processing=\u041f\u0440\u0438\u043a\u0440\u0435\u043f\u043b\u0435\u043d\u0438\u0435 \u0434\u0438\u0441\u043a\u0430... label.action.attach.disk=\u041f\u0440\u0438\u043a\u0440\u0435\u043f\u0438\u0442\u044c \u0434\u0438\u0441\u043a label.action.attach.iso.processing=\u041f\u0440\u0438\u043a\u0440\u0435\u043f\u043b\u0435\u043d\u0438\u0435 ISO... @@ -91,6 +95,7 @@ label.action.delete.load.balancer=\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0 label.action.delete.network.processing=\u0423\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0441\u0435\u0442\u0438... label.action.delete.network=\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0441\u0435\u0442\u044c label.action.delete.nexusVswitch=\u0423\u0434\u0430\u043b\u0438\u0442\u044c NexusVswitch +label.action.delete.nic=\u0423\u0434\u0430\u043b\u0438\u0442\u044c NIC label.action.delete.physical.network=\u0423\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u0441\u0435\u0442\u0438 label.action.delete.pod.processing=\u0423\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0441\u0442\u0435\u043d\u0434\u0430... label.action.delete.pod=\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0441\u0442\u0435\u043d\u0434 @@ -207,6 +212,8 @@ label.action.resize.volume=Resize Volume label.action.resource.limits=\u041f\u0440\u0435\u0434\u0435\u043b\u044b \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 label.action.restore.instance.processing=\u0412\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u043c\u0430\u0448\u0438\u043d\u044b... label.action.restore.instance=\u0412\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043c\u0430\u0448\u0438\u043d\u0443 +label.action.revert.snapshot.processing=\u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0435\u043d\u0438\u0435 \u043a \u0441\u043d\u0438\u043c\u043a\u0443... +label.action.revert.snapshot=\u0412\u043e\u0437\u0432\u0440\u0430\u0442 \u043a \u0441\u043d\u0438\u043c\u043a\u0443 label.action.start.instance.processing=\u0417\u0430\u043f\u0443\u0441\u043a \u043c\u0430\u0448\u0438\u043d\u044b... label.action.start.instance=\u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043c\u0430\u0448\u0438\u043d\u0443 label.action.start.router.processing=\u0417\u0430\u043f\u0443\u0441\u043a \u0440\u043e\u0443\u0442\u0435\u0440\u0430 @@ -228,12 +235,18 @@ label.action.update.OS.preference.processing=\u041e\u0431\u043d\u043e\u0432\u043 label.action.update.OS.preference=\u041e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u041e\u0421 label.action.update.resource.count.processing=\u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u0447\u0435\u0442\u0447\u0438\u043a\u0430 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432... label.action.update.resource.count=\u041e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u0441\u0447\u0451\u0442\u0447\u0438\u043a \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 +label.action.vmsnapshot.create=\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u043d\u0438\u043c\u043e\u043a \u0412\u041c +label.action.vmsnapshot.delete=\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0441\u043d\u0438\u043c\u043e\u043a \u0412\u041c +label.action.vmsnapshot.revert=\u0412\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0441\u043d\u0438\u043c\u043e\u043a \u0412\u041c label.activate.project=\u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043f\u0440\u043e\u0435\u043a\u0442 label.active.sessions=\u0410\u043a\u0442\u0438\u0432\u043d\u044b\u0435 \u0441\u0435\u0441\u0441\u0438\u0438 label.add.accounts.to=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0443\u0447\u0451\u0442\u043d\u044b\u0435 \u0437\u0430\u043f\u0438\u0441\u0438 label.add.accounts=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0430\u043a\u043a\u0430\u0443\u043d\u0442\u044b label.add.account.to.project=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0430\u043a\u043a\u0430\u0443\u043d\u0442 \u0432 \u043f\u0440\u043e\u0435\u043a\u0442 label.add.account=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0430\u043a\u043a\u0430\u0443\u043d\u0442 +label.add.ACL=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c ACL +label.add.affinity.group=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043d\u043e\u0432\u0443\u044e affinity group +label.add.BigSwitchVns.device=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c BigSwitch Vns Controller label.add.by.cidr=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043a CIDR label.add.by.group=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043a \u0433\u0440\u0443\u043f\u043f\u0435 label.add.by=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c @@ -261,40 +274,55 @@ label.additional.networks=\u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435 label.add.load.balancer=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0431\u0430\u043b\u0430\u043d\u0441\u0438\u0440\u043e\u0432\u043a\u0443 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0438 label.add.more=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0447\u0442\u043e-\u0442\u043e \u0435\u0449\u0435 label.add.netScaler.device=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c Netscaler \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e +label.add.network.ACL=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0441\u0435\u0442\u0435\u0432\u0443\u044e ACL label.add.network.device=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0441\u0435\u0442\u0435\u0432\u043e\u0435 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e label.add.network.offering=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0441\u0435\u0442\u0435\u0432\u043e\u0439 \u0440\u0435\u0441\u0443\u0440\u0441 label.add.network=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0441\u0435\u0442\u044c label.add.new.F5=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043d\u043e\u0432\u044b\u0439 F5 +label.add.new.gateway=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043d\u043e\u0432\u044b\u0439 \u0448\u043b\u044e\u0437 label.add.new.NetScaler=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043d\u043e\u0432\u044b\u0439 NetScaler +label.add.new.PA=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c Palo Alto label.add.new.SRX=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043d\u043e\u0432\u044b\u0439 SRX +label.add.new.tier=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043d\u043e\u0432\u044b\u0439 Tier +label.add.NiciraNvp.device=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 Nvp +label.add.PA.device=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e Palo Alto label.add.physical.network=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043a\u0443\u044e \u0441\u0435\u0442\u044c label.add.pod=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0441\u0442\u0435\u043d\u0434 +label.add.port.forwarding.rule=\u0414\u0430\u043b\u0438\u0442\u044c \u043f\u0440\u0430\u0432\u0438\u043b\u043e \u043f\u0435\u0440\u0435\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u043e\u0440\u0442\u0430 label.add.primary.storage=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 +label.add.region=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0440\u0435\u0433\u0438\u043e\u043d label.add.resources=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 +label.add.route=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043c\u0430\u0440\u0448\u0440\u0443\u0442 label.add.rule=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u0440\u0430\u0432\u0438\u043b\u043e label.add.secondary.storage=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 label.add.security.group=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0433\u0440\u0443\u043f\u043f\u0443 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u0438 label.add.service.offering=\u041d\u043e\u0432\u044b\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0439 \u0440\u0435\u0441\u0443\u0440\u0441 label.add.SRX.device=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c SRX \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e label.add.static.nat.rule=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u0440\u0430\u0432\u0438\u043b\u043e \u0441\u0442\u0430\u0442\u0438\u0447\u043d\u043e\u0433\u043e NAT +label.add.static.route=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0441\u0442\u0430\u0442\u0438\u0447\u043d\u044b\u0439 \u043c\u0430\u0440\u0448\u0440\u0443\u0442 label.add.system.service.offering=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0439 \u0440\u0435\u0441\u0443\u0440\u0441 label.add.template=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0448\u0430\u0431\u043b\u043e\u043d label.add.to.group=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432 \u0433\u0440\u0443\u043f\u043f\u0443 label.add=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c label.add.user=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f label.add.vlan=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c VLAN -label.add.vxlan=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c VXLAN label.add.vms.to.lb=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0412\u041c \u0432 \u043f\u0440\u0430\u0432\u0438\u043b\u043e \u0431\u0430\u043b\u0430\u043d\u0441\u0438\u0440\u043e\u0432\u043a\u0438 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0438 label.add.vms=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0412\u041c +label.add.VM.to.tier=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0412\u041c \u043a tier label.add.vm=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0412\u041c label.add.volume=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0442\u043e\u043c +label.add.vpc=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c VPC +label.add.vpn.customer.gateway=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c VPN \u0448\u043b\u044e\u0437 \u043a\u043b\u0438\u0435\u043d\u0442\u0430 +label.add.VPN.gateway=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c VPN \u0448\u043b\u044e\u0437 label.add.vpn.user=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f VPN +label.add.vxlan=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c VXLAN label.add.zone=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0437\u043e\u043d\u0443 label.admin.accounts=\u0410\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u0441\u043a\u0438\u0435 \u0443\u0447\u0451\u0442\u043d\u044b\u0435 \u0437\u0430\u043f\u0438\u0441\u0438 label.admin=\u0410\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440 label.advanced.mode=\u041f\u0440\u043e\u0434\u0432\u0438\u043d\u0443\u0442\u044b\u0439 \u0440\u0435\u0436\u0438\u043c label.advanced.search=\u0420\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u043d\u044b\u0439 \u043f\u043e\u0438\u0441\u043a label.advanced=\u041f\u0440\u043e\u0434\u0432\u0438\u043d\u0443\u0442\u044b\u0439 +label.affinity=\ \u0421\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u043e\u0441\u0442\u044c label.agent.password=\u041f\u0430\u0440\u043e\u043b\u044c \u0430\u0433\u0435\u043d\u0442\u0430 label.agent.username=\u0418\u043c\u044f \u0430\u0433\u0435\u043d\u0442\u0430 label.agree=\u0421\u043e\u0433\u043b\u0430\u0441\u0435\u043d @@ -304,10 +332,16 @@ label.allocated=\u0420\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u04 label.allocation.state=\u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f label.api.key=\u041a\u043b\u044e\u0447 API label.apply=\u041f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c +label.app.name=CloudStack +label.archive.alerts=\u0410\u0440\u0445\u0438\u0432\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u0440\u0435\u0432\u043e\u0433\u0438 +label.archive.events=\u0430\u0440\u0445\u0438\u0432\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u043e\u0431\u044b\u0442\u0438\u044f label.assign.to.load.balancer=\u0412\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043c\u0430\u0448\u0438\u043d\u044b \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u0431\u0430\u043b\u0430\u043d\u0441\u0438\u0440\u043e\u0432\u043a\u0438 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0438 label.assign=\u041f\u0440\u0438\u0441\u0432\u043e\u0438\u0442\u044c label.associated.network.id=\u0421\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0439 ID \u0441\u0435\u0442\u0438 +label.associated.network=\u0421\u0432\u044f\u0437\u0430\u043d\u043d\u0430\u044f \u0441\u0435\u0442\u044c label.attached.iso=\u041f\u0440\u0438\u043a\u0440\u0435\u043f\u043b\u0435\u043d\u043d\u044b\u0439 ISO +label.author.email=E-mail \u0430\u0432\u0442\u043e\u0440\u0430 +label.author.name=\u0418\u043c\u044f \u0430\u0432\u0442\u043e\u0440\u0430 label.availability=\u0414\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u044c label.availability.zone=\u0414\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u044c \u0437\u043e\u043d\u044b label.available.public.ips=\u0414\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u043f\u0443\u0431\u043b\u0438\u0447\u043d\u044b\u0435 IP-\u0430\u0434\u0440\u0435\u0441\u0430 @@ -316,13 +350,19 @@ label.back=\u041d\u0430\u0437\u0430\u0434 label.bandwidth=\u041f\u0440\u043e\u043f\u0443\u0441\u043a\u043d\u0430\u044f \u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e\u0441\u0442\u044c label.basic.mode=\u041f\u0440\u043e\u0441\u0442\u043e \u0440\u0435\u0436\u0438\u043c label.basic=\u041f\u0440\u043e\u0441\u0442\u043e\u0439 +label.bigswitch.controller.address=\u0410\u0434\u0440\u0435\u0441 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430 BigSwitch VNC label.bootable=\u0417\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c\u044b\u0439 label.broadcast.domain.range=\u0414\u0438\u0430\u043f\u0430\u0437\u043e\u043d \u0448\u0438\u0440\u043e\u043a\u043e\u0432\u0435\u0449\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u0434\u043e\u043c\u0435\u043d\u0430 label.broadcast.domain.type=\u0422\u0438\u043f \u0448\u0438\u0440\u043e\u043a\u043e\u0432\u0435\u0449\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u0434\u043e\u043c\u0435\u043d\u0430 +label.broadcast.uri=\u0428\u0438\u0440\u043e\u043a\u043e\u0432\u0435\u0449\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0439 URI label.by.account=\u041f\u043e \u0443\u0447\u0451\u0442\u043d\u043e\u0439 \u0437\u0430\u043f\u0438\u0441\u0438 +label.by.alert.type=\u041f\u043e \u0442\u0438\u043f\u0443 \u0442\u0440\u0435\u0432\u043e\u0433\u0438 label.by.availability=\u041f\u043e \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u0438 +label.by.date.end=\u041f\u043e \u0434\u0430\u0442\u0435(\u043a\u043e\u043d\u0435\u0446) +label.by.date.start=\u041f\u043e \u0434\u0430\u0442\u0435(\u043d\u0430\u0447\u0430\u043b\u043e) label.by.domain=\u0414\u043e \u0434\u043e\u043c\u0435\u043d\u0443 label.by.end.date=\u041f\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044e +label.by.event.type=\u041f\u043e \u0442\u0438\u043f\u0443 \u0441\u043e\u0431\u044b\u0442\u0438\u044f label.by.level=\u041f\u043e \u0443\u0440\u043e\u0432\u043d\u044e label.by.pod=\u041f\u043e \u0441\u0442\u0435\u043d\u0434\u0443 label.by.role=\u041f\u043e \u0440\u043e\u043b\u0438 @@ -344,6 +384,8 @@ label.checksum=\u041f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c MD5 \u0441 label.cidr.account=CIDR \u0438\u043b\u0438 \u0443\u0447\u0451\u0442\u043d\u0430\u044f \u0437\u0430\u043f\u0438\u0441\u044c/\u0433\u0440\u0443\u043f\u043f\u0430 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u0438 label.cidr=CIDR label.cidr.list=CIDR \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430 +label.CIDR.list=\u0421\u043f\u0438\u0441\u043e\u043a CIDR +label.CIDR.of.destination.network=CIDR \u0441\u0435\u0442\u0438 \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f label.clean.up=\u041e\u0447\u0438\u0441\u0442\u0438\u0442\u044c label.clear.list=\u041e\u0447\u0438\u0441\u0442\u0438\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a label.close=\u0417\u0430\u043a\u0440\u044b\u0442\u044c @@ -357,10 +399,13 @@ label.clvm=CLVM label.code=\u041a\u043e\u0434 label.community=\u0421\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u043e label.compute.and.storage=\u0412\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u0438 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 +label.compute.offerings=\u0423\u0441\u043b\u0443\u0433\u0438 \u0432\u044b\u0447\u0435\u0441\u043b\u0435\u043d\u0438\u044f label.compute.offering=\u0412\u044b\u0447\u0438\u0441\u043b\u0438\u0442\u044c \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u0435 label.compute=\u0412\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 label.configuration=\u041a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f +label.configure.network.ACLs=\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 ACL \u0441\u0435\u0442\u0438 label.configure=\u041d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c +label.configure.vpc=\u041d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c VPC label.confirmation=\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435 label.confirm.password=\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435 \u043f\u0430\u0440\u043e\u043b\u044c label.congratulations=\u041f\u043e\u0437\u0434\u0440\u0430\u0432\u043b\u044f\u0435\u043c\! @@ -373,29 +418,43 @@ label.cpu.allocated.for.VMs=\u0420\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u04 label.cpu.allocated=\u0420\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043e \u0426\u041f\u0423 label.CPU.cap=CPU Cap label.cpu=CPU +label.cpu.limits=\u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f CPU label.cpu.mhz=CPU (\u0432 \u041c\u0433\u0446) label.cpu.utilized=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 CPU label.created.by.system=\u0421\u043e\u0437\u0434\u0430\u043d\u043e \u0441\u0438\u0441\u0442\u0435\u043c\u043e\u0439 label.created=\u0421\u043e\u0437\u0434\u0430\u043d\u043e label.create.project=\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u043f\u0440\u043e\u0435\u043a\u0442 label.create.template=\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0448\u0430\u0431\u043b\u043e\u043d +label.create.VPN.connection=\u0421\u043e\u0437\u0434\u0430\u0442\u044c VPN \u043f\u043e\u0434\u043b\u044e\u0447\u0435\u043d\u0438\u0435 label.cross.zones=\u041e\u0431\u0449\u0438\u0435 \u0434\u043b\u044f \u0437\u043e\u043d +label.custom.disk.iops=\u0421\u0432\u043e\u0435 \u043a\u043e\u043b-\u0432\u043e IPOS label.custom.disk.size=\u0421\u0432\u043e\u0439 \u0440\u0430\u0437\u043c\u0435\u0440 \u0434\u0438\u0441\u043a\u0430 label.daily=\u0415\u0436\u0435\u0434\u043d\u0435\u0432\u043d\u043e label.data.disk.offering=\u0414\u0430\u043d\u043d\u044b\u0435 \u0434\u0438\u0441\u043a\u0430 label.date=\u0414\u0430\u0442\u0430 label.day.of.month=\u0414\u0435\u043d\u044c \u043c\u0435\u0441\u044f\u0446\u0430 label.day.of.week=\u0414\u0435\u043d\u044c \u043d\u0435\u0434\u0435\u043b\u0438 +label.dead.peer.detection=Dead Peer Detection label.decline.invitation=\u041e\u0442\u043c\u0435\u043d\u0438\u0442\u044c \u043f\u0440\u0438\u0433\u043b\u0430\u0448\u0435\u043d\u0438\u0435 label.dedicated=\u0412\u044b\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0439 label.default=\u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e label.default.use=\u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e label.default.view=\u041e\u0431\u044b\u0447\u043d\u044b\u0439 \u0432\u0438\u0434 +label.delete.affinity.group=\u0423\u0434\u0430\u043b\u0438\u0442\u044c affinity group +label.delete.alerts=\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0442\u0440\u0435\u0432\u043e\u0433\u0438 +label.delete.BigSwitchVns=\u0423\u0434\u0430\u043b\u0438\u0442\u044c BigSwitch VNC \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 +label.delete.events=\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0441\u043e\u0431\u044b\u0442\u0438\u044f label.delete.F5=\u0423\u0434\u0430\u043b\u0438\u0442\u044c F5 +label.delete.gateway=\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0448\u043b\u044e\u0437 label.delete.NetScaler=\u0423\u0434\u0430\u043b\u0438\u0442\u044c NetScaler +label.delete.NiciraNvp=\u0423\u0434\u0430\u043b\u0438\u0442\u044c Nvp \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 +label.delete.PA=\u0423\u0434\u0430\u043b\u0438\u0442\u044c Palo Alto label.delete.project=\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u043f\u0440\u043e\u0435\u043a\u0442 label.delete.SRX=\u0423\u0434\u0430\u043b\u0438\u0442\u044c SRX label.delete=\u0423\u0434\u0430\u043b\u0438\u0442\u044c +label.delete.VPN.connection=\u0423\u0434\u0430\u043b\u0438\u0442\u044c VPN \u043f\u043e\u0434\u043b\u044e\u0447\u0435\u043d\u0438\u0435 +label.delete.VPN.customer.gateway=\u0423\u0434\u0430\u043b\u0438\u0442\u044c VPN \u0448\u043b\u044e\u0437 \u043a\u043b\u0438\u0435\u043d\u0442\u0430 +label.delete.VPN.gateway=\u0423\u0434\u0430\u043b\u0438\u0442\u044c VPN \u0448\u043b\u044e\u0437 label.delete.vpn.user=\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f VPN label.deleting.failed=\u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0443\u0434\u0430\u043b\u0438\u0442\u044c label.deleting.processing=\u0423\u0434\u0430\u043b\u0435\u043d\u0438\u0435... @@ -416,15 +475,28 @@ label.disable.provider=\u0412\u044b\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u label.disable.vpn=\u0412\u044b\u043a\u043b\u044e\u0447\u0438\u0442\u044c VPN label.disabling.vpn.access=\u0412\u044b\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a VPN label.disk.allocated=\u0420\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043e \u0434\u0438\u0441\u043a\u043e\u0432\u043e\u0433\u043e \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0430 +label.disk.bytes.read.rate=\u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0447\u0442\u0435\u043d\u0438\u044f \u0434\u0438\u0441\u043a\u0430 (BPS) +label.disk.bytes.write.rate=\u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0437\u0430\u043f\u0438\u0441\u0438 \u0434\u0438\u0441\u043a\u0430 (BPS) +label.disk.iops.max=\u041c\u0430\u043a\u0441. IOPS +label.disk.iops.min=\u041c\u0438\u043d. IOPS +label.disk.iops.read.rate=\u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0437\u0430\u043f\u0438\u0441\u0438 \u0434\u0438\u0441\u043a\u0430 (IOPS) +label.disk.iops.total=\u0412\u0441\u0435\u0433\u043e IOPS +label.disk.iops.write.rate=\u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0437\u0430\u043f\u0438\u0441\u0438 \u0434\u0438\u0441\u043a\u0430 (IOPS) label.disk.offering=\u0414\u0438\u0441\u043a\u043e\u0432\u044b\u0439 \u0440\u0435\u0441\u0443\u0440\u0441 +label.disk.read.bytes=\u041f\u0440\u043e\u0447\u0438\u0442\u0430\u043d\u043e \u0441 \u0434\u0438\u0441\u043a\u0430 (\u0411\u0430\u0439\u0442) +label.disk.read.io=\u041f\u0440\u043e\u0447\u0438\u0442\u0430\u043d\u043e \u0441 \u0434\u0438\u0441\u043a\u0430 (IO) label.disk.size.gb=\u0420\u0430\u0437\u043c\u0435\u0440 \u0434\u0438\u0441\u043a\u0430 (\u0432 \u0413\u0411) label.disk.size=\u0420\u0430\u0437\u043c\u0435\u0440 \u0434\u0438\u0441\u043a\u0430 label.disk.total=\u0412\u0441\u0435\u0433\u043e \u0432 \u0434\u0438\u0441\u043a\u0430\u0445 label.disk.volume=\u0422\u043e\u043c \u0434\u0438\u0441\u043a\u0430 +label.disk.write.bytes=\u0417\u0430\u043f\u0438\u0441\u0430\u043d\u043e \u043d\u0430 \u0434\u0438\u0441\u043a (\u0411\u0430\u0439\u0442) +label.disk.write.io=\u0417\u0430\u043f\u0438\u0441\u0430\u043d\u043e \u043d\u0430 \u0434\u0438\u0441\u043a (IO) label.display.name=\u041e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u043c\u043e\u0435 \u0438\u043c\u044f label.display.text=\u041e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u043c\u044b\u0439 \u0442\u0435\u043a\u0441\u0442 label.dns.1=DNS 1 label.dns.2=DNS 2 +label.dns=DNS +label.DNS.domain.for.guest.networks=DNS \u0434\u043e\u043c\u0435\u043d \u0434\u043b\u044f \u0433\u043e\u0441\u0442\u0435\u0432\u043e\u0439 \u0441\u0435\u0442\u0438 label.domain.admin=\u0410\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440 \u0434\u043e\u043c\u0435\u043d\u0430 label.domain.id=ID \u0434\u043e\u043c\u0435\u043d\u0430 label.domain.name=\u0418\u043c\u044f \u0434\u043e\u043c\u0435\u043d\u0430 @@ -435,23 +507,30 @@ label.done=\u0413\u043e\u0442\u043e\u0432\u043e label.double.quotes.are.not.allowed=\u0414\u0432\u043e\u0439\u043d\u044b\u0435 \u043a\u0430\u0432\u044b\u0447\u043a\u0438 \u0437\u0430\u043f\u0440\u0435\u0449\u0435\u043d\u044b label.download.progress=\u0421\u0442\u0430\u0442\u0443\u0441 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 label.drag.new.position=\u041f\u0435\u0440\u0435\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u043d\u0430 \u043d\u043e\u0432\u0443\u044e \u043f\u043e\u0437\u0438\u0446\u0438\u044e +label.edit.affinity.group=\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c affinity group label.edit.lb.rule=\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c LB \u043f\u0440\u0430\u0432\u0438\u043b\u0430 label.edit.network.details=\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0434\u0435\u0442\u0430\u043b\u0438 \u0441\u0435\u0442\u0438 label.edit.project.details=\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0434\u0435\u0442\u0430\u043b\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 +label.edit.tags=\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u044d\u0433\u0438 label.edit.traffic.type=\u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0442\u0438\u043f \u0442\u0440\u0430\u0444\u0438\u043a\u0430 label.edit=\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c +label.edit.vpc=\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c VPC +label.egress.default.policy=\u0418\u0441\u0445\u043e\u0434\u044f\u0449\u0430\u044f \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0430 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e +label.egress.rules=\u0418\u0441\u0445\u043e\u0434\u044f\u0449\u0438\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 label.egress.rule=\u0412\u044b\u0445\u043e\u0434\u043d\u043e\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u043e label.elastic.IP=\u0413\u0438\u0431\u043a\u0438\u0439 IP label.elastic.LB=\u0413\u0438\u0431\u043a\u0438\u0439 LB label.elastic=\u0413\u0438\u0431\u043a\u0438\u0439 label.email=E-mail label.enable.provider=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043f\u043e\u0441\u0442\u0430\u0432\u0449\u0438\u043a\u0430 +label.enable.s3=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c S3-\u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u043e\u0435 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 label.enable.swift=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c Swift label.enable.vpn=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c VPN label.enabling.vpn.access=\u0412\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a VPN label.enabling.vpn=\u0412\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 VPN label.end.IP=\u041a\u043e\u043d\u0435\u0447\u043d\u044b\u0439 IP label.endpoint.or.operation=\u041a\u043e\u043d\u0435\u0447\u043d\u0430\u044f \u0442\u043e\u0447\u043a\u0430 \u0438\u043b\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f +label.endpoint=\u041a\u043e\u043d\u0435\u0447\u043d\u0430\u044f \u0442\u043e\u0447\u043a\u0430 label.end.port=\u041a\u043e\u043d\u0435\u0447\u043d\u044b\u0439 \u043f\u043e\u0440\u0442 label.end.reserved.system.IP=\u041a\u043e\u043d\u0435\u0447\u043d\u044b\u0439 \u0437\u0430\u0440\u0435\u0437\u0435\u0440\u0432\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0439 IP-\u0430\u0434\u0440\u0435\u0441 label.end.vlan=\u041a\u043e\u043d\u0435\u0447\u043d\u044b\u0439 VLAN @@ -459,8 +538,13 @@ label.end.vxlan=\u041a\u043e\u043d\u0435\u0447\u043d\u044b\u0439 VXLAN label.enter.token=\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u0442\u0430\u043b\u043e\u043d label.error.code=\u041a\u043e\u0434 \u043e\u0448\u0438\u0431\u043a\u0438 label.error=\u041e\u0448\u0438\u0431\u043a\u0430 +label.ESP.encryption=\u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u0438\u0435 ESP +label.ESP.hash=\u0445\u044d\u0448 ESP +label.ESP.lifetime=\u0412\u0440\u0435\u043c\u044f \u0436\u0438\u0437\u043d\u0438 ESP (\u0432 \u0441\u0435\u043a\u0443\u043d\u0434\u0430\u0445) +label.ESP.policy=\u041f\u043e\u043b\u0438\u0442\u0438\u043a\u0430 ESP label.esx.host=\u0423\u0437\u0435\u043b ESX/ESXi label.example=\u041f\u0440\u0438\u043c\u0435\u0440 +label.external.link=\u0412\u043d\u0435\u0448\u043d\u0435\u0435 \u043f\u043e\u0434\u043b\u044e\u0447\u0435\u043d\u0438\u0435 label.f5=F5 label.failed=\u041d\u0435\u0443\u0434\u0430\u0447\u043d\u043e label.featured=\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0439 @@ -475,6 +559,7 @@ label.full=\u041f\u043e\u043b\u043d\u044b\u0439 label.gateway=\u0428\u043b\u044e\u0437 label.general.alerts=\u041e\u0431\u0449\u0438\u0435 \u0442\u0440\u0435\u0432\u043e\u0433\u0438 label.generating.url=\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 URL +label.gluster.volume=\u0422\u043e\u043c label.go.step.2=\u041f\u0435\u0440\u0435\u0439\u0442\u0438 \u043a \u0448\u0430\u0433\u0443 2 label.go.step.3=\u041f\u0435\u0440\u0435\u0439\u0442\u0438 \u043a \u0448\u0430\u0433\u0443 3 label.go.step.4=\u041f\u0435\u0440\u0435\u0439\u0442\u0438 \u043a \u0448\u0430\u0433\u0443 4 @@ -496,6 +581,7 @@ label.ha.enabled=HA \u0432\u043a\u043b\u044e\u0447\u0435\u043d label.help=\u041f\u043e\u043c\u043e\u0449\u044c label.hide.ingress.rule=\u0421\u043a\u0440\u044b\u0442\u044c \u0432\u0445\u043e\u0434\u043d\u043e\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u043e label.hints=\u041f\u043e\u0434\u0441\u043a\u0430\u0437\u043a\u0438 +label.home=\u0413\u043b\u0430\u0432\u043d\u0430\u044f label.host.alerts=\u0422\u0440\u0435\u0432\u043e\u0433\u0438 \u0443\u0437\u043b\u0430 label.host.MAC=MAC \u0443\u0437\u043b\u0430 label.host.name=\u0418\u043c\u044f \u0443\u0437\u043b\u0430 @@ -504,10 +590,16 @@ label.host.tags=\u041c\u0435\u0442\u043a\u0438 \u0443\u0437\u043b\u0430 label.host=\u0423\u0437\u0435\u043b label.hourly=\u0427\u0430\u0441\u043e\u0432\u0430\u044f label.hypervisor.capabilities=\u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0433\u0438\u043f\u0435\u0440\u0432\u0438\u0437\u043e\u0440\u0430 +label.hypervisors=\u0413\u0438\u043f\u0435\u0440\u0432\u0438\u0437\u043e\u0440\u044b label.hypervisor.type=\u0422\u0438\u043f \u0433\u0438\u043f\u0435\u0440\u0432\u0438\u0437\u043e\u0440\u0430 label.hypervisor=\u0413\u0438\u043f\u0435\u0440\u0432\u0438\u0437\u043e\u0440 label.hypervisor.version=\u0412\u0435\u0440\u0441\u0438\u044f \u0433\u0438\u043f\u0435\u0440\u0432\u0438\u0437\u043e\u0440\u0430 label.id=ID +label.IKE.DH=IKE DH +label.IKE.encryption=\u0428\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u0438\u0435 IKE +label.IKE.hash=IKE Hash +label.IKE.lifetime=IKE lifetime (second) +label.IKE.policy=\u041f\u043e\u043b\u0438\u0442\u0438\u043a\u0430 IKE label.info=\u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f label.ingress.rule=\u0412\u043d\u0443\u0442\u0440\u0438\u043d\u0435\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u043e label.initiated.by=\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c @@ -550,6 +642,7 @@ label.ip.limits=\u041f\u0440\u0435\u0434\u0435\u043b\u044b \u043f\u0443\u0431\u0 label.ip.or.fqdn=IP \u0438\u043b\u0438 FQDN label.ip.ranges=\u0414\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u044b IP label.ip.range=\u0414\u0438\u0430\u043f\u0430\u0437\u043e\u043d IP +label.IPsec.preshared.key=IPsec Preshared-Key label.ips=IP label.iscsi=iSCSI label.is.default=\u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e @@ -558,6 +651,7 @@ label.iso=ISO label.isolated.networks=\u0418\u0437\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0441\u0435\u0442\u0438 label.isolation.method=\u041c\u0435\u0442\u043e\u0434 \u0438\u0437\u043e\u043b\u044f\u0446\u0438\u0438 label.isolation.mode=\u0420\u0435\u0436\u0438\u043c \u0438\u0437\u043e\u043b\u044f\u0446\u0438\u0438 +label.isolation.uri=\u0418\u0437\u043e\u043b\u044f\u0446\u0438\u044f URI label.is.redundant.router=\u0420\u0435\u0437\u0435\u0440\u0432\u043d\u043e\u0439 label.is.shared=\u043e\u0431\u0449\u0438\u0435 label.is.system=\u0415\u0441\u0442\u044c \u0441\u0438\u0441\u0442\u0435\u043c\u0430 @@ -571,6 +665,7 @@ label.lang.chinese=\u041a\u0438\u0442\u0430\u0439\u0441\u043a\u0438\u0439 (\u044 label.lang.english=\u0410\u043d\u0433\u043b\u0438\u0439\u0441\u043a\u0438\u0439 label.lang.japanese=\u042f\u043f\u043e\u043d\u0441\u043a\u0438\u0439 label.lang.korean=\u043a\u043e\u0440\u0435\u0439\u0441\u043a\u0438\u0439 +label.lang.russian=\u0420\u0443\u0441\u0441\u043a\u0438\u0439 label.lang.spanish=\u0418\u0441\u043f\u0430\u043d\u0441\u043a\u0438\u0439 label.last.disconnected=\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0435 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 label.last.name=\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0435 \u0438\u043c\u044f @@ -581,10 +676,12 @@ label.launch.zone=\u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0437\ label.LB.isolation=\u0418\u0437\u043e\u043b\u044f\u0446\u0438\u044f LB label.least.connections=Least connections label.level=\u0423\u0440\u043e\u0432\u0435\u043d\u044c +label.linklocal.ip=\u041b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0439 IP \u0430\u0434\u0440\u0435\u0441 label.load.balancer=\u0411\u0430\u043b\u0430\u043d\u0441\u0438\u0440\u043e\u0432\u043a\u0430 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0438 label.load.balancing.policies=\u041f\u043e\u043b\u0438\u0442\u0438\u043a\u0438 \u0431\u0430\u043b\u0430\u043d\u0441\u0438\u0440\u043e\u0432\u043a\u0438 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0438 label.load.balancing=\u0411\u0430\u043b\u0430\u043d\u0441\u0438\u0440\u043e\u0432\u043a\u0430 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0438 label.loading=\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 +label.local.storage.enabled=\u041b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u043e label.local.storage=\u041b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 label.local=\u041b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0439 label.login=\u0412\u0445\u043e\u0434 @@ -596,16 +693,22 @@ label.management.ips=\u041f\u0430\u043d\u0435\u043b\u044c \u0443\u043f\u0440\u04 label.management=\u0423\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 label.manage.resources=\u0423\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u0430\u043c\u0438 label.manage=\u0423\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 +label.max.cpus=\u041c\u0430\u043a\u0441. \u044f\u0434\u0435\u0440 \u0426\u041f label.max.guest.limit=\u041f\u0440\u0435\u0434\u0435\u043b \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0433\u043e\u0441\u0442\u0435\u0439 label.maximum=\u041c\u0430\u043a\u0441\u0438\u043c\u0443\u043c +label.max.memory=\u041c\u0430\u043a\u0441. \u043f\u0430\u043c\u044f\u0442\u0438 (\u0432 \u041c\u0438\u0411) label.max.networks=\u041c\u0430\u043a\u0441\u0438\u043c\u0443\u043c \u0441\u0435\u0442\u0435\u0439 +label.max.primary.storage=\u041c\u0430\u043a\u0441. \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0433\u043e \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 (\u0432 \u0413\u0438\u0411) label.max.public.ips=\u041c\u0430\u043a\u0441. \u043f\u0443\u0431\u043b\u0438\u0447\u043d\u044b\u0445 IP +label.max.secondary.storage=\u041c\u0430\u043a\u0441. \u0432\u0442\u043e\u0440\u0438\u0447\u043d\u043e\u0433\u043e \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 (\u0432 \u0413\u0438\u0411) label.max.snapshots=\u041c\u0430\u043a\u0441. \u0441\u043d\u0438\u043c\u043a\u043e\u0432 label.max.templates=\u041c\u0430\u043a\u0441. \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u0432 label.max.vms=\u041c\u0430\u043a\u0441. \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0445 \u0412\u041c label.max.volumes=\u041c\u0430\u043a\u0441. \u0442\u043e\u043c\u043e\u0432 +label.max.vpcs=\u041c\u0430\u043a\u0441. VPC label.may.continue=\u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u044c. label.memory.allocated=\u0420\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043e \u043f\u0430\u043c\u044f\u0442\u0438 +label.memory.limits=\u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f \u043f\u0430\u043c\u044f\u0442\u0438 (\u0432 \u041c\u0438\u0411) label.memory.mb=\u041f\u0430\u043c\u044f\u0442\u044c (\u0432 \u041c\u0411) label.memory.total=\u0412\u0441\u0435\u0433\u043e \u043f\u0430\u043c\u044f\u0442\u0438 label.memory=\u041f\u0430\u043c\u044f\u0442\u044c @@ -636,6 +739,7 @@ label.menu.my.templates=\u041c\u043e\u0438 \u0448\u0430\u0431\u043b\u043e\u043d\ label.menu.network.offerings=\u041f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441\u0435\u0442\u0438 label.menu.network=\u0421\u0435\u0442\u044c label.menu.physical.resources=\u0424\u0438\u0437\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u044b +label.menu.regions=\u0420\u0435\u0433\u0438\u043e\u043d label.menu.running.instances=\u0417\u0430\u043f\u0443\u0449\u0435\u043d\u043d\u044b\u0435 \u043c\u0430\u0448\u0438\u043d\u044b label.menu.security.groups=\u0413\u0440\u0443\u043f\u043f\u044b \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u0438 label.menu.service.offerings=\u0423\u0441\u043b\u0443\u0433\u0438 @@ -654,13 +758,17 @@ label.migrate.instance.to.ps=\u041f\u0435\u0440\u0435\u043d\u043e\u0441 \u043c\u label.migrate.instance.to=\u041f\u0435\u0440\u0435\u043d\u0435\u0441\u0442\u0438 \u043c\u0430\u0448\u0438\u043d\u0443 \u0432 label.migrate.router.to=\u041f\u0435\u0440\u0435\u043d\u0435\u0441\u0442\u0438 \u0440\u043e\u0443\u0442\u0435\u0440 \u0432 label.migrate.systemvm.to=\u041f\u0435\u0440\u0435\u043d\u0435\u0441\u0442\u0438 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u0443\u044e \u0412\u041c \u0432 +label.migrate.to.host=\u041f\u0435\u0440\u0435\u043d\u0435\u0441\u0442\u0438 \u043d\u0430 \u0443\u0437\u0435\u043b +label.migrate.to.storage=\u041f\u0435\u0440\u0435\u043d\u0435\u0441\u0442\u0438 \u043d\u0430 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 label.migrate.volume=\u041f\u0435\u0440\u0435\u043d\u0435\u0441\u0442\u0438 \u0442\u043e\u043c \u0432 \u0434\u0440\u0443\u0433\u043e\u0435 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 label.minimum=\u041c\u0438\u043d\u0438\u043c\u0443\u043c label.minute.past.hour=\u041c\u0438\u043d\u0443\u0442\u0430 +label.mode=\u0420\u0435\u0436\u0438\u043c label.monday=\u041f\u043e\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u0438\u043a label.monthly=\u041a\u0430\u0436\u0434\u044b\u0439 \u043c\u0435\u0441\u044f\u0446 label.more.templates=\u0411\u043e\u043b\u044c\u0448\u0435 \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u0432 label.move.down.row=\u041f\u0435\u0440\u0435\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u043d\u0430 \u043e\u0434\u043d\u0443 \u0441\u0442\u0440\u043e\u043a\u0443 \u043d\u0438\u0436\u0435 +label.move.to.bottom=\u041f\u0435\u0440\u0435\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u0432\u043d\u0438\u0437 label.move.to.top=\u041f\u0435\u0440\u0435\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u043d\u0430 \u0441\u0430\u043c\u044b\u0439 \u0432\u0435\u0440\u0445 label.move.up.row=\u041f\u0435\u0440\u0435\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u043d\u0430 \u043e\u0434\u043d\u0443 \u0441\u0442\u0440\u043e\u043a\u0443 \u0432\u044b\u0448\u0435 label.my.account=\u041c\u043e\u044f \u0443\u0447\u0451\u0442\u043d\u0430\u044f \u0437\u0430\u043f\u0438\u0441\u044c @@ -671,6 +779,9 @@ label.name=\u0418\u043c\u044f label.nat.port.range=NAT \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d \u043f\u043e\u0440\u0442\u043e\u0432 label.netmask=\u0421\u0435\u0442\u0435\u0432\u0430\u044f \u043c\u0430\u0441\u043a\u0430 label.netScaler=NetScaler +label.network.ACL=ACL \u0441\u0435\u0442\u0438 +label.network.ACLs=\u0421\u0435\u0442\u0435\u0432\u044b\u0435 ACL +label.network.ACL.total=\u0412\u0441\u0435\u0433\u043e ACL \u0441\u0435\u0442\u0438 label.network.desc=\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0441\u0435\u0442\u0438 label.network.device.type=\u0422\u0438\u043f \u0441\u0435\u0442\u0435\u0432\u043e\u0433\u043e \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 label.network.device=\u0421\u0435\u0442\u0435\u0432\u043e\u0435 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e @@ -679,11 +790,13 @@ label.network.domain=\u0414\u043e\u043c\u0435\u043d \u0441\u0435\u0442\u0438 label.network.id=ID \u0441\u0435\u0442\u0438 label.networking.and.security=\u0421\u0435\u0442\u044c \u0438 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u044c label.network.label.display.for.blank.value=\u0418\u0441\u043f. \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0448\u043b\u044e\u0437 +label.network.limits=\u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f \u0441\u0435\u0442\u0438 label.network.name=\u0418\u043c\u044f \u0441\u0435\u0442\u0438 label.network.offering.display.text=\u0441\u0435\u0442\u044c, \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u044e\u0449\u0443\u044e \u041e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0442\u0435\u043a\u0441\u0442\u0430 label.network.offering.id=\u0441\u0435\u0442\u044c, \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u044e\u0449\u0443\u044e ID label.network.offering.name=\u0441\u0435\u0442\u044c, \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u044e\u0449\u0443\u044e \u0418\u043c\u044f label.network.offering=\u0421\u0435\u0442\u0435\u0432\u044b\u0435 \u0443\u0441\u043b\u0443\u0433\u0438 +label.network.rate.megabytes=\u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0441\u0435\u0442\u0438 (MB/s) label.network.rate=\u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0441\u0435\u0442\u0438 label.network.read=\u041f\u0440\u043e\u0447\u0438\u0442\u0430\u043d\u043e \u0447\u0435\u0440\u0435\u0437 \u0441\u0435\u0442\u044c label.network.service.providers=\u041f\u043e\u0441\u0442\u0430\u0432\u0449\u0438\u043a\u0438 \u0441\u0435\u0442\u0435\u0432\u044b\u0445 \u0441\u043b\u0443\u0436\u0431 @@ -701,6 +814,9 @@ label.nfs=NFS label.nfs.server=\u0421\u0435\u0440\u0432\u0435\u0440 NFS label.nfs.storage=\u0425\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 NFS label.nic.adapter.type=\u0422\u0438\u043f \u0441\u0435\u0442\u0435\u0432\u043e\u0439 \u043a\u0430\u0440\u0442\u044b (NIC) +label.nicira.controller.address=\u0410\u0434\u0440\u0435\u0441 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430 +label.nicira.l3gatewayserviceuuid=L3 Gateway Service Uuid +label.nicira.transportzoneuuid=Transport Zone Uuid label.nics=\u0421\u0435\u0442\u0435\u0432\u044b\u0435 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 (NIC) label.no.actions=\u041d\u0435\u0442 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 label.no.alerts=\u0422\u0440\u0435\u0432\u043e\u0433 \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043e @@ -736,6 +852,7 @@ label.parent.domain=\u0420\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a label.password.enabled=\u041f\u0430\u0440\u043e\u043b\u044c \u0432\u043a\u043b\u044e\u0447\u0435\u043d label.password=\u041f\u0430\u0440\u043e\u043b\u044c label.path=\u041f\u0443\u0442\u044c +label.perfect.forward.secrecy=Perfect Forward Secrecy label.physical.network.ID=ID \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u0441\u0435\u0442\u0438 label.physical.network=\u0424\u0438\u0437\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0441\u0435\u0442\u0438 label.PING.CIFS.password=\u041f\u0430\u0440\u043e\u043b\u044c PING CIFS @@ -744,6 +861,8 @@ label.PING.dir=\u041a\u0430\u0442\u0430\u043b\u043e\u0433 PING label.PING.storage.IP=IP \u0430\u0434\u0440\u0435\u0441 PING-\u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 label.please.specify.netscaler.info=\u0423\u043a\u0430\u0436\u0438\u0442\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 NetScaler label.please.wait=\u041f\u043e\u0434\u043e\u0436\u0434\u0438\u0442\u0435 +label.plugin.details=\u0414\u0435\u0442\u0430\u043b\u0438 \u043f\u043b\u0430\u0433\u0438\u043d\u0430 +label.plugins=\u041f\u043b\u0430\u0433\u0438\u043d\u044b label.pod.name=\u0418\u043c\u044f \u0441\u0442\u0435\u043d\u0434\u0430 label.pods=\u0421\u0442\u0435\u043d\u0434\u044b label.pod=\u0421\u0442\u0435\u043d\u0434 @@ -756,8 +875,10 @@ label.prev=\u041f\u0440\u0435\u0434\u044b\u0434\u0443\u0448\u0438\u0439 label.primary.allocated=\u0420\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0433\u043e \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 label.primary.network=\u041e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u0441\u0435\u0442\u044c label.primary.storage.count=\u041f\u0435\u0440\u0432\u0438\u0447\u043d\u044b\u0439 \u0430\u0440\u0445\u0438\u0432 \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f +label.primary.storage.limits=\u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0433\u043e \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 (\u0432 \u0413\u0438\u0411) label.primary.storage=\u041e\u0441\u043d\u043e\u0432\u043d\u043e\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 label.primary.used=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0433\u043e \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 +label.private.Gateway=\u0427\u0430\u0441\u0442\u043d\u044b\u0439 \u0448\u043b\u044e\u0437 label.private.interface=\u0427\u0430\u0441\u0442\u043d\u044b\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 label.private.ip.range=\u0414\u0438\u0430\u043f\u0430\u0437\u043e\u043d \u0447\u0430\u0441\u0442\u043d\u044b\u0445 IP label.private.ips=\u0427\u0430\u0441\u0442\u043d\u044b\u0435 IP-\u0430\u0434\u0440\u0435\u0441\u0430 @@ -785,29 +906,38 @@ label.public=\u041f\u0443\u0431\u043b\u0438\u0447\u043d\u044b\u0439 label.public.zone=\u041f\u0443\u0431\u043b\u0438\u0447\u043d\u0430\u044f \u0437\u043e\u043d\u0430 label.purpose=\u041d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 label.Pxe.server.type=\u0422\u0438\u043f \u0441\u0435\u0440\u0432\u0435\u0440\u0430 PXE +label.qos.type=\u0422\u0438\u043f QoS +label.quickview=\u0411\u044b\u0441\u0442\u0440\u044b\u0439 \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440 label.reboot=\u041f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c label.recent.errors=\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 label.redundant.router.capability=\u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0440\u0435\u0437\u0435\u0440\u0432\u043d\u043e\u0433\u043e \u0440\u043e\u0443\u0442\u0435\u0440\u0430 label.redundant.router=\u0420\u0435\u0437\u0435\u0440\u0432\u043d\u043e\u0439 \u0440\u043e\u0443\u0442\u0435\u0440 label.redundant.state=\u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0440\u0435\u0437\u0435\u0440\u0432\u0430 label.refresh=\u041e\u0431\u043d\u043e\u0432\u0438\u0442\u044c +label.region=\u0420\u0435\u0433\u0438\u043e\u043d label.related=\u0421\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0439 label.remind.later=\u041f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0434\u0438\u0442\u044c \u043f\u043e\u0437\u0436\u0435 +label.remove.ACL=\u0423\u0434\u0430\u043b\u0438\u0442\u044c ACL label.remove.egress.rule=\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0432\u044b\u0445\u043e\u0434\u043d\u043e\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u043e label.remove.from.load.balancer=\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u043c\u0430\u0448\u0438\u043d\u0443 \u0441 \u0431\u0430\u043b\u0430\u043d\u0441\u0438\u0440\u043e\u0432\u043a\u0438 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0438 label.remove.ingress.rule=\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0432\u0445\u043e\u0434\u043d\u043e\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u043e label.remove.ip.range=\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d IP label.remove.pf=\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u043f\u0440\u0430\u0432\u0438\u043b\u043e \u043f\u0440\u043e\u0431\u0440\u043e\u0441\u0430 \u043f\u043e\u0440\u0442\u0430 label.remove.project.account=\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0443\u0447\u0435\u0442\u043d\u0443\u044e \u0437\u0430\u043f\u0438\u0441\u044c \u043f\u0440\u043e\u0435\u043a\u0442\u0430 +label.remove.region=\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0440\u0435\u0433\u0438\u043e\u043d label.remove.rule=\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u043f\u0440\u0430\u0432\u0438\u043b\u043e label.remove.static.nat.rule=\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u043f\u0440\u0430\u0432\u0438\u043b\u043e \u0441\u0442\u0430\u0442\u0438\u0447\u043d\u043e\u0433\u043e NAT +label.remove.static.route=\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0441\u0442\u0430\u0442\u0438\u0447\u043d\u044b\u0439 \u043c\u0430\u0440\u0448\u0440\u0443\u0442 +label.remove.tier=\u0423\u0434\u0430\u043b\u0438\u0442\u044c tier label.remove.vm.from.lb=\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0412\u041c \u0441 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0431\u0430\u043b\u0430\u043d\u0441\u0438\u0440\u043e\u0432\u043a\u0438 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0438 +label.remove.vpc=\u0423\u0434\u0430\u043b\u0438\u0442\u044c VPC label.removing=\u0423\u0434\u0430\u043b\u0435\u043d\u0438\u0435 label.removing.user=\u0423\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f label.required=\u0422\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f label.reserved.system.gateway=\u0417\u0430\u0440\u0435\u0437\u0435\u0440\u0432\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0439 \u0448\u043b\u044e\u0437 label.reserved.system.ip=\u0417\u0430\u0440\u0435\u0437\u0435\u0440\u0432\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0439 IP label.reserved.system.netmask=\u0417\u0430\u0440\u0435\u0437\u0435\u0440\u0432\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0430\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u0430\u044f \u043c\u0430\u0441\u043a\u0430 +label.reset.VPN.connection=\u0412\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c VPN \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 label.resize.new.offering.id=New Offering label.resize.new.size=New Size(GB) label.resize.shrink.ok=Shrink OK @@ -817,15 +947,27 @@ label.resources=\u0420\u0435\u0441\u0443\u0440\u0441\u044b label.resource=\u0420\u0435\u0441\u0443\u0440\u0441 label.restart.network=\u041f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0441\u0435\u0442\u044c label.restart.required=\u0422\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a +label.restart.vpc=\u041f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c VPC +label.restore=\u0412\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c label.review=\u041e\u0431\u0437\u043e\u0440 label.revoke.project.invite=\u041e\u0442\u043e\u0437\u0432\u0430\u0442\u044c \u043f\u0440\u0438\u0433\u043b\u0430\u0448\u0435\u043d\u0438\u0435 label.role=\u0420\u043e\u043b\u044c label.root.disk.controller=\u041a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 \u043a\u043e\u0440\u043d\u0435\u0432\u043e\u0433\u043e \u0434\u0438\u0441\u043a\u0430 label.root.disk.offering=\u0420\u0435\u0441\u0443\u0440\u0441 \u043a\u043e\u0440\u043d\u0435\u0432\u043e\u0433\u043e \u0434\u0438\u0441\u043a\u0430 +label.root.disk.size=\u0420\u0430\u0437\u043c\u0435\u0440 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0433\u043e \u0434\u0438\u0441\u043a\u0430 label.round.robin=Round-robin +label.routing=\u041c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0446\u0438\u044f label.rules=\u041f\u0440\u0430\u0432\u0438\u043b\u0430 label.running.vms=\u0417\u0430\u043f\u0443\u0449\u0435\u043d\u043d\u044b\u0435 \u0412\u041c +label.s3.access_key=\u041a\u043b\u044e\u0447 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 +label.s3.bucket=Bucket +label.s3.connection_timeout=\u041f\u0440\u0435\u0432\u044b\u0448\u0435\u043d\u0438\u0435 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f +label.s3.endpoint=\u041a\u043e\u043d\u0435\u0447\u043d\u0430\u044f \u0442\u043e\u0447\u043a\u0430 +label.s3.nfs.path=S3 NFS \u043f\u0443\u0442\u044c +label.s3.nfs.server=S3 NFS \u0421\u0435\u0440\u0432\u0435\u0440 label.s3.secret_key=\u0421\u0435\u043a\u0440\u0435\u0442\u043d\u044b\u0439 \u043a\u043b\u044e\u0447 +label.s3.socket_timeout=\u041f\u0440\u0435\u0432\u044b\u0448\u0435\u043d\u0438\u0435 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f \u0441\u043e\u043a\u0435\u0442\u0430 +label.s3.use_https=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 HTTPS label.saturday=\u0421\u0443\u0431\u0431\u043e\u0442\u0430 label.save.and.continue=\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0438 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u044c label.save=\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c @@ -833,6 +975,7 @@ label.saving.processing=\u0421\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u label.scope=\u041e\u0445\u0432\u0430\u0442 label.search=\u041f\u043e\u0438\u0441\u043a label.secondary.storage.count=\u0412\u0442\u043e\u0440\u0438\u0447\u043d\u044b\u0439 \u0430\u0440\u0445\u0438\u0432 \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f +label.secondary.storage.limits=\u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 (\u0432 \u0413\u0438\u0411) label.secondary.storage=\u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 label.secondary.storage.vm=\u0412\u0442\u043e\u0440\u0438\u0447\u043d\u044b\u0439 \u0444\u0430\u0439\u043b\u043e\u0432\u044b\u0439 \u0441\u0435\u0440\u0432\u0435\u0440 label.secondary.used=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 @@ -848,6 +991,7 @@ label.select.instance=\u0412\u044b\u0431\u0438\u0440\u0438\u0442\u0435 \u0441\u0 label.select.iso.or.template=\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 ISO \u0438\u043b\u0438 \u0448\u0430\u0431\u043b\u043e\u043d label.select.offering=\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u0435 label.select.project=\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u043f\u0440\u043e\u0435\u043a\u0442 +label.select.tier=\u0412\u044b\u0431\u0440\u0430\u0442\u044c Tier label.select=\u0412\u044b\u0431\u0440\u0430\u0442\u044c label.select-view=\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0432\u0438\u0434 label.select.vm.for.static.nat=\u0412\u044b\u0431\u043e\u0440 VM \u0434\u043b\u044f NAT @@ -855,6 +999,7 @@ label.sent=\u041e\u0442\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043e label.server=\u0421\u0435\u0440\u0432\u0435\u0440 label.service.capabilities=\u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0441\u043b\u0443\u0436\u0431\u044b label.service.offering=\u0421\u043b\u0443\u0436\u0435\u0431\u043d\u044b\u0439 \u0440\u0435\u0441\u0443\u0440\u0441 +label.service.state=\u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0441\u043b\u0443\u0436\u0431 label.session.expired=\u0412\u0440\u0435\u043c\u044f \u0441\u0435\u0441\u0441\u0438\u0438 \u0432\u044b\u0448\u043b\u043e label.setup.network=\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0441\u0435\u0442\u0438 label.setup=\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 @@ -925,9 +1070,11 @@ label.submitted.by=[\u041e\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430 label.submit=\u041e\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u0442\u044c label.succeeded=\u0423\u0441\u043f\u0435\u0448\u043d\u043e label.sunday=\u0412\u043e\u0441\u043a\u0440\u0435\u0441\u0435\u043d\u044c\u0435 +label.super.cidr.for.guest.networks=Super CIDR \u0433\u043e\u0441\u0442\u0435\u0432\u043e\u0439 \u0441\u0435\u0442\u0438 label.supported.services=\u041f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043c\u044b\u0435 \u0441\u043b\u0443\u0436\u0431\u044b label.supported.source.NAT.type=\u041f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043c\u044b\u0435 \u0442\u0438\u043f\u044b NAT-\u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430 label.suspend.project=\u041f\u0440\u0438\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043f\u0440\u043e\u0435\u043a\u0442 +label.switch.type=\u0422\u0438\u043f \u0441\u0432\u0438\u0447\u0430 label.system.capacity=\u041c\u043e\u0449\u043d\u043e\u0441\u0442\u044c \u0441\u0438\u0441\u0442\u0435\u043c\u044b label.system.offering=\u0421\u0438\u0441\u0442\u0435\u043c\u0430 \u0440\u0430\u0437\u043c\u0435\u0449\u0435\u043d\u0438\u044f label.system.service.offering=\u0421\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0439 \u0440\u0435\u0441\u0443\u0440\u0441 @@ -946,6 +1093,7 @@ label.theme.default=\u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0430 label.theme.grey=\u0421\u0435\u0440\u0430\u044f \u0442\u0435\u043c\u0430 label.theme.lightblue=\u0413\u043e\u043b\u0443\u0431\u0430\u044f \u0442\u0435\u043c\u0430 label.thursday=\u0427\u0435\u0442\u0432\u0435\u0440\u0433 +label.tier.details=\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438 Tier label.timeout.in.second = \u0412\u0440\u0435\u043c\u044f \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u0435 (\u0441\u0435\u043a.) label.timeout=\u0412\u0440\u0435\u043c\u044f \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f label.time=\u0412\u0440\u0435\u043c\u044f @@ -981,6 +1129,7 @@ label.used=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0 label.username=\u0418\u043c\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f label.users=\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438 label.user=\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c +label.use.vm.ip=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 IP \u0412\u041c\: label.value=\u0417\u043d\u0430\u0447\u0435\u043d\u0438\u0435 label.vcdcname=\u0418\u043c\u044f vCenter DC label.vcenter.cluster=\u041a\u043b\u0430\u0441\u0442\u0435\u0440 vCenter @@ -995,6 +1144,7 @@ label.view.all=\u041f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044 label.view.console=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u043a\u043e\u043d\u0441\u043e\u043b\u044c label.viewing=\u041f\u0440\u043e\u0441\u043c\u043e\u0442\u0440 label.view.more=\u041f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u0435 +label.view.secondary.ips=\u041f\u0440\u043e\u0441\u043c\u043e\u0442\u0440 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 IP-\u0430\u0434\u0440\u0435\u0441\u043e\u0432 label.view=\u0412\u0438\u0434 label.virtual.appliances=\u0412\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0435 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 label.virtual.appliance=\u0412\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0435 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e @@ -1005,9 +1155,7 @@ label.virtual.router=\u0412\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044 label.vlan.id=ID VLAN label.vlan.range=\u0414\u0438\u0430\u043f\u0430\u0437\u043e\u043d VLAN label.vlan=VLAN -label.vxlan.id=VXLAN ID -label.vxlan.range=\u0414\u0438\u0430\u043f\u0430\u0437\u043e\u043d Range -label.vxlan=VXLAN +label.vlan.vni.range=\u0414\u0438\u0430\u043f\u0430\u0437\u043e\u043d VLAN label.vm.add=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043c\u0430\u0448\u0438\u043d\u044b label.vm.destroy=\u0423\u043d\u0438\u0447\u0442\u043e\u0436\u0438\u0442\u044c label.vm.display.name=\u041e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u043c\u043e\u0435 \u0438\u043c\u044f \u0412\u041c @@ -1015,22 +1163,39 @@ label.VMFS.datastore=\u0425\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 VMFS label.vmfs=VMFS label.vm.name=\u0418\u043c\u044f VM label.vm.reboot=\u041f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c +label.VMs.in.tier=Tier \u0412\u041c +label.vmsnapshot.current=\u0422\u0435\u043a\u0443\u0449\u0435\u0439 +label.vmsnapshot.memory=\u0421\u043d\u0438\u043c\u043e\u043a \u043f\u0430\u043c\u044f\u0442\u0438 +label.vmsnapshot.parentname=\u0420\u043e\u0434\u0438\u0442\u0435\u043b\u044c label.vmsnapshot.type=\u0422\u0438\u043f +label.vmsnapshot=\u0421\u043d\u0438\u043c\u043e\u043a \u0412\u041c label.vm.start=\u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c label.vm.state=\u0421\u0442\u0430\u0442\u0443\u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 label.vm.stop=\u041e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c label.vms=\u0412\u041c label.vmware.traffic.label=\u041c\u0435\u0442\u043a\u0430 \u0442\u0440\u0430\u0444\u0438\u043a\u0430 VMware +label.vnet.id=ID VLAN +label.vnet=VLAN label.volgroup=\u0413\u0440\u0443\u043f\u043f\u0430 \u0442\u043e\u043c\u0430 label.volume.limits=\u041f\u0440\u0435\u0434\u0435\u043b\u044b \u0442\u043e\u043c\u043e\u0432 label.volume.name=\u0418\u043c\u044f \u0442\u043e\u043c\u0430 label.volumes=\u0417\u043d\u0430\u0447\u0435\u043d\u0438\u044f label.volume=\u0422\u043e\u043c +label.vpc.id=VPC ID +label.VPC.router.details=\u0414\u0435\u0442\u0430\u043b\u0438 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0442\u043e\u0440\u0430 VPC +label.vpc=VPC +label.VPN.connection=VPN \u043f\u043e\u0434\u043b\u044e\u0447\u0435\u043d\u0438\u0435 +label.vpn.customer.gateway=VPN \u0448\u043b\u044e\u0437 \u043a\u043b\u0438\u0435\u043d\u0442\u0430 +label.VPN.customer.gateway=VPN \u0448\u043b\u044e\u0437 \u043a\u043b\u0438\u0435\u043d\u0442\u0430 +label.VPN.gateway=VPN \u0448\u043b\u044e\u0437 label.vpn=VPN label.vsmctrlvlanid=\u0423\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 VLAN ID label.vsmpktvlanid=\u041f\u0430\u043a\u0435\u0442 VLAN ID label.vsmstoragevlanid=\u0425\u0440\u0430\u043d\u0435\u043d\u0438\u0435 VLAN ID label.vsphere.managed=\u041e\u0431\u0441\u043b\u0443\u0436\u0438\u0432\u0430\u043d\u0438\u0435 vSphere +label.vxlan.id=VXLAN ID +label.vxlan.range=\u0414\u0438\u0430\u043f\u0430\u0437\u043e\u043d Range +label.vxlan=VXLAN label.waiting=\u041e\u0436\u0438\u0434\u0430\u043d\u0438\u0435 label.warn=\u0412\u043d\u0438\u043c\u0430\u043d\u0438\u0435 label.wednesday=\u0421\u0440\u0435\u0434\u0430 @@ -1051,8 +1216,14 @@ label.zones=\u0417\u043e\u043d\u044b label.zone.type=\u0422\u0438\u043f \u0437\u043e\u043d\u044b label.zone=\u0417\u043e\u043d\u0430 label.zone.wide=\u0412\u0441\u0435\u0439 \u0437\u043e\u043d\u044b +label.zoneWizard.trafficType.guest=\u0413\u043e\u0441\u0442\u0435\u0432\u043e\u0439\: \u0422\u0440\u0430\u0444\u0438\u043a \u043c\u0435\u0436\u0434\u0443 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u043c\u0438 \u043c\u0430\u0448\u0438\u043d\u0430\u043c\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 +label.zoneWizard.trafficType.management=\u0423\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435\: \u0422\u0440\u0430\u0444\u0438\u043a \u043c\u0435\u0436\u0434\u0443 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u043c \u0440\u0435\u0441\u0443\u0440\u0441\u0430\u043c CloudStack, \u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435 \u043b\u044e\u0431\u044b\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0443\u044e\u0442 \u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u043e\u043c \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f, \u0442\u0430\u043a\u0438\u0445 \u043a\u0430\u043a \u0443\u0437\u043b\u044b \u0438 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0435 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0435 \u043c\u0430\u0448\u0438\u043d\u044b. +label.zoneWizard.trafficType.public=\u041f\u0443\u0431\u043b\u0438\u0447\u043d\u044b\u0439\: \u0442\u0440\u0430\u0444\u0438\u043a \u043c\u0435\u0436\u0434\u0443 \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442\u043e\u043c \u0438 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u043c\u0438 \u043c\u0430\u0448\u0438\u043d\u0430\u043c\u0438 \u0432 \u043e\u0431\u043b\u0430\u043a\u0435 +label.zoneWizard.trafficType.storage=\u0425\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435\: \u0422\u0440\u0430\u0444\u0438\u043a \u043c\u0435\u0436\u0434\u0443 \u043f\u0435\u0440\u0432\u0438\u0447\u043d\u044b\u043c\u0438 \u0438 \u0432\u0442\u043e\u0440\u0438\u0447\u043d\u044b\u043c\u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u0430\u043c\u0438 \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f, \u0442\u0430\u043a\u0438\u0445 \u043a\u0430\u043a \u0448\u0430\u0431\u043b\u043e\u043d\u044b \u0438 \u0441\u043d\u0438\u043c\u043a\u0438 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0445 \u043c\u0430\u0448\u0438\u043d. managed.state=\u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043e\u0431\u0441\u043b\u0443\u0436\u0438\u0432\u0430\u043d\u0438\u044f +message.acquire.ip.nic=\u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435, \u0447\u0442\u043e \u0432\u044b \u0445\u043e\u0442\u0435\u043b\u0438 \u0431\u044b \u0437\u0430\u043f\u0440\u043e\u0441\u0438\u0442\u044c \u043d\u043e\u0432\u044b\u0439 \u0432\u0442\u043e\u0440\u0438\u0447\u043d\u044b\u0439 IP \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e NIC.
\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435\: \u0412\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0432\u0440\u0443\u0447\u043d\u0443\u044e \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u043d\u0435\u0434\u0430\u0432\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 IP \u0432\u043d\u0443\u0442\u0440\u0438 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0439 \u043c\u0430\u0448\u0438\u043d\u044b. message.acquire.new.ip=\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435, \u0447\u0442\u043e \u0432\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c "\u0431\u0435\u043b\u044b\u0439" IP \u0434\u043b\u044f \u044d\u0442\u043e\u0439 \u0441\u0435\u0442\u0438. +message.acquire.new.ip.vpc=\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435, \u0447\u0442\u043e \u0432\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c "\u0431\u0435\u043b\u044b\u0439" IP \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e VPC. message.acquire.public.ip=\u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0432\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0437\u043e\u043d\u0443, \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u043f\u0440\u0438\u043e\u0431\u0440\u0435\u0441\u0442\u0438 \u043d\u043e\u0432\u044b\u0439 IP. message.action.cancel.maintenance.mode=\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435, \u0447\u0442\u043e \u0432\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u043e\u0442\u043c\u0435\u043d\u0438\u0442\u044c \u0440\u0435\u0436\u0438\u043c \u043e\u0431\u0441\u043b\u0443\u0436\u0438\u0432\u0430\u043d\u0438\u044f. message.action.cancel.maintenance=\u0423\u0437\u0435\u043b \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0432\u044b\u0448\u0435\u043b \u0438\u0437 \u0440\u0435\u0436\u0438\u043c\u0430 \u043e\u0431\u0441\u043b\u0443\u0436\u0438\u0432\u0430\u043d\u0438\u044f. \u042d\u0442\u043b\u044c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043c\u043e\u0436\u0435\u0442 \u0434\u043b\u0438\u0442\u044c\u0441\u044f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043c\u0438\u043d\u0443\u0442. @@ -1068,6 +1239,7 @@ message.action.delete.ISO.for.all.zones=\u042d\u0442\u043e ISO, \u0438\u0441\u04 message.action.delete.ISO=\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435, \u0447\u0442\u043e \u0432\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u044d\u0442\u043e\u0442 ISO. message.action.delete.network=\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435, \u0447\u0442\u043e \u0432\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u044d\u0442\u0443 \u0441\u0435\u0442\u044c. message.action.delete.nexusVswitch=\u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435, \u0447\u0442\u043e \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u044d\u0442\u043e nexusVswitch. +message.action.delete.nic=\u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435, \u0447\u0442\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u044d\u0442\u043e\u0442 NIC, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0442\u0430\u043a\u0436\u0435 \u0443\u0434\u0430\u043b\u0438\u0442 \u0432\u0441\u0435 \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0435 \u0441\u0435\u0442\u0438 \u0438\u0437 \u0412\u041c. message.action.delete.physical.network=\u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435, \u0447\u0442\u043e \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u044d\u0442\u043e\u0442 \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043a\u0443\u044e \u0441\u0435\u0442\u044c message.action.delete.pod=\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435, \u0447\u0442\u043e \u0432\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u044d\u0442\u043e\u0442 \u0441\u0442\u0435\u043d\u0434. message.action.delete.primary.storage=\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435, \u0447\u0442\u043e \u0432\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u044d\u0442\u043e \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435. @@ -1109,6 +1281,7 @@ message.action.remove.host=\u0423\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u04 message.action.reset.password.off=\u041d\u0430 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u043c\u0430\u0448\u0438\u043d\u0430 \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0434\u0430\u043d\u043d\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e message.action.reset.password.warning=\u041c\u0430\u0448\u0438\u043d\u0430 \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u044b\u0442\u044c \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0430 \u0434\u043b\u044f \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043f\u0430\u0440\u043e\u043b\u044f message.action.restore.instance=\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435, \u0447\u0442\u043e \u0432\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u0432\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u044d\u0442\u0443 \u043c\u0430\u0448\u0438\u043d\u0443. +message.action.revert.snapshot=\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435, \u0447\u0442\u043e \u0432\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0434\u0438\u0441\u043a \u043a \u044d\u0442\u043e\u043c\u0443 \u0442\u043e\u043c \u0441\u043d\u0438\u043c\u043a\u0443 message.action.start.instance=\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435, \u0447\u0442\u043e \u0432\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u044d\u0442\u0443 \u043c\u0430\u0448\u0438\u043d\u0443. message.action.start.router=\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435, \u0447\u0442\u043e \u0432\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u044d\u0442\u043e\u0442 \u0440\u043e\u0443\u0442\u0435\u0440. message.action.start.systemvm=\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435, \u0447\u0442\u043e \u0432\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u044d\u0442\u0443 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u0443\u044e \u0412\u041c. @@ -1117,6 +1290,8 @@ message.action.stop.router=\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u043 message.action.stop.systemvm=\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435, \u0447\u0442\u043e \u0432\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u044d\u0442\u0443 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u0443\u044e \u0412\u041c. message.action.take.snapshot=\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435, \u0447\u0442\u043e \u0432\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u043d\u0438\u043c\u043e\u043a \u044d\u0442\u043e\u0433\u043e \u0442\u043e\u043c\u0430. message.action.unmanage.cluster=\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435, \u0447\u0442\u043e \u0432\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u043f\u0435\u0440\u0435\u0432\u0435\u0441\u0442\u0438 \u043a\u043b\u0430\u0441\u0442\u0435\u0440 \u0432 \u043e\u0431\u044b\u0447\u043d\u044b\u0439 \u0440\u0435\u0436\u0438\u043c. +message.action.vmsnapshot.delete=\u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435, \u0447\u0442\u043e \u0412\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u044d\u0442\u043e\u0442 \u0441\u043d\u0438\u043c\u043e\u043a \u0412\u041c. +message.action.vmsnapshot.revert=\u0412\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0441\u043d\u0438\u043c\u043e\u043a \u0412\u041c message.activate.project=\u0412\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u044d\u0442\u043e\u0442 \u043f\u0440\u043e\u0435\u043a\u0442? message.add.cluster=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0433\u0438\u043f\u0435\u0440\u0432\u0438\u0437\u043e\u0440 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u043e\u043c \u0434\u043b\u044f \u0437\u043e\u043d\u044b , \u043c\u043e\u0434\u0443\u043b\u044c message.add.cluster.zone=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0433\u0438\u043f\u0435\u0440\u0432\u0438\u0437\u043e\u0440\u0430 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u043e\u043c \u0434\u043b\u044f \u0437\u043e\u043d\u044b @@ -1135,18 +1310,22 @@ message.additional.networks.desc=\u041f\u043e\u0436\u0430\u043b\u0443\u0439\u044 message.add.load.balancer=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0431\u0430\u043b\u0430\u043d\u0441\u0438\u0440\u043e\u0432\u043a\u0443 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0432 \u0437\u043e\u043d\u0443 message.add.load.balancer.under.ip=\u041f\u0440\u0430\u0432\u0438\u043b\u043e \u0431\u0430\u043b\u0430\u043d\u0441\u0438\u0440\u043e\u0432\u043a\u0438 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0431\u044b\u043b \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d \u0432 IP\: message.add.network=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043d\u043e\u0432\u0443\u044e \u0441\u0435\u0442\u044c \u0434\u043b\u044f \u0437\u043e\u043d\u044b\: +message.add.new.gateway.to.vpc=\u0423\u043a\u0430\u0436\u0438\u0442\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u0434\u043b\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043d\u043e\u0432\u043e\u0433\u043e \u0448\u043b\u044e\u0437\u0430 \u0432 VPC message.add.pod.during.zone.creation=\u041a\u0430\u0436\u0434\u0430\u044f \u0437\u043e\u043d\u0430 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043e\u0434\u0438\u043d \u0438\u043b\u0438 \u0431\u043e\u043b\u0435\u0435 \u0441\u0442\u0435\u043d\u0434\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b \u0441\u0435\u0439\u0447\u0430\u0441 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u0435 \u043f\u0435\u0440\u0432\u044b\u043c. \u0421\u0442\u0435\u043d\u0434 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0443\u0437\u043b\u044b \u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u044b \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0433\u043e \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u044b \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u043c \u0448\u0430\u0433\u0435. \u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d \u0440\u0435\u0437\u0435\u0440\u0432\u043d\u044b\u0445 \u0430\u0434\u0440\u0435\u0441\u043e\u0432 IP \u0434\u043b\u044f \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u0439 \u0441\u0435\u0442\u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f. \u0414\u0438\u0430\u043f\u0430\u0437\u043e\u043d \u0440\u0435\u0437\u0435\u0440\u0432\u043d\u044b\u0445 IP \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u043c \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u0437\u043e\u043d\u044b \u043e\u0431\u043b\u0430\u043a\u0430. message.add.pod=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043d\u043e\u0432\u044b\u0439 \u0441\u0442\u0435\u043d\u0434 \u0434\u043b\u044f \u0437\u043e\u043d\u044b message.add.primary.storage=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \u0434\u043b\u044f \u0437\u043e\u043d\u044b , \u0441\u0442\u0435\u043d\u0434\u0430 message.add.primary=\u0423\u043a\u0430\u0436\u0438\u0442\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0434\u043b\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043d\u043e\u0432\u043e\u0433\u043e \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0433\u043e \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 +message.add.region=\u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430 \u0443\u043a\u0430\u0436\u0438\u0442\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u0434\u043b\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043d\u043e\u0432\u043e\u0433\u043e \u0440\u0435\u0433\u0438\u043e\u043d\u0430. message.add.secondary.storage=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \u0432 \u0437\u043e\u043d\u0443 message.add.service.offering=\u0423\u043a\u0430\u0436\u0438\u0442\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0434\u043b\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043d\u043e\u0432\u043e\u0433\u043e \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u043e\u0433\u043e \u0440\u0435\u0441\u0443\u0440\u0441\u0430. message.add.system.service.offering=\u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u0434\u043b\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043d\u043e\u0432\u043e\u0433\u043e \u0440\u0435\u0441\u0443\u0440\u0441\u0430 \u0434\u043b\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0445 \u0441\u043b\u0443\u0436\u0431. message.add.template=\u0423\u043a\u0430\u0436\u0438\u0442\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0434\u043b\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043d\u043e\u0432\u043e\u0433\u043e \u0448\u0430\u0431\u043b\u043e\u043d\u0430 message.add.volume=\u0423\u043a\u0430\u0436\u0438\u0442\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0434\u043b\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043d\u043e\u0432\u043e\u0433\u043e \u0442\u043e\u043c\u0430 +message.add.VPN.gateway=\u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435 \u0436\u0435\u043b\u0430\u043d\u0438\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c VPN \u0448\u043b\u044e\u0437 message.advanced.mode.desc=\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u044d\u0442\u0443 \u043c\u043e\u0434\u0435\u043b\u044c \u0441\u0435\u0442\u0438, \u0435\u0441\u043b\u0438 \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 VLAN. \u042d\u0442\u0430 \u0441\u0435\u0442\u0435\u0432\u0430\u044f \u043c\u043e\u0434\u0435\u043b\u044c \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u0435\u0442 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0443\u044e \u0433\u0438\u0431\u043a\u043e\u0441\u0442\u044c \u0432 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0438 \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u0430\u043c \u0434\u043b\u044f \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0445 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0441\u0435\u0442\u0438, \u0442\u0430\u043a\u0438\u0435 \u043a\u0430\u043a \u043c\u0435\u0436\u0441\u0435\u0442\u0435\u0432\u043e\u0439 \u044d\u043a\u0440\u0430\u043d, VPN, \u0438\u043b\u0438 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 \u0431\u0430\u043b\u0430\u043d\u0441\u0438\u0440\u043e\u0432\u043a\u0438 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0438, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u0440\u044f\u043c\u043e\u0435 \u043f\u0440\u043e\u0442\u0438\u0432 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0445 \u0441\u0435\u0442\u0435\u0439. message.advanced.security.group=\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u044d\u0442\u043e\u0442 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440, \u0435\u0441\u043b\u0438 \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0433\u0440\u0443\u043f\u043f\u044b \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u0438, \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0442\u044c \u0438\u0437\u043e\u043b\u044f\u0446\u0438\u044e \u0441\u0435\u0440\u0432\u0435\u0440\u0430. message.advanced.virtual=\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u044d\u0442\u043e\u0442 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440, \u0435\u0441\u043b\u0438 \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432\u0441\u0435\u0439 \u0437\u043e\u043d\u044b \u0441\u0435\u0442\u0438 VLAN, \u0447\u0442\u043e\u0431\u044b \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0442\u044c \u0438\u0437\u043e\u043b\u044f\u0446\u0438\u044e \u0441\u0435\u0440\u0432\u0435\u0440\u0430. +message.after.enable.s3=S3-\u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u043e\u0435 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043d\u043e. \u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435\: \u0415\u0441\u043b\u0438 \u0432\u044b \u043f\u043e\u043a\u0438\u043d\u0435\u0442\u0435 \u044d\u0442\u0443 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443, \u0432\u0430\u043c \u043d\u0435 \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0442\u044c S3 \u0441\u043d\u043e\u0432\u0430. message.after.enable.swift=Swift \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043d. \u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435\: \u0415\u0441\u043b\u0438 \u0432\u044b \u043f\u043e\u043a\u0438\u043d\u0435\u0442\u0435 \u044d\u0442\u0443 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443, \u0432\u0430\u043c \u043d\u0435 \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0442\u044c Swift \u0441\u043d\u043e\u0432\u0430 message.alert.state.detected=\u041e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d \u0441\u0438\u0433\u043d\u0430\u043b \u0442\u0440\u0435\u0432\u043e\u0433\u0438 message.allow.vpn.access=\u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0432\u0432\u0435\u0434\u0438\u0442\u0435 \u0438\u043c\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0438 \u043f\u0430\u0440\u043e\u043b\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0434\u043b\u044f VPN-\u0434\u043e\u0441\u0442\u0443\u043f\u0430. @@ -1164,6 +1343,7 @@ message.configuring.storage.traffic=\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u message.confirm.action.force.reconnect=\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435, \u0447\u0442\u043e \u0432\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u043f\u0435\u0440\u0435\u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c\u0441\u044f \u043a \u0443\u0437\u043b\u0443 message.confirm.delete.F5=\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435, \u0447\u0442\u043e \u0432\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u0443\u0434\u0430\u043b\u0438\u0442\u044c F5 message.confirm.delete.NetScaler=\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435, \u0447\u0442\u043e \u0432\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u0443\u0434\u0430\u043b\u0438\u0442\u044c NetScaler +message.confirm.delete.PA=\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435, \u0447\u0442\u043e \u0432\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u0443\u0434\u0430\u043b\u0438\u0442\u044c Palo Alto message.confirm.delete.SRX=\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435, \u0447\u0442\u043e \u0432\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u0443\u0434\u0430\u043b\u0438\u0442\u044c SRX message.confirm.destroy.router=\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435, \u0447\u0442\u043e \u0432\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u0440\u043e\u0443\u0442\u0435\u0440 message.confirm.disable.provider=\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435, \u0447\u0442\u043e \u0432\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u0432\u044b\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043f\u043e\u0441\u0442\u0430\u0432\u0449\u0438\u043a\u0430 @@ -1184,9 +1364,15 @@ message.creating.primary.storage=\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u043 message.creating.secondary.storage=\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 message.creating.zone=\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0437\u043e\u043d\u044b message.decline.invitation=\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435, \u0447\u0442\u043e \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u043e\u0442\u043c\u0435\u043d\u0438\u0442\u044c \u043f\u0440\u0438\u0433\u043b\u0430\u0448\u0435\u043d\u0438\u0435 \u043d\u0430 \u043f\u0440\u043e\u0435\u043a\u0442. +message.dedicate.zone=\u0412\u044b\u0434\u0435\u043b\u0435\u043d\u043d\u0430\u044f \u0437\u043e\u043d\u0430 message.delete.account=\u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435, \u0447\u0442\u043e \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u044d\u0442\u043e\u0442 \u0430\u043a\u043a\u0430\u0443\u043d\u0442. +message.delete.affinity.group=\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435, \u0447\u0442\u043e \u0432\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u044d\u0442\u0443 affinity group +message.delete.gateway=\u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435, \u0447\u0442\u043e \u0412\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u044d\u0442\u043e\u0442 \u0448\u043b\u044e\u0437. message.delete.project=\u0412\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u044d\u0442\u043e\u0442 \u043f\u0440\u043e\u0435\u043a\u0442? message.delete.user=\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435, \u0447\u0442\u043e \u0432\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f. +message.delete.VPN.connection=\u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435, \u0447\u0442\u043e \u0412\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u044d\u0442\u043e VPN \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435. +message.delete.VPN.customer.gateway=\u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435, \u0447\u0442\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u044d\u0442\u043e\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0439 \u0448\u043b\u044e\u0437 VPN. +message.delete.VPN.gateway=\u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435, \u0447\u0442\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u044d\u0442\u043e\u0442 \u0448\u043b\u044e\u0437 VPN. message.desc.advanced.zone=\u0414\u043b\u044f \u0431\u043e\u043b\u0435\u0435 \u0441\u043b\u043e\u0436\u043d\u044b\u0445 \u0441\u0435\u0442\u0435\u0432\u044b\u0445 \u0442\u043e\u043f\u043e\u043b\u043e\u0433\u0438\u0439. \u042d\u0442\u0430 \u0441\u0435\u0442\u0435\u0432\u0430\u044f \u043c\u043e\u0434\u0435\u043b\u044c \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u0435\u0442 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0443\u044e \u0433\u0438\u0431\u043a\u043e\u0441\u0442\u044c \u0432 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0438 \u0433\u043e\u0441\u0442\u0435\u0432\u043e\u0439 \u0441\u0435\u0442\u0438 \u0438 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0443\u0441\u043b\u0443\u0433, \u0442\u0430\u043a\u0438\u0445 \u043a\u0430\u043a \u043c\u0435\u0436\u0441\u0435\u0442\u0435\u0432\u043e\u0439 \u044d\u043a\u0440\u0430\u043d, VPN, \u0438\u043b\u0438 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 \u0431\u0430\u043b\u0430\u043d\u0441\u0438\u0440\u043e\u0432\u043a\u0438 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0438. message.desc.basic.zone=\u041f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0435\u0434\u0438\u0441\u0442\u0432\u0435\u043d\u043d\u0443\u044e \u0441\u0435\u0442\u044c, \u0433\u0434\u0435 \u043a\u0430\u0436\u0434\u0430\u044f \u0412\u041c \u0438\u043c\u0435\u0435\u0442 \u00ab\u0431\u0435\u043b\u044b\u0439\u00bb IP-\u0430\u0434\u0440\u0435\u0441 \u0441\u0435\u0442\u0438. \u0418\u0437\u043e\u043b\u044f\u0446\u0438\u0438 \u0433\u043e\u0441\u0442\u0435\u0439 \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0431\u0438\u0442\u044c\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0441\u0435\u0442\u0438 3-\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0433\u0440\u0443\u043f\u043f\u044b \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u0438 (\u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u044f IP-\u0432\u0434\u0440\u0435\u0441\u043e\u0432) message.desc.cluster=\u041a\u0430\u0436\u0434\u044b\u0439 \u0441\u0442\u0435\u043d\u0434 \u0434\u043e\u043b\u0436\u0435\u043d \u0438\u043c\u0435\u0442\u044c \u043e\u0434\u0438\u043d \u0438\u043b\u0438 \u0431\u043e\u043b\u0435\u0435 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u043e\u0432, \u043f\u0435\u0440\u0432\u044b\u0439 \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0432\u044b \u0441\u0435\u0439\u0447\u0430\u0441 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u0435. \u041a\u043b\u0430\u0441\u0442\u0435\u0440 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0433\u0440\u0443\u043f\u043f\u0443 \u0443\u0437\u043b\u043e\u0432. \u0423\u0437\u043b\u044b \u0432 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0435 \u0438\u043c\u0435\u044e\u0442 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u043e\u0435 \u043e\u0431\u043e\u0440\u0443\u0434\u043e\u0432\u0430\u043d\u0438\u0435, \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 \u043e\u0434\u0438\u043d \u0433\u0438\u043f\u0435\u0440\u0432\u0438\u0437\u043e\u0440, \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u0432 \u043e\u0434\u043d\u043e\u0439 \u0441\u0435\u0442\u0438 \u0438 \u0438\u043c\u0435\u044e\u0442 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u043e\u0434\u043d\u043e\u043c\u0443 \u0438 \u0442\u043e\u043c\u0443 \u0436\u0435 \u043e\u0442\u043a\u0440\u044b\u0442\u043e\u043c\u0443 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0443. \u041a\u0430\u0436\u0434\u044b\u0439 \u043a\u043b\u0430\u0441\u0442\u0435\u0440 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043e\u0434\u0438\u043d \u0438\u043b\u0438 \u0431\u043e\u043b\u0435\u0435 \u0443\u0437\u043b\u043e\u0432, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0438\u0435\u0442\u044c \u043e\u0434\u0438\u043d \u0438\u043b\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449. @@ -1269,6 +1455,7 @@ message.migrate.router.confirm=\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\ message.migrate.systemvm.confirm=\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435, \u0447\u0442\u043e \u0432\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u043f\u0435\u0440\u0435\u043d\u0435\u0441\u0442\u0438 \u0440\u043e\u0443\u0442\u0435\u0440 \u0432 \u0443\u0437\u0435\u043b message.migrate.volume=\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435, \u0447\u0442\u043e \u0432\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u043f\u0435\u0440\u0435\u043d\u0435\u0441\u0442\u0438 \u0442\u043e\u043c \u0432 \u0434\u0440\u0443\u0433\u043e\u0435 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435. message.new.user=\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u0434\u043b\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043d\u043e\u0432\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0432 \u0443\u0447\u0451\u0442\u043d\u0443\u044e \u0437\u0430\u043f\u0438\u0441\u044c. +message.no.affinity.groups=\u0412\u044b \u043d\u0435 \u0438\u043c\u0435\u0435\u0442\u0435 affinity groups. \u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430 \u043f\u0435\u0440\u0435\u0439\u0434\u0438\u0442\u0435 \u043a \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c\u0443 \u0448\u0430\u0433\u0443. message.no.network.support.configuration.not.true=\u041d\u0438 \u0432 \u043e\u0434\u043d\u043e\u0439 \u0437\u043e\u043d\u0435 \u043d\u0435\u0442 \u0433\u0440\u0443\u043f\u043f \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u0438. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0441\u0435\u0442\u0435\u0432\u044b\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b. \u041f\u0435\u0440\u0435\u0439\u0434\u0438\u0442\u0435 \u043a \u0448\u0430\u0433\u0443 5. message.no.network.support=\u0412\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0439 \u0433\u0438\u043f\u0435\u0440\u0432\u0438\u0437\u043e\u0440 (vSphere) \u043d\u0435 \u043e\u0431\u043b\u0430\u0434\u0430\u0435\u0442 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u043c\u0438 \u0441\u0435\u0442\u0435\u0432\u044b\u043c\u0438 \u0432\u043e\u0437\u043c\u043e\u0434\u043d\u043e\u0441\u0442\u044f\u043c\u0438. \u041f\u0435\u0440\u0435\u0439\u0434\u0438\u0442\u0435 \u043a \u0448\u0430\u0433\u0443 5. message.no.projects.adminOnly=\u0423 \u0432\u0430\u0441 \u043d\u0435\u0442 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432.
\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435\u0441\u044c \u043a \u0432\u0430\u0448\u0435\u043c\u0443 \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u0443 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043d\u043e\u0432\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430. @@ -1289,13 +1476,19 @@ message.please.wait.while.zone.is.being.created=\u041f\u043e\u0434\u043e\u0436\u message.project.invite.sent=\u041f\u0440\u0438\u0433\u043b\u0430\u0448\u0435\u043d\u0438\u0435 \u0431\u044b\u043b\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e; \u043e\u043d \u0431\u0443\u0434\u0435\u0442 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d \u0432 \u043f\u0440\u043e\u0435\u043a\u0442 \u043f\u043e\u0441\u043b\u0435 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u044f \u043f\u0440\u0438\u0433\u043b\u0430\u0448\u0435\u043d\u0438\u044f. message.public.traffic.in.advanced.zone=\u041f\u0443\u0431\u043b\u0438\u0447\u043d\u044b\u0439 \u0442\u0440\u0430\u0444\u0438\u043a \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043f\u0440\u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0412\u041c \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u0418\u043d\u0442\u0435\u0440\u043d\u0435\u0442\u0443. \u041f\u0443\u0431\u043b\u0438\u0447\u043d\u043e \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 IP \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u044b. \u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043c\u043e\u0436\u0435\u0442 \u0438\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c CloudStack UI \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f IP \u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f NAT, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0439 \u0434\u043b\u044f \u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043c\u0435\u0436\u0434\u0443 \u0433\u043e\u0441\u0442\u0435\u0432\u043e\u0439 \u0438 \u043f\u0443\u0431\u043b\u0438\u0447\u043d\u043e\u0439 \u0441\u0435\u0442\u044c\u044e.

\u0423\u043a\u0430\u0436\u0438\u0442\u0435 \u043a\u0430\u043a \u043c\u0438\u043d\u0438\u043c\u0443\u043c \u043e\u0434\u0438\u043d \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d \u0430\u0434\u0440\u0435\u0441\u043e\u0432 \u0434\u043b\u044f \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442-\u0442\u0440\u0430\u0444\u0438\u043a\u0430. message.public.traffic.in.basic.zone=\u041f\u0443\u0431\u043b\u0438\u0447\u043d\u044b\u0439 \u0442\u0440\u0430\u0444\u0438\u043a \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043f\u0440\u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0412\u041c \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u0418\u043d\u0442\u0435\u0440\u043d\u0435\u0442\u0443 \u0438\u043b\u0438 \u043f\u0440\u0438 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u0430\u043c \u0441\u043b\u0443\u0436\u0431 \u0447\u0435\u0440\u0435\u0437 \u0418\u043d\u0442\u0435\u0440\u043d\u0435\u0442. \u041f\u0443\u0431\u043b\u0438\u0447\u043d\u043e \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 IP \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u044b. \u041f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u0412\u041c, \u0430\u0434\u0440\u0435\u0441 \u0438\u0437 \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u0430 \u043f\u0443\u0431\u043b\u0438\u0447\u043d\u044b\u0445 Ip \u043f\u0440\u0438\u0432\u044f\u0436\u0435\u0442\u0441\u044f \u043a \u043c\u0430\u0448\u0438\u043d\u0435 \u0432 \u0434\u043e\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0433\u043e\u0441\u0442\u0435\u0432\u043e\u0433\u043e \u0430\u0434\u0440\u0435\u0441\u0430 IP. \u0421\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 1-1 NAT \u0434\u043e\u043b\u0436\u0435\u043d \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c\u0441\u044f \u043d\u0430 \u0440\u0430\u0431\u043e\u0442\u0443 \u043c\u0435\u0436\u0434\u0443 \u043f\u0443\u0431\u043b\u0438\u0447\u043d\u043e\u0439 \u0438 \u0433\u043e\u0441\u0442\u0435\u0432\u043e\u0439 \u0441\u0435\u0442\u044c\u044e. \u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0442\u0430\u043a\u0436\u0435 \u0438\u043c\u0435\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c CloudStack UI \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0430\u0434\u0440\u0435\u0441\u043e\u0432 \u0434\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e NAT \u043c\u0435\u0436\u0434\u0443 \u043c\u0430\u0448\u0438\u043d\u0430\u043c\u0438 \u0438 \u043f\u0443\u0431\u043b\u0438\u0447\u043d\u043e\u0439 \u0441\u0435\u0442\u044c\u044e. +message.redirecting.region=\u041f\u0435\u0440\u0435\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0432 \u0440\u0435\u0433\u0438\u043e\u043d +message.remove.region=\u0412\u044b \u0443\u0432\u0435\u0440\u0435\u043d\u044b, \u0447\u0442\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u044d\u0442\u043e\u0442 \u0440\u0435\u0433\u0438\u043e\u043d \u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f? +message.remove.vpc=\u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435, \u0447\u0442\u043e \u0412\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u044d\u0442\u043e\u0442 VPC message.remove.vpn.access=\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435, \u0447\u0442\u043e \u0432\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043a VPN \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f. message.reset.password.warning.notPasswordEnabled=\u0428\u0430\u0431\u043b\u043e\u043d \u0434\u043b\u044f \u044d\u0442\u043e\u0439 \u043c\u0430\u0448\u0438\u043d\u044b \u0441\u043e\u0437\u0434\u0430\u043d \u0431\u0435\u0437 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u0430\u0440\u043e\u043b\u044f message.reset.password.warning.notStopped=\u0414\u043b\u044f \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043f\u0430\u0440\u043e\u043b\u044f \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043c\u0430\u0448\u0438\u043d\u0443 +message.reset.VPN.connection=\u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435, \u0447\u0442\u043e \u0412\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u044d\u0442\u043e VPN \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435. message.restart.mgmt.server=\u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u0435 \u0441\u0435\u0440\u0432\u0435\u0440(\u044b) \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u043f\u0440\u0438\u043d\u044f\u0442\u0438\u044f \u043d\u043e\u0432\u044b\u0445 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a. message.restart.mgmt.usage.server=\u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u0435 \u0441\u0435\u0440\u0432\u0435\u0440 \u0434\u043b\u044f \u0432\u0441\u0442\u0443\u043f\u043b\u0435\u043d\u0438\u044f \u043d\u043e\u0432\u044b\u0445 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u0432 \u0441\u0438\u043b\u0443. message.restart.network=\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435, \u0447\u0442\u043e \u0432\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0441\u0435\u0442\u044c. +message.restart.vpc=\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435, \u0447\u0442\u043e \u0432\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c VPC message.security.group.usage=(\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 Ctrl-\u043a\u043b\u0438\u043a, \u0447\u0442\u043e\u0431\u044b \u0432\u044b\u0431\u0440\u0430\u0442\u044c \u0432\u0441\u0435 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0433\u0440\u0443\u043f\u043f\u044b \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u0438) +message.select.affinity.groups=\u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0432\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u043b\u044e\u0431\u044b\u0435 affinity groups, \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043f\u0440\u0438\u043d\u0430\u0434\u043b\u0435\u0436\u0438\u0442 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u0430\u044f \u043c\u0430\u0448\u0438\u043d\u0430\: message.select.a.zone=\u0417\u043e\u043d\u0430 \u043e\u0431\u044b\u0447\u043d\u043e \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0435\u0434\u0438\u043d\u0438\u0447\u043d\u043e\u043c\u0443 \u0446\u0435\u043d\u0442\u0440\u0443 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0434\u0430\u043d\u043d\u044b\u0445. \u041d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0437\u043e\u043d\u044b\u043f\u043e\u043c\u043e\u0433\u0430\u044e\u0442 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0431\u043e\u043b\u0435\u0435 \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0435 \u043e\u0431\u043b\u0430\u043a\u0430, \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u044f \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043a\u0443\u044e \u0438\u0437\u043e\u043b\u044f\u0446\u0438\u044e \u0438 \u0438\u0437\u0431\u044b\u0442\u043e\u0447\u043d\u043e\u0441\u0442\u044c. message.select.instance=\u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0432\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0441\u0435\u0440\u0432\u0435\u0440. message.select.iso=\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u043e\u0431\u0440\u0430\u0437 ISO \u0434\u043b\u044f \u043d\u043e\u0432\u043e\u0439 \u0412\u041c @@ -1315,7 +1508,7 @@ message.step.3.continue=\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0434\ message.step.3.desc= message.step.4.continue=\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0445\u043e\u0442\u044f \u0431\u044b \u043e\u0434\u043d\u0443 \u0441\u0435\u0442\u044c \u0434\u043b\u044f \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u044f. message.step.4.desc=\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u043e\u0441\u043d\u043e\u0432\u043d\u0443\u044e \u0441\u0435\u0442\u044c, \u043a \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0430 \u043c\u0430\u0448\u0438\u043d\u0430. -message.storage.traffic=\u0422\u0440\u0430\u0444\u0438\u043a \u043c\u0435\u0436\u0434\u0443 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u043c\u0438 \u0440\u0435\u0441\u0443\u0440\u0441\u0430\u043c\u0438 CloudStack, \u0432\u043a\u043b\u044e\u0447\u0430\u044f \u0432\u0441\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0443\u044e\u0442 \u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u043e\u043c \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f, \u0442\u0430\u043a\u0438\u0435 \u043a\u0430\u043a \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0435 \u0445\u043e\u0441\u0442\u044b \u0438 CloudStack \u0441\u0438\u0441\u0442\u0435\u043c\u044b. \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u0442\u0435 \u0442\u0440\u0430\u0444\u0438\u043a \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0437\u0434\u0435\u0441\u044c. +message.storage.traffic=\u0422\u0440\u0430\u0444\u0438\u043a \u043c\u0435\u0436\u0434\u0443 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u043c\u0438 \u0440\u0435\u0441\u0443\u0440\u0441\u0430\u043c\u0438 CloudStack, \u0432\u043a\u043b\u044e\u0447\u0430\u044f \u0432\u0441\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0443\u044e\u0442 \u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u043e\u043c \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f, \u0442\u0430\u043a\u0438\u0435 \u043a\u0430\u043a \u0443\u0437\u043b\u044b \u0438 CloudStack \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0435 \u0412\u041c. \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u0442\u0435 \u0442\u0440\u0430\u0444\u0438\u043a \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0437\u0434\u0435\u0441\u044c. message.suspend.project=\u0412\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u043f\u0440\u0438\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043f\u0440\u043e\u0435\u043a\u0442? message.template.desc=\u041e\u0431\u0440\u0430\u0437 \u041e\u0421, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u043e\u0447\u043d\u043e\u0439 \u0432 \u0412\u041c message.tooltip.dns.1=\u0418\u043c\u044f \u0441\u0435\u0440\u0432\u0435\u0440\u0430 DNS \u0434\u043b\u044f \u0412\u041c \u044d\u0442\u043e\u0439 \u0437\u043e\u043d\u044b. \u041f\u0443\u0431\u043b\u0438\u0447\u043d\u044b\u0435 IP-\u0430\u0434\u0440\u0435\u0441\u0430 \u044d\u0442\u043e\u0439 \u0437\u043e\u043d\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0438\u043c\u0435\u0442\u044c \u043c\u0430\u0440\u0448\u0440\u0443\u0442 \u0434\u043e \u044d\u0442\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u0430. @@ -1331,6 +1524,7 @@ message.update.os.preference=\u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0 message.update.resource.count=\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435, \u0447\u0442\u043e \u0432\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u0441\u0447\u0435\u0442\u0447\u0438\u043a \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0430\u043a\u043a\u0430\u0443\u043d\u0442\u0430. message.update.ssl=\u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u043e\u0442\u043f\u0440\u0430\u0432\u044c\u0442\u0435 \u043d\u043e\u0432\u044b\u0439 \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u044b\u0439 X.509 SSL \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442 \u0434\u043b\u044f \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u043a\u043e\u043d\u0441\u043e\u043b\u0438 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0445 \u043f\u0440\u043e\u043a\u0441\u0438, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440\: message.validate.instance.name=\u0418\u043c\u044f \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0434\u043b\u0438\u043d\u0435\u0435 63 \u0441\u0438\u043c\u0432\u043e\u043b\u0430. \u0422\u043e\u043b\u044c\u043a\u043e ASCII, \u0431\u0443\u043a\u0432\u044b a~z, A~Z, \u0446\u044b\u0444\u0440\u044b 0~9, \u0434\u0435\u0444\u0438\u0441 \u043d\u0435 \u0434\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f. \u0414\u043e\u043b\u0436\u043d\u0430 \u043d\u0430\u0447\u0438\u043d\u0430\u0442\u044c\u0441\u044f \u0441 \u0431\u0443\u043a\u0432\u044b \u0438 \u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u0431\u0443\u043a\u0432\u043e\u0439 \u0438\u043b\u0438 \u0446\u0438\u0444\u0440\u043e\u0439. +message.validate.invalid.characters=\u041d\u0430\u0439\u0434\u0435\u043d\u044b \u043d\u0435\u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b\u0435 \u0441\u0438\u043c\u0432\u043e\u043b\u044b; \u043f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u043f\u043e\u043f\u0440\u0430\u0432\u044c\u0442\u0435. message.virtual.network.desc=\u0432\u044b\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0439 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0439 \u0441\u0435\u0442\u0438 \u0434\u043b\u044f \u0432\u0430\u0448\u0435\u0439 \u0443\u0447\u0435\u0442\u043d\u043e\u0439 \u0437\u0430\u043f\u0438\u0441\u0438. \u0428\u0438\u0440\u043e\u043a\u043e\u0432\u0435\u0449\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u0434\u043e\u043c\u0435\u043d \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432\u043d\u0443\u0442\u0440\u0438 VLAN \u0438 \u0432\u0435\u0441\u044c \u0432\u043d\u0435\u0448\u043d\u0438\u0439 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0441\u0435\u0442\u0438 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0443\u0442\u0435\u043c \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0442\u043e\u0440\u0430. message.vm.create.template.confirm=\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0448\u0430\u0431\u043b\u043e\u043d\u0430 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442 \u0412\u041c message.vm.review.launch=\u041f\u0440\u043e\u0432\u0435\u0440\u044c\u0442\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u0438 \u0443\u0434\u043e\u0441\u0442\u043e\u0432\u0435\u0440\u044c\u0442\u0435\u0441\u044c \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0432\u0430\u0448\u0430 \u043c\u0430\u0448\u0438\u043d\u0430 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043d\u0430 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e. diff --git a/client/WEB-INF/classes/resources/messages_zh_CN.properties b/client/WEB-INF/classes/resources/messages_zh_CN.properties index ea7bfd4c6e..1ec4e9537a 100644 --- a/client/WEB-INF/classes/resources/messages_zh_CN.properties +++ b/client/WEB-INF/classes/resources/messages_zh_CN.properties @@ -14,57 +14,12 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -label.port=\u7aef\u53e3 -label.remove.ldap=\u5220\u9664 LDAP -label.configure.ldap=\u914d\u7f6e LDAP -label.ldap.configuration=LDAP \u914d\u7f6e -label.ldap.port=LDAP \u7aef\u53e3 -label.create.nfs.secondary.staging.store=\u521b\u5efa NFS \u4e8c\u7ea7\u6682\u5b58\u5b58\u50a8 -label.volatile=\u53ef\u53d8 -label.planner.mode=\u89c4\u5212\u5668\u6a21\u5f0f -label.deployment.planner=\u90e8\u7f72\u89c4\u5212\u5668 -label.quiesce.vm=\u9759\u9ed8 VM -label.smb.username=SMB \u7528\u6237\u540d -label.smb.password=SMB \u5bc6\u7801 -label.smb.domain=SMB \u57df -label.hypervisors=\u865a\u62df\u673a\u7ba1\u7406\u7a0b\u5e8f -label.home=\u9996\u9875 -label.sockets=CPU \u63d2\u69fd -label.root.disk.size=\u6839\u78c1\u76d8\u5927\u5c0f -label.s3.nfs.server=S3 NFS \u670d\u52a1\u5668 -label.s3.nfs.path=S3 NFS \u8def\u5f84 -label.delete.events=\u5220\u9664\u4e8b\u4ef6 -label.delete.alerts=\u5220\u9664\u8b66\u62a5 -label.archive.alerts=\u5b58\u6863\u8b66\u62a5 -label.archive.events=\u5b58\u6863\u4e8b\u4ef6 -label.by.alert.type=\u6309\u8b66\u62a5\u7c7b\u578b -label.by.event.type=\u6309\u4e8b\u4ef6\u7c7b\u578b -label.by.date.start=\u6309\u65e5\u671f(\u5f00\u59cb\u65e5\u671f) -label.by.date.end=\u6309\u65e5\u671f(\u7ed3\u675f\u65e5\u671f) -label.switch.type=\u4ea4\u6362\u673a\u7c7b\u578b -label.service.state=\u670d\u52a1\u72b6\u6001 -label.egress.default.policy=\u51fa\u53e3\u9ed8\u8ba4\u7b56\u7565 -label.routing=\u6b63\u5728\u8def\u7531 -label.about=\u5173\u4e8e -label.app.name=CloudStack -label.about.app=\u5173\u4e8e CloudStack -label.custom.disk.iops=\u81ea\u5b9a\u4e49 IOPS -label.disk.iops.min=\u6700\u5c0f IOPS -label.disk.iops.max=\u6700\u5927 IOPS -label.disk.iops.total=\u603b IOPS -label.hypervisor.snapshot.reserve=\u865a\u62df\u673a\u7ba1\u7406\u7a0b\u5e8f\u5feb\u7167\u9884\u7559 -label.view.secondary.ips=\u67e5\u770b\u4e8c\u7ea7 IP -message.validate.invalid.characters=\u67e5\u627e\u5230\u65e0\u6548\u5b57\u7b26\uff0c\u8bf7\u66f4\u6b63\u3002 -message.acquire.ip.nic=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u83b7\u53d6\u6b64 NIC \u7684\u65b0\u4e8c\u7ea7 IP\u3002
\u6ce8\u610f: \u60a8\u9700\u8981\u5728\u865a\u62df\u673a\u5185\u90e8\u624b\u52a8\u914d\u7f6e\u65b0\u83b7\u53d6\u7684\u4e8c\u7ea7 IP\u3002 -message.select.affinity.groups=\u8bf7\u9009\u62e9\u60a8\u5e0c\u671b\u6b64 VM \u6240\u5c5e\u7684\u4efb\u4f55\u5173\u8054\u6027\u7ec4: -message.no.affinity.groups=\u60a8\u6ca1\u6709\u4efb\u4f55\u5173\u8054\u6027\u7ec4\u3002\u8bf7\u7ee7\u7eed\u6267\u884c\u4e0b\u4e00\u6b65\u64cd\u4f5c\u3002 -label.action.delete.nic=\u79fb\u9664 NIC -message.action.delete.nic=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u79fb\u9664\u6b64 NIC\uff0c\u6b64\u64cd\u4f5c\u8fd8\u5c06\u4ece VM \u4e2d\u79fb\u9664\u5173\u8054\u7684\u7f51\u7edc\u3002 + changed.item.properties=\u66f4\u6539\u9879\u76ee\u5c5e\u6027 -confirm.enable.s3=\u8bf7\u586b\u5199\u4ee5\u4e0b\u4fe1\u606f\u4ee5\u542f\u7528\u5bf9 S3 \u652f\u6301\u7684\u4e8c\u7ea7\u5b58\u50a8\u7684\u652f\u6301 +confirm.enable.s3=\u8bf7\u586b\u5199\u4ee5\u4e0b\u4fe1\u606f\u4ee5\u542f\u7528\u5bf9 S3 \u652f\u6301\u7684\u8f85\u52a9\u5b58\u50a8\u7684\u652f\u6301 confirm.enable.swift=\u8bf7\u586b\u5199\u4ee5\u4e0b\u4fe1\u606f\u4ee5\u542f\u7528\u5bf9 SWIFT \u7684\u652f\u6301 error.could.not.change.your.password.because.ldap.is.enabled=\u9519\u8bef\u3002LDAP \u5904\u4e8e\u542f\u7528\u72b6\u6001\uff0c\u65e0\u6cd5\u66f4\u6539\u60a8\u7684\u5bc6\u7801\u3002 -error.could.not.enable.zone=\u65e0\u6cd5\u542f\u7528\u8d44\u6e90\u57df +error.could.not.enable.zone=\u65e0\u6cd5\u542f\u7528\u533a\u57df error.installWizard.message=\u51fa\u73b0\u95ee\u9898\uff1b\u8bf7\u8fd4\u56de\u5e76\u66f4\u6b63\u4efb\u4f55\u9519\u8bef error.invalid.username.password=\u7528\u6237\u540d\u6216\u5bc6\u7801\u65e0\u6548 error.login=\u60a8\u7684\u7528\u6237\u540d/\u5bc6\u7801\u4e0e\u6211\u4eec\u7684\u8bb0\u5f55\u4e0d\u4e00\u81f4\u3002 @@ -88,15 +43,19 @@ ICMP.type=ICMP \u7c7b\u578b image.directory=\u56fe\u7247\u76ee\u5f55 inline=\u5185\u8054 instances.actions.reboot.label=\u91cd\u65b0\u542f\u52a8\u5b9e\u4f8b +label.about.app=\u5173\u4e8e CloudStack +label.about=\u5173\u4e8e label.accept.project.invitation=\u63a5\u53d7\u9879\u76ee\u9080\u8bf7 label.account.and.security.group=\u5e10\u6237\u3001\u5b89\u5168\u7ec4 label.account.id=\u5e10\u6237 ID +label.account.lower=\u5e10\u6237 label.account.name=\u5e10\u6237\u540d\u79f0 label.account.specific=\u5e10\u6237\u4e13\u7528 -label.account=\u5e10\u6237 label.accounts=\u5e10\u6237 +label.account=\u5e10\u6237 +label.acl=ACL label.acquire.new.ip=\u83b7\u53d6\u65b0 IP -label.acquire.new.secondary.ip=\u83b7\u53d6\u65b0\u4e8c\u7ea7 IP +label.acquire.new.secondary.ip=\u83b7\u53d6\u65b0\u8f85\u52a9 IP label.action.attach.disk.processing=\u6b63\u5728\u9644\u52a0\u78c1\u76d8... label.action.attach.disk=\u9644\u52a0\u78c1\u76d8 label.action.attach.iso.processing=\u6b63\u5728\u9644\u52a0 ISO... @@ -139,13 +98,14 @@ label.action.delete.load.balancer=\u5220\u9664\u8d1f\u8f7d\u5e73\u8861\u5668\u89 label.action.delete.network.processing=\u6b63\u5728\u5220\u9664\u7f51\u7edc... label.action.delete.network=\u5220\u9664\u7f51\u7edc label.action.delete.nexusVswitch=\u5220\u9664 Nexus 1000v +label.action.delete.nic=\u79fb\u9664 NIC label.action.delete.physical.network=\u5220\u9664\u7269\u7406\u7f51\u7edc label.action.delete.pod.processing=\u6b63\u5728\u5220\u9664\u63d0\u4f9b\u70b9... label.action.delete.pod=\u5220\u9664\u63d0\u4f9b\u70b9 label.action.delete.primary.storage.processing=\u6b63\u5728\u5220\u9664\u4e3b\u5b58\u50a8... label.action.delete.primary.storage=\u5220\u9664\u4e3b\u5b58\u50a8 -label.action.delete.secondary.storage.processing=\u6b63\u5728\u5220\u9664\u4e8c\u7ea7\u5b58\u50a8... -label.action.delete.secondary.storage=\u5220\u9664\u4e8c\u7ea7\u5b58\u50a8 +label.action.delete.secondary.storage.processing=\u6b63\u5728\u5220\u9664\u8f85\u52a9\u5b58\u50a8... +label.action.delete.secondary.storage=\u5220\u9664\u8f85\u52a9\u5b58\u50a8 label.action.delete.security.group.processing=\u6b63\u5728\u5220\u9664\u5b89\u5168\u7ec4... label.action.delete.security.group=\u5220\u9664\u5b89\u5168\u7ec4 label.action.delete.service.offering.processing=\u6b63\u5728\u5220\u9664\u670d\u52a1\u65b9\u6848... @@ -159,8 +119,8 @@ label.action.delete.user.processing=\u6b63\u5728\u5220\u9664\u7528\u6237... label.action.delete.user=\u5220\u9664\u7528\u6237 label.action.delete.volume.processing=\u6b63\u5728\u5220\u9664\u5377... label.action.delete.volume=\u5220\u9664\u5377 -label.action.delete.zone.processing=\u6b63\u5728\u5220\u9664\u8d44\u6e90\u57df... -label.action.delete.zone=\u5220\u9664\u8d44\u6e90\u57df +label.action.delete.zone.processing=\u6b63\u5728\u5220\u9664\u533a\u57df... +label.action.delete.zone=\u5220\u9664\u533a\u57df label.action.destroy.instance.processing=\u6b63\u5728\u9500\u6bc1\u5b9e\u4f8b... label.action.destroy.instance=\u9500\u6bc1\u5b9e\u4f8b label.action.destroy.systemvm.processing=\u6b63\u5728\u9500\u6bc1\u7cfb\u7edf VM... @@ -181,8 +141,8 @@ label.action.disable.static.NAT.processing=\u6b63\u5728\u7981\u7528\u9759\u6001 label.action.disable.static.NAT=\u7981\u7528\u9759\u6001 NAT label.action.disable.user.processing=\u6b63\u5728\u7981\u7528\u7528\u6237... label.action.disable.user=\u7981\u7528\u7528\u6237 -label.action.disable.zone.processing=\u6b63\u5728\u7981\u7528\u8d44\u6e90\u57df... -label.action.disable.zone=\u7981\u7528\u8d44\u6e90\u57df +label.action.disable.zone.processing=\u6b63\u5728\u7981\u7528\u533a\u57df... +label.action.disable.zone=\u7981\u7528\u533a\u57df label.action.download.ISO=\u4e0b\u8f7d ISO label.action.download.template=\u4e0b\u8f7d\u6a21\u677f label.action.download.volume.processing=\u6b63\u5728\u4e0b\u8f7d\u5377... @@ -203,7 +163,7 @@ label.action.edit.resource.limits=\u7f16\u8f91\u8d44\u6e90\u9650\u5236 label.action.edit.service.offering=\u7f16\u8f91\u670d\u52a1\u65b9\u6848 label.action.edit.template=\u7f16\u8f91\u6a21\u677f label.action.edit.user=\u7f16\u8f91\u7528\u6237 -label.action.edit.zone=\u7f16\u8f91\u8d44\u6e90\u57df +label.action.edit.zone=\u7f16\u8f91\u533a\u57df label.action.enable.account.processing=\u6b63\u5728\u542f\u7528\u5e10\u6237... label.action.enable.account=\u542f\u7528\u5e10\u6237 label.action.enable.cluster.processing=\u6b63\u5728\u542f\u7528\u7fa4\u96c6... @@ -218,10 +178,10 @@ label.action.enable.static.NAT.processing=\u6b63\u5728\u542f\u7528\u9759\u6001 N label.action.enable.static.NAT=\u542f\u7528\u9759\u6001 NAT label.action.enable.user.processing=\u6b63\u5728\u542f\u7528\u7528\u6237... label.action.enable.user=\u542f\u7528\u7528\u6237 -label.action.enable.zone.processing=\u6b63\u5728\u542f\u7528\u8d44\u6e90\u57df... -label.action.enable.zone=\u542f\u7528\u8d44\u6e90\u57df -label.action.expunge.instance=\u5220\u9664\u5b9e\u4f8b +label.action.enable.zone.processing=\u6b63\u5728\u542f\u7528\u533a\u57df... +label.action.enable.zone=\u542f\u7528\u533a\u57df label.action.expunge.instance.processing=\u6b63\u5728\u5220\u9664\u5b9e\u4f8b... +label.action.expunge.instance=\u5220\u9664\u5b9e\u4f8b label.action.force.reconnect.processing=\u6b63\u5728\u91cd\u65b0\u8fde\u63a5... label.action.force.reconnect=\u5f3a\u5236\u91cd\u65b0\u8fde\u63a5 label.action.generate.keys.processing=\u6b63\u5728\u751f\u6210\u5bc6\u94a5... @@ -257,6 +217,8 @@ label.action.resize.volume=\u8c03\u6574\u5377\u5927\u5c0f label.action.resource.limits=\u8d44\u6e90\u9650\u5236 label.action.restore.instance.processing=\u6b63\u5728\u8fd8\u539f\u5b9e\u4f8b... label.action.restore.instance=\u8fd8\u539f\u5b9e\u4f8b +label.action.revert.snapshot.processing=\u6b63\u5728\u8fd8\u539f\u5230\u5feb\u7167... +label.action.revert.snapshot=\u8fd8\u539f\u5230\u5feb\u7167 label.action.start.instance.processing=\u6b63\u5728\u542f\u52a8\u5b9e\u4f8b... label.action.start.instance=\u542f\u52a8\u5b9e\u4f8b label.action.start.router.processing=\u6b63\u5728\u542f\u52a8\u8def\u7531\u5668... @@ -269,10 +231,10 @@ label.action.stop.router.processing=\u6b63\u5728\u505c\u6b62\u8def\u7531\u5668.. label.action.stop.router=\u505c\u6b62\u8def\u7531\u5668 label.action.stop.systemvm.processing=\u6b63\u5728\u505c\u6b62\u7cfb\u7edf VM... label.action.stop.systemvm=\u505c\u6b62\u7cfb\u7edf VM +label.actions=\u64cd\u4f5c label.action.take.snapshot.processing=\u6b63\u5728\u521b\u5efa\u5feb\u7167... label.action.take.snapshot=\u521b\u5efa\u5feb\u7167 -label.action.revert.snapshot.processing=\u6b63\u5728\u8fd8\u539f\u5230\u5feb\u7167... -label.action.revert.snapshot=\u8fd8\u539f\u5230\u5feb\u7167 +label.action=\u64cd\u4f5c label.action.unmanage.cluster.processing=\u6b63\u5728\u53d6\u6d88\u6258\u7ba1\u7fa4\u96c6... label.action.unmanage.cluster=\u53d6\u6d88\u6258\u7ba1\u7fa4\u96c6 label.action.update.OS.preference.processing=\u6b63\u5728\u66f4\u65b0\u64cd\u4f5c\u7cfb\u7edf\u9996\u9009\u9879... @@ -282,15 +244,15 @@ label.action.update.resource.count=\u66f4\u65b0\u8d44\u6e90\u6570\u91cf label.action.vmsnapshot.create=\u521b\u5efa VM \u5feb\u7167 label.action.vmsnapshot.delete=\u5220\u9664 VM \u5feb\u7167 label.action.vmsnapshot.revert=\u8fd8\u539f\u5230 VM \u5feb\u7167 -label.actions=\u64cd\u4f5c label.activate.project=\u6fc0\u6d3b\u9879\u76ee label.active.sessions=\u6d3b\u52a8\u4f1a\u8bdd -label.add.account.to.project=\u5411\u9879\u76ee\u4e2d\u6dfb\u52a0\u5e10\u6237 -label.add.account=\u6dfb\u52a0\u5e10\u6237 label.add.accounts.to=\u6dfb\u52a0\u5e10\u6237\u81f3 label.add.accounts=\u6dfb\u52a0\u5e10\u6237 +label.add.account.to.project=\u5411\u9879\u76ee\u4e2d\u6dfb\u52a0\u5e10\u6237 +label.add.account=\u6dfb\u52a0\u5e10\u6237 label.add.ACL=\u6dfb\u52a0 ACL label.add.affinity.group=\u6dfb\u52a0\u65b0\u5173\u8054\u6027\u7ec4 +label.add.baremetal.dhcp.device=\u6dfb\u52a0\u88f8\u673a DHCP \u8bbe\u5907 label.add.BigSwitchVns.device=\u6dfb\u52a0 BigSwitch Vns \u63a7\u5236\u5668 label.add.by.cidr=\u6309 CIDR \u6dfb\u52a0 label.add.by.group=\u6309\u7ec4\u6dfb\u52a0 @@ -300,13 +262,26 @@ label.add.compute.offering=\u6dfb\u52a0\u8ba1\u7b97\u65b9\u6848 label.add.direct.iprange=\u6dfb\u52a0\u76f4\u63a5 IP \u8303\u56f4 label.add.disk.offering=\u6dfb\u52a0\u78c1\u76d8\u65b9\u6848 label.add.domain=\u6dfb\u52a0\u57df +label.added.new.bigswitch.vns.controller=\u5df2\u6dfb\u52a0\u65b0 BigSwitch VNS \u63a7\u5236\u5668 label.add.egress.rule=\u6dfb\u52a0\u51fa\u53e3\u89c4\u5219 +label.addes.new.f5=\u5df2\u6dfb\u52a0\u65b0 F5 label.add.F5.device=\u6dfb\u52a0 F5 \u8bbe\u5907 label.add.firewall=\u6dfb\u52a0\u9632\u706b\u5899\u89c4\u5219 +label.add.gslb=\u6dfb\u52a0 GSLB label.add.guest.network=\u6dfb\u52a0\u6765\u5bbe\u7f51\u7edc label.add.host=\u6dfb\u52a0\u4e3b\u673a +label.adding.cluster=\u6b63\u5728\u6dfb\u52a0\u7fa4\u96c6 +label.adding.failed=\u6dfb\u52a0\u5931\u8d25 +label.adding.pod=\u6b63\u5728\u6dfb\u52a0\u63d0\u4f9b\u70b9 +label.adding.processing=\u6b63\u5728\u6dfb\u52a0... label.add.ingress.rule=\u6dfb\u52a0\u5165\u53e3\u89c4\u5219 +label.adding.succeeded=\u5df2\u6210\u529f\u6dfb\u52a0 +label.adding=\u6b63\u5728\u6dfb\u52a0 +label.adding.user=\u6b63\u5728\u6dfb\u52a0\u7528\u6237 +label.adding.zone=\u6b63\u5728\u6dfb\u52a0\u533a\u57df label.add.ip.range=\u6dfb\u52a0 IP \u8303\u56f4 +label.add.isolated.network=\u6dfb\u52a0\u9694\u79bb\u7f51\u7edc +label.additional.networks=\u5176\u4ed6\u7f51\u7edc label.add.load.balancer=\u6dfb\u52a0\u8d1f\u8f7d\u5e73\u8861\u5668 label.add.more=\u6dfb\u52a0\u66f4\u591a label.add.netScaler.device=\u6dfb\u52a0 Netscaler \u8bbe\u5907 @@ -317,58 +292,56 @@ label.add.network=\u6dfb\u52a0\u7f51\u7edc label.add.new.F5=\u6dfb\u52a0\u65b0 F5 label.add.new.gateway=\u6dfb\u52a0\u65b0\u7f51\u5173 label.add.new.NetScaler=\u6dfb\u52a0\u65b0 NetScaler -label.add.new.SRX=\u6dfb\u52a0\u65b0 SRX label.add.new.PA=\u6dfb\u52a0\u65b0 Palo Alto +label.add.new.SRX=\u6dfb\u52a0\u65b0 SRX label.add.new.tier=\u6dfb\u52a0\u65b0\u5c42 +label.add.nfs.secondary.staging.store=\u6dfb\u52a0 NFS \u4e8c\u7ea7\u6682\u5b58\u5b58\u50a8 label.add.NiciraNvp.device=\u6dfb\u52a0 Nvp \u63a7\u5236\u5668 +label.add.OpenDaylight.device=\u6dfb\u52a0 OpenDaylight \u63a7\u5236\u5668 +label.add.PA.device=\u6dfb\u52a0 Palo Alto \u8bbe\u5907 label.add.physical.network=\u6dfb\u52a0\u7269\u7406\u7f51\u7edc label.add.pod=\u6dfb\u52a0\u63d0\u4f9b\u70b9 +label.add.portable.ip.range=\u6dfb\u52a0\u53ef\u79fb\u690d IP \u8303\u56f4 label.add.port.forwarding.rule=\u6dfb\u52a0\u7aef\u53e3\u8f6c\u53d1\u89c4\u5219 label.add.primary.storage=\u6dfb\u52a0\u4e3b\u5b58\u50a8 -label.add.region=\u6dfb\u52a0\u5730\u7406\u533a\u57df +label.add.region=\u6dfb\u52a0\u533a\u57df label.add.resources=\u6dfb\u52a0\u8d44\u6e90 label.add.route=\u6dfb\u52a0\u8def\u7531 label.add.rule=\u6dfb\u52a0\u89c4\u5219 -label.add.secondary.storage=\u6dfb\u52a0\u4e8c\u7ea7\u5b58\u50a8 +label.add.secondary.storage=\u6dfb\u52a0\u8f85\u52a9\u5b58\u50a8 label.add.security.group=\u6dfb\u52a0\u5b89\u5168\u7ec4 label.add.service.offering=\u6dfb\u52a0\u670d\u52a1\u65b9\u6848 label.add.SRX.device=\u6dfb\u52a0 SRX \u8bbe\u5907 -label.add.PA.device=\u6dfb\u52a0 Palo Alto \u8bbe\u5907 label.add.static.nat.rule=\u6dfb\u52a0\u9759\u6001 NAT \u89c4\u5219 label.add.static.route=\u6dfb\u52a0\u9759\u6001\u8def\u7531 label.add.system.service.offering=\u6dfb\u52a0\u7cfb\u7edf\u670d\u52a1\u65b9\u6848 label.add.template=\u6dfb\u52a0\u6a21\u677f label.add.to.group=\u6dfb\u52a0\u5230\u7ec4 +label.add=\u6dfb\u52a0 +label.add.ucs.manager=\u6dfb\u52a0 UCS \u7ba1\u7406\u5668 label.add.user=\u6dfb\u52a0\u7528\u6237 label.add.vlan=\u6dfb\u52a0 VLAN -label.add.vxlan=\u6dfb\u52a0 VXLAN -label.add.VM.to.tier=\u5411\u5c42\u4e2d\u6dfb\u52a0 VM -label.add.vm=\u6dfb\u52a0 VM label.add.vms.to.lb=\u5411\u8d1f\u8f7d\u5e73\u8861\u5668\u89c4\u5219\u4e2d\u6dfb\u52a0 VM label.add.vms=\u6dfb\u52a0 VM +label.add.VM.to.tier=\u5411\u5c42\u4e2d\u6dfb\u52a0 VM +label.add.vm=\u6dfb\u52a0 VM +label.add.vmware.datacenter=\u6dfb\u52a0 VMware \u6570\u636e\u4e2d\u5fc3 +label.add.vnmc.device=\u6dfb\u52a0 VNMC \u8bbe\u5907 +label.add.vnmc.provider=\u6dfb\u52a0 VNMC \u63d0\u4f9b\u7a0b\u5e8f label.add.volume=\u6dfb\u52a0\u5377 label.add.vpc=\u6dfb\u52a0 VPC label.add.vpn.customer.gateway=\u6dfb\u52a0 VPN \u5ba2\u6237\u7f51\u5173 label.add.VPN.gateway=\u6dfb\u52a0 VPN \u7f51\u5173 label.add.vpn.user=\u6dfb\u52a0 VPN \u7528\u6237 -label.add.zone=\u6dfb\u52a0\u8d44\u6e90\u57df -label.add=\u6dfb\u52a0 -label.adding.cluster=\u6b63\u5728\u6dfb\u52a0\u7fa4\u96c6 -label.adding.failed=\u6dfb\u52a0\u5931\u8d25 -label.adding.pod=\u6b63\u5728\u6dfb\u52a0\u63d0\u4f9b\u70b9 -label.adding.processing=\u6b63\u5728\u6dfb\u52a0... -label.adding.succeeded=\u5df2\u6210\u529f\u6dfb\u52a0 -label.adding.user=\u6b63\u5728\u6dfb\u52a0\u7528\u6237 -label.adding.zone=\u6b63\u5728\u6dfb\u52a0\u8d44\u6e90\u57df -label.adding=\u6b63\u5728\u6dfb\u52a0 -label.additional.networks=\u5176\u4ed6\u7f51\u7edc +label.add.vxlan=\u6dfb\u52a0 VXLAN +label.add.zone=\u6dfb\u52a0\u533a\u57df label.admin.accounts=\u7ba1\u7406\u5458\u5e10\u6237 label.admin=\u7ba1\u7406\u5458 label.advanced.mode=\u9ad8\u7ea7\u6a21\u5f0f label.advanced.search=\u9ad8\u7ea7\u641c\u7d22 label.advanced=\u9ad8\u7ea7 -label.affinity.group=\u5173\u8054\u6027\u7ec4 label.affinity.groups=\u5173\u8054\u6027\u7ec4 +label.affinity.group=\u5173\u8054\u6027\u7ec4 label.affinity=\u5173\u8054\u6027 label.agent.password=\u4ee3\u7406\u5bc6\u7801 label.agent.username=\u4ee3\u7406\u7528\u6237\u540d @@ -377,152 +350,210 @@ label.alert=\u8b66\u62a5 label.algorithm=\u7b97\u6cd5 label.allocated=\u5df2\u5206\u914d label.allocation.state=\u5206\u914d\u72b6\u6001 -label.anti.affinity.group=\u53cd\u5173\u8054\u6027\u7ec4 +label.allow=\u5141\u8bb8 label.anti.affinity.groups=\u53cd\u5173\u8054\u6027\u7ec4 +label.anti.affinity.group=\u53cd\u5173\u8054\u6027\u7ec4 label.anti.affinity=\u53cd\u5173\u8054\u6027 label.api.key=API \u5bc6\u94a5 label.apply=\u5e94\u7528 +label.app.name=CloudStack +label.archive.alerts=\u5b58\u6863\u8b66\u62a5 +label.archive.events=\u5b58\u6863\u4e8b\u4ef6 +label.assign.instance.another=\u5c06\u5b9e\u4f8b\u5206\u914d\u7ed9\u5176\u4ed6\u5e10\u6237 label.assign.to.load.balancer=\u6b63\u5728\u5c06\u5b9e\u4f8b\u5206\u914d\u7ed9\u8d1f\u8f7d\u5e73\u8861\u5668 label.assign=\u5206\u914d label.associated.network.id=\u5df2\u5173\u8054\u7f51\u7edc ID label.associated.network=\u5173\u8054\u7f51\u7edc +label.associated.profile=\u5df2\u5173\u8054\u914d\u7f6e\u6587\u4ef6 +label.associate.public.ip=\u5173\u8054\u516c\u7528 IP label.attached.iso=\u5df2\u9644\u52a0 ISO label.author.email=\u4f5c\u8005\u7535\u5b50\u90ae\u4ef6 label.author.name=\u4f5c\u8005\u59d3\u540d -label.availability.zone=\u53ef\u7528\u8d44\u6e90\u57df +label.autoscale=\u81ea\u52a8\u6269\u5c55 label.availability=\u53ef\u7528\u6027 +label.availability.zone=\u53ef\u7528\u533a\u57df label.available.public.ips=\u53ef\u7528\u516c\u7528 IP \u5730\u5740 label.available=\u53ef\u7528 label.back=\u540e\u9000 label.bandwidth=\u5e26\u5bbd +label.baremetal.dhcp.devices=\u88f8\u673a DHCP \u8bbe\u5907 +label.baremetal.dhcp.provider=\u88f8\u673a DHCP \u63d0\u4f9b\u7a0b\u5e8f +label.baremetal.pxe.devices=\u88f8\u673a PXE \u8bbe\u5907 +label.baremetal.pxe.device=\u6dfb\u52a0\u88f8\u673a PXE \u8bbe\u5907 +label.baremetal.pxe.provider=\u88f8\u673a PXE \u63d0\u4f9b\u7a0b\u5e8f label.basic.mode=\u57fa\u672c\u6a21\u5f0f label.basic=\u57fa\u672c label.bigswitch.controller.address=BigSwitch Vns \u63a7\u5236\u5668\u5730\u5740 +label.bigswitch.vns.details=BigSwitch VNS \u8be6\u7ec6\u4fe1\u606f +label.blade.id=\u5200\u7247\u5f0f\u670d\u52a1\u5668 ID +label.blades=\u5200\u7247\u5f0f\u670d\u52a1\u5668 label.bootable=\u53ef\u542f\u52a8 label.broadcast.domain.range=\u5e7f\u64ad\u57df\u8303\u56f4 label.broadcast.domain.type=\u5e7f\u64ad\u57df\u7c7b\u578b label.broadcast.uri=\u5e7f\u64ad URI +label.broadcasturi=\u5e7f\u64ad URI +label.broadcat.uri=\u5e7f\u64ad URI label.by.account=\u6309\u5e10\u6237 +label.by.alert.type=\u6309\u8b66\u62a5\u7c7b\u578b label.by.availability=\u6309\u53ef\u7528\u6027 +label.by.date.end=\u6309\u65e5\u671f(\u7ed3\u675f\u65e5\u671f) +label.by.date.start=\u6309\u65e5\u671f(\u5f00\u59cb\u65e5\u671f) label.by.domain=\u6309\u57df label.by.end.date=\u6309\u7ed3\u675f\u65e5\u671f +label.by.event.type=\u6309\u4e8b\u4ef6\u7c7b\u578b label.by.level=\u6309\u7ea7\u522b label.by.pod=\u6309\u63d0\u4f9b\u70b9 label.by.role=\u6309\u89d2\u8272 label.by.start.date=\u6309\u5f00\u59cb\u65e5\u671f label.by.state=\u6309\u72b6\u6001 -label.by.traffic.type=\u6309\u6d41\u91cf\u7c7b\u578b -label.by.type.id=\u6309\u7c7b\u578b ID -label.by.type=\u6309\u7c7b\u578b -label.by.zone=\u6309\u8d44\u6e90\u57df label.bytes.received=\u63a5\u6536\u7684\u5b57\u8282\u6570 label.bytes.sent=\u53d1\u9001\u7684\u5b57\u8282\u6570 +label.by.traffic.type=\u6309\u901a\u4fe1\u7c7b\u578b +label.by.type.id=\u6309\u7c7b\u578b ID +label.by.type=\u6309\u7c7b\u578b +label.by.zone=\u6309\u533a\u57df +label.cache.mode=\u5199\u5165\u7f13\u5b58\u7c7b\u578b label.cancel=\u53d6\u6d88 label.capacity=\u5bb9\u91cf label.certificate=\u8bc1\u4e66 +label.change.affinity=\u66f4\u6539\u5173\u8054\u6027 label.change.service.offering=\u66f4\u6539\u670d\u52a1\u65b9\u6848 label.change.value=\u66f4\u6539\u503c label.character=\u5b57\u7b26 +label.chassis=\u673a\u7bb1 label.checksum=MD5 \u6821\u9a8c\u548c label.cidr.account=CIDR \u6216\u5e10\u6237/\u5b89\u5168\u7ec4 +label.cidr=CIDR label.CIDR.list=CIDR \u5217\u8868 label.cidr.list=\u6e90 CIDR label.CIDR.of.destination.network=\u76ee\u7684\u5730\u7f51\u7edc\u7684 CIDR -label.cidr=CIDR +label.cisco.nexus1000v.ip.address=Nexus 1000v IP \u5730\u5740 +label.cisco.nexus1000v.password=Nexus 1000v \u5bc6\u7801 +label.cisco.nexus1000v.username=Nexus 1000v \u7528\u6237\u540d +label.ciscovnmc.resource.details=CiscoVNMC \u8d44\u6e90\u8be6\u7ec6\u4fe1\u606f label.clean.up=\u6e05\u7406 label.clear.list=\u6e05\u9664\u5217\u8868 label.close=\u5173\u95ed label.cloud.console=\u4e91\u7ba1\u7406\u63a7\u5236\u53f0 label.cloud.managed=\u7531 Cloud.com \u7ba1\u7406 label.cluster.name=\u7fa4\u96c6\u540d\u79f0 +label.clusters=\u7fa4\u96c6 label.cluster.type=\u7fa4\u96c6\u7c7b\u578b label.cluster=\u7fa4\u96c6 -label.clusters=\u7fa4\u96c6 label.clvm=CLVM -label.rbd=RBD -label.rbd.monitor=Ceph \u76d1\u89c6\u5668 -label.rbd.pool=Ceph \u6c60 -label.rbd.id=Cephx \u7528\u6237 -label.rbd.secret=Cephx \u5bc6\u94a5 label.code=\u4ee3\u7801 label.community=\u793e\u533a label.compute.and.storage=\u8ba1\u7b97\u4e0e\u5b58\u50a8 -label.compute.offering=\u8ba1\u7b97\u65b9\u6848 label.compute.offerings=\u8ba1\u7b97\u65b9\u6848 +label.compute.offering=\u8ba1\u7b97\u65b9\u6848 label.compute=\u8ba1\u7b97 label.configuration=\u914d\u7f6e +label.configure.ldap=\u914d\u7f6e LDAP label.configure.network.ACLs=\u914d\u7f6e\u7f51\u7edc ACL -label.configure.vpc=\u914d\u7f6e VPC label.configure=\u914d\u7f6e -label.confirm.password=\u786e\u8ba4\u5bc6\u7801 +label.configure.vpc=\u914d\u7f6e VPC label.confirmation=\u786e\u8ba4 +label.confirm.password=\u786e\u8ba4\u5bc6\u7801 label.congratulations=\u795d\u8d3a\u60a8\! label.conserve.mode=\u4fdd\u62a4\u6a21\u5f0f label.console.proxy=\u63a7\u5236\u53f0\u4ee3\u7406 +label.console.proxy.vm=\u63a7\u5236\u5668\u4ee3\u7406 VM label.continue.basic.install=\u7ee7\u7eed\u6267\u884c\u57fa\u672c\u5b89\u88c5 label.continue=\u7ee7\u7eed label.corrections.saved=\u5df2\u4fdd\u5b58\u4fee\u6b63 label.cpu.allocated.for.VMs=\u5df2\u5206\u914d\u7ed9 VM \u7684 CPU label.cpu.allocated=\u5df2\u5206\u914d\u7684 CPU label.CPU.cap=CPU \u4e0a\u9650 +label.cpu=CPU label.cpu.limits=CPU \u9650\u5236 label.cpu.mhz=CPU (MHz) label.cpu.utilized=CPU \u5229\u7528\u7387 -label.cpu=CPU +label.created.by.system=\u7531\u7cfb\u7edf\u521b\u5efa +label.created=\u521b\u5efa\u65e5\u671f +label.create.nfs.secondary.staging.storage=\u521b\u5efa NFS \u4e8c\u7ea7\u6682\u5b58\u5b58\u50a8 +label.create.nfs.secondary.staging.store=\u521b\u5efa NFS \u4e8c\u7ea7\u6682\u5b58\u5b58\u50a8 label.create.project=\u521b\u5efa\u9879\u76ee label.create.template=\u521b\u5efa\u6a21\u677f label.create.VPN.connection=\u521b\u5efa VPN \u8fde\u63a5 -label.created.by.system=\u7531\u7cfb\u7edf\u521b\u5efa -label.created=\u521b\u5efa\u65e5\u671f -label.cross.zones=\u8de8\u8d44\u6e90\u57df +label.cross.zones=\u8de8\u533a\u57df +label.custom.disk.iops=\u81ea\u5b9a\u4e49 IOPS label.custom.disk.size=\u81ea\u5b9a\u4e49\u78c1\u76d8\u5927\u5c0f +label.custom=\u81ea\u5b9a\u4e49 label.daily=\u6bcf\u5929 label.data.disk.offering=\u6570\u636e\u78c1\u76d8\u65b9\u6848 label.date=\u65e5\u671f label.day.of.month=\u65e5\u671f label.day.of.week=\u661f\u671f +label.dc.name=\u6570\u636e\u4e2d\u5fc3\u540d\u79f0 label.dead.peer.detection=\u5931\u6548\u5bf9\u7b49\u4f53\u68c0\u6d4b label.decline.invitation=\u62d2\u7edd\u9080\u8bf7 +label.dedicate.cluster=\u5c06\u7fa4\u96c6\u4e13\u7528 label.dedicated=\u4e13\u7528 +label.dedicated.vlan.vni.ranges=VLAN/VNI \u8303\u56f4\u5df2\u4e13\u7528 +label.dedicate.host=\u5c06\u4e3b\u673a\u4e13\u7528 +label.dedicate.pod=\u5c06\u63d0\u4f9b\u70b9\u4e13\u7528 +label.dedicate=\u4e13\u7528 +label.dedicate.vlan.vni.range=\u5c06 VLAN/VNI \u8303\u56f4\u4e13\u7528 +label.dedicate.zone=\u5c06\u8d44\u6e90\u57df\u4e13\u7528 +label.default.egress.policy=\u9ed8\u8ba4\u51fa\u53e3\u89c4\u5219 +label.default=\u9ed8\u8ba4\u8bbe\u7f6e label.default.use=\u9ed8\u8ba4\u4f7f\u7528 label.default.view=\u9ed8\u8ba4\u89c6\u56fe -label.default=\u9ed8\u8ba4\u8bbe\u7f6e label.delete.affinity.group=\u5220\u9664\u5173\u8054\u6027\u7ec4 +label.delete.alerts=\u5220\u9664\u8b66\u62a5 label.delete.BigSwitchVns=\u79fb\u9664 BigSwitch Vns \u63a7\u5236\u5668 +label.delete.ciscovnmc.resource=\u5220\u9664 CiscoVNMC \u8d44\u6e90 +label.delete.events=\u5220\u9664\u4e8b\u4ef6 label.delete.F5=\u5220\u9664 F5 label.delete.gateway=\u5220\u9664\u7f51\u5173 label.delete.NetScaler=\u5220\u9664 NetScaler label.delete.NiciraNvp=\u79fb\u9664 Nvp \u63a7\u5236\u5668 +label.delete.OpenDaylight.device=\u5220\u9664 OpenDaylight \u63a7\u5236\u5668 +label.delete.PA=\u5220\u9664 Palo Alto +label.delete.portable.ip.range=\u5220\u9664\u53ef\u79fb\u690d IP \u8303\u56f4 +label.delete.profile=\u5220\u9664\u914d\u7f6e\u6587\u4ef6 label.delete.project=\u5220\u9664\u9879\u76ee +label.delete.secondary.staging.store=\u5220\u9664\u4e8c\u7ea7\u6682\u5b58\u5b58\u50a8 label.delete.SRX=\u5220\u9664 SRX -label.delete.PA=\u5220\u9664 Palo Alto +label.delete=\u5220\u9664 +label.delete.ucs.manager=\u5220\u9664 UCS Manager label.delete.VPN.connection=\u5220\u9664 VPN \u8fde\u63a5 label.delete.VPN.customer.gateway=\u5220\u9664 VPN \u5ba2\u6237\u7f51\u5173 label.delete.VPN.gateway=\u5220\u9664 VPN \u7f51\u5173 label.delete.vpn.user=\u5220\u9664 VPN \u7528\u6237 -label.delete=\u5220\u9664 label.deleting.failed=\u5220\u9664\u5931\u8d25 label.deleting.processing=\u6b63\u5728\u5220\u9664... +label.deny=\u62d2\u7edd +label.deployment.planner=\u90e8\u7f72\u89c4\u5212\u5668 label.description=\u8bf4\u660e label.destination.physical.network.id=\u76ee\u6807\u7269\u7406\u7f51\u7edc ID -label.destination.zone=\u76ee\u6807\u8d44\u6e90\u57df +label.destination.zone=\u76ee\u6807\u533a\u57df label.destroy.router=\u9500\u6bc1\u8def\u7531\u5668 label.destroy=\u9500\u6bc1 +label.destroy.vm.graceperiod=\u9500\u6bc1 VM \u5bbd\u9650\u671f label.detaching.disk=\u6b63\u5728\u53d6\u6d88\u9644\u52a0\u78c1\u76d8 label.details=\u8be6\u7ec6\u4fe1\u606f label.device.id=\u8bbe\u5907 ID label.devices=\u8bbe\u5907 -label.DHCP.server.type=DHCP \u670d\u52a1\u5668\u7c7b\u578b label.dhcp=DHCP +label.DHCP.server.type=DHCP \u670d\u52a1\u5668\u7c7b\u578b label.direct.ips=\u5171\u4eab\u7f51\u7edc IP +label.disable.autoscale=\u7981\u7528\u81ea\u52a8\u6269\u5c55 +label.disabled=\u5df2\u7981\u7528 +label.disable.network.offering=\u7981\u7528\u7f51\u7edc\u65b9\u6848 label.disable.provider=\u7981\u7528\u63d0\u4f9b\u7a0b\u5e8f +label.disable.vnmc.provider=\u7981\u7528 VNMC \u63d0\u4f9b\u7a0b\u5e8f label.disable.vpn=\u7981\u7528 VPN -label.disabled=\u5df2\u7981\u7528 label.disabling.vpn.access=\u6b63\u5728\u7981\u7528 VPN \u8bbf\u95ee +label.disassociate.profile.blade=\u53d6\u6d88\u5c06\u914d\u7f6e\u6587\u4ef6\u4e0e\u5200\u7247\u5f0f\u670d\u52a1\u5668\u5173\u8054 +label.disbale.vnmc.device=\u7981\u7528 VNMC \u8bbe\u5907 label.disk.allocated=\u5df2\u5206\u914d\u7684\u78c1\u76d8 label.disk.bytes.read.rate=\u78c1\u76d8\u8bfb\u53d6\u901f\u5ea6(BPS) label.disk.bytes.write.rate=\u78c1\u76d8\u5199\u5165\u901f\u5ea6(BPS) +label.disk.iops.max=\u6700\u5927 IOPS +label.disk.iops.min=\u6700\u5c0f IOPS label.disk.iops.read.rate=\u78c1\u76d8\u8bfb\u53d6\u901f\u5ea6(IOPS) +label.disk.iops.total=\u603b IOPS label.disk.iops.write.rate=\u78c1\u76d8\u5199\u5165\u901f\u5ea6(IOPS) label.disk.offering=\u78c1\u76d8\u65b9\u6848 label.disk.read.bytes=\u78c1\u76d8\u8bfb\u53d6(\u5b57\u8282) @@ -537,10 +568,11 @@ label.display.name=\u663e\u793a\u540d\u79f0 label.display.text=\u663e\u793a\u6587\u672c label.dns.1=DNS 1 label.dns.2=DNS 2 -label.DNS.domain.for.guest.networks=\u6765\u5bbe\u7f51\u7edc\u7684 DNS \u57df label.dns=DNS +label.DNS.domain.for.guest.networks=\u6765\u5bbe\u7f51\u7edc\u7684 DNS \u57df label.domain.admin=\u57df\u7ba1\u7406\u5458 label.domain.id=\u57df ID +label.domain.lower=\u57df label.domain.name=\u57df\u540d label.domain.router=\u57df\u8def\u7531\u5668 label.domain.suffix=DNS \u57df\u540e\u7f00(\u4f8b\u5982 xyz.com) @@ -549,33 +581,41 @@ label.done=\u5b8c\u6210 label.double.quotes.are.not.allowed=\u4e0d\u5141\u8bb8\u4f7f\u7528\u53cc\u5f15\u53f7 label.download.progress=\u4e0b\u8f7d\u8fdb\u5ea6 label.drag.new.position=\u62d6\u52a8\u5230\u65b0\u4f4d\u7f6e +label.dynamically.scalable=\u53ef\u52a8\u6001\u6269\u5c55 label.edit.affinity.group=\u7f16\u8f91\u5173\u8054\u6027\u7ec4 label.edit.lb.rule=\u7f16\u8f91\u8d1f\u8f7d\u5e73\u8861\u5668\u89c4\u5219 label.edit.network.details=\u7f16\u8f91\u7f51\u7edc\u8be6\u60c5 label.edit.project.details=\u7f16\u8f91\u9879\u76ee\u8be6\u60c5 +label.edit.region=\u7f16\u8f91\u5730\u7406\u533a\u57df label.edit.tags=\u7f16\u8f91\u6807\u7b7e -label.edit.traffic.type=\u7f16\u8f91\u6d41\u91cf\u7c7b\u578b -label.edit.vpc=\u7f16\u8f91 VPC +label.edit.traffic.type=\u7f16\u8f91\u901a\u4fe1\u7c7b\u578b label.edit=\u7f16\u8f91 -label.egress.rule=\u51fa\u53e3\u89c4\u5219 +label.edit.vpc=\u7f16\u8f91 VPC +label.egress.default.policy=\u51fa\u53e3\u9ed8\u8ba4\u7b56\u7565 label.egress.rules=\u51fa\u53e3\u89c4\u5219 +label.egress.rule=\u51fa\u53e3\u89c4\u5219 label.elastic.IP=\u5f39\u6027 IP label.elastic.LB=\u5f39\u6027\u8d1f\u8f7d\u5e73\u8861\u5668 label.elastic=\u5f39\u6027 +label.email.lower=\u7535\u5b50\u90ae\u4ef6 label.email=\u7535\u5b50\u90ae\u4ef6 +label.enable.autoscale=\u542f\u7528\u81ea\u52a8\u6269\u5c55 +label.enable.network.offering=\u542f\u7528\u7f51\u7edc\u65b9\u6848 label.enable.provider=\u542f\u7528\u63d0\u4f9b\u7a0b\u5e8f -label.enable.s3=\u542f\u7528 S3 \u652f\u6301\u7684\u4e8c\u7ea7\u5b58\u50a8 +label.enable.s3=\u542f\u7528 S3 \u652f\u6301\u7684\u8f85\u52a9\u5b58\u50a8 label.enable.swift=\u542f\u7528 SWIFT +label.enable.vnmc.device=\u542f\u7528 VNMC \u8bbe\u5907 +label.enable.vnmc.provider=\u542f\u7528 VNMC \u63d0\u4f9b\u7a0b\u5e8f label.enable.vpn=\u542f\u7528 VPN label.enabling.vpn.access=\u6b63\u5728\u542f\u7528 VPN \u8bbf\u95ee label.enabling.vpn=\u6b63\u5728\u542f\u7528 VPN label.end.IP=\u7ed3\u675f IP +label.endpoint.or.operation=\u7aef\u70b9\u6216\u64cd\u4f5c +label.endpoint=\u7aef\u70b9 label.end.port=\u7ed3\u675f\u7aef\u53e3 label.end.reserved.system.IP=\u7ed3\u675f\u9884\u7559\u7cfb\u7edf IP label.end.vlan=\u7ed3\u675f VLAN label.end.vxlan=\u7ed3\u675f VXLAN -label.endpoint.or.operation=\u7aef\u70b9\u6216\u64cd\u4f5c -label.endpoint=\u7aef\u70b9 label.enter.token=\u8f93\u5165\u4ee4\u724c label.error.code=\u9519\u8bef\u4ee3\u7801 label.error=\u9519\u8bef @@ -587,12 +627,14 @@ label.esx.host=ESX/ESXi \u4e3b\u673a label.example=\u793a\u4f8b label.expunge=\u5220\u9664 label.external.link=\u5916\u90e8\u94fe\u63a5 +label.f5.details=F5 \u8be6\u7ec6\u4fe1\u606f label.f5=F5 label.failed=\u5931\u8d25 label.featured=\u7cbe\u9009 label.fetch.latest=\u63d0\u53d6\u6700\u65b0\u5185\u5bb9 label.filterBy=\u8fc7\u6ee4\u4f9d\u636e label.firewall=\u9632\u706b\u5899 +label.firstname.lower=\u540d\u5b57 label.first.name=\u540d\u5b57 label.format=\u683c\u5f0f label.friday=\u661f\u671f\u4e94 @@ -606,34 +648,58 @@ label.go.step.2=\u8f6c\u81f3\u6b65\u9aa4 2 label.go.step.3=\u8f6c\u81f3\u6b65\u9aa4 3 label.go.step.4=\u8f6c\u81f3\u6b65\u9aa4 4 label.go.step.5=\u8f6c\u81f3\u6b65\u9aa4 5 +label.group.by.account=\u6309\u5e10\u6237\u5206\u7ec4 +label.group.by.cluster=\u6309\u7fa4\u96c6\u5206\u7ec4 +label.group.by.pod=\u6309\u63d0\u4f9b\u70b9\u5206\u7ec4 +label.group.by.zone=\u6309\u8d44\u6e90\u57df\u5206\u7ec4 label.group.optional=\u7ec4(\u53ef\u9009) label.group=\u7ec4 +label.gslb.assigned.lb.more=\u5206\u914d\u66f4\u591a\u8d1f\u8f7d\u5e73\u8861 +label.gslb.assigned.lb=\u5df2\u5206\u914d\u8d1f\u8f7d\u5e73\u8861 +label.gslb.delete=\u5220\u9664 GSLB +label.gslb.details=GSLB \u8be6\u7ec6\u4fe1\u606f +label.gslb.domain.name=GSLB \u57df\u540d +label.gslb.lb.details=\u8d1f\u8f7d\u5e73\u8861\u8be6\u7ec6\u4fe1\u606f +label.gslb.lb.remove=\u4ece\u6b64 GSLB \u4e2d\u5220\u9664\u8d1f\u8f7d\u5e73\u8861 +label.gslb.lb.rule=\u8d1f\u8f7d\u5e73\u8861\u89c4\u5219 +label.gslb.service=GSLB \u670d\u52a1 +label.gslb.service.private.ip=GSLB \u670d\u52a1\u4e13\u7528 IP +label.gslb.service.public.ip=GSLB \u670d\u52a1\u516c\u7528 IP +label.gslb.servicetype=\u670d\u52a1\u7c7b\u578b label.guest.cidr=\u6765\u5bbe CIDR label.guest.end.ip=\u6765\u5bbe\u7ed3\u675f IP label.guest.gateway=\u6765\u5bbe\u7f51\u5173 label.guest.ip.range=\u6765\u5bbe IP \u8303\u56f4 label.guest.ip=\u6765\u5bbe IP \u5730\u5740 label.guest.netmask=\u6765\u5bbe\u7f51\u7edc\u63a9\u7801 +label.guest.network.details=\u6765\u5bbe\u7f51\u7edc\u8be6\u7ec6\u4fe1\u606f label.guest.networks=\u6765\u5bbe\u7f51\u7edc label.guest.start.ip=\u6765\u5bbe\u8d77\u59cb IP -label.guest.traffic=\u6765\u5bbe\u6d41\u91cf +label.guest.traffic=\u6765\u5bbe\u901a\u4fe1 +label.guest.traffic.vswitch.name=\u6765\u5bbe\u6d41\u91cf\u865a\u62df\u4ea4\u6362\u673a\u540d\u79f0 +label.guest.traffic.vswitch.type=\u6765\u5bbe\u6d41\u91cf\u865a\u62df\u4ea4\u6362\u673a\u7c7b\u578b label.guest.type=\u6765\u5bbe\u7c7b\u578b label.guest=\u6765\u5bbe label.ha.enabled=\u5df2\u542f\u7528\u9ad8\u53ef\u7528\u6027 +label.health.check=\u8fd0\u884c\u72b6\u51b5\u68c0\u67e5 label.help=\u5e2e\u52a9 label.hide.ingress.rule=\u9690\u85cf\u5165\u53e3\u89c4\u5219 label.hints=\u63d0\u793a +label.home=\u9996\u9875 label.host.alerts=\u4e3b\u673a\u8b66\u62a5 label.host.MAC=\u4e3b\u673a MAC label.host.name=\u4e3b\u673a\u540d\u79f0 +label.hosts=\u4e3b\u673a label.host.tags=\u4e3b\u673a\u6807\u7b7e label.host=\u4e3b\u673a -label.hosts=\u4e3b\u673a label.hourly=\u6bcf\u5c0f\u65f6 label.hypervisor.capabilities=\u865a\u62df\u673a\u7ba1\u7406\u7a0b\u5e8f\u529f\u80fd +label.hypervisor.snapshot.reserve=\u865a\u62df\u673a\u7ba1\u7406\u7a0b\u5e8f\u5feb\u7167\u9884\u7559 +label.hypervisors=\u865a\u62df\u673a\u7ba1\u7406\u7a0b\u5e8f label.hypervisor.type=\u865a\u62df\u673a\u7ba1\u7406\u7a0b\u5e8f\u7c7b\u578b -label.hypervisor.version=\u865a\u62df\u673a\u7ba1\u7406\u7a0b\u5e8f\u7248\u672c label.hypervisor=\u865a\u62df\u673a\u7ba1\u7406\u7a0b\u5e8f +label.hypervisor.version=\u865a\u62df\u673a\u7ba1\u7406\u7a0b\u5e8f\u7248\u672c +label.hyperv.traffic.label=HyperV \u6d41\u91cf\u6807\u7b7e label.id=ID label.IKE.DH=IKE DH \u7b97\u6cd5 label.IKE.encryption=IKE \u52a0\u5bc6\u7b97\u6cd5 @@ -651,18 +717,20 @@ label.installWizard.addPodIntro.subtitle=\u4ec0\u4e48\u662f\u63d0\u4f9b\u70b9? label.installWizard.addPodIntro.title=\u6dfb\u52a0\u4e00\u4e2a\u63d0\u4f9b\u70b9 label.installWizard.addPrimaryStorageIntro.subtitle=\u4ec0\u4e48\u662f\u4e3b\u5b58\u50a8? label.installWizard.addPrimaryStorageIntro.title=\u6dfb\u52a0\u4e00\u4e2a\u4e3b\u5b58\u50a8 -label.installWizard.addSecondaryStorageIntro.subtitle=\u4ec0\u4e48\u662f\u4e8c\u7ea7\u5b58\u50a8? -label.installWizard.addSecondaryStorageIntro.title=\u6dfb\u52a0\u4e00\u4e2a\u4e8c\u7ea7\u5b58\u50a8 -label.installWizard.addZone.title=\u6dfb\u52a0\u8d44\u6e90\u57df -label.installWizard.addZoneIntro.subtitle=\u4ec0\u4e48\u662f\u8d44\u6e90\u57df? -label.installWizard.addZoneIntro.title=\u6dfb\u52a0\u4e00\u4e2a\u8d44\u6e90\u57df +label.installWizard.addSecondaryStorageIntro.subtitle=\u4ec0\u4e48\u662f\u8f85\u52a9\u5b58\u50a8? +label.installWizard.addSecondaryStorageIntro.title=\u6dfb\u52a0\u4e00\u4e2a\u8f85\u52a9\u5b58\u50a8 +label.installWizard.addZoneIntro.subtitle=\u4ec0\u4e48\u662f\u533a\u57df? +label.installWizard.addZoneIntro.title=\u6dfb\u52a0\u4e00\u4e2a\u533a\u57df +label.installWizard.addZone.title=\u6dfb\u52a0\u533a\u57df label.installWizard.click.launch=\u8bf7\u5355\u51fb\u201c\u542f\u52a8\u201d\u6309\u94ae\u3002 label.installWizard.subtitle=\u6b64\u6559\u7a0b\u5c06\u5e2e\u52a9\u60a8\u8bbe\u7f6e CloudStack&\#8482 \u5b89\u88c5 label.installWizard.title=\u60a8\u597d\uff0c\u6b22\u8fce\u4f7f\u7528 CloudStack&\#8482 label.instance.limits=\u5b9e\u4f8b\u9650\u5236 label.instance.name=\u5b9e\u4f8b\u540d\u79f0 -label.instance=\u5b9e\u4f8b +label.instance.scaled.up=\u5df2\u6269\u5c55\u5b9e\u4f8b label.instances=\u5b9e\u4f8b +label.instance=\u5b9e\u4f8b +label.instanciate.template.associate.profile.blade=\u5c06\u6a21\u677f\u5b9e\u4f8b\u5316\u5e76\u5c06\u914d\u7f6e\u6587\u4ef6\u4e0e\u5200\u7247\u5f0f\u670d\u52a1\u5668\u5173\u8054 label.internal.dns.1=\u5185\u90e8 DNS 1 label.internal.dns.2=\u5185\u90e8 DNS 2 label.internal.name=\u5185\u90e8\u540d\u79f0 @@ -671,35 +739,47 @@ label.introduction.to.cloudstack=CloudStack&\#8482 \u7b80\u4ecb label.invalid.integer=\u65e0\u6548\u6574\u6570 label.invalid.number=\u65e0\u6548\u6570\u5b57 label.invitations=\u9080\u8bf7 +label.invited.accounts=\u5df2\u9080\u8bf7\u7684\u5e10\u6237 label.invite.to=\u9080\u8bf7\u52a0\u5165 label.invite=\u9080\u8bf7 -label.invited.accounts=\u5df2\u9080\u8bf7\u7684\u5e10\u6237 label.ip.address=IP \u5730\u5740 +label.ipaddress=IP \u5730\u5740 label.ip.allocations=IP \u5206\u914d +label.ip=IP label.ip.limits=\u516c\u7528 IP \u9650\u5236 label.ip.or.fqdn=IP \u6216 FQDN label.ip.range=IP \u8303\u56f4 label.ip.ranges=IP \u8303\u56f4 -label.ip=IP -label.ipaddress=IP \u5730\u5740 -label.ips=IP label.IPsec.preshared.key=IPsec \u9884\u5171\u4eab\u5bc6\u94a5 -label.is.default=\u662f\u5426\u4e3a\u9ed8\u8ba4\u8bbe\u7f6e -label.is.redundant.router=\u5197\u4f59 -label.is.shared=\u662f\u5426\u5171\u4eab -label.is.system=\u662f\u5426\u4e3a\u7cfb\u7edf +label.ips=IP +label.ipv4.cidr=IPv4 CIDR +label.ipv4.end.ip=IPv4 \u7ed3\u675f IP +label.ipv4.gateway=IPv4 \u7f51\u5173 +label.ipv4.netmask=IPv4 \u7f51\u7edc\u63a9\u7801 +label.ipv4.start.ip=IPv4 \u8d77\u59cb IP +label.ipv6.address=IPv6 IP \u5730\u5740 +label.ipv6.CIDR=IPv6 CIDR +label.ipv6.dns1=IPv6 DNS1 +label.ipv6.dns2=IPv6 DNS2 +label.ipv6.end.ip=IPv6 \u7ed3\u675f IP +label.ipv6.gateway=IPv6 \u7f51\u5173 +label.ipv6.start.ip=IPv6 \u8d77\u59cb IP label.iscsi=iSCSI +label.is.default=\u662f\u5426\u4e3a\u9ed8\u8ba4\u8bbe\u7f6e label.iso.boot=ISO \u542f\u52a8 label.iso=ISO label.isolated.networks=\u9694\u79bb\u7f51\u7edc label.isolation.method=\u9694\u79bb\u65b9\u6cd5 label.isolation.mode=\u9694\u79bb\u6a21\u5f0f label.isolation.uri=\u9694\u79bb URI +label.is.redundant.router=\u5197\u4f59 +label.is.shared=\u662f\u5426\u5171\u4eab +label.is.system=\u662f\u5426\u4e3a\u7cfb\u7edf label.item.listing=\u9879\u76ee\u5217\u8868 label.keep=\u4fdd\u7559 -label.key=\u5bc6\u94a5 label.keyboard.type=\u952e\u76d8\u7c7b\u578b -label.kvm.traffic.label=KVM \u6d41\u91cf\u6807\u7b7e +label.key=\u5bc6\u94a5 +label.kvm.traffic.label=KVM \u901a\u4fe1\u6807\u7b7e label.label=\u6807\u7b7e label.lang.arabic=\u963f\u62c9\u4f2f\u8bed label.lang.brportugese=\u8461\u8404\u7259\u8bed(\u5df4\u897f) @@ -717,12 +797,16 @@ label.lang.polish=\u6ce2\u5170\u8bed label.lang.russian=\u4fc4\u8bed label.lang.spanish=\u897f\u73ed\u7259\u8bed label.last.disconnected=\u4e0a\u6b21\u65ad\u5f00\u8fde\u63a5\u65f6\u95f4 +label.lastname.lower=\u59d3\u6c0f label.last.name=\u59d3\u6c0f label.latest.events=\u6700\u65b0\u4e8b\u4ef6 -label.launch.vm=\u542f\u52a8 VM -label.launch.zone=\u542f\u52a8\u8d44\u6e90\u57df label.launch=\u542f\u52a8 +label.launch.vm=\u542f\u52a8 VM +label.launch.zone=\u542f\u52a8\u533a\u57df label.LB.isolation=\u8d1f\u8f7d\u5e73\u8861\u5668\u9694\u79bb +label.ldap.configuration=LDAP \u914d\u7f6e +label.ldap.group.name=LDAP \u7ec4 +label.ldap.port=LDAP \u7aef\u53e3 label.least.connections=\u6700\u5c11\u8fde\u63a5\u7b97\u6cd5 label.level=\u7ea7\u522b label.linklocal.ip=\u94fe\u63a5\u672c\u5730 IP \u5730\u5740 @@ -735,33 +819,35 @@ label.local.storage=\u672c\u5730\u5b58\u50a8 label.local=\u672c\u5730 label.login=\u767b\u5f55 label.logout=\u6ce8\u9500 -label.LUN.number=LUN \u53f7 label.lun=LUN +label.LUN.number=LUN \u53f7 +label.lxc.traffic.label=LXC \u6d41\u91cf\u6807\u7b7e label.make.project.owner=\u8bbe\u4e3a\u5e10\u6237\u9879\u76ee\u6240\u6709\u8005 -label.manage.resources=\u7ba1\u7406\u8d44\u6e90 -label.manage=\u6258\u7ba1 label.management.ips=\u7ba1\u7406\u7c7b IP \u5730\u5740 label.management=\u7ba1\u7406 +label.manage.resources=\u7ba1\u7406\u8d44\u6e90 +label.manage=\u6258\u7ba1 label.max.cpus=\u6700\u5927 CPU \u5185\u6838\u6570 label.max.guest.limit=\u6700\u5927\u6765\u5bbe\u6570\u9650\u5236 +label.maximum=\u6700\u5927\u503c +label.max.instances=\u6700\u5927\u5b9e\u4f8b\u6570 label.max.memory=\u6700\u5927\u5185\u5b58(MiB) label.max.networks=\u6700\u5927\u7f51\u7edc\u6570 label.max.primary.storage=\u6700\u5927\u4e3b\u5b58\u50a8(GiB) label.max.public.ips=\u6700\u5927\u516c\u7528 IP \u6570 -label.max.secondary.storage=\u6700\u5927\u4e8c\u7ea7\u5b58\u50a8(GiB) +label.max.secondary.storage=\u6700\u5927\u8f85\u52a9\u5b58\u50a8(GiB) label.max.snapshots=\u6700\u5927\u5feb\u7167\u6570 label.max.templates=\u6700\u5927\u6a21\u677f\u6570 label.max.vms=\u6700\u5927\u7528\u6237 VM \u6570 label.max.volumes=\u6700\u5927\u5377\u6570 label.max.vpcs=\u6700\u5927 VPC \u6570 -label.maximum=\u6700\u5927\u503c label.may.continue=\u60a8\u73b0\u5728\u53ef\u4ee5\u7ee7\u7eed\u8fdb\u884c\u64cd\u4f5c\u3002 label.memory.allocated=\u5df2\u5206\u914d\u7684\u5185\u5b58 label.memory.limits=\u5185\u5b58\u9650\u5236(MiB) label.memory.mb=\u5185\u5b58(MB) label.memory.total=\u5185\u5b58\u603b\u91cf -label.memory.used=\u5df2\u4f7f\u7528\u7684\u5185\u5b58 label.memory=\u5185\u5b58 +label.memory.used=\u5df2\u4f7f\u7528\u7684\u5185\u5b58 label.menu.accounts=\u5e10\u6237 label.menu.alerts=\u8b66\u62a5 label.menu.all.accounts=\u6240\u6709\u5e10\u6237 @@ -788,7 +874,7 @@ label.menu.my.templates=\u6211\u7684\u6a21\u677f label.menu.network.offerings=\u7f51\u7edc\u65b9\u6848 label.menu.network=\u7f51\u7edc label.menu.physical.resources=\u7269\u7406\u8d44\u6e90 -label.menu.regions=\u5730\u7406\u533a\u57df +label.menu.regions=\u533a\u57df label.menu.running.instances=\u6b63\u5728\u8fd0\u884c\u7684\u5b9e\u4f8b label.menu.security.groups=\u5b89\u5168\u7ec4 label.menu.service.offerings=\u670d\u52a1\u65b9\u6848 @@ -796,8 +882,8 @@ label.menu.snapshots=\u5feb\u7167 label.menu.stopped.instances=\u5df2\u505c\u6b62\u7684\u5b9e\u4f8b label.menu.storage=\u5b58\u50a8 label.menu.system.service.offerings=\u7cfb\u7edf\u65b9\u6848 -label.menu.system.vms=\u7cfb\u7edf VM label.menu.system=\u7cfb\u7edf +label.menu.system.vms=\u7cfb\u7edf VM label.menu.templates=\u6a21\u677f label.menu.virtual.appliances=\u865a\u62df\u8bbe\u5907 label.menu.virtual.resources=\u865a\u62df\u8d44\u6e90 @@ -805,13 +891,16 @@ label.menu.volumes=\u5377 label.migrate.instance.to.host=\u5c06\u5b9e\u4f8b\u8fc1\u79fb\u5230\u5176\u4ed6\u4e3b\u673a label.migrate.instance.to.ps=\u5c06\u5b9e\u4f8b\u8fc1\u79fb\u5230\u5176\u4ed6\u4e3b\u5b58\u50a8 label.migrate.instance.to=\u8fc1\u79fb\u5b9e\u4f8b\u81f3 +label.migrate.lb.vm=\u8fc1\u79fb LB VM label.migrate.router.to=\u8fc1\u79fb\u8def\u7531\u5668\u81f3 label.migrate.systemvm.to=\u8fc1\u79fb\u7cfb\u7edf VM \u81f3 label.migrate.to.host=\u8fc1\u79fb\u5230\u4e3b\u673a label.migrate.to.storage=\u8fc1\u79fb\u5230\u5b58\u50a8 label.migrate.volume=\u5c06\u5377\u8fc1\u79fb\u5230\u5176\u4ed6\u4e3b\u5b58\u50a8 label.minimum=\u6700\u5c0f\u503c +label.min.instances=\u6700\u5c0f\u5b9e\u4f8b\u6570 label.minute.past.hour=\u5206 +label.mode=\u6a21\u5f0f label.monday=\u661f\u671f\u4e00 label.monthly=\u6bcf\u6708 label.more.templates=\u66f4\u591a\u6a21\u677f @@ -822,20 +911,25 @@ label.move.up.row=\u5411\u4e0a\u79fb\u52a8\u4e00\u884c label.my.account=\u6211\u7684\u5e10\u6237 label.my.network=\u6211\u7684\u7f51\u7edc label.my.templates=\u6211\u7684\u6a21\u677f +label.name.lower=\u540d\u79f0 label.name.optional=\u540d\u79f0(\u53ef\u9009) label.name=\u540d\u79f0 label.nat.port.range=NAT \u7aef\u53e3\u8303\u56f4 label.netmask=\u7f51\u7edc\u63a9\u7801 +label.netscaler.details=NetScaler \u8be6\u7ec6\u4fe1\u606f label.netScaler=NetScaler +label.network.ACLs=\u7f51\u7edc ACL label.network.ACL.total=\u7f51\u7edc ACL \u603b\u6570 label.network.ACL=\u7f51\u7edc ACL -label.network.ACLs=\u7f51\u7edc ACL +label.network.addVM=\u5c06\u7f51\u7edc\u6dfb\u52a0\u5230 VM +label.network.cidr=\u7f51\u7edc CIDR label.network.desc=\u7f51\u7edc\u63cf\u8ff0 label.network.device.type=\u7f51\u7edc\u8bbe\u5907\u7c7b\u578b label.network.device=\u7f51\u7edc\u8bbe\u5907 label.network.domain.text=\u7f51\u7edc\u57df label.network.domain=\u7f51\u7edc\u57df label.network.id=\u7f51\u7edc ID +label.networking.and.security=\u7f51\u7edc\u8fde\u63a5\u4e0e\u5b89\u5168 label.network.label.display.for.blank.value=\u4f7f\u7528\u9ed8\u8ba4\u7f51\u5173 label.network.limits=\u7f51\u7edc\u9650\u5236 label.network.name=\u7f51\u7edc\u540d\u79f0 @@ -847,81 +941,102 @@ label.network.rate.megabytes=\u7f51\u7edc\u901f\u7387(MB/\u79d2) label.network.rate=\u7f51\u7edc\u901f\u7387(MB/\u79d2) label.network.read=\u7f51\u7edc\u8bfb\u53d6\u91cf label.network.service.providers=\u7f51\u7edc\u670d\u52a1\u63d0\u4f9b\u7a0b\u5e8f +label.networks=\u7f51\u7edc label.network.type=\u7f51\u7edc\u7c7b\u578b -label.network.write=\u7f51\u7edc\u5199\u5165\u91cf label.network=\u7f51\u7edc -label.networking.and.security=\u7f51\u7edc\u8fde\u63a5\u4e0e\u5b89\u5168 -label.networks=\u7f51\u7edc +label.network.write=\u7f51\u7edc\u5199\u5165\u91cf label.new.password=\u65b0\u5bc6\u7801 label.new.project=\u65b0\u5efa\u9879\u76ee -label.new.vm=\u65b0\u5efa VM label.new=\u65b0\u5efa +label.new.vm=\u65b0\u5efa VM label.next=\u4e0b\u4e00\u6b65 label.nexusVswitch=Nexus 1000v +label.nfs=NFS label.nfs.server=NFS \u670d\u52a1\u5668 label.nfs.storage=NFS \u5b58\u50a8 -label.nfs=NFS label.nic.adapter.type=NIC \u9002\u914d\u5668\u7c7b\u578b label.nicira.controller.address=\u63a7\u5236\u5668\u5730\u5740 label.nicira.l3gatewayserviceuuid=L3 Gateway Service UUID -label.nicira.transportzoneuuid=\u4f20\u8f93\u8d44\u6e90\u57df UUID +label.nicira.transportzoneuuid=\u4f20\u8f93\u533a\u57df UUID label.nics=NIC label.no.actions=\u65e0\u53ef\u7528\u64cd\u4f5c label.no.alerts=\u65e0\u6700\u8fd1\u53d1\u51fa\u7684\u8b66\u62a5 label.no.data=\u65e0\u53ef\u663e\u793a\u7684\u6570\u636e label.no.errors=\u65e0\u6700\u8fd1\u51fa\u73b0\u7684\u9519\u8bef +label.no.grouping=(\u4e0d\u5206\u7ec4) label.no.isos=\u65e0\u53ef\u7528 ISO label.no.items=\u65e0\u53ef\u7528\u9879\u76ee -label.no.security.groups=\u65e0\u53ef\u7528\u5b89\u5168\u7ec4 -label.no.thanks=\u4e0d\uff0c\u8c22\u8c22 -label.no=\u5426 label.none=\u65e0 +label.no.security.groups=\u65e0\u53ef\u7528\u5b89\u5168\u7ec4 label.not.found=\u672a\u627e\u5230 +label.no.thanks=\u4e0d\uff0c\u8c22\u8c22 label.notifications=\u901a\u77e5 -label.num.cpu.cores=CPU \u5185\u6838\u6570 +label.no=\u5426 label.number.of.clusters=\u7fa4\u96c6\u6570\u91cf +label.number.of.cpu.sockets=CPU \u63d2\u69fd\u6570 label.number.of.hosts=\u4e3b\u673a\u6570\u91cf label.number.of.pods=\u63d0\u4f9b\u70b9\u6570\u91cf label.number.of.system.vms=\u7cfb\u7edf VM \u6570 label.number.of.virtual.routers=\u865a\u62df\u8def\u7531\u5668\u6570 -label.number.of.zones=\u8d44\u6e90\u57df\u6570\u91cf +label.number.of.zones=\u533a\u57df\u6570\u91cf +label.num.cpu.cores=CPU \u5185\u6838\u6570 label.numretries=\u91cd\u8bd5\u6b21\u6570 label.ocfs2=OCFS2 label.offer.ha=\u63d0\u4f9b\u9ad8\u53ef\u7528\u6027 label.ok=\u786e\u5b9a +label.opendaylight.controllerdetail=OpenDaylight \u63a7\u5236\u5668\u8be6\u7ec6\u4fe1\u606f +label.opendaylight.controller=OpenDaylight \u63a7\u5236\u5668 +label.opendaylight.controllers=OpenDaylight \u63a7\u5236\u5668 +label.openDaylight=OpenDaylight label.optional=\u53ef\u9009 label.order=\u6392\u5e8f label.os.preference=\u64cd\u4f5c\u7cfb\u7edf\u9996\u9009\u9879 label.os.type=\u64cd\u4f5c\u7cfb\u7edf\u7c7b\u578b +label.override.guest.traffic=\u66ff\u4ee3\u6765\u5bbe\u6d41\u91cf +label.override.public.traffic=\u66ff\u4ee3\u516c\u5171\u6d41\u91cf +label.ovm.traffic.label=OVM \u6d41\u91cf\u6807\u7b7e +label.ovs=OVS label.owned.public.ips=\u62e5\u6709\u7684\u516c\u7528 IP \u5730\u5740\u6570 label.owner.account=\u6240\u6709\u8005\u5e10\u6237 label.owner.domain=\u6240\u6709\u8005\u57df +label.palo.alto.details=Palo Alto \u8be6\u7ec6\u4fe1\u606f label.PA.log.profile=Palo Alto \u65e5\u5fd7\u914d\u7f6e\u6587\u4ef6 -label.PA.threat.profile=Palo Alto \u5a01\u80c1\u914d\u7f6e\u6587\u4ef6 +label.PA=Palo Alto label.parent.domain=\u7236\u57df label.password.enabled=\u5df2\u542f\u7528\u5bc6\u7801 +label.password.lower=\u5bc6\u7801 +label.password.reset.confirm=\u5bc6\u7801\u5df2\u91cd\u7f6e\u4e3a label.password=\u5bc6\u7801 +label.PA.threat.profile=Palo Alto \u5a01\u80c1\u914d\u7f6e\u6587\u4ef6 label.path=\u8def\u5f84 label.perfect.forward.secrecy=\u5b8c\u5168\u6b63\u5411\u4fdd\u5bc6 +label.persistent=\u6c38\u4e45 label.physical.network.ID=\u7269\u7406\u7f51\u7edc ID label.physical.network=\u7269\u7406\u7f51\u7edc label.PING.CIFS.password=PING CIFS \u5bc6\u7801 label.PING.CIFS.username=PING CIFS \u7528\u6237\u540d label.PING.dir=PING \u76ee\u5f55 label.PING.storage.IP=PING \u5b58\u50a8 IP +label.planner.mode=\u89c4\u5212\u5668\u6a21\u5f0f label.please.specify.netscaler.info=\u8bf7\u6307\u5b9a Netscaler \u4fe1\u606f label.please.wait=\u8bf7\u7a0d\u5019 label.plugin.details=\u63d2\u4ef6\u8be6\u7ec6\u4fe1\u606f label.plugins=\u63d2\u4ef6 +label.pod.dedicated=\u63d0\u4f9b\u70b9\u5df2\u4e13\u7528 label.pod.name=\u63d0\u4f9b\u70b9\u540d\u79f0 -label.pod=\u63d0\u4f9b\u70b9 label.pods=\u63d0\u4f9b\u70b9 +label.pod=\u63d0\u4f9b\u70b9 +label.polling.interval.sec=\u8f6e\u8be2\u65f6\u95f4\u95f4\u9694(\u79d2) +label.portable.ip.range.details=\u53ef\u79fb\u690d IP \u8303\u56f4\u8be6\u7ec6\u4fe1\u606f +label.portable.ip.ranges=\u53ef\u79fb\u690d IP \u8303\u56f4 +label.portable.ips=\u53ef\u79fb\u690d IP label.port.forwarding.policies=\u7aef\u53e3\u8f6c\u53d1\u7b56\u7565 label.port.forwarding=\u7aef\u53e3\u8f6c\u53d1 label.port.range=\u7aef\u53e3\u8303\u56f4 +label.port=\u7aef\u53e3 label.PreSetup=PreSetup -label.prev=\u4e0a\u4e00\u9875 label.previous=\u4e0a\u4e00\u6b65 +label.prev=\u4e0a\u4e00\u9875 label.primary.allocated=\u5df2\u5206\u914d\u7684\u4e3b\u5b58\u50a8 label.primary.network=\u4e3b\u7f51\u7edc label.primary.storage.count=\u4e3b\u5b58\u50a8\u6c60 @@ -931,69 +1046,98 @@ label.primary.used=\u5df2\u4f7f\u7528\u7684\u4e3b\u5b58\u50a8 label.private.Gateway=\u4e13\u7528\u7f51\u5173 label.private.interface=\u4e13\u7528\u63a5\u53e3 label.private.ip.range=\u4e13\u7528 IP \u8303\u56f4 -label.private.ip=\u4e13\u7528 IP \u5730\u5740 label.private.ips=\u4e13\u7528 IP \u5730\u5740 +label.private.ip=\u4e13\u7528 IP \u5730\u5740 +label.privatekey=PKCS\#8 \u79c1\u94a5 label.private.network=\u4e13\u7528\u7f51\u7edc label.private.port=\u4e13\u7528\u7aef\u53e3 -label.private.zone=\u4e13\u7528\u8d44\u6e90\u57df -label.privatekey=PKCS\#8 \u79c1\u94a5 +label.private.zone=\u4e13\u7528\u533a\u57df +label.profile=\u914d\u7f6e\u6587\u4ef6 label.project.dashboard=\u9879\u76ee\u63a7\u5236\u677f label.project.id=\u9879\u76ee ID label.project.invite=\u9080\u8bf7\u52a0\u5165\u9879\u76ee label.project.name=\u9879\u76ee\u540d\u79f0 -label.project.view=\u9879\u76ee\u89c6\u56fe -label.project=\u9879\u76ee label.projects=\u9879\u76ee +label.project=\u9879\u76ee +label.project.view=\u9879\u76ee\u89c6\u56fe label.protocol=\u534f\u8bae label.providers=\u63d0\u4f9b\u7a0b\u5e8f +label.provider=\u63d0\u4f9b\u7a0b\u5e8f label.public.interface=\u516c\u7528\u63a5\u53e3 -label.public.ip=\u516c\u7528 IP \u5730\u5740 label.public.ips=\u516c\u7528 IP \u5730\u5740 +label.public.ip=\u516c\u7528 IP \u5730\u5740 +label.public.load.balancer.provider=\u516c\u7528\u8d1f\u8f7d\u5e73\u8861\u5668\u63d0\u4f9b\u7a0b\u5e8f label.public.network=\u516c\u7528\u7f51\u7edc label.public.port=\u516c\u7528\u7aef\u53e3 -label.public.traffic=\u516c\u5171\u6d41\u91cf -label.public.zone=\u516c\u7528\u8d44\u6e90\u57df +label.public.traffic=\u516c\u5171\u901a\u4fe1 +label.public.traffic.vswitch.name=\u516c\u5171\u6d41\u91cf\u865a\u62df\u4ea4\u6362\u673a\u540d\u79f0 +label.public.traffic.vswitch.type=\u516c\u5171\u6d41\u91cf\u865a\u62df\u4ea4\u6362\u673a\u7c7b\u578b label.public=\u516c\u7528 +label.public.zone=\u516c\u7528\u533a\u57df label.purpose=\u76ee\u7684 label.Pxe.server.type=Pxe \u670d\u52a1\u5668\u7c7b\u578b +label.qos.type=QoS \u7c7b\u578b label.quickview=\u5feb\u901f\u67e5\u770b +label.quiesce.vm=\u9759\u9ed8 VM +label.quiet.time.sec=\u5b89\u9759\u65f6\u95f4(\u79d2) +label.rbd.id=Cephx \u7528\u6237 +label.rbd.monitor=Ceph \u76d1\u89c6\u5668 +label.rbd.pool=Ceph \u6c60 +label.rbd=RBD +label.rbd.secret=Cephx \u5bc6\u94a5 label.reboot=\u91cd\u65b0\u542f\u52a8 label.recent.errors=\u6700\u8fd1\u51fa\u73b0\u7684\u9519\u8bef label.redundant.router.capability=\u5197\u4f59\u8def\u7531\u5668\u529f\u80fd label.redundant.router=\u5197\u4f59\u8def\u7531\u5668 label.redundant.state=\u5197\u4f59\u72b6\u6001 +label.refresh.blades=\u5237\u65b0\u5200\u7247\u5f0f\u670d\u52a1\u5668 label.refresh=\u5237\u65b0 -label.region=\u5730\u7406\u533a\u57df +label.region=\u533a\u57df label.related=\u76f8\u5173\u8054 +label.release.account.lowercase=\u4ece\u5e10\u6237\u4e2d\u91ca\u653e +label.release.account=\u4ece\u5e10\u6237\u4e2d\u91ca\u653e +label.release.dedicated.cluster=\u91ca\u653e\u4e13\u7528\u7fa4\u96c6 +label.release.dedicated.host=\u91ca\u653e\u4e13\u7528\u4e3b\u673a +label.release.dedicated.pod=\u91ca\u653e\u4e13\u7528\u63d0\u4f9b\u70b9 +label.release.dedicated.vlan.range=\u91ca\u653e\u4e13\u7528 VLAN \u8303\u56f4 +label.release.dedicated.zone=\u91ca\u653e\u4e13\u7528\u8d44\u6e90\u57df label.remind.later=\u4ee5\u540e\u63d0\u9192\u6211 label.remove.ACL=\u5220\u9664 ACL label.remove.egress.rule=\u5220\u9664\u51fa\u53e3\u89c4\u5219 label.remove.from.load.balancer=\u6b63\u5728\u4ece\u8d1f\u8f7d\u5e73\u8861\u5668\u4e2d\u5220\u9664\u5b9e\u4f8b label.remove.ingress.rule=\u5220\u9664\u5165\u53e3\u89c4\u5219 label.remove.ip.range=\u5220\u9664 IP \u8303\u56f4 +label.remove.ldap=\u5220\u9664 LDAP +label.remove.network.offering=\u5220\u9664\u7f51\u7edc\u65b9\u6848 label.remove.pf=\u5220\u9664\u7aef\u53e3\u8f6c\u53d1\u89c4\u5219 label.remove.project.account=\u4ece\u9879\u76ee\u4e2d\u5220\u9664\u5e10\u6237 -label.remove.region=\u5220\u9664\u5730\u7406\u533a\u57df +label.remove.region=\u79fb\u9664\u533a\u57df label.remove.rule=\u5220\u9664\u89c4\u5219 label.remove.static.nat.rule=\u5220\u9664\u9759\u6001 NAT \u89c4\u5219 label.remove.static.route=\u5220\u9664\u9759\u6001\u8def\u7531 label.remove.tier=\u5220\u9664\u5c42 label.remove.vm.from.lb=\u4ece\u8d1f\u8f7d\u5e73\u8861\u5668\u89c4\u5219\u4e2d\u5220\u9664 VM +label.remove.vmware.datacenter=\u5220\u9664 VMware \u6570\u636e\u4e2d\u5fc3 label.remove.vpc=\u5220\u9664 VPC -label.removing.user=\u6b63\u5728\u5220\u9664\u7528\u6237 label.removing=\u6b63\u5728\u5220\u9664 +label.removing.user=\u6b63\u5728\u5220\u9664\u7528\u6237 +label.reource.id=\u8d44\u6e90 ID label.required=\u5fc5\u586b\u9879 +label.requires.upgrade=\u9700\u8981\u5347\u7ea7 +label.reserved.ip.range=\u9884\u7559 IP \u8303\u56f4 label.reserved.system.gateway=\u9884\u7559\u7684\u7cfb\u7edf\u7f51\u5173 label.reserved.system.ip=\u9884\u7559\u7684\u7cfb\u7edf IP label.reserved.system.netmask=\u9884\u7559\u7684\u7cfb\u7edf\u7f51\u7edc\u63a9\u7801 +label.resetVM=\u91cd\u7f6e VM label.reset.VPN.connection=\u91cd\u7f6e VPN \u8fde\u63a5 label.resize.new.offering.id=\u65b0\u65b9\u6848 label.resize.new.size=\u65b0\u5efa\u5927\u5c0f(GB) label.resize.shrink.ok=\u662f\u5426\u786e\u5b9e\u8981\u7f29\u5c0f\u5377\u5927\u5c0f label.resource.limits=\u8d44\u6e90\u9650\u5236 +label.resource.name=\u8d44\u6e90\u540d\u79f0 label.resource.state=\u8d44\u6e90\u72b6\u6001 -label.resource=\u8d44\u6e90 label.resources=\u8d44\u6e90 +label.resource=\u8d44\u6e90 label.restart.network=\u91cd\u65b0\u542f\u52a8\u7f51\u7edc label.restart.required=\u9700\u8981\u91cd\u65b0\u542f\u52a8 label.restart.vpc=\u91cd\u65b0\u542f\u52a8 VPC @@ -1003,7 +1147,11 @@ label.revoke.project.invite=\u64a4\u9500\u9080\u8bf7 label.role=\u89d2\u8272 label.root.disk.controller=\u6839\u78c1\u76d8\u63a7\u5236\u5668 label.root.disk.offering=\u6839\u78c1\u76d8\u65b9\u6848 +label.root.disk.size=\u6839\u78c1\u76d8\u5927\u5c0f label.round.robin=\u8f6e\u8be2\u7b97\u6cd5 +label.router.vm.scaled.up=\u5df2\u6269\u5c55\u8def\u7531\u5668 VM +label.routing=\u6b63\u5728\u8def\u7531 +label.rule.number=\u89c4\u5219\u7f16\u53f7 label.rules=\u89c4\u5219 label.running.vms=\u6b63\u5728\u8fd0\u884c\u7684 VM label.s3.access_key=\u8bbf\u95ee\u5bc6\u94a5 @@ -1011,6 +1159,8 @@ label.s3.bucket=\u5b58\u50a8\u6876 label.s3.connection_timeout=\u8fde\u63a5\u8d85\u65f6 label.s3.endpoint=\u7aef\u70b9 label.s3.max_error_retry=\u6700\u5927\u9519\u8bef\u91cd\u8bd5\u6b21\u6570 +label.s3.nfs.path=S3 NFS \u8def\u5f84 +label.s3.nfs.server=S3 NFS \u670d\u52a1\u5668 label.s3.secret_key=\u5bc6\u94a5 label.s3.socket_timeout=\u5957\u63a5\u5b57\u8d85\u65f6 label.s3.use_https=\u4f7f\u7528 HTTPS @@ -1020,67 +1170,84 @@ label.save=\u4fdd\u5b58 label.saving.processing=\u6b63\u5728\u4fdd\u5b58... label.scope=\u8303\u56f4 label.search=\u641c\u7d22 -label.secondary.storage.count=\u4e8c\u7ea7\u5b58\u50a8\u6c60 -label.secondary.storage.limits=\u4e8c\u7ea7\u5b58\u50a8\u9650\u5236(GiB) -label.secondary.storage.vm=\u4e8c\u7ea7\u5b58\u50a8 VM -label.secondary.storage=\u4e8c\u7ea7\u5b58\u50a8 -label.secondary.used=\u5df2\u4f7f\u7528\u7684\u4e8c\u7ea7\u5b58\u50a8 +label.secondary.isolated.vlan.id=\u4e8c\u7ea7\u9694\u79bb VLAN ID +label.secondary.staging.store.details=\u4e8c\u7ea7\u6682\u5b58\u5b58\u50a8\u8be6\u7ec6\u4fe1\u606f +label.secondary.staging.store=\u4e8c\u7ea7\u6682\u5b58\u5b58\u50a8 +label.secondary.storage.count=\u8f85\u52a9\u5b58\u50a8\u6c60 +label.secondary.storage.details=\u4e8c\u7ea7\u5b58\u50a8\u8be6\u7ec6\u4fe1\u606f +label.secondary.storage.limits=\u8f85\u52a9\u5b58\u50a8\u9650\u5236(GiB) +label.secondary.storage=\u8f85\u52a9\u5b58\u50a8 +label.secondary.storage.vm=\u8f85\u52a9\u5b58\u50a8 VM +label.secondary.used=\u5df2\u4f7f\u7528\u7684\u8f85\u52a9\u5b58\u50a8 label.secret.key=\u5bc6\u94a5 label.security.group.name=\u5b89\u5168\u7ec4\u540d\u79f0 -label.security.group=\u5b89\u5168\u7ec4 label.security.groups.enabled=\u5df2\u542f\u7528\u5b89\u5168\u7ec4 label.security.groups=\u5b89\u5168\u7ec4 -label.select-view=\u9009\u62e9\u89c6\u56fe +label.security.group=\u5b89\u5168\u7ec4 label.select.a.template=\u9009\u62e9\u4e00\u4e2a\u6a21\u677f -label.select.a.zone=\u9009\u62e9\u4e00\u4e2a\u8d44\u6e90\u57df +label.select.a.zone=\u9009\u62e9\u4e00\u4e2a\u533a\u57df label.select.instance.to.attach.volume.to=\u9009\u62e9\u8981\u5c06\u5377\u9644\u52a0\u5230\u7684\u5b9e\u4f8b label.select.instance=\u9009\u62e9\u5b9e\u4f8b label.select.iso.or.template=\u9009\u62e9 ISO \u6216\u6a21\u677f label.select.offering=\u9009\u62e9\u65b9\u6848 label.select.project=\u9009\u62e9\u9879\u76ee +label.select.template=\u9009\u62e9\u6a21\u677f label.select.tier=\u9009\u62e9\u5c42 -label.select.vm.for.static.nat=\u4e3a\u9759\u6001 NAT \u9009\u62e9 VM label.select=\u9009\u62e9 +label.select-view=\u9009\u62e9\u89c6\u56fe +label.select.vm.for.static.nat=\u4e3a\u9759\u6001 NAT \u9009\u62e9 VM label.sent=\u5df2\u53d1\u9001 label.server=\u670d\u52a1\u5668 label.service.capabilities=\u670d\u52a1\u529f\u80fd label.service.offering=\u670d\u52a1\u65b9\u6848 +label.service.state=\u670d\u52a1\u72b6\u6001 +label.services=\u670d\u52a1 label.session.expired=\u4f1a\u8bdd\u5df2\u8fc7\u671f -label.set.up.zone.type=\u8bbe\u7f6e\u8d44\u6e90\u57df\u7c7b\u578b +label.set.default.NIC=\u8bbe\u7f6e\u9ed8\u8ba4 NIC +label.settings=\u8bbe\u7f6e label.setup.network=\u8bbe\u7f6e\u7f51\u7edc -label.setup.zone=\u8bbe\u7f6e\u8d44\u6e90\u57df label.setup=\u8bbe\u7f6e -label.shared=\u5df2\u5171\u4eab +label.set.up.zone.type=\u8bbe\u7f6e\u533a\u57df\u7c7b\u578b +label.setup.zone=\u8bbe\u7f6e\u533a\u57df label.SharedMountPoint=SharedMountPoint +label.shared=\u5df2\u5171\u4eab +label.show.advanced.settings=\u663e\u793a\u9ad8\u7ea7\u8bbe\u7f6e label.show.ingress.rule=\u663e\u793a\u5165\u53e3\u89c4\u5219 label.shutdown.provider=\u5173\u95ed\u63d0\u4f9b\u7a0b\u5e8f label.site.to.site.VPN=\u70b9\u5bf9\u70b9 VPN label.size=\u5927\u5c0f label.skip.guide=\u6211\u4ee5\u524d\u4f7f\u7528\u8fc7 CloudStack\uff0c\u8df3\u8fc7\u6b64\u6307\u5357 +label.smb.domain=SMB \u57df +label.smb.password=SMB \u5bc6\u7801 +label.smb.username=SMB \u7528\u6237\u540d label.snapshot.limits=\u5feb\u7167\u9650\u5236 label.snapshot.name=\u5feb\u7167\u540d\u79f0 -label.snapshot.s=\u5feb\u7167 label.snapshot.schedule=\u8bbe\u7f6e\u91cd\u73b0\u5feb\u7167 -label.snapshot=\u5feb\u7167 +label.snapshot.s=\u5feb\u7167 label.snapshots=\u5feb\u7167 +label.snapshot=\u5feb\u7167 +label.SNMP.community=SNMP \u793e\u533a +label.SNMP.port=SNMP \u7aef\u53e3 +label.sockets=CPU \u63d2\u69fd label.source.nat=\u6e90 NAT label.source=\u6e90\u7b97\u6cd5 label.specify.IP.ranges=\u6307\u5b9a IP \u8303\u56f4 label.specify.vlan=\u6307\u5b9a VLAN label.specify.vxlan=\u6307\u5b9a VXLAN -label.SR.name=SR \u540d\u79f0\u6807\u7b7e +label.SR.name = SR \u540d\u79f0\u6807\u7b7e +label.srx.details=SRX \u8be6\u7ec6\u4fe1\u606f label.srx=SRX -label.PA=Palo Alto label.start.IP=\u8d77\u59cb IP +label.start.lb.vm=\u542f\u52a8 LB VM label.start.port=\u8d77\u59cb\u7aef\u53e3 label.start.reserved.system.IP=\u8d77\u59cb\u9884\u7559\u7cfb\u7edf IP label.start.vlan=\u8d77\u59cb VLAN -label.start.vxlan=\u542f\u52a8 VXLAN +label.start.vxlan=\u8d77\u59cb VXLAN label.state=\u72b6\u6001 label.static.nat.enabled=\u5df2\u542f\u7528\u9759\u6001 NAT label.static.nat.to=\u9759\u6001 NAT \u76ee\u6807 -label.static.nat.vm.details=\u9759\u6001 NAT VM \u8be6\u60c5 label.static.nat=\u9759\u6001 NAT +label.static.nat.vm.details=\u9759\u6001 NAT VM \u8be6\u60c5 label.statistics=\u7edf\u8ba1\u6570\u636e label.status=\u72b6\u6001 label.step.1.title=\u6b65\u9aa4 1\: \u9009\u62e9\u4e00\u4e2a\u6a21\u677f @@ -1106,79 +1273,93 @@ label.sticky.postonly=postonly label.sticky.prefix=prefix label.sticky.request-learn=request-learn label.sticky.tablesize=\u8868\u5927\u5c0f -label.stop=\u505c\u6b62 +label.stop.lb.vm=\u505c\u6b62 LB VM label.stopped.vms=\u5df2\u505c\u6b62\u7684 VM +label.stop=\u505c\u6b62 label.storage.tags=\u5b58\u50a8\u6807\u7b7e -label.storage.traffic=\u5b58\u50a8\u6d41\u91cf +label.storage.traffic=\u5b58\u50a8\u901a\u4fe1 label.storage.type=\u5b58\u50a8\u7c7b\u578b -label.qos.type=QoS \u7c7b\u578b -label.cache.mode=\u5199\u5165\u7f13\u5b58\u7c7b\u578b label.storage=\u5b58\u50a8 label.subdomain.access=\u5b50\u57df\u8bbf\u95ee -label.submit=\u63d0\u4ea4 label.submitted.by=[\u63d0\u4ea4\u8005\: ] +label.submit=\u63d0\u4ea4 label.succeeded=\u6210\u529f label.sunday=\u661f\u671f\u65e5 label.super.cidr.for.guest.networks=\u6765\u5bbe\u7f51\u7edc\u7684\u8d85\u7ea7 CIDR label.supported.services=\u652f\u6301\u7684\u670d\u52a1 label.supported.source.NAT.type=\u652f\u6301\u7684\u6e90 NAT \u7c7b\u578b label.suspend.project=\u6682\u505c\u9879\u76ee +label.switch.type=\u4ea4\u6362\u673a\u7c7b\u578b label.system.capacity=\u7cfb\u7edf\u5bb9\u91cf +label.system.offering.for.router=\u8def\u7531\u5668\u7684\u7cfb\u7edf\u65b9\u6848 label.system.offering=\u7cfb\u7edf\u65b9\u6848 label.system.service.offering=\u7cfb\u7edf\u670d\u52a1\u65b9\u6848 +label.system.vm.details=\u7cfb\u7edf VM \u8be6\u7ec6\u4fe1\u606f +label.system.vm.scaled.up=\u5df2\u6269\u5c55\u7cfb\u7edf VM +label.system.vms=\u7cfb\u7edf VM label.system.vm.type=\u7cfb\u7edf VM \u7c7b\u578b label.system.vm=\u7cfb\u7edf VM -label.system.vms=\u7cfb\u7edf VM label.system.wide.capacity=\u6574\u4e2a\u7cfb\u7edf\u7684\u5bb9\u91cf label.tagged=\u5df2\u6807\u8bb0 +label.tag.key=\u6807\u8bb0\u5bc6\u94a5 label.tags=\u6807\u7b7e +label.tag.value=\u6807\u8bb0\u503c label.target.iqn=\u76ee\u6807 IQN label.task.completed=\u5df2\u5b8c\u6210\u4efb\u52a1 label.template.limits=\u6a21\u677f\u9650\u5236 label.template=\u6a21\u677f label.TFTP.dir=TFTP \u76ee\u5f55 +label.tftp.root.directory=Tftp \u6839\u76ee\u5f55 label.theme.default=\u9ed8\u8ba4\u4e3b\u9898 label.theme.grey=\u81ea\u5b9a\u4e49 - \u7070\u8272 label.theme.lightblue=\u81ea\u5b9a\u4e49 - \u6de1\u84dd\u8272 label.thursday=\u661f\u671f\u56db label.tier.details=\u5c42\u8be6\u7ec6\u4fe1\u606f label.tier=\u5c42 -label.time.zone=\u65f6\u533a -label.time=\u65f6\u95f4 -label.timeout.in.second=\u8d85\u65f6(\u79d2) +label.timeout.in.second = \u8d85\u65f6(\u79d2) label.timeout=\u8d85\u65f6 +label.time=\u65f6\u95f4 +label.time.zone=\u65f6\u533a label.timezone=\u65f6\u533a label.token=\u4ee4\u724c -label.total.CPU=CPU \u603b\u91cf label.total.cpu=CPU \u603b\u91cf +label.total.CPU=CPU \u603b\u91cf label.total.hosts=\u603b\u4e3b\u673a\u6570 label.total.memory=\u5185\u5b58\u603b\u91cf label.total.of.ip=\u603b IP \u5730\u5740\u6570 label.total.of.vm=\u603b VM \u6570 label.total.storage=\u5b58\u50a8\u603b\u91cf +label.total.virtual.routers=\u865a\u62df\u8def\u7531\u5668\u603b\u6570 +label.total.virtual.routers.upgrade=\u9700\u8981\u5347\u7ea7\u7684\u865a\u62df\u8def\u7531\u5668\u603b\u6570 label.total.vms=\u603b VM \u6570 -label.traffic.label=\u6d41\u91cf\u6807\u7b7e -label.traffic.type=\u6d41\u91cf\u7c7b\u578b -label.traffic.types=\u6d41\u91cf\u7c7b\u578b +label.traffic.label=\u901a\u4fe1\u6807\u7b7e +label.traffic.types=\u901a\u4fe1\u7c7b\u578b +label.traffic.type=\u901a\u4fe1\u7c7b\u578b label.tuesday=\u661f\u671f\u4e8c label.type.id=\u7c7b\u578b ID +label.type.lower=\u7c7b\u578b label.type=\u7c7b\u578b +label.ucs=UCS label.unavailable=\u4e0d\u53ef\u7528 label.unlimited=\u65e0\u9650\u5236 label.untagged=\u5df2\u53d6\u6d88\u6807\u8bb0 label.update.project.resources=\u66f4\u65b0\u9879\u76ee\u8d44\u6e90 -label.update.ssl.cert=SSL \u8bc1\u4e66 -label.update.ssl=SSL \u8bc1\u4e66 +label.update.ssl.cert= SSL \u8bc1\u4e66 +label.update.ssl= SSL \u8bc1\u4e66 label.updating=\u6b63\u5728\u66f4\u65b0 -label.upload.volume=\u4e0a\u8f7d\u5377 +label.upgrade.required=\u9700\u8981\u5347\u7ea7 +label.upgrade.router.newer.template=\u5347\u7ea7\u8def\u7531\u5668\u4ee5\u4f7f\u7528\u66f4\u65b0\u7684\u6a21\u677f label.upload=\u4e0a\u8f7d +label.upload.volume=\u4e0a\u8f7d\u5377 label.url=URL label.usage.interface=\u4f7f\u7528\u754c\u9762 -label.use.vm.ip=\u4f7f\u7528 VM IP\: label.used=\u5df2\u4f7f\u7528 -label.user=\u7528\u6237 +label.user.data=\u7528\u6237\u6570\u636e +label.username.lower=\u7528\u6237\u540d label.username=\u7528\u6237\u540d label.users=\u7528\u6237 +label.user=\u7528\u6237 +label.use.vm.ip=\u4f7f\u7528 VM IP\: label.value=\u503c label.vcdcname=vCenter DC \u540d\u79f0 label.vcenter.cluster=vCenter \u7fa4\u96c6 @@ -1187,62 +1368,82 @@ label.vcenter.datastore=vCenter \u6570\u636e\u5b58\u50a8 label.vcenter.host=vCenter \u4e3b\u673a label.vcenter.password=vCenter \u5bc6\u7801 label.vcenter.username=vCenter \u7528\u6237\u540d +label.vcenter=vCenter label.vcipaddress=vCenter IP \u5730\u5740 label.version=\u7248\u672c label.view.all=\u67e5\u770b\u5168\u90e8 label.view.console=\u67e5\u770b\u63a7\u5236\u53f0 +label.viewing=\u67e5\u770b label.view.more=\u67e5\u770b\u66f4\u591a +label.view.secondary.ips=\u67e5\u770b\u8f85\u52a9 IP label.view=\u67e5\u770b -label.viewing=\u67e5\u770b -label.virtual.appliance=\u865a\u62df\u8bbe\u5907 +label.virtual.appliance.details=\u865a\u62df\u8bbe\u5907\u8be6\u7ec6\u4fe1\u606f label.virtual.appliances=\u865a\u62df\u8bbe\u5907 +label.virtual.appliance=\u865a\u62df\u8bbe\u5907 label.virtual.machines=\u865a\u62df\u673a +label.virtual.networking=\u865a\u62df\u7f51\u7edc\u8fde\u63a5 label.virtual.network=\u865a\u62df\u7f51\u7edc -label.virtual.router=\u865a\u62df\u8def\u7531\u5668 +label.virtual.routers.group.account=\u865a\u62df\u8def\u7531\u5668(\u6309\u5e10\u6237\u5206\u7ec4) +label.virtual.routers.group.cluster=\u865a\u62df\u8def\u7531\u5668(\u6309\u7fa4\u96c6\u5206\u7ec4) +label.virtual.routers.group.pod=\u865a\u62df\u8def\u7531\u5668(\u6309\u63d0\u4f9b\u70b9\u5206\u7ec4) +label.virtual.routers.group.zone=\u865a\u62df\u8def\u7531\u5668(\u6309\u8d44\u6e90\u57df\u5206\u7ec4) label.virtual.routers=\u865a\u62df\u8def\u7531\u5668 -label.vlan.id=VLAN/VNI ID -label.vlan.range=VLAN/VNI \u8303\u56f4 -label.vlan=VLAN/VNI -label.vnet=VLAN/VNI -label.vnet.id=VLAN/VNI ID -label.vxlan.id=VXLAN ID -label.vxlan.range=VXLAN \u8303\u56f4 -label.vxlan=VXLAN +label.virtual.router=\u865a\u62df\u8def\u7531\u5668 +label.vlan.id=VLAN ID +label.vlan.range.details=VLAN \u8303\u56f4\u8be6\u7ec6\u4fe1\u606f +label.vlan.ranges=VLAN \u8303\u56f4 +label.vlan.range=VLAN \u8303\u56f4 +label.vlan=VLAN +label.vlan.vni.ranges=VLAN/VNI \u8303\u56f4 +label.vlan.vni.range=VLAN/VNI \u8303\u56f4 label.vm.add=\u6dfb\u52a0\u5b9e\u4f8b label.vm.destroy=\u9500\u6bc1 label.vm.display.name=VM \u663e\u793a\u540d\u79f0 -label.vm.name=VM \u540d\u79f0 -label.vm.reboot=\u91cd\u65b0\u542f\u52a8 -label.vm.start=\u542f\u52a8 -label.vm.state=VM \u72b6\u6001 -label.vm.stop=\u505c\u6b62 label.VMFS.datastore=VMFS \u6570\u636e\u5b58\u50a8 label.vmfs=VMFS +label.vm.name=VM \u540d\u79f0 +label.vm.password=VM \u7684\u5bc6\u7801 +label.vm.reboot=\u91cd\u65b0\u542f\u52a8 label.VMs.in.tier=\u5c42\u4e2d\u7684 VM -label.vms=VM label.vmsnapshot.current=\u6700\u65b0\u7248\u672c label.vmsnapshot.memory=\u5feb\u7167\u5185\u5b58 label.vmsnapshot.parentname=\u7236\u540d\u79f0 label.vmsnapshot.type=\u7c7b\u578b label.vmsnapshot=VM \u5feb\u7167 -label.vmware.traffic.label=VMware \u6d41\u91cf\u6807\u7b7e -label.volgroup=\u5377\u7ec4 -label.volume.limits=\u5377\u9650\u5236 +label.vm.start=\u542f\u52a8 +label.vm.state=VM \u72b6\u6001 +label.vm.stop=\u505c\u6b62 +label.vms=VM +label.vmware.datacenter.id=VMware \u6570\u636e\u4e2d\u5fc3 ID +label.vmware.datacenter.name=VMware \u6570\u636e\u4e2d\u5fc3\u540d\u79f0 +label.vmware.datacenter.vcenter=VMware \u6570\u636e\u4e2d\u5fc3 vCenter +label.vmware.traffic.label=VMware \u901a\u4fe1\u6807\u7b7e +label.vnet.id=VLAN ID +label.vnet=VLAN +label.vnmc.devices=VNMC \u8bbe\u5907 +label.volatile=\u53ef\u53d8 +label.volgroup=\u5377\u7ec4 +label.volume.limits=\u5377\u9650\u5236 label.volume.name=\u5377\u540d\u79f0 -label.volume=\u5377 label.volumes=\u5377 +label.volume=\u5377 label.vpc.id=VPC ID +label.VPC.limits=VPC \u9650\u5236 label.VPC.router.details=VPC \u8def\u7531\u5668\u8be6\u7ec6\u4fe1\u606f +label.vpc.virtual.router=VPC \u865a\u62df\u8def\u7531\u5668 label.vpc=VPC label.VPN.connection=VPN \u8fde\u63a5 -label.VPN.customer.gateway=VPN \u5ba2\u6237\u7f51\u5173 label.vpn.customer.gateway=VPN \u5ba2\u6237\u7f51\u5173 +label.VPN.customer.gateway=VPN \u5ba2\u6237\u7f51\u5173 label.VPN.gateway=VPN \u7f51\u5173 label.vpn=VPN label.vsmctrlvlanid=\u63a7\u5236 VLAN ID label.vsmpktvlanid=\u6570\u636e\u5305 VLAN ID label.vsmstoragevlanid=\u5b58\u50a8 VLAN ID label.vsphere.managed=\u7531 vSphere \u7ba1\u7406 +label.vxlan.id=VXLAN ID +label.vxlan.range=VXLAN Range +label.vxlan=VXLAN label.waiting=\u6b63\u5728\u7b49\u5f85 label.warn=\u8b66\u544a label.wednesday=\u661f\u671f\u4e09 @@ -1250,240 +1451,32 @@ label.weekly=\u6bcf\u5468 label.welcome.cloud.console=\u6b22\u8fce\u4f7f\u7528\u7ba1\u7406\u63a7\u5236\u53f0 label.welcome=\u6b22\u8fce label.what.is.cloudstack=\u4ec0\u4e48\u662f CloudStack&\#8482? +label.xenserver.tools.version.61.plus=XenServer Tools \u7248\u672c 6.1\\+ +label.Xenserver.Tools.Version61plus=XenServer Tools \u7248\u672c 6.1\\+ label.xen.traffic.label=XenServer \u6d41\u91cf\u6807\u7b7e label.yes=\u662f -label.zone.details=\u8d44\u6e90\u57df\u8be6\u7ec6\u4fe1\u606f -label.zone.id=\u8d44\u6e90\u57df ID -label.zone.name=\u8d44\u6e90\u57df\u540d\u79f0 +label.zone.dedicated=\u8d44\u6e90\u57df\u5df2\u4e13\u7528 +label.zone.details=\u533a\u57df\u8be6\u60c5 +label.zone.id=\u533a\u57df ID +label.zone.lower=\u8d44\u6e90\u57df +label.zone.name=\u533a\u57df\u540d\u79f0 label.zone.step.1.title=\u6b65\u9aa4 1\: \u9009\u62e9\u4e00\u4e2a\u7f51\u7edc -label.zone.step.2.title=\u6b65\u9aa4 2\: \u6dfb\u52a0\u4e00\u4e2a\u8d44\u6e90\u57df +label.zone.step.2.title=\u6b65\u9aa4 2\: \u6dfb\u52a0\u4e00\u4e2a\u533a\u57df label.zone.step.3.title=\u6b65\u9aa4 3\: \u6dfb\u52a0\u4e00\u4e2a\u63d0\u4f9b\u70b9 label.zone.step.4.title=\u6b65\u9aa4 4\: \u6dfb\u52a0\u4e00\u4e2a IP \u8303\u56f4 -label.zone.type=\u8d44\u6e90\u57df\u7c7b\u578b -label.zone.wide=\u6574\u4e2a\u8d44\u6e90\u57df -label.zone=\u8d44\u6e90\u57df -label.zones=\u8d44\u6e90\u57df -label.zoneWizard.trafficType.guest=\u6765\u5bbe\: \u6700\u7ec8\u7528\u6237\u865a\u62df\u673a\u4e4b\u95f4\u7684\u6d41\u91cf -label.zoneWizard.trafficType.management=\u7ba1\u7406\: CloudStack \u7684\u5185\u90e8\u8d44\u6e90(\u5305\u62ec\u4e0e\u7ba1\u7406\u670d\u52a1\u5668\u901a\u4fe1\u7684\u4efb\u4f55\u7ec4\u4ef6\uff0c\u4f8b\u5982\u4e3b\u673a\u548c CloudStack \u7cfb\u7edf VM)\u4e4b\u95f4\u7684\u6d41\u91cf -label.zoneWizard.trafficType.public=\u516c\u5171\: \u4e91\u4e2d Internet \u4e0e\u865a\u62df\u673a\u4e4b\u95f4\u7684\u6d41\u91cf\u3002 -label.zoneWizard.trafficType.storage=\u5b58\u50a8\: \u4e3b\u5b58\u50a8\u670d\u52a1\u5668\u4e0e\u4e8c\u7ea7\u5b58\u50a8\u670d\u52a1\u5668(\u4f8b\u5982 VM \u6a21\u677f\u4e0e\u5feb\u7167)\u4e4b\u95f4\u7684\u6d41\u91cf -label.ldap.group.name=LDAP \u7ec4 -label.password.reset.confirm=\u5bc6\u7801\u5df2\u91cd\u7f6e\u4e3a -label.provider=\u63d0\u4f9b\u7a0b\u5e8f -label.resetVM=\u91cd\u7f6e VM -label.openDaylight=OpenDaylight -label.assign.instance.another=\u5c06\u5b9e\u4f8b\u5206\u914d\u7ed9\u5176\u4ed6\u5e10\u6237 -label.network.addVM=\u5c06\u7f51\u7edc\u6dfb\u52a0\u5230 VM -label.set.default.NIC=\u8bbe\u7f6e\u9ed8\u8ba4 NIC -label.Xenserver.Tools.Version61plus=XenServer Tools \u7248\u672c 6.1\+ -label.dynamically.scalable=\u53ef\u52a8\u6001\u6269\u5c55 -label.instance.scaled.up=\u5df2\u6269\u5c55\u5b9e\u4f8b -label.tag.key=\u6807\u8bb0\u5bc6\u94a5 -label.tag.value=\u6807\u8bb0\u503c -label.ipv6.address=IPv6 IP \u5730\u5740 -label.ipv6.gateway=IPv6 \u7f51\u5173 -label.ipv6.CIDR=IPv6 CIDR -label.VPC.limits=VPC \u9650\u5236 -label.edit.region=\u7f16\u8f91\u5730\u7406\u533a\u57df -label.gslb.domain.name=GSLB \u57df\u540d -label.add.gslb=\u6dfb\u52a0 GSLB -label.gslb.servicetype=\u670d\u52a1\u7c7b\u578b -label.gslb.details=GSLB \u8be6\u7ec6\u4fe1\u606f -label.gslb.delete=\u5220\u9664 GSLB -label.opendaylight.controller=OpenDaylight \u63a7\u5236\u5668 -label.opendaylight.controllers=OpenDaylight \u63a7\u5236\u5668 -label.portable.ip.ranges=\u53ef\u79fb\u690d IP \u8303\u56f4 -label.add.portable.ip.range=\u6dfb\u52a0\u53ef\u79fb\u690d IP \u8303\u56f4 -label.delete.portable.ip.range=\u5220\u9664\u53ef\u79fb\u690d IP \u8303\u56f4 -label.opendaylight.controllerdetail=OpenDaylight \u63a7\u5236\u5668\u8be6\u7ec6\u4fe1\u606f -label.portable.ip.range.details=\u53ef\u79fb\u690d IP \u8303\u56f4\u8be6\u7ec6\u4fe1\u606f -label.portable.ips=\u53ef\u79fb\u690d IP -label.gslb.assigned.lb=\u5df2\u5206\u914d\u8d1f\u8f7d\u5e73\u8861 -label.gslb.assigned.lb.more=\u5206\u914d\u66f4\u591a\u8d1f\u8f7d\u5e73\u8861 -label.gslb.lb.rule=\u8d1f\u8f7d\u5e73\u8861\u89c4\u5219 -label.gslb.lb.details=\u8d1f\u8f7d\u5e73\u8861\u8be6\u7ec6\u4fe1\u606f -label.gslb.lb.remove=\u4ece\u6b64 GSLB \u4e2d\u5220\u9664\u8d1f\u8f7d\u5e73\u8861 -label.enable.autoscale=\u542f\u7528\u81ea\u52a8\u6269\u5c55 -label.disable.autoscale=\u7981\u7528\u81ea\u52a8\u6269\u5c55 -label.min.instances=\u6700\u5c0f\u5b9e\u4f8b\u6570 -label.max.instances=\u6700\u5927\u5b9e\u4f8b\u6570 -label.add.OpenDaylight.device=\u6dfb\u52a0 OpenDaylight \u63a7\u5236\u5668 -label.show.advanced.settings=\u663e\u793a\u9ad8\u7ea7\u8bbe\u7f6e -label.delete.OpenDaylight.device=\u5220\u9664 OpenDaylight \u63a7\u5236\u5668 -label.polling.interval.sec=\u8f6e\u8be2\u65f6\u95f4\u95f4\u9694(\u79d2) -label.quiet.time.sec=\u5b89\u9759\u65f6\u95f4(\u79d2) -label.destroy.vm.graceperiod=\u9500\u6bc1 VM \u5bbd\u9650\u671f -label.SNMP.community=SNMP \u793e\u533a -label.SNMP.port=SNMP \u7aef\u53e3 -label.add.ucs.manager=\u6dfb\u52a0 UCS \u7ba1\u7406\u5668 -label.ovm.traffic.label=OVM \u6d41\u91cf\u6807\u7b7e -label.lxc.traffic.label=LXC \u6d41\u91cf\u6807\u7b7e -label.hyperv.traffic.label=HyperV \u6d41\u91cf\u6807\u7b7e -label.resource.name=\u8d44\u6e90\u540d\u79f0 -label.reource.id=\u8d44\u6e90 ID -label.vnmc.devices=VNMC \u8bbe\u5907 -label.add.vnmc.provider=\u6dfb\u52a0 VNMC \u63d0\u4f9b\u7a0b\u5e8f -label.enable.vnmc.provider=\u542f\u7528 VNMC \u63d0\u4f9b\u7a0b\u5e8f -label.add.vnmc.device=\u6dfb\u52a0 VNMC \u8bbe\u5907 -label.ciscovnmc.resource.details=CiscoVNMC \u8d44\u6e90\u8be6\u7ec6\u4fe1\u606f -label.delete.ciscovnmc.resource=\u5220\u9664 CiscoVNMC \u8d44\u6e90 -label.enable.vnmc.device=\u542f\u7528 VNMC \u8bbe\u5907 -label.disbale.vnmc.device=\u7981\u7528 VNMC \u8bbe\u5907 -label.disable.vnmc.provider=\u7981\u7528 VNMC \u63d0\u4f9b\u7a0b\u5e8f -label.services=\u670d\u52a1 -label.secondary.staging.store=\u4e8c\u7ea7\u6682\u5b58\u5b58\u50a8 -label.release.account=\u4ece\u5e10\u6237\u4e2d\u91ca\u653e -label.release.account.lowercase=\u4ece\u5e10\u6237\u4e2d\u91ca\u653e -label.vlan.vni.ranges=VLAN/VNI \u8303\u56f4 -label.dedicated.vlan.vni.ranges=VLAN/VNI \u8303\u56f4\u5df2\u4e13\u7528 -label.dedicate.vlan.vni.range=\u5c06 VLAN/VNI \u8303\u56f4\u4e13\u7528 -label.vlan.vni.range=VLAN/VNI \u8303\u56f4 -label.vlan.range.details=VLAN \u8303\u56f4\u8be6\u7ec6\u4fe1\u606f -label.release.dedicated.vlan.range=\u91ca\u653e\u4e13\u7528 VLAN \u8303\u56f4 -label.broadcat.uri=\u5e7f\u64ad URI -label.ipv4.cidr=IPv4 CIDR -label.guest.network.details=\u6765\u5bbe\u7f51\u7edc\u8be6\u7ec6\u4fe1\u606f -label.ipv4.gateway=IPv4 \u7f51\u5173 -label.release.dedicated.vlan.range=\u91ca\u653e\u4e13\u7528 VLAN \u8303\u56f4 -label.vlan.ranges=VLAN \u8303\u56f4 -label.virtual.appliance.details=\u865a\u62df\u8bbe\u5907\u8be6\u7ec6\u4fe1\u606f -label.start.lb.vm=\u542f\u52a8 LB VM -label.stop.lb.vm=\u505c\u6b62 LB VM -label.migrate.lb.vm=\u8fc1\u79fb LB VM -label.vpc.virtual.router=VPC \u865a\u62df\u8def\u7531\u5668 -label.ovs=OVS -label.gslb.service=GSLB \u670d\u52a1 -label.gslb.service.public.ip=GSLB \u670d\u52a1\u516c\u7528 IP -label.gslb.service.private.ip=GSLB \u670d\u52a1\u4e13\u7528 IP -label.baremetal.dhcp.provider=\u88f8\u673a DHCP \u63d0\u4f9b\u7a0b\u5e8f -label.add.baremetal.dhcp.device=\u6dfb\u52a0\u88f8\u673a DHCP \u8bbe\u5907 -label.baremetal.pxe.provider=\u88f8\u673a PXE \u63d0\u4f9b\u7a0b\u5e8f -label.baremetal.pxe.device=\u6dfb\u52a0\u88f8\u673a PXE \u8bbe\u5907 -label.tftp.root.directory=Tftp \u6839\u76ee\u5f55 -label.add.vmware.datacenter=\u6dfb\u52a0 VMware \u6570\u636e\u4e2d\u5fc3 -label.remove.vmware.datacenter=\u5220\u9664 VMware \u6570\u636e\u4e2d\u5fc3 -label.dc.name=\u6570\u636e\u4e2d\u5fc3\u540d\u79f0 -label.vcenter=vCenter -label.dedicate.zone=\u5c06\u8d44\u6e90\u57df\u4e13\u7528 -label.zone.dedicated=\u8d44\u6e90\u57df\u5df2\u4e13\u7528 -label.release.dedicated.zone=\u91ca\u653e\u4e13\u7528\u8d44\u6e90\u57df -label.ipv6.dns1=IPv6 DNS1 -label.ipv6.dns2=IPv6 DNS2 -label.vmware.datacenter.name=VMware \u6570\u636e\u4e2d\u5fc3\u540d\u79f0 -label.vmware.datacenter.vcenter=VMware \u6570\u636e\u4e2d\u5fc3 vCenter -label.vmware.datacenter.id=VMware \u6570\u636e\u4e2d\u5fc3 ID -label.system.vm.details=\u7cfb\u7edf VM \u8be6\u7ec6\u4fe1\u606f -label.system.vm.scaled.up=\u5df2\u6269\u5c55\u7cfb\u7edf VM -label.console.proxy.vm=\u63a7\u5236\u5668\u4ee3\u7406 VM -label.settings=\u8bbe\u7f6e -label.requires.upgrade=\u9700\u8981\u5347\u7ea7 -label.upgrade.router.newer.template=\u5347\u7ea7\u8def\u7531\u5668\u4ee5\u4f7f\u7528\u66f4\u65b0\u7684\u6a21\u677f -label.router.vm.scaled.up=\u5df2\u6269\u5c55\u8def\u7531\u5668 VM -label.total.virtual.routers=\u865a\u62df\u8def\u7531\u5668\u603b\u6570 -label.upgrade.required=\u9700\u8981\u5347\u7ea7 -label.virtual.routers.group.zone=\u865a\u62df\u8def\u7531\u5668(\u6309\u8d44\u6e90\u57df\u5206\u7ec4) -label.total.virtual.routers.upgrade=\u9700\u8981\u5347\u7ea7\u7684\u865a\u62df\u8def\u7531\u5668\u603b\u6570 -label.virtual.routers.group.pod=\u865a\u62df\u8def\u7531\u5668(\u6309\u63d0\u4f9b\u70b9\u5206\u7ec4) -label.virtual.routers.group.cluster=\u865a\u62df\u8def\u7531\u5668(\u6309\u7fa4\u96c6\u5206\u7ec4) -label.zone.lower=\u8d44\u6e90\u57df -label.virtual.routers.group.account=\u865a\u62df\u8def\u7531\u5668(\u6309\u5e10\u6237\u5206\u7ec4) -label.netscaler.details=NetScaler \u8be6\u7ec6\u4fe1\u606f -label.baremetal.dhcp.devices=\u88f8\u673a DHCP \u8bbe\u5907 -label.baremetal.pxe.devices=\u88f8\u673a PXE \u8bbe\u5907 -label.addes.new.f5=\u5df2\u6dfb\u52a0\u65b0 F5 -label.f5.details=F5 \u8be6\u7ec6\u4fe1\u606f -label.srx.details=SRX \u8be6\u7ec6\u4fe1\u606f -label.palo.alto.details=Palo Alto \u8be6\u7ec6\u4fe1\u606f -label.added.nicira.nvp.controller=\u5df2\u6dfb\u52a0\u65b0 Nicira NVP \u63a7\u5236\u5668\ -label.nicira.nvp.details=Nicira NVP \u8be6\u7ec6\u4fe1\u606f -label.added.new.bigswitch.vns.controller=\u5df2\u6dfb\u52a0\u65b0 BigSwitch VNS \u63a7\u5236\u5668 -label.bigswitch.vns.details=BigSwitch VNS \u8be6\u7ec6\u4fe1\u606f -label.dedicate=\u4e13\u7528 -label.dedicate.pod=\u5c06\u63d0\u4f9b\u70b9\u4e13\u7528 -label.pod.dedicated=\u63d0\u4f9b\u70b9\u5df2\u4e13\u7528 -label.release.dedicated.pod=\u91ca\u653e\u4e13\u7528\u63d0\u4f9b\u70b9 -label.override.public.traffic=\u66ff\u4ee3\u516c\u5171\u6d41\u91cf -label.public.traffic.vswitch.type=\u516c\u5171\u6d41\u91cf\u865a\u62df\u4ea4\u6362\u673a\u7c7b\u578b -label.public.traffic.vswitch.name=\u516c\u5171\u6d41\u91cf\u865a\u62df\u4ea4\u6362\u673a\u540d\u79f0 -label.override.guest.traffic=\u66ff\u4ee3\u6765\u5bbe\u6d41\u91cf -label.guest.traffic.vswitch.type=\u6765\u5bbe\u6d41\u91cf\u865a\u62df\u4ea4\u6362\u673a\u7c7b\u578b -label.guest.traffic.vswitch.name=\u6765\u5bbe\u6d41\u91cf\u865a\u62df\u4ea4\u6362\u673a\u540d\u79f0 -label.cisco.nexus1000v.ip.address=Nexus 1000v IP \u5730\u5740 -label.cisco.nexus1000v.username=Nexus 1000v \u7528\u6237\u540d -label.cisco.nexus1000v.password=Nexus 1000v \u5bc6\u7801 -label.dedicate.cluster=\u5c06\u7fa4\u96c6\u4e13\u7528 -label.release.dedicated.cluster=\u91ca\u653e\u4e13\u7528\u7fa4\u96c6 -label.dedicate.host=\u5c06\u4e3b\u673a\u4e13\u7528 -label.release.dedicated.host=\u91ca\u653e\u4e13\u7528\u4e3b\u673a -label.number.of.cpu.sockets=CPU \u63d2\u69fd\u6570 -label.delete.ucs.manager=\u5220\u9664 UCS Manager -label.blades=\u5200\u7247\u5f0f\u670d\u52a1\u5668 -label.chassis=\u673a\u7bb1 -label.blade.id=\u5200\u7247\u5f0f\u670d\u52a1\u5668 ID -label.associated.profile=\u5df2\u5173\u8054\u914d\u7f6e\u6587\u4ef6 -label.refresh.blades=\u5237\u65b0\u5200\u7247\u5f0f\u670d\u52a1\u5668 -label.instanciate.template.associate.profile.blade=\u5c06\u6a21\u677f\u5b9e\u4f8b\u5316\u5e76\u5c06\u914d\u7f6e\u6587\u4ef6\u4e0e\u5200\u7247\u5f0f\u670d\u52a1\u5668\u5173\u8054 -label.select.template=\u9009\u62e9\u6a21\u677f -label.profile=\u914d\u7f6e\u6587\u4ef6 -label.delete.profile=\u5220\u9664\u914d\u7f6e\u6587\u4ef6 -label.disassociate.profile.blade=\u53d6\u6d88\u5c06\u914d\u7f6e\u6587\u4ef6\u4e0e\u5200\u7247\u5f0f\u670d\u52a1\u5668\u5173\u8054 -label.secondary.storage.details=\u4e8c\u7ea7\u5b58\u50a8\u8be6\u7ec6\u4fe1\u606f -label.secondary.staging.store.details=\u4e8c\u7ea7\u6682\u5b58\u5b58\u50a8\u8be6\u7ec6\u4fe1\u606f -label.add.nfs.secondary.staging.store=\u6dfb\u52a0 NFS \u4e8c\u7ea7\u6682\u5b58\u5b58\u50a8 -label.delete.secondary.staging.store=\u5220\u9664\u4e8c\u7ea7\u6682\u5b58\u5b58\u50a8 -label.ipv4.start.ip=IPv4 \u8d77\u59cb IP -label.ipv4.end.ip=IPv4 \u7ed3\u675f IP -label.ipv6.start.ip=IPv6 \u8d77\u59cb IP -label.ipv6.end.ip=IPv6 \u7ed3\u675f IP -label.vm.password=VM \u7684\u5bc6\u7801 -label.group.by.zone=\u6309\u8d44\u6e90\u57df\u5206\u7ec4 -label.group.by.pod=\u6309\u63d0\u4f9b\u70b9\u5206\u7ec4 -label.group.by.cluster=\u6309\u7fa4\u96c6\u5206\u7ec4 -label.group.by.account=\u6309\u5e10\u6237\u5206\u7ec4 -label.no.grouping=(\u4e0d\u5206\u7ec4) -label.create.nfs.secondary.staging.storage=\u521b\u5efa NFS \u4e8c\u7ea7\u6682\u5b58\u5b58\u50a8 -label.username.lower=\u7528\u6237\u540d -label.password.lower=\u5bc6\u7801 -label.email.lower=\u7535\u5b50\u90ae\u4ef6 -label.firstname.lower=\u540d\u5b57 -label.lastname.lower=\u59d3\u6c0f -label.domain.lower=\u57df -label.account.lower=\u5e10\u6237 -label.type.lower=\u7c7b\u578b -label.rule.number=\u89c4\u5219\u7f16\u53f7 -label.action=\u64cd\u4f5c -label.name.lower=\u540d\u79f0 -label.ucs=UCS -label.change.affinity=\u66f4\u6539\u5173\u8054\u6027 -label.persistent=\u6c38\u4e45 -label.broadcasturi=\u5e7f\u64ad URI -label.network.cidr=\u7f51\u7edc CIDR -label.reserved.ip.range=\u9884\u7559 IP \u8303\u56f4 -label.autoscale=\u81ea\u52a8\u6269\u5c55 -label.health.check=\u8fd0\u884c\u72b6\u51b5\u68c0\u67e5 -label.public.load.balancer.provider=\u516c\u7528\u8d1f\u8f7d\u5e73\u8861\u5668\u63d0\u4f9b\u7a0b\u5e8f -label.add.isolated.network=\u6dfb\u52a0\u9694\u79bb\u7f51\u7edc -label.vlan=VLAN -label.secondary.isolated.vlan.id=\u4e8c\u7ea7\u9694\u79bb VLAN ID -label.ipv4.netmask=IPv4 \u7f51\u7edc\u63a9\u7801 -label.custom=\u81ea\u5b9a\u4e49 -label.disable.network.offering=\u7981\u7528\u7f51\u7edc\u65b9\u6848 -label.enable.network.offering=\u542f\u7528\u7f51\u7edc\u65b9\u6848 -label.remove.network.offering=\u5220\u9664\u7f51\u7edc\u65b9\u6848 -label.system.offering.for.router=\u8def\u7531\u5668\u7684\u7cfb\u7edf\u65b9\u6848 -label.mode=\u6a21\u5f0f -label.associate.public.ip=\u5173\u8054\u516c\u7528 IP -label.acl=ACL -label.user.data=\u7528\u6237\u6570\u636e -label.virtual.networking=\u865a\u62df\u7f51\u7edc\u8fde\u63a5 -label.allow=\u5141\u8bb8 -label.deny=\u62d2\u7edd -label.default.egress.policy=\u9ed8\u8ba4\u51fa\u53e3\u89c4\u5219 -label.xenserver.tools.version.61.plus=XenServer Tools \u7248\u672c 6.1\+ +label.zones=\u533a\u57df +label.zone.type=\u533a\u57df\u7c7b\u578b +label.zone=\u533a\u57df +label.zone.wide=\u6574\u4e2a\u533a\u57df +label.zoneWizard.trafficType.guest=\u6765\u5bbe\: \u6700\u7ec8\u7528\u6237\u865a\u62df\u673a\u4e4b\u95f4\u7684\u901a\u4fe1 +label.zoneWizard.trafficType.management=\u7ba1\u7406\: CloudStack \u7684\u5185\u90e8\u8d44\u6e90(\u5305\u62ec\u4e0e\u7ba1\u7406\u670d\u52a1\u5668\u901a\u4fe1\u7684\u4efb\u4f55\u7ec4\u4ef6\uff0c\u4f8b\u5982\u4e3b\u673a\u548c CloudStack \u7cfb\u7edf VM)\u4e4b\u95f4\u7684\u901a\u4fe1 +label.zoneWizard.trafficType.public=\u516c\u7528\: \u4e91\u4e2d Internet \u4e0e\u865a\u62df\u673a\u4e4b\u95f4\u7684\u901a\u4fe1\u3002 +label.zoneWizard.trafficType.storage=\u5b58\u50a8\: \u4e3b\u5b58\u50a8\u670d\u52a1\u5668\u4e0e\u8f85\u52a9\u5b58\u50a8\u670d\u52a1\u5668(\u4f8b\u5982 VM \u6a21\u677f\u4e0e\u5feb\u7167)\u4e4b\u95f4\u7684\u901a\u4fe1 managed.state=\u6258\u7ba1\u72b6\u6001 -message.acquire.new.ip.vpc=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u4e3a\u6b64 VPC \u83b7\u53d6\u4e00\u4e2a\u65b0 IP\u3002 +message.acquire.ip.nic=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u83b7\u53d6\u6b64 NIC \u7684\u65b0\u8f85\u52a9 IP\u3002
\u6ce8\u610f\: \u60a8\u9700\u8981\u5728\u865a\u62df\u673a\u5185\u90e8\u624b\u52a8\u914d\u7f6e\u65b0\u83b7\u53d6\u7684\u8f85\u52a9 IP\u3002 message.acquire.new.ip=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u4e3a\u6b64\u7f51\u7edc\u83b7\u53d6\u4e00\u4e2a\u65b0 IP\u3002 -message.acquire.public.ip=\u8bf7\u9009\u62e9\u4e00\u4e2a\u8981\u4ece\u4e2d\u83b7\u53d6\u65b0 IP \u7684\u8d44\u6e90\u57df\u3002 +message.acquire.new.ip.vpc=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u4e3a\u6b64 VPC \u83b7\u53d6\u4e00\u4e2a\u65b0 IP\u3002 +message.acquire.public.ip=\u8bf7\u9009\u62e9\u4e00\u4e2a\u8981\u4ece\u4e2d\u83b7\u53d6\u65b0 IP \u7684\u533a\u57df\u3002 message.action.cancel.maintenance.mode=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u53d6\u6d88\u6b64\u7ef4\u62a4\u6a21\u5f0f\u3002 message.action.cancel.maintenance=\u5df2\u6210\u529f\u53d6\u6d88\u7ef4\u62a4\u60a8\u7684\u4e3b\u673a\u3002\u6b64\u8fc7\u7a0b\u53ef\u80fd\u9700\u8981\u957f\u8fbe\u51e0\u5206\u949f\u65f6\u95f4\u3002 message.action.change.service.warning.for.instance=\u5fc5\u987b\u5148\u7981\u7528\u60a8\u7684\u5b9e\u4f8b\uff0c\u7136\u540e\u518d\u5c1d\u8bd5\u66f4\u6539\u5176\u5f53\u524d\u7684\u670d\u52a1\u65b9\u6848\u3002 @@ -1494,22 +1487,23 @@ message.action.delete.domain=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9 message.action.delete.external.firewall=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664\u6b64\u5916\u90e8\u9632\u706b\u5899\u3002\u8b66\u544a\: \u5982\u679c\u60a8\u8ba1\u5212\u91cd\u65b0\u6dfb\u52a0\u540c\u4e00\u4e2a\u5916\u90e8\u9632\u706b\u5899\uff0c\u5219\u5fc5\u987b\u5728\u8bbe\u5907\u4e0a\u91cd\u7f6e\u4f7f\u7528\u6570\u636e\u3002 message.action.delete.external.load.balancer=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664\u6b64\u5916\u90e8\u8d1f\u8f7d\u5e73\u8861\u5668\u3002\u8b66\u544a\: \u5982\u679c\u60a8\u8ba1\u5212\u91cd\u65b0\u6dfb\u52a0\u540c\u4e00\u4e2a\u5916\u90e8\u8d1f\u8f7d\u5e73\u8861\u5668\uff0c\u5219\u5fc5\u987b\u5728\u8bbe\u5907\u4e0a\u91cd\u7f6e\u4f7f\u7528\u6570\u636e\u3002 message.action.delete.ingress.rule=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664\u6b64\u5165\u53e3\u89c4\u5219\u3002 -message.action.delete.ISO.for.all.zones=\u6b64 ISO \u7531\u6240\u6709\u8d44\u6e90\u57df\u4f7f\u7528\u3002\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5c06\u5176\u4ece\u6240\u6709\u8d44\u6e90\u57df\u4e2d\u5220\u9664\u3002 +message.action.delete.ISO.for.all.zones=\u6b64 ISO \u7531\u6240\u6709\u533a\u57df\u4f7f\u7528\u3002\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5c06\u5176\u4ece\u6240\u6709\u533a\u57df\u4e2d\u5220\u9664\u3002 message.action.delete.ISO=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664\u6b64 ISO\u3002 message.action.delete.network=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664\u6b64\u7f51\u7edc\u3002 message.action.delete.nexusVswitch=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664\u6b64 Nexus 1000v +message.action.delete.nic=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u79fb\u9664\u6b64 NIC\uff0c\u6b64\u64cd\u4f5c\u8fd8\u5c06\u4ece VM \u4e2d\u79fb\u9664\u5173\u8054\u7684\u7f51\u7edc\u3002 message.action.delete.physical.network=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664\u6b64\u7269\u7406\u7f51\u7edc message.action.delete.pod=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664\u6b64\u63d0\u4f9b\u70b9\u3002 message.action.delete.primary.storage=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664\u6b64\u4e3b\u5b58\u50a8\u3002 -message.action.delete.secondary.storage=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664\u6b64\u4e8c\u7ea7\u5b58\u50a8\u3002 +message.action.delete.secondary.storage=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664\u6b64\u8f85\u52a9\u5b58\u50a8\u3002 message.action.delete.security.group=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664\u6b64\u5b89\u5168\u7ec4\u3002 message.action.delete.service.offering=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664\u6b64\u670d\u52a1\u65b9\u6848\u3002 message.action.delete.snapshot=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664\u6b64\u5feb\u7167\u3002 message.action.delete.system.service.offering=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664\u6b64\u7cfb\u7edf\u670d\u52a1\u65b9\u6848\u3002 -message.action.delete.template.for.all.zones=\u6b64\u6a21\u677f\u7531\u6240\u6709\u8d44\u6e90\u57df\u4f7f\u7528\u3002\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5c06\u5176\u4ece\u6240\u6709\u8d44\u6e90\u57df\u4e2d\u5220\u9664\u3002 +message.action.delete.template.for.all.zones=\u6b64\u6a21\u677f\u7531\u6240\u6709\u533a\u57df\u4f7f\u7528\u3002\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5c06\u5176\u4ece\u6240\u6709\u533a\u57df\u4e2d\u5220\u9664\u3002 message.action.delete.template=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664\u6b64\u6a21\u677f\u3002 message.action.delete.volume=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664\u6b64\u5377\u3002 -message.action.delete.zone=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664\u6b64\u8d44\u6e90\u57df\u3002 +message.action.delete.zone=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664\u6b64\u533a\u57df\u3002 message.action.destroy.instance=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u9500\u6bc1\u6b64\u5b9e\u4f8b\u3002 message.action.destroy.systemvm=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u9500\u6bc1\u6b64\u7cfb\u7edf VM\u3002 message.action.disable.cluster=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u7981\u7528\u6b64\u7fa4\u96c6\u3002 @@ -1517,7 +1511,8 @@ message.action.disable.nexusVswitch=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u message.action.disable.physical.network=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u7981\u7528\u6b64\u7269\u7406\u7f51\u7edc\u3002 message.action.disable.pod=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u7981\u7528\u6b64\u63d0\u4f9b\u70b9\u3002 message.action.disable.static.NAT=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u7981\u7528\u9759\u6001 NAT\u3002 -message.action.disable.zone=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u7981\u7528\u6b64\u8d44\u6e90\u57df\u3002 +message.action.disable.zone=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u7981\u7528\u6b64\u533a\u57df\u3002 +message.action.downloading.template=\u6b63\u5728\u4e0b\u8f7d\u6a21\u677f\u3002 message.action.download.iso=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u4e0b\u8f7d\u6b64 ISO\u3002 message.action.download.template=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u4e0b\u8f7d\u6b64\u6a21\u677f\u3002 message.action.enable.cluster=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u542f\u7528\u6b64\u7fa4\u96c6\u3002 @@ -1525,7 +1520,7 @@ message.action.enable.maintenance=\u5df2\u6210\u529f\u51c6\u5907\u597d\u7ef4\u62 message.action.enable.nexusVswitch=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u542f\u7528\u6b64 Nexus 1000v message.action.enable.physical.network=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u542f\u7528\u6b64\u7269\u7406\u7f51\u7edc\u3002 message.action.enable.pod=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u542f\u7528\u6b64\u63d0\u4f9b\u70b9\u3002 -message.action.enable.zone=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u542f\u7528\u6b64\u8d44\u6e90\u57df\u3002 +message.action.enable.zone=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u542f\u7528\u6b64\u533a\u57df\u3002 message.action.expunge.instance=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664\u6b64\u5b9e\u4f8b\u3002 message.action.force.reconnect=\u5df2\u6210\u529f\u5f3a\u5236\u91cd\u65b0\u8fde\u63a5\u60a8\u7684\u4e3b\u673a\u3002\u6b64\u8fc7\u7a0b\u53ef\u80fd\u9700\u8981\u957f\u8fbe\u51e0\u5206\u949f\u65f6\u95f4\u3002 message.action.host.enable.maintenance.mode=\u542f\u7528\u7ef4\u62a4\u6a21\u5f0f\u4f1a\u5bfc\u81f4\u5c06\u6b64\u4e3b\u673a\u4e0a\u6b63\u5728\u8fd0\u884c\u7684\u6240\u6709\u5b9e\u4f8b\u5b9e\u65f6\u8fc1\u79fb\u5230\u4efb\u4f55\u53ef\u7528\u7684\u4e3b\u673a\u3002 @@ -1540,6 +1535,7 @@ message.action.remove.host=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u966 message.action.reset.password.off=\u60a8\u7684\u5b9e\u4f8b\u5f53\u524d\u4e0d\u652f\u6301\u6b64\u529f\u80fd\u3002 message.action.reset.password.warning=\u5fc5\u987b\u5148\u505c\u6b62\u60a8\u7684\u5b9e\u4f8b\uff0c\u7136\u540e\u518d\u5c1d\u8bd5\u66f4\u6539\u5176\u5f53\u524d\u7684\u5bc6\u7801\u3002 message.action.restore.instance=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u8fd8\u539f\u6b64\u5b9e\u4f8b\u3002 +message.action.revert.snapshot=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5c06\u62e5\u6709\u7684\u5377\u8fd8\u539f\u4e3a\u6b64\u5feb\u7167\u3002 message.action.start.instance=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u542f\u52a8\u6b64\u5b9e\u4f8b\u3002 message.action.start.router=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u542f\u52a8\u6b64\u8def\u7531\u5668\u3002 message.action.start.systemvm=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u542f\u52a8\u6b64\u7cfb\u7edf VM\u3002 @@ -1547,44 +1543,44 @@ message.action.stop.instance=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u505c\u6 message.action.stop.router=\u6b64\u865a\u62df\u8def\u7531\u5668\u63d0\u4f9b\u7684\u6240\u6709\u670d\u52a1\u90fd\u5c06\u4e2d\u65ad\u3002\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u505c\u6b62\u6b64\u8def\u7531\u5668\u3002 message.action.stop.systemvm=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u505c\u6b62\u6b64\u7cfb\u7edf VM\u3002 message.action.take.snapshot=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u521b\u5efa\u6b64\u5377\u7684\u5feb\u7167\u3002 -message.action.revert.snapshot=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5c06\u62e5\u6709\u7684\u5377\u8fd8\u539f\u4e3a\u6b64\u5feb\u7167\u3002 message.action.unmanage.cluster=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u53d6\u6d88\u6258\u7ba1\u6b64\u7fa4\u96c6\u3002 message.action.vmsnapshot.delete=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664\u6b64 VM \u5feb\u7167\u3002 message.action.vmsnapshot.revert=\u8fd8\u539f VM \u5feb\u7167 message.activate.project=\u662f\u5426\u786e\u5b9e\u8981\u6fc0\u6d3b\u6b64\u9879\u76ee? -message.add.cluster.zone=\u5411\u8d44\u6e90\u57df \u4e2d\u6dfb\u52a0\u4e00\u4e2a\u865a\u62df\u673a\u7ba1\u7406\u7a0b\u5e8f\u6258\u7ba1\u7684\u7fa4\u96c6 -message.add.cluster=\u5411\u8d44\u6e90\u57df \u3001\u63d0\u4f9b\u70b9 \u4e2d\u6dfb\u52a0\u4e00\u4e2a\u865a\u62df\u673a\u7ba1\u7406\u7a0b\u5e8f\u6258\u7ba1\u7684\u7fa4\u96c6 +message.add.cluster=\u5411\u533a\u57df \u3001\u63d0\u4f9b\u70b9 \u4e2d\u6dfb\u52a0\u4e00\u4e2a\u865a\u62df\u673a\u7ba1\u7406\u7a0b\u5e8f\u6258\u7ba1\u7684\u7fa4\u96c6 +message.add.cluster.zone=\u5411\u533a\u57df \u4e2d\u6dfb\u52a0\u4e00\u4e2a\u865a\u62df\u673a\u7ba1\u7406\u7a0b\u5e8f\u6258\u7ba1\u7684\u7fa4\u96c6 message.add.disk.offering=\u8bf7\u6307\u5b9a\u4ee5\u4e0b\u53c2\u6570\u4ee5\u6dfb\u52a0\u4e00\u4e2a\u65b0\u7684\u78c1\u76d8\u65b9\u6848 message.add.domain=\u8bf7\u6307\u5b9a\u8981\u5728\u6b64\u57df\u4e0b\u521b\u5efa\u7684\u5b50\u57df -message.add.firewall=\u5411\u8d44\u6e90\u57df\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u9632\u706b\u5899 +message.add.firewall=\u5411\u533a\u57df\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u9632\u706b\u5899 message.add.guest.network=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u6dfb\u52a0\u4e00\u4e2a\u6765\u5bbe\u7f51\u7edc message.add.host=\u8bf7\u6307\u5b9a\u4ee5\u4e0b\u53c2\u6570\u4ee5\u6dfb\u52a0\u4e00\u53f0\u65b0\u4e3b\u673a -message.add.ip.range.direct.network=\u5411\u8d44\u6e90\u57df \u4e2d\u7684\u76f4\u63a5\u7f51\u7edc \u6dfb\u52a0\u4e00\u4e2a IP \u8303\u56f4 +message.adding.host=\u6b63\u5728\u6dfb\u52a0\u4e3b\u673a +message.adding.Netscaler.device=\u6b63\u5728\u6dfb\u52a0 Netscaler \u8bbe\u5907 +message.adding.Netscaler.provider=\u6b63\u5728\u6dfb\u52a0 Netscaler \u63d0\u4f9b\u7a0b\u5e8f +message.add.ip.range.direct.network=\u5411\u533a\u57df \u4e2d\u7684\u76f4\u63a5\u7f51\u7edc \u6dfb\u52a0\u4e00\u4e2a IP \u8303\u56f4 message.add.ip.range.to.pod=

\u5411\u63d0\u4f9b\u70b9\u6dfb\u52a0\u4e00\u4e2a IP \u8303\u56f4\:

-message.add.ip.range=\u5411\u8d44\u6e90\u57df\u4e2d\u7684\u516c\u7528\u7f51\u7edc\u6dfb\u52a0\u4e00\u4e2a IP \u8303\u56f4 +message.add.ip.range=\u5411\u533a\u57df\u4e2d\u7684\u516c\u7528\u7f51\u7edc\u6dfb\u52a0\u4e00\u4e2a IP \u8303\u56f4 +message.additional.networks.desc=\u8bf7\u9009\u62e9\u865a\u62df\u673a\u8981\u8fde\u63a5\u5230\u7684\u5176\u4ed6\u7f51\u7edc\u3002 +message.add.load.balancer=\u5411\u533a\u57df\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u8d1f\u8f7d\u5e73\u8861\u5668 message.add.load.balancer.under.ip=\u5df2\u5728\u4ee5\u4e0b IP \u4e0b\u6dfb\u52a0\u8d1f\u8f7d\u5e73\u8861\u5668\u89c4\u5219\: -message.add.load.balancer=\u5411\u8d44\u6e90\u57df\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u8d1f\u8f7d\u5e73\u8861\u5668 -message.add.network=\u4e3a\u8d44\u6e90\u57df \u6dfb\u52a0\u4e00\u4e2a\u65b0\u7f51\u7edc +message.add.network=\u4e3a\u533a\u57df \u6dfb\u52a0\u4e00\u4e2a\u65b0\u7f51\u7edc message.add.new.gateway.to.vpc=\u8bf7\u6307\u5b9a\u5c06\u65b0\u7f51\u5173\u6dfb\u52a0\u5230\u6b64 VPC \u6240\u9700\u7684\u4fe1\u606f\u3002 -message.add.pod.during.zone.creation=\u6bcf\u4e2a\u8d44\u6e90\u57df\u4e2d\u5fc5\u987b\u5305\u542b\u4e00\u4e2a\u6216\u591a\u4e2a\u63d0\u4f9b\u70b9\uff0c\u73b0\u5728\u6211\u4eec\u5c06\u6dfb\u52a0\u7b2c\u4e00\u4e2a\u63d0\u4f9b\u70b9\u3002\u63d0\u4f9b\u70b9\u4e2d\u5305\u542b\u4e3b\u673a\u548c\u4e3b\u5b58\u50a8\u670d\u52a1\u5668\uff0c\u60a8\u5c06\u5728\u968f\u540e\u7684\u67d0\u4e2a\u6b65\u9aa4\u4e2d\u6dfb\u52a0\u8fd9\u4e9b\u4e3b\u673a\u548c\u670d\u52a1\u5668\u3002\u9996\u5148\uff0c\u8bf7\u4e3a CloudStack \u7684\u5185\u90e8\u7ba1\u7406\u6d41\u91cf\u914d\u7f6e\u4e00\u4e2a\u9884\u7559 IP \u5730\u5740\u8303\u56f4\u3002\u9884\u7559\u7684 IP \u8303\u56f4\u5bf9\u4e91\u4e2d\u7684\u6bcf\u4e2a\u8d44\u6e90\u57df\u6765\u8bf4\u5fc5\u987b\u552f\u4e00\u3002 -message.add.pod=\u4e3a\u8d44\u6e90\u57df \u6dfb\u52a0\u4e00\u4e2a\u65b0\u63d0\u4f9b\u70b9 -message.add.primary.storage=\u4e3a\u8d44\u6e90\u57df \u3001\u63d0\u4f9b\u70b9 \u6dfb\u52a0\u4e00\u4e2a\u65b0\u4e3b\u5b58\u50a8 +message.add.pod.during.zone.creation=\u6bcf\u4e2a\u533a\u57df\u4e2d\u5fc5\u987b\u5305\u542b\u4e00\u4e2a\u6216\u591a\u4e2a\u63d0\u4f9b\u70b9\uff0c\u73b0\u5728\u6211\u4eec\u5c06\u6dfb\u52a0\u7b2c\u4e00\u4e2a\u63d0\u4f9b\u70b9\u3002\u63d0\u4f9b\u70b9\u4e2d\u5305\u542b\u4e3b\u673a\u548c\u4e3b\u5b58\u50a8\u670d\u52a1\u5668\uff0c\u60a8\u5c06\u5728\u968f\u540e\u7684\u67d0\u4e2a\u6b65\u9aa4\u4e2d\u6dfb\u52a0\u8fd9\u4e9b\u4e3b\u673a\u548c\u670d\u52a1\u5668\u3002\u9996\u5148\uff0c\u8bf7\u4e3a CloudStack \u7684\u5185\u90e8\u7ba1\u7406\u901a\u4fe1\u914d\u7f6e\u4e00\u4e2a\u9884\u7559 IP \u5730\u5740\u8303\u56f4\u3002\u9884\u7559\u7684 IP \u8303\u56f4\u5bf9\u4e91\u4e2d\u7684\u6bcf\u4e2a\u533a\u57df\u6765\u8bf4\u5fc5\u987b\u552f\u4e00\u3002 +message.add.pod=\u4e3a\u533a\u57df \u6dfb\u52a0\u4e00\u4e2a\u65b0\u63d0\u4f9b\u70b9 +message.add.primary.storage=\u4e3a\u533a\u57df \u3001\u63d0\u4f9b\u70b9 \u6dfb\u52a0\u4e00\u4e2a\u65b0\u4e3b\u5b58\u50a8 message.add.primary=\u8bf7\u6307\u5b9a\u4ee5\u4e0b\u53c2\u6570\u4ee5\u6dfb\u52a0\u4e00\u4e2a\u65b0\u4e3b\u5b58\u50a8 -message.add.region=\u8bf7\u6307\u5b9a\u6dfb\u52a0\u65b0\u5730\u7406\u533a\u57df\u6240\u9700\u7684\u4fe1\u606f\u3002 -message.add.secondary.storage=\u4e3a\u8d44\u6e90\u57df \u6dfb\u52a0\u4e00\u4e2a\u65b0\u5b58\u50a8 +message.add.region=\u8bf7\u6307\u5b9a\u6dfb\u52a0\u65b0\u533a\u57df\u6240\u9700\u7684\u4fe1\u606f\u3002 +message.add.secondary.storage=\u4e3a\u533a\u57df \u6dfb\u52a0\u4e00\u4e2a\u65b0\u5b58\u50a8 message.add.service.offering=\u8bf7\u586b\u5199\u4ee5\u4e0b\u6570\u636e\u4ee5\u6dfb\u52a0\u4e00\u4e2a\u65b0\u8ba1\u7b97\u65b9\u6848\u3002 message.add.system.service.offering=\u8bf7\u586b\u5199\u4ee5\u4e0b\u6570\u636e\u4ee5\u6dfb\u52a0\u4e00\u4e2a\u65b0\u7684\u7cfb\u7edf\u670d\u52a1\u65b9\u6848\u3002 message.add.template=\u8bf7\u8f93\u5165\u4ee5\u4e0b\u6570\u636e\u4ee5\u521b\u5efa\u65b0\u6a21\u677f message.add.volume=\u8bf7\u586b\u5199\u4ee5\u4e0b\u6570\u636e\u4ee5\u6dfb\u52a0\u4e00\u4e2a\u65b0\u5377\u3002 message.add.VPN.gateway=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u6dfb\u52a0 VPN \u7f51\u5173 -message.adding.host=\u6b63\u5728\u6dfb\u52a0\u4e3b\u673a -message.adding.Netscaler.device=\u6b63\u5728\u6dfb\u52a0 Netscaler \u8bbe\u5907 -message.adding.Netscaler.provider=\u6b63\u5728\u6dfb\u52a0 Netscaler \u63d0\u4f9b\u7a0b\u5e8f -message.additional.networks.desc=\u8bf7\u9009\u62e9\u865a\u62df\u673a\u8981\u8fde\u63a5\u5230\u7684\u5176\u4ed6\u7f51\u7edc\u3002 +message.admin.guide.read=\u5bf9\u4e8e\u57fa\u4e8e VMware \u7684 VM\uff0c\u8bf7\u5148\u9605\u8bfb\u7ba1\u7406\u6307\u5357\u4e2d\u7684\u52a8\u6001\u6269\u5c55\u90e8\u5206\uff0c\u7136\u540e\u518d\u8fdb\u884c\u6269\u5c55\u3002\u662f\u5426\u8981\u7ee7\u7eed?\\, message.advanced.mode.desc=\u5982\u679c\u60a8\u5e0c\u671b\u542f\u7528 VLAN \u652f\u6301\uff0c\u8bf7\u9009\u62e9\u6b64\u7f51\u7edc\u6a21\u5f0f\u3002\u6b64\u7f51\u7edc\u6a21\u5f0f\u5728\u5141\u8bb8\u7ba1\u7406\u5458\u63d0\u4f9b\u9632\u706b\u5899\u3001VPN \u6216\u8d1f\u8f7d\u5e73\u8861\u5668\u652f\u6301\u7b49\u81ea\u5b9a\u4e49\u7f51\u7edc\u65b9\u6848\u4ee5\u53ca\u542f\u7528\u76f4\u63a5\u7f51\u7edc\u8fde\u63a5\u4e0e\u865a\u62df\u7f51\u7edc\u8fde\u63a5\u7b49\u65b9\u9762\u63d0\u4f9b\u4e86\u6700\u5927\u7684\u7075\u6d3b\u6027\u3002 message.advanced.security.group=\u5982\u679c\u8981\u4f7f\u7528\u5b89\u5168\u7ec4\u63d0\u4f9b\u6765\u5bbe VM \u9694\u79bb\uff0c\u8bf7\u9009\u62e9\u6b64\u6a21\u5f0f\u3002 -message.advanced.virtual=\u5982\u679c\u8981\u4f7f\u7528\u6574\u4e2a\u8d44\u6e90\u57df\u7684 VLAN \u63d0\u4f9b\u6765\u5bbe VM \u9694\u79bb\uff0c\u8bf7\u9009\u62e9\u6b64\u6a21\u5f0f\u3002 -message.after.enable.s3=\u5df2\u914d\u7f6e S3 \u652f\u6301\u7684\u4e8c\u7ea7\u5b58\u50a8\u3002\u6ce8\u610f\: \u9000\u51fa\u6b64\u9875\u9762\u540e\uff0c\u60a8\u5c06\u65e0\u6cd5\u518d\u6b21\u91cd\u65b0\u914d\u7f6e S3\u3002 +message.advanced.virtual=\u5982\u679c\u8981\u4f7f\u7528\u6574\u4e2a\u533a\u57df\u7684 VLAN \u63d0\u4f9b\u6765\u5bbe VM \u9694\u79bb\uff0c\u8bf7\u9009\u62e9\u6b64\u6a21\u5f0f\u3002 +message.after.enable.s3=\u5df2\u914d\u7f6e S3 \u652f\u6301\u7684\u8f85\u52a9\u5b58\u50a8\u3002\u6ce8\u610f\: \u9000\u51fa\u6b64\u9875\u9762\u540e\uff0c\u60a8\u5c06\u65e0\u6cd5\u518d\u6b21\u91cd\u65b0\u914d\u7f6e S3\u3002 message.after.enable.swift=\u5df2\u914d\u7f6e SWIFT\u3002\u6ce8\u610f\: \u9000\u51fa\u6b64\u9875\u9762\u540e\uff0c\u60a8\u5c06\u65e0\u6cd5\u518d\u6b21\u91cd\u65b0\u914d\u7f6e SWIFT\u3002 message.alert.state.detected=\u68c0\u6d4b\u5230\u8b66\u62a5\u72b6\u6001 message.allow.vpn.access=\u8bf7\u8f93\u5165\u8981\u5141\u8bb8\u8fdb\u884c VPN \u8bbf\u95ee\u7684\u7528\u6237\u7684\u7528\u6237\u540d\u548c\u5bc6\u7801\u3002 @@ -1594,36 +1590,71 @@ message.attach.volume=\u8bf7\u586b\u5199\u4ee5\u4e0b\u6570\u636e\u4ee5\u9644\u52 message.basic.mode.desc=\u5982\u679c\u60a8*\u4e0d*\u5e0c\u671b\u542f\u7528\u4efb\u4f55 VLAN \u652f\u6301\uff0c\u8bf7\u9009\u62e9\u6b64\u7f51\u7edc\u6a21\u5f0f\u3002\u5c06\u76f4\u63a5\u4ece\u6b64\u7f51\u7edc\u4e2d\u4e3a\u5728\u6b64\u7f51\u7edc\u6a21\u5f0f\u4e0b\u521b\u5efa\u7684\u6240\u6709\u865a\u62df\u673a\u5b9e\u4f8b\u5206\u914d\u4e00\u4e2a IP\uff0c\u5e76\u4f7f\u7528\u5b89\u5168\u7ec4\u63d0\u4f9b\u5b89\u5168\u6027\u548c\u9694\u79bb\u3002 message.change.offering.confirm=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u66f4\u6539\u6b64\u865a\u62df\u5b9e\u4f8b\u7684\u670d\u52a1\u65b9\u6848\u3002 message.change.password=\u8bf7\u66f4\u6539\u60a8\u7684\u5bc6\u7801\u3002 -message.configure.all.traffic.types=\u60a8\u6709\u591a\u4e2a\u7269\u7406\u7f51\u7edc\uff0c\u8bf7\u5355\u51fb\u201c\u7f16\u8f91\u201d\u6309\u94ae\u4e3a\u6bcf\u79cd\u6d41\u91cf\u7c7b\u578b\u914d\u7f6e\u6807\u7b7e\u3002 -message.configuring.guest.traffic=\u6b63\u5728\u914d\u7f6e\u6765\u5bbe\u6d41\u91cf +message.cluster.dedicated=\u7fa4\u96c6\u5df2\u4e13\u7528 +message.cluster.dedication.released=\u5df2\u91ca\u653e\u4e13\u7528\u7fa4\u96c6 +message.configure.all.traffic.types=\u60a8\u6709\u591a\u4e2a\u7269\u7406\u7f51\u7edc\uff0c\u8bf7\u5355\u51fb\u201c\u7f16\u8f91\u201d\u6309\u94ae\u4e3a\u6bcf\u79cd\u901a\u4fe1\u7c7b\u578b\u914d\u7f6e\u6807\u7b7e\u3002 +message.configure.ldap=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u914d\u7f6e LDAP\u3002 +message.configuring.guest.traffic=\u6b63\u5728\u914d\u7f6e\u6765\u5bbe\u901a\u4fe1 message.configuring.physical.networks=\u6b63\u5728\u914d\u7f6e\u7269\u7406\u7f51\u7edc -message.configuring.public.traffic=\u6b63\u5728\u914d\u7f6e\u516c\u5171\u6d41\u91cf -message.configuring.storage.traffic=\u6b63\u5728\u914d\u7f6e\u5b58\u50a8\u6d41\u91cf +message.configuring.public.traffic=\u6b63\u5728\u914d\u7f6e\u516c\u5171\u901a\u4fe1 +message.configuring.storage.traffic=\u6b63\u5728\u914d\u7f6e\u5b58\u50a8\u901a\u4fe1 message.confirm.action.force.reconnect=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5f3a\u5236\u91cd\u65b0\u8fde\u63a5\u6b64\u4e3b\u673a\u3002 +message.confirm.add.vnmc.provider=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u6dfb\u52a0 VNMC \u63d0\u4f9b\u7a0b\u5e8f\u3002 +message.confirm.dedicate.cluster.domain.account=\u662f\u5426\u786e\u5b9e\u8981\u5c06\u6b64\u7fa4\u96c6\u4e13\u7528\u4e8e\u57df/\u5e10\u6237? +message.confirm.dedicate.host.domain.account=\u662f\u5426\u786e\u5b9e\u8981\u5c06\u6b64\u4e3b\u673a\u4e13\u7528\u4e8e\u57df/\u5e10\u6237? +message.confirm.dedicate.pod.domain.account=\u662f\u5426\u786e\u5b9e\u8981\u5c06\u6b64\u63d0\u4f9b\u70b9\u4e13\u7528\u4e8e\u57df/\u5e10\u6237? +message.confirm.dedicate.zone=\u662f\u5426\u8981\u5c06\u6b64\u8d44\u6e90\u57df\u4e13\u7528\u4e8e\u57df/\u5e10\u6237? +message.confirm.delete.ciscovnmc.resource=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664 CiscoVNMC \u8d44\u6e90 message.confirm.delete.F5=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664 F5 message.confirm.delete.NetScaler=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664 NetScaler -message.confirm.delete.SRX=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664 SRX message.confirm.delete.PA=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664 Palo Alto +message.confirm.delete.secondary.staging.store=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664\u4e8c\u7ea7\u6682\u5b58\u5b58\u50a8\u3002 +message.confirm.delete.SRX=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664 SRX +message.confirm.delete.ucs.manager=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664 UCS Manager message.confirm.destroy.router=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u9500\u6bc1\u6b64\u8def\u7531\u5668 +message.confirm.disable.network.offering=\u662f\u5426\u786e\u5b9e\u8981\u7981\u7528\u6b64\u7f51\u7edc\u65b9\u6848? message.confirm.disable.provider=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u7981\u7528\u6b64\u63d0\u4f9b\u7a0b\u5e8f +message.confirm.disable.vnmc.provider=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u7981\u7528 VNMC \u63d0\u4f9b\u7a0b\u5e8f\u3002 +message.confirm.enable.network.offering=\u662f\u5426\u786e\u5b9e\u8981\u542f\u7528\u6b64\u7f51\u7edc\u65b9\u6848? message.confirm.enable.provider=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u542f\u7528\u6b64\u63d0\u4f9b\u7a0b\u5e8f +message.confirm.enable.vnmc.provider=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u542f\u7528 VNMC \u63d0\u4f9b\u7a0b\u5e8f\u3002 message.confirm.join.project=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u52a0\u5165\u6b64\u9879\u76ee\u3002 +message.confirm.refresh.blades=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5237\u65b0\u5200\u7247\u5f0f\u670d\u52a1\u5668\u3002 +message.confirm.release.dedicated.cluster=\u662f\u5426\u8981\u91ca\u653e\u6b64\u4e13\u7528\u7fa4\u96c6? +message.confirm.release.dedicated.host=\u662f\u5426\u8981\u91ca\u653e\u6b64\u4e13\u7528\u4e3b\u673a? +message.confirm.release.dedicated.pod=\u662f\u5426\u8981\u91ca\u653e\u6b64\u4e13\u7528\u63d0\u4f9b\u70b9? +message.confirm.release.dedicated.zone=\u662f\u5426\u8981\u91ca\u653e\u6b64\u4e13\u7528\u8d44\u6e90\u57df? +message.confirm.release.dedicate.vlan.range=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u91ca\u653e\u4e13\u7528 VLAN \u8303\u56f4 message.confirm.remove.IP.range=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664\u6b64 IP \u8303\u56f4\u3002 +message.confirm.remove.network.offering=\u662f\u5426\u786e\u5b9e\u8981\u5220\u9664\u6b64\u7f51\u7edc\u65b9\u6848? +message.confirm.remove.vmware.datacenter=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664 VMware \u6570\u636e\u4e2d\u5fc3 +message.confirm.scale.up.router.vm=\u662f\u5426\u786e\u5b9e\u8981\u6269\u5c55\u8def\u7531\u5668 VM? +message.confirm.scale.up.system.vm=\u662f\u5426\u786e\u5b9e\u8981\u6269\u5c55\u7cfb\u7edf VM? message.confirm.shutdown.provider=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5173\u95ed\u6b64\u63d0\u4f9b\u7a0b\u5e8f +message.confirm.start.lb.vm=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u542f\u52a8 LB VM +message.confirm.stop.lb.vm=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u505c\u6b62 LB VM +message.confirm.upgrade.router.newer.template=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5347\u7ea7\u8def\u7531\u5668\u4ee5\u4f7f\u7528\u66f4\u65b0\u7684\u6a21\u677f +message.confirm.upgrade.routers.account.newtemplate=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5347\u7ea7\u6b64\u5e10\u6237\u4e2d\u7684\u6240\u6709\u8def\u7531\u5668\u4ee5\u4f7f\u7528\u66f4\u65b0\u7684\u6a21\u677f +message.confirm.upgrade.routers.cluster.newtemplate=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5347\u7ea7\u6b64\u7fa4\u96c6\u4e2d\u7684\u6240\u6709\u8def\u7531\u5668\u4ee5\u4f7f\u7528\u66f4\u65b0\u7684\u6a21\u677f +message.confirm.upgrade.routers.newtemplate=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5347\u7ea7\u6b64\u8d44\u6e90\u57df\u4e2d\u7684\u6240\u6709\u8def\u7531\u5668\u4ee5\u4f7f\u7528\u66f4\u65b0\u7684\u6a21\u677f +message.confirm.upgrade.routers.pod.newtemplate=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5347\u7ea7\u6b64\u63d0\u4f9b\u70b9\u4e2d\u7684\u6240\u6709\u8def\u7531\u5668\u4ee5\u4f7f\u7528\u66f4\u65b0\u7684\u6a21\u677f message.copy.iso.confirm=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5c06 ISO \u590d\u5236\u5230 -message.copy.template=\u5c06\u6a21\u677f XXX \u4ece\u8d44\u6e90\u57df \u590d\u5236\u5230 +message.copy.template.confirm=\u662f\u5426\u786e\u5b9e\u8981\u590d\u5236\u6a21\u677f? +message.copy.template=\u5c06\u6a21\u677f XXX \u4ece\u533a\u57df \u590d\u5236\u5230 +message.create.template=\u662f\u5426\u786e\u5b9e\u8981\u521b\u5efa\u6a21\u677f? message.create.template.vm=\u57fa\u4e8e\u6a21\u677f \u521b\u5efa VM message.create.template.volume=\u8bf7\u5148\u6307\u5b9a\u4ee5\u4e0b\u4fe1\u606f\uff0c\u7136\u540e\u518d\u521b\u5efa\u78c1\u76d8\u5377 \u7684\u6a21\u677f\u3002\u521b\u5efa\u6a21\u677f\u53ef\u80fd\u9700\u8981\u51e0\u5206\u949f\u5230\u66f4\u957f\u7684\u65f6\u95f4\uff0c\u5177\u4f53\u53d6\u51b3\u4e8e\u78c1\u76d8\u5377\u7684\u5927\u5c0f\u3002 -message.create.template=\u662f\u5426\u786e\u5b9e\u8981\u521b\u5efa\u6a21\u677f? message.creating.cluster=\u6b63\u5728\u521b\u5efa\u7fa4\u96c6 message.creating.guest.network=\u6b63\u5728\u521b\u5efa\u6765\u5bbe\u7f51\u7edc message.creating.physical.networks=\u6b63\u5728\u521b\u5efa\u7269\u7406\u7f51\u7edc message.creating.pod=\u6b63\u5728\u521b\u5efa\u63d0\u4f9b\u70b9 message.creating.primary.storage=\u6b63\u5728\u521b\u5efa\u4e3b\u5b58\u50a8 -message.creating.secondary.storage=\u6b63\u5728\u521b\u5efa\u4e8c\u7ea7\u5b58\u50a8 -message.creating.zone=\u6b63\u5728\u521b\u5efa\u8d44\u6e90\u57df +message.creating.secondary.storage=\u6b63\u5728\u521b\u5efa\u8f85\u52a9\u5b58\u50a8 +message.creating.systemVM=\u6b63\u5728\u521b\u5efa\u7cfb\u7edf VM (\u6b64\u64cd\u4f5c\u53ef\u80fd\u9700\u8981\u4e00\u4e9b\u65f6\u95f4) +message.creating.zone=\u6b63\u5728\u521b\u5efa\u533a\u57df message.decline.invitation=\u662f\u5426\u786e\u5b9e\u8981\u62d2\u7edd\u6b64\u9879\u76ee\u9080\u8bf7? -message.dedicate.zone=\u6b63\u5728\u5c06\u8d44\u6e90\u57df\u4e13\u7528 +message.dedicated.zone.released=\u5df2\u91ca\u653e\u4e13\u7528\u8d44\u6e90\u57df +message.dedicate.zone=\u6b63\u5728\u5c06\u533a\u57df\u4e13\u6709\u5316 message.delete.account=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664\u6b64\u5e10\u6237\u3002 message.delete.affinity.group=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664\u6b64\u5173\u8054\u6027\u7ec4\u3002 message.delete.gateway=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664\u6b64\u7f51\u5173 @@ -1637,8 +1668,8 @@ message.desc.basic.zone=\u63d0\u4f9b\u4e00\u4e2a\u7f51\u7edc\uff0c\u5c06\u76f4\u message.desc.cluster=\u6bcf\u4e2a\u63d0\u4f9b\u70b9\u4e2d\u5fc5\u987b\u5305\u542b\u4e00\u4e2a\u6216\u591a\u4e2a\u7fa4\u96c6\uff0c\u73b0\u5728\u6211\u4eec\u5c06\u6dfb\u52a0\u7b2c\u4e00\u4e2a\u7fa4\u96c6\u3002\u7fa4\u96c6\u63d0\u4f9b\u4e86\u4e00\u79cd\u7f16\u7ec4\u4e3b\u673a\u7684\u65b9\u6cd5\u3002\u7fa4\u96c6\u4e2d\u7684\u6240\u6709\u4e3b\u673a\u90fd\u5177\u6709\u76f8\u540c\u7684\u786c\u4ef6\uff0c\u8fd0\u884c\u76f8\u540c\u7684\u865a\u62df\u673a\u7ba1\u7406\u7a0b\u5e8f\uff0c\u4f4d\u4e8e\u76f8\u540c\u7684\u5b50\u7f51\u4e2d\uff0c\u5e76\u8bbf\u95ee\u76f8\u540c\u7684\u5171\u4eab\u5b58\u50a8\u3002\u6bcf\u4e2a\u7fa4\u96c6\u7531\u4e00\u4e2a\u6216\u591a\u4e2a\u4e3b\u673a\u4ee5\u53ca\u4e00\u4e2a\u6216\u591a\u4e2a\u4e3b\u5b58\u50a8\u670d\u52a1\u5668\u7ec4\u6210\u3002 message.desc.host=\u6bcf\u4e2a\u7fa4\u96c6\u4e2d\u5fc5\u987b\u81f3\u5c11\u5305\u542b\u4e00\u4e2a\u4e3b\u673a\u4ee5\u4f9b\u6765\u5bbe VM \u5728\u4e0a\u9762\u8fd0\u884c\uff0c\u73b0\u5728\u6211\u4eec\u5c06\u6dfb\u52a0\u7b2c\u4e00\u4e2a\u4e3b\u673a\u3002\u8981\u4f7f\u4e3b\u673a\u5728 CloudStack \u4e2d\u8fd0\u884c\uff0c\u5fc5\u987b\u5728\u6b64\u4e3b\u673a\u4e0a\u5b89\u88c5\u865a\u62df\u673a\u7ba1\u7406\u7a0b\u5e8f\u8f6f\u4ef6\uff0c\u4e3a\u5176\u5206\u914d\u4e00\u4e2a IP \u5730\u5740\uff0c\u5e76\u786e\u4fdd\u5c06\u5176\u8fde\u63a5\u5230 CloudStack \u7ba1\u7406\u670d\u52a1\u5668\u3002

\u8bf7\u63d0\u4f9b\u4e3b\u673a\u7684 DNS \u6216 IP \u5730\u5740\u3001\u7528\u6237\u540d(\u901a\u5e38\u4e3a root)\u548c\u5bc6\u7801\uff0c\u4ee5\u53ca\u7528\u4e8e\u5bf9\u4e3b\u673a\u8fdb\u884c\u5206\u7c7b\u7684\u4efb\u4f55\u6807\u7b7e\u3002 message.desc.primary.storage=\u6bcf\u4e2a\u7fa4\u96c6\u4e2d\u5fc5\u987b\u5305\u542b\u4e00\u4e2a\u6216\u591a\u4e2a\u4e3b\u5b58\u50a8\u670d\u52a1\u5668\uff0c\u73b0\u5728\u6211\u4eec\u5c06\u6dfb\u52a0\u7b2c\u4e00\u4e2a\u4e3b\u5b58\u50a8\u670d\u52a1\u5668\u3002\u4e3b\u5b58\u50a8\u4e2d\u5305\u542b\u5728\u7fa4\u96c6\u4e2d\u7684\u4e3b\u673a\u4e0a\u8fd0\u884c\u7684\u6240\u6709 VM \u7684\u78c1\u76d8\u5377\u3002\u8bf7\u4f7f\u7528\u5e95\u5c42\u865a\u62df\u673a\u7ba1\u7406\u7a0b\u5e8f\u652f\u6301\u7684\u7b26\u5408\u6807\u51c6\u7684\u534f\u8bae\u3002 -message.desc.secondary.storage=\u6bcf\u4e2a\u8d44\u6e90\u57df\u4e2d\u5fc5\u987b\u81f3\u5c11\u5305\u542b\u4e00\u4e2a NFS \u6216\u4e8c\u7ea7\u5b58\u50a8\u670d\u52a1\u5668\uff0c\u73b0\u5728\u6211\u4eec\u5c06\u6dfb\u52a0\u7b2c\u4e00\u4e2a NFS \u6216\u4e8c\u7ea7\u5b58\u50a8\u670d\u52a1\u5668\u3002\u4e8c\u7ea7\u5b58\u50a8\u7528\u4e8e\u5b58\u50a8 VM \u6a21\u677f\u3001ISO \u6620\u50cf\u548c VM \u78c1\u76d8\u5377\u5feb\u7167\u3002\u6b64\u670d\u52a1\u5668\u5fc5\u987b\u5bf9\u8d44\u6e90\u57df\u4e2d\u7684\u6240\u6709\u670d\u52a1\u5668\u53ef\u7528\u3002

\u8bf7\u63d0\u4f9b IP \u5730\u5740\u548c\u5bfc\u51fa\u8def\u5f84\u3002 -message.desc.zone=\u8d44\u6e90\u57df\u662f CloudStack \u4e2d\u6700\u5927\u7684\u7ec4\u7ec7\u5355\u4f4d\uff0c\u4e00\u4e2a\u8d44\u6e90\u57df\u901a\u5e38\u4e0e\u4e00\u4e2a\u6570\u636e\u4e2d\u5fc3\u76f8\u5bf9\u5e94\u3002\u8d44\u6e90\u57df\u53ef\u63d0\u4f9b\u7269\u7406\u9694\u79bb\u548c\u5197\u4f59\u3002\u4e00\u4e2a\u8d44\u6e90\u57df\u7531\u4e00\u4e2a\u6216\u591a\u4e2a\u63d0\u4f9b\u70b9\u4ee5\u53ca\u7531\u8d44\u6e90\u57df\u4e2d\u7684\u6240\u6709\u63d0\u4f9b\u70b9\u5171\u4eab\u7684\u4e00\u4e2a\u4e8c\u7ea7\u5b58\u50a8\u670d\u52a1\u5668\u7ec4\u6210\uff0c\u5176\u4e2d\u6bcf\u4e2a\u63d0\u4f9b\u70b9\u4e2d\u5305\u542b\u591a\u4e2a\u4e3b\u673a\u548c\u4e3b\u5b58\u50a8\u670d\u52a1\u5668\u3002 +message.desc.secondary.storage=\u6bcf\u4e2a\u533a\u57df\u4e2d\u5fc5\u987b\u81f3\u5c11\u5305\u542b\u4e00\u4e2a NFS \u6216\u8f85\u52a9\u5b58\u50a8\u670d\u52a1\u5668\uff0c\u73b0\u5728\u6211\u4eec\u5c06\u6dfb\u52a0\u7b2c\u4e00\u4e2a NFS \u6216\u8f85\u52a9\u5b58\u50a8\u670d\u52a1\u5668\u3002\u8f85\u52a9\u5b58\u50a8\u7528\u4e8e\u5b58\u50a8 VM \u6a21\u677f\u3001ISO \u6620\u50cf\u548c VM \u78c1\u76d8\u5377\u5feb\u7167\u3002\u6b64\u670d\u52a1\u5668\u5fc5\u987b\u5bf9\u533a\u57df\u4e2d\u7684\u6240\u6709\u670d\u52a1\u5668\u53ef\u7528\u3002

\u8bf7\u63d0\u4f9b IP \u5730\u5740\u548c\u5bfc\u51fa\u8def\u5f84\u3002 +message.desc.zone=\u533a\u57df\u662f CloudStack \u4e2d\u6700\u5927\u7684\u7ec4\u7ec7\u5355\u4f4d\uff0c\u4e00\u4e2a\u533a\u57df\u901a\u5e38\u4e0e\u4e00\u4e2a\u6570\u636e\u4e2d\u5fc3\u76f8\u5bf9\u5e94\u3002\u533a\u57df\u53ef\u63d0\u4f9b\u7269\u7406\u9694\u79bb\u548c\u5197\u4f59\u3002\u4e00\u4e2a\u533a\u57df\u7531\u4e00\u4e2a\u6216\u591a\u4e2a\u63d0\u4f9b\u70b9\u4ee5\u53ca\u7531\u533a\u57df\u4e2d\u7684\u6240\u6709\u63d0\u4f9b\u70b9\u5171\u4eab\u7684\u4e00\u4e2a\u8f85\u52a9\u5b58\u50a8\u670d\u52a1\u5668\u7ec4\u6210\uff0c\u5176\u4e2d\u6bcf\u4e2a\u63d0\u4f9b\u70b9\u4e2d\u5305\u542b\u591a\u4e2a\u4e3b\u673a\u548c\u4e3b\u5b58\u50a8\u670d\u52a1\u5668\u3002 message.detach.disk=\u662f\u5426\u786e\u5b9e\u8981\u53d6\u6d88\u9644\u52a0\u6b64\u78c1\u76d8? message.detach.iso.confirm=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u4ece\u6b64\u865a\u62df\u673a\u4e2d\u53d6\u6d88\u9644\u52a0\u6b64 ISO\u3002 message.disable.account=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u7981\u7528\u6b64\u5e10\u6237\u3002\u7981\u7528\u540e\uff0c\u6b64\u5e10\u6237\u7684\u6240\u6709\u7528\u6237\u5c06\u4e0d\u518d\u6709\u6743\u8bbf\u95ee\u5404\u81ea\u7684\u4e91\u8d44\u6e90\u3002\u6240\u6709\u6b63\u5728\u8fd0\u884c\u7684\u865a\u62df\u673a\u5c06\u7acb\u5373\u5173\u95ed\u3002 @@ -1646,6 +1677,8 @@ message.disable.snapshot.policy=\u60a8\u5df2\u6210\u529f\u7981\u7528\u5f53\u524d message.disable.user=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u7981\u7528\u6b64\u7528\u6237\u3002 message.disable.vpn.access=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u7981\u7528 VPN \u8bbf\u95ee\u3002 message.disable.vpn=\u662f\u5426\u786e\u5b9e\u8981\u7981\u7528 VPN? +message.disabling.network.offering=\u6b63\u5728\u7981\u7528\u7f51\u7edc\u65b9\u6848 +message.disallowed.characters=\u7981\u7528\u5b57\u7b26\: \\<\\,\\> message.download.ISO=\u8bf7\u5355\u51fb 00000 \u4e0b\u8f7d ISO message.download.template=\u8bf7\u5355\u51fb 00000 \u4e0b\u8f7d\u6a21\u677f message.download.volume.confirm=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u4e0b\u8f7d\u6b64\u5377 @@ -1653,59 +1686,67 @@ message.download.volume=\u8bf7\u5355\u51fb 00000 \u4e0b\u8f7d\ message.edit.account=\u7f16\u8f91(\u201c-1\u201d\u8868\u793a\u5bf9\u8981\u521b\u5efa\u7684\u8d44\u6e90\u6570\u91cf\u6ca1\u6709\u4efb\u4f55\u9650\u5236) message.edit.confirm=\u8bf7\u5148\u786e\u8ba4\u60a8\u6240\u505a\u7684\u66f4\u6539\uff0c\u7136\u540e\u5355\u51fb\u201c\u4fdd\u5b58\u201d\u3002 message.edit.limits=\u8bf7\u6307\u5b9a\u5bf9\u4ee5\u4e0b\u8d44\u6e90\u7684\u9650\u5236\u3002\u201c-1\u201d\u8868\u793a\u4e0d\u9650\u5236\u8981\u521b\u5efa\u7684\u8d44\u6e90\u6570\u3002 -message.edit.traffic.type=\u8bf7\u6307\u5b9a\u60a8\u5e0c\u671b\u4e0e\u6b64\u6d41\u91cf\u7c7b\u578b\u5173\u8054\u7684\u6d41\u91cf\u6807\u7b7e\u3002 +message.edit.traffic.type=\u8bf7\u6307\u5b9a\u60a8\u5e0c\u671b\u4e0e\u6b64\u901a\u4fe1\u7c7b\u578b\u5173\u8054\u7684\u901a\u4fe1\u6807\u7b7e\u3002 message.enable.account=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u542f\u7528\u6b64\u5e10\u6237\u3002 +message.enabled.vpn.ip.sec=\u60a8\u7684 IPSec \u9884\u5171\u4eab\u5bc6\u94a5 +message.enabled.vpn=\u60a8\u7684 VPN \u8bbf\u95ee\u529f\u80fd\u5f53\u524d\u5df2\u542f\u7528\uff0c\u53ef\u4ee5\u901a\u8fc7 IP \u8fdb\u884c\u8bbf\u95ee message.enable.user=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u542f\u7528\u6b64\u7528\u6237\u3002 message.enable.vpn.access=\u5f53\u524d\u5df2\u5bf9\u6b64 IP \u5730\u5740\u7981\u7528\u4e86 VPN\u3002\u662f\u5426\u8981\u542f\u7528 VPN \u8bbf\u95ee? message.enable.vpn=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5bf9\u6b64 IP \u5730\u5740\u542f\u7528 VPN \u8bbf\u95ee\u3002 -message.enabled.vpn.ip.sec=\u60a8\u7684 IPSec \u9884\u5171\u4eab\u5bc6\u94a5 -message.enabled.vpn=\u60a8\u7684 VPN \u8bbf\u95ee\u529f\u80fd\u5f53\u524d\u5df2\u542f\u7528\uff0c\u53ef\u4ee5\u901a\u8fc7 IP \u8fdb\u884c\u8bbf\u95ee +message.enabling.network.offering=\u6b63\u5728\u542f\u7528\u7f51\u7edc\u65b9\u6848 message.enabling.security.group.provider=\u6b63\u5728\u542f\u7528\u5b89\u5168\u7ec4\u63d0\u4f9b\u7a0b\u5e8f -message.enabling.zone=\u6b63\u5728\u542f\u7528\u8d44\u6e90\u57df +message.enabling.zone.dots=\u6b63\u5728\u542f\u7528\u8d44\u6e90\u57df... +message.enabling.zone=\u6b63\u5728\u542f\u7528\u533a\u57df +message.enter.seperated.list.multiple.cidrs=\u5982\u679c\u5b58\u5728\u591a\u4e2a CIDR\uff0c\u8bf7\u8f93\u5165\u7528\u9017\u53f7\u5206\u9694\u7684 CIDR \u5217\u8868 message.enter.token=\u8bf7\u8f93\u5165\u60a8\u5728\u9080\u8bf7\u7535\u5b50\u90ae\u4ef6\u4e2d\u6536\u5230\u7684\u4ee4\u724c\u3002 message.generate.keys=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u4e3a\u6b64\u7528\u6237\u751f\u6210\u65b0\u5bc6\u94a5\u3002 -message.guest.traffic.in.advanced.zone=\u6765\u5bbe\u7f51\u7edc\u6d41\u91cf\u662f\u6307\u6700\u7ec8\u7528\u6237\u865a\u62df\u673a\u4e4b\u95f4\u7684\u901a\u4fe1\u3002\u6307\u5b9a\u4e00\u4e2a VLAN ID \u8303\u56f4\u53ef\u4f20\u9001\u6bcf\u4e2a\u7269\u7406\u7f51\u7edc\u7684\u6765\u5bbe\u6d41\u91cf\u3002 -message.guest.traffic.in.basic.zone=\u6765\u5bbe\u7f51\u7edc\u6d41\u91cf\u662f\u6307\u6700\u7ec8\u7528\u6237\u865a\u62df\u673a\u4e4b\u95f4\u7684\u901a\u4fe1\u3002\u5e94\u6307\u5b9a\u4e00\u4e2a CloudStack \u53ef\u4ee5\u5206\u914d\u7ed9\u6765\u5bbe VM \u7684 IP \u5730\u5740\u8303\u56f4\u3002\u8bf7\u786e\u4fdd\u6b64\u8303\u56f4\u4e0e\u9884\u7559\u7684\u7cfb\u7edf IP \u8303\u56f4\u4e0d\u91cd\u53e0\u3002 +message.gslb.delete.confirm=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664\u6b64 GSLB +message.gslb.lb.remove.confirm=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u4ece GSLB \u4e2d\u5220\u9664\u8d1f\u8f7d\u5e73\u8861 +message.guest.traffic.in.advanced.zone=\u6765\u5bbe\u7f51\u7edc\u901a\u4fe1\u662f\u6307\u6700\u7ec8\u7528\u6237\u865a\u62df\u673a\u4e4b\u95f4\u7684\u901a\u4fe1\u3002\u6307\u5b9a\u4e00\u4e2a VLAN ID \u8303\u56f4\u53ef\u4f20\u9001\u6bcf\u4e2a\u7269\u7406\u7f51\u7edc\u7684\u6765\u5bbe\u901a\u4fe1\u3002 +message.guest.traffic.in.basic.zone=\u6765\u5bbe\u7f51\u7edc\u901a\u4fe1\u662f\u6307\u6700\u7ec8\u7528\u6237\u865a\u62df\u673a\u4e4b\u95f4\u7684\u901a\u4fe1\u3002\u5e94\u6307\u5b9a\u4e00\u4e2a CloudStack \u53ef\u4ee5\u5206\u914d\u7ed9\u6765\u5bbe VM \u7684 IP \u5730\u5740\u8303\u56f4\u3002\u8bf7\u786e\u4fdd\u6b64\u8303\u56f4\u4e0e\u9884\u7559\u7684\u7cfb\u7edf IP \u8303\u56f4\u4e0d\u91cd\u53e0\u3002 +message.host.dedicated=\u4e3b\u673a\u5df2\u4e13\u7528 +message.host.dedication.released=\u5df2\u91ca\u653e\u4e13\u7528\u4e3b\u673a message.installWizard.click.retry=\u8bf7\u5355\u51fb\u6b64\u6309\u94ae\u91cd\u65b0\u5c1d\u8bd5\u542f\u52a8\u3002 -message.installWizard.copy.whatIsACluster=\u7fa4\u96c6\u63d0\u4f9b\u4e86\u4e00\u79cd\u7f16\u7ec4\u4e3b\u673a\u7684\u65b9\u6cd5\u3002\u7fa4\u96c6\u4e2d\u7684\u6240\u6709\u4e3b\u673a\u90fd\u5177\u6709\u76f8\u540c\u7684\u786c\u4ef6\uff0c\u8fd0\u884c\u76f8\u540c\u7684\u865a\u62df\u673a\u7ba1\u7406\u7a0b\u5e8f\uff0c\u4f4d\u4e8e\u540c\u4e00\u5b50\u7f51\u4e2d\uff0c\u5e76\u8bbf\u95ee\u76f8\u540c\u7684\u5171\u4eab\u5b58\u50a8\u3002\u53ef\u4ee5\u5b9e\u65f6\u5c06\u865a\u62df\u673a\u5b9e\u4f8b(VM)\u4ece\u4e00\u53f0\u4e3b\u673a\u8fc1\u79fb\u5230\u540c\u4e00\u7fa4\u96c6\u5185\u7684\u5176\u4ed6\u4e3b\u673a\uff0c\u800c\u65e0\u9700\u4e2d\u65ad\u5411\u7528\u6237\u63d0\u4f9b\u670d\u52a1\u3002\u7fa4\u96c6\u662f CloudStack&\#8482; \u90e8\u7f72\u4e2d\u7684\u7b2c\u4e09\u5927\u7ec4\u7ec7\u5355\u4f4d\u3002\u7fa4\u96c6\u5305\u542b\u5728\u63d0\u4f9b\u70b9\u4e2d\uff0c\u63d0\u4f9b\u70b9\u5305\u542b\u5728\u8d44\u6e90\u57df\u4e2d\u3002

CloudStack&\#8482; \u5141\u8bb8\u4e91\u90e8\u7f72\u4e2d\u5b58\u5728\u591a\u4e2a\u7fa4\u96c6\uff0c\u4f46\u5bf9\u4e8e\u57fa\u672c\u5b89\u88c5\uff0c\u6211\u4eec\u53ea\u9700\u8981\u4e00\u4e2a\u7fa4\u96c6\u3002 -message.installWizard.copy.whatIsAHost=\u4e3b\u673a\u662f\u6307\u4e00\u53f0\u8ba1\u7b97\u673a\u3002\u4e3b\u673a\u63d0\u4f9b\u8fd0\u884c\u6765\u5bbe\u865a\u62df\u673a\u7684\u8ba1\u7b97\u8d44\u6e90\u3002\u6bcf\u53f0\u4e3b\u673a\u4e0a\u90fd\u5b89\u88c5\u6709\u865a\u62df\u673a\u7ba1\u7406\u7a0b\u5e8f\u8f6f\u4ef6\uff0c\u7528\u4e8e\u7ba1\u7406\u6765\u5bbe VM (\u88f8\u673a\u4e3b\u673a\u9664\u5916\uff0c\u5c06\u5728\u201c\u9ad8\u7ea7\u5b89\u88c5\u6307\u5357\u201d\u4e2d\u8ba8\u8bba\u8fd9\u4e00\u7279\u6b8a\u6848\u4f8b)\u3002\u4f8b\u5982\uff0c\u542f\u7528\u4e86 KVM \u7684 Linux \u670d\u52a1\u5668\u3001Citrix XenServer \u670d\u52a1\u5668\u548c ESXi \u670d\u52a1\u5668\u90fd\u53ef\u7528\u4f5c\u4e3b\u673a\u3002\u5728\u57fa\u672c\u5b89\u88c5\u4e2d\uff0c\u6211\u4eec\u5c06\u4f7f\u7528\u4e00\u53f0\u8fd0\u884c XenServer \u7684\u4e3b\u673a\u3002

\u4e3b\u673a\u662f CloudStack&\#8482; \u90e8\u7f72\u4e2d\u6700\u5c0f\u7684\u7ec4\u7ec7\u5355\u4f4d\u3002\u4e3b\u673a\u5305\u542b\u5728\u7fa4\u96c6\u4e2d\uff0c\u7fa4\u96c6\u5305\u542b\u5728\u63d0\u4f9b\u70b9\u4e2d\uff0c\u63d0\u4f9b\u70b9\u5305\u542b\u5728\u8d44\u6e90\u57df\u4e2d\u3002 -message.installWizard.copy.whatIsAPod=\u4e00\u4e2a\u63d0\u4f9b\u70b9\u901a\u5e38\u4ee3\u8868\u4e00\u4e2a\u673a\u67b6\u3002\u540c\u4e00\u63d0\u4f9b\u70b9\u4e2d\u7684\u4e3b\u673a\u4f4d\u4e8e\u540c\u4e00\u5b50\u7f51\u4e2d\u3002

\u63d0\u4f9b\u70b9\u662f CloudStack&\#8482; \u90e8\u7f72\u4e2d\u7684\u7b2c\u4e8c\u5927\u7ec4\u7ec7\u5355\u4f4d\u3002\u63d0\u4f9b\u70b9\u5305\u542b\u5728\u8d44\u6e90\u57df\u4e2d\u3002\u6bcf\u4e2a\u8d44\u6e90\u57df\u4e2d\u53ef\u4ee5\u5305\u542b\u4e00\u4e2a\u6216\u591a\u4e2a\u63d0\u4f9b\u70b9\uff1b\u5728\u57fa\u672c\u5b89\u88c5\u4e2d\uff0c\u60a8\u7684\u8d44\u6e90\u57df\u4e2d\u5c06\u4ec5\u5305\u542b\u4e00\u4e2a\u63d0\u4f9b\u70b9\u3002 -message.installWizard.copy.whatIsAZone=\u8d44\u6e90\u57df\u662f CloudStack&\#8482; \u90e8\u7f72\u4e2d\u6700\u5927\u7684\u7ec4\u7ec7\u5355\u4f4d\u3002\u867d\u7136\u5141\u8bb8\u4e00\u4e2a\u6570\u636e\u4e2d\u5fc3\u4e2d\u5b58\u5728\u591a\u4e2a\u8d44\u6e90\u57df\uff0c\u4f46\u662f\u4e00\u4e2a\u8d44\u6e90\u57df\u901a\u5e38\u4e0e\u4e00\u4e2a\u6570\u636e\u4e2d\u5fc3\u76f8\u5bf9\u5e94\u3002\u5c06\u57fa\u7840\u67b6\u6784\u7f16\u7ec4\u5230\u8d44\u6e90\u57df\u4e2d\u7684\u597d\u5904\u662f\u53ef\u4ee5\u63d0\u4f9b\u7269\u7406\u9694\u79bb\u548c\u5197\u4f59\u3002\u4f8b\u5982\uff0c\u6bcf\u4e2a\u8d44\u6e90\u57df\u90fd\u53ef\u4ee5\u62e5\u6709\u5404\u81ea\u7684\u7535\u6e90\u4f9b\u5e94\u548c\u7f51\u7edc\u4e0a\u884c\u65b9\u6848\uff0c\u5e76\u4e14\u5404\u8d44\u6e90\u57df\u53ef\u4ee5\u5728\u5730\u7406\u4f4d\u7f6e\u4e0a\u76f8\u9694\u5f88\u8fdc(\u867d\u7136\u5e76\u975e\u5fc5\u987b\u76f8\u9694\u5f88\u8fdc)\u3002 -message.installWizard.copy.whatIsCloudStack=CloudStack&\#8482 \u662f\u4e00\u4e2a\u8f6f\u4ef6\u5e73\u53f0\uff0c\u53ef\u5c06\u8ba1\u7b97\u8d44\u6e90\u96c6\u4e2d\u5728\u4e00\u8d77\u4ee5\u6784\u5efa\u516c\u6709\u3001\u79c1\u6709\u548c\u6df7\u5408\u57fa\u7840\u8bbe\u65bd\u5373\u670d\u52a1(IaaS)\u4e91\u3002CloudStack&\#8482 \u8d1f\u8d23\u7ba1\u7406\u7ec4\u6210\u4e91\u57fa\u7840\u67b6\u6784\u7684\u7f51\u7edc\u3001\u5b58\u50a8\u548c\u8ba1\u7b97\u8282\u70b9\u3002\u4f7f\u7528 CloudStack&\#8482 \u53ef\u4ee5\u90e8\u7f72\u3001\u7ba1\u7406\u548c\u914d\u7f6e\u4e91\u8ba1\u7b97\u73af\u5883\u3002

CloudStack&\#8482 \u901a\u8fc7\u6269\u5c55\u5546\u7528\u786c\u4ef6\u4e0a\u8fd0\u884c\u7684\u6bcf\u4e2a\u865a\u62df\u673a\u6620\u50cf\u7684\u8303\u56f4\uff0c\u63d0\u4f9b\u4e86\u4e00\u4e2a\u5b9e\u65f6\u53ef\u7528\u7684\u4e91\u57fa\u7840\u67b6\u6784\u8f6f\u4ef6\u5806\u6808\u7528\u4e8e\u4ee5\u670d\u52a1\u65b9\u5f0f\u4ea4\u4ed8\u865a\u62df\u6570\u636e\u4e2d\u5fc3\uff0c\u5373\u4ea4\u4ed8\u6784\u5efa\u3001\u90e8\u7f72\u548c\u7ba1\u7406\u591a\u5c42\u6b21\u548c\u591a\u79df\u6237\u4e91\u5e94\u7528\u7a0b\u5e8f\u5fc5\u9700\u7684\u6240\u6709\u7ec4\u4ef6\u3002\u5f00\u6e90\u7248\u672c\u548c Premium \u7248\u672c\u90fd\u5df2\u53ef\u7528\uff0c\u4e14\u63d0\u4f9b\u7684\u529f\u80fd\u51e0\u4e4e\u5b8c\u5168\u76f8\u540c\u3002 -message.installWizard.copy.whatIsPrimaryStorage=CloudStack&\#8482; \u4e91\u57fa\u7840\u67b6\u6784\u4f7f\u7528\u4ee5\u4e0b\u4e24\u79cd\u7c7b\u578b\u7684\u5b58\u50a8\: \u4e3b\u5b58\u50a8\u548c\u4e8c\u7ea7\u5b58\u50a8\u3002\u8fd9\u4e24\u79cd\u7c7b\u578b\u7684\u5b58\u50a8\u53ef\u4ee5\u662f iSCSI \u6216 NFS \u670d\u52a1\u5668\uff0c\u4e5f\u53ef\u4ee5\u662f\u672c\u5730\u78c1\u76d8\u3002

\u4e3b\u5b58\u50a8\u4e0e\u7fa4\u96c6\u76f8\u5173\u8054\uff0c\u7528\u4e8e\u5b58\u50a8\u8be5\u7fa4\u96c6\u4e2d\u7684\u4e3b\u673a\u4e0a\u6b63\u5728\u8fd0\u884c\u7684\u6240\u6709 VM \u5bf9\u5e94\u7684\u6bcf\u4e2a\u6765\u5bbe VM \u7684\u78c1\u76d8\u5377\u3002\u4e3b\u5b58\u50a8\u670d\u52a1\u5668\u901a\u5e38\u4f4d\u4e8e\u9760\u8fd1\u4e3b\u673a\u7684\u4f4d\u7f6e\u3002 -message.installWizard.copy.whatIsSecondaryStorage=\u4e8c\u7ea7\u5b58\u50a8\u4e0e\u8d44\u6e90\u57df\u76f8\u5173\u8054\uff0c\u7528\u4e8e\u5b58\u50a8\u4ee5\u4e0b\u9879\u76ee\:
  • \u6a21\u677f - \u53ef\u7528\u4e8e\u542f\u52a8 VM \u5e76\u53ef\u4ee5\u5305\u542b\u5176\u4ed6\u914d\u7f6e\u4fe1\u606f(\u4f8b\u5982\uff0c\u5df2\u5b89\u88c5\u7684\u5e94\u7528\u7a0b\u5e8f)\u7684\u64cd\u4f5c\u7cfb\u7edf\u6620\u50cf
  • ISO \u6620\u50cf - \u53ef\u91cd\u65b0\u542f\u52a8\u6216\u4e0d\u53ef\u91cd\u65b0\u542f\u52a8\u7684\u64cd\u4f5c\u7cfb\u7edf\u6620\u50cf
  • \u78c1\u76d8\u5377\u5feb\u7167 - \u5df2\u4fdd\u5b58\u7684 VM \u6570\u636e\u526f\u672c\uff0c\u53ef\u7528\u4e8e\u6267\u884c\u6570\u636e\u6062\u590d\u6216\u521b\u5efa\u65b0\u6a21\u677f
+message.installWizard.copy.whatIsACluster=\u7fa4\u96c6\u63d0\u4f9b\u4e86\u4e00\u79cd\u7f16\u7ec4\u4e3b\u673a\u7684\u65b9\u6cd5\u3002\u7fa4\u96c6\u4e2d\u7684\u6240\u6709\u4e3b\u673a\u90fd\u5177\u6709\u76f8\u540c\u7684\u786c\u4ef6\uff0c\u8fd0\u884c\u76f8\u540c\u7684\u865a\u62df\u673a\u7ba1\u7406\u7a0b\u5e8f\uff0c\u4f4d\u4e8e\u540c\u4e00\u5b50\u7f51\u4e2d\uff0c\u5e76\u8bbf\u95ee\u76f8\u540c\u7684\u5171\u4eab\u5b58\u50a8\u3002\u53ef\u4ee5\u5b9e\u65f6\u5c06\u865a\u62df\u673a\u5b9e\u4f8b(VM)\u4ece\u4e00\u53f0\u4e3b\u673a\u8fc1\u79fb\u5230\u540c\u4e00\u7fa4\u96c6\u5185\u7684\u5176\u4ed6\u4e3b\u673a\uff0c\u800c\u65e0\u9700\u4e2d\u65ad\u5411\u7528\u6237\u63d0\u4f9b\u670d\u52a1\u3002\u7fa4\u96c6\u662f CloudStack&\#8482; \u90e8\u7f72\u4e2d\u7684\u7b2c\u4e09\u5927\u7ec4\u7ec7\u5355\u4f4d\u3002\u7fa4\u96c6\u5305\u542b\u5728\u63d0\u4f9b\u70b9\u4e2d\uff0c\u63d0\u4f9b\u70b9\u5305\u542b\u5728\u533a\u57df\u4e2d\u3002

CloudStack&\#8482; \u5141\u8bb8\u4e91\u90e8\u7f72\u4e2d\u5b58\u5728\u591a\u4e2a\u7fa4\u96c6\uff0c\u4f46\u5bf9\u4e8e\u57fa\u672c\u5b89\u88c5\uff0c\u6211\u4eec\u53ea\u9700\u8981\u4e00\u4e2a\u7fa4\u96c6\u3002 +message.installWizard.copy.whatIsAHost=\u4e3b\u673a\u662f\u6307\u4e00\u53f0\u8ba1\u7b97\u673a\u3002\u4e3b\u673a\u63d0\u4f9b\u8fd0\u884c\u6765\u5bbe\u865a\u62df\u673a\u7684\u8ba1\u7b97\u8d44\u6e90\u3002\u6bcf\u53f0\u4e3b\u673a\u4e0a\u90fd\u5b89\u88c5\u6709\u865a\u62df\u673a\u7ba1\u7406\u7a0b\u5e8f\u8f6f\u4ef6\uff0c\u7528\u4e8e\u7ba1\u7406\u6765\u5bbe VM (\u88f8\u673a\u4e3b\u673a\u9664\u5916\uff0c\u5c06\u5728\u201c\u9ad8\u7ea7\u5b89\u88c5\u6307\u5357\u201d\u4e2d\u8ba8\u8bba\u8fd9\u4e00\u7279\u6b8a\u6848\u4f8b)\u3002\u4f8b\u5982\uff0c\u542f\u7528\u4e86 KVM \u7684 Linux \u670d\u52a1\u5668\u3001Citrix XenServer \u670d\u52a1\u5668\u548c ESXi \u670d\u52a1\u5668\u90fd\u53ef\u7528\u4f5c\u4e3b\u673a\u3002\u5728\u57fa\u672c\u5b89\u88c5\u4e2d\uff0c\u6211\u4eec\u5c06\u4f7f\u7528\u4e00\u53f0\u8fd0\u884c XenServer \u7684\u4e3b\u673a\u3002

\u4e3b\u673a\u662f CloudStack&\#8482; \u90e8\u7f72\u4e2d\u6700\u5c0f\u7684\u7ec4\u7ec7\u5355\u4f4d\u3002\u4e3b\u673a\u5305\u542b\u5728\u7fa4\u96c6\u4e2d\uff0c\u7fa4\u96c6\u5305\u542b\u5728\u63d0\u4f9b\u70b9\u4e2d\uff0c\u63d0\u4f9b\u70b9\u5305\u542b\u5728\u533a\u57df\u4e2d\u3002 +message.installWizard.copy.whatIsAPod=\u4e00\u4e2a\u63d0\u4f9b\u70b9\u901a\u5e38\u4ee3\u8868\u4e00\u4e2a\u673a\u67b6\u3002\u540c\u4e00\u63d0\u4f9b\u70b9\u4e2d\u7684\u4e3b\u673a\u4f4d\u4e8e\u540c\u4e00\u5b50\u7f51\u4e2d\u3002

\u63d0\u4f9b\u70b9\u662f CloudStack&\#8482; \u90e8\u7f72\u4e2d\u7684\u7b2c\u4e8c\u5927\u7ec4\u7ec7\u5355\u4f4d\u3002\u63d0\u4f9b\u70b9\u5305\u542b\u5728\u533a\u57df\u4e2d\u3002\u6bcf\u4e2a\u533a\u57df\u4e2d\u53ef\u4ee5\u5305\u542b\u4e00\u4e2a\u6216\u591a\u4e2a\u63d0\u4f9b\u70b9\uff1b\u5728\u57fa\u672c\u5b89\u88c5\u4e2d\uff0c\u60a8\u7684\u533a\u57df\u4e2d\u5c06\u4ec5\u5305\u542b\u4e00\u4e2a\u63d0\u4f9b\u70b9\u3002 +message.installWizard.copy.whatIsAZone=\u533a\u57df\u662f CloudStack&\#8482; \u90e8\u7f72\u4e2d\u6700\u5927\u7684\u7ec4\u7ec7\u5355\u4f4d\u3002\u867d\u7136\u5141\u8bb8\u4e00\u4e2a\u6570\u636e\u4e2d\u5fc3\u4e2d\u5b58\u5728\u591a\u4e2a\u533a\u57df\uff0c\u4f46\u662f\u4e00\u4e2a\u533a\u57df\u901a\u5e38\u4e0e\u4e00\u4e2a\u6570\u636e\u4e2d\u5fc3\u76f8\u5bf9\u5e94\u3002\u5c06\u57fa\u7840\u67b6\u6784\u7f16\u7ec4\u5230\u533a\u57df\u4e2d\u7684\u597d\u5904\u662f\u53ef\u4ee5\u63d0\u4f9b\u7269\u7406\u9694\u79bb\u548c\u5197\u4f59\u3002\u4f8b\u5982\uff0c\u6bcf\u4e2a\u533a\u57df\u90fd\u53ef\u4ee5\u62e5\u6709\u5404\u81ea\u7684\u7535\u6e90\u4f9b\u5e94\u548c\u7f51\u7edc\u4e0a\u884c\u65b9\u6848\uff0c\u5e76\u4e14\u5404\u533a\u57df\u53ef\u4ee5\u5728\u5730\u7406\u4f4d\u7f6e\u4e0a\u76f8\u9694\u5f88\u8fdc(\u867d\u7136\u5e76\u975e\u5fc5\u987b\u76f8\u9694\u5f88\u8fdc)\u3002 +message.installWizard.copy.whatIsCloudStack=CloudStack&\#8482 \u662f\u4e00\u4e2a\u8f6f\u4ef6\u5e73\u53f0\uff0c\u53ef\u5c06\u8ba1\u7b97\u8d44\u6e90\u96c6\u4e2d\u5728\u4e00\u8d77\u4ee5\u6784\u5efa\u516c\u5171\u3001\u79c1\u6709\u548c\u6df7\u5408\u57fa\u7840\u8bbe\u65bd\u5373\u670d\u52a1(IaaS)\u4e91\u3002CloudStack&\#8482 \u8d1f\u8d23\u7ba1\u7406\u7ec4\u6210\u4e91\u57fa\u7840\u67b6\u6784\u7684\u7f51\u7edc\u3001\u5b58\u50a8\u548c\u8ba1\u7b97\u8282\u70b9\u3002\u4f7f\u7528 CloudStack&\#8482 \u53ef\u4ee5\u90e8\u7f72\u3001\u7ba1\u7406\u548c\u914d\u7f6e\u4e91\u8ba1\u7b97\u73af\u5883\u3002

CloudStack&\#8482 \u901a\u8fc7\u6269\u5c55\u5546\u7528\u786c\u4ef6\u4e0a\u8fd0\u884c\u7684\u6bcf\u4e2a\u865a\u62df\u673a\u6620\u50cf\u7684\u8303\u56f4\uff0c\u63d0\u4f9b\u4e86\u4e00\u4e2a\u5b9e\u65f6\u53ef\u7528\u7684\u4e91\u57fa\u7840\u67b6\u6784\u8f6f\u4ef6\u5806\u6808\u7528\u4e8e\u4ee5\u670d\u52a1\u65b9\u5f0f\u4ea4\u4ed8\u865a\u62df\u6570\u636e\u4e2d\u5fc3\uff0c\u5373\u4ea4\u4ed8\u6784\u5efa\u3001\u90e8\u7f72\u548c\u7ba1\u7406\u591a\u5c42\u6b21\u548c\u591a\u79df\u6237\u4e91\u5e94\u7528\u7a0b\u5e8f\u5fc5\u9700\u7684\u6240\u6709\u7ec4\u4ef6\u3002\u5f00\u6e90\u7248\u672c\u548c Premium \u7248\u672c\u90fd\u5df2\u53ef\u7528\uff0c\u4e14\u63d0\u4f9b\u7684\u529f\u80fd\u51e0\u4e4e\u5b8c\u5168\u76f8\u540c\u3002 +message.installWizard.copy.whatIsPrimaryStorage=CloudStack&\#8482; \u4e91\u57fa\u7840\u67b6\u6784\u4f7f\u7528\u4ee5\u4e0b\u4e24\u79cd\u7c7b\u578b\u7684\u5b58\u50a8\: \u4e3b\u5b58\u50a8\u548c\u8f85\u52a9\u5b58\u50a8\u3002\u8fd9\u4e24\u79cd\u7c7b\u578b\u7684\u5b58\u50a8\u53ef\u4ee5\u662f iSCSI \u6216 NFS \u670d\u52a1\u5668\uff0c\u4e5f\u53ef\u4ee5\u662f\u672c\u5730\u78c1\u76d8\u3002

\u4e3b\u5b58\u50a8\u4e0e\u7fa4\u96c6\u76f8\u5173\u8054\uff0c\u7528\u4e8e\u5b58\u50a8\u8be5\u7fa4\u96c6\u4e2d\u7684\u4e3b\u673a\u4e0a\u6b63\u5728\u8fd0\u884c\u7684\u6240\u6709 VM \u5bf9\u5e94\u7684\u6bcf\u4e2a\u6765\u5bbe VM \u7684\u78c1\u76d8\u5377\u3002\u4e3b\u5b58\u50a8\u670d\u52a1\u5668\u901a\u5e38\u4f4d\u4e8e\u9760\u8fd1\u4e3b\u673a\u7684\u4f4d\u7f6e\u3002 +message.installWizard.copy.whatIsSecondaryStorage=\u8f85\u52a9\u5b58\u50a8\u4e0e\u533a\u57df\u76f8\u5173\u8054\uff0c\u7528\u4e8e\u5b58\u50a8\u4ee5\u4e0b\u9879\u76ee\:
  • \u6a21\u677f - \u53ef\u7528\u4e8e\u542f\u52a8 VM \u5e76\u53ef\u4ee5\u5305\u542b\u5176\u4ed6\u914d\u7f6e\u4fe1\u606f(\u4f8b\u5982\uff0c\u5df2\u5b89\u88c5\u7684\u5e94\u7528\u7a0b\u5e8f)\u7684\u64cd\u4f5c\u7cfb\u7edf\u6620\u50cf
  • ISO \u6620\u50cf - \u53ef\u91cd\u65b0\u542f\u52a8\u6216\u4e0d\u53ef\u91cd\u65b0\u542f\u52a8\u7684\u64cd\u4f5c\u7cfb\u7edf\u6620\u50cf
  • \u78c1\u76d8\u5377\u5feb\u7167 - \u5df2\u4fdd\u5b58\u7684 VM \u6570\u636e\u526f\u672c\uff0c\u53ef\u7528\u4e8e\u6267\u884c\u6570\u636e\u6062\u590d\u6216\u521b\u5efa\u65b0\u6a21\u677f
message.installWizard.now.building=\u73b0\u5728\u6b63\u5728\u6784\u5efa\u60a8\u7684\u4e91... message.installWizard.tooltip.addCluster.name=\u7fa4\u96c6\u7684\u540d\u79f0\u3002\u6b64\u540d\u79f0\u53ef\u4ee5\u662f\u60a8\u9009\u62e9\u7684\u6587\u672c\uff0c\u4e14\u672a\u7531 CloudStack \u4f7f\u7528\u3002 message.installWizard.tooltip.addHost.hostname=\u4e3b\u673a\u7684 DNS \u540d\u79f0\u6216 IP \u5730\u5740\u3002 message.installWizard.tooltip.addHost.password=\u6b64\u4e3a\u4e0a\u8ff0\u7528\u6237\u7684\u5bc6\u7801(\u6765\u81ea XenServer \u5b89\u88c5)\u3002 message.installWizard.tooltip.addHost.username=\u901a\u5e38\u4e3a root\u3002 message.installWizard.tooltip.addPod.name=\u63d0\u4f9b\u70b9\u7684\u540d\u79f0 -message.installWizard.tooltip.addPod.reservedSystemEndIp=\u6b64\u4e3a CloudStack \u7528\u4e8e\u7ba1\u7406\u4e8c\u7ea7\u5b58\u50a8 VM \u548c\u63a7\u5236\u53f0\u4ee3\u7406 VM \u7684\u4e13\u7528\u7f51\u7edc\u4e2d\u7684 IP \u8303\u56f4\u3002\u8fd9\u4e9b IP \u5730\u5740\u6765\u81ea\u4e0e\u8ba1\u7b97\u670d\u52a1\u5668\u76f8\u540c\u7684\u5b50\u7f51\u3002 +message.installWizard.tooltip.addPod.reservedSystemEndIp=\u6b64\u4e3a CloudStack \u7528\u4e8e\u7ba1\u7406\u8f85\u52a9\u5b58\u50a8 VM \u548c\u63a7\u5236\u53f0\u4ee3\u7406 VM \u7684\u4e13\u7528\u7f51\u7edc\u4e2d\u7684 IP \u8303\u56f4\u3002\u8fd9\u4e9b IP \u5730\u5740\u6765\u81ea\u4e0e\u8ba1\u7b97\u670d\u52a1\u5668\u76f8\u540c\u7684\u5b50\u7f51\u3002 message.installWizard.tooltip.addPod.reservedSystemGateway=\u8be5\u63d0\u4f9b\u70b9\u4e2d\u7684\u4e3b\u673a\u7f51\u5173\u3002 message.installWizard.tooltip.addPod.reservedSystemNetmask=\u6765\u5bbe\u5c06\u8981\u4f7f\u7528\u7684\u5b50\u7f51\u4e0a\u6b63\u5728\u4f7f\u7528\u7684\u7f51\u7edc\u63a9\u7801\u3002 -message.installWizard.tooltip.addPod.reservedSystemStartIp=\u6b64\u4e3a CloudStack \u7528\u4e8e\u7ba1\u7406\u4e8c\u7ea7\u5b58\u50a8 VM \u548c\u63a7\u5236\u53f0\u4ee3\u7406 VM \u7684\u4e13\u7528\u7f51\u7edc\u4e2d\u7684 IP \u8303\u56f4\u3002\u8fd9\u4e9b IP \u5730\u5740\u6765\u81ea\u4e0e\u8ba1\u7b97\u670d\u52a1\u5668\u76f8\u540c\u7684\u5b50\u7f51\u3002 +message.installWizard.tooltip.addPod.reservedSystemStartIp=\u6b64\u4e3a CloudStack \u7528\u4e8e\u7ba1\u7406\u8f85\u52a9\u5b58\u50a8 VM \u548c\u63a7\u5236\u53f0\u4ee3\u7406 VM \u7684\u4e13\u7528\u7f51\u7edc\u4e2d\u7684 IP \u8303\u56f4\u3002\u8fd9\u4e9b IP \u5730\u5740\u6765\u81ea\u4e0e\u8ba1\u7b97\u670d\u52a1\u5668\u76f8\u540c\u7684\u5b50\u7f51\u3002 message.installWizard.tooltip.addPrimaryStorage.name=\u5b58\u50a8\u8bbe\u5907\u7684\u540d\u79f0\u3002 -message.installWizard.tooltip.addPrimaryStorage.path=(\u9002\u7528\u4e8e NFS)\u5728 NFS \u4e2d\uff0c\u6b64\u8def\u5f84\u4e3a\u670d\u52a1\u5668\u7684\u5bfc\u51fa\u8def\u5f84\u3002\u8def\u5f84(\u9488\u5bf9 SharedMountPoint)\u3002\u5bf9\u4e8e KVM\uff0c\u6b64\u8def\u5f84\u4e3a\u88c5\u8f7d\u4e86\u4e8c\u7ea7\u5b58\u50a8\u7684\u6bcf\u4e2a\u4e3b\u673a\u4e0a\u7684\u8def\u5f84\u3002\u4f8b\u5982\uff0c/mnt/primary\u3002 +message.installWizard.tooltip.addPrimaryStorage.path=(\u9002\u7528\u4e8e NFS)\u5728 NFS \u4e2d\uff0c\u6b64\u8def\u5f84\u4e3a\u670d\u52a1\u5668\u7684\u5bfc\u51fa\u8def\u5f84\u3002\u8def\u5f84(\u9488\u5bf9 SharedMountPoint)\u3002\u5bf9\u4e8e KVM\uff0c\u6b64\u8def\u5f84\u4e3a\u88c5\u8f7d\u4e86\u8f85\u52a9\u5b58\u50a8\u7684\u6bcf\u4e2a\u4e3b\u673a\u4e0a\u7684\u8def\u5f84\u3002\u4f8b\u5982\uff0c/mnt/primary\u3002 message.installWizard.tooltip.addPrimaryStorage.server=(\u9002\u7528\u4e8e NFS\u3001iSCSI \u6216 PreSetup)\u5b58\u50a8\u8bbe\u5907\u7684 IP \u5730\u5740\u6216 DNS \u540d\u79f0\u3002 -message.installWizard.tooltip.addSecondaryStorage.nfsServer=\u6258\u7ba1\u4e8c\u7ea7\u5b58\u50a8\u7684 NFS \u670d\u52a1\u5668\u7684 IP \u5730\u5740 +message.installWizard.tooltip.addSecondaryStorage.nfsServer=\u6258\u7ba1\u8f85\u52a9\u5b58\u50a8\u7684 NFS \u670d\u52a1\u5668\u7684 IP \u5730\u5740 message.installWizard.tooltip.addSecondaryStorage.path=\u5bfc\u51fa\u8def\u5f84(\u4f4d\u4e8e\u4e0a\u8ff0\u6307\u5b9a\u670d\u52a1\u5668\u4e0a) -message.installWizard.tooltip.addZone.dns1=\u8fd9\u4e9b\u670d\u52a1\u5668\u662f\u4f9b\u6b64\u8d44\u6e90\u57df\u4e2d\u7684\u6765\u5bbe VM \u4f7f\u7528\u7684 DNS \u670d\u52a1\u5668\uff0c\u5c06\u901a\u8fc7\u60a8\u7a0d\u540e\u8981\u6dfb\u52a0\u7684\u516c\u7528\u7f51\u7edc\u8fdb\u884c\u8bbf\u95ee\u3002\u6b64\u8d44\u6e90\u57df\u7684\u516c\u7528 IP \u5730\u5740\u5fc5\u987b\u8def\u7531\u5230\u5728\u6b64\u5904\u6307\u5b9a\u7684 DNS \u670d\u52a1\u5668\u3002 -message.installWizard.tooltip.addZone.dns2=\u8fd9\u4e9b\u670d\u52a1\u5668\u662f\u4f9b\u6b64\u8d44\u6e90\u57df\u4e2d\u7684\u6765\u5bbe VM \u4f7f\u7528\u7684 DNS \u670d\u52a1\u5668\uff0c\u5c06\u901a\u8fc7\u60a8\u7a0d\u540e\u8981\u6dfb\u52a0\u7684\u516c\u7528\u7f51\u7edc\u8fdb\u884c\u8bbf\u95ee\u3002\u6b64\u8d44\u6e90\u57df\u7684\u516c\u7528 IP \u5730\u5740\u5fc5\u987b\u8def\u7531\u5230\u5728\u6b64\u5904\u6307\u5b9a\u7684 DNS \u670d\u52a1\u5668\u3002 -message.installWizard.tooltip.addZone.internaldns1=\u8fd9\u4e9b\u670d\u52a1\u5668\u662f\u4f9b\u6b64\u8d44\u6e90\u57df\u4e2d\u7684\u7cfb\u7edf VM \u4f7f\u7528\u7684 DNS \u670d\u52a1\u5668\uff0c\u5c06\u901a\u8fc7\u7cfb\u7edf VM \u7684\u4e13\u7528\u7f51\u7edc\u63a5\u53e3\u8fdb\u884c\u8bbf\u95ee\u3002\u60a8\u4e3a\u63d0\u4f9b\u70b9\u63d0\u4f9b\u7684\u4e13\u7528 IP \u5730\u5740\u5fc5\u987b\u8def\u7531\u5230\u5728\u6b64\u5904\u6307\u5b9a\u7684 DNS \u670d\u52a1\u5668\u3002 -message.installWizard.tooltip.addZone.internaldns2=\u8fd9\u4e9b\u670d\u52a1\u5668\u662f\u4f9b\u6b64\u8d44\u6e90\u57df\u4e2d\u7684\u7cfb\u7edf VM \u4f7f\u7528\u7684 DNS \u670d\u52a1\u5668\uff0c\u5c06\u901a\u8fc7\u7cfb\u7edf VM \u7684\u4e13\u7528\u7f51\u7edc\u63a5\u53e3\u8fdb\u884c\u8bbf\u95ee\u3002\u60a8\u4e3a\u63d0\u4f9b\u70b9\u63d0\u4f9b\u7684\u4e13\u7528 IP \u5730\u5740\u5fc5\u987b\u8def\u7531\u5230\u5728\u6b64\u5904\u6307\u5b9a\u7684 DNS \u670d\u52a1\u5668\u3002 -message.installWizard.tooltip.addZone.name=\u8d44\u6e90\u57df\u540d\u79f0 +message.installWizard.tooltip.addZone.dns1=\u8fd9\u4e9b\u670d\u52a1\u5668\u662f\u4f9b\u6b64\u533a\u57df\u4e2d\u7684\u6765\u5bbe VM \u4f7f\u7528\u7684 DNS \u670d\u52a1\u5668\uff0c\u5c06\u901a\u8fc7\u60a8\u7a0d\u540e\u8981\u6dfb\u52a0\u7684\u516c\u7528\u7f51\u7edc\u8fdb\u884c\u8bbf\u95ee\u3002\u6b64\u533a\u57df\u7684\u516c\u7528 IP \u5730\u5740\u5fc5\u987b\u8def\u7531\u5230\u5728\u6b64\u5904\u6307\u5b9a\u7684 DNS \u670d\u52a1\u5668\u3002 +message.installWizard.tooltip.addZone.dns2=\u8fd9\u4e9b\u670d\u52a1\u5668\u662f\u4f9b\u6b64\u533a\u57df\u4e2d\u7684\u6765\u5bbe VM \u4f7f\u7528\u7684 DNS \u670d\u52a1\u5668\uff0c\u5c06\u901a\u8fc7\u60a8\u7a0d\u540e\u8981\u6dfb\u52a0\u7684\u516c\u7528\u7f51\u7edc\u8fdb\u884c\u8bbf\u95ee\u3002\u6b64\u533a\u57df\u7684\u516c\u7528 IP \u5730\u5740\u5fc5\u987b\u8def\u7531\u5230\u5728\u6b64\u5904\u6307\u5b9a\u7684 DNS \u670d\u52a1\u5668\u3002 +message.installWizard.tooltip.addZone.internaldns1=\u8fd9\u4e9b\u670d\u52a1\u5668\u662f\u4f9b\u6b64\u533a\u57df\u4e2d\u7684\u7cfb\u7edf VM \u4f7f\u7528\u7684 DNS \u670d\u52a1\u5668\uff0c\u5c06\u901a\u8fc7\u7cfb\u7edf VM \u7684\u4e13\u7528\u7f51\u7edc\u63a5\u53e3\u8fdb\u884c\u8bbf\u95ee\u3002\u60a8\u4e3a\u63d0\u4f9b\u70b9\u63d0\u4f9b\u7684\u4e13\u7528 IP \u5730\u5740\u5fc5\u987b\u8def\u7531\u5230\u5728\u6b64\u5904\u6307\u5b9a\u7684 DNS \u670d\u52a1\u5668\u3002 +message.installWizard.tooltip.addZone.internaldns2=\u8fd9\u4e9b\u670d\u52a1\u5668\u662f\u4f9b\u6b64\u533a\u57df\u4e2d\u7684\u7cfb\u7edf VM \u4f7f\u7528\u7684 DNS \u670d\u52a1\u5668\uff0c\u5c06\u901a\u8fc7\u7cfb\u7edf VM \u7684\u4e13\u7528\u7f51\u7edc\u63a5\u53e3\u8fdb\u884c\u8bbf\u95ee\u3002\u60a8\u4e3a\u63d0\u4f9b\u70b9\u63d0\u4f9b\u7684\u4e13\u7528 IP \u5730\u5740\u5fc5\u987b\u8def\u7531\u5230\u5728\u6b64\u5904\u6307\u5b9a\u7684 DNS \u670d\u52a1\u5668\u3002 +message.installWizard.tooltip.addZone.name=\u533a\u57df\u540d\u79f0 message.installWizard.tooltip.configureGuestTraffic.description=\u60a8\u7684\u7f51\u7edc\u8bf4\u660e -message.installWizard.tooltip.configureGuestTraffic.guestEndIp=\u80fd\u591f\u5206\u914d\u7ed9\u6b64\u8d44\u6e90\u57df\u4e2d\u7684\u6765\u5bbe\u7684 IP \u5730\u5740\u8303\u56f4\u3002\u5982\u679c\u4f7f\u7528\u4e00\u4e2a NIC\uff0c\u8fd9\u4e9b IP \u5e94\u4f4d\u4e8e\u4e0e\u63d0\u4f9b\u70b9 CIDR \u76f8\u540c\u7684 CIDR \u4e2d\u3002 +message.installWizard.tooltip.configureGuestTraffic.guestEndIp=\u80fd\u591f\u5206\u914d\u7ed9\u6b64\u533a\u57df\u4e2d\u7684\u6765\u5bbe\u7684 IP \u5730\u5740\u8303\u56f4\u3002\u5982\u679c\u4f7f\u7528\u4e00\u4e2a NIC\uff0c\u8fd9\u4e9b IP \u5e94\u4f4d\u4e8e\u4e0e\u63d0\u4f9b\u70b9 CIDR \u76f8\u540c\u7684 CIDR \u4e2d\u3002 message.installWizard.tooltip.configureGuestTraffic.guestGateway=\u6765\u5bbe\u5e94\u4f7f\u7528\u7684\u7f51\u5173 message.installWizard.tooltip.configureGuestTraffic.guestNetmask=\u6765\u5bbe\u5e94\u4f7f\u7528\u7684\u5b50\u7f51\u4e0a\u6b63\u5728\u4f7f\u7528\u7684\u7f51\u7edc\u63a9\u7801 -message.installWizard.tooltip.configureGuestTraffic.guestStartIp=\u80fd\u591f\u5206\u914d\u7ed9\u6b64\u8d44\u6e90\u57df\u4e2d\u7684\u6765\u5bbe\u7684 IP \u5730\u5740\u8303\u56f4\u3002\u5982\u679c\u4f7f\u7528\u4e00\u4e2a NIC\uff0c\u8fd9\u4e9b IP \u5e94\u4f4d\u4e8e\u4e0e\u63d0\u4f9b\u70b9 CIDR \u76f8\u540c\u7684 CIDR \u4e2d\u3002 +message.installWizard.tooltip.configureGuestTraffic.guestStartIp=\u80fd\u591f\u5206\u914d\u7ed9\u6b64\u533a\u57df\u4e2d\u7684\u6765\u5bbe\u7684 IP \u5730\u5740\u8303\u56f4\u3002\u5982\u679c\u4f7f\u7528\u4e00\u4e2a NIC\uff0c\u8fd9\u4e9b IP \u5e94\u4f4d\u4e8e\u4e0e\u63d0\u4f9b\u70b9 CIDR \u76f8\u540c\u7684 CIDR \u4e2d\u3002 message.installWizard.tooltip.configureGuestTraffic.name=\u60a8\u7684\u7f51\u7edc\u540d\u79f0 +message.instance.scaled.up.confirm=\u662f\u5426\u786e\u5b9e\u8981\u6269\u5c55\u60a8\u7684\u5b9e\u4f8b? message.instanceWizard.noTemplates=\u60a8\u6ca1\u6709\u4efb\u4f55\u53ef\u7528\u6a21\u677f\uff1b\u8bf7\u6dfb\u52a0\u4e00\u4e2a\u517c\u5bb9\u7684\u6a21\u677f\uff0c\u7136\u540e\u91cd\u65b0\u542f\u52a8\u5b9e\u4f8b\u5411\u5bfc\u3002 message.ip.address.changed=\u60a8\u7684 IP \u5730\u5740\u53ef\u80fd\u5df2\u53d1\u751f\u53d8\u5316\uff1b\u662f\u5426\u8981\u5237\u65b0\u6b64\u5217\u8868? \u8bf7\u6ce8\u610f\uff0c\u5237\u65b0\u6b64\u5217\u8868\u65f6\uff0c\u201c\u8be6\u7ec6\u4fe1\u606f\u201d\u7a97\u683c\u5c06\u5173\u95ed\u3002 message.iso.desc=\u78c1\u76d8\u6620\u50cf\uff0c\u5176\u4e2d\u5305\u542b\u64cd\u4f5c\u7cfb\u7edf\u7684\u6570\u636e\u6216\u53ef\u542f\u52a8\u4ecb\u8d28 message.join.project=\u60a8\u73b0\u5728\u5df2\u52a0\u5165\u4e86\u4e00\u4e2a\u9879\u76ee\u3002\u8bf7\u5207\u6362\u5230\u201c\u9879\u76ee\u89c6\u56fe\u201d\u4ee5\u67e5\u770b\u9879\u76ee\u3002 message.launch.vm.on.private.network=\u662f\u5426\u8981\u5728\u60a8\u7684\u79c1\u4eba\u4e13\u7528\u7f51\u7edc\u4e2d\u542f\u52a8\u5b9e\u4f8b? -message.launch.zone=\u8d44\u6e90\u57df\u5df2\u51c6\u5907\u5c31\u7eea\uff0c\u53ef\u968f\u65f6\u542f\u52a8\uff1b\u8bf7\u7ee7\u7eed\u6267\u884c\u4e0b\u4e00\u6b65\u9aa4\u3002 +message.launch.zone=\u533a\u57df\u5df2\u51c6\u5907\u5c31\u7eea\uff0c\u53ef\u968f\u65f6\u542f\u52a8\uff1b\u8bf7\u7ee7\u7eed\u6267\u884c\u4e0b\u4e00\u6b65\u9aa4\u3002 message.lock.account=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u9501\u5b9a\u6b64\u5e10\u6237\u3002\u901a\u8fc7\u9501\u5b9a\u6b64\u5e10\u6237\uff0c\u6b64\u5e10\u6237\u7684\u6240\u6709\u7528\u6237\u5c06\u4e0d\u518d\u80fd\u591f\u7ba1\u7406\u5404\u81ea\u7684\u4e91\u8d44\u6e90\uff0c\u4f46\u4ecd\u7136\u53ef\u4ee5\u8bbf\u95ee\u73b0\u6709\u8d44\u6e90\u3002 message.migrate.instance.confirm=\u8bf7\u786e\u8ba4\u8981\u5c06\u865a\u62df\u5b9e\u4f8b\u8fc1\u79fb\u5230\u7684\u4e3b\u673a\u3002 message.migrate.instance.to.host=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5c06\u5b9e\u4f8b\u8fc1\u79fb\u5230\u5176\u4ed6\u4e3b\u673a\u3002 @@ -1713,8 +1754,12 @@ message.migrate.instance.to.ps=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5c06\ message.migrate.router.confirm=\u8bf7\u786e\u8ba4\u60a8\u8981\u5c06\u8def\u7531\u5668\u8fc1\u79fb\u5230\u7684\u4e3b\u673a\: message.migrate.systemvm.confirm=\u8bf7\u786e\u8ba4\u60a8\u8981\u5c06\u7cfb\u7edf VM \u8fc1\u79fb\u5230\u7684\u4e3b\u673a\: message.migrate.volume=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5c06\u5377\u8fc1\u79fb\u5230\u5176\u4ed6\u4e3b\u5b58\u50a8\u3002 +message.network.addVM.desc=\u8bf7\u6307\u5b9a\u8981\u5c06\u6b64 VM \u6dfb\u52a0\u5230\u7684\u7f51\u7edc\u3002\u5c06\u4e3a\u6b64\u7f51\u7edc\u6dfb\u52a0\u4e00\u4e2a\u65b0 NIC\u3002 +message.network.addVMNIC=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u4e3a\u6b64\u7f51\u7edc\u6dfb\u52a0\u4e00\u4e2a\u65b0 VM NIC\u3002 message.new.user=\u8bf7\u6307\u5b9a\u4ee5\u4e0b\u4fe1\u606f\u4ee5\u5411\u5e10\u6237\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u65b0\u7528\u6237 -message.no.network.support.configuration.not.true=\u60a8\u7684\u6240\u6709\u8d44\u6e90\u57df\u90fd\u672a\u542f\u7528\u5b89\u5168\u7ec4\uff0c\u56e0\u6b64\u65e0\u5176\u4ed6\u7f51\u7edc\u529f\u80fd\u3002\u8bf7\u7ee7\u7eed\u6267\u884c\u6b65\u9aa4 5\u3002 +message.no.affinity.groups=\u60a8\u6ca1\u6709\u4efb\u4f55\u5173\u8054\u6027\u7ec4\u3002\u8bf7\u7ee7\u7eed\u6267\u884c\u4e0b\u4e00\u6b65\u64cd\u4f5c\u3002 +message.no.host.available=\u6ca1\u6709\u53ef\u7528\u4e8e\u8fc1\u79fb\u7684\u4e3b\u673a +message.no.network.support.configuration.not.true=\u60a8\u7684\u6240\u6709\u533a\u57df\u90fd\u672a\u542f\u7528\u5b89\u5168\u7ec4\uff0c\u56e0\u6b64\u65e0\u5176\u4ed6\u7f51\u7edc\u529f\u80fd\u3002\u8bf7\u7ee7\u7eed\u6267\u884c\u6b65\u9aa4 5\u3002 message.no.network.support=\u60a8\u9009\u62e9\u7684\u865a\u62df\u673a\u7ba1\u7406\u7a0b\u5e8f vSphere \u6ca1\u6709\u4efb\u4f55\u5176\u4ed6\u7f51\u7edc\u529f\u80fd\u3002\u8bf7\u7ee7\u7eed\u6267\u884c\u6b65\u9aa4 5\u3002 message.no.projects.adminOnly=\u60a8\u6ca1\u6709\u4efb\u4f55\u9879\u76ee\u3002
\u8bf7\u8981\u6c42\u7ba1\u7406\u5458\u521b\u5efa\u4e00\u4e2a\u65b0\u9879\u76ee\u3002 message.no.projects=\u60a8\u6ca1\u6709\u4efb\u4f55\u9879\u76ee\u3002
\u8bf7\u4ece\u201c\u9879\u76ee\u201d\u90e8\u5206\u4e2d\u521b\u5efa\u4e00\u4e2a\u65b0\u9879\u76ee\u3002 @@ -1722,20 +1767,24 @@ message.number.clusters=

\u7fa4\u96c6\u6570

message.number.hosts=

\u4e3b\u673a\u6570

message.number.pods=

\u63d0\u4f9b\u70b9\u6570

message.number.storage=

\u4e3b\u5b58\u50a8\u5377\u6570

-message.number.zones=

\u8d44\u6e90\u57df\u6570

+message.number.zones=

\u533a\u57df\u6570

message.pending.projects.1=\u60a8\u6709\u5f85\u5b9a\u9879\u76ee\u9080\u8bf7\: message.pending.projects.2=\u8981\u67e5\u770b\uff0c\u8bf7\u8f6c\u81f3\u201c\u9879\u76ee\u201d\u90e8\u5206\uff0c\u7136\u540e\u4ece\u4e0b\u62c9\u5217\u8868\u4e2d\u9009\u62e9\u201c\u9080\u8bf7\u201d\u3002 -message.please.add.at.lease.one.traffic.range=\u8bf7\u81f3\u5c11\u6dfb\u52a0\u4e00\u4e2a\u6d41\u91cf\u8303\u56f4\u3002 +message.please.add.at.lease.one.traffic.range=\u8bf7\u81f3\u5c11\u6dfb\u52a0\u4e00\u4e2a\u901a\u4fe1\u8303\u56f4\u3002 message.please.proceed=\u8bf7\u7ee7\u7eed\u6267\u884c\u4e0b\u4e2a\u6b65\u9aa4\u3002 -message.please.select.a.configuration.for.your.zone=\u8bf7\u4e3a\u60a8\u7684\u8d44\u6e90\u57df\u9009\u62e9\u4e00\u79cd\u914d\u7f6e\u3002 -message.please.select.a.different.public.and.management.network.before.removing=\u8bf7\u5148\u9009\u62e9\u5176\u4ed6\u516c\u7528\u7ba1\u7406\u7f51\u7edc\uff0c\u7136\u540e\u518d\u5220\u9664 +message.please.select.a.configuration.for.your.zone=\u8bf7\u4e3a\u60a8\u7684\u533a\u57df\u9009\u62e9\u4e00\u79cd\u914d\u7f6e\u3002 +message.please.select.a.different.public.and.management.network.before.removing=\u8bf7\u5148\u9009\u62e9\u5176\u4ed6\u516c\u5171\u7ba1\u7406\u7f51\u7edc\uff0c\u7136\u540e\u518d\u5220\u9664 message.please.select.networks=\u8bf7\u4e3a\u60a8\u7684\u865a\u62df\u673a\u9009\u62e9\u7f51\u7edc\u3002 -message.please.wait.while.zone.is.being.created=\u6b63\u5728\u521b\u5efa\u8d44\u6e90\u57df\uff0c\u8bf7\u7a0d\u5019\uff1b\u6b64\u64cd\u4f5c\u53ef\u80fd\u9700\u8981\u4e00\u6bb5\u65f6\u95f4\u624d\u80fd\u5b8c\u6210... +message.please.wait.while.zone.is.being.created=\u6b63\u5728\u521b\u5efa\u533a\u57df\uff0c\u8bf7\u7a0d\u5019\uff1b\u6b64\u64cd\u4f5c\u53ef\u80fd\u9700\u8981\u4e00\u6bb5\u65f6\u95f4\u624d\u80fd\u5b8c\u6210... +message.pod.dedication.released=\u5df2\u91ca\u653e\u4e13\u7528\u63d0\u4f9b\u70b9 +message.portable.ip.delete.confirm=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664\u53ef\u79fb\u690d IP \u8303\u56f4 message.project.invite.sent=\u53d1\u9001\u7ed9\u7528\u6237\u7684\u9080\u8bf7\uff1b\u7528\u6237\u63a5\u53d7\u9080\u8bf7\u540e\uff0c\u5c06\u52a0\u5165\u5230\u9879\u76ee\u4e2d -message.public.traffic.in.advanced.zone=\u4e91\u4e2d\u7684 VM \u8bbf\u95ee Internet \u65f6\u5c06\u751f\u6210\u516c\u5171\u6d41\u91cf\uff0c\u4f46\u5fc5\u987b\u5206\u914d\u53ef\u516c\u5f00\u8bbf\u95ee\u7684 IP \u624d\u80fd\u5b9e\u73b0\u3002\u6700\u7ec8\u7528\u6237\u53ef\u4ee5\u4f7f\u7528 CloudStack UI \u83b7\u53d6\u8fd9\u4e9b IP\uff0c\u4ee5\u5728\u5176\u6765\u5bbe\u7f51\u7edc\u4e0e\u516c\u7528\u7f51\u7edc\u4e4b\u95f4\u6267\u884c NAT\u3002

\u8bf7\u81f3\u5c11\u4e3a Internet \u6d41\u91cf\u63d0\u4f9b\u4e00\u4e2a IP \u5730\u5740\u8303\u56f4\u3002 -message.public.traffic.in.basic.zone=\u4e91\u4e2d\u7684 VM \u8bbf\u95ee Internet \u6216\u901a\u8fc7 Internet \u5411\u5ba2\u6237\u7aef\u63d0\u4f9b\u670d\u52a1\u65f6\u5c06\u751f\u6210\u516c\u5171\u6d41\u91cf\uff0c\u4f46\u5fc5\u987b\u5206\u914d\u53ef\u516c\u5f00\u8bbf\u95ee\u7684 IP \u624d\u80fd\u5b9e\u73b0\u3002\u521b\u5efa\u5b9e\u4f8b\u65f6\uff0c\u5c06\u628a\u8fd9\u4e00\u7ec4\u516c\u7528 IP \u4e2d\u7684 IP (\u6765\u5bbe IP \u5730\u5740\u9664\u5916)\u5206\u914d\u7ed9\u6b64\u5b9e\u4f8b\u3002\u9759\u6001 1-1 NAT \u5c06\u5728\u516c\u7528 IP \u4e0e\u6765\u5bbe IP \u4e4b\u95f4\u81ea\u52a8\u8bbe\u7f6e\u3002\u6700\u7ec8\u7528\u6237\u8fd8\u53ef\u4ee5\u4f7f\u7528 CloudStack UI \u83b7\u53d6\u5176\u4ed6 IP\uff0c\u4ee5\u5728\u5176\u5b9e\u4f8b\u4e0e\u516c\u7528 IP \u4e4b\u95f4\u6267\u884c\u9759\u6001 NAT\u3002 -message.redirecting.region=\u6b63\u5728\u91cd\u5b9a\u5411\u5230\u5730\u7406\u533a\u57df... -message.remove.region=\u662f\u5426\u786e\u5b9e\u8981\u4ece\u6b64\u7ba1\u7406\u670d\u52a1\u5668\u4e2d\u5220\u9664\u6b64\u5730\u7406\u533a\u57df? +message.public.traffic.in.advanced.zone=\u4e91\u4e2d\u7684 VM \u8bbf\u95ee Internet \u65f6\u5c06\u751f\u6210\u516c\u5171\u901a\u4fe1\uff0c\u4f46\u5fc5\u987b\u5206\u914d\u53ef\u516c\u5f00\u8bbf\u95ee\u7684 IP \u624d\u80fd\u5b9e\u73b0\u3002\u6700\u7ec8\u7528\u6237\u53ef\u4ee5\u4f7f\u7528 CloudStack UI \u83b7\u53d6\u8fd9\u4e9b IP\uff0c\u4ee5\u5728\u5176\u6765\u5bbe\u7f51\u7edc\u4e0e\u516c\u7528\u7f51\u7edc\u4e4b\u95f4\u6267\u884c NAT\u3002

\u8bf7\u81f3\u5c11\u4e3a Internet \u901a\u4fe1\u63d0\u4f9b\u4e00\u4e2a IP \u5730\u5740\u8303\u56f4\u3002 +message.public.traffic.in.basic.zone=\u4e91\u4e2d\u7684 VM \u8bbf\u95ee Internet \u6216\u901a\u8fc7 Internet \u5411\u5ba2\u6237\u7aef\u63d0\u4f9b\u670d\u52a1\u65f6\u5c06\u751f\u6210\u516c\u5171\u901a\u4fe1\uff0c\u4f46\u5fc5\u987b\u5206\u914d\u53ef\u516c\u5f00\u8bbf\u95ee\u7684 IP \u624d\u80fd\u5b9e\u73b0\u3002\u521b\u5efa\u5b9e\u4f8b\u65f6\uff0c\u5c06\u628a\u8fd9\u4e00\u7ec4\u516c\u7528 IP \u4e2d\u7684 IP (\u6765\u5bbe IP \u5730\u5740\u9664\u5916)\u5206\u914d\u7ed9\u6b64\u5b9e\u4f8b\u3002\u9759\u6001 1-1 NAT \u5c06\u5728\u516c\u7528 IP \u4e0e\u6765\u5bbe IP \u4e4b\u95f4\u81ea\u52a8\u8bbe\u7f6e\u3002\u6700\u7ec8\u7528\u6237\u8fd8\u53ef\u4ee5\u4f7f\u7528 CloudStack UI \u83b7\u53d6\u5176\u4ed6 IP\uff0c\u4ee5\u5728\u5176\u5b9e\u4f8b\u4e0e\u516c\u7528 IP \u4e4b\u95f4\u6267\u884c\u9759\u6001 NAT\u3002 +message.read.admin.guide.scaling.up=\u5f00\u59cb\u6269\u5c55\u4e4b\u524d\uff0c\u8bf7\u9605\u8bfb\u7ba1\u7406\u6307\u5357\u4e2d\u7684\u52a8\u6001\u6269\u5c55\u90e8\u5206\u3002 +message.redirecting.region=\u6b63\u5728\u91cd\u5b9a\u5411\u5230\u533a\u57df... +message.remove.ldap=\u662f\u5426\u786e\u5b9e\u8981\u5220\u9664 LDAP \u914d\u7f6e? +message.remove.region=\u662f\u5426\u786e\u5b9e\u8981\u4ece\u6b64\u7ba1\u7406\u670d\u52a1\u5668\u4e2d\u5220\u9664\u6b64\u533a\u57df? message.remove.vpc=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664 VPC message.remove.vpn.access=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664\u4ee5\u4e0b\u7528\u6237\u7684 VPN \u8bbf\u95ee\u3002 message.reset.password.warning.notPasswordEnabled=\u521b\u5efa\u6b64\u5b9e\u4f8b\u7684\u6a21\u677f\u65f6\u672a\u542f\u7528\u5bc6\u7801 @@ -1745,17 +1794,23 @@ message.restart.mgmt.server=\u8bf7\u91cd\u65b0\u542f\u52a8\u7ba1\u7406\u670d\u52 message.restart.mgmt.usage.server=\u8bf7\u91cd\u65b0\u542f\u52a8\u7ba1\u7406\u670d\u52a1\u5668\u548c\u4f7f\u7528\u670d\u52a1\u5668\u4ee5\u4f7f\u60a8\u7684\u65b0\u8bbe\u7f6e\u751f\u6548\u3002 message.restart.network=\u6b64\u7f51\u7edc\u63d0\u4f9b\u7684\u6240\u6709\u670d\u52a1\u90fd\u5c06\u4e2d\u65ad\u3002\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u91cd\u65b0\u542f\u52a8\u6b64\u7f51\u7edc\u3002 message.restart.vpc=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u91cd\u65b0\u542f\u52a8 VPC +message.restoreVM=\u662f\u5426\u8981\u8fd8\u539f\u6b64 VM? message.security.group.usage=(\u6309\u4f4f Ctrl \u952e\u5e76\u5355\u51fb\u9f20\u6807\u53ef\u9009\u62e9\u6240\u6709\u9002\u7528\u7684\u5b89\u5168\u7ec4) -message.select.a.zone=\u4e00\u4e2a\u8d44\u6e90\u57df\u901a\u5e38\u4e0e\u4e00\u4e2a\u6570\u636e\u4e2d\u5fc3\u76f8\u5bf9\u5e94\u3002\u591a\u4e2a\u8d44\u6e90\u57df\u53ef\u4ee5\u63d0\u4f9b\u7269\u7406\u9694\u79bb\u548c\u5197\u4f59\uff0c\u6709\u52a9\u4e8e\u4f7f\u4e91\u66f4\u52a0\u53ef\u9760\u3002 +message.select.affinity.groups=\u8bf7\u9009\u62e9\u60a8\u5e0c\u671b\u6b64 VM \u6240\u5c5e\u7684\u4efb\u4f55\u5173\u8054\u6027\u7ec4\: +message.select.a.zone=\u4e00\u4e2a\u533a\u57df\u901a\u5e38\u4e0e\u4e00\u4e2a\u6570\u636e\u4e2d\u5fc3\u76f8\u5bf9\u5e94\u3002\u591a\u4e2a\u533a\u57df\u53ef\u4ee5\u63d0\u4f9b\u7269\u7406\u9694\u79bb\u548c\u5197\u4f59\uff0c\u6709\u52a9\u4e8e\u4f7f\u4e91\u66f4\u52a0\u53ef\u9760\u3002 message.select.instance=\u8bf7\u9009\u62e9\u4e00\u4e2a\u5b9e\u4f8b\u3002 message.select.iso=\u8bf7\u4e3a\u60a8\u7684\u65b0\u865a\u62df\u5b9e\u4f8b\u9009\u62e9\u4e00\u4e2a ISO\u3002 message.select.item=\u8bf7\u9009\u62e9\u4e00\u4e2a\u9879\u76ee\u3002 message.select.security.groups=\u8bf7\u4e3a\u60a8\u7684\u65b0 VM \u9009\u62e9\u5b89\u5168\u7ec4 message.select.template=\u8bf7\u4e3a\u60a8\u7684\u65b0\u865a\u62df\u5b9e\u4f8b\u9009\u62e9\u4e00\u4e2a\u6a21\u677f\u3002 -message.setup.physical.network.during.zone.creation.basic=\u6dfb\u52a0\u57fa\u7840\u8d44\u6e90\u57df\u65f6\uff0c\u53ef\u4ee5\u8bbe\u7f6e\u4e00\u4e2a\u7269\u7406\u7f51\u7edc\uff0c\u6b64\u7f51\u7edc\u5e94\u4e0e\u865a\u62df\u673a\u7ba1\u7406\u7a0b\u5e8f\u4e2d\u7684 NIC \u76f8\u5bf9\u5e94\u3002\u6b64\u7f51\u7edc\u53ef\u4ee5\u627f\u8f7d\u591a\u79cd\u6d41\u91cf\u7c7b\u578b\u3002

\u6b64\u5916\uff0c\u8fd8\u53ef\u4ee5\u5c06\u5176\u4ed6\u6d41\u91cf\u7c7b\u578b\u62d6\u653e\u5230\u6b64\u7269\u7406\u7f51\u7edc\u3002 -message.setup.physical.network.during.zone.creation=\u6dfb\u52a0\u9ad8\u7ea7\u8d44\u6e90\u57df\u65f6\uff0c\u9700\u8981\u8bbe\u7f6e\u4e00\u4e2a\u6216\u591a\u4e2a\u7269\u7406\u7f51\u7edc\u3002\u6bcf\u4e2a\u7f51\u7edc\u90fd\u4e0e\u865a\u62df\u673a\u7ba1\u7406\u7a0b\u5e8f\u4e2d\u7684\u4e00\u4e2a NIC \u76f8\u5bf9\u5e94\u3002\u6bcf\u4e2a\u7269\u7406\u7f51\u7edc\u4e2d\u53ef\u4ee5\u5305\u542b\u4e00\u79cd\u6216\u591a\u79cd\u6d41\u91cf\u7c7b\u578b\uff0c\u5e76\u5bf9\u8fd9\u4e9b\u6d41\u91cf\u7c7b\u578b\u53ef\u80fd\u7684\u7ec4\u5408\u65b9\u5f0f\u8bbe\u7f6e\u4e86\u67d0\u4e9b\u9650\u5236\u3002

\u53ef\u4ee5\u5c06\u4e00\u79cd\u6216\u591a\u79cd\u6d41\u91cf\u7c7b\u578b\u62d6\u653e\u5230\u6bcf\u4e2a\u7269\u7406\u7f51\u7edc\u4e2d\u3002 +message.select.tier=\u8bf7\u9009\u62e9\u4e00\u4e2a\u5c42 +message.set.default.NIC.manual=\u8bf7\u7acb\u5373\u624b\u52a8\u66f4\u65b0\u6b64 VM \u4e0a\u7684\u9ed8\u8ba4 NIC\u3002 +message.set.default.NIC=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5c06\u6b64 NIC \u8bbe\u7f6e\u4e3a\u6b64 VM \u7684\u9ed8\u8ba4 NIC\u3002 +message.setup.physical.network.during.zone.creation.basic=\u6dfb\u52a0\u57fa\u7840\u533a\u57df\u65f6\uff0c\u53ef\u4ee5\u8bbe\u7f6e\u4e00\u4e2a\u7269\u7406\u7f51\u7edc\uff0c\u6b64\u7f51\u7edc\u5e94\u4e0e\u865a\u62df\u673a\u7ba1\u7406\u7a0b\u5e8f\u4e2d\u7684 NIC \u76f8\u5bf9\u5e94\u3002\u6b64\u7f51\u7edc\u53ef\u4ee5\u627f\u8f7d\u591a\u79cd\u901a\u4fe1\u7c7b\u578b\u3002

\u6b64\u5916\uff0c\u8fd8\u53ef\u4ee5\u5c06\u5176\u4ed6\u901a\u4fe1\u7c7b\u578b\u62d6\u653e\u5230\u6b64\u7269\u7406\u7f51\u7edc\u3002 +message.setup.physical.network.during.zone.creation=\u6dfb\u52a0\u9ad8\u7ea7\u533a\u57df\u65f6\uff0c\u9700\u8981\u8bbe\u7f6e\u4e00\u4e2a\u6216\u591a\u4e2a\u7269\u7406\u7f51\u7edc\u3002\u6bcf\u4e2a\u7f51\u7edc\u90fd\u4e0e\u865a\u62df\u673a\u7ba1\u7406\u7a0b\u5e8f\u4e2d\u7684\u4e00\u4e2a NIC \u76f8\u5bf9\u5e94\u3002\u6bcf\u4e2a\u7269\u7406\u7f51\u7edc\u4e2d\u53ef\u4ee5\u5305\u542b\u4e00\u79cd\u6216\u591a\u79cd\u901a\u4fe1\u7c7b\u578b\uff0c\u5e76\u5bf9\u8fd9\u4e9b\u901a\u4fe1\u7c7b\u578b\u53ef\u80fd\u7684\u7ec4\u5408\u65b9\u5f0f\u8bbe\u7f6e\u4e86\u67d0\u4e9b\u9650\u5236\u3002

\u53ef\u4ee5\u5c06\u4e00\u79cd\u6216\u591a\u79cd\u901a\u4fe1\u7c7b\u578b\u62d6\u653e\u5230\u6bcf\u4e2a\u7269\u7406\u7f51\u7edc\u4e2d\u3002 message.setup.successful=\u5df2\u6210\u529f\u8bbe\u7f6e\u4e91\! message.snapshot.schedule=\u53ef\u4ee5\u901a\u8fc7\u4ece\u4ee5\u4e0b\u53ef\u7528\u9009\u9879\u4e2d\u8fdb\u884c\u9009\u62e9\u5e76\u5e94\u7528\u60a8\u7684\u7b56\u7565\u9996\u9009\u9879\u6765\u8bbe\u7f6e\u91cd\u73b0\u5feb\u7167\u8ba1\u5212 +message.specifiy.tag.key.value=\u8bf7\u6307\u5b9a\u6807\u8bb0\u5bc6\u94a5\u548c\u503c message.specify.url=\u8bf7\u6307\u5b9a URL message.step.1.continue=\u8bf7\u9009\u62e9\u4e00\u4e2a\u6a21\u677f\u6216 ISO \u4ee5\u7ee7\u7eed message.step.1.desc=\u8bf7\u4e3a\u60a8\u7684\u65b0\u865a\u62df\u5b9e\u4f8b\u9009\u62e9\u4e00\u4e2a\u6a21\u677f\u3002\u8fd8\u53ef\u4ee5\u9009\u62e9\u4e00\u4e2a\u53ef\u5c06 ISO \u6620\u50cf\u5b89\u88c5\u5230\u5176\u4e2d\u7684\u7a7a\u6a21\u677f\u3002 @@ -1765,118 +1820,59 @@ message.step.3.continue=\u8bf7\u9009\u62e9\u4e00\u79cd\u78c1\u76d8\u65b9\u6848\u message.step.3.desc= message.step.4.continue=\u8bf7\u81f3\u5c11\u9009\u62e9\u4e00\u4e2a\u7f51\u7edc\u4ee5\u7ee7\u7eed message.step.4.desc=\u8bf7\u9009\u62e9\u865a\u62df\u5b9e\u4f8b\u8981\u8fde\u63a5\u5230\u7684\u4e3b\u7f51\u7edc\u3002 -message.storage.traffic=CloudStack \u5185\u90e8\u8d44\u6e90(\u5305\u62ec\u4e0e\u7ba1\u7406\u670d\u52a1\u5668\u901a\u4fe1\u7684\u4efb\u4f55\u7ec4\u4ef6\uff0c\u4f8b\u5982\u4e3b\u673a\u548c CloudStack \u7cfb\u7edf VM)\u4e4b\u95f4\u7684\u6d41\u91cf\u3002\u8bf7\u5728\u6b64\u5904\u914d\u7f6e\u5b58\u50a8\u6d41\u91cf\u3002 +message.storage.traffic=CloudStack \u5185\u90e8\u8d44\u6e90(\u5305\u62ec\u4e0e\u7ba1\u7406\u670d\u52a1\u5668\u901a\u4fe1\u7684\u4efb\u4f55\u7ec4\u4ef6\uff0c\u4f8b\u5982\u4e3b\u673a\u548c CloudStack \u7cfb\u7edf VM)\u4e4b\u95f4\u7684\u901a\u4fe1\u3002\u8bf7\u5728\u6b64\u5904\u914d\u7f6e\u5b58\u50a8\u901a\u4fe1\u3002 message.suspend.project=\u662f\u5426\u786e\u5b9e\u8981\u6682\u505c\u6b64\u9879\u76ee? +message.systems.vms.ready=\u7cfb\u7edf VM \u5df2\u5c31\u7eea\u3002 +message.template.copying=\u6b63\u5728\u590d\u5236\u6a21\u677f\u3002 message.template.desc=\u64cd\u4f5c\u7cfb\u7edf\u6620\u50cf\uff0c\u53ef\u7528\u4e8e\u542f\u52a8 VM -message.tooltip.dns.1=\u4f9b\u8d44\u6e90\u57df\u4e2d\u7684 VM \u4f7f\u7528\u7684 DNS \u670d\u52a1\u5668\u540d\u79f0\u3002\u8d44\u6e90\u57df\u7684\u516c\u7528 IP \u5730\u5740\u5fc5\u987b\u8def\u7531\u5230\u6b64\u670d\u52a1\u5668\u3002 -message.tooltip.dns.2=\u4f9b\u8d44\u6e90\u57df\u4e2d\u7684 VM \u4f7f\u7528\u7684\u4e8c\u7ea7 DNS \u670d\u52a1\u5668\u540d\u79f0\u3002\u8d44\u6e90\u57df\u7684\u516c\u7528 IP \u5730\u5740\u5fc5\u987b\u8def\u7531\u5230\u6b64\u670d\u52a1\u5668\u3002 -message.tooltip.internal.dns.1=\u4f9b\u8d44\u6e90\u57df\u4e2d\u7684 CloudStack \u5185\u90e8\u7cfb\u7edf VM \u4f7f\u7528\u7684 DNS \u670d\u52a1\u5668\u540d\u79f0\u3002\u63d0\u4f9b\u70b9\u7684\u4e13\u7528 IP \u5730\u5740\u5fc5\u987b\u8def\u7531\u5230\u6b64\u670d\u52a1\u5668\u3002 -message.tooltip.internal.dns.2=\u4f9b\u8d44\u6e90\u57df\u4e2d\u7684 CloudStack \u5185\u90e8\u7cfb\u7edf VM \u4f7f\u7528\u7684 DNS \u670d\u52a1\u5668\u540d\u79f0\u3002\u63d0\u4f9b\u70b9\u7684\u4e13\u7528 IP \u5730\u5740\u5fc5\u987b\u8def\u7531\u5230\u6b64\u670d\u52a1\u5668\u3002 +message.tier.required=\u201c\u5c42\u201d\u4e3a\u5fc5\u586b\u9879 +message.tooltip.dns.1=\u4f9b\u533a\u57df\u4e2d\u7684 VM \u4f7f\u7528\u7684 DNS \u670d\u52a1\u5668\u540d\u79f0\u3002\u533a\u57df\u7684\u516c\u7528 IP \u5730\u5740\u5fc5\u987b\u8def\u7531\u5230\u6b64\u670d\u52a1\u5668\u3002 +message.tooltip.dns.2=\u4f9b\u533a\u57df\u4e2d\u7684 VM \u4f7f\u7528\u7684\u8f85\u52a9 DNS \u670d\u52a1\u5668\u540d\u79f0\u3002\u533a\u57df\u7684\u516c\u7528 IP \u5730\u5740\u5fc5\u987b\u8def\u7531\u5230\u6b64\u670d\u52a1\u5668\u3002 +message.tooltip.internal.dns.1=\u4f9b\u533a\u57df\u4e2d\u7684 CloudStack \u5185\u90e8\u7cfb\u7edf VM \u4f7f\u7528\u7684 DNS \u670d\u52a1\u5668\u540d\u79f0\u3002\u63d0\u4f9b\u70b9\u7684\u4e13\u7528 IP \u5730\u5740\u5fc5\u987b\u8def\u7531\u5230\u6b64\u670d\u52a1\u5668\u3002 +message.tooltip.internal.dns.2=\u4f9b\u533a\u57df\u4e2d\u7684 CloudStack \u5185\u90e8\u7cfb\u7edf VM \u4f7f\u7528\u7684 DNS \u670d\u52a1\u5668\u540d\u79f0\u3002\u63d0\u4f9b\u70b9\u7684\u4e13\u7528 IP \u5730\u5740\u5fc5\u987b\u8def\u7531\u5230\u6b64\u670d\u52a1\u5668\u3002 message.tooltip.network.domain=DNS \u540e\u7f00\uff0c\u5c06\u4e3a\u7531\u6765\u5bbe VM \u8bbf\u95ee\u7684\u7f51\u7edc\u521b\u5efa\u4e00\u4e2a\u81ea\u5b9a\u4e49\u57df\u540d\u3002 message.tooltip.pod.name=\u6b64\u63d0\u4f9b\u70b9\u7684\u540d\u79f0\u3002 message.tooltip.reserved.system.gateway=\u63d0\u4f9b\u70b9\u4e2d\u7684\u4e3b\u673a\u7f51\u5173\u3002 message.tooltip.reserved.system.netmask=\u7528\u4e8e\u5b9a\u4e49\u63d0\u4f9b\u70b9\u5b50\u7f51\u7684\u7f51\u7edc\u524d\u7f00\u3002\u8bf7\u4f7f\u7528 CIDR \u7b26\u53f7\u3002 -message.tooltip.zone.name=\u8d44\u6e90\u57df\u540d\u79f0\u3002 +message.tooltip.zone.name=\u533a\u57df\u540d\u79f0\u3002 message.update.os.preference=\u8bf7\u4e3a\u6b64\u4e3b\u673a\u9009\u62e9\u4e00\u4e2a\u64cd\u4f5c\u7cfb\u7edf\u9996\u9009\u9879\u3002\u9996\u5148\u5c06\u5177\u6709\u76f8\u4f3c\u9996\u9009\u9879\u7684\u6240\u6709\u865a\u62df\u5b9e\u4f8b\u5206\u914d\u81f3\u6b64\u4e3b\u673a\uff0c\u7136\u540e\u518d\u9009\u62e9\u5176\u4ed6\u5b9e\u4f8b\u3002 message.update.resource.count=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u66f4\u65b0\u6b64\u5e10\u6237\u7684\u8d44\u6e90\u6570\u3002 message.update.ssl=\u8bf7\u63d0\u4ea4\u4e00\u4e2a\u65b0\u7684 X.509 \u517c\u5bb9\u7684 SSL \u8bc1\u4e66\uff0c\u4ee5\u4fbf\u5c06\u5176\u66f4\u65b0\u5230\u6bcf\u4e2a\u63a7\u5236\u53f0\u4ee3\u7406\u865a\u62df\u5b9e\u4f8b\: -message.validate.instance.name=\u5b9e\u4f8b\u540d\u79f0\u4e0d\u5f97\u8d85\u8fc7 63 \u4e2a\u5b57\u7b26\u3002\u4ec5\u5141\u8bb8\u4f7f\u7528 ASCII \u5b57\u6bcd a - z \u6216 A - Z\u3001\u6570\u5b57 0 - 9 \u4ee5\u53ca\u8fde\u5b57\u7b26\u3002\u5b9e\u4f8b\u540d\u79f0\u5fc5\u987b\u4ee5\u5b57\u6bcd\u5f00\u5934\u5e76\u4ee5\u5b57\u6bcd\u6216\u6570\u5b57\u7ed3\u675f\u3002 -message.virtual.network.desc=\u60a8\u7684\u5e10\u6237\u7684\u4e13\u7528\u865a\u62df\u7f51\u7edc\u3002\u5e7f\u64ad\u57df\u5305\u542b\u5728 VLAN \u4e2d\uff0c\u5e76\u4e14\u6240\u6709\u516c\u7528\u7f51\u7edc\u8bbf\u95ee\u90fd\u7531\u865a\u62df\u8def\u7531\u5668\u8def\u7531\u51fa\u53bb\u3002 -message.vm.create.template.confirm=\u521b\u5efa\u6a21\u677f\u5c06\u81ea\u52a8\u91cd\u65b0\u542f\u52a8 VM\u3002 -message.vm.review.launch=\u8bf7\u5148\u6838\u5bf9\u4ee5\u4e0b\u4fe1\u606f\uff0c\u786e\u8ba4\u60a8\u7684\u865a\u62df\u5b9e\u4f8b\u6b63\u786e\u65e0\u8bef\uff0c\u7136\u540e\u518d\u542f\u52a8\u3002 -message.volume.create.template.confirm=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u4e3a\u6b64\u78c1\u76d8\u5377\u521b\u5efa\u4e00\u4e2a\u6a21\u677f\u3002\u521b\u5efa\u6a21\u677f\u53ef\u80fd\u9700\u8981\u51e0\u5206\u949f\u5230\u66f4\u957f\u7684\u65f6\u95f4\uff0c\u5177\u4f53\u53d6\u51b3\u4e8e\u5377\u7684\u5927\u5c0f\u3002 -message.you.must.have.at.least.one.physical.network=\u60a8\u5fc5\u987b\u81f3\u5c11\u62e5\u6709\u4e00\u4e2a\u7269\u7406\u7f51\u7edc -message.zone.creation.complete.would.you.like.to.enable.this.zone=\u5df2\u5b8c\u6210\u521b\u5efa\u8d44\u6e90\u57df\u3002\u662f\u5426\u8981\u542f\u7528\u6b64\u8d44\u6e90\u57df? -message.Zone.creation.complete=\u5df2\u5b8c\u6210\u521b\u5efa\u8d44\u6e90\u57df -message.zone.no.network.selection=\u6240\u9009\u8d44\u6e90\u57df\u65e0\u4efb\u4f55\u7f51\u7edc\u9009\u9879\u3002 -message.zone.step.1.desc=\u8bf7\u4e3a\u60a8\u7684\u8d44\u6e90\u57df\u9009\u62e9\u4e00\u79cd\u7f51\u7edc\u6a21\u5f0f\u3002 -message.zone.step.2.desc=\u8bf7\u8f93\u5165\u4ee5\u4e0b\u4fe1\u606f\u4ee5\u6dfb\u52a0\u4e00\u4e2a\u65b0\u8d44\u6e90\u57df -message.zone.step.3.desc=\u8bf7\u8f93\u5165\u4ee5\u4e0b\u4fe1\u606f\u4ee5\u6dfb\u52a0\u4e00\u4e2a\u65b0\u63d0\u4f9b\u70b9 -message.zoneWizard.enable.local.storage=\u8b66\u544a\: \u5982\u679c\u4e3a\u6b64\u8d44\u6e90\u57df\u542f\u7528\u4e86\u672c\u5730\u5b58\u50a8\uff0c\u5219\u5fc5\u987b\u6267\u884c\u4ee5\u4e0b\u64cd\u4f5c\uff0c\u5177\u4f53\u53d6\u51b3\u4e8e\u60a8\u5e0c\u671b\u542f\u52a8\u7cfb\u7edf VM \u7684\u4f4d\u7f6e\:

1. \u5982\u679c\u9700\u8981\u5728\u4e3b\u5b58\u50a8\u4e2d\u542f\u52a8\u7cfb\u7edf VM\uff0c\u5219\u5fc5\u987b\u5728\u5b8c\u6210\u521b\u5efa\u540e\u5c06\u4e3b\u5b58\u50a8\u6dfb\u52a0\u5230\u6b64\u8d44\u6e90\u57df\u4e2d\u3002

2. \u5982\u679c\u9700\u8981\u5728\u672c\u5730\u5b58\u50a8\u4e2d\u542f\u52a8\u7cfb\u7edf VM\uff0c\u5219\u5fc5\u987b\u5c06 system.vm.use.local.storage \u8bbe\u7f6e\u4e3a true\u3002


\u662f\u5426\u8981\u7ee7\u7eed? -message.validate.fieldrequired=\u6b64\u5b57\u6bb5\u4e3a\u5fc5\u586b\u5b57\u6bb5\u3002 -message.validate.fixfield=\u8bf7\u4fee\u590d\u6b64\u5b57\u6bb5\u3002 -message.validate.email.address=\u8bf7\u8f93\u5165\u4e00\u4e2a\u6709\u6548\u7684\u7535\u5b50\u90ae\u4ef6\u5730\u5740\u3002 -message.validate.URL=\u8bf7\u8f93\u5165\u6709\u6548\u7684 URL\u3002 -message.validate.date=\u8bf7\u8f93\u5165\u6709\u6548\u7684\u65e5\u671f\u3002 +message.validate.accept=\u8bf7\u8f93\u5165\u4e00\u4e2a\u5e26\u6709\u6709\u6548\u6269\u5c55\u540d\u7684\u503c\u3002 +message.validate.creditcard=\u8bf7\u8f93\u5165\u4e00\u4e2a\u6709\u6548\u7684\u4fe1\u7528\u5361\u5361\u53f7\u3002 message.validate.date.ISO=\u8bf7\u8f93\u5165\u6709\u6548\u7684\u65e5\u671f(ISO)\u3002 -message.validate.number=\u8bf7\u8f93\u5165\u4e00\u4e2a\u6709\u6548\u6570\u5b57\u3002 +message.validate.date=\u8bf7\u8f93\u5165\u6709\u6548\u7684\u65e5\u671f\u3002 message.validate.digits=\u8bf7\u4ec5\u8f93\u5165\u6570\u5b57\u3002 -message.validate.creditcard=\u8bf7\u8f93\u5165\u4e00\u4e2a\u6709\u6548\u7684\u4fe1\u7528\u5361\u5361\u53f7\u3002 +message.validate.email.address=\u8bf7\u8f93\u5165\u4e00\u4e2a\u6709\u6548\u7684\u7535\u5b50\u90ae\u4ef6\u5730\u5740\u3002 message.validate.equalto=\u8bf7\u91cd\u65b0\u8f93\u5165\u76f8\u540c\u7684\u503c\u3002 -message.validate.accept=\u8bf7\u8f93\u5165\u4e00\u4e2a\u5e26\u6709\u6709\u6548\u6269\u5c55\u540d\u7684\u503c\u3002 +message.validate.fieldrequired=\u6b64\u5b57\u6bb5\u4e3a\u5fc5\u586b\u5b57\u6bb5\u3002 +message.validate.fixfield=\u8bf7\u4fee\u590d\u6b64\u5b57\u6bb5\u3002 +message.validate.instance.name=\u5b9e\u4f8b\u540d\u79f0\u4e0d\u5f97\u8d85\u8fc7 63 \u4e2a\u5b57\u7b26\u3002\u4ec5\u5141\u8bb8\u4f7f\u7528 ASCII \u5b57\u6bcd a - z \u6216 A - Z\u3001\u6570\u5b57 0 - 9 \u4ee5\u53ca\u8fde\u5b57\u7b26\u3002\u5b9e\u4f8b\u540d\u79f0\u5fc5\u987b\u4ee5\u5b57\u6bcd\u5f00\u5934\u5e76\u4ee5\u5b57\u6bcd\u6216\u6570\u5b57\u7ed3\u675f\u3002 +message.validate.invalid.characters=\u67e5\u627e\u5230\u65e0\u6548\u5b57\u7b26\uff0c\u8bf7\u66f4\u6b63\u3002 message.validate.maxlength=\u8bf7\u6700\u591a\u8f93\u5165 {0} \u4e2a\u5b57\u7b26\u3002 +message.validate.max=\u8bf7\u8f93\u5165\u4e00\u4e2a\u5c0f\u4e8e\u6216\u7b49\u4e8e {0} \u7684\u503c\u3002 message.validate.minlength=\u8bf7\u81f3\u5c11\u8f93\u5165 {0} \u4e2a\u5b57\u7b26\u3002 +message.validate.number=\u8bf7\u8f93\u5165\u4e00\u4e2a\u6709\u6548\u6570\u5b57\u3002 message.validate.range.length=\u8bf7\u8f93\u5165\u4e00\u4e2a\u957f\u5ea6\u4ecb\u4e8e {0} \u5230 {1} \u4e4b\u95f4\u7684\u503c\u3002 message.validate.range=\u8bf7\u8f93\u5165\u4e00\u4e2a\u4ecb\u4e8e {0} \u5230 {1} \u4e4b\u95f4\u7684\u503c\u3002 -message.validate.max=\u8bf7\u8f93\u5165\u4e00\u4e2a\u5c0f\u4e8e\u6216\u7b49\u4e8e {0} \u7684\u503c\u3002 -messgae.validate.min=\u8bf7\u8f93\u5165\u4e00\u4e2a\u5927\u4e8e\u6216\u7b49\u4e8e {0} \u7684\u503c\u3002 -message.creating.systemVM=\u6b63\u5728\u521b\u5efa\u7cfb\u7edf VM (\u6b64\u64cd\u4f5c\u53ef\u80fd\u9700\u8981\u4e00\u4e9b\u65f6\u95f4) -message.enabling.zone.dots=\u6b63\u5728\u542f\u7528\u8d44\u6e90\u57df... -message.restoreVM=\u662f\u5426\u8981\u8fd8\u539f\u6b64 VM? -message.no.host.available=\u6ca1\u6709\u53ef\u7528\u4e8e\u8fc1\u79fb\u7684\u4e3b\u673a -message.network.addVM.desc=\u8bf7\u6307\u5b9a\u8981\u5c06\u6b64 VM \u6dfb\u52a0\u5230\u7684\u7f51\u7edc\u3002\u5c06\u4e3a\u6b64\u7f51\u7edc\u6dfb\u52a0\u4e00\u4e2a\u65b0 NIC\u3002 -message.network.addVMNIC=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u4e3a\u6b64\u7f51\u7edc\u6dfb\u52a0\u4e00\u4e2a\u65b0 VM NIC\u3002 -message.set.default.NIC=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5c06\u6b64 NIC \u8bbe\u7f6e\u4e3a\u6b64 VM \u7684\u9ed8\u8ba4 NIC\u3002 -message.set.default.NIC.manual=\u8bf7\u7acb\u5373\u624b\u52a8\u66f4\u65b0\u6b64 VM \u4e0a\u7684\u9ed8\u8ba4 NIC\u3002 -message.instance.scaled.up.confirm=\u662f\u5426\u786e\u5b9e\u8981\u6269\u5c55\u60a8\u7684\u5b9e\u4f8b? -message.copy.template.confirm=\u662f\u5426\u786e\u5b9e\u8981\u590d\u5236\u6a21\u677f? -message.template.copying=\u6b63\u5728\u590d\u5236\u6a21\u677f\u3002 -message.XSTools61plus.update.failed=\u65e0\u6cd5\u66f4\u65b0\u201cXenServer Tools \u7248\u672c 6.1\+\u201d\u5b57\u6bb5\u3002\u9519\u8bef\: -message.gslb.delete.confirm=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664\u6b64 GSLB -message.portable.ip.delete.confirm=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664\u53ef\u79fb\u690d IP \u8303\u56f4 -message.gslb.lb.remove.confirm=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u4ece GSLB \u4e2d\u5220\u9664\u8d1f\u8f7d\u5e73\u8861 -message.admin.guide.read=\u5bf9\u4e8e\u57fa\u4e8e VMware \u7684 VM\uff0c\u8bf7\u5148\u9605\u8bfb\u7ba1\u7406\u6307\u5357\u4e2d\u7684\u52a8\u6001\u6269\u5c55\u90e8\u5206\uff0c\u7136\u540e\u518d\u8fdb\u884c\u6269\u5c55\u3002\u662f\u5426\u8981\u7ee7\u7eed?\, -message.tier.required=\u201c\u5c42\u201d\u4e3a\u5fc5\u586b\u9879 -message.remove.ldap=\u662f\u5426\u786e\u5b9e\u8981\u5220\u9664 LDAP \u914d\u7f6e? -message.action.downloading.template=\u6b63\u5728\u4e0b\u8f7d\u6a21\u677f\u3002 -message.configure.ldap=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u914d\u7f6e LDAP\u3002 -message.confirm.delete.ciscovnmc.resource=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664 CiscoVNMC \u8d44\u6e90 -message.confirm.add.vnmc.provider=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u6dfb\u52a0 VNMC \u63d0\u4f9b\u7a0b\u5e8f\u3002 -message.confirm.enable.vnmc.provider=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u542f\u7528 VNMC \u63d0\u4f9b\u7a0b\u5e8f\u3002 -message.confirm.disable.vnmc.provider=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u7981\u7528 VNMC \u63d0\u4f9b\u7a0b\u5e8f\u3002 +message.validate.URL=\u8bf7\u8f93\u5165\u6709\u6548\u7684 URL\u3002 +message.virtual.network.desc=\u60a8\u7684\u5e10\u6237\u7684\u4e13\u7528\u865a\u62df\u7f51\u7edc\u3002\u5e7f\u64ad\u57df\u5305\u542b\u5728 VLAN \u4e2d\uff0c\u5e76\u4e14\u6240\u6709\u516c\u7528\u7f51\u7edc\u8bbf\u95ee\u90fd\u7531\u865a\u62df\u8def\u7531\u5668\u8def\u7531\u51fa\u53bb\u3002 +message.vm.create.template.confirm=\u521b\u5efa\u6a21\u677f\u5c06\u81ea\u52a8\u91cd\u65b0\u542f\u52a8 VM\u3002 +message.vm.review.launch=\u8bf7\u5148\u6838\u5bf9\u4ee5\u4e0b\u4fe1\u606f\uff0c\u786e\u8ba4\u60a8\u7684\u865a\u62df\u5b9e\u4f8b\u6b63\u786e\u65e0\u8bef\uff0c\u7136\u540e\u518d\u542f\u52a8\u3002 message.vnmc.available.list=\u63d0\u4f9b\u7a0b\u5e8f\u5217\u8868\u4e2d\u672a\u63d0\u4f9b VNMC\u3002 message.vnmc.not.available.list=\u63d0\u4f9b\u7a0b\u5e8f\u5217\u8868\u4e2d\u672a\u63d0\u4f9b VNMC\u3002 -message.confirm.release.dedicate.vlan.range=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u91ca\u653e\u4e13\u7528 VLAN \u8303\u56f4 -message.confirm.start.lb.vm=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u542f\u52a8 LB VM -message.confirm.stop.lb.vm=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u505c\u6b62 LB VM -message.confirm.remove.vmware.datacenter=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664 VMware \u6570\u636e\u4e2d\u5fc3 -message.confirm.dedicate.zone=\u662f\u5426\u8981\u5c06\u6b64\u8d44\u6e90\u57df\u4e13\u7528\u4e8e\u57df/\u5e10\u6237? -message.confirm.release.dedicated.zone=\u662f\u5426\u8981\u91ca\u653e\u6b64\u4e13\u7528\u8d44\u6e90\u57df? -message.dedicated.zone.released=\u5df2\u91ca\u653e\u4e13\u7528\u8d44\u6e90\u57df -message.read.admin.guide.scaling.up=\u5f00\u59cb\u6269\u5c55\u4e4b\u524d\uff0c\u8bf7\u9605\u8bfb\u7ba1\u7406\u6307\u5357\u4e2d\u7684\u52a8\u6001\u6269\u5c55\u90e8\u5206\u3002 -message.confirm.scale.up.system.vm=\u662f\u5426\u786e\u5b9e\u8981\u6269\u5c55\u7cfb\u7edf VM? -message.confirm.upgrade.router.newer.template=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5347\u7ea7\u8def\u7531\u5668\u4ee5\u4f7f\u7528\u66f4\u65b0\u7684\u6a21\u677f -message.confirm.scale.up.router.vm=\u662f\u5426\u786e\u5b9e\u8981\u6269\u5c55\u8def\u7531\u5668 VM? -message.confirm.upgrade.routers.newtemplate=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5347\u7ea7\u6b64\u8d44\u6e90\u57df\u4e2d\u7684\u6240\u6709\u8def\u7531\u5668\u4ee5\u4f7f\u7528\u66f4\u65b0\u7684\u6a21\u677f -message.confirm.upgrade.routers.pod.newtemplate=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5347\u7ea7\u6b64\u63d0\u4f9b\u70b9\u4e2d\u7684\u6240\u6709\u8def\u7531\u5668\u4ee5\u4f7f\u7528\u66f4\u65b0\u7684\u6a21\u677f -message.confirm.upgrade.routers.cluster.newtemplate=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5347\u7ea7\u6b64\u7fa4\u96c6\u4e2d\u7684\u6240\u6709\u8def\u7531\u5668\u4ee5\u4f7f\u7528\u66f4\u65b0\u7684\u6a21\u677f -message.confirm.upgrade.routers.account.newtemplate=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5347\u7ea7\u6b64\u5e10\u6237\u4e2d\u7684\u6240\u6709\u8def\u7531\u5668\u4ee5\u4f7f\u7528\u66f4\u65b0\u7684\u6a21\u677f -message.confirm.dedicate.pod.domain.account=\u662f\u5426\u786e\u5b9e\u8981\u5c06\u6b64\u63d0\u4f9b\u70b9\u4e13\u7528\u4e8e\u57df/\u5e10\u6237? -message.confirm.release.dedicated.pod=\u662f\u5426\u8981\u91ca\u653e\u6b64\u4e13\u7528\u63d0\u4f9b\u70b9? -message.pod.dedication.released=\u5df2\u91ca\u653e\u4e13\u7528\u63d0\u4f9b\u70b9 -message.confirm.dedicate.cluster.domain.account=\u662f\u5426\u786e\u5b9e\u8981\u5c06\u6b64\u7fa4\u96c6\u4e13\u7528\u4e8e\u57df/\u5e10\u6237? -message.cluster.dedicated=\u7fa4\u96c6\u5df2\u4e13\u7528 -message.confirm.release.dedicated.cluster=\u662f\u5426\u8981\u91ca\u653e\u6b64\u4e13\u7528\u7fa4\u96c6? -message.cluster.dedication.released=\u5df2\u91ca\u653e\u4e13\u7528\u7fa4\u96c6 -message.confirm.dedicate.host.domain.account=\u662f\u5426\u786e\u5b9e\u8981\u5c06\u6b64\u4e3b\u673a\u4e13\u7528\u4e8e\u57df/\u5e10\u6237? -message.host.dedicated=\u4e3b\u673a\u5df2\u4e13\u7528 -message.confirm.release.dedicated.host=\u662f\u5426\u8981\u91ca\u653e\u6b64\u4e13\u7528\u4e3b\u673a? -message.host.dedication.released=\u5df2\u91ca\u653e\u4e13\u7528\u4e3b\u673a -message.confirm.delete.ucs.manager=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664 UCS Manager -message.confirm.refresh.blades=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5237\u65b0\u5200\u7247\u5f0f\u670d\u52a1\u5668\u3002 -message.confirm.delete.secondary.staging.store=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664\u4e8c\u7ea7\u6682\u5b58\u5b58\u50a8\u3002 -message.select.tier=\u8bf7\u9009\u62e9\u4e00\u4e2a\u5c42 -message.disallowed.characters=\u7981\u7528\u5b57\u7b26: \<\,\> +message.volume.create.template.confirm=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u4e3a\u6b64\u78c1\u76d8\u5377\u521b\u5efa\u4e00\u4e2a\u6a21\u677f\u3002\u521b\u5efa\u6a21\u677f\u53ef\u80fd\u9700\u8981\u51e0\u5206\u949f\u5230\u66f4\u957f\u7684\u65f6\u95f4\uff0c\u5177\u4f53\u53d6\u51b3\u4e8e\u5377\u7684\u5927\u5c0f\u3002 message.waiting.for.builtin.templates.to.load=\u6b63\u5728\u7b49\u5f85\u52a0\u8f7d\u5185\u7f6e\u6a21\u677f... -message.systems.vms.ready=\u7cfb\u7edf VM \u5df2\u5c31\u7eea\u3002 +message.XSTools61plus.update.failed=\u65e0\u6cd5\u66f4\u65b0\u201cXenServer Tools \u7248\u672c 6.1\\+\u201d\u5b57\u6bb5\u3002\u9519\u8bef\: +message.you.must.have.at.least.one.physical.network=\u60a8\u5fc5\u987b\u81f3\u5c11\u62e5\u6709\u4e00\u4e2a\u7269\u7406\u7f51\u7edc message.your.cloudstack.is.ready=\u60a8\u7684 CloudStack \u5df2\u5c31\u7eea\! -message.specifiy.tag.key.value=\u8bf7\u6307\u5b9a\u6807\u8bb0\u5bc6\u94a5\u548c\u503c -message.enter.seperated.list.multiple.cidrs=\u5982\u679c\u5b58\u5728\u591a\u4e2a CIDR\uff0c\u8bf7\u8f93\u5165\u7528\u9017\u53f7\u5206\u9694\u7684 CIDR \u5217\u8868 -message.disabling.network.offering=\u6b63\u5728\u7981\u7528\u7f51\u7edc\u65b9\u6848 -message.confirm.enable.network.offering=\u662f\u5426\u786e\u5b9e\u8981\u542f\u7528\u6b64\u7f51\u7edc\u65b9\u6848? -message.enabling.network.offering=\u6b63\u5728\u542f\u7528\u7f51\u7edc\u65b9\u6848 -message.confirm.remove.network.offering=\u662f\u5426\u786e\u5b9e\u8981\u5220\u9664\u6b64\u7f51\u7edc\u65b9\u6848? -message.confirm.disable.network.offering=\u662f\u5426\u786e\u5b9e\u8981\u7981\u7528\u6b64\u7f51\u7edc\u65b9\u6848? +message.Zone.creation.complete=\u5df2\u5b8c\u6210\u521b\u5efa\u533a\u57df +message.zone.creation.complete.would.you.like.to.enable.this.zone=\u5df2\u5b8c\u6210\u521b\u5efa\u533a\u57df\u3002\u662f\u5426\u8981\u542f\u7528\u6b64\u533a\u57df? +message.zone.no.network.selection=\u6240\u9009\u533a\u57df\u65e0\u4efb\u4f55\u7f51\u7edc\u9009\u9879\u3002 +message.zone.step.1.desc=\u8bf7\u4e3a\u60a8\u7684\u533a\u57df\u9009\u62e9\u4e00\u79cd\u7f51\u7edc\u6a21\u5f0f\u3002 +message.zone.step.2.desc=\u8bf7\u8f93\u5165\u4ee5\u4e0b\u4fe1\u606f\u4ee5\u6dfb\u52a0\u4e00\u4e2a\u65b0\u533a\u57df +message.zone.step.3.desc=\u8bf7\u8f93\u5165\u4ee5\u4e0b\u4fe1\u606f\u4ee5\u6dfb\u52a0\u4e00\u4e2a\u65b0\u63d0\u4f9b\u70b9 +messgae.validate.min=\u8bf7\u8f93\u5165\u4e00\u4e2a\u5927\u4e8e\u6216\u7b49\u4e8e {0} \u7684\u503c\u3002 mode=\u6a21\u5f0f network.rate=\u7f51\u7edc\u901f\u7387 notification.reboot.instance=\u91cd\u65b0\u542f\u52a8\u5b9e\u4f8b @@ -1894,14 +1890,14 @@ state.Creating=\u6b63\u5728\u521b\u5efa state.Declined=\u5df2\u62d2\u7edd state.Destroyed=\u5df2\u9500\u6bc1 state.Disabled=\u5df2\u7981\u7528 -state.Enabled=\u5df2\u542f\u7528 state.enabled=\u5df2\u542f\u7528 +state.Enabled=\u5df2\u542f\u7528 state.Error=\u9519\u8bef state.Expunging=\u6b63\u5728\u5220\u9664 state.Migrating=\u6b63\u5728\u8fc1\u79fb state.Pending=\u5f85\u5b9a -state.Ready=\u5df2\u5c31\u7eea state.ready=\u5df2\u5c31\u7eea +state.Ready=\u5df2\u5c31\u7eea state.Running=\u6b63\u5728\u8fd0\u884c state.Starting=\u6b63\u5728\u542f\u52a8 state.Stopped=\u5df2\u505c\u6b62 diff --git a/client/pom.xml b/client/pom.xml index 74c459e769..1a972c9d3d 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -35,6 +35,11 @@ cloud-plugin-storage-volume-solidfire ${project.version}
+ + org.apache.cloudstack + cloud-plugin-storage-volume-cloudbyte + ${project.version} + org.apache.cloudstack cloud-server @@ -221,16 +226,6 @@ cloud-mom-inmemory ${project.version} - - org.apache.cloudstack - cloud-plugin-iam - ${project.version} - - - org.apache.cloudstack - cloud-iam - ${project.version} - org.apache.cloudstack cloud-framework-ipc diff --git a/client/tomcatconf/commands.properties.in b/client/tomcatconf/commands.properties.in index 45debe41a9..b9ac27b0ba 100644 --- a/client/tomcatconf/commands.properties.in +++ b/client/tomcatconf/commands.properties.in @@ -79,6 +79,7 @@ createSnapshot=15 listSnapshots=15 deleteSnapshot=15 createSnapshotPolicy=15 +updateSnapshotPolicy=15 deleteSnapshotPolicies=15 listSnapshotPolicies=15 revertSnapshot=15 @@ -146,7 +147,7 @@ listDedicatedGuestVlanRanges=1 associateIpAddress=15 disassociateIpAddress=15 listPublicIpAddresses=15 -updatePublicIpAddress=15 +updateIpAddress=15 #### firewall commands listPortForwardingRules=15 @@ -167,11 +168,13 @@ deleteLoadBalancerRule=15 removeFromLoadBalancerRule=15 assignToLoadBalancerRule=15 createLBStickinessPolicy=15 +updateLBStickinessPolicy=15 deleteLBStickinessPolicy=15 listLoadBalancerRules=15 listLBStickinessPolicies=15 listLBHealthCheckPolicies=15 createLBHealthCheckPolicy=15 +updateLBHealthCheckPolicy=15 deleteLBHealthCheckPolicy=15 listLoadBalancerRuleInstances=15 updateLoadBalancerRule=15 @@ -618,6 +621,8 @@ deleteStratoshereSsp=1 #### host simulator commands configureSimulator=1 +querySimulatorMock=1 +cleanupSimulatorMock=1 #### api discovery commands @@ -728,21 +733,6 @@ listLdapUsers=3 ldapCreateAccount=3 importLdapUsers=3 -### IAM commands -createIAMPolicy=1 -deleteIAMPolicy=1 -listIAMPolicies=1 -addIAMPermissionToIAMPolicy=1 -removeIAMPermissionFromIAMPolicy=1 -createIAMGroup=1 -deleteIAMGroup=1 -listIAMGroups=1 -addAccountToIAMGroup=1 -removeAccountFromIAMGroup=1 -attachIAMPolicyToIAMGroup=1 -removeIAMPolicyFromIAMGroup=1 -attachIAMPolicyToAccount=1 -removeIAMPolicyFromAccount=1 #### juniper-contrail commands createServiceInstance=1 diff --git a/core/resources/META-INF/cloudstack/core/spring-core-registry-core-context.xml b/core/resources/META-INF/cloudstack/core/spring-core-registry-core-context.xml index 0f58d7d35e..819fb830d5 100644 --- a/core/resources/META-INF/cloudstack/core/spring-core-registry-core-context.xml +++ b/core/resources/META-INF/cloudstack/core/spring-core-registry-core-context.xml @@ -46,7 +46,7 @@ + value="AffinityGroupAccessChecker,DomainChecker" /> + + + diff --git a/core/src/com/cloud/agent/api/GetGPUStatsAnswer.java b/core/src/com/cloud/agent/api/GetGPUStatsAnswer.java index 566eed5ab6..583326b839 100644 --- a/core/src/com/cloud/agent/api/GetGPUStatsAnswer.java +++ b/core/src/com/cloud/agent/api/GetGPUStatsAnswer.java @@ -23,14 +23,14 @@ @LogLevel(Log4jLevel.Trace) public class GetGPUStatsAnswer extends Answer { - private HashMap> groupDetails; + private HashMap> groupDetails; - public GetGPUStatsAnswer(GetGPUStatsCommand cmd, HashMap> groupDetails) { + public GetGPUStatsAnswer(GetGPUStatsCommand cmd, HashMap> groupDetails) { super(cmd); this.groupDetails = groupDetails; } - public HashMap> getGroupDetails() { + public HashMap> getGroupDetails() { return this.groupDetails; } } diff --git a/core/src/com/cloud/agent/api/GetRouterAlertsAnswer.java b/core/src/com/cloud/agent/api/GetRouterAlertsAnswer.java index 06a7a7a84e..31485396f4 100644 --- a/core/src/com/cloud/agent/api/GetRouterAlertsAnswer.java +++ b/core/src/com/cloud/agent/api/GetRouterAlertsAnswer.java @@ -22,7 +22,6 @@ public class GetRouterAlertsAnswer extends Answer { - String routerName; String[] alerts; String timeStamp; @@ -36,8 +35,8 @@ public GetRouterAlertsAnswer(GetRouterAlertsCommand cmd, String alerts[], String } - public GetRouterAlertsAnswer(GetRouterAlertsCommand cmd, Exception ex) { - super(cmd, ex); + public GetRouterAlertsAnswer(GetRouterAlertsCommand cmd, String details) { + super(cmd, false, details); } public void setAlerts(String[] alerts) { @@ -56,7 +55,4 @@ public String getTimeStamp() { return timeStamp; } - public String getRouterName() { - return routerName; - } } diff --git a/core/src/com/cloud/agent/api/GetVmConfigAnswer.java b/core/src/com/cloud/agent/api/GetVmConfigAnswer.java index 46e003ecae..e0d1536341 100644 --- a/core/src/com/cloud/agent/api/GetVmConfigAnswer.java +++ b/core/src/com/cloud/agent/api/GetVmConfigAnswer.java @@ -42,13 +42,15 @@ public List getNics() { public class NicDetails { String macAddress; int vlanid; + boolean state; public NicDetails() { } - public NicDetails(String macAddress, int vlanid) { + public NicDetails(String macAddress, int vlanid, boolean state) { this.macAddress = macAddress; this.vlanid = vlanid; + this.state = state; } public String getMacAddress() { @@ -59,6 +61,9 @@ public int getVlanid() { return vlanid; } + public boolean getState() { + return state; + } } @Override diff --git a/core/src/com/cloud/agent/api/MigrateCompleteCommand.java b/core/src/com/cloud/agent/api/MigrateCompleteCommand.java new file mode 100644 index 0000000000..3f78ecc0d9 --- /dev/null +++ b/core/src/com/cloud/agent/api/MigrateCompleteCommand.java @@ -0,0 +1,44 @@ +/* + * 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.agent.api.to.VirtualMachineTO; + +public class MigrateCompleteCommand extends Command { + VirtualMachineTO vm; + boolean executeInSequence = false; + + @Override + public boolean executeInSequence() { + return executeInSequence; + } + + public MigrateCompleteCommand(VirtualMachineTO vm, boolean executeInSequence) { + this.vm = vm; + this.executeInSequence = executeInSequence; + } + + public VirtualMachineTO getVm() { + return vm; + } + + public void setVm(VirtualMachineTO vm) { + this.vm = vm; + } +} diff --git a/core/src/com/cloud/agent/api/MigrateWithStorageDestPathsCommand.java b/core/src/com/cloud/agent/api/MigrateWithStorageDestPathsCommand.java new file mode 100644 index 0000000000..50271826b5 --- /dev/null +++ b/core/src/com/cloud/agent/api/MigrateWithStorageDestPathsCommand.java @@ -0,0 +1,55 @@ +/* + * 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.to.VirtualMachineTO; +import com.cloud.agent.api.to.VolumeTO; +import com.cloud.utils.Pair; + +public class MigrateWithStorageDestPathsCommand extends Command { + VirtualMachineTO vm; + List> volumeToDestPathsAsList; + String tgtHost; + + public MigrateWithStorageDestPathsCommand(VirtualMachineTO vm, List> volumeToDestPathsAsList, String tgtHost) { + this.vm = vm; + this.volumeToDestPathsAsList = volumeToDestPathsAsList; + this.tgtHost = tgtHost; + } + + public VirtualMachineTO getVm() { + return vm; + } + + public List> getVolumeToDestPathsAsList() { + return volumeToDestPathsAsList; + } + + public String getTgtHost() { + return tgtHost; + } + + @Override + public boolean executeInSequence() { + return true; + } + +} diff --git a/core/src/com/cloud/agent/api/MigrateWithStorageGetDestPathsAnswer.java b/core/src/com/cloud/agent/api/MigrateWithStorageGetDestPathsAnswer.java new file mode 100644 index 0000000000..9254f151c2 --- /dev/null +++ b/core/src/com/cloud/agent/api/MigrateWithStorageGetDestPathsAnswer.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.agent.api; + +import java.util.List; + +import com.cloud.agent.api.to.VolumeTO; +import com.cloud.utils.Pair; + +public class MigrateWithStorageGetDestPathsAnswer extends Answer { + List> volumeToDestPathsAsList; + + public MigrateWithStorageGetDestPathsAnswer(MigrateWithStorageGetDestPathsCommand cmd, Exception ex) { + super(cmd, ex); + volumeToDestPathsAsList = null; + } + + public MigrateWithStorageGetDestPathsAnswer(MigrateWithStorageGetDestPathsCommand cmd, List> volumeToDestPathsAsList) { + super(cmd, true, null); + this.volumeToDestPathsAsList = volumeToDestPathsAsList; + } + + public List> getVolumeToDestPathsAsList() { + return volumeToDestPathsAsList; + } +} diff --git a/core/src/com/cloud/agent/api/MigrateWithStorageGetDestPathsCommand.java b/core/src/com/cloud/agent/api/MigrateWithStorageGetDestPathsCommand.java new file mode 100644 index 0000000000..fafbc739fb --- /dev/null +++ b/core/src/com/cloud/agent/api/MigrateWithStorageGetDestPathsCommand.java @@ -0,0 +1,43 @@ +/* + * 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.to.StorageFilerTO; +import com.cloud.agent.api.to.VolumeTO; +import com.cloud.utils.Pair; + +public class MigrateWithStorageGetDestPathsCommand extends Command { + List> volumeToFilerAsList; + + public MigrateWithStorageGetDestPathsCommand(List> volumeToFilerAsList) { + this.volumeToFilerAsList = volumeToFilerAsList; + } + + public List> getVolumeToFilerAsList() { + return volumeToFilerAsList; + } + + @Override + public boolean executeInSequence() { + return true; + } + +} diff --git a/core/src/com/cloud/agent/api/ModifyVmNicConfigCommand.java b/core/src/com/cloud/agent/api/ModifyVmNicConfigCommand.java index 5f4f0e1d9a..54c0eb098b 100644 --- a/core/src/com/cloud/agent/api/ModifyVmNicConfigCommand.java +++ b/core/src/com/cloud/agent/api/ModifyVmNicConfigCommand.java @@ -22,6 +22,9 @@ public class ModifyVmNicConfigCommand extends Command { int vlan; String macAddress; int index; + boolean enable; + String switchLableName; + protected ModifyVmNicConfigCommand() { } @@ -37,10 +40,24 @@ public ModifyVmNicConfigCommand(String vmName, int vlan, int position) { this.index = position; } + public ModifyVmNicConfigCommand(String vmName, int vlan, int position, boolean enable) { + this.vmName = vmName; + this.vlan = vlan; + this.index = position; + this.enable = enable; + } + public String getVmName() { return vmName; } + public String getSwitchLableName() { + return switchLableName; + } + + public void setSwitchLableName(String switchlableName) { + this.switchLableName = switchlableName; + } @Override public boolean executeInSequence() { diff --git a/core/src/com/cloud/agent/api/PoolEjectCommand.java b/core/src/com/cloud/agent/api/PoolEjectCommand.java deleted file mode 100644 index fa6b651797..0000000000 --- a/core/src/com/cloud/agent/api/PoolEjectCommand.java +++ /dev/null @@ -1,44 +0,0 @@ -// 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 PoolEjectCommand extends Command { - private String hostuuid; - - public String getHostuuid() { - return hostuuid; - } - - public void setHostuuid(String hostuuid) { - this.hostuuid = hostuuid; - } - - public PoolEjectCommand() { - super(); - } - - public PoolEjectCommand(String hostuuid) { - super(); - setHostuuid(hostuuid); - } - - @Override - public boolean executeInSequence() { - return true; - } - -} diff --git a/core/src/com/cloud/agent/api/StartupRoutingCommand.java b/core/src/com/cloud/agent/api/StartupRoutingCommand.java index dc37113386..52814eac9a 100755 --- a/core/src/com/cloud/agent/api/StartupRoutingCommand.java +++ b/core/src/com/cloud/agent/api/StartupRoutingCommand.java @@ -70,7 +70,7 @@ public String getHost() { HypervisorType hypervisorType; Map hostDetails; //stuff like host os, cpu capabilities String hypervisorVersion; - HashMap> groupDetails = new HashMap>(); + HashMap> groupDetails = new HashMap>(); public StartupRoutingCommand() { super(Host.Type.Routing); @@ -246,11 +246,11 @@ public void setHostVmStateReport(Map hostVmState this._hostVmStateReport = hostVmStateReport; } - public HashMap> getGpuGroupDetails() { + public HashMap> getGpuGroupDetails() { return groupDetails; } - public void setGpuGroupDetails(HashMap> groupDetails) { + public void setGpuGroupDetails(HashMap> groupDetails) { this.groupDetails = groupDetails; } } diff --git a/core/src/com/cloud/agent/api/StopCommand.java b/core/src/com/cloud/agent/api/StopCommand.java index 00d7f5fff6..61d13e0f8e 100755 --- a/core/src/com/cloud/agent/api/StopCommand.java +++ b/core/src/com/cloud/agent/api/StopCommand.java @@ -25,26 +25,30 @@ public class StopCommand extends RebootCommand { private String publicConsoleProxyIpAddress = null; boolean executeInSequence = false; private GPUDeviceTO gpuDevice; + boolean checkBeforeCleanup = false; protected StopCommand() { } - public StopCommand(VirtualMachine vm, boolean isProxy, String urlPort, String publicConsoleProxyIpAddress, boolean executeInSequence) { + public StopCommand(VirtualMachine vm, boolean isProxy, String urlPort, String publicConsoleProxyIpAddress, boolean executeInSequence, boolean checkBeforeCleanup) { super(vm); this.isProxy = isProxy; this.urlPort = urlPort; this.publicConsoleProxyIpAddress = publicConsoleProxyIpAddress; this.executeInSequence = executeInSequence; + this.checkBeforeCleanup = checkBeforeCleanup; } - public StopCommand(VirtualMachine vm, boolean executeInSequence) { + public StopCommand(VirtualMachine vm, boolean executeInSequence, boolean checkBeforeCleanup) { super(vm); this.executeInSequence = executeInSequence; + this.checkBeforeCleanup = checkBeforeCleanup; } - public StopCommand(String vmName, boolean executeInSequence) { + public StopCommand(String vmName, boolean executeInSequence, boolean checkBeforeCleanup) { super(vmName); this.executeInSequence = executeInSequence; + this.checkBeforeCleanup = checkBeforeCleanup; } @Override @@ -71,4 +75,8 @@ public GPUDeviceTO getGpuDevice() { public void setGpuDevice(GPUDeviceTO gpuDevice) { this.gpuDevice = gpuDevice; } + + public boolean checkBeforeCleanup() { + return this.checkBeforeCleanup; + } } diff --git a/core/src/com/cloud/agent/api/VMSnapshotBaseCommand.java b/core/src/com/cloud/agent/api/VMSnapshotBaseCommand.java index d2abd54e04..2752965311 100644 --- a/core/src/com/cloud/agent/api/VMSnapshotBaseCommand.java +++ b/core/src/com/cloud/agent/api/VMSnapshotBaseCommand.java @@ -26,10 +26,11 @@ public class VMSnapshotBaseCommand extends Command { protected VMSnapshotTO target; protected String vmName; protected String guestOSType; + protected String platformEmulator; public VMSnapshotBaseCommand(String vmName, VMSnapshotTO snapshot, List volumeTOs, String guestOSType) { this.vmName = vmName; - this.target = snapshot; + target = snapshot; this.volumeTOs = volumeTOs; this.guestOSType = guestOSType; } @@ -70,4 +71,12 @@ public String getGuestOSType() { public void setGuestOSType(String guestOSType) { this.guestOSType = guestOSType; } + + public String getPlatformEmulator() { + return platformEmulator; + } + + public void setPlatformEmulator(String platformEmulator) { + this.platformEmulator = platformEmulator; + } } diff --git a/core/src/com/cloud/agent/api/storage/DeleteEntityDownloadURLAnswer.java b/core/src/com/cloud/agent/api/storage/DeleteEntityDownloadURLAnswer.java deleted file mode 100644 index 7b8da59c5d..0000000000 --- a/core/src/com/cloud/agent/api/storage/DeleteEntityDownloadURLAnswer.java +++ /dev/null @@ -1,37 +0,0 @@ -// 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.storage; - -import com.cloud.agent.api.Answer; - -public class DeleteEntityDownloadURLAnswer extends Answer { - - String resultString; - short resultCode; - public static final short RESULT_SUCCESS = 1; - public static final short RESULT_FAILURE = 0; - - public DeleteEntityDownloadURLAnswer(String resultString, short resultCode) { - super(); - this.resultString = resultString; - this.resultCode = resultCode; - } - - public DeleteEntityDownloadURLAnswer() { - } - -} diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRouterDeployer.java b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRouterDeployer.java index 243098abea..1feaaead9f 100644 --- a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRouterDeployer.java +++ b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRouterDeployer.java @@ -21,6 +21,8 @@ public interface VirtualRouterDeployer { ExecutionResult executeInVR(String routerIp, String script, String args); + /* timeout in seconds */ + ExecutionResult executeInVR(String routerIp, String script, String args, int timeout); ExecutionResult createFileInVR(String routerIp, String path, String filename, String content); ExecutionResult prepareCommand(NetworkElementCommand cmd); ExecutionResult cleanupCommand(NetworkElementCommand cmd); diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java index e13fbf651c..7bb6f5ea6c 100755 --- a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java +++ b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java @@ -134,6 +134,7 @@ protected class VRScripts { private int _sleep; private int _retry; private int _port; + private int _eachTimeout; private String _cfgVersion = "1.0"; @@ -649,25 +650,23 @@ private CheckS2SVpnConnectionsAnswer execute(CheckS2SVpnConnectionsCommand cmd) private GetRouterAlertsAnswer execute(GetRouterAlertsCommand cmd) { - String args = null; String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - if (cmd.getPreviousAlertTimeStamp() != null) { - args = cmd.getPreviousAlertTimeStamp(); - } + String args = cmd.getPreviousAlertTimeStamp(); ExecutionResult result = _vrDeployer.executeInVR(routerIp, VRScripts.ROUTER_ALERTS, args); String alerts[] = null; String lastAlertTimestamp = null; - // CallHostPlugin results "success" when there are no alerts on virtual router + if (result.isSuccess()) { - if (!result.getDetails().isEmpty() && !result.getDetails().equals("No Alerts")) { - alerts = result.getDetails().split("\\\\n"); - String[] lastAlert = alerts[alerts.length - 1].split(" "); - lastAlertTimestamp = lastAlert[0] + " " + lastAlert[1]; + if (!result.getDetails().isEmpty() && !result.getDetails().trim().equals("No Alerts")) { + alerts = result.getDetails().trim().split("\\\\n"); + String[] lastAlert = alerts[alerts.length - 1].split(","); + lastAlertTimestamp = lastAlert[0]; } + return new GetRouterAlertsAnswer(cmd, alerts, lastAlertTimestamp); + } else { + return new GetRouterAlertsAnswer(cmd, result.getDetails()); } - - return new GetRouterAlertsAnswer(cmd, alerts, lastAlertTimestamp); } protected Answer execute(CheckRouterCommand cmd) { @@ -760,21 +759,6 @@ protected List generateConfig(SetMonitorServiceCommand cmd) { return cfg; } - protected List generateConfig(GetRouterAlertsCommand cmd) { - LinkedList cfg = new LinkedList<>(); - - String args = null; - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - if (cmd.getPreviousAlertTimeStamp() != null) { - args = "getRouterAlerts.sh " + routerIp + " " + cmd.getPreviousAlertTimeStamp(); - } else { - args = "getRouterAlerts.sh " + routerIp; - } - - cfg.add(new ConfigItem(VRScripts.ROUTER_ALERTS, args)); - return cfg; - } - protected List generateConfig(SetupGuestNetworkCommand cmd) { LinkedList cfg = new LinkedList<>(); @@ -796,8 +780,14 @@ protected List generateConfig(SetupGuestNetworkCommand cmd) { String dev = "eth" + nic.getDeviceId(); String netmask = NetUtils.getSubNet(routerGIP, nic.getNetmask()); - - String args = " -C"; + String args = ""; + if(cmd.isAdd() == false) { + //pass the argument to script to delete the network + args +=" -D"; + } else { + // pass create option argument if the ip needs to be added to eth device + args +=" -C"; + } args += " -M " + nic.getMac(); args += " -d " + dev; args += " -i " + routerGIP; @@ -989,6 +979,9 @@ public boolean configure(final String name, final Map params) th value = (String)params.get("ssh.port"); _port = NumbersUtil.parseInt(value, 3922); + value = (String)params.get("router.aggregation.command.each.timeout"); + _eachTimeout = NumbersUtil.parseInt(value, 3); + if (_vrDeployer == null) { throw new ConfigurationException("Unable to find the resource for VirtualRouterDeployer!"); } @@ -1137,11 +1130,13 @@ private Answer execute(AggregationControlCommand cmd) { return new Answer(cmd); } else if (action == Action.Finish) { Queue queue = _vrAggregateCommandsSet.get(routerName); + int answerCounts = 0; try { StringBuilder sb = new StringBuilder(); sb.append("#Apache CloudStack Virtual Router Config File\n"); sb.append("\n" + _cfgVersion + "\n\n"); for (NetworkElementCommand command : queue) { + answerCounts += command.getAnswersCount(); List cfg = generateCommandCfg(command); if (cfg == null) { s_logger.warn("Unknown commands for VirtualRoutingResource, but continue: " + cmd.toString()); @@ -1168,7 +1163,12 @@ private Answer execute(AggregationControlCommand cmd) { return new Answer(cmd, false, result.getDetails()); } - result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), VRScripts.VR_CFG, "-c " + cfgFilePath + cfgFileName); + // 120s is the minimal timeout + int timeout = answerCounts * _eachTimeout; + if (timeout < 120) { + timeout = 120; + } + result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), VRScripts.VR_CFG, "-c " + cfgFilePath + cfgFileName, timeout); if (!result.isSuccess()) { return new Answer(cmd, false, result.getDetails()); } diff --git a/core/src/com/cloud/storage/resource/StoragePoolResource.java b/core/src/com/cloud/storage/resource/StoragePoolResource.java index 5ec8f0ef2b..a87dfec0a0 100644 --- a/core/src/com/cloud/storage/resource/StoragePoolResource.java +++ b/core/src/com/cloud/storage/resource/StoragePoolResource.java @@ -19,8 +19,6 @@ import com.cloud.agent.api.Answer; import com.cloud.agent.api.storage.CopyVolumeAnswer; import com.cloud.agent.api.storage.CopyVolumeCommand; -import com.cloud.agent.api.storage.CreateAnswer; -import com.cloud.agent.api.storage.CreateCommand; import com.cloud.agent.api.storage.DestroyCommand; import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer; import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand; @@ -33,6 +31,4 @@ public interface StoragePoolResource { Answer execute(DestroyCommand cmd); CopyVolumeAnswer execute(CopyVolumeCommand cmd); - - CreateAnswer execute(CreateCommand cmd); } diff --git a/core/src/org/apache/cloudstack/storage/command/AttachCommand.java b/core/src/org/apache/cloudstack/storage/command/AttachCommand.java index 7e47ba4e31..303457b4a4 100644 --- a/core/src/org/apache/cloudstack/storage/command/AttachCommand.java +++ b/core/src/org/apache/cloudstack/storage/command/AttachCommand.java @@ -24,6 +24,7 @@ public final class AttachCommand extends Command implements StorageSubSystemCommand { private DiskTO disk; private String vmName; + private boolean inSeq = false; public AttachCommand(DiskTO disk, String vmName) { super(); @@ -51,4 +52,9 @@ public String getVmName() { public void setVmName(String vmName) { this.vmName = vmName; } + + @Override + public void setExecuteInSequence(boolean inSeq) { + this.inSeq = inSeq; + } } diff --git a/core/src/org/apache/cloudstack/storage/command/AttachPrimaryDataStoreCmd.java b/core/src/org/apache/cloudstack/storage/command/AttachPrimaryDataStoreCmd.java index 2083876b56..25679ba28c 100644 --- a/core/src/org/apache/cloudstack/storage/command/AttachPrimaryDataStoreCmd.java +++ b/core/src/org/apache/cloudstack/storage/command/AttachPrimaryDataStoreCmd.java @@ -21,6 +21,11 @@ import com.cloud.agent.api.Command; public final class AttachPrimaryDataStoreCmd extends Command implements StorageSubSystemCommand { + @Override + public void setExecuteInSequence(boolean inSeq) { + + } + private final String dataStore; public AttachPrimaryDataStoreCmd(String uri) { diff --git a/core/src/org/apache/cloudstack/storage/command/CopyCommand.java b/core/src/org/apache/cloudstack/storage/command/CopyCommand.java index 446c61f9a7..96822a4ff2 100644 --- a/core/src/org/apache/cloudstack/storage/command/CopyCommand.java +++ b/core/src/org/apache/cloudstack/storage/command/CopyCommand.java @@ -78,4 +78,8 @@ public Map getOptions() { return options; } + @Override + public void setExecuteInSequence(boolean inSeq) { + this.executeInSequence = inSeq; + } } diff --git a/core/src/org/apache/cloudstack/storage/command/CreateObjectCommand.java b/core/src/org/apache/cloudstack/storage/command/CreateObjectCommand.java index 121a7ee449..8c239b5304 100644 --- a/core/src/org/apache/cloudstack/storage/command/CreateObjectCommand.java +++ b/core/src/org/apache/cloudstack/storage/command/CreateObjectCommand.java @@ -42,4 +42,8 @@ public DataTO getData() { return this.data; } + @Override + public void setExecuteInSequence(boolean inSeq) { + + } } diff --git a/core/src/org/apache/cloudstack/storage/command/CreatePrimaryDataStoreCmd.java b/core/src/org/apache/cloudstack/storage/command/CreatePrimaryDataStoreCmd.java index b536028927..21716cf111 100644 --- a/core/src/org/apache/cloudstack/storage/command/CreatePrimaryDataStoreCmd.java +++ b/core/src/org/apache/cloudstack/storage/command/CreatePrimaryDataStoreCmd.java @@ -35,4 +35,8 @@ public boolean executeInSequence() { return false; } + @Override + public void setExecuteInSequence(boolean inSeq) { + + } } diff --git a/core/src/org/apache/cloudstack/storage/command/DeleteCommand.java b/core/src/org/apache/cloudstack/storage/command/DeleteCommand.java index 76696da30a..7445050763 100644 --- a/core/src/org/apache/cloudstack/storage/command/DeleteCommand.java +++ b/core/src/org/apache/cloudstack/storage/command/DeleteCommand.java @@ -42,4 +42,8 @@ public DataTO getData() { return this.data; } + @Override + public void setExecuteInSequence(boolean inSeq) { + + } } diff --git a/core/src/org/apache/cloudstack/storage/command/DettachCommand.java b/core/src/org/apache/cloudstack/storage/command/DettachCommand.java index 61cb88b284..1e501d9600 100644 --- a/core/src/org/apache/cloudstack/storage/command/DettachCommand.java +++ b/core/src/org/apache/cloudstack/storage/command/DettachCommand.java @@ -87,4 +87,9 @@ public void setStoragePort(int storagePort) { public int getStoragePort() { return _storagePort; } + + @Override + public void setExecuteInSequence(boolean inSeq) { + + } } diff --git a/core/src/org/apache/cloudstack/storage/command/ForgetObjectCmd.java b/core/src/org/apache/cloudstack/storage/command/ForgetObjectCmd.java index ffee0ab921..981a098102 100644 --- a/core/src/org/apache/cloudstack/storage/command/ForgetObjectCmd.java +++ b/core/src/org/apache/cloudstack/storage/command/ForgetObjectCmd.java @@ -36,4 +36,9 @@ public DataTO getDataTO() { public boolean executeInSequence() { return false; } + + @Override + public void setExecuteInSequence(boolean inSeq) { + + } } diff --git a/core/src/org/apache/cloudstack/storage/command/IntroduceObjectCmd.java b/core/src/org/apache/cloudstack/storage/command/IntroduceObjectCmd.java index c6c6d23726..b463b2c5f0 100644 --- a/core/src/org/apache/cloudstack/storage/command/IntroduceObjectCmd.java +++ b/core/src/org/apache/cloudstack/storage/command/IntroduceObjectCmd.java @@ -36,4 +36,9 @@ public DataTO getDataTO() { public boolean executeInSequence() { return false; } + + @Override + public void setExecuteInSequence(boolean inSeq) { + + } } diff --git a/core/src/org/apache/cloudstack/storage/command/StorageSubSystemCommand.java b/core/src/org/apache/cloudstack/storage/command/StorageSubSystemCommand.java index d14161ae4c..fb7b373684 100644 --- a/core/src/org/apache/cloudstack/storage/command/StorageSubSystemCommand.java +++ b/core/src/org/apache/cloudstack/storage/command/StorageSubSystemCommand.java @@ -19,5 +19,5 @@ package org.apache.cloudstack.storage.command; public interface StorageSubSystemCommand { - + void setExecuteInSequence(boolean inSeq); } diff --git a/core/src/org/apache/cloudstack/storage/to/PrimaryDataStoreTO.java b/core/src/org/apache/cloudstack/storage/to/PrimaryDataStoreTO.java index 6a5d679331..29e53b0d95 100644 --- a/core/src/org/apache/cloudstack/storage/to/PrimaryDataStoreTO.java +++ b/core/src/org/apache/cloudstack/storage/to/PrimaryDataStoreTO.java @@ -27,6 +27,7 @@ public class PrimaryDataStoreTO implements DataStoreTO { public static final String MANAGED = PrimaryDataStore.MANAGED; public static final String STORAGE_HOST = PrimaryDataStore.STORAGE_HOST; + public static final String STORAGE_PORT = PrimaryDataStore.STORAGE_PORT; public static final String MANAGED_STORE_TARGET = PrimaryDataStore.MANAGED_STORE_TARGET; public static final String MANAGED_STORE_TARGET_ROOT_VOLUME = PrimaryDataStore.MANAGED_STORE_TARGET_ROOT_VOLUME; public static final String CHAP_INITIATOR_USERNAME = PrimaryDataStore.CHAP_INITIATOR_USERNAME; diff --git a/core/test/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResourceTest.java b/core/test/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResourceTest.java index 48da1bb58b..531c71854d 100644 --- a/core/test/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResourceTest.java +++ b/core/test/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResourceTest.java @@ -91,6 +91,11 @@ public class VirtualRoutingResourceTest implements VirtualRouterDeployer { @Override public ExecutionResult executeInVR(String routerIp, String script, String args) { + return executeInVR(routerIp, script, args, 60); + } + + @Override + public ExecutionResult executeInVR(String routerIp, String script, String args, int timeout) { assertEquals(routerIp, ROUTERIP); verifyCommand(_currentCmd, script, args); return new ExecutionResult(true, null); diff --git a/core/test/org/apache/cloudstack/api/agent/test/BackupSnapshotCommandTest.java b/core/test/org/apache/cloudstack/api/agent/test/BackupSnapshotCommandTest.java index eaa9b94fee..33361e8726 100644 --- a/core/test/org/apache/cloudstack/api/agent/test/BackupSnapshotCommandTest.java +++ b/core/test/org/apache/cloudstack/api/agent/test/BackupSnapshotCommandTest.java @@ -28,6 +28,7 @@ import com.cloud.agent.api.BackupSnapshotCommand; import com.cloud.agent.api.to.SwiftTO; +import com.cloud.hypervisor.Hypervisor; import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.StoragePool; import com.cloud.storage.StoragePoolStatus; @@ -145,7 +146,14 @@ public String getStorageProviderName() { public boolean isInMaintenance() { // TODO Auto-generated method stub return false; - }; + } + + @Override + public Hypervisor.HypervisorType getHypervisor() { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + ; }; BackupSnapshotCommand bsc = new BackupSnapshotCommand("http://secondary.Storage.Url", 101L, 102L, 103L, 104L, 105L, "vPath", pool, diff --git a/core/test/org/apache/cloudstack/api/agent/test/CheckNetworkAnswerTest.java b/core/test/org/apache/cloudstack/api/agent/test/CheckNetworkAnswerTest.java index b0872bfc52..66feaecb5e 100644 --- a/core/test/org/apache/cloudstack/api/agent/test/CheckNetworkAnswerTest.java +++ b/core/test/org/apache/cloudstack/api/agent/test/CheckNetworkAnswerTest.java @@ -32,6 +32,7 @@ import com.cloud.agent.api.CheckNetworkCommand; import com.cloud.agent.api.storage.ResizeVolumeCommand; import com.cloud.agent.api.to.StorageFilerTO; +import com.cloud.hypervisor.Hypervisor; import com.cloud.storage.Storage; import com.cloud.storage.StoragePool; import com.cloud.storage.StoragePoolStatus; @@ -184,7 +185,14 @@ public String getStorageProviderName() { public boolean isInMaintenance() { // TODO Auto-generated method stub return false; - }; + } + + @Override + public Hypervisor.HypervisorType getHypervisor() { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + ; }; Long newSize = 4194304L; diff --git a/core/test/org/apache/cloudstack/api/agent/test/SnapshotCommandTest.java b/core/test/org/apache/cloudstack/api/agent/test/SnapshotCommandTest.java index 8339a98b9f..114c8854d1 100644 --- a/core/test/org/apache/cloudstack/api/agent/test/SnapshotCommandTest.java +++ b/core/test/org/apache/cloudstack/api/agent/test/SnapshotCommandTest.java @@ -28,6 +28,7 @@ import org.junit.Test; import com.cloud.agent.api.SnapshotCommand; +import com.cloud.hypervisor.Hypervisor; import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.StoragePool; import com.cloud.storage.StoragePoolStatus; @@ -146,7 +147,14 @@ public String getStorageProviderName() { public boolean isInMaintenance() { // TODO Auto-generated method stub return false; - }; + } + + @Override + public Hypervisor.HypervisorType getHypervisor() { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + ; }; SnapshotCommand ssc = new SnapshotCommand(pool, "http://secondary.Storage.Url", "420fa39c-4ef1-a83c-fd93-46dc1ff515ae", "snapshotName", 101L, 102L, 103L); diff --git a/debian/control b/debian/control index ab4644badd..504ef99f31 100644 --- a/debian/control +++ b/debian/control @@ -15,7 +15,7 @@ Description: A common package which contains files which are shared by several C Package: cloudstack-management Architecture: all -Depends: cloudstack-common (= ${source:Version}), tomcat6, sysvinit-utils, sudo, jsvc, python-mysqldb, python-paramiko, augeas-tools +Depends: cloudstack-common (= ${source:Version}), tomcat6, sysvinit-utils, sudo, jsvc, python-mysqldb, libmysql-java, python-paramiko, augeas-tools Conflicts: cloud-server, cloud-client, cloud-client-ui Description: CloudStack server library The CloudStack management server diff --git a/debian/rules b/debian/rules index 4edf893060..197e243bcf 100755 --- a/debian/rules +++ b/debian/rules @@ -35,7 +35,7 @@ build: build-indep build-indep: build-indep-stamp build-indep-stamp: configure - mvn clean package -Pawsapi -DskipTests -Dsystemvm \ + mvn -T C1.5 clean package -Pawsapi -DskipTests -Dsystemvm \ -Dcs.replace.properties=replace.properties.tmp \ ${ACS_BUILD_OPTS} touch $@ diff --git a/engine/api/src/com/cloud/vm/VirtualMachineManager.java b/engine/api/src/com/cloud/vm/VirtualMachineManager.java index 99f5595579..b1e5258af7 100644 --- a/engine/api/src/com/cloud/vm/VirtualMachineManager.java +++ b/engine/api/src/com/cloud/vm/VirtualMachineManager.java @@ -36,11 +36,9 @@ import com.cloud.exception.ResourceUnavailableException; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.network.Network; -import com.cloud.offering.DiskOffering; import com.cloud.offering.DiskOfferingInfo; import com.cloud.offering.ServiceOffering; import com.cloud.storage.StoragePool; -import com.cloud.storage.Volume; import com.cloud.template.VirtualMachineTemplate; import com.cloud.utils.component.Manager; import com.cloud.utils.fsm.NoTransitionException; @@ -77,7 +75,7 @@ public interface Topics { * @throws InsufficientCapacityException If there are insufficient capacity to deploy this vm. */ void allocate(String vmInstanceName, VirtualMachineTemplate template, ServiceOffering serviceOffering, DiskOfferingInfo rootDiskOfferingInfo, - LinkedHashMap dataDiskOfferings, LinkedHashMap> auxiliaryNetworks, DeploymentPlan plan, + List dataDiskOfferings, LinkedHashMap> auxiliaryNetworks, DeploymentPlan plan, HypervisorType hyperType) throws InsufficientCapacityException; void allocate(String vmInstanceName, VirtualMachineTemplate template, ServiceOffering serviceOffering, @@ -114,7 +112,7 @@ void orchestrateStart(String vmUuid, Map pa void migrate(String vmUuid, long srcHostId, DeployDestination dest) throws ResourceUnavailableException, ConcurrentOperationException; - void migrateWithStorage(String vmUuid, long srcId, long destId, Map volumeToPool) throws ResourceUnavailableException, ConcurrentOperationException; + void migrateWithStorage(String vmUuid, long srcId, long destId, Map volumeToPool) throws ResourceUnavailableException, ConcurrentOperationException; void reboot(String vmUuid, Map params) throws InsufficientCapacityException, ResourceUnavailableException; 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 2531074029..3b555e55be 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 @@ -21,6 +21,7 @@ import java.util.Map; import java.util.Set; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import com.cloud.agent.api.to.VirtualMachineTO; @@ -86,7 +87,7 @@ VolumeInfo moveVolume(VolumeInfo volume, long destPoolDcId, Long destPoolPodId, void destroyVolume(Volume volume); - DiskProfile allocateRawVolume(Type type, String name, DiskOffering offering, Long size, VirtualMachine vm, VirtualMachineTemplate template, Account owner); + DiskProfile allocateRawVolume(Type type, String name, DiskOffering offering, Long size, Long minIops, Long maxIops, VirtualMachine vm, VirtualMachineTemplate template, Account owner); VolumeInfo createVolumeOnPrimaryStorage(VirtualMachine vm, Volume rootVolumeOfVm, VolumeInfo volume, HypervisorType rootDiskHyperType) throws NoTransitionException; @@ -94,6 +95,8 @@ VolumeInfo moveVolume(VolumeInfo volume, long destPoolDcId, Long destPoolPodId, void cleanupVolumes(long vmId) throws ConcurrentOperationException; + void disconnectVolumeFromHost(VolumeInfo volumeInfo, Host host, DataStore dataStore); + void disconnectVolumesFromHost(long vmId, long hostId); void migrateVolumes(VirtualMachine vm, VirtualMachineTO vmTo, Host srcHost, Host destHost, Map volumeToPool); @@ -118,4 +121,5 @@ DiskProfile allocateTemplatedVolume(Type type, String name, DiskOffering offerin StoragePool findStoragePool(DiskProfile dskCh, DataCenter dc, Pod pod, Long clusterId, Long hostId, VirtualMachine vm, Set avoid); void updateVolumeDiskChain(long volumeId, String path, String chainInfo); + } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreInfo.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreInfo.java index bb9f2dad1f..f08d9a4550 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreInfo.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreInfo.java @@ -29,6 +29,7 @@ public interface PrimaryDataStoreInfo extends StoragePool { static final String MANAGED = "managed"; static final String STORAGE_HOST= "storageHost"; + static final String STORAGE_PORT = "storagePort"; static final String MANAGED_STORE_TARGET = "managedStoreTarget"; static final String MANAGED_STORE_TARGET_ROOT_VOLUME = "managedStoreTargetRootVolume"; static final String CHAP_INITIATOR_USERNAME = "chapInitiatorUsername"; diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateDataFactory.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateDataFactory.java index 801c4427f5..fd22da12e4 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateDataFactory.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateDataFactory.java @@ -25,6 +25,8 @@ public interface TemplateDataFactory { TemplateInfo getTemplate(long templateId, DataStore store); + TemplateInfo getReadyTemplateOnImageStore(long templateId, Long zoneId); + TemplateInfo getTemplate(DataObject obj, DataStore store); TemplateInfo getTemplate(long templateId, DataStoreRole storeRole); diff --git a/engine/api/src/org/apache/cloudstack/storage/image/datastore/ImageStoreEntity.java b/engine/api/src/org/apache/cloudstack/storage/image/datastore/ImageStoreEntity.java index 43a0f75c8d..461bd50ab0 100644 --- a/engine/api/src/org/apache/cloudstack/storage/image/datastore/ImageStoreEntity.java +++ b/engine/api/src/org/apache/cloudstack/storage/image/datastore/ImageStoreEntity.java @@ -20,6 +20,7 @@ import java.util.Set; +import com.cloud.storage.Upload; import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; @@ -43,4 +44,6 @@ public interface ImageStoreEntity extends DataStore, ImageStore { String getMountPoint(); // get the mount point on ssvm. String createEntityExtractUrl(String installPath, ImageFormat format, DataObject dataObject); // get the entity download URL + + void deleteExtractUrl(String installPath, String url, Upload.Type volume); } diff --git a/engine/components-api/src/com/cloud/event/UsageEventUtils.java b/engine/components-api/src/com/cloud/event/UsageEventUtils.java index 4f32cb3263..f1707bd45d 100644 --- a/engine/components-api/src/com/cloud/event/UsageEventUtils.java +++ b/engine/components-api/src/com/cloud/event/UsageEventUtils.java @@ -70,6 +70,15 @@ public static void publishUsageEvent(String usageType, long accountId, long zone publishUsageEvent(usageType, accountId, zoneId, entityType, entityUUID); } + public static void publishUsageEvent(String usageType, long accountId, long zoneId, long resourceId, String resourceName, Long offeringId, Long templateId, + Long size, String entityType, String entityUUID, boolean displayResource) { + if(displayResource){ + saveUsageEvent(usageType, accountId, zoneId, resourceId, resourceName, offeringId, templateId, size); + } + publishUsageEvent(usageType, accountId, zoneId, entityType, entityUUID); + + } + public static void publishUsageEvent(String usageType, long accountId, long zoneId, long resourceId, String resourceName, Long offeringId, Long templateId, Long size, Long virtualSize, String entityType, String entityUUID) { saveUsageEvent(usageType, accountId, zoneId, resourceId, resourceName, offeringId, templateId, size, virtualSize); @@ -81,6 +90,13 @@ public static void publishUsageEvent(String usageType, long accountId, long zone publishUsageEvent(usageType, accountId, zoneId, entityType, entityUUID); } + public static void publishUsageEvent(String usageType, long accountId, long zoneId, long resourceId, String resourceName, String entityType, String entityUUID, boolean diplayResource) { + if (diplayResource){ + saveUsageEvent(usageType, accountId, zoneId, resourceId, resourceName); + publishUsageEvent(usageType, accountId, zoneId, entityType, entityUUID); + } + } + public static void publishUsageEvent(String usageType, long accountId, long zoneId, long ipAddressId, String ipAddress, boolean isSourceNat, String guestType, boolean isSystem, String entityType, String entityUUID) { saveUsageEvent(usageType, accountId, zoneId, ipAddressId, ipAddress, isSourceNat, guestType, isSystem); @@ -88,9 +104,12 @@ public static void publishUsageEvent(String usageType, long accountId, long zone } public static void publishUsageEvent(String usageType, long accountId, long zoneId, long resourceId, String resourceName, Long offeringId, Long templateId, - String resourceType, String entityType, String entityUUID) { - saveUsageEvent(usageType, accountId, zoneId, resourceId, resourceName, offeringId, templateId, resourceType); + String resourceType, String entityType, String entityUUID, boolean displayResource) { + if(displayResource){ + saveUsageEvent(usageType, accountId, zoneId, resourceId, resourceName, offeringId, templateId, resourceType); + } publishUsageEvent(usageType, accountId, zoneId, entityType, entityUUID); + } public static void publishUsageEvent(String usageType, long accountId, long zoneId, long vmId, long securityGroupId, String entityType, String entityUUID) { @@ -99,9 +118,12 @@ public static void publishUsageEvent(String usageType, long accountId, long zone } public static void publishUsageEvent(String usageType, long accountId, long zoneId, long resourceId, String resourceName, Long offeringId, Long templateId, - String resourceType, String entityType, String entityUUID, Map details) { - saveUsageEvent(usageType, accountId, zoneId, resourceId, resourceName, offeringId, templateId, resourceType, details); + String resourceType, String entityType, String entityUUID, Map details, boolean displayResource) { + if(displayResource){ + saveUsageEvent(usageType, accountId, zoneId, resourceId, resourceName, offeringId, templateId, resourceType, details); + } publishUsageEvent(usageType, accountId, zoneId, entityType, entityUUID); + } private static void saveUsageEvent(String usageType, long accountId, long zoneId, long resourceId, String resourceName, Long offeringId, Long templateId, diff --git a/engine/components-api/src/com/cloud/network/addr/PublicIp.java b/engine/components-api/src/com/cloud/network/addr/PublicIp.java index ff11b3349a..49cae4bacc 100644 --- a/engine/components-api/src/com/cloud/network/addr/PublicIp.java +++ b/engine/components-api/src/com/cloud/network/addr/PublicIp.java @@ -18,9 +18,8 @@ import java.util.Date; -import org.apache.cloudstack.acl.IAMEntityType; - import com.cloud.dc.VlanVO; +import com.cloud.network.IpAddress; import com.cloud.network.PublicIpAddress; import com.cloud.network.dao.IPAddressVO; import com.cloud.utils.net.Ip; @@ -240,7 +239,17 @@ public boolean isDisplay() { } @Override - public IAMEntityType getEntityType() { - return IAMEntityType.PublicIpAddress; + public Date getRemoved() { + return _addr.getRemoved(); + } + + @Override + public Date getCreated() { + return _addr.getCreated(); + } + + @Override + public Class getEntityType() { + return IpAddress.class; } } diff --git a/engine/components-api/src/com/cloud/network/rules/StaticNatRuleImpl.java b/engine/components-api/src/com/cloud/network/rules/StaticNatRuleImpl.java index bdaf2bc1b2..9a49db0ca1 100644 --- a/engine/components-api/src/com/cloud/network/rules/StaticNatRuleImpl.java +++ b/engine/components-api/src/com/cloud/network/rules/StaticNatRuleImpl.java @@ -18,8 +18,6 @@ import java.util.List; -import org.apache.cloudstack.acl.IAMEntityType; - public class StaticNatRuleImpl implements StaticNatRule { long id; String xid; @@ -152,7 +150,7 @@ public boolean isDisplay() { } @Override - public IAMEntityType getEntityType() { - return IAMEntityType.FirewallRule; + public Class getEntityType() { + return FirewallRule.class; } } diff --git a/engine/components-api/src/com/cloud/resource/ResourceManager.java b/engine/components-api/src/com/cloud/resource/ResourceManager.java index 5a9bddb186..4f43adb3f5 100755 --- a/engine/components-api/src/com/cloud/resource/ResourceManager.java +++ b/engine/components-api/src/com/cloud/resource/ResourceManager.java @@ -23,6 +23,7 @@ import com.cloud.agent.api.StartupCommand; import com.cloud.agent.api.StartupRoutingCommand; +import com.cloud.agent.api.VgpuTypesInfo; import com.cloud.agent.api.to.GPUDeviceTO; import com.cloud.dc.DataCenterVO; import com.cloud.dc.HostPodVO; @@ -141,41 +142,51 @@ public interface ResourceManager extends ResourceService { */ List listAllUpAndEnabledNonHAHosts(Type type, Long clusterId, Long podId, long dcId); + /** + * Check if host is GPU enabled + * @param hostId the host to be checked + * @return true if host contains GPU card else false + */ + boolean isHostGpuEnabled(long hostId); + /** * Check if host has GPU devices available * @param hostId the host to be checked + * @param groupName: gpuCard name * @param vgpuType the VGPU type * @return true when the host has the capacity with given VGPU type */ - boolean isGPUDeviceAvailable(long hostId, String vgpuType); + boolean isGPUDeviceAvailable(long hostId, String groupName, String vgpuType); /** * Get available GPU device * @param hostId the host to be checked + * @param groupName: gpuCard name * @param vgpuType the VGPU type * @return GPUDeviceTO[] */ - GPUDeviceTO getGPUDevice(long hostId, String vgpuType); + GPUDeviceTO getGPUDevice(long hostId, String groupName, String vgpuType); /** * Return listof available GPU devices * @param hostId, the host to be checked + * @param groupName: gpuCard name * @param vgpuType the VGPU type * @return List of HostGpuGroupsVO. */ - List listAvailableGPUDevice(long hostId, String vgpuType); + List listAvailableGPUDevice(long hostId, String groupName, String vgpuType); /** * Update GPU device details (post VM deployment) * @param hostId, the dest host Id * @param groupDetails, capacity of GPU group. */ - void updateGPUDetails(long hostId, HashMap> groupDetails); + void updateGPUDetails(long hostId, HashMap> groupDetails); /** * Get GPU details for a host * @param host, the Host object * @return Details of groupNames and enabled VGPU type with remaining capacity. */ - HashMap> getGPUStatistics(HostVO host); + HashMap> getGPUStatistics(HostVO host); } diff --git a/engine/orchestration/src/com/cloud/agent/manager/AgentAttache.java b/engine/orchestration/src/com/cloud/agent/manager/AgentAttache.java index fd1531e25a..24a6fe71f8 100755 --- a/engine/orchestration/src/com/cloud/agent/manager/AgentAttache.java +++ b/engine/orchestration/src/com/cloud/agent/manager/AgentAttache.java @@ -30,7 +30,6 @@ import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; import org.apache.cloudstack.managed.context.ManagedContextRunnable; import org.apache.log4j.Logger; @@ -107,7 +106,6 @@ public int compare(final Object o1, final Object o2) { protected Status _status = Status.Connecting; protected boolean _maintenance; protected long _nextSequence; - protected AtomicInteger _outstandingTaskCount; protected AgentManagerImpl _agentMgr; @@ -130,7 +128,6 @@ protected AgentAttache(final AgentManagerImpl agentMgr, final long id, final Str _requests = new LinkedList(); _agentMgr = agentMgr; _nextSequence = new Long(s_rand.nextInt(Short.MAX_VALUE)) << 48; - _outstandingTaskCount = new AtomicInteger(0); } public synchronized long getNextSequence() { diff --git a/engine/orchestration/src/com/cloud/agent/manager/AgentManagerImpl.java b/engine/orchestration/src/com/cloud/agent/manager/AgentManagerImpl.java index 0d41bc1b3b..2d0be24fcf 100755 --- a/engine/orchestration/src/com/cloud/agent/manager/AgentManagerImpl.java +++ b/engine/orchestration/src/com/cloud/agent/manager/AgentManagerImpl.java @@ -162,6 +162,7 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl protected ExecutorService _executor; protected ThreadPoolExecutor _connectExecutor; protected ScheduledExecutorService _directAgentExecutor; + protected ScheduledExecutorService _cronJobExecutor; protected ScheduledExecutorService _monitorExecutor; private int _directAgentThreadCap; @@ -185,8 +186,15 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl "The number of direct agents to load each time", false); protected final ConfigKey DirectAgentPoolSize = new ConfigKey(Integer.class, "direct.agent.pool.size", "Advanced", "500", "Default size for DirectAgentPool", false); - protected final ConfigKey DirectAgentThreadCap = new ConfigKey(Float.class, "direct.agent.thread.cap", "Advanced", "0.1", + protected final ConfigKey DirectAgentThreadCap = new ConfigKey(Float.class, "direct.agent.thread.cap", "Advanced", "1", "Percentage (as a value between 0 and 1) of direct.agent.pool.size to be used as upper thread cap for a single direct agent to process requests", false); + protected final ConfigKey CheckTxnBeforeSending = new ConfigKey( + "Developer", + Boolean.class, + "check.txn.before.sending.agent.commands", + "false", + "This parameter allows developers to enable a check to see if a transaction wraps commands that are sent to the resource. This is not to be enabled on production systems.", + true); @Override public boolean configure(final String name, final Map params) throws ConfigurationException { @@ -212,7 +220,10 @@ public boolean configure(final String name, final Map params) th _connection = new NioServer("AgentManager", Port.value(), Workers.value() + 10, this); s_logger.info("Listening on " + Port.value() + " with " + Workers.value() + " workers"); + // executes all agent commands other than cron and ping _directAgentExecutor = new ScheduledThreadPoolExecutor(DirectAgentPoolSize.value(), new NamedThreadFactory("DirectAgent")); + // executes cron and ping agent commands + _cronJobExecutor = new ScheduledThreadPoolExecutor(DirectAgentPoolSize.value(), new NamedThreadFactory("DirectAgentCronJob")); s_logger.debug("Created DirectAgentAttache pool with size: " + DirectAgentPoolSize.value()); _directAgentThreadCap = Math.round(DirectAgentPoolSize.value() * DirectAgentThreadCap.value()) + 1; // add 1 to always make the value > 0 @@ -378,7 +389,16 @@ public Answer[] send(Long hostId, Commands commands, int timeout) throws AgentUn if (timeout <= 0) { timeout = Wait.value(); } - assert noDbTxn() : "I know, I know. Why are we so strict as to not allow txn across an agent call? ... Why are we so cruel ... Why are we such a dictator .... Too bad... Sorry...but NO AGENT COMMANDS WRAPPED WITHIN DB TRANSACTIONS!"; + + if (CheckTxnBeforeSending.value()) { + if (!noDbTxn()) { + throw new CloudRuntimeException("We do not allow transactions to be wrapped around commands sent to be executed on remote agents. " + + "We cannot predict how long it takes a command to complete. " + + "The transaction may be rolled back because the connection took too long."); + } + } else { + assert noDbTxn() : "I know, I know. Why are we so strict as to not allow txn across an agent call? ... Why are we so cruel ... Why are we such a dictator .... Too bad... Sorry...but NO AGENT COMMANDS WRAPPED WITHIN DB TRANSACTIONS!"; + } Command[] cmds = commands.toCommands(); @@ -1435,6 +1455,10 @@ public ScheduledExecutorService getDirectAgentPool() { return _directAgentExecutor; } + public ScheduledExecutorService getCronJobPool() { + return _cronJobExecutor; + } + public int getDirectAgentThreadCap() { return _directAgentThreadCap; } @@ -1582,7 +1606,7 @@ public String getConfigComponentName() { @Override public ConfigKey[] getConfigKeys() { - return new ConfigKey[] {Workers, Port, PingInterval, PingTimeout, Wait, AlertWait, DirectAgentLoadSize, DirectAgentPoolSize, DirectAgentThreadCap}; + return new ConfigKey[] {CheckTxnBeforeSending, Workers, Port, PingInterval, PingTimeout, Wait, AlertWait, DirectAgentLoadSize, DirectAgentPoolSize, DirectAgentThreadCap}; } } diff --git a/engine/orchestration/src/com/cloud/agent/manager/DirectAgentAttache.java b/engine/orchestration/src/com/cloud/agent/manager/DirectAgentAttache.java index 9874ee4193..7ca6929686 100755 --- a/engine/orchestration/src/com/cloud/agent/manager/DirectAgentAttache.java +++ b/engine/orchestration/src/com/cloud/agent/manager/DirectAgentAttache.java @@ -17,12 +17,13 @@ package com.cloud.agent.manager; import java.util.ArrayList; +import java.util.LinkedList; import java.util.List; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; import org.apache.log4j.Logger; - import org.apache.cloudstack.managed.context.ManagedContextRunnable; import com.cloud.agent.api.Answer; @@ -43,11 +44,16 @@ public class DirectAgentAttache extends AgentAttache { List> _futures = new ArrayList>(); AgentManagerImpl _mgr; long _seq = 0; + LinkedList tasks = new LinkedList(); + AtomicInteger _outstandingTaskCount; + AtomicInteger _outstandingCronTaskCount; public DirectAgentAttache(AgentManagerImpl agentMgr, long id, String name, ServerResource resource, boolean maintenance, AgentManagerImpl mgr) { super(agentMgr, id, name, maintenance); _resource = resource; _mgr = mgr; + _outstandingTaskCount = new AtomicInteger(0); + _outstandingCronTaskCount = new AtomicInteger(0); } @Override @@ -90,15 +96,16 @@ public void send(Request req) throws AgentUnavailableException { if (answers != null && answers[0] instanceof StartupAnswer) { StartupAnswer startup = (StartupAnswer)answers[0]; int interval = startup.getPingInterval(); - _futures.add(_agentMgr.getDirectAgentPool().scheduleAtFixedRate(new PingTask(), interval, interval, TimeUnit.SECONDS)); + _futures.add(_agentMgr.getCronJobPool().scheduleAtFixedRate(new PingTask(), interval, interval, TimeUnit.SECONDS)); } } else { Command[] cmds = req.getCommands(); if (cmds.length > 0 && !(cmds[0] instanceof CronCommand)) { - _agentMgr.getDirectAgentPool().execute(new Task(req)); + queueTask(new Task(req)); + scheduleFromQueue(); } else { CronCommand cmd = (CronCommand)cmds[0]; - _futures.add(_agentMgr.getDirectAgentPool().scheduleAtFixedRate(new Task(req), cmd.getInterval(), cmd.getInterval(), TimeUnit.SECONDS)); + _futures.add(_agentMgr.getCronJobPool().scheduleAtFixedRate(new CronTask(req), cmd.getInterval(), cmd.getInterval(), TimeUnit.SECONDS)); } } } @@ -109,7 +116,7 @@ public void process(Answer[] answers) { StartupAnswer startup = (StartupAnswer)answers[0]; int interval = startup.getPingInterval(); s_logger.info("StartupAnswer received " + startup.getHostId() + " Interval = " + interval); - _futures.add(_agentMgr.getDirectAgentPool().scheduleAtFixedRate(new PingTask(), interval, interval, TimeUnit.SECONDS)); + _futures.add(_agentMgr.getCronJobPool().scheduleAtFixedRate(new PingTask(), interval, interval, TimeUnit.SECONDS)); } } @@ -128,13 +135,26 @@ protected void finalize() throws Throwable { } } + private synchronized void queueTask(Task task) { + tasks.add(task); + } + + private synchronized void scheduleFromQueue() { + if (s_logger.isTraceEnabled()) { + s_logger.trace("Agent attache=" + _id + ", task queue size=" + tasks.size() + ", outstanding tasks=" + _outstandingTaskCount.get()); + } + while (!tasks.isEmpty() && _outstandingTaskCount.get() < _agentMgr.getDirectAgentThreadCap()) { + _outstandingTaskCount.incrementAndGet(); + _agentMgr.getDirectAgentPool().execute(tasks.remove()); + } + } + protected class PingTask extends ManagedContextRunnable { @Override protected synchronized void runInContext() { try { - if (_outstandingTaskCount.incrementAndGet() > _agentMgr.getDirectAgentThreadCap()) { - s_logger.warn("Task execution for direct attache(" + _id + ") has reached maximum outstanding limit(" + _agentMgr.getDirectAgentThreadCap() + - "), bailing out"); + if (_outstandingCronTaskCount.incrementAndGet() >= _agentMgr.getDirectAgentThreadCap()) { + s_logger.warn("PingTask execution for direct attache(" + _id + ") has reached maximum outstanding limit(" + _agentMgr.getDirectAgentThreadCap() + "), bailing out"); return; } @@ -162,15 +182,15 @@ protected synchronized void runInContext() { } catch (Exception e) { s_logger.warn("Unable to complete the ping task", e); } finally { - _outstandingTaskCount.decrementAndGet(); + _outstandingCronTaskCount.decrementAndGet(); } } } - protected class Task extends ManagedContextRunnable { + protected class CronTask extends ManagedContextRunnable { Request _req; - public Task(Request req) { + public CronTask(Request req) { _req = req; } @@ -194,9 +214,8 @@ private void bailout() { protected void runInContext() { long seq = _req.getSequence(); try { - if (_outstandingTaskCount.incrementAndGet() > _agentMgr.getDirectAgentThreadCap()) { - s_logger.warn("Task execution for direct attache(" + _id + ") has reached maximum outstanding limit(" + _agentMgr.getDirectAgentThreadCap() + - "), bailing out"); + if (_outstandingCronTaskCount.incrementAndGet() >= _agentMgr.getDirectAgentThreadCap()) { + s_logger.warn("CronTask execution for direct attache(" + _id + ") has reached maximum outstanding limit(" + _agentMgr.getDirectAgentThreadCap() + "), bailing out"); bailout(); return; } @@ -243,9 +262,67 @@ protected void runInContext() { } catch (Exception e) { s_logger.warn(log(seq, "Exception caught "), e); } finally { - _outstandingTaskCount.decrementAndGet(); + _outstandingCronTaskCount.decrementAndGet(); } } } + protected class Task extends ManagedContextRunnable { + Request _req; + + public Task(Request req) { + _req = req; + } + + @Override + protected void runInContext() { + long seq = _req.getSequence(); + try { + ServerResource resource = _resource; + Command[] cmds = _req.getCommands(); + boolean stopOnError = _req.stopOnError(); + + if (s_logger.isDebugEnabled()) { + s_logger.debug(log(seq, "Executing request")); + } + ArrayList answers = new ArrayList(cmds.length); + for (int i = 0; i < cmds.length; i++) { + Answer answer = null; + try { + if (resource != null) { + answer = resource.executeRequest(cmds[i]); + if (answer == null) { + s_logger.warn("Resource returned null answer!"); + answer = new Answer(cmds[i], false, "Resource returned null answer"); + } + } else { + answer = new Answer(cmds[i], false, "Agent is disconnected"); + } + } catch (Exception e) { + s_logger.warn(log(seq, "Exception Caught while executing command"), e); + answer = new Answer(cmds[i], false, e.toString()); + } + answers.add(answer); + if (!answer.getResult() && stopOnError) { + if (i < cmds.length - 1 && s_logger.isDebugEnabled()) { + s_logger.debug(log(seq, "Cancelling because one of the answers is false and it is stop on error.")); + } + break; + } + } + + Response resp = new Response(_req, answers.toArray(new Answer[answers.size()])); + if (s_logger.isDebugEnabled()) { + s_logger.debug(log(seq, "Response Received: ")); + } + + processAnswers(seq, resp); + } catch (Exception e) { + s_logger.warn(log(seq, "Exception caught "), e); + } finally { + _outstandingTaskCount.decrementAndGet(); + scheduleFromQueue(); + } + } + } } diff --git a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java index e9d2fd2073..55bfdc87d7 100755 --- a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -1,4 +1,4 @@ -// Licensed to the Apache Software Foundation (ASF) under one +// Licensed to the Apacohe 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 @@ -26,6 +26,7 @@ import java.util.Date; import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -40,6 +41,8 @@ import javax.inject.Inject; import javax.naming.ConfigurationException; +import org.apache.log4j.Logger; + import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao; import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; @@ -68,7 +71,6 @@ import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.cloudstack.storage.to.VolumeObjectTO; import org.apache.cloudstack.utils.identity.ManagementServerNode; -import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; import com.cloud.agent.Listener; @@ -84,6 +86,7 @@ import com.cloud.agent.api.Command; import com.cloud.agent.api.MigrateAnswer; import com.cloud.agent.api.MigrateCommand; +import com.cloud.agent.api.MigrateCompleteCommand; import com.cloud.agent.api.PingRoutingCommand; import com.cloud.agent.api.PlugNicAnswer; import com.cloud.agent.api.PlugNicCommand; @@ -154,7 +157,6 @@ import com.cloud.network.dao.NetworkDao; import com.cloud.network.dao.NetworkVO; import com.cloud.network.rules.RulesManager; -import com.cloud.offering.DiskOffering; import com.cloud.offering.DiskOfferingInfo; import com.cloud.offering.ServiceOffering; import com.cloud.org.Cluster; @@ -162,6 +164,7 @@ import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.storage.DiskOfferingVO; +import com.cloud.storage.ScopeType; import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.StoragePool; import com.cloud.storage.Volume; @@ -376,7 +379,7 @@ public void registerGuru(VirtualMachine.Type type, VirtualMachineGuru guru) { @Override @DB public void allocate(String vmInstanceName, final VirtualMachineTemplate template, ServiceOffering serviceOffering, - final DiskOfferingInfo rootDiskOfferingInfo, LinkedHashMap dataDiskOfferings, + final DiskOfferingInfo rootDiskOfferingInfo, final List dataDiskOfferings, final LinkedHashMap> auxiliaryNetworks, DeploymentPlan plan, HypervisorType hyperType) throws InsufficientCapacityException { @@ -389,12 +392,10 @@ public void allocate(String vmInstanceName, final VirtualMachineTemplate templat vm.setDataCenterId(plan.getDataCenterId()); if (plan.getPodId() != null) { - vm.setPodId(plan.getPodId()); + vm.setPodIdToDeployIn(plan.getPodId()); } assert (plan.getClusterId() == null && plan.getPoolId() == null) : "We currently don't support cluster and pool preset yet"; final VMInstanceVO vmFinal = _vmDao.persist(vm); - final LinkedHashMap dataDiskOfferingsFinal = - dataDiskOfferings == null ? new LinkedHashMap() : dataDiskOfferings; final VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vmFinal, template, serviceOffering, null, null); @@ -416,8 +417,8 @@ public void doInTransactionWithoutResult(TransactionStatus status) throws Insuff } if (template.getFormat() == ImageFormat.ISO) { - volumeMgr.allocateRawVolume(Type.ROOT, "ROOT-" + vmFinal.getId(), rootDiskOfferingInfo.getDiskOffering(), rootDiskOfferingInfo.getSize(), vmFinal, - template, owner); + volumeMgr.allocateRawVolume(Type.ROOT, "ROOT-" + vmFinal.getId(), rootDiskOfferingInfo.getDiskOffering(), rootDiskOfferingInfo.getSize(), + rootDiskOfferingInfo.getMinIops(), rootDiskOfferingInfo.getMaxIops(), vmFinal, template, owner); } else if (template.getFormat() == ImageFormat.BAREMETAL) { // Do nothing } else { @@ -425,8 +426,11 @@ public void doInTransactionWithoutResult(TransactionStatus status) throws Insuff rootDiskOfferingInfo.getMinIops(), rootDiskOfferingInfo.getMaxIops(), template, vmFinal, owner); } - for (Map.Entry offering : dataDiskOfferingsFinal.entrySet()) { - volumeMgr.allocateRawVolume(Type.DATADISK, "DATA-" + vmFinal.getId(), offering.getKey(), offering.getValue(), vmFinal, template, owner); + if (dataDiskOfferings != null) { + for (DiskOfferingInfo dataDiskOfferingInfo : dataDiskOfferings) { + volumeMgr.allocateRawVolume(Type.DATADISK, "DATA-" + vmFinal.getId(), dataDiskOfferingInfo.getDiskOffering(), dataDiskOfferingInfo.getSize(), + dataDiskOfferingInfo.getMinIops(), dataDiskOfferingInfo.getMaxIops(), vmFinal, template, owner); + } } } }); @@ -439,7 +443,7 @@ public void doInTransactionWithoutResult(TransactionStatus status) throws Insuff @Override public void allocate(String vmInstanceName, VirtualMachineTemplate template, ServiceOffering serviceOffering, LinkedHashMap> networks, DeploymentPlan plan, HypervisorType hyperType) throws InsufficientCapacityException { - allocate(vmInstanceName, template, serviceOffering, new DiskOfferingInfo(serviceOffering), null, networks, plan, hyperType); + allocate(vmInstanceName, template, serviceOffering, new DiskOfferingInfo(serviceOffering), new ArrayList(), networks, plan, hyperType); } private VirtualMachineGuru getVmGuru(VirtualMachine vm) { @@ -569,8 +573,8 @@ protected void advanceExpunge(VMInstanceVO vm) throws ResourceUnavailableExcepti @Override public boolean start() { // TODO, initial delay is hardcoded - _executor.scheduleAtFixedRate(new TransitionTask(), 5000, VmJobStateReportInterval.value(), TimeUnit.SECONDS); - _executor.scheduleAtFixedRate(new CleanupTask(), VmOpCleanupInterval.value(), VmOpCleanupInterval.value(), TimeUnit.SECONDS); + _executor.scheduleAtFixedRate(new CleanupTask(), 5, VmJobStateReportInterval.value(), TimeUnit.SECONDS); + _executor.scheduleAtFixedRate(new TransitionTask(), VmOpCleanupInterval.value(), VmOpCleanupInterval.value(), TimeUnit.SECONDS); cancelWorkItems(_nodeId); // cleanup left over place holder works @@ -774,8 +778,9 @@ public void advanceStart(String vmUuid, Map try { orchestrateStart(vmUuid, params, planToDeploy, planner); } finally { - if (VmJobEnabled.value()) + if (placeHolder != null) { _workJobDao.expunge(placeHolder.getId()); + } } } else { Outcome outcome = startVmThroughJobQueue(vmUuid, params, planToDeploy, planner); @@ -950,7 +955,7 @@ public void orchestrateStart(String vmUuid, Map vmmetadata = new HashMap(); + vmmetadata.put(vm.getInstanceName(), platform); + syncVMMetaData(vmmetadata); } } } @@ -1214,9 +1221,18 @@ public void stop(String vmUuid) throws ResourceUnavailableException { } } - protected boolean sendStop(VirtualMachineGuru guru, VirtualMachineProfile profile, boolean force) { + + protected boolean getExecuteInSequence(HypervisorType hypervisorType) { + if (HypervisorType.KVM == hypervisorType) { + return false; + } else { + return ExecuteInSequence.value(); + } + } + + protected boolean sendStop(VirtualMachineGuru guru, VirtualMachineProfile profile, boolean force, boolean checkBeforeCleanup) { VirtualMachine vm = profile.getVirtualMachine(); - StopCommand stop = new StopCommand(vm, ExecuteInSequence.value()); + StopCommand stop = new StopCommand(vm, getExecuteInSequence(vm.getHypervisorType()), checkBeforeCleanup); try { StopAnswer answer = (StopAnswer)_agentMgr.send(vm.getHostId(), stop); if (answer != null) { @@ -1262,62 +1278,65 @@ protected boolean cleanup(VirtualMachineGuru guru, VirtualMachineProfile profile VirtualMachine vm = profile.getVirtualMachine(); State state = vm.getState(); s_logger.debug("Cleaning up resources for the vm " + vm + " in " + state + " state"); - if (state == State.Starting) { - Step step = work.getStep(); - if (step == Step.Starting && !cleanUpEvenIfUnableToStop) { - s_logger.warn("Unable to cleanup vm " + vm + "; work state is incorrect: " + step); - return false; - } + try { + if (state == State.Starting) { + Step step = work.getStep(); + if (step == Step.Starting && !cleanUpEvenIfUnableToStop) { + s_logger.warn("Unable to cleanup vm " + vm + "; work state is incorrect: " + step); + return false; + } + + if (step == Step.Started || step == Step.Starting || step == Step.Release) { + if (vm.getHostId() != null) { + if (!sendStop(guru, profile, cleanUpEvenIfUnableToStop, false)) { + s_logger.warn("Failed to stop vm " + vm + " in " + State.Starting + " state as a part of cleanup process"); + return false; + } + } + } - if (step == Step.Started || step == Step.Starting || step == Step.Release) { + if (step != Step.Release && step != Step.Prepare && step != Step.Started && step != Step.Starting) { + s_logger.debug("Cleanup is not needed for vm " + vm + "; work state is incorrect: " + step); + return true; + } + } else if (state == State.Stopping) { if (vm.getHostId() != null) { - if (!sendStop(guru, profile, cleanUpEvenIfUnableToStop)) { - s_logger.warn("Failed to stop vm " + vm + " in " + State.Starting + " state as a part of cleanup process"); + if (!sendStop(guru, profile, cleanUpEvenIfUnableToStop, false)) { + s_logger.warn("Failed to stop vm " + vm + " in " + State.Stopping + " state as a part of cleanup process"); return false; } } - } - - if (step != Step.Release && step != Step.Prepare && step != Step.Started && step != Step.Starting) { - s_logger.debug("Cleanup is not needed for vm " + vm + "; work state is incorrect: " + step); - return true; - } - } else if (state == State.Stopping) { - if (vm.getHostId() != null) { - if (!sendStop(guru, profile, cleanUpEvenIfUnableToStop)) { - s_logger.warn("Failed to stop vm " + vm + " in " + State.Stopping + " state as a part of cleanup process"); - return false; + } else if (state == State.Migrating) { + if (vm.getHostId() != null) { + if (!sendStop(guru, profile, cleanUpEvenIfUnableToStop, false)) { + s_logger.warn("Failed to stop vm " + vm + " in " + State.Migrating + " state as a part of cleanup process"); + return false; + } } - } - } else if (state == State.Migrating) { - if (vm.getHostId() != null) { - if (!sendStop(guru, profile, cleanUpEvenIfUnableToStop)) { - s_logger.warn("Failed to stop vm " + vm + " in " + State.Migrating + " state as a part of cleanup process"); - return false; + if (vm.getLastHostId() != null) { + if (!sendStop(guru, profile, cleanUpEvenIfUnableToStop, false)) { + s_logger.warn("Failed to stop vm " + vm + " in " + State.Migrating + " state as a part of cleanup process"); + return false; + } } - } - if (vm.getLastHostId() != null) { - if (!sendStop(guru, profile, cleanUpEvenIfUnableToStop)) { - s_logger.warn("Failed to stop vm " + vm + " in " + State.Migrating + " state as a part of cleanup process"); + } else if (state == State.Running) { + if (!sendStop(guru, profile, cleanUpEvenIfUnableToStop, false)) { + s_logger.warn("Failed to stop vm " + vm + " in " + State.Running + " state as a part of cleanup process"); return false; } } - } else if (state == State.Running) { - if (!sendStop(guru, profile, cleanUpEvenIfUnableToStop)) { - s_logger.warn("Failed to stop vm " + vm + " in " + State.Running + " state as a part of cleanup process"); - return false; + } finally { + try { + _networkMgr.release(profile, cleanUpEvenIfUnableToStop); + s_logger.debug("Successfully released network resources for the vm " + vm); + } catch (Exception e) { + s_logger.warn("Unable to release some network resources.", e); } - } - try { - _networkMgr.release(profile, cleanUpEvenIfUnableToStop); - s_logger.debug("Successfully released network resources for the vm " + vm); - } catch (Exception e) { - s_logger.warn("Unable to release some network resources.", e); + volumeMgr.release(profile); + s_logger.debug("Successfully cleanued up resources for the vm " + vm + " in " + state + " state"); } - volumeMgr.release(profile); - s_logger.debug("Successfully cleanued up resources for the vm " + vm + " in " + state + " state"); return true; } @@ -1337,8 +1356,9 @@ public void advanceStop(String vmUuid, boolean cleanUpEvenIfUnableToStop) try { orchestrateStop(vmUuid, cleanUpEvenIfUnableToStop); } finally { - if (VmJobEnabled.value()) + if (placeHolder != null) { _workJobDao.expunge(placeHolder.getId()); + } } } else { @@ -1436,7 +1456,7 @@ private void advanceStop(VMInstanceVO vm, boolean cleanUpEvenIfUnableToStop) thr if (s_logger.isDebugEnabled()) { s_logger.debug("Unable to transition the state but we're moving on because it's forced stop"); } - if (state == State.Starting || state == State.Migrating) { + if ((state == State.Starting) || (state == State.Migrating) || (state == State.Stopping)) { if (work != null) { doCleanup = true; } else { @@ -1445,8 +1465,6 @@ private void advanceStop(VMInstanceVO vm, boolean cleanUpEvenIfUnableToStop) thr } throw new CloudRuntimeException("Work item not found, We cannot stop " + vm + " when it is in state " + vm.getState()); } - } else if (state == State.Stopping) { - doCleanup = true; } if (doCleanup) { @@ -1476,7 +1494,9 @@ private void advanceStop(VMInstanceVO vm, boolean cleanUpEvenIfUnableToStop) thr } vmGuru.prepareStop(profile); - StopCommand stop = new StopCommand(vm, ExecuteInSequence.value()); + + StopCommand stop = new StopCommand(vm, getExecuteInSequence(vm.getHypervisorType()), false); + boolean stopped = false; StopAnswer answer = null; try { @@ -1664,8 +1684,9 @@ public void storageMigration(String vmUuid, StoragePool destPool) { try { orchestrateStorageMigration(vmUuid, destPool); } finally { - if (VmJobEnabled.value()) + if (placeHolder != null) { _workJobDao.expunge(placeHolder.getId()); + } } } else { Outcome outcome = migrateVmStorageThroughJobQueue(vmUuid, destPool); @@ -1714,7 +1735,7 @@ private void orchestrateStorageMigration(String vmUuid, StoragePool destPool) { //when start the vm next time, don;'t look at last_host_id, only choose the host based on volume/storage pool vm.setLastHostId(null); - vm.setPodId(destPool.getPodId()); + vm.setPodIdToDeployIn(destPool.getPodId()); } else { s_logger.debug("Storage migration failed"); } @@ -1758,8 +1779,9 @@ public void migrate(String vmUuid, long srcHostId, DeployDestination dest) try { orchestrateMigrate(vmUuid, srcHostId, dest); } finally { - if (VmJobEnabled.value()) + if (placeHolder != null) { _workJobDao.expunge(placeHolder.getId()); + } } } else { Outcome outcome = migrateVmThroughJobQueue(vmUuid, srcHostId, dest); @@ -1809,8 +1831,16 @@ protected void migrate(VMInstanceVO vm, long srcHostId, DeployDestination dest) } if (fromHost.getClusterId().longValue() != dest.getCluster().getId()) { - s_logger.info("Source and destination host are not in same cluster, unable to migrate to host: " + dest.getHost().getId()); - throw new CloudRuntimeException("Source and destination host are not in same cluster, unable to migrate to host: " + dest.getHost().getId()); + List volumes = _volsDao.findCreatedByInstance(vm.getId()); + for (VolumeVO volume : volumes) { + if (!(_storagePoolDao.findById(volume.getPoolId())).getScope().equals(ScopeType.ZONE)) { + s_logger.info("Source and destination host are not in same cluster and all volumes are not on zone wide primary store, unable to migrate to host: " + + dest.getHost().getId()); + throw new CloudRuntimeException( + "Source and destination host are not in same cluster and all volumes are not on zone wide primary store, unable to migrate to host: " + + dest.getHost().getId()); + } + } } VirtualMachineGuru vmGuru = getVmGuru(vm); @@ -1889,6 +1919,22 @@ protected void migrate(VMInstanceVO vm, long srcHostId, DeployDestination dest) if (!ma.getResult()) { throw new CloudRuntimeException("Unable to migrate due to " + ma.getDetails()); } + try { + if (dest.getHost().getHypervisorType() == HypervisorType.Hyperv) { + MigrateCompleteCommand mcc = new MigrateCompleteCommand(to, ExecuteInSequence.value()); + Answer answer = _agentMgr.send(dstHostId, mcc); + if (answer == null || !answer.getResult()) { + s_logger.error("HA may not work for vm: " + vm + " on destination host: " + dstHostId); + _alertMgr.sendAlert(alertType, dest.getHost().getDataCenterId(), dest.getHost().getPodId(), "HA may not work for vm: " + vm + " on destination host: " + + dstHostId, null); + } + } + } catch (Exception e) { + s_logger.error("HA may not work for vm: " + vm + " on destination host: " + dstHostId); + _alertMgr.sendAlert(alertType, dest.getHost().getDataCenterId(), dest.getHost().getPodId(), "HA may not work for vm: " + vm + " on destination host: " + + dstHostId, null); + } + } catch (OperationTimedoutException e) { if (e.isActive()) { s_logger.warn("Active migration command so scheduling a restart for " + vm); @@ -1948,24 +1994,26 @@ protected void migrate(VMInstanceVO vm, long srcHostId, DeployDestination dest) } } - private Map getPoolListForVolumesForMigration(VirtualMachineProfile profile, Host host, Map volumeToPool) { + private Map getPoolListForVolumesForMigration(VirtualMachineProfile profile, Host host, Map volumeToPool) { List allVolumes = _volsDao.findUsableVolumesForInstance(profile.getId()); + Map volumeToPoolObjectMap = new HashMap (); for (VolumeVO volume : allVolumes) { - StoragePool pool = volumeToPool.get(volume); - DiskOfferingVO diskOffering = _diskOfferingDao.findById(volume.getDiskOfferingId()); + Long poolId = volumeToPool.get(Long.valueOf(volume.getId())); + StoragePoolVO pool = _storagePoolDao.findById(poolId); StoragePoolVO currentPool = _storagePoolDao.findById(volume.getPoolId()); + DiskOfferingVO diskOffering = _diskOfferingDao.findById(volume.getDiskOfferingId()); if (pool != null) { // Check if pool is accessible from the destination host and disk offering with which the volume was // created is compliant with the pool type. if (_poolHostDao.findByPoolHost(pool.getId(), host.getId()) == null || pool.isLocal() != diskOffering.getUseLocalStorage()) { // Cannot find a pool for the volume. Throw an exception. throw new CloudRuntimeException("Cannot migrate volume " + volume + " to storage pool " + pool + " while migrating vm to host " + host + - ". Either the pool is not accessible from the " + "host or because of the offering with which the volume is created it cannot be placed on " + + ". Either the pool is not accessible from the host or because of the offering with which the volume is created it cannot be placed on " + "the given pool."); } else if (pool.getId() == currentPool.getId()) { - // If the pool to migrate too is the same as current pool, remove the volume from the list of - // volumes to be migrated. - volumeToPool.remove(volume); + // If the pool to migrate too is the same as current pool, the volume doesn't need to be migrated. + } else { + volumeToPoolObjectMap.put(volume, pool); } } else { // Find a suitable pool for the volume. Call the storage pool allocator to find the list of pools. @@ -1974,23 +2022,33 @@ private Map getPoolListForVolumesForMigration(VirtualMachin ExcludeList avoid = new ExcludeList(); boolean currentPoolAvailable = false; + List poolList = new ArrayList(); for (StoragePoolAllocator allocator : _storagePoolAllocators) { - List poolList = allocator.allocateToPool(diskProfile, profile, plan, avoid, StoragePoolAllocator.RETURN_UPTO_ALL); - if (poolList != null && !poolList.isEmpty()) { - // Volume needs to be migrated. Pick the first pool from the list. Add a mapping to migrate the - // volume to a pool only if it is required; that is the current pool on which the volume resides - // is not available on the destination host. - if (poolList.contains(currentPool)) { + List poolListFromAllocator = allocator.allocateToPool(diskProfile, profile, plan, avoid, StoragePoolAllocator.RETURN_UPTO_ALL); + if (poolListFromAllocator != null && !poolListFromAllocator.isEmpty()) { + poolList.addAll(poolListFromAllocator); + } + } + + if (poolList != null && !poolList.isEmpty()) { + // Volume needs to be migrated. Pick the first pool from the list. Add a mapping to migrate the + // volume to a pool only if it is required; that is the current pool on which the volume resides + // is not available on the destination host. + Iterator iter = poolList.iterator(); + while (iter.hasNext()) { + if (currentPool.getId() == iter.next().getId()) { currentPoolAvailable = true; - } else { - volumeToPool.put(volume, _storagePoolDao.findByUuid(poolList.get(0).getUuid())); + break; } + } - break; + if (!currentPoolAvailable) { + volumeToPoolObjectMap.put(volume, _storagePoolDao.findByUuid(poolList.get(0).getUuid())); } } - if (!currentPoolAvailable && !volumeToPool.containsKey(volume)) { + + if (!currentPoolAvailable && !volumeToPoolObjectMap.containsKey(volume)) { // Cannot find a pool for the volume. Throw an exception. throw new CloudRuntimeException("Cannot find a storage pool which is available for volume " + volume + " while migrating virtual machine " + profile.getVirtualMachine() + " to host " + host); @@ -1998,7 +2056,7 @@ private Map getPoolListForVolumesForMigration(VirtualMachin } } - return volumeToPool; + return volumeToPoolObjectMap; } private void moveVmToMigratingState(T vm, Long hostId, ItWorkVO work) throws ConcurrentOperationException { @@ -2028,7 +2086,7 @@ private void moveVmOutofMigratingStateOnSuccess(T vm, L } @Override - public void migrateWithStorage(String vmUuid, long srcHostId, long destHostId, Map volumeToPool) + public void migrateWithStorage(String vmUuid, long srcHostId, long destHostId, Map volumeToPool) throws ResourceUnavailableException, ConcurrentOperationException { AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext(); @@ -2043,8 +2101,9 @@ public void migrateWithStorage(String vmUuid, long srcHostId, long destHostId, M try { orchestrateMigrateWithStorage(vmUuid, srcHostId, destHostId, volumeToPool); } finally { - if (VmJobEnabled.value()) + if (placeHolder != null) { _workJobDao.expunge(placeHolder.getId()); + } } } else { @@ -2072,7 +2131,7 @@ else if (jobException instanceof Throwable) } } - private void orchestrateMigrateWithStorage(String vmUuid, long srcHostId, long destHostId, Map volumeToPool) throws ResourceUnavailableException, + private void orchestrateMigrateWithStorage(String vmUuid, long srcHostId, long destHostId, Map volumeToPool) throws ResourceUnavailableException, ConcurrentOperationException { VMInstanceVO vm = _vmDao.findByUuid(vmUuid); @@ -2088,11 +2147,11 @@ private void orchestrateMigrateWithStorage(String vmUuid, long srcHostId, long d // Create a map of which volume should go in which storage pool. VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm); - volumeToPool = getPoolListForVolumesForMigration(profile, destHost, volumeToPool); + Map volumeToPoolMap = getPoolListForVolumesForMigration(profile, destHost, volumeToPool); // If none of the volumes have to be migrated, fail the call. Administrator needs to make a call for migrating // a vm and not migrating a vm with storage. - if (volumeToPool.isEmpty()) { + if (volumeToPoolMap == null || volumeToPoolMap.isEmpty()) { throw new InvalidParameterValueException("Migration of the vm " + vm + "from host " + srcHost + " to destination host " + destHost + " doesn't involve migrating the volumes."); } @@ -2122,7 +2181,7 @@ private void orchestrateMigrateWithStorage(String vmUuid, long srcHostId, long d boolean migrated = false; try { // Migrate the vm and its volume. - volumeMgr.migrateVolumes(vm, to, srcHost, destHost, volumeToPool); + volumeMgr.migrateVolumes(vm, to, srcHost, destHost, volumeToPoolMap); // Put the vm back to running state. moveVmOutofMigratingStateOnSuccess(vm, destHost.getId(), work); @@ -2389,8 +2448,9 @@ public void advanceReboot(String vmUuid, Map outcome = rebootVmThroughJobQueue(vmUuid, params); @@ -2451,11 +2511,12 @@ private void orchestrateReboot(String vmUuid, Map vmMetadatum) { } VMInstanceVO vm = _vmDao.findVMByInstanceName(name); if (vm != null && vm.getType() == VirtualMachine.Type.User) { - // track platform info + boolean changed = false; UserVmVO userVm = _userVmDao.findById(vm.getId()); _userVmDao.loadDetails(userVm); - userVm.setDetail("platform", platform); + if ( userVm.details.containsKey("timeoffset")) { + userVm.details.remove("timeoffset"); + changed = true; + } + if (!userVm.details.containsKey("platform") || !userVm.details.get("platform").equals(platform)) { + userVm.setDetail("platform", platform); + changed = true; + } String pvdriver = "xenserver56"; if ( platform.contains("device_id")) { pvdriver = "xenserver61"; } - userVm.setDetail("hypervisortoolsversion", pvdriver); - _userVmDao.saveDetails(userVm); + if (!userVm.details.containsKey("hypervisortoolsversion") || !userVm.details.get("hypervisortoolsversion").equals(pvdriver)) { + userVm.setDetail("hypervisortoolsversion", pvdriver); + changed = true; + } + if ( changed ) { + _userVmDao.saveDetails(userVm); + } } } } - public void deltaSync(Map> newStates) { Map states = convertToInfos(newStates); @@ -3241,7 +3313,6 @@ protected class AgentVmInfo { public String hostUuid; public VMInstanceVO vm; - @SuppressWarnings("unchecked") public AgentVmInfo(String name, VMInstanceVO vm, State state, String host) { this.name = name; this.state = state; @@ -3351,8 +3422,9 @@ public NicProfile addVmToNetwork(VirtualMachine vm, Network network, NicProfile try { return orchestrateAddVmToNetwork(vm, network, requested); } finally { - if (VmJobEnabled.value()) + if (placeHolder != null) { _workJobDao.expunge(placeHolder.getId()); + } } } else { Outcome outcome = addVmToNetworkThroughJobQueue(vm, network, requested); @@ -3362,7 +3434,7 @@ public NicProfile addVmToNetwork(VirtualMachine vm, Network network, NicProfile } catch (InterruptedException e) { throw new RuntimeException("Operation is interrupted", e); } catch (java.util.concurrent.ExecutionException e) { - throw new RuntimeException("Execution excetion", e); + throw new RuntimeException("Execution exception", e); } Object jobException = _jobMgr.unmarshallResultObject(outcome.getJob()); @@ -3422,7 +3494,7 @@ private NicProfile orchestrateAddVmToNetwork(VirtualMachine vm, Network network, long isDefault = (nic.isDefaultNic()) ? 1 : 0; // insert nic's Id into DB as resource_name UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NETWORK_OFFERING_ASSIGN, vmVO.getAccountId(), vmVO.getDataCenterId(), vmVO.getId(), - Long.toString(nic.getId()), network.getNetworkOfferingId(), null, isDefault, VirtualMachine.class.getName(), vmVO.getUuid()); + Long.toString(nic.getId()), network.getNetworkOfferingId(), null, isDefault, VirtualMachine.class.getName(), vmVO.getUuid(), vm.isDisplay()); return nic; } else { s_logger.warn("Failed to plug nic to the vm " + vm + " in network " + network); @@ -3465,8 +3537,9 @@ public boolean removeNicFromVm(VirtualMachine vm, Nic nic) try { return orchestrateRemoveNicFromVm(vm, nic); } finally { - if (VmJobEnabled.value()) + if (placeHolder != null) { _workJobDao.expunge(placeHolder.getId()); + } } } else { @@ -3537,7 +3610,7 @@ private boolean orchestrateRemoveNicFromVm(VirtualMachine vm, Nic nic) throws Co s_logger.debug("Nic is unplugged successfully for vm " + vm + " in network " + network); long isDefault = (nic.isDefaultNic()) ? 1 : 0; UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NETWORK_OFFERING_REMOVE, vm.getAccountId(), vm.getDataCenterId(), vm.getId(), - Long.toString(nic.getId()), network.getNetworkOfferingId(), null, isDefault, VirtualMachine.class.getName(), vm.getUuid()); + Long.toString(nic.getId()), network.getNetworkOfferingId(), null, isDefault, VirtualMachine.class.getName(), vm.getUuid(), vm.isDisplay()); } else { s_logger.warn("Failed to unplug nic for the vm " + vm + " from network " + network); return false; @@ -3717,8 +3790,9 @@ public void migrateForScale(String vmUuid, long srcHostId, DeployDestination des try { orchestrateMigrateForScale(vmUuid, srcHostId, dest, oldSvcOfferingId); } finally { - if (VmJobEnabled.value()) + if (placeHolder != null) { _workJobDao.expunge(placeHolder.getId()); + } } } else { Outcome outcome = migrateVmForScaleThroughJobQueue(vmUuid, srcHostId, dest, oldSvcOfferingId); @@ -3842,6 +3916,21 @@ private void orchestrateMigrateForScale(String vmUuid, long srcHostId, DeployDes s_logger.error("Unable to migrate due to " + ma.getDetails()); throw new CloudRuntimeException("Unable to migrate due to " + ma.getDetails()); } + try { + if (dest.getHost().getHypervisorType() == HypervisorType.Hyperv) { + MigrateCompleteCommand mcc = new MigrateCompleteCommand(to, ExecuteInSequence.value()); + Answer answer = _agentMgr.send(dstHostId, mcc); + if (answer == null || !answer.getResult()) { + s_logger.error("HA may not work for vm: " + vm + " on destination host: " + dstHostId); + _alertMgr.sendAlert(alertType, dest.getHost().getDataCenterId(), dest.getHost().getPodId(), "HA may not work for vm: " + vm + " on destination host: " + + dstHostId, null); + } + } + } catch (Exception e) { + s_logger.error("HA may not work for vm: " + vm + " on destination host: " + dstHostId); + _alertMgr.sendAlert(alertType, dest.getHost().getDataCenterId(), dest.getHost().getPodId(), "HA may not work for vm: " + vm + " on destination host: " + + dstHostId, null); + } } catch (OperationTimedoutException e) { if (e.isActive()) { s_logger.warn("Active migration command so scheduling a restart for " + vm); @@ -3980,8 +4069,9 @@ public VMInstanceVO reConfigureVm(String vmUuid, ServiceOffering oldServiceOffer try { return orchestrateReConfigureVm(vmUuid, oldServiceOffering, reconfiguringOnExistingHost); } finally { - if (VmJobEnabled.value()) + if (placeHolder != null) { _workJobDao.expunge(placeHolder.getId()); + } } } else { Outcome outcome = reconfigureVmThroughJobQueue(vmUuid, oldServiceOffering, reconfiguringOnExistingHost); @@ -4033,7 +4123,7 @@ private VMInstanceVO orchestrateReConfigureVm(String vmUuid, ServiceOffering old work.setStep(Step.Prepare); work.setResourceType(ItWorkVO.ResourceType.Host); work.setResourceId(vm.getHostId()); - work = _workDao.persist(work); + _workDao.persist(work); boolean success = false; try { if (reconfiguringOnExistingHost) { @@ -4055,8 +4145,6 @@ private VMInstanceVO orchestrateReConfigureVm(String vmUuid, ServiceOffering old } catch (AgentUnavailableException e) { throw e; } finally { - // work.setStep(Step.Done); - //_workDao.update(work.getId(), work); if (!success) { _capacityMgr.releaseVmCapacity(vm, false, false, vm.getHostId()); // release the new capacity vm.setServiceOfferingId(oldServiceOffering.getId()); @@ -4100,7 +4188,7 @@ private void HandlePowerStateReport(String subject, String senderAddress, Object List pendingWorkJobs = _workJobDao.listPendingWorkJobs( VirtualMachine.Type.Instance, vmId); - if (pendingWorkJobs.size() == 0 || !_haMgr.hasPendingHaWork(vmId)) { + if (pendingWorkJobs.size() == 0 && !_haMgr.hasPendingHaWork(vmId)) { // there is no pending operation job VMInstanceVO vm = _vmDao.findById(vmId); if (vm != null) { @@ -4221,9 +4309,18 @@ private void handlePowerOffReportWithNoPendingJobsOnVM(VMInstanceVO vm) { case Stopped: case Migrating: s_logger.info("VM " + vm.getInstanceName() + " is at " + vm.getState() + " and we received a power-off report while there is no pending jobs on it"); + if(vm.isHaEnabled() && vm.getState() == State.Running && vm.getHypervisorType() != HypervisorType.VMware && vm.getHypervisorType() != HypervisorType.Hyperv) { + s_logger.info("Detected out-of-band stop of a HA enabled VM " + vm.getInstanceName() + ", will schedule restart"); + if(!_haMgr.hasPendingHaWork(vm.getId())) + _haMgr.scheduleRestart(vm, true); + else + s_logger.info("VM " + vm.getInstanceName() + " already has an pending HA task working on it"); + return; + } + VirtualMachineGuru vmGuru = getVmGuru(vm); VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm); - sendStop(vmGuru, profile, true); + sendStop(vmGuru, profile, true, true); try { stateTransitTo(vm, VirtualMachine.Event.FollowAgentPowerOffReport, null); @@ -4406,8 +4503,9 @@ public VmStateSyncOutcome(final AsyncJob job, final PowerState desiredPowerState super(VirtualMachine.class, job, VmJobCheckInterval.value(), new Predicate() { @Override public boolean checkCondition() { - VMInstanceVO instance = _vmDao.findById(vmId); - if (instance.getPowerState() == desiredPowerState && (srcHostIdForMigration != null && srcHostIdForMigration.equals(instance.getPowerHostId()))) + AsyncJobVO jobVo = _entityMgr.findById(AsyncJobVO.class, job.getId()); + assert (jobVo != null); + if (jobVo == null || jobVo.getStatus() != JobInfo.Status.IN_PROGRESS) return true; return false; } @@ -4730,7 +4828,7 @@ public Object[] doInTransaction(TransactionStatus status) { public Outcome migrateVmWithStorageThroughJobQueue( final String vmUuid, final long srcHostId, final long destHostId, - final Map volumeToPool) { + final Map volumeToPool) { final CallContext context = CallContext.current(); final User user = context.getCallingUser(); diff --git a/engine/orchestration/src/com/cloud/vm/VmWorkMigrateWithStorage.java b/engine/orchestration/src/com/cloud/vm/VmWorkMigrateWithStorage.java index ee30c74abf..52fe9f2877 100644 --- a/engine/orchestration/src/com/cloud/vm/VmWorkMigrateWithStorage.java +++ b/engine/orchestration/src/com/cloud/vm/VmWorkMigrateWithStorage.java @@ -18,18 +18,15 @@ import java.util.Map; -import com.cloud.storage.StoragePool; -import com.cloud.storage.Volume; - public class VmWorkMigrateWithStorage extends VmWork { private static final long serialVersionUID = -5626053872453569165L; long srcHostId; long destHostId; - Map volumeToPool; + Map volumeToPool; public VmWorkMigrateWithStorage(long userId, long accountId, long vmId, String handlerName, long srcHostId, - long destHostId, Map volumeToPool) { + long destHostId, Map volumeToPool) { super(userId, accountId, vmId, handlerName); @@ -46,7 +43,7 @@ public long getDestHostId() { return destHostId; } - public Map getVolumeToPool() { + public Map getVolumeToPool() { return volumeToPool; } } diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/CloudOrchestrator.java b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/CloudOrchestrator.java index fc1b85c080..2b4995466b 100755 --- a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/CloudOrchestrator.java +++ b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/CloudOrchestrator.java @@ -45,7 +45,6 @@ import com.cloud.network.Network; import com.cloud.network.dao.NetworkDao; import com.cloud.network.dao.NetworkVO; -import com.cloud.offering.DiskOffering; import com.cloud.offering.DiskOfferingInfo; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; @@ -181,14 +180,14 @@ public VirtualMachineEntity createVirtualMachine(String id, String owner, String // Else, a disk offering is optional, and if present will be used to create the data disk DiskOfferingInfo rootDiskOfferingInfo = new DiskOfferingInfo(); - LinkedHashMap dataDiskOfferings = new LinkedHashMap(); + List dataDiskOfferings = new ArrayList(); - ServiceOfferingVO offering = _serviceOfferingDao.findById(vm.getId(), vm.getServiceOfferingId()); + ServiceOfferingVO computeOffering = _serviceOfferingDao.findById(vm.getId(), vm.getServiceOfferingId()); - rootDiskOfferingInfo.setDiskOffering(offering); + rootDiskOfferingInfo.setDiskOffering(computeOffering); rootDiskOfferingInfo.setSize(rootDiskSize); - if (offering.isCustomizedIops() != null && offering.isCustomizedIops()) { + if (computeOffering.isCustomizedIops() != null && computeOffering.isCustomizedIops()) { Map userVmDetails = _userVmDetailsDao.listDetailsKeyPairs(vm.getId()); if (userVmDetails != null) { @@ -213,10 +212,28 @@ public VirtualMachineEntity createVirtualMachine(String id, String owner, String } _volumeMgr.validateVolumeSizeRange(size * 1024 * 1024 * 1024); } - dataDiskOfferings.put(diskOffering, size); + + DiskOfferingInfo dataDiskOfferingInfo = new DiskOfferingInfo(); + + dataDiskOfferingInfo.setDiskOffering(diskOffering); + dataDiskOfferingInfo.setSize(size); + + if (diskOffering.isCustomizedIops() != null && diskOffering.isCustomizedIops()) { + Map userVmDetails = _userVmDetailsDao.listDetailsKeyPairs(vm.getId()); + + if (userVmDetails != null) { + String minIops = userVmDetails.get("minIopsDo"); + String maxIops = userVmDetails.get("maxIopsDo"); + + dataDiskOfferingInfo.setMinIops(minIops != null && minIops.trim().length() > 0 ? Long.parseLong(minIops) : null); + dataDiskOfferingInfo.setMaxIops(maxIops != null && maxIops.trim().length() > 0 ? Long.parseLong(maxIops) : null); + } + } + + dataDiskOfferings.add(dataDiskOfferingInfo); } - _itMgr.allocate(vm.getInstanceName(), _templateDao.findById(new Long(templateId)), offering, rootDiskOfferingInfo, dataDiskOfferings, networkIpMap, plan, + _itMgr.allocate(vm.getInstanceName(), _templateDao.findById(new Long(templateId)), computeOffering, rootDiskOfferingInfo, dataDiskOfferings, networkIpMap, plan, hypervisorType); return vmEntity; @@ -234,13 +251,12 @@ public VirtualMachineEntity createVirtualMachineFromScratch(String id, String ow //load vm instance and offerings and call virtualMachineManagerImpl VMInstanceVO vm = _vmDao.findByUuid(id); - ServiceOfferingVO offering = _serviceOfferingDao.findById(vm.getId(), vm.getServiceOfferingId()); + ServiceOfferingVO computeOffering = _serviceOfferingDao.findById(vm.getId(), vm.getServiceOfferingId()); DiskOfferingInfo rootDiskOfferingInfo = new DiskOfferingInfo(); - rootDiskOfferingInfo.setDiskOffering(offering); + rootDiskOfferingInfo.setDiskOffering(computeOffering); - LinkedHashMap dataDiskOfferings = new LinkedHashMap(); Long diskOfferingId = vm.getDiskOfferingId(); if (diskOfferingId == null) { throw new InvalidParameterValueException("Installing from ISO requires a disk offering to be specified for the root disk."); @@ -261,6 +277,18 @@ public VirtualMachineEntity createVirtualMachineFromScratch(String id, String ow rootDiskOfferingInfo.setDiskOffering(diskOffering); rootDiskOfferingInfo.setSize(size); + if (diskOffering.isCustomizedIops() != null && diskOffering.isCustomizedIops()) { + Map userVmDetails = _userVmDetailsDao.listDetailsKeyPairs(vm.getId()); + + if (userVmDetails != null) { + String minIops = userVmDetails.get("minIopsDo"); + String maxIops = userVmDetails.get("maxIopsDo"); + + rootDiskOfferingInfo.setMinIops(minIops != null && minIops.trim().length() > 0 ? Long.parseLong(minIops) : null); + rootDiskOfferingInfo.setMaxIops(maxIops != null && maxIops.trim().length() > 0 ? Long.parseLong(maxIops) : null); + } + } + LinkedHashMap> networkIpMap = new LinkedHashMap>(); for (String uuid : networkNicMap.keySet()) { NetworkVO network = _networkDao.findByUuid(uuid); @@ -271,7 +299,7 @@ public VirtualMachineEntity createVirtualMachineFromScratch(String id, String ow HypervisorType hypervisorType = HypervisorType.valueOf(hypervisor); - _itMgr.allocate(vm.getInstanceName(), _templateDao.findById(new Long(isoId)), offering, rootDiskOfferingInfo, dataDiskOfferings, networkIpMap, plan, hypervisorType); + _itMgr.allocate(vm.getInstanceName(), _templateDao.findById(new Long(isoId)), computeOffering, rootDiskOfferingInfo, new ArrayList(), networkIpMap, plan, hypervisorType); return vmEntity; } diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java index 6aa1e36ccd..96dafe947d 100755 --- a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java +++ b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java @@ -40,7 +40,6 @@ import org.apache.log4j.Logger; import org.apache.cloudstack.acl.ControlledEntity.ACLType; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; @@ -668,6 +667,7 @@ public void doInTransactionWithoutResult(TransactionStatus status) { NetworkVO vo = new NetworkVO(id, network, offering.getId(), guru.getName(), owner.getDomainId(), owner.getId(), relatedFile, name, displayText, predefined .getNetworkDomain(), offering.getGuestType(), plan.getDataCenterId(), plan.getPhysicalNetworkId(), aclType, offering.getSpecifyIpRanges(), vpcId); vo.setDisplayNetwork(isDisplayNetworkEnabled == null ? true : isDisplayNetworkEnabled); + vo.setStrechedL2Network(offering.getSupportsStrechedL2()); networks.add(_networksDao.persist(vo, vo.getGuestType() == Network.GuestType.Isolated, finalizeServicesAndProvidersForNetwork(offering, plan.getPhysicalNetworkId()))); @@ -675,7 +675,7 @@ public void doInTransactionWithoutResult(TransactionStatus status) { _networksDao.addDomainToNetwork(id, domainId, subdomainAccess == null ? true : subdomainAccess); //send event for storing the domain wide resource access Map params = new HashMap(); - params.put(ApiConstants.ENTITY_TYPE, IAMEntityType.Network); + params.put(ApiConstants.ENTITY_TYPE, Network.class); params.put(ApiConstants.ENTITY_ID, id); params.put(ApiConstants.DOMAIN_ID, domainId); params.put(ApiConstants.SUBDOMAIN_ACCESS, subdomainAccess == null ? true : subdomainAccess); @@ -2245,7 +2245,7 @@ public void doInTransactionWithoutResult(TransactionStatus status) { _networkAccountDao.remove(networkAccount.getId()); // remove its related ACL permission - Pair networkMsg = new Pair(IAMEntityType.Network, networkFinal.getId()); + Pair, Long> networkMsg = new Pair, Long>(Network.class, networkFinal.getId()); _messageBus.publish(_name, EntityManager.MESSAGE_REMOVE_ENTITY_EVENT, PublishScope.LOCAL, networkMsg); } diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java index f3753a7417..76281c6ba1 100644 --- a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java +++ b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java @@ -35,8 +35,10 @@ import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService; import org.apache.cloudstack.engine.subsystem.api.storage.ChapInfo; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreDriver; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStore; +import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotService; @@ -109,10 +111,12 @@ import com.cloud.utils.fsm.NoTransitionException; import com.cloud.utils.fsm.StateMachine2; import com.cloud.vm.DiskProfile; +import com.cloud.vm.UserVmVO; import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachine.State; import com.cloud.vm.VirtualMachineProfile; import com.cloud.vm.VirtualMachineProfileImpl; +import com.cloud.vm.dao.UserVmDao; public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrationService, Configurable { private static final Logger s_logger = Logger.getLogger(VolumeOrchestrator.class); @@ -149,6 +153,8 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati HostDao _hostDao; @Inject SnapshotService _snapshotSrv; + @Inject + protected UserVmDao _userVmDao; private final StateMachine2 _volStateMachine; protected List _storagePoolAllocators; @@ -569,14 +575,17 @@ protected DiskProfile toDiskProfile(Volume vol, DiskOffering offering) { } @Override - public DiskProfile allocateRawVolume(Type type, String name, DiskOffering offering, Long size, VirtualMachine vm, VirtualMachineTemplate template, Account owner) { + public DiskProfile allocateRawVolume(Type type, String name, DiskOffering offering, Long size, Long minIops, Long maxIops, VirtualMachine vm, VirtualMachineTemplate template, Account owner) { if (size == null) { size = offering.getDiskSize(); } else { size = (size * 1024 * 1024 * 1024); } - VolumeVO vol = new VolumeVO(type, name, vm.getDataCenterId(), owner.getDomainId(), owner.getId(), offering.getId(), size, offering.getMinIops(), offering.getMaxIops(), - null); + + minIops = minIops != null ? minIops : offering.getMinIops(); + maxIops = maxIops != null ? maxIops : offering.getMaxIops(); + + VolumeVO vol = new VolumeVO(type, name, vm.getDataCenterId(), owner.getDomainId(), owner.getId(), offering.getId(), size, minIops, maxIops, null); if (vm != null) { vol.setInstanceId(vm.getId()); } @@ -589,6 +598,11 @@ public DiskProfile allocateRawVolume(Type type, String name, DiskOffering offeri if (template.getFormat() == ImageFormat.ISO) { vol.setIsoId(template.getId()); } + // display flag matters only for the User vms + if (vm.getType() == VirtualMachine.Type.User) { + UserVmVO userVm = _userVmDao.findById(vm.getId()); + vol.setDisplayVolume(userVm.isDisplayVm()); + } vol.setFormat(getSupportedImageFormatForCluster(vm.getHypervisorType())); vol = _volsDao.persist(vol); @@ -596,10 +610,10 @@ public DiskProfile allocateRawVolume(Type type, String name, DiskOffering offeri // Save usage event and update resource count for user vm volumes if (vm.getType() == VirtualMachine.Type.User) { UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, vol.getAccountId(), vol.getDataCenterId(), vol.getId(), vol.getName(), offering.getId(), null, size, - Volume.class.getName(), vol.getUuid()); + Volume.class.getName(), vol.getUuid(), vol.isDisplayVolume()); - _resourceLimitMgr.incrementResourceCount(vm.getAccountId(), ResourceType.volume); - _resourceLimitMgr.incrementResourceCount(vm.getAccountId(), ResourceType.primary_storage, new Long(vol.getSize())); + _resourceLimitMgr.incrementResourceCount(vm.getAccountId(), ResourceType.volume, vol.isDisplayVolume()); + _resourceLimitMgr.incrementResourceCount(vm.getAccountId(), ResourceType.primary_storage, vol.isDisplayVolume(), new Long(vol.getSize())); } return toDiskProfile(vol, offering); } @@ -609,8 +623,14 @@ public DiskProfile allocateTemplatedVolume(Type type, String name, DiskOffering assert (template.getFormat() != ImageFormat.ISO) : "ISO is not a template really...."; Long size = _tmpltMgr.getTemplateSize(template.getId(), vm.getDataCenterId()); - if (rootDisksize != null) { - size = (rootDisksize * 1024 * 1024 * 1024); + if (rootDisksize != null ) { + rootDisksize = rootDisksize * 1024 * 1024 * 1024; + if (rootDisksize > size) { + s_logger.debug("Using root disk size of " + rootDisksize + " for volume " + name); + size = rootDisksize; + } else { + s_logger.debug("Using root disk size of " + size + " for volume " + name + "since specified root disk size of " + rootDisksize + " is smaller than template"); + } } minIops = minIops != null ? minIops : offering.getMinIops(); @@ -633,6 +653,12 @@ public DiskProfile allocateTemplatedVolume(Type type, String name, DiskOffering vol.setDeviceId(1l); } + if (vm.getType() == VirtualMachine.Type.User) { + UserVmVO userVm = _userVmDao.findById(vm.getId()); + vol.setDisplayVolume(userVm.isDisplayVm()); + } + + vol = _volsDao.persist(vol); // Create event and update resource count for volumes if vm is a user vm @@ -643,10 +669,10 @@ public DiskProfile allocateTemplatedVolume(Type type, String name, DiskOffering offeringId = offering.getId(); UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, vol.getAccountId(), vol.getDataCenterId(), vol.getId(), vol.getName(), offeringId, null, size, - Volume.class.getName(), vol.getUuid()); + Volume.class.getName(), vol.getUuid(), vol.isDisplayVolume()); - _resourceLimitMgr.incrementResourceCount(vm.getAccountId(), ResourceType.volume); - _resourceLimitMgr.incrementResourceCount(vm.getAccountId(), ResourceType.primary_storage, new Long(vol.getSize())); + _resourceLimitMgr.incrementResourceCount(vm.getAccountId(), ResourceType.volume, vol.isDisplayVolume()); + _resourceLimitMgr.incrementResourceCount(vm.getAccountId(), ResourceType.primary_storage, vol.isDisplayVolume(), new Long(vol.getSize())); } return toDiskProfile(vol, offering); } @@ -661,16 +687,29 @@ private ImageFormat getSupportedImageFormatForCluster(HypervisorType hyperType) } else if (hyperType == HypervisorType.Ovm) { return ImageFormat.RAW; } else if (hyperType == HypervisorType.Hyperv) { - return ImageFormat.VHD; + return ImageFormat.VHDX; } else { return null; } } + private boolean isSupportedImageFormatForCluster(VolumeInfo volume, HypervisorType rootDiskHyperType) { + ImageFormat volumeFormat = volume.getFormat(); + if (rootDiskHyperType == HypervisorType.Hyperv) { + if (volumeFormat.equals(ImageFormat.VHDX) || volumeFormat.equals(ImageFormat.VHD)) { + return true; + } else { + return false; + } + } else { + return volume.getFormat().equals(getSupportedImageFormatForCluster(rootDiskHyperType)); + } + } + private VolumeInfo copyVolume(StoragePool rootDiskPool, VolumeInfo volume, VirtualMachine vm, VirtualMachineTemplate rootDiskTmplt, DataCenter dcVO, Pod pod, DiskOffering diskVO, ServiceOffering svo, HypervisorType rootDiskHyperType) throws NoTransitionException { - if (!volume.getFormat().equals(getSupportedImageFormatForCluster(rootDiskHyperType))) { + if (!isSupportedImageFormatForCluster(volume, rootDiskHyperType)) { throw new InvalidParameterValueException("Failed to attach volume to VM since volumes format " + volume.getFormat().getFileExtension() + " is not compatible with the vm hypervisor type"); } @@ -685,8 +724,8 @@ private VolumeInfo copyVolume(StoragePool rootDiskPool, VolumeInfo volume, Virtu public VolumeInfo createVolumeOnPrimaryStorage(VirtualMachine vm, Volume rootVolumeOfVm, VolumeInfo volume, HypervisorType rootDiskHyperType) throws NoTransitionException { VirtualMachineTemplate rootDiskTmplt = _entityMgr.findById(VirtualMachineTemplate.class, vm.getTemplateId()); DataCenter dcVO = _entityMgr.findById(DataCenter.class, vm.getDataCenterId()); - Pod pod = _entityMgr.findById(Pod.class, vm.getPodIdToDeployIn()); StoragePoolVO rootDiskPool = _storagePoolDao.findById(rootVolumeOfVm.getPoolId()); + Pod pod = _entityMgr.findById(Pod.class, rootDiskPool.getPodId()); ServiceOffering svo = _entityMgr.findById(ServiceOffering.class, vm.getServiceOfferingId()); DiskOffering diskVO = _entityMgr.findById(DiskOffering.class, volume.getDiskOfferingId()); Long clusterId = (rootDiskPool == null ? null : rootDiskPool.getClusterId()); @@ -707,7 +746,9 @@ public VolumeInfo createVolumeOnPrimaryStorage(VirtualMachine vm, Volume rootVol throw new CloudRuntimeException("Volume shouldn't be null " + volume.getId()); } VolumeVO volVO = _volsDao.findById(vol.getId()); - volVO.setFormat(getSupportedImageFormatForCluster(rootDiskHyperType)); + if (volVO.getFormat() == null) { + volVO.setFormat(getSupportedImageFormatForCluster(rootDiskHyperType)); + } _volsDao.update(volVO.getId(), volVO); return volFactory.getVolume(volVO.getId()); } @@ -807,6 +848,15 @@ public void doInTransactionWithoutResult(TransactionStatus status) { } } + @Override + public void disconnectVolumeFromHost(VolumeInfo volumeInfo, Host host, DataStore dataStore) { + DataStoreDriver dataStoreDriver = dataStore != null ? dataStore.getDriver() : null; + + if (dataStoreDriver instanceof PrimaryDataStoreDriver) { + ((PrimaryDataStoreDriver)dataStoreDriver).disconnectVolumeFromHost(volumeInfo, host, dataStore); + } + } + @Override public void disconnectVolumesFromHost(long vmId, long hostId) { HostVO host = _hostDao.findById(hostId); @@ -816,9 +866,11 @@ public void disconnectVolumesFromHost(long vmId, long hostId) { if (volumesForVm != null) { for (VolumeVO volumeForVm : volumesForVm) { VolumeInfo volumeInfo = volFactory.getVolume(volumeForVm.getId()); - DataStore dataStore = dataStoreMgr.getDataStore(volumeForVm.getPoolId(), DataStoreRole.Primary); - - volService.disconnectVolumeFromHost(volumeInfo, host, dataStore); + // pool id can be null for the VM's volumes in Allocated state + if (volumeForVm.getPoolId() != null) { + DataStore dataStore = dataStoreMgr.getDataStore(volumeForVm.getPoolId(), DataStoreRole.Primary); + volService.disconnectVolumeFromHost(volumeInfo, host, dataStore); + } } } } @@ -1117,7 +1169,12 @@ private Pair recreateVolume(VolumeVO vol, VirtualMachinePro future = volService.createVolumeAsync(volume, destPool); } else { - TemplateInfo templ = tmplFactory.getTemplate(templateId, DataStoreRole.Image); + + TemplateInfo templ = tmplFactory.getReadyTemplateOnImageStore(templateId, dest.getDataCenter().getId()); + if (templ == null) { + s_logger.debug("can't find ready template: " + templateId + " for data center " + dest.getDataCenter().getId()); + throw new CloudRuntimeException("can't find ready template: " + templateId + " for data center " + dest.getDataCenter().getId()); + } PrimaryDataStore primaryDataStore = (PrimaryDataStore)destPool; @@ -1151,7 +1208,7 @@ private Pair recreateVolume(VolumeVO vol, VirtualMachinePro StoragePoolVO storagePool = _storagePoolDao.findById(destPool.getId()); - if (newVol.getVolumeType() == Type.DATADISK && storagePool.isManaged()) { + if (storagePool.isManaged()) { long hostId = vm.getVirtualMachine().getHostId(); Host host = _hostDao.findById(hostId); diff --git a/engine/orchestration/test/com/cloud/vm/VirtualMachineManagerImplTest.java b/engine/orchestration/test/com/cloud/vm/VirtualMachineManagerImplTest.java index 49b2fc5fb1..c39c6d1b41 100644 --- a/engine/orchestration/test/com/cloud/vm/VirtualMachineManagerImplTest.java +++ b/engine/orchestration/test/com/cloud/vm/VirtualMachineManagerImplTest.java @@ -84,10 +84,8 @@ import com.cloud.offering.ServiceOffering; import com.cloud.service.ServiceOfferingVO; import com.cloud.storage.DiskOfferingVO; -import com.cloud.storage.StoragePool; import com.cloud.storage.StoragePoolHostVO; import com.cloud.storage.VMTemplateVO; -import com.cloud.storage.Volume; import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.DiskOfferingDao; import com.cloud.storage.dao.StoragePoolHostDao; @@ -196,7 +194,7 @@ public class VirtualMachineManagerImplTest { @Mock HostVO _destHostMock; @Mock - Map _volumeToPoolMock; + Map _volumeToPoolMock; @Mock EntityManager _entityMgr; @Mock @@ -355,11 +353,13 @@ private void initializeMockConfigForMigratingVmWithVolumes() throws OperationTim // Mock the disk offering and pool objects for a volume. when(_volumeMock.getDiskOfferingId()).thenReturn(5L); when(_volumeMock.getPoolId()).thenReturn(200L); + when(_volumeMock.getId()).thenReturn(5L); when(_diskOfferingDao.findById(anyLong())).thenReturn(_diskOfferingMock); - when(_storagePoolDao.findById(anyLong())).thenReturn(_srcStoragePoolMock); + when(_storagePoolDao.findById(200L)).thenReturn(_srcStoragePoolMock); + when(_storagePoolDao.findById(201L)).thenReturn(_destStoragePoolMock); // Mock the volume to pool mapping. - when(_volumeToPoolMock.get(_volumeMock)).thenReturn(_destStoragePoolMock); + when(_volumeToPoolMock.get(5L)).thenReturn(201L); when(_destStoragePoolMock.getId()).thenReturn(201L); when(_srcStoragePoolMock.getId()).thenReturn(200L); when(_destStoragePoolMock.isLocal()).thenReturn(false); @@ -465,12 +465,12 @@ public void testSendStopWithOkAnswer() throws Exception { VirtualMachineGuru guru = mock(VirtualMachineGuru.class); VirtualMachine vm = mock(VirtualMachine.class); VirtualMachineProfile profile = mock(VirtualMachineProfile.class); - StopAnswer answer = new StopAnswer(new StopCommand(vm, false), "ok", true); + StopAnswer answer = new StopAnswer(new StopCommand(vm, false, false), "ok", true); when(profile.getVirtualMachine()).thenReturn(vm); when(vm.getHostId()).thenReturn(1L); when(_agentMgr.send(anyLong(), (Command)any())).thenReturn(answer); - boolean actual = _vmMgr.sendStop(guru, profile, false); + boolean actual = _vmMgr.sendStop(guru, profile, false, false); Assert.assertTrue(actual); } @@ -480,12 +480,12 @@ public void testSendStopWithFailAnswer() throws Exception { VirtualMachineGuru guru = mock(VirtualMachineGuru.class); VirtualMachine vm = mock(VirtualMachine.class); VirtualMachineProfile profile = mock(VirtualMachineProfile.class); - StopAnswer answer = new StopAnswer(new StopCommand(vm, false), "fail", false); + StopAnswer answer = new StopAnswer(new StopCommand(vm, false, false), "fail", false); when(profile.getVirtualMachine()).thenReturn(vm); when(vm.getHostId()).thenReturn(1L); when(_agentMgr.send(anyLong(), (Command)any())).thenReturn(answer); - boolean actual = _vmMgr.sendStop(guru, profile, false); + boolean actual = _vmMgr.sendStop(guru, profile, false, false); Assert.assertFalse(actual); } @@ -499,7 +499,7 @@ public void testSendStopWithNullAnswer() throws Exception { when(vm.getHostId()).thenReturn(1L); when(_agentMgr.send(anyLong(), (Command)any())).thenReturn(null); - boolean actual = _vmMgr.sendStop(guru, profile, false); + boolean actual = _vmMgr.sendStop(guru, profile, false, false); Assert.assertFalse(actual); } diff --git a/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml b/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml index 489b37d04b..c73d3d9952 100644 --- a/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml +++ b/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml @@ -195,6 +195,7 @@ + @@ -221,6 +222,7 @@ + @@ -252,13 +254,13 @@ + - @@ -337,5 +339,8 @@ + + + diff --git a/engine/schema/src/com/cloud/dc/VlanVO.java b/engine/schema/src/com/cloud/dc/VlanVO.java index ff103b9a07..50106e07fc 100644 --- a/engine/schema/src/com/cloud/dc/VlanVO.java +++ b/engine/schema/src/com/cloud/dc/VlanVO.java @@ -16,6 +16,9 @@ // under the License. package com.cloud.dc; +import com.cloud.utils.db.GenericDao; + +import java.util.Date; import java.util.UUID; import javax.persistence.Column; @@ -73,6 +76,13 @@ public class VlanVO implements Vlan { @Column(name = "uuid") String uuid; + @Column(name= GenericDao.REMOVED_COLUMN) + private Date removed; + + @Column(name = GenericDao.CREATED_COLUMN) + private Date created; + + public VlanVO(VlanType vlanType, String vlanTag, String vlanGateway, String vlanNetmask, long dataCenterId, String ipRange, Long networkId, Long physicalNetworkId, String ip6Gateway, String ip6Cidr, String ip6Range) { this.vlanType = vlanType; @@ -150,6 +160,16 @@ public void setUuid(String uuid) { this.uuid = uuid; } + @Override + public Date getRemoved() { + return removed; + } + + @Override + public Date getCreated() { + return created; + } + @Override public Long getPhysicalNetworkId() { return physicalNetworkId; diff --git a/engine/schema/src/com/cloud/event/EventVO.java b/engine/schema/src/com/cloud/event/EventVO.java index 3ae46d6244..9be37ddb96 100644 --- a/engine/schema/src/com/cloud/event/EventVO.java +++ b/engine/schema/src/com/cloud/event/EventVO.java @@ -29,8 +29,6 @@ import javax.persistence.Table; import javax.persistence.Transient; -import org.apache.cloudstack.acl.IAMEntityType; - import com.cloud.utils.db.GenericDao; @Entity @@ -223,7 +221,7 @@ public void setDisplay(boolean display) { } @Override - public IAMEntityType getEntityType() { - return IAMEntityType.Event; + public Class getEntityType() { + return Event.class; } } diff --git a/engine/schema/src/com/cloud/gpu/VGPUTypesVO.java b/engine/schema/src/com/cloud/gpu/VGPUTypesVO.java index 586a0c9279..fa6674c2c7 100644 --- a/engine/schema/src/com/cloud/gpu/VGPUTypesVO.java +++ b/engine/schema/src/com/cloud/gpu/VGPUTypesVO.java @@ -33,22 +33,55 @@ public class VGPUTypesVO implements InternalIdentity { @Column(name="id") private long id; + @Column(name="gpu_group_id") + private long gpuGroupId; + @Column(name="vgpu_type") private String vgpuType; - @Column(name="gpu_group_id") - private long gpuGroupId; + @Column(name="video_ram") + private long videoRam; + + @Column(name="max_heads") + private long maxHeads; - @Column(name="remaining_vm_capacity") + @Column(name="max_resolution_x") + private long maxResolutionX; + + @Column(name="max_resolution_y") + private long maxResolutionY; + + @Column(name="max_vgpu_per_pgpu") + private long maxVgpuPerPgpu; + + @Column(name="remaining_capacity") private long remainingCapacity; + @Column(name="max_capacity") + private long maxCapacity; + protected VGPUTypesVO() { } - public VGPUTypesVO(String vgpuType, long gpuGroupId, long remainingCapacity) { - this.vgpuType = vgpuType; + public VGPUTypesVO(long gpuGroupId, String vgpuType, long videoRam, long maxHeads, long maxResolutionX, long maxResolutionY, long maxVgpuPerPgpu, + long remainingCapacity, long maxCapacity) { this.gpuGroupId = gpuGroupId; + this.vgpuType = vgpuType; + this.videoRam = videoRam; + this.maxHeads = maxHeads; + this.maxResolutionX = maxResolutionX; + this.maxResolutionY = maxResolutionY; + this.maxVgpuPerPgpu = maxVgpuPerPgpu; this.remainingCapacity = remainingCapacity; + this.maxCapacity = maxCapacity; + } + + public long getGpuGroupId() { + return gpuGroupId; + } + + public void setGpuGroupId(long gpuGroupId) { + this.gpuGroupId = gpuGroupId; } public String getVgpuType() { @@ -59,12 +92,44 @@ public void setVgpuType(String vgpuType) { this.vgpuType = vgpuType; } - public long getGpuGroupId() { - return gpuGroupId; + public long getVideoRam() { + return videoRam; } - public void setGpuGroupId(long gpuGroupId) { - this.gpuGroupId = gpuGroupId; + public void setVideoRam(long videoRam) { + this.videoRam = videoRam; + } + + public long getMaxHeads() { + return maxHeads; + } + + public void setMaxHeads(long maxHeads) { + this.maxHeads = maxHeads; + } + + public long getMaxResolutionX() { + return maxResolutionX; + } + + public void setMaxResolutionX(long maxResolutionX) { + this.maxResolutionX = maxResolutionX; + } + + public long getMaxResolutionY() { + return maxResolutionY; + } + + public void setMaxResolutionY(long maxResolutionY) { + this.maxResolutionY = maxResolutionY; + } + + public long getMaxVgpuPerPgpu() { + return maxVgpuPerPgpu; + } + + public void setMaxVgpuPerPgpu(long maxVgpuPerPgpu) { + this.maxVgpuPerPgpu = maxVgpuPerPgpu; } public long getRemainingCapacity() { @@ -75,6 +140,14 @@ public void setRemainingCapacity(long remainingCapacity) { this.remainingCapacity = remainingCapacity; } + public long getMaxCapacity() { + return maxCapacity; + } + + public void setMaxCapacity(long maxCapacity) { + this.maxCapacity = maxCapacity; + } + @Override public long getId() { return id; diff --git a/engine/schema/src/com/cloud/gpu/dao/HostGpuGroupsDao.java b/engine/schema/src/com/cloud/gpu/dao/HostGpuGroupsDao.java index 5864144397..8e4f2f742a 100644 --- a/engine/schema/src/com/cloud/gpu/dao/HostGpuGroupsDao.java +++ b/engine/schema/src/com/cloud/gpu/dao/HostGpuGroupsDao.java @@ -24,7 +24,7 @@ public interface HostGpuGroupsDao extends GenericDao { /** - * Find host device by hostId and PCI ID + * Find host device by hostId and groupName * @param hostId the host * @param groupName GPU group * @return HostGpuGroupsVO diff --git a/engine/schema/src/com/cloud/gpu/dao/VGPUTypesDao.java b/engine/schema/src/com/cloud/gpu/dao/VGPUTypesDao.java index 2872cfda88..94d97c0073 100644 --- a/engine/schema/src/com/cloud/gpu/dao/VGPUTypesDao.java +++ b/engine/schema/src/com/cloud/gpu/dao/VGPUTypesDao.java @@ -19,30 +19,40 @@ import java.util.HashMap; import java.util.List; +import com.cloud.agent.api.VgpuTypesInfo; import com.cloud.gpu.VGPUTypesVO; import com.cloud.utils.db.GenericDao; public interface VGPUTypesDao extends GenericDao { - /** - * Find VGPU types by group Id - * @param groupId of the GPU group - * @return list of VGPUTypesVO - */ - List listByGroupId(long groupId); + /** + * List zonewide/podwide/clusterwide GPU card capacities. + * @param zoneId + * @param podId + * @param clusterId + * @return Custom Query result + */ + List listGPUCapacities(Long zoneId, Long podId, Long clusterId); - /** - * Find VGPU type by group Id and VGPU type - * @param groupId of the GPU group - * @param vgpuType name of VGPU type - * @return VGPUTypesVO - */ - VGPUTypesVO findByGroupIdVGPUType(long groupId, String vgpuType); + /** + * Find VGPU types by group Id + * @param groupId of the GPU group + * @return list of VGPUTypesVO + */ + List listByGroupId(long groupId); - /** - * Save the list of enabled VGPU types - * @param hostId the host - * @param groupDetails with enabled VGPU types - */ - void persist(long hostId, HashMap> groupDetails); + /** + * Find VGPU type by group Id and VGPU type + * @param groupId of the GPU group + * @param vgpuType name of VGPU type + * @return VGPUTypesVO + */ + VGPUTypesVO findByGroupIdVGPUType(long groupId, String vgpuType); + + /** + * Save the list of enabled VGPU types + * @param hostId the host + * @param groupDetails with enabled VGPU types + */ + void persist(long hostId, HashMap> groupDetails); } diff --git a/engine/schema/src/com/cloud/gpu/dao/VGPUTypesDaoImpl.java b/engine/schema/src/com/cloud/gpu/dao/VGPUTypesDaoImpl.java index 7cc83cc9eb..96e3a6277f 100644 --- a/engine/schema/src/com/cloud/gpu/dao/VGPUTypesDaoImpl.java +++ b/engine/schema/src/com/cloud/gpu/dao/VGPUTypesDaoImpl.java @@ -16,6 +16,10 @@ //under the License. package com.cloud.gpu.dao; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; @@ -27,11 +31,14 @@ import org.apache.log4j.Logger; import org.springframework.stereotype.Component; +import com.cloud.agent.api.VgpuTypesInfo; import com.cloud.gpu.HostGpuGroupsVO; import com.cloud.gpu.VGPUTypesVO; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.TransactionLegacy; +import com.cloud.utils.exception.CloudRuntimeException; @Component @Local(value = VGPUTypesDao.class) @@ -40,11 +47,14 @@ public class VGPUTypesDaoImpl extends GenericDaoBase implemen private final SearchBuilder _searchByGroupId; private final SearchBuilder _searchByGroupIdVGPUType; - // private final SearchBuilder _searchByHostId; - // private final SearchBuilder _searchForStaleEntries; @Inject protected HostGpuGroupsDao _hostGpuGroupsDao; + private static final String LIST_ZONE_POD_CLUSTER_WIDE_GPU_CAPACITIES = + "SELECT host_gpu_groups.group_name, vgpu_type, max_vgpu_per_pgpu, SUM(remaining_capacity) AS remaining_capacity, SUM(max_capacity) AS total_capacity FROM" + + " `cloud`.`vgpu_types` INNER JOIN `cloud`.`host_gpu_groups` ON vgpu_types.gpu_group_id = host_gpu_groups.id INNER JOIN `cloud`.`host`" + + " ON host_gpu_groups.host_id = host.id WHERE host.type = 'Routing' AND host.data_center_id = ?"; + public VGPUTypesDaoImpl() { _searchByGroupId = createSearchBuilder(); @@ -57,6 +67,47 @@ public VGPUTypesDaoImpl() { _searchByGroupIdVGPUType.done(); } + @Override + public List listGPUCapacities(Long dcId, Long podId, Long clusterId) { + StringBuilder finalQuery = new StringBuilder(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); + PreparedStatement pstmt = null; + List resourceIdList = new ArrayList(); + ArrayList result = new ArrayList(); + + resourceIdList.add(dcId); + finalQuery.append(LIST_ZONE_POD_CLUSTER_WIDE_GPU_CAPACITIES); + + if (podId != null) { + finalQuery.append(" AND host.pod_id = ?"); + resourceIdList.add(podId); + } + + if (clusterId != null) { + finalQuery.append(" AND host.cluster_id = ?"); + resourceIdList.add(clusterId); + } + finalQuery.append(" GROUP BY host_gpu_groups.group_name, vgpu_type"); + + try { + pstmt = txn.prepareAutoCloseStatement(finalQuery.toString()); + for (int i = 0; i < resourceIdList.size(); i++) { + pstmt.setLong(1 + i, resourceIdList.get(i)); + } + ResultSet rs = pstmt.executeQuery(); + while (rs.next()) { + + VgpuTypesInfo gpuCapacity = new VgpuTypesInfo(rs.getString(1), rs.getString(2), null, null, null, null, rs.getLong(3), rs.getLong(4), rs.getLong(5)); + result.add(gpuCapacity); + } + return result; + } catch (SQLException e) { + throw new CloudRuntimeException("DB Exception on: " + finalQuery, e); + } catch (Throwable e) { + throw new CloudRuntimeException("Caught: " + finalQuery, e); + } + } + @Override public List listByGroupId(long groupId) { SearchCriteria sc = _searchByGroupId.create(); @@ -73,20 +124,23 @@ public VGPUTypesVO findByGroupIdVGPUType(long groupId, String vgpuType) { } @Override - public void persist(long hostId, HashMap> groupDetails) { - Iterator>> it1 = groupDetails.entrySet().iterator(); + public void persist(long hostId, HashMap> groupDetails) { + Iterator>> it1 = groupDetails.entrySet().iterator(); while (it1.hasNext()) { - Entry> entry = it1.next(); + Entry> entry = it1.next(); HostGpuGroupsVO gpuGroup = _hostGpuGroupsDao.findByHostIdGroupName(hostId, entry.getKey()); - HashMap values = entry.getValue(); - Iterator> it2 = values.entrySet().iterator(); + HashMap values = entry.getValue(); + Iterator> it2 = values.entrySet().iterator(); while (it2.hasNext()) { - Entry record = it2.next(); + Entry record = it2.next(); + VgpuTypesInfo details = record.getValue(); VGPUTypesVO vgpuType = null; if ((vgpuType = findByGroupIdVGPUType(gpuGroup.getId(), record.getKey())) == null) { - persist(new VGPUTypesVO(record.getKey(), gpuGroup.getId(), record.getValue())); + persist(new VGPUTypesVO(gpuGroup.getId(), record.getKey(), details.getVideoRam(), details.getMaxHeads(), details.getMaxResolutionX(), + details.getMaxResolutionY(), details.getMaxVpuPerGpu(), details.getRemainingCapacity(), details.getMaxCapacity())); } else { - vgpuType.setRemainingCapacity(record.getValue()); + vgpuType.setRemainingCapacity(details.getRemainingCapacity()); + vgpuType.setMaxCapacity(details.getMaxCapacity()); update(vgpuType.getId(), vgpuType); } } diff --git a/engine/schema/src/com/cloud/host/HostVO.java b/engine/schema/src/com/cloud/host/HostVO.java index 25cc9544da..4af8fb73d8 100755 --- a/engine/schema/src/com/cloud/host/HostVO.java +++ b/engine/schema/src/com/cloud/host/HostVO.java @@ -38,6 +38,7 @@ import javax.persistence.TemporalType; import javax.persistence.Transient; +import com.cloud.agent.api.VgpuTypesInfo; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.resource.ResourceState; import com.cloud.storage.Storage.StoragePoolType; @@ -156,7 +157,7 @@ public class HostVO implements Host { // This value is only for saving and current cannot be loaded. @Transient - HashMap> groupDetails = new HashMap>(); + HashMap> groupDetails = new HashMap>(); @Override public String getStorageIpAddressDeux() { @@ -318,11 +319,11 @@ public void setHostTags(List hostTags) { this.hostTags = hostTags; } - public HashMap> getGpuGroupDetails() { + public HashMap> getGpuGroupDetails() { return groupDetails; } - public void setGpuGroups(HashMap> groupDetails) { + public void setGpuGroups(HashMap> groupDetails) { this.groupDetails = groupDetails; } diff --git a/engine/schema/src/com/cloud/host/dao/HostDaoImpl.java b/engine/schema/src/com/cloud/host/dao/HostDaoImpl.java index c2a9826405..4d7e83de59 100755 --- a/engine/schema/src/com/cloud/host/dao/HostDaoImpl.java +++ b/engine/schema/src/com/cloud/host/dao/HostDaoImpl.java @@ -34,6 +34,7 @@ import org.apache.log4j.Logger; import org.springframework.stereotype.Component; +import com.cloud.agent.api.VgpuTypesInfo; import com.cloud.cluster.agentlb.HostTransferMapVO; import com.cloud.cluster.agentlb.dao.HostTransferMapDao; import com.cloud.dc.ClusterVO; @@ -782,7 +783,7 @@ protected void saveHostTags(HostVO host) { } protected void saveGpuRecords(HostVO host) { - HashMap> groupDetails = host.getGpuGroupDetails(); + HashMap> groupDetails = host.getGpuGroupDetails(); if (groupDetails != null) { // Create/Update GPU group entries _hostGpuGroupsDao.persist(host.getId(), new ArrayList(groupDetails.keySet())); @@ -899,7 +900,8 @@ public long countRoutingHostsByDataCenter(long dcId) { @Override public boolean updateState(Status oldStatus, Event event, Status newStatus, Host vo, Object data) { - HostVO host = findById(vo.getId()); + // lock target row from beginning to avoid lock-promotion caused deadlock + HostVO host = lockRow(vo.getId(), true); if (host == null) { if (event == Event.Remove && newStatus == Status.Removed) { host = findByIdIncludingRemoved(vo.getId()); @@ -953,46 +955,49 @@ public boolean updateState(Status oldStatus, Event event, Status newStatus, Host int result = update(ub, sc, null); assert result <= 1 : "How can this update " + result + " rows? "; - if (status_logger.isDebugEnabled() && result == 0) { + if (result == 0) { HostVO ho = findById(host.getId()); assert ho != null : "How how how? : " + host.getId(); - StringBuilder str = new StringBuilder("Unable to update host for event:").append(event.toString()); - str.append(". Name=").append(host.getName()); - str.append("; New=[status=") - .append(newStatus.toString()) - .append(":msid=") - .append(newStatus.lostConnection() ? "null" : host.getManagementServerId()) - .append(":lastpinged=") - .append(host.getLastPinged()) - .append("]"); - str.append("; Old=[status=") - .append(oldStatus.toString()) - .append(":msid=") - .append(host.getManagementServerId()) - .append(":lastpinged=") - .append(oldPingTime) - .append("]"); - str.append("; DB=[status=") - .append(vo.getStatus().toString()) - .append(":msid=") - .append(vo.getManagementServerId()) - .append(":lastpinged=") - .append(vo.getLastPinged()) - .append(":old update count=") - .append(oldUpdateCount) - .append("]"); - status_logger.debug(str.toString()); - } else { - StringBuilder msg = new StringBuilder("Agent status update: ["); - msg.append("id = " + host.getId()); - msg.append("; name = " + host.getName()); - msg.append("; old status = " + oldStatus); - msg.append("; event = " + event); - msg.append("; new status = " + newStatus); - msg.append("; old update count = " + oldUpdateCount); - msg.append("; new update count = " + newUpdateCount + "]"); - status_logger.debug(msg.toString()); + if (status_logger.isDebugEnabled()) { + + StringBuilder str = new StringBuilder("Unable to update host for event:").append(event.toString()); + str.append(". Name=").append(host.getName()); + str.append("; New=[status=") + .append(newStatus.toString()) + .append(":msid=") + .append(newStatus.lostConnection() ? "null" : host.getManagementServerId()) + .append(":lastpinged=") + .append(host.getLastPinged()) + .append("]"); + str.append("; Old=[status=").append(oldStatus.toString()).append(":msid=").append(host.getManagementServerId()).append(":lastpinged=").append(oldPingTime) + .append("]"); + str.append("; DB=[status=") + .append(vo.getStatus().toString()) + .append(":msid=") + .append(vo.getManagementServerId()) + .append(":lastpinged=") + .append(vo.getLastPinged()) + .append(":old update count=") + .append(oldUpdateCount) + .append("]"); + status_logger.debug(str.toString()); + } else { + StringBuilder msg = new StringBuilder("Agent status update: ["); + msg.append("id = " + host.getId()); + msg.append("; name = " + host.getName()); + msg.append("; old status = " + oldStatus); + msg.append("; event = " + event); + msg.append("; new status = " + newStatus); + msg.append("; old update count = " + oldUpdateCount); + msg.append("; new update count = " + newUpdateCount + "]"); + status_logger.debug(msg.toString()); + } + + if (ho.getState() == newStatus) { + status_logger.debug("Host " + ho.getName() + " state has already been updated to " + newStatus); + return true; + } } return result > 0; diff --git a/engine/schema/src/com/cloud/hypervisor/dao/HypervisorCapabilitiesDaoImpl.java b/engine/schema/src/com/cloud/hypervisor/dao/HypervisorCapabilitiesDaoImpl.java index 2b94e69737..e83a4add7d 100644 --- a/engine/schema/src/com/cloud/hypervisor/dao/HypervisorCapabilitiesDaoImpl.java +++ b/engine/schema/src/com/cloud/hypervisor/dao/HypervisorCapabilitiesDaoImpl.java @@ -101,6 +101,12 @@ public Integer getMaxHostsPerCluster(HypervisorType hypervisorType, String hyper @Override public Boolean isVmSnapshotEnabled(HypervisorType hypervisorType, String hypervisorVersion) { HypervisorCapabilitiesVO result = getCapabilities(hypervisorType, hypervisorVersion); - return result.getVmSnapshotEnabled(); + // if default capability profile not present for any hypervisor type result will be null. + // So returning vm snapshot not supported if there is no default capability profile for hypervisor. + if (result != null) { + return result.getVmSnapshotEnabled(); + } else { + return false; + } } } diff --git a/engine/schema/src/com/cloud/network/LBHealthCheckPolicyVO.java b/engine/schema/src/com/cloud/network/LBHealthCheckPolicyVO.java index f1e8fe8f82..72dbf5cbdc 100644 --- a/engine/schema/src/com/cloud/network/LBHealthCheckPolicyVO.java +++ b/engine/schema/src/com/cloud/network/LBHealthCheckPolicyVO.java @@ -64,6 +64,9 @@ public class LBHealthCheckPolicyVO implements HealthCheckPolicy { @Column(name = "revoke") private boolean revoke = false; + @Column(name = "display", updatable = true, nullable = false) + protected boolean display = true; + protected LBHealthCheckPolicyVO() { this.uuid = UUID.randomUUID().toString(); } @@ -157,4 +160,13 @@ public String getUuid() { public void setUuid(String uuid) { this.uuid = uuid; } + + public void setDisplay(boolean display) { + this.display = display; + } + + @Override + public boolean isDisplay() { + return display; + } } diff --git a/engine/schema/src/com/cloud/network/UserIpv6AddressVO.java b/engine/schema/src/com/cloud/network/UserIpv6AddressVO.java index 9314993620..397c7b3b31 100644 --- a/engine/schema/src/com/cloud/network/UserIpv6AddressVO.java +++ b/engine/schema/src/com/cloud/network/UserIpv6AddressVO.java @@ -28,8 +28,6 @@ import javax.persistence.Id; import javax.persistence.Table; -import org.apache.cloudstack.acl.IAMEntityType; - import com.cloud.utils.db.GenericDao; @Entity @@ -188,7 +186,7 @@ public void setCreated(Date created) { } @Override - public IAMEntityType getEntityType() { - return IAMEntityType.UserIpv6Address; + public Class getEntityType() { + return UserIpv6Address.class; } } diff --git a/engine/schema/src/com/cloud/network/VpnUserVO.java b/engine/schema/src/com/cloud/network/VpnUserVO.java index 695aac0a9d..d6c4b60352 100644 --- a/engine/schema/src/com/cloud/network/VpnUserVO.java +++ b/engine/schema/src/com/cloud/network/VpnUserVO.java @@ -27,8 +27,6 @@ import javax.persistence.Id; import javax.persistence.Table; -import org.apache.cloudstack.acl.IAMEntityType; - import com.cloud.utils.db.Encrypt; @Entity @@ -129,7 +127,7 @@ public void setUuid(String uuid) { } @Override - public IAMEntityType getEntityType() { - return IAMEntityType.VpnUser; + public Class getEntityType() { + return VpnUser.class; } } diff --git a/engine/schema/src/com/cloud/network/as/AutoScalePolicyVO.java b/engine/schema/src/com/cloud/network/as/AutoScalePolicyVO.java index bde38f83d9..1842533000 100644 --- a/engine/schema/src/com/cloud/network/as/AutoScalePolicyVO.java +++ b/engine/schema/src/com/cloud/network/as/AutoScalePolicyVO.java @@ -30,7 +30,6 @@ import javax.persistence.Temporal; import javax.persistence.TemporalType; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.InternalIdentity; import com.cloud.utils.db.GenericDao; @@ -153,8 +152,8 @@ public void setLastQuiteTime(Date lastQuiteTime) { } @Override - public IAMEntityType getEntityType() { - return IAMEntityType.AutoScalePolicy; + public Class getEntityType() { + return AutoScalePolicy.class; } } diff --git a/engine/schema/src/com/cloud/network/as/AutoScaleVmGroupVO.java b/engine/schema/src/com/cloud/network/as/AutoScaleVmGroupVO.java index 3a05a7b909..d32e7f873a 100644 --- a/engine/schema/src/com/cloud/network/as/AutoScaleVmGroupVO.java +++ b/engine/schema/src/com/cloud/network/as/AutoScaleVmGroupVO.java @@ -30,7 +30,6 @@ import javax.persistence.Temporal; import javax.persistence.TemporalType; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.InternalIdentity; import com.cloud.utils.db.GenericDao; @@ -227,7 +226,7 @@ public boolean isDisplay() { } @Override - public IAMEntityType getEntityType() { - return IAMEntityType.AutoScaleVmGroup; + public Class getEntityType() { + return AutoScaleVmGroup.class; } } diff --git a/engine/schema/src/com/cloud/network/as/AutoScaleVmProfileVO.java b/engine/schema/src/com/cloud/network/as/AutoScaleVmProfileVO.java index 0b59394ddd..69e4c8190f 100644 --- a/engine/schema/src/com/cloud/network/as/AutoScaleVmProfileVO.java +++ b/engine/schema/src/com/cloud/network/as/AutoScaleVmProfileVO.java @@ -33,7 +33,6 @@ import javax.persistence.InheritanceType; import javax.persistence.Table; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.Identity; import org.apache.cloudstack.api.InternalIdentity; @@ -235,8 +234,8 @@ public boolean isDisplay() { } @Override - public IAMEntityType getEntityType() { - return IAMEntityType.AutoScaleVmProfile; + public Class getEntityType() { + return AutoScaleVmProfile.class; } } diff --git a/engine/schema/src/com/cloud/network/as/ConditionVO.java b/engine/schema/src/com/cloud/network/as/ConditionVO.java index e8c1d0bc59..5035f731b5 100644 --- a/engine/schema/src/com/cloud/network/as/ConditionVO.java +++ b/engine/schema/src/com/cloud/network/as/ConditionVO.java @@ -29,7 +29,6 @@ import javax.persistence.Id; import javax.persistence.Table; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.Identity; import org.apache.cloudstack.api.InternalIdentity; @@ -130,8 +129,8 @@ public Date getRemoved() { } @Override - public IAMEntityType getEntityType() { - return IAMEntityType.Condition; + public Class getEntityType() { + return Condition.class; } } diff --git a/engine/schema/src/com/cloud/network/dao/IPAddressDaoImpl.java b/engine/schema/src/com/cloud/network/dao/IPAddressDaoImpl.java index b569718965..e1530cacbb 100755 --- a/engine/schema/src/com/cloud/network/dao/IPAddressDaoImpl.java +++ b/engine/schema/src/com/cloud/network/dao/IPAddressDaoImpl.java @@ -25,6 +25,7 @@ import javax.ejb.Local; import javax.inject.Inject; +import org.apache.cloudstack.resourcedetail.dao.UserIpAddressDetailsDao; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -63,6 +64,8 @@ public class IPAddressDaoImpl extends GenericDaoBase implemen protected GenericSearchBuilder CountFreePublicIps; @Inject ResourceTagDao _tagsDao; + @Inject + UserIpAddressDetailsDao _detailsDao; // make it public for JUnit test public IPAddressDaoImpl() { @@ -166,6 +169,8 @@ public void unassignIpAddress(long ipAddressId) { address.setSystem(false); address.setVmIp(null); address.setDisplay(true); + //remove resource details for the ip + _detailsDao.removeDetails(ipAddressId); update(ipAddressId, address); } diff --git a/engine/schema/src/com/cloud/network/dao/IPAddressVO.java b/engine/schema/src/com/cloud/network/dao/IPAddressVO.java index d06b8c51d7..0be781b500 100644 --- a/engine/schema/src/com/cloud/network/dao/IPAddressVO.java +++ b/engine/schema/src/com/cloud/network/dao/IPAddressVO.java @@ -31,9 +31,8 @@ import javax.persistence.TemporalType; import javax.persistence.Transient; -import org.apache.cloudstack.acl.IAMEntityType; - import com.cloud.network.IpAddress; +import com.cloud.utils.db.GenericDao; import com.cloud.utils.net.Ip; /** @@ -54,7 +53,6 @@ public class IPAddressVO implements IpAddress { @Column(name = "domain_id") private Long allocatedInDomainId = null; - @Id @Column(name = "public_ip_address") @Enumerated(value = EnumType.STRING) private Ip address = null; @@ -119,6 +117,12 @@ public class IPAddressVO implements IpAddress { @Column(name = "display", updatable = true, nullable = false) protected boolean display = true; + @Column(name= GenericDao.REMOVED_COLUMN) + private Date removed; + + @Column(name = GenericDao.CREATED_COLUMN) + private Date created; + protected IPAddressVO() { uuid = UUID.randomUUID().toString(); } @@ -350,7 +354,17 @@ public void setDisplay(boolean display) { } @Override - public IAMEntityType getEntityType() { - return IAMEntityType.IpAddress; + public Class getEntityType() { + return IpAddress.class; + } + + @Override + public Date getRemoved() { + return removed; + } + + @Override + public Date getCreated() { + return created; } } diff --git a/engine/schema/src/com/cloud/network/dao/LBHealthCheckPolicyDao.java b/engine/schema/src/com/cloud/network/dao/LBHealthCheckPolicyDao.java index 67a347d370..eed97d650c 100644 --- a/engine/schema/src/com/cloud/network/dao/LBHealthCheckPolicyDao.java +++ b/engine/schema/src/com/cloud/network/dao/LBHealthCheckPolicyDao.java @@ -26,7 +26,7 @@ public interface LBHealthCheckPolicyDao extends GenericDao listByLoadBalancerId(long loadBalancerId); + List listByLoadBalancerIdAndDisplayFlag(long loadBalancerId, Boolean forDisplay); List listByLoadBalancerId(long loadBalancerId, boolean revoke); } diff --git a/engine/schema/src/com/cloud/network/dao/LBHealthCheckPolicyDaoImpl.java b/engine/schema/src/com/cloud/network/dao/LBHealthCheckPolicyDaoImpl.java index ddebd3622d..52c1d0e1ea 100644 --- a/engine/schema/src/com/cloud/network/dao/LBHealthCheckPolicyDaoImpl.java +++ b/engine/schema/src/com/cloud/network/dao/LBHealthCheckPolicyDaoImpl.java @@ -48,9 +48,12 @@ public void remove(long loadBalancerId, Boolean revoke) { } @Override - public List listByLoadBalancerId(long loadBalancerId) { + public List listByLoadBalancerIdAndDisplayFlag(long loadBalancerId, Boolean forDisplay) { SearchCriteria sc = createSearchCriteria(); sc.addAnd("loadBalancerId", SearchCriteria.Op.EQ, loadBalancerId); + if (forDisplay != null) { + sc.addAnd("display", SearchCriteria.Op.EQ, forDisplay); + } return listBy(sc); } diff --git a/engine/schema/src/com/cloud/network/dao/LBStickinessPolicyDao.java b/engine/schema/src/com/cloud/network/dao/LBStickinessPolicyDao.java index 82e68d61e8..6669d70824 100644 --- a/engine/schema/src/com/cloud/network/dao/LBStickinessPolicyDao.java +++ b/engine/schema/src/com/cloud/network/dao/LBStickinessPolicyDao.java @@ -25,7 +25,7 @@ public interface LBStickinessPolicyDao extends GenericDao listByLoadBalancerId(long loadBalancerId); + List listByLoadBalancerIdAndDisplayFlag(long loadBalancerId, boolean forDisplay); List listByLoadBalancerId(long loadBalancerId, boolean revoke); } diff --git a/engine/schema/src/com/cloud/network/dao/LBStickinessPolicyDaoImpl.java b/engine/schema/src/com/cloud/network/dao/LBStickinessPolicyDaoImpl.java index fdce8c7596..e8295c592d 100644 --- a/engine/schema/src/com/cloud/network/dao/LBStickinessPolicyDaoImpl.java +++ b/engine/schema/src/com/cloud/network/dao/LBStickinessPolicyDaoImpl.java @@ -47,9 +47,10 @@ public void remove(long loadBalancerId, Boolean revoke) { } @Override - public List listByLoadBalancerId(long loadBalancerId) { + public List listByLoadBalancerIdAndDisplayFlag(long loadBalancerId, boolean forDisplay) { SearchCriteria sc = createSearchCriteria(); sc.addAnd("loadBalancerId", SearchCriteria.Op.EQ, loadBalancerId); + sc.addAnd("display", SearchCriteria.Op.EQ, forDisplay); return listBy(sc); } diff --git a/engine/schema/src/com/cloud/network/dao/LBStickinessPolicyVO.java b/engine/schema/src/com/cloud/network/dao/LBStickinessPolicyVO.java index 6e8dfbb032..9628a32ae4 100644 --- a/engine/schema/src/com/cloud/network/dao/LBStickinessPolicyVO.java +++ b/engine/schema/src/com/cloud/network/dao/LBStickinessPolicyVO.java @@ -64,6 +64,9 @@ public class LBStickinessPolicyVO implements StickinessPolicy { @Column(name = "revoke") private boolean revoke = false; + @Column(name = "display", updatable = true, nullable = false) + protected boolean display = true; + protected LBStickinessPolicyVO() { this.uuid = UUID.randomUUID().toString(); } @@ -150,4 +153,13 @@ public String getUuid() { public void setUuid(String uuid) { this.uuid = uuid; } + + public void setDisplay(boolean display) { + this.display = display; + } + + @Override + public boolean isDisplay() { + return display; + } } diff --git a/engine/schema/src/com/cloud/network/dao/LoadBalancerVMMapDao.java b/engine/schema/src/com/cloud/network/dao/LoadBalancerVMMapDao.java index 79eaf8e16b..a25534b701 100644 --- a/engine/schema/src/com/cloud/network/dao/LoadBalancerVMMapDao.java +++ b/engine/schema/src/com/cloud/network/dao/LoadBalancerVMMapDao.java @@ -34,4 +34,12 @@ public interface LoadBalancerVMMapDao extends GenericDao listByInstanceIp(String instanceIp); + + List listByLoadBalancerIdAndVmId(long loadBalancerId, long instanceId); + + LoadBalancerVMMapVO findByLoadBalancerIdAndVmIdVmIp(long loadBalancerId, long instanceId, String instanceIp); + + void remove(long id, long instanceId, String instanceIp, Boolean revoke); } diff --git a/engine/schema/src/com/cloud/network/dao/LoadBalancerVMMapDaoImpl.java b/engine/schema/src/com/cloud/network/dao/LoadBalancerVMMapDaoImpl.java index b0b14fc23c..cbfda8fadb 100644 --- a/engine/schema/src/com/cloud/network/dao/LoadBalancerVMMapDaoImpl.java +++ b/engine/schema/src/com/cloud/network/dao/LoadBalancerVMMapDaoImpl.java @@ -51,6 +51,21 @@ public void remove(long loadBalancerId, List instanceIds, Boolean revoke) expunge(sc); } + @Override + public void remove(long loadBalancerId, long instanceId, String instanceIp, Boolean revoke) { + SearchCriteria sc = createSearchCriteria(); + sc.addAnd("loadBalancerId", SearchCriteria.Op.EQ, loadBalancerId); + sc.addAnd("instanceId", SearchCriteria.Op.IN, instanceId); + sc.addAnd("instanceIp", SearchCriteria.Op.EQ, instanceIp); + + if (revoke != null) { + sc.addAnd("revoke", SearchCriteria.Op.EQ, revoke); + } + + expunge(sc); + } + + @Override public List listByInstanceId(long instanceId) { SearchCriteria sc = createSearchCriteria(); @@ -59,6 +74,14 @@ public List listByInstanceId(long instanceId) { return listBy(sc); } + @Override + public List listByInstanceIp(String instanceIp) { + SearchCriteria sc = createSearchCriteria(); + sc.addAnd("instanceIp", SearchCriteria.Op.EQ, instanceIp); + + return listBy(sc); + } + @Override public List listByLoadBalancerId(long loadBalancerId) { SearchCriteria sc = createSearchCriteria(); @@ -84,6 +107,18 @@ public LoadBalancerVMMapVO findByLoadBalancerIdAndVmId(long loadBalancerId, long return findOneBy(sc); } + + @Override + public LoadBalancerVMMapVO findByLoadBalancerIdAndVmIdVmIp(long loadBalancerId, long instanceId, String instanceIp) { + SearchCriteria sc = createSearchCriteria(); + sc.addAnd("loadBalancerId", SearchCriteria.Op.EQ, loadBalancerId); + sc.addAnd("instanceId", SearchCriteria.Op.EQ, instanceId); + sc.addAnd("instanceIp", SearchCriteria.Op.EQ, instanceIp); + + return findOneBy(sc); + } + + @Override public boolean isVmAttachedToLoadBalancer(long loadBalancerId) { GenericSearchBuilder CountByAccount = createSearchBuilder(Long.class); @@ -94,4 +129,12 @@ public boolean isVmAttachedToLoadBalancer(long loadBalancerId) { sc.setParameters("loadBalancerId", loadBalancerId); return customSearch(sc, null).get(0) > 0; } + + @Override + public List listByLoadBalancerIdAndVmId(long loadBalancerId, long instanceId) { + SearchCriteria sc = createSearchCriteria(); + sc.addAnd("loadBalancerId", SearchCriteria.Op.EQ, loadBalancerId); + sc.addAnd("instanceId", SearchCriteria.Op.EQ, instanceId); + return listBy(sc); + } } diff --git a/engine/schema/src/com/cloud/network/dao/LoadBalancerVMMapVO.java b/engine/schema/src/com/cloud/network/dao/LoadBalancerVMMapVO.java index 0a67106dc9..08b918475c 100644 --- a/engine/schema/src/com/cloud/network/dao/LoadBalancerVMMapVO.java +++ b/engine/schema/src/com/cloud/network/dao/LoadBalancerVMMapVO.java @@ -39,6 +39,9 @@ public class LoadBalancerVMMapVO implements InternalIdentity { @Column(name = "instance_id") private long instanceId; + @Column(name = "instance_ip") + private String instanceIp; + @Column(name = "revoke") private boolean revoke = false; @@ -59,6 +62,13 @@ public LoadBalancerVMMapVO(long loadBalancerId, long instanceId, boolean revoke) this.revoke = revoke; } + public LoadBalancerVMMapVO(long loadBalancerId, long instanceId, String vmIp, boolean revoke) { + this.loadBalancerId = loadBalancerId; + this.instanceId = instanceId; + this.instanceIp = vmIp; + this.revoke = revoke; + } + @Override public long getId() { return id; @@ -87,4 +97,13 @@ public String getState() { public void setState(String state) { this.state = state; } + + public String getInstanceIp() { + return instanceIp; + } + + public void setInstanceIp(String instanceIp) { + this.instanceIp = instanceIp; + } + } diff --git a/engine/schema/src/com/cloud/network/dao/MonitoringServiceVO.java b/engine/schema/src/com/cloud/network/dao/MonitoringServiceVO.java index 999fdfc649..01fba00d0b 100644 --- a/engine/schema/src/com/cloud/network/dao/MonitoringServiceVO.java +++ b/engine/schema/src/com/cloud/network/dao/MonitoringServiceVO.java @@ -25,8 +25,6 @@ import javax.persistence.Id; import javax.persistence.Table; -import org.apache.cloudstack.acl.IAMEntityType; - import com.cloud.network.MonitoringService; @Entity @@ -120,7 +118,7 @@ public String getProcessName() { } @Override - public IAMEntityType getEntityType() { - return IAMEntityType.MonitorService; + public Class getEntityType() { + return MonitoringService.class; } } diff --git a/engine/schema/src/com/cloud/network/dao/NetworkVO.java b/engine/schema/src/com/cloud/network/dao/NetworkVO.java index 13e8dbff09..8c0466fbfa 100644 --- a/engine/schema/src/com/cloud/network/dao/NetworkVO.java +++ b/engine/schema/src/com/cloud/network/dao/NetworkVO.java @@ -30,7 +30,6 @@ import javax.persistence.Transient; import org.apache.cloudstack.acl.ControlledEntity; -import org.apache.cloudstack.acl.IAMEntityType; import com.cloud.network.Network; import com.cloud.network.Networks.BroadcastDomainType; @@ -167,6 +166,9 @@ public class NetworkVO implements Network { @Column(name = "network_acl_id") Long networkACLId; + @Column(name = "streched_l2") + boolean strechedL2Network = false; + public NetworkVO() { uuid = UUID.randomUUID().toString(); } @@ -511,7 +513,7 @@ public boolean equals(Object obj) { @Override public String toString() { StringBuilder buf = new StringBuilder("Ntwk["); - buf.append(id).append("|").append(trafficType).append("|").append(networkOfferingId).append("]"); + buf.append(uuid).append("|").append(trafficType).append("|").append(networkOfferingId).append("]"); return buf.toString(); } @@ -575,6 +577,11 @@ public void setDisplayNetwork(boolean displayNetwork) { this.displayNetwork = displayNetwork; } + @Override + public boolean isDisplay(){ + return displayNetwork; + } + @Override public void setNetworkACLId(Long networkACLId) { this.networkACLId = networkACLId; @@ -586,7 +593,20 @@ public Long getNetworkACLId() { } @Override - public IAMEntityType getEntityType() { - return IAMEntityType.Network; + public Class getEntityType() { + return Network.class; + } + + @Override + public boolean isStrechedL2Network() { + return strechedL2Network; + } + + public void setStrechedL2Network(boolean strechedL2Network) { + this.strechedL2Network = strechedL2Network; + } + + public void setVpcId(long vpcId) { + this.vpcId = vpcId; } } diff --git a/engine/schema/src/com/cloud/network/dao/RemoteAccessVpnVO.java b/engine/schema/src/com/cloud/network/dao/RemoteAccessVpnVO.java index 8f95f184c4..0616939fc2 100644 --- a/engine/schema/src/com/cloud/network/dao/RemoteAccessVpnVO.java +++ b/engine/schema/src/com/cloud/network/dao/RemoteAccessVpnVO.java @@ -25,8 +25,6 @@ import javax.persistence.Id; import javax.persistence.Table; -import org.apache.cloudstack.acl.IAMEntityType; - import com.cloud.network.RemoteAccessVpn; @Entity @@ -168,7 +166,7 @@ public boolean isDisplay() { } @Override - public IAMEntityType getEntityType() { - return IAMEntityType.RemoteAccessVpn; + public Class getEntityType() { + return RemoteAccessVpn.class; } } diff --git a/engine/schema/src/com/cloud/network/dao/Site2SiteCustomerGatewayVO.java b/engine/schema/src/com/cloud/network/dao/Site2SiteCustomerGatewayVO.java index 6de4d429ce..5bcf361836 100644 --- a/engine/schema/src/com/cloud/network/dao/Site2SiteCustomerGatewayVO.java +++ b/engine/schema/src/com/cloud/network/dao/Site2SiteCustomerGatewayVO.java @@ -26,8 +26,6 @@ import javax.persistence.Id; import javax.persistence.Table; -import org.apache.cloudstack.acl.IAMEntityType; - import com.cloud.network.Site2SiteCustomerGateway; import com.cloud.utils.db.Encrypt; import com.cloud.utils.db.GenericDao; @@ -211,7 +209,7 @@ public long getAccountId() { } @Override - public IAMEntityType getEntityType() { - return IAMEntityType.Site2SiteCustomerGateway; + public Class getEntityType() { + return Site2SiteCustomerGateway.class; } } diff --git a/engine/schema/src/com/cloud/network/dao/Site2SiteVpnConnectionVO.java b/engine/schema/src/com/cloud/network/dao/Site2SiteVpnConnectionVO.java index f0074c04dc..85643fc043 100644 --- a/engine/schema/src/com/cloud/network/dao/Site2SiteVpnConnectionVO.java +++ b/engine/schema/src/com/cloud/network/dao/Site2SiteVpnConnectionVO.java @@ -28,7 +28,6 @@ import javax.persistence.Id; import javax.persistence.Table; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.InternalIdentity; import com.cloud.network.Site2SiteVpnConnection; @@ -175,7 +174,7 @@ public boolean isDisplay() { } @Override - public IAMEntityType getEntityType() { - return IAMEntityType.Site2SiteVpnConnection; + public Class getEntityType() { + return Site2SiteVpnConnection.class; } } diff --git a/engine/schema/src/com/cloud/network/dao/Site2SiteVpnGatewayVO.java b/engine/schema/src/com/cloud/network/dao/Site2SiteVpnGatewayVO.java index 33236b9d68..260e5fc4c0 100644 --- a/engine/schema/src/com/cloud/network/dao/Site2SiteVpnGatewayVO.java +++ b/engine/schema/src/com/cloud/network/dao/Site2SiteVpnGatewayVO.java @@ -26,8 +26,6 @@ import javax.persistence.Id; import javax.persistence.Table; -import org.apache.cloudstack.acl.IAMEntityType; - import com.cloud.network.Site2SiteVpnGateway; import com.cloud.utils.db.GenericDao; @@ -133,7 +131,7 @@ public boolean isDisplay() { } @Override - public IAMEntityType getEntityType() { - return IAMEntityType.Site2SiteVpnGateway; + public Class getEntityType() { + return Site2SiteVpnGateway.class; } } diff --git a/engine/schema/src/com/cloud/network/dao/SslCertVO.java b/engine/schema/src/com/cloud/network/dao/SslCertVO.java index 6ef7afd1c7..2676d611bd 100644 --- a/engine/schema/src/com/cloud/network/dao/SslCertVO.java +++ b/engine/schema/src/com/cloud/network/dao/SslCertVO.java @@ -23,8 +23,6 @@ import javax.persistence.Id; import javax.persistence.Table; -import org.apache.cloudstack.acl.IAMEntityType; - import com.cloud.network.lb.SslCert; import com.cloud.utils.db.Encrypt; @@ -124,8 +122,8 @@ public String getFingerPrint() { } @Override - public IAMEntityType getEntityType() { - return IAMEntityType.SSLCert; + public Class getEntityType() { + return SslCert.class; } } \ No newline at end of file diff --git a/engine/schema/src/com/cloud/network/rules/FirewallRuleVO.java b/engine/schema/src/com/cloud/network/rules/FirewallRuleVO.java index 5e22dd4f4e..169102af8c 100644 --- a/engine/schema/src/com/cloud/network/rules/FirewallRuleVO.java +++ b/engine/schema/src/com/cloud/network/rules/FirewallRuleVO.java @@ -34,8 +34,6 @@ import javax.persistence.Table; import javax.persistence.Transient; -import org.apache.cloudstack.acl.IAMEntityType; - import com.cloud.utils.db.GenericDao; import com.cloud.utils.net.NetUtils; @@ -285,7 +283,7 @@ public boolean isDisplay() { } @Override - public IAMEntityType getEntityType() { - return IAMEntityType.FirewallRule; + public Class getEntityType() { + return FirewallRule.class; } } diff --git a/engine/schema/src/com/cloud/network/security/SecurityGroupVO.java b/engine/schema/src/com/cloud/network/security/SecurityGroupVO.java index 26859f704e..4a4c83ae74 100644 --- a/engine/schema/src/com/cloud/network/security/SecurityGroupVO.java +++ b/engine/schema/src/com/cloud/network/security/SecurityGroupVO.java @@ -25,8 +25,6 @@ import javax.persistence.Id; import javax.persistence.Table; -import org.apache.cloudstack.acl.IAMEntityType; - @Entity @Table(name = ("security_group")) public class SecurityGroupVO implements SecurityGroup { @@ -97,7 +95,7 @@ public void setUuid(String uuid) { } @Override - public IAMEntityType getEntityType() { - return IAMEntityType.SecurityGroup; + public Class getEntityType() { + return SecurityGroup.class; } } diff --git a/engine/schema/src/com/cloud/network/vpc/NetworkACLItemCidrsDao.java b/engine/schema/src/com/cloud/network/vpc/NetworkACLItemCidrsDao.java new file mode 100644 index 0000000000..5e49368de7 --- /dev/null +++ b/engine/schema/src/com/cloud/network/vpc/NetworkACLItemCidrsDao.java @@ -0,0 +1,39 @@ +/** + * 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.vpc; + +import java.util.List; + +import com.cloud.utils.db.DB; +import com.cloud.utils.db.GenericDao; + +/** + * @author daan + * + */ +public interface NetworkACLItemCidrsDao extends GenericDao { + + void persist(long networkACLItemId, List cidrs); + + List getCidrs(long networkACLItemId); + + @DB + List listByNetworkACLItemId(long networkACLItemId); + +} diff --git a/engine/schema/src/com/cloud/network/vpc/NetworkACLItemCidrsVO.java b/engine/schema/src/com/cloud/network/vpc/NetworkACLItemCidrsVO.java new file mode 100644 index 0000000000..c366f94796 --- /dev/null +++ b/engine/schema/src/com/cloud/network/vpc/NetworkACLItemCidrsVO.java @@ -0,0 +1,78 @@ +/** + * 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.vpc; + +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; + +@Entity +@Table(name = "network_acl_item_cidrs") +public class NetworkACLItemCidrsVO implements InternalIdentity { + private static final long serialVersionUID = 7805284475485494754L; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private Long id; + + @Column(name = "network_acl_item_id") + private long networkACLItemId; + + @Column(name = "cidr") + private String cidrList; + + public NetworkACLItemCidrsVO() { + } + + public NetworkACLItemCidrsVO(long networkAclItemId, String cidrList) { + this.networkACLItemId = networkAclItemId; + this.cidrList = cidrList; + } + + /* (non-Javadoc) + * @see org.apache.cloudstack.api.InternalIdentity#getId() + */ + @Override + public long getId() { + return id; + } + + public long getNetworkACLItemId() { + return networkACLItemId; + } + + public String getCidr() { + return cidrList; + } + + public String getCidrList() { + return cidrList; + } + + public void setCidrList(String cidrList) { + this.cidrList = cidrList; + } + +} diff --git a/engine/schema/src/com/cloud/network/vpc/NetworkACLItemDao.java b/engine/schema/src/com/cloud/network/vpc/NetworkACLItemDao.java index e27848522f..9ab6365df1 100644 --- a/engine/schema/src/com/cloud/network/vpc/NetworkACLItemDao.java +++ b/engine/schema/src/com/cloud/network/vpc/NetworkACLItemDao.java @@ -34,4 +34,6 @@ public interface NetworkACLItemDao extends GenericDao { int getMaxNumberByACL(long aclId); NetworkACLItemVO findByAclAndNumber(long aclId, int number); + + void loadCidrs(NetworkACLItemVO item); } diff --git a/engine/schema/src/com/cloud/network/vpc/NetworkACLItemVO.java b/engine/schema/src/com/cloud/network/vpc/NetworkACLItemVO.java index 8031b001b8..6eb9cb0e99 100644 --- a/engine/schema/src/com/cloud/network/vpc/NetworkACLItemVO.java +++ b/engine/schema/src/com/cloud/network/vpc/NetworkACLItemVO.java @@ -16,9 +16,10 @@ // under the License. package com.cloud.network.vpc; -import java.util.ArrayList; import java.util.Date; +import java.util.LinkedList; import java.util.List; +import java.util.StringTokenizer; import java.util.UUID; import javax.persistence.Column; @@ -29,6 +30,7 @@ import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; +import javax.persistence.Transient; import com.cloud.utils.db.GenericDao; import com.cloud.utils.net.NetUtils; @@ -37,6 +39,11 @@ @Table(name = "network_acl_item") public class NetworkACLItemVO implements NetworkACLItem { + /** + * + */ + private static final long serialVersionUID = 2790623532888742060L; + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id") @@ -71,8 +78,11 @@ public class NetworkACLItemVO implements NetworkACLItem { @Enumerated(value = EnumType.STRING) TrafficType trafficType; - @Column(name = "cidr", length = 2048) - String sourceCidrs; + // This is a delayed load value. If the value is null, + // then this field has not been loaded yet. + // Call the NetworkACLItem dao to load it. + @Transient + List sourceCidrs; @Column(name = "uuid") String uuid; @@ -108,32 +118,12 @@ public NetworkACLItemVO(Integer portStart, Integer portEnd, String protocol, lon } public void setSourceCidrList(List sourceCidrs) { - if (sourceCidrs == null) { - this.sourceCidrs = null; - } else { - StringBuilder sb = new StringBuilder(); - for (String cidr : sourceCidrs) { - if (sb.length() != 0) { - sb.append(","); - } - sb.append(cidr); - } - this.sourceCidrs = sb.toString(); - } + this.sourceCidrs = sourceCidrs; } @Override public List getSourceCidrList() { - if (sourceCidrs == null || sourceCidrs.isEmpty()) { - return null; - } else { - List cidrList = new ArrayList(); - String[] cidrs = sourceCidrs.split(","); - for (String cidr : cidrs) { - cidrList.add(cidr); - } - return cidrList; - } + return sourceCidrs; } @Override @@ -234,7 +224,12 @@ public void setTrafficType(TrafficType trafficType) { } public void setSourceCidrs(String sourceCidrs) { - this.sourceCidrs = sourceCidrs; + List srcCidrs = new LinkedList(); + StringTokenizer st = new StringTokenizer(sourceCidrs,",;"); + while(st.hasMoreTokens()) { + srcCidrs.add(st.nextToken()); + } + this.sourceCidrs = srcCidrs; } public void setNumber(int number) { diff --git a/engine/schema/src/com/cloud/network/vpc/StaticRouteVO.java b/engine/schema/src/com/cloud/network/vpc/StaticRouteVO.java index a9ba05154b..2c2d53edb2 100644 --- a/engine/schema/src/com/cloud/network/vpc/StaticRouteVO.java +++ b/engine/schema/src/com/cloud/network/vpc/StaticRouteVO.java @@ -28,8 +28,6 @@ import javax.persistence.Id; import javax.persistence.Table; -import org.apache.cloudstack.acl.IAMEntityType; - import com.cloud.utils.db.GenericDao; @Entity @@ -139,7 +137,7 @@ public String toString() { } @Override - public IAMEntityType getEntityType() { - return IAMEntityType.StaticRoute; + public Class getEntityType() { + return StaticRoute.class; } } \ No newline at end of file diff --git a/engine/schema/src/com/cloud/network/vpc/VpcGatewayVO.java b/engine/schema/src/com/cloud/network/vpc/VpcGatewayVO.java index 48238b1971..23568b4923 100644 --- a/engine/schema/src/com/cloud/network/vpc/VpcGatewayVO.java +++ b/engine/schema/src/com/cloud/network/vpc/VpcGatewayVO.java @@ -28,8 +28,6 @@ import javax.persistence.Id; import javax.persistence.Table; -import org.apache.cloudstack.acl.IAMEntityType; - import com.cloud.utils.db.GenericDao; @Entity @@ -219,7 +217,7 @@ public long getNetworkACLId() { } @Override - public IAMEntityType getEntityType() { - return IAMEntityType.VpcGateway; + public Class getEntityType() { + return VpcGateway.class; } } diff --git a/engine/schema/src/com/cloud/network/vpc/VpcOfferingVO.java b/engine/schema/src/com/cloud/network/vpc/VpcOfferingVO.java index 53f6f6055e..a7d61b3692 100644 --- a/engine/schema/src/com/cloud/network/vpc/VpcOfferingVO.java +++ b/engine/schema/src/com/cloud/network/vpc/VpcOfferingVO.java @@ -70,6 +70,9 @@ public class VpcOfferingVO implements VpcOffering { @Column(name = "supports_distributed_router") boolean supportsDistributedRouter=false; + @Column(name = "supports_region_level_vpc") + boolean offersRegionLevelVPC = false; + public VpcOfferingVO() { this.uuid = UUID.randomUUID().toString(); } @@ -84,10 +87,11 @@ public VpcOfferingVO(String name, String displayText, Long serviceOfferingId) { } public VpcOfferingVO(String name, String displayText, boolean isDefault, Long serviceOfferingId, - boolean supportsDistributedRouter) { + boolean supportsDistributedRouter, boolean offersRegionLevelVPC) { this(name, displayText, serviceOfferingId); this.isDefault = isDefault; this.supportsDistributedRouter = supportsDistributedRouter; + this.offersRegionLevelVPC = offersRegionLevelVPC; } @Override @@ -155,4 +159,9 @@ public Long getServiceOfferingId() { public boolean supportsDistributedRouter() { return supportsDistributedRouter; } + + @Override + public boolean offersRegionLevelVPC() { + return offersRegionLevelVPC; + } } diff --git a/engine/schema/src/com/cloud/network/vpc/VpcVO.java b/engine/schema/src/com/cloud/network/vpc/VpcVO.java index dea8c314bc..22d51dd542 100644 --- a/engine/schema/src/com/cloud/network/vpc/VpcVO.java +++ b/engine/schema/src/com/cloud/network/vpc/VpcVO.java @@ -26,8 +26,6 @@ import javax.persistence.Id; import javax.persistence.Table; -import org.apache.cloudstack.acl.IAMEntityType; - import com.cloud.utils.db.GenericDao; @Entity @@ -84,12 +82,15 @@ public class VpcVO implements Vpc { @Column(name="uses_distributed_router") boolean usesDistributedRouter = false; + @Column(name = "region_level_vpc") + boolean regionLevelVpc = false; + public VpcVO() { uuid = UUID.randomUUID().toString(); } public VpcVO(long zoneId, String name, String displayText, long accountId, long domainId, long vpcOffId, String cidr, - String networkDomain, boolean useDistributedRouter) { + String networkDomain, boolean useDistributedRouter, boolean regionLevelVpc) { this.zoneId = zoneId; this.name = name; this.displayText = displayText; @@ -99,8 +100,9 @@ public VpcVO(long zoneId, String name, String displayText, long accountId, long uuid = UUID.randomUUID().toString(); state = State.Enabled; this.networkDomain = networkDomain; - this.vpcOfferingId = vpcOffId; - this.usesDistributedRouter = useDistributedRouter; + vpcOfferingId = vpcOffId; + usesDistributedRouter = useDistributedRouter; + this.regionLevelVpc = regionLevelVpc; } @Override @@ -193,6 +195,11 @@ public void setUuid(String uuid) { this.uuid = uuid; } + @Override + public boolean isRegionLevelVpc() { + return regionLevelVpc; + } + public void setDisplay(boolean display) { this.display = display; @@ -204,8 +211,8 @@ public boolean isDisplay() { } @Override - public IAMEntityType getEntityType() { - return IAMEntityType.Vpc; + public Class getEntityType() { + return Vpc.class; } @Override diff --git a/engine/schema/src/com/cloud/network/vpc/dao/NetworkACLItemCidrsDaoImpl.java b/engine/schema/src/com/cloud/network/vpc/dao/NetworkACLItemCidrsDaoImpl.java new file mode 100644 index 0000000000..7c02f8b554 --- /dev/null +++ b/engine/schema/src/com/cloud/network/vpc/dao/NetworkACLItemCidrsDaoImpl.java @@ -0,0 +1,94 @@ +/** + * 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.vpc.dao; + +import java.util.ArrayList; +import java.util.List; + +import javax.ejb.Local; + +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; + +import com.cloud.network.vpc.NetworkACLItemCidrsDao; +import com.cloud.network.vpc.NetworkACLItemCidrsVO; +import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.TransactionLegacy; + +/** + * @author daan + * + */ +@Component +@Local(value = NetworkACLItemCidrsDao.class) +public class NetworkACLItemCidrsDaoImpl extends GenericDaoBase implements NetworkACLItemCidrsDao { + private static final Logger s_logger = Logger.getLogger(NetworkACLItemCidrsDaoImpl.class); + protected final SearchBuilder cidrsSearch; + + protected NetworkACLItemCidrsDaoImpl() { + cidrsSearch = createSearchBuilder(); + cidrsSearch.and("networkAclItemId", cidrsSearch.entity().getNetworkACLItemId(), SearchCriteria.Op.EQ); + cidrsSearch.done(); + } + + /* (non-Javadoc) + * @see com.cloud.network.dao.NetworkAclItemCidrsDao#persist(long, java.util.List) + */ + @Override + public void persist(long networkACLItemId, List cidrs) { + TransactionLegacy txn = TransactionLegacy.currentTxn(); + + txn.start(); + for (String cidr : cidrs) { + NetworkACLItemCidrsVO vo = new NetworkACLItemCidrsVO(networkACLItemId, cidr); + persist(vo); + } + txn.commit(); + } + + /* (non-Javadoc) + * @see com.cloud.network.dao.NetworkAclItemCidrsDao#getCidrs(long) + */ + @Override + public List getCidrs(long networkACLItemId) { + SearchCriteria sc = cidrsSearch.create(); + sc.setParameters("networkAclItemId", networkACLItemId); + + List results = search(sc, null); + List cidrs = new ArrayList(results.size()); + for (NetworkACLItemCidrsVO result : results) { + cidrs.add(result.getCidr()); + } + + return cidrs; + } + + @Override + public List listByNetworkACLItemId(long networkACLItemId) { + SearchCriteria sc = cidrsSearch.create(); + sc.setParameters("networkAclItemId", networkACLItemId); + + List results = search(sc, null); + + return results; + } + +} diff --git a/engine/schema/src/com/cloud/network/vpc/dao/NetworkACLItemDaoImpl.java b/engine/schema/src/com/cloud/network/vpc/dao/NetworkACLItemDaoImpl.java index 31ff6f259a..abd8bae563 100644 --- a/engine/schema/src/com/cloud/network/vpc/dao/NetworkACLItemDaoImpl.java +++ b/engine/schema/src/com/cloud/network/vpc/dao/NetworkACLItemDaoImpl.java @@ -19,10 +19,13 @@ import java.util.List; import javax.ejb.Local; +import javax.inject.Inject; +import org.apache.log4j.Logger; import org.springframework.stereotype.Component; import com.cloud.network.vpc.NetworkACLItem.State; +import com.cloud.network.vpc.NetworkACLItemCidrsDao; import com.cloud.network.vpc.NetworkACLItemDao; import com.cloud.network.vpc.NetworkACLItemVO; import com.cloud.utils.db.DB; @@ -31,17 +34,22 @@ import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria.Op; +import com.cloud.utils.db.TransactionLegacy; @Component @Local(value = NetworkACLItemDao.class) @DB() public class NetworkACLItemDaoImpl extends GenericDaoBase implements NetworkACLItemDao { + private static final Logger s_logger = Logger.getLogger(NetworkACLItemDaoImpl.class); protected final SearchBuilder AllFieldsSearch; protected final SearchBuilder NotRevokedSearch; protected final SearchBuilder ReleaseSearch; protected final GenericSearchBuilder MaxNumberSearch; + @Inject + protected NetworkACLItemCidrsDao _networkACLItemCidrsDao; + protected NetworkACLItemDaoImpl() { super(); @@ -75,6 +83,13 @@ protected NetworkACLItemDaoImpl() { MaxNumberSearch.done(); } + @Override + public NetworkACLItemVO findById(Long id) { + NetworkACLItemVO item = super.findById(id); + loadCidrs(item); + return item; + } + @Override public boolean setStateToAdd(NetworkACLItemVO rule) { SearchCriteria sc = AllFieldsSearch.create(); @@ -96,8 +111,11 @@ public boolean revoke(NetworkACLItemVO rule) { public List listByACL(long aclId) { SearchCriteria sc = AllFieldsSearch.create(); sc.setParameters("aclId", aclId); - - return listBy(sc); + List list = listBy(sc); + for(NetworkACLItemVO item :list) { + loadCidrs(item); + } + return list; } @Override @@ -113,6 +131,37 @@ public NetworkACLItemVO findByAclAndNumber(long aclId, int number) { SearchCriteria sc = AllFieldsSearch.create(); sc.setParameters("aclId", aclId); sc.setParameters("number", number); - return findOneBy(sc); + NetworkACLItemVO vo = findOneBy(sc); + if(vo != null) { + loadCidrs(vo); + } + return vo; + } + + @Override + @DB + public NetworkACLItemVO persist(NetworkACLItemVO networkAclItem) { + TransactionLegacy txn = TransactionLegacy.currentTxn(); + txn.start(); + + NetworkACLItemVO dbNetworkACLItem = super.persist(networkAclItem); + saveCidrs(networkAclItem, networkAclItem.getSourceCidrList()); + loadCidrs(dbNetworkACLItem); + + txn.commit(); + return dbNetworkACLItem; + } + + public void saveCidrs(NetworkACLItemVO networkACLItem, List cidrList) { + if (cidrList == null) { + return; + } + _networkACLItemCidrsDao.persist(networkACLItem.getId(), cidrList); + } + + @Override + public void loadCidrs(NetworkACLItemVO item) { + List cidrs = _networkACLItemCidrsDao.getCidrs(item.getId()); + item.setSourceCidrList(cidrs); } } diff --git a/engine/schema/src/com/cloud/offerings/NetworkOfferingVO.java b/engine/schema/src/com/cloud/offerings/NetworkOfferingVO.java index bf07807494..c3d849d134 100755 --- a/engine/schema/src/com/cloud/offerings/NetworkOfferingVO.java +++ b/engine/schema/src/com/cloud/offerings/NetworkOfferingVO.java @@ -139,6 +139,9 @@ public class NetworkOfferingVO implements NetworkOffering { @Column(name = "keep_alive_enabled") boolean keepAliveEnabled = false; + @Column(name="supports_streched_l2") + boolean supportsStrechedL2 = false; + @Override public String getDisplayText() { return displayText; @@ -331,7 +334,7 @@ public NetworkOfferingVO(String name, String displayText, TrafficType trafficTyp public NetworkOfferingVO(String name, String displayText, TrafficType trafficType, boolean systemOnly, boolean specifyVlan, Integer rateMbps, Integer multicastRateMbps, boolean isDefault, Availability availability, String tags, Network.GuestType guestType, boolean conserveMode, boolean dedicatedLb, boolean sharedSourceNat, boolean redundantRouter, boolean elasticIp, boolean elasticLb, boolean specifyIpRanges, boolean inline, boolean isPersistent, - boolean associatePublicIP, boolean publicLb, boolean internalLb, boolean egressdefaultpolicy) { + boolean associatePublicIP, boolean publicLb, boolean internalLb, boolean egressdefaultpolicy, boolean supportsStrechedL2) { this(name, displayText, trafficType, @@ -356,6 +359,7 @@ public NetworkOfferingVO(String name, String displayText, TrafficType trafficTyp this.inline = inline; this.eipAssociatePublicIp = associatePublicIP; this.egressdefaultpolicy = egressdefaultpolicy; + this.supportsStrechedL2 = supportsStrechedL2; } public NetworkOfferingVO() { @@ -486,4 +490,9 @@ public void setConcurrentConnections(Integer concurrentConnections) { public void setPublicLb(boolean publicLb) { this.publicLb = publicLb; } + + @Override + public boolean getSupportsStrechedL2() { + return supportsStrechedL2; + } } diff --git a/engine/schema/src/com/cloud/projects/ProjectInvitationVO.java b/engine/schema/src/com/cloud/projects/ProjectInvitationVO.java index 885c148c2b..9775135bea 100644 --- a/engine/schema/src/com/cloud/projects/ProjectInvitationVO.java +++ b/engine/schema/src/com/cloud/projects/ProjectInvitationVO.java @@ -28,8 +28,6 @@ import javax.persistence.Id; import javax.persistence.Table; -import org.apache.cloudstack.acl.IAMEntityType; - import com.cloud.utils.db.GenericDao; @Entity @@ -149,7 +147,7 @@ public long getAccountId() { } @Override - public IAMEntityType getEntityType() { - return IAMEntityType.ProjectInvitation; + public Class getEntityType() { + return ProjectInvitation.class; } } diff --git a/engine/schema/src/com/cloud/service/ServiceOfferingVO.java b/engine/schema/src/com/cloud/service/ServiceOfferingVO.java index 3873dd272f..0ea68b9a63 100755 --- a/engine/schema/src/com/cloud/service/ServiceOfferingVO.java +++ b/engine/schema/src/com/cloud/service/ServiceOfferingVO.java @@ -173,6 +173,7 @@ public ServiceOfferingVO(ServiceOfferingVO offering) { offering.getUseLocalStorage(), offering.getSystemUse(), true, + offering.isCustomizedIops()== null ? false:offering.isCustomizedIops(), offering.getDomainId()); cpu = offering.getCpu(); ramSize = offering.getRamSize(); diff --git a/engine/schema/src/com/cloud/storage/DiskOfferingVO.java b/engine/schema/src/com/cloud/storage/DiskOfferingVO.java index d1a48d20c9..99214b2190 100755 --- a/engine/schema/src/com/cloud/storage/DiskOfferingVO.java +++ b/engine/schema/src/com/cloud/storage/DiskOfferingVO.java @@ -207,7 +207,7 @@ public DiskOfferingVO(String name, String displayText, boolean mirrored, String } public DiskOfferingVO(long id, String name, String displayText, boolean mirrored, String tags, boolean recreatable, - boolean useLocalStorage, boolean systemUse, boolean customized, Long domainId) { + boolean useLocalStorage, boolean systemUse, boolean customized, boolean customizedIops, Long domainId) { this.id = id; type = Type.Service; this.name = name; @@ -217,6 +217,7 @@ public DiskOfferingVO(long id, String name, String displayText, boolean mirrored this.useLocalStorage = useLocalStorage; this.systemUse = systemUse; this.customized = customized; + this.customizedIops = customizedIops; this.domainId = domainId; uuid = UUID.randomUUID().toString(); state = State.Active; diff --git a/engine/schema/src/com/cloud/storage/GuestOSHypervisorVO.java b/engine/schema/src/com/cloud/storage/GuestOSHypervisorVO.java index 1fbc9d7178..087649b887 100644 --- a/engine/schema/src/com/cloud/storage/GuestOSHypervisorVO.java +++ b/engine/schema/src/com/cloud/storage/GuestOSHypervisorVO.java @@ -57,6 +57,9 @@ public class GuestOSHypervisorVO implements GuestOSHypervisor { @Column(name = GenericDao.CREATED_COLUMN) Date created; + @Column(name = "is_user_defined") + private boolean isUserDefined; + @Override public long getId() { return id; @@ -120,4 +123,13 @@ public void setUuid(String uuid) { public void setRemoved(Date removed) { this.removed = removed; } + + @Override + public boolean getIsUserDefined() { + return isUserDefined; + } + + public void setIsUserDefined(boolean isUserDefined) { + this.isUserDefined = isUserDefined; + } } diff --git a/engine/schema/src/com/cloud/storage/GuestOSVO.java b/engine/schema/src/com/cloud/storage/GuestOSVO.java index a0040beeaf..f04f9a4208 100644 --- a/engine/schema/src/com/cloud/storage/GuestOSVO.java +++ b/engine/schema/src/com/cloud/storage/GuestOSVO.java @@ -54,6 +54,9 @@ public class GuestOSVO implements GuestOS { @Column(name = GenericDao.CREATED_COLUMN) private Date created; + @Column(name = "is_user_defined") + private boolean isUserDefined; + @Override public long getId() { return id; @@ -108,4 +111,13 @@ public void setRemoved(Date removed) { public Date getRemoved() { return removed; } + + @Override + public boolean getIsUserDefined() { + return isUserDefined; + } + + public void setIsUserDefined(boolean isUserDefined) { + this.isUserDefined = isUserDefined; + } } diff --git a/engine/schema/src/com/cloud/storage/SnapshotPolicyVO.java b/engine/schema/src/com/cloud/storage/SnapshotPolicyVO.java index 2f8638e5d1..c784858682 100644 --- a/engine/schema/src/com/cloud/storage/SnapshotPolicyVO.java +++ b/engine/schema/src/com/cloud/storage/SnapshotPolicyVO.java @@ -58,17 +58,21 @@ public class SnapshotPolicyVO implements SnapshotPolicy { @Column(name = "uuid") String uuid; + @Column(name = "display", updatable = true, nullable = false) + protected boolean display = true; + public SnapshotPolicyVO() { this.uuid = UUID.randomUUID().toString(); } - public SnapshotPolicyVO(long volumeId, String schedule, String timezone, IntervalType intvType, int maxSnaps) { + public SnapshotPolicyVO(long volumeId, String schedule, String timezone, IntervalType intvType, int maxSnaps, boolean display) { this.volumeId = volumeId; this.schedule = schedule; this.timezone = timezone; this.interval = (short)intvType.ordinal(); this.maxSnaps = maxSnaps; this.active = true; + this.display = display; this.uuid = UUID.randomUUID().toString(); } @@ -140,4 +144,12 @@ public String getUuid() { public void setUuid(String uuid) { this.uuid = uuid; } + + public boolean isDisplay() { + return display; + } + + public void setDisplay(boolean display) { + this.display = display; + } } diff --git a/engine/schema/src/com/cloud/storage/SnapshotVO.java b/engine/schema/src/com/cloud/storage/SnapshotVO.java index 4c8ceb7cdd..dae049f604 100644 --- a/engine/schema/src/com/cloud/storage/SnapshotVO.java +++ b/engine/schema/src/com/cloud/storage/SnapshotVO.java @@ -30,8 +30,6 @@ import com.google.gson.annotations.Expose; -import org.apache.cloudstack.acl.IAMEntityType; - import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.utils.db.GenericDao; @@ -239,7 +237,7 @@ public void setUuid(String uuid) { } @Override - public IAMEntityType getEntityType() { - return IAMEntityType.Snapshot; + public Class getEntityType() { + return Snapshot.class; } } diff --git a/engine/schema/src/com/cloud/storage/VMTemplateVO.java b/engine/schema/src/com/cloud/storage/VMTemplateVO.java index c0b7d0fc02..9a77cbf873 100755 --- a/engine/schema/src/com/cloud/storage/VMTemplateVO.java +++ b/engine/schema/src/com/cloud/storage/VMTemplateVO.java @@ -31,8 +31,6 @@ import javax.persistence.TemporalType; import javax.persistence.Transient; -import org.apache.cloudstack.acl.IAMEntityType; - import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Storage.TemplateType; @@ -635,7 +633,7 @@ public void setUpdated(Date updated) { } @Override - public IAMEntityType getEntityType() { - return IAMEntityType.VirtualMachineTemplate; + public Class getEntityType() { + return VirtualMachineTemplate.class; } } diff --git a/engine/schema/src/com/cloud/storage/VolumeVO.java b/engine/schema/src/com/cloud/storage/VolumeVO.java index af99a16ffa..50b235e6c9 100755 --- a/engine/schema/src/com/cloud/storage/VolumeVO.java +++ b/engine/schema/src/com/cloud/storage/VolumeVO.java @@ -32,8 +32,6 @@ import javax.persistence.TemporalType; import javax.persistence.Transient; -import org.apache.cloudstack.acl.IAMEntityType; - import com.cloud.storage.Storage.StoragePoolType; import com.cloud.utils.NumbersUtil; import com.cloud.utils.db.GenericDao; @@ -554,6 +552,15 @@ public boolean isDisplayVolume() { return displayVolume; } + @Override + public boolean isDisplay(){ + return displayVolume; + } + + public void setDisplay(boolean display){ + this.displayVolume = display; + } + public void setDisplayVolume(boolean displayVolume) { this.displayVolume = displayVolume; } @@ -601,7 +608,7 @@ public Integer getHypervisorSnapshotReserve() { } @Override - public IAMEntityType getEntityType() { - return IAMEntityType.Volume; + public Class getEntityType() { + return Volume.class; } } diff --git a/engine/schema/src/com/cloud/storage/dao/GuestOSHypervisorDao.java b/engine/schema/src/com/cloud/storage/dao/GuestOSHypervisorDao.java index 5b6e7198f0..a777516526 100644 --- a/engine/schema/src/com/cloud/storage/dao/GuestOSHypervisorDao.java +++ b/engine/schema/src/com/cloud/storage/dao/GuestOSHypervisorDao.java @@ -27,4 +27,6 @@ public interface GuestOSHypervisorDao extends GenericDao guestOsSearch; protected final SearchBuilder mappingSearch; + protected final SearchBuilder userDefinedMappingSearch; protected GuestOSHypervisorDaoImpl() { guestOsSearch = createSearchBuilder(); @@ -45,6 +46,13 @@ protected GuestOSHypervisorDaoImpl() { mappingSearch.and("hypervisor_type", mappingSearch.entity().getHypervisorType(), SearchCriteria.Op.EQ); mappingSearch.and("hypervisor_version", mappingSearch.entity().getHypervisorVersion(), SearchCriteria.Op.EQ); mappingSearch.done(); + + userDefinedMappingSearch = createSearchBuilder(); + userDefinedMappingSearch.and("guest_os_id", userDefinedMappingSearch.entity().getGuestOsId(), SearchCriteria.Op.EQ); + userDefinedMappingSearch.and("hypervisor_type", userDefinedMappingSearch.entity().getHypervisorType(), SearchCriteria.Op.EQ); + userDefinedMappingSearch.and("hypervisor_version", userDefinedMappingSearch.entity().getHypervisorVersion(), SearchCriteria.Op.EQ); + userDefinedMappingSearch.and("is_user_defined", userDefinedMappingSearch.entity().getIsUserDefined(), SearchCriteria.Op.EQ); + userDefinedMappingSearch.done(); } @Override @@ -58,9 +66,27 @@ public HypervisorType findHypervisorTypeByGuestOsId(long guestOsId) { @Override public GuestOSHypervisorVO findByOsIdAndHypervisor(long guestOsId, String hypervisorType, String hypervisorVersion) { SearchCriteria sc = mappingSearch.create(); + String version = "default"; + if (!(hypervisorVersion == null || hypervisorVersion.isEmpty())) { + version = hypervisorVersion; + } + sc.setParameters("guest_os_id", guestOsId); + sc.setParameters("hypervisor_type", hypervisorType); + sc.setParameters("hypervisor_version", version); + return findOneBy(sc); + } + + @Override + public GuestOSHypervisorVO findByOsIdAndHypervisorAndUserDefined(long guestOsId, String hypervisorType, String hypervisorVersion, boolean isUserDefined) { + SearchCriteria sc = userDefinedMappingSearch.create(); + String version = "default"; + if (!(hypervisorVersion == null || hypervisorVersion.isEmpty())) { + version = hypervisorVersion; + } sc.setParameters("guest_os_id", guestOsId); sc.setParameters("hypervisor_type", hypervisorType); - sc.setParameters("hypervisor_version", hypervisorVersion); + sc.setParameters("hypervisor_version", version); + sc.setParameters("is_user_defined", isUserDefined); return findOneBy(sc); } diff --git a/engine/schema/src/com/cloud/storage/dao/SnapshotPolicyDao.java b/engine/schema/src/com/cloud/storage/dao/SnapshotPolicyDao.java index f65b5839f7..0ce2b17088 100644 --- a/engine/schema/src/com/cloud/storage/dao/SnapshotPolicyDao.java +++ b/engine/schema/src/com/cloud/storage/dao/SnapshotPolicyDao.java @@ -32,13 +32,15 @@ public interface SnapshotPolicyDao extends GenericDao { List listByVolumeId(long volumeId, Filter filter); - Pair, Integer> listAndCountByVolumeId(long volumeId); + Pair, Integer> listAndCountByVolumeId(long volumeId, boolean display); - Pair, Integer> listAndCountByVolumeId(long volumeId, Filter filter); + Pair, Integer> listAndCountByVolumeId(long volumeId, boolean display, Filter filter); SnapshotPolicyVO findOneByVolumeInterval(long volumeId, IntervalType intvType); List listActivePolicies(); SnapshotPolicyVO findOneByVolume(long volumeId); + + Pair, Integer> listAndCountById(long id, boolean display, Filter filter); } diff --git a/engine/schema/src/com/cloud/storage/dao/SnapshotPolicyDaoImpl.java b/engine/schema/src/com/cloud/storage/dao/SnapshotPolicyDaoImpl.java index b0ea9176f3..033a82d5a6 100644 --- a/engine/schema/src/com/cloud/storage/dao/SnapshotPolicyDaoImpl.java +++ b/engine/schema/src/com/cloud/storage/dao/SnapshotPolicyDaoImpl.java @@ -36,6 +36,7 @@ public class SnapshotPolicyDaoImpl extends GenericDaoBase VolumeIdSearch; private final SearchBuilder VolumeIdIntervalSearch; private final SearchBuilder ActivePolicySearch; + private final SearchBuilder SnapshotPolicySearch; @Override public SnapshotPolicyVO findOneByVolumeInterval(long volumeId, IntervalType intvType) { @@ -66,22 +67,32 @@ public List listByVolumeId(long volumeId, Filter filter) { } @Override - public Pair, Integer> listAndCountByVolumeId(long volumeId) { - return listAndCountByVolumeId(volumeId, null); + public Pair, Integer> listAndCountByVolumeId(long volumeId, boolean display) { + return listAndCountByVolumeId(volumeId, display, null); } @Override - public Pair, Integer> listAndCountByVolumeId(long volumeId, Filter filter) { + public Pair, Integer> listAndCountByVolumeId(long volumeId, boolean display, Filter filter) { SearchCriteria sc = VolumeIdSearch.create(); sc.setParameters("volumeId", volumeId); + sc.setParameters("display", display); sc.setParameters("active", true); return searchAndCount(sc, filter); } + @Override + public Pair, Integer> listAndCountById(long id, boolean display, Filter filter){ + SearchCriteria sc = SnapshotPolicySearch.create(); + sc.setParameters("id", id); + sc.setParameters("display", display); + return searchAndCount(sc, filter); + } + protected SnapshotPolicyDaoImpl() { VolumeIdSearch = createSearchBuilder(); VolumeIdSearch.and("volumeId", VolumeIdSearch.entity().getVolumeId(), SearchCriteria.Op.EQ); VolumeIdSearch.and("active", VolumeIdSearch.entity().isActive(), SearchCriteria.Op.EQ); + VolumeIdSearch.and("display", VolumeIdSearch.entity().isDisplay(), SearchCriteria.Op.EQ); VolumeIdSearch.done(); VolumeIdIntervalSearch = createSearchBuilder(); @@ -92,6 +103,11 @@ protected SnapshotPolicyDaoImpl() { ActivePolicySearch = createSearchBuilder(); ActivePolicySearch.and("active", ActivePolicySearch.entity().isActive(), SearchCriteria.Op.EQ); ActivePolicySearch.done(); + + SnapshotPolicySearch = createSearchBuilder(); + SnapshotPolicySearch.and("id", SnapshotPolicySearch.entity().getId(), SearchCriteria.Op.EQ); + SnapshotPolicySearch.and("display", SnapshotPolicySearch.entity().isDisplay(), SearchCriteria.Op.EQ); + SnapshotPolicySearch.done(); } @Override diff --git a/engine/schema/src/com/cloud/tags/ResourceTagVO.java b/engine/schema/src/com/cloud/tags/ResourceTagVO.java index 6b743ffd23..eadddd1e31 100644 --- a/engine/schema/src/com/cloud/tags/ResourceTagVO.java +++ b/engine/schema/src/com/cloud/tags/ResourceTagVO.java @@ -27,8 +27,6 @@ import javax.persistence.Id; import javax.persistence.Table; -import org.apache.cloudstack.acl.IAMEntityType; - import com.cloud.server.ResourceTag; @@ -166,7 +164,7 @@ public String getResourceUuid() { } @Override - public IAMEntityType getEntityType() { - return IAMEntityType.ResourceTag; + public Class getEntityType() { + return ResourceTag.class; } } diff --git a/engine/schema/src/com/cloud/upgrade/DatabaseCreator.java b/engine/schema/src/com/cloud/upgrade/DatabaseCreator.java index 91ef318873..b04607decc 100755 --- a/engine/schema/src/com/cloud/upgrade/DatabaseCreator.java +++ b/engine/schema/src/com/cloud/upgrade/DatabaseCreator.java @@ -20,14 +20,13 @@ import java.io.File; import java.io.FileInputStream; -import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.io.Reader; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.SQLException; import java.sql.Statement; +import java.sql.SQLException; +import java.sql.DriverManager; +import java.sql.Connection; import java.util.ArrayList; import java.util.List; import java.util.Properties; @@ -75,13 +74,10 @@ private static void runScript(Connection conn, Reader reader, String filename, b private static void runQuery(String host, String port, String rootPassword, String query, boolean dryRun) { System.out.println("============> Running query: " + query); - Connection conn = null; - try { - conn = DriverManager.getConnection(String.format("jdbc:mysql://%s:%s/", host, port), "root", rootPassword); - Statement stmt = conn.createStatement(); - if (!dryRun) + try (Connection conn = DriverManager.getConnection(String.format("jdbc:mysql://%s:%s/", host, port), "root", rootPassword); + Statement stmt = conn.createStatement();){ + if (!dryRun) stmt.executeUpdate(query); - conn.close(); } catch (SQLException e) { System.out.println("SQL exception in trying initDB: " + e); System.exit(1); @@ -186,24 +182,23 @@ public static void main(String[] args) { } System.out.println("========> Processing SQL file at " + sqlScript.getAbsolutePath()); - Connection conn = TransactionLegacy.getStandaloneConnection(); - try { - FileReader reader = null; - try { - reader = new FileReader(sqlScript); - } catch (FileNotFoundException e) { - System.err.println("Unable to read " + sqlFile + ": " + e.getMessage()); - System.exit(1); - } + + try(Connection conn = TransactionLegacy.getStandaloneConnection(); + FileReader reader = new FileReader(sqlScript); + ) { if (!dryRun) runScript(conn, reader, sqlFile, verbosity); - } finally { - try { - conn.close(); - } catch (SQLException e) { - System.err.println("Unable to close DB connection: " + e.getMessage()); - } + }catch (SQLException e) + { + System.err.println("Sql Exception:" + e.getMessage()); + System.exit(1); + } + catch (IOException e) + { + System.err.println("File IO Exception : " + e.getMessage()); + System.exit(1); } + } TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); diff --git a/engine/schema/src/com/cloud/upgrade/DatabaseIntegrityChecker.java b/engine/schema/src/com/cloud/upgrade/DatabaseIntegrityChecker.java index c20a418313..2001fae052 100755 --- a/engine/schema/src/com/cloud/upgrade/DatabaseIntegrityChecker.java +++ b/engine/schema/src/com/cloud/upgrade/DatabaseIntegrityChecker.java @@ -75,81 +75,106 @@ private String formatDuplicateHostToReadText(Long poolId, ResultSet rs) throws S } private Boolean checkDuplicateHostWithTheSameLocalStorage() { + TransactionLegacy txn = TransactionLegacy.open("Integrity"); - txn.start(); try { - Connection conn; + txn.start(); + Connection conn = txn.getConnection(); + try (PreparedStatement pstmt = + conn.prepareStatement("SELECT pool_id FROM host INNER JOIN storage_pool_host_ref INNER JOIN storage_pool WHERE storage_pool.id = storage_pool_host_ref.pool_id and storage_pool.pool_type='LVM' AND host.id=storage_pool_host_ref.host_id AND host.removed IS NULL group by pool_id having count(*) > 1"); + ResultSet rs = pstmt.executeQuery();) + { + boolean noDuplicate = true; + StringBuffer helpInfo = new StringBuffer(); + String note = + "DATABASE INTEGRITY ERROR\nManagement server detected there are some hosts connect to the same loacal storage, please contact CloudStack support team for solution. Below are detialed info, please attach all of them to CloudStack support. Thank you\n"; + helpInfo.append(note); + while (rs.next()) { + try ( PreparedStatement sel_pstmt = + conn.prepareStatement("select id, status, removed, private_ip_address from host where id in (select host_id from storage_pool_host_ref where pool_id=?)"); + ){ + long poolId = rs.getLong(1); + pstmt.setLong(1, poolId); + try(ResultSet dhrs = sel_pstmt.executeQuery();) { + String help = formatDuplicateHostToReadText(poolId, dhrs); + helpInfo.append(help); + helpInfo.append("\n"); + noDuplicate = false; + } + catch (Exception e) + { + s_logger.error("checkDuplicateHostWithTheSameLocalStorage: Exception :" + e.getMessage()); + throw new CloudRuntimeException("checkDuplicateHostWithTheSameLocalStorage: Exception :" + e.getMessage(),e); + } + } + catch (Exception e) + { + s_logger.error("checkDuplicateHostWithTheSameLocalStorage: Exception :" + e.getMessage()); + throw new CloudRuntimeException("checkDuplicateHostWithTheSameLocalStorage: Exception :" + e.getMessage(),e); + } + } + if (noDuplicate) { + s_logger.debug("No duplicate hosts with the same local storage found in database"); + } else { + s_logger.error(helpInfo.toString()); + } + txn.commit(); + return noDuplicate; + }catch (Exception e) + { + s_logger.error("checkDuplicateHostWithTheSameLocalStorage: Exception :" + e.getMessage()); + throw new CloudRuntimeException("checkDuplicateHostWithTheSameLocalStorage: Exception :" + e.getMessage(),e); + } + } + catch (Exception e) + { + s_logger.error("checkDuplicateHostWithTheSameLocalStorage: Exception :" + e.getMessage()); + throw new CloudRuntimeException("checkDuplicateHostWithTheSameLocalStorage: Exception :" + e.getMessage(),e); + } + finally + { try { - conn = txn.getConnection(); - PreparedStatement pstmt = - conn.prepareStatement("SELECT pool_id FROM host INNER JOIN storage_pool_host_ref INNER JOIN storage_pool WHERE storage_pool.id = storage_pool_host_ref.pool_id and storage_pool.pool_type='LVM' AND host.id=storage_pool_host_ref.host_id AND host.removed IS NULL group by pool_id having count(*) > 1"); - ResultSet rs = pstmt.executeQuery(); - - boolean noDuplicate = true; - StringBuffer helpInfo = new StringBuffer(); - String note = - "DATABASE INTEGRITY ERROR\nManagement server detected there are some hosts connect to the same loacal storage, please contact CloudStack support team for solution. Below are detialed info, please attach all of them to CloudStack support. Thank you\n"; - helpInfo.append(note); - while (rs.next()) { - long poolId = rs.getLong(1); - pstmt = - conn.prepareStatement("select id, status, removed, private_ip_address from host where id in (select host_id from storage_pool_host_ref where pool_id=?)"); - pstmt.setLong(1, poolId); - ResultSet dhrs = pstmt.executeQuery(); - String help = formatDuplicateHostToReadText(poolId, dhrs); - helpInfo.append(help); - helpInfo.append("\n"); - noDuplicate = false; + if (txn != null) { + txn.close(); } - - if (noDuplicate) { - s_logger.debug("No duplicate hosts with the same local storage found in database"); - } else { - s_logger.error(helpInfo.toString()); - } - - return noDuplicate; - } catch (SQLException e) { - s_logger.error("Unable to check duplicate hosts with the same local storage in database", e); - throw new CloudRuntimeException("Unable to check duplicate hosts with the same local storage in database", e); + }catch(Exception e) + { + s_logger.error("checkDuplicateHostWithTheSameLocalStorage: Exception:"+ e.getMessage()); } - } finally { - txn.commit(); - txn.close(); } } private boolean check21to22PremiumUprage(Connection conn) throws SQLException { - PreparedStatement pstmt = conn.prepareStatement("show tables in cloud_usage"); - ResultSet rs = pstmt.executeQuery(); - int num = 0; - - while (rs.next()) { - String tableName = rs.getString(1); - if (tableName.equalsIgnoreCase("usage_event") || tableName.equalsIgnoreCase("usage_port_forwarding") || tableName.equalsIgnoreCase("usage_network_offering")) { - num++; - s_logger.debug("Checking 21to22PremiumUprage table " + tableName + " found"); - } - if (num == 3) { - return true; + try (PreparedStatement pstmt = conn.prepareStatement("show tables in cloud_usage"); + ResultSet rs = pstmt.executeQuery();) { + int num = 0; + while (rs.next()) { + String tableName = rs.getString(1); + if (tableName.equalsIgnoreCase("usage_event") || tableName.equalsIgnoreCase("usage_port_forwarding") || tableName.equalsIgnoreCase("usage_network_offering")) { + num++; + s_logger.debug("Checking 21to22PremiumUprage table " + tableName + " found"); + } + if (num == 3) { + return true; + } } + return false; } - - return false; } private boolean isColumnExisted(Connection conn, String dbName, String tableName, String column) throws SQLException { - PreparedStatement pstmt = conn.prepareStatement(String.format("describe %1$s.%2$s", dbName, tableName)); - ResultSet rs = pstmt.executeQuery(); - boolean found = false; - while (rs.next()) { - if (column.equalsIgnoreCase(rs.getString(1))) { - s_logger.debug(String.format("Column %1$s.%2$s.%3$s found", dbName, tableName, column)); - found = true; - break; + try (PreparedStatement pstmt = conn.prepareStatement(String.format("describe %1$s.%2$s", dbName, tableName)); + ResultSet rs = pstmt.executeQuery();) { + boolean found = false; + while (rs.next()) { + if (column.equalsIgnoreCase(rs.getString(1))) { + s_logger.debug(String.format("Column %1$s.%2$s.%3$s found", dbName, tableName, column)); + found = true; + break; + } } + return found; } - return found; } private boolean check221to222PremiumUprage(Connection conn) throws SQLException { @@ -174,22 +199,23 @@ private boolean check222to224PremiumUpgrade(Connection conn) throws SQLException private boolean checkMissedPremiumUpgradeFor228() { TransactionLegacy txn = TransactionLegacy.open("Integrity"); - txn.start(); try { - String dbVersion = _dao.getCurrentVersion(); - - if (dbVersion == null) - return false; + txn.start(); + Connection conn = txn.getConnection(); + try ( + PreparedStatement pstmt = conn.prepareStatement("show databases"); + ResultSet rs = pstmt.executeQuery();) { + String dbVersion = _dao.getCurrentVersion(); - if (Version.compare(Version.trimToPatch(dbVersion), Version.trimToPatch("2.2.8")) != 0) { - return true; - } + if (dbVersion == null) { + txn.commit(); + return false; + } - Connection conn; - try { - conn = txn.getConnection(); - PreparedStatement pstmt = conn.prepareStatement("show databases"); - ResultSet rs = pstmt.executeQuery(); + if (Version.compare(Version.trimToPatch(dbVersion), Version.trimToPatch("2.2.8")) != 0) { + txn.commit(); + return true; + } boolean hasUsage = false; while (rs.next()) { String dbName = rs.getString(1); @@ -198,35 +224,46 @@ private boolean checkMissedPremiumUpgradeFor228() { break; } } - if (!hasUsage) { s_logger.debug("No cloud_usage found in database, no need to check missed premium upgrade"); + txn.commit(); return true; } - if (!check21to22PremiumUprage(conn)) { s_logger.error("21to22 premium upgrade missed"); + txn.commit(); return false; } - if (!check221to222PremiumUprage(conn)) { s_logger.error("221to222 premium upgrade missed"); + txn.commit(); return false; } - if (!check222to224PremiumUpgrade(conn)) { s_logger.error("222to224 premium upgrade missed"); + txn.commit(); return false; } - + txn.commit(); return true; - } catch (SQLException e) { - s_logger.error("Unable to check missed premiumg upgrade"); - throw new CloudRuntimeException("Unable to check missed premiumg upgrade"); + } catch (Exception e) { + s_logger.error("checkMissedPremiumUpgradeFor228: Exception:" + e.getMessage()); + throw new CloudRuntimeException("checkMissedPremiumUpgradeFor228: Exception:" + e.getMessage(), e); + } + }catch (Exception e) { + s_logger.error("checkMissedPremiumUpgradeFor228: Exception:"+ e.getMessage()); + throw new CloudRuntimeException("checkMissedPremiumUpgradeFor228: Exception:" + e.getMessage(),e); + } + finally + { + try { + if (txn != null) { + txn.close(); + } + }catch(Exception e) + { + s_logger.error("checkMissedPremiumUpgradeFor228: Exception:"+ e.getMessage()); } - } finally { - txn.commit(); - txn.close(); } } diff --git a/engine/schema/src/com/cloud/upgrade/DatabaseUpgradeChecker.java b/engine/schema/src/com/cloud/upgrade/DatabaseUpgradeChecker.java index 0761c9fe61..8586ed484e 100755 --- a/engine/schema/src/com/cloud/upgrade/DatabaseUpgradeChecker.java +++ b/engine/schema/src/com/cloud/upgrade/DatabaseUpgradeChecker.java @@ -237,8 +237,8 @@ public DatabaseUpgradeChecker() { } 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) { @@ -251,6 +251,7 @@ protected void runScript(Connection conn, File file) { s_logger.error("Unable to execute upgrade script: " + file.getAbsolutePath(), e); throw new CloudRuntimeException("Unable to execute upgrade script: " + file.getAbsolutePath(), e); } + } protected void upgrade(String dbVersion, String currentVersion) { @@ -314,10 +315,9 @@ protected void upgrade(String dbVersion, String currentVersion) { // we don't have VersionDao in 2.1.x upgradeVersion = false; } else if (upgrade.getUpgradedVersion().equals("2.2.4")) { - try { + try(PreparedStatement pstmt = conn.prepareStatement("SELECT * FROM version WHERE version='2.2.4'"); + ResultSet rs = pstmt.executeQuery();) { // specifically for domain vlan update from 2.1.8 to 2.2.4 - PreparedStatement pstmt = conn.prepareStatement("SELECT * FROM version WHERE version='2.2.4'"); - ResultSet rs = pstmt.executeQuery(); if (rs.next()) { upgradeVersion = false; } diff --git a/engine/schema/src/com/cloud/upgrade/dao/DatabaseAccessObject.java b/engine/schema/src/com/cloud/upgrade/dao/DatabaseAccessObject.java index 836a537686..1e620a5a58 100644 --- a/engine/schema/src/com/cloud/upgrade/dao/DatabaseAccessObject.java +++ b/engine/schema/src/com/cloud/upgrade/dao/DatabaseAccessObject.java @@ -26,63 +26,50 @@ public class DatabaseAccessObject { private static Logger s_logger = Logger.getLogger(DatabaseAccessObject.class); - public void dropKey(Connection conn, String tableName, String key, boolean isForeignKey) { - PreparedStatement pstmt = null; - try { - if (isForeignKey) { - pstmt = conn.prepareStatement("ALTER TABLE " + tableName + " DROP FOREIGN KEY " + key); - } else { - pstmt = conn.prepareStatement("ALTER TABLE " + tableName + " DROP KEY " + key); - } + public void dropKey(Connection conn, String tableName, String key, boolean isForeignKey) + { + String alter_sql_str; + if (isForeignKey) { + alter_sql_str = "ALTER TABLE " + tableName + " DROP FOREIGN KEY " + key; + } else { + alter_sql_str = "ALTER TABLE " + tableName + " DROP KEY " + key; + } + try(PreparedStatement pstmt = conn.prepareStatement(alter_sql_str);) + { pstmt.executeUpdate(); s_logger.debug("Key " + key + " is dropped successfully from the table " + tableName); } catch (SQLException e) { - s_logger.warn("Ignored SQL Exception when trying to drop " + (isForeignKey ? "foreign " : "") + "key " + key + " on table " + tableName, e); - } finally { - closePreparedStatement(pstmt, "Ignored SQL Exception when trying to close PreparedStatement atfer dropping " + (isForeignKey ? "foreign " : "") + "key " + key - + " on table " + tableName); + s_logger.warn("Ignored SQL Exception when trying to drop " + (isForeignKey ? "foreign " : "") + "key " + key + " on table " + tableName, e); + } } public void dropPrimaryKey(Connection conn, String tableName) { - PreparedStatement pstmt = null; - try { - pstmt = conn.prepareStatement("ALTER TABLE " + tableName + " DROP PRIMARY KEY "); + try(PreparedStatement pstmt = conn.prepareStatement("ALTER TABLE " + tableName + " DROP PRIMARY KEY ");) { pstmt.executeUpdate(); s_logger.debug("Primary key is dropped successfully from the table " + tableName); } catch (SQLException e) { s_logger.warn("Ignored SQL Exception when trying to drop primary key on table " + tableName, e); - } finally { - closePreparedStatement(pstmt, "Ignored SQL Exception when trying to close PreparedStatement atfer dropping primary key on table " + tableName); } } public void dropColumn(Connection conn, String tableName, String columnName) { - PreparedStatement pstmt = null; - try { - pstmt = conn.prepareStatement("ALTER TABLE " + tableName + " DROP COLUMN " + columnName); + try (PreparedStatement pstmt = conn.prepareStatement("ALTER TABLE " + tableName + " DROP COLUMN " + columnName);){ pstmt.executeUpdate(); s_logger.debug("Column " + columnName + " is dropped successfully from the table " + tableName); } catch (SQLException e) { - s_logger.warn("Unable to drop columns using query " + pstmt + " due to exception", e); - } finally { - closePreparedStatement(pstmt, "Ignored SQL Exception when trying to close PreparedStatement after dropping column " + columnName + " on table " + tableName); + s_logger.warn("Unable to drop column " + columnName + " due to exception", e); } } public boolean columnExists(Connection conn, String tableName, String columnName) { boolean columnExists = false; - PreparedStatement pstmt = null; - try { - pstmt = conn.prepareStatement("SELECT " + columnName + " FROM " + tableName); + try (PreparedStatement pstmt = conn.prepareStatement("SELECT " + columnName + " FROM " + tableName);){ pstmt.executeQuery(); columnExists = true; } catch (SQLException e) { s_logger.warn("Field " + columnName + " doesn't exist in " + tableName, e); - } finally { - closePreparedStatement(pstmt, "Ignored SQL Exception when trying to close PreparedStatement atfer checking if column " + columnName + " existed on table " + tableName); } - return columnExists; } diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade410to420.java b/engine/schema/src/com/cloud/upgrade/dao/Upgrade410to420.java index 82b6d8481a..671cbb7269 100755 --- a/engine/schema/src/com/cloud/upgrade/dao/Upgrade410to420.java +++ b/engine/schema/src/com/cloud/upgrade/dao/Upgrade410to420.java @@ -738,8 +738,8 @@ private void updateOverCommitRatioClusterDetails(Connection conn) { pstmt2.execute(); } else { //update cluster_details table with the default overcommit ratios. - pstmt1.setLong(1, id); - pstmt1.setString(2, "1"); + pstmt1.setLong(1,id); + pstmt1.setString(2,global_cpu_overprovisioning_factor); pstmt1.execute(); pstmt2.setLong(1, id); pstmt2.setString(2, "1"); diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade420to421.java b/engine/schema/src/com/cloud/upgrade/dao/Upgrade420to421.java index c3a6b0688a..a0093f8fe4 100644 --- a/engine/schema/src/com/cloud/upgrade/dao/Upgrade420to421.java +++ b/engine/schema/src/com/cloud/upgrade/dao/Upgrade420to421.java @@ -23,6 +23,7 @@ import java.sql.ResultSet; import java.sql.SQLException; +import com.cloud.hypervisor.Hypervisor; import org.apache.log4j.Logger; import com.cloud.utils.exception.CloudRuntimeException; @@ -64,10 +65,12 @@ public File[] getCleanupScripts() { @Override public void performDataMigration(Connection conn) { upgradeResourceCount(conn); - updateCpuOverprovisioning(conn); + updateOverprovisioningPerVm(conn); } - private void updateCpuOverprovisioning(Connection conn) { + + + private void updateOverprovisioningPerVm(Connection conn) { PreparedStatement pstmt1 = null; PreparedStatement pstmt2 = null; PreparedStatement pstmt3 = null; @@ -79,28 +82,49 @@ private void updateCpuOverprovisioning(Connection conn) { try { pstmt1 = conn.prepareStatement("select value from `cloud`.`configuration` where name='cpu.overprovisioning.factor'"); result1 = pstmt1.executeQuery(); - String overprov = "1"; - if (result1.next()) { - overprov = result1.getString(1); + String cpuoverprov = "1"; + if(result1.next()){ + cpuoverprov = result1.getString(1); + } + pstmt1 = conn.prepareStatement("select value from `cloud`.`configuration` where name='mem.overprovisioning.factor'"); + result1 = pstmt1.executeQuery(); + String memoverprov = "1"; + if(result1.next()){ + memoverprov = result1.getString(1); } + // Need to populate only when overprovisioning factor doesn't pre exist. s_logger.debug("Starting updating user_vm_details with cpu/memory overprovisioning factors"); - pstmt2 = - conn.prepareStatement("select id from `cloud`.`vm_instance` where removed is null and id not in (select vm_id from `cloud`.`user_vm_details` where name='cpuOvercommitRatio')"); + pstmt2 = conn.prepareStatement("select id, hypervisor_type from `cloud`.`vm_instance` where removed is null and id not in (select vm_id from `cloud`.`user_vm_details` where name='cpuOvercommitRatio')"); pstmt3 = conn.prepareStatement("INSERT IGNORE INTO cloud.user_vm_details (vm_id, name, value) VALUES (?, ?, ?)"); result2 = pstmt2.executeQuery(); while (result2.next()) { - //For cpu - pstmt3.setLong(1, result2.getLong(1)); - pstmt3.setString(2, "cpuOvercommitRatio"); - pstmt3.setString(3, overprov); - pstmt3.executeUpdate(); + String hypervisor_type = result2.getString(2); + if (hypervisor_type.equalsIgnoreCase(Hypervisor.HypervisorType.VMware.name())) { + //For cpu + pstmt3.setLong(1, result2.getLong(1)); + pstmt3.setString(2, "cpuOvercommitRatio"); + pstmt3.setString(3, cpuoverprov); + pstmt3.executeUpdate(); + + // For memory + pstmt3.setLong(1, result2.getLong(1)); + pstmt3.setString(2, "memoryOvercommitRatio"); + pstmt3.setString(3, memoverprov); // memory overprovisioning was used to reserve memory in case of VMware. + pstmt3.executeUpdate(); + } else { + //For cpu + pstmt3.setLong(1, result2.getLong(1)); + pstmt3.setString(2, "cpuOvercommitRatio"); + pstmt3.setString(3, cpuoverprov); + pstmt3.executeUpdate(); - // For memory - pstmt3.setLong(1, result2.getLong(1)); - pstmt3.setString(2, "memoryOvercommitRatio"); - pstmt3.setString(3, "1"); // memory overprovisioning didn't exist earlier. - pstmt3.executeUpdate(); + // For memory + pstmt3.setLong(1, result2.getLong(1)); + pstmt3.setString(2, "memoryOvercommitRatio"); + pstmt3.setString(3, "1"); // memory overprovisioning didn't exist earlier. + pstmt3.executeUpdate(); + } } s_logger.debug("Done updating user_vm_details with cpu/memory overprovisioning factors"); @@ -108,13 +132,23 @@ private void updateCpuOverprovisioning(Connection conn) { throw new CloudRuntimeException("Unable to update cpu/memory overprovisioning factors", e); } finally { try { - if (pstmt1 != null) + if (pstmt1 != null && !pstmt1.isClosed()) { pstmt1.close(); - if (pstmt2 != null) + } + if (pstmt2 != null && !pstmt2.isClosed()) { pstmt2.close(); - if (pstmt3 != null) + } + if (pstmt3 != null && !pstmt3.isClosed()) { pstmt3.close(); - } catch (SQLException e) { + } + if (result1 != null) { + result1.close(); + } + if (result2 != null) { + result2.close(); + } + }catch (SQLException e){ + } } diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade421to430.java b/engine/schema/src/com/cloud/upgrade/dao/Upgrade421to430.java index 7e26132d9e..50822a35a4 100644 --- a/engine/schema/src/com/cloud/upgrade/dao/Upgrade421to430.java +++ b/engine/schema/src/com/cloud/upgrade/dao/Upgrade421to430.java @@ -116,8 +116,6 @@ private void upgradeMemoryOfSsvmOffering(Connection conn) { } private void encryptLdapConfigParams(Connection conn) { - PreparedStatement pstmt = null; - String[][] ldapParams = { {"ldap.user.object", "inetOrgPerson", "Sets the object type of users within LDAP"}, {"ldap.username.attribute", "uid", "Sets the username attribute used within LDAP"}, {"ldap.email.attribute", "mail", "Sets the email attribute used within LDAP"}, {"ldap.firstname.attribute", "givenname", "Sets the firstname attribute used within LDAP"}, @@ -129,77 +127,82 @@ private void encryptLdapConfigParams(Connection conn) { + "?) ON DUPLICATE KEY UPDATE category='Secure';"; try { - - for (String[] ldapParam : ldapParams) { - String name = ldapParam[0]; - String value = ldapParam[1]; - String desc = ldapParam[2]; - String encryptedValue = DBEncryptionUtil.encrypt(value); - pstmt = conn.prepareStatement(insertSql); - pstmt.setString(1, name); - pstmt.setBytes(2, encryptedValue.getBytes("UTF-8")); - pstmt.setString(3, desc); - pstmt.executeUpdate(); + String port; + int portNumber = 0; + String hostname = null; + try ( PreparedStatement pstmt = conn.prepareStatement(insertSql);) { + for (String[] ldapParam : ldapParams) { + String name = ldapParam[0]; + String value = ldapParam[1]; + String desc = ldapParam[2]; + String encryptedValue = DBEncryptionUtil.encrypt(value); + pstmt.setString(1, name); + pstmt.setBytes(2, encryptedValue.getBytes("UTF-8")); + pstmt.setString(3, desc); + pstmt.executeUpdate(); + } + }catch (Exception e) { + s_logger.error("encryptLdapConfigParams:Exception:"+e.getMessage()); + throw new CloudRuntimeException("encryptLdapConfigParams:Exception:"+e.getMessage(), e); } - /** * if encrypted, decrypt the ldap hostname and port and then update as they are not encrypted now. */ - pstmt = conn.prepareStatement("SELECT conf.value FROM `cloud`.`configuration` conf WHERE conf.name='ldap.hostname'"); - ResultSet resultSet = pstmt.executeQuery(); - String hostname = null; - String port; - int portNumber = 0; - if (resultSet.next()) { - hostname = DBEncryptionUtil.decrypt(resultSet.getString(1)); - } - - pstmt = conn.prepareStatement("SELECT conf.value FROM `cloud`.`configuration` conf WHERE conf.name='ldap.port'"); - resultSet = pstmt.executeQuery(); - if (resultSet.next()) { - port = DBEncryptionUtil.decrypt(resultSet.getString(1)); - if (StringUtils.isNotBlank(port)) { - portNumber = Integer.valueOf(port); + try(PreparedStatement sel_ldap_hostname_pstmt = conn.prepareStatement("SELECT conf.value FROM `cloud`.`configuration` conf WHERE conf.name='ldap.hostname'"); + ResultSet resultSet = sel_ldap_hostname_pstmt.executeQuery();) { + if (resultSet.next()) { + hostname = DBEncryptionUtil.decrypt(resultSet.getString(1)); } + }catch (Exception e) { + s_logger.error("encryptLdapConfigParams:Exception:"+e.getMessage()); + throw new CloudRuntimeException("encryptLdapConfigParams:Exception:"+e.getMessage(), e); } - if (StringUtils.isNotBlank(hostname)) { - pstmt = conn.prepareStatement("INSERT INTO `cloud`.`ldap_configuration`(hostname, port) VALUES(?,?)"); - pstmt.setString(1, hostname); - if (portNumber != 0) { - pstmt.setInt(2, portNumber); - } else { - pstmt.setNull(2, Types.INTEGER); + try( PreparedStatement sel_ldap_port_pstmt = conn.prepareStatement("SELECT conf.value FROM `cloud`.`configuration` conf WHERE conf.name='ldap.port'"); + ResultSet resultSet = sel_ldap_port_pstmt.executeQuery();) + { + if (resultSet.next()) { + port = DBEncryptionUtil.decrypt(resultSet.getString(1)); + if (StringUtils.isNotBlank(port)) { + portNumber = Integer.valueOf(port); + } } - pstmt.executeUpdate(); + }catch (Exception e) { + s_logger.error("encryptLdapConfigParams:Exception:"+e.getMessage()); + throw new CloudRuntimeException("encryptLdapConfigParams:Exception:"+e.getMessage(), e); } - } catch (SQLException e) { - throw new CloudRuntimeException("Unable to insert ldap configuration values ", e); - } catch (UnsupportedEncodingException e) { - throw new CloudRuntimeException("Unable to insert ldap configuration values ", e); - } finally { - try { - if (pstmt != null) { - pstmt.close(); + if (StringUtils.isNotBlank(hostname)) { + try(PreparedStatement insert_pstmt = conn.prepareStatement("INSERT INTO `cloud`.`ldap_configuration`(hostname, port) VALUES(?,?)");) + { + insert_pstmt.setString(1, hostname); + if (portNumber != 0) { + insert_pstmt.setInt(2, portNumber); + } else { + insert_pstmt.setNull(2, Types.INTEGER); + } + insert_pstmt.executeUpdate(); + }catch (Exception e) { + s_logger.error("encryptLdapConfigParams:Exception:"+e.getMessage()); + throw new CloudRuntimeException("encryptLdapConfigParams:Exception:"+e.getMessage(), e); } - } catch (SQLException e) { } + } catch (Exception e) { + s_logger.error("encryptLdapConfigParams:Exception:"+e.getMessage()); + throw new CloudRuntimeException("encryptLdapConfigParams:Exception:"+e.getMessage(), e); } s_logger.debug("Done encrypting ldap Config values"); } private void updateSystemVmTemplates(Connection conn) { - PreparedStatement pstmt = null; - ResultSet rs = null; s_logger.debug("Updating System Vm template IDs"); try{ //Get all hypervisors in use Set hypervisorsListInUse = new HashSet(); - try { - pstmt = conn.prepareStatement("select distinct(hypervisor_type) from `cloud`.`cluster` where removed is null"); - rs = pstmt.executeQuery(); + try(PreparedStatement pstmt = conn.prepareStatement("select distinct(hypervisor_type) from `cloud`.`cluster` where removed is null"); + ResultSet rs = pstmt.executeQuery(); + ) { while(rs.next()){ switch (Hypervisor.HypervisorType.getType(rs.getString(1))) { case XenServer: hypervisorsListInUse.add(Hypervisor.HypervisorType.XenServer); @@ -214,8 +217,9 @@ private void updateSystemVmTemplates(Connection conn) { break; } } - } catch (SQLException e) { - throw new CloudRuntimeException("Error while listing hypervisors in use", e); + } catch (Exception e) { + s_logger.error("updateSystemVmTemplates:Exception:"+e.getMessage()); + throw new CloudRuntimeException("updateSystemVmTemplates:Exception:"+e.getMessage(), e); } Map NewTemplateNameList = new HashMap(){ @@ -256,77 +260,98 @@ private void updateSystemVmTemplates(Connection conn) { for (Map.Entry hypervisorAndTemplateName : NewTemplateNameList.entrySet()){ s_logger.debug("Updating " + hypervisorAndTemplateName.getKey() + " System Vms"); - try { - //Get 4.3.0 system Vm template Id for corresponding hypervisor - pstmt = conn.prepareStatement("select id from `cloud`.`vm_template` where name = ? and removed is null order by id desc limit 1"); - pstmt.setString(1, hypervisorAndTemplateName.getValue()); - rs = pstmt.executeQuery(); - if(rs.next()){ - long templateId = rs.getLong(1); - rs.close(); - pstmt.close(); -// // Mark the old system templates as removed + try (PreparedStatement pstmt = conn.prepareStatement("select id from `cloud`.`vm_template` where name = ? and removed is null order by id desc limit 1");) + { + //Get 4.3.0 system Vm template Id for corresponding hypervisor + long templateId = -1; + pstmt.setString(1, hypervisorAndTemplateName.getValue()); + try(ResultSet rs = pstmt.executeQuery();) + { + if(rs.next()) { + templateId = rs.getLong(1); + } + }catch (Exception e) + { + s_logger.error("updateSystemVmTemplates:Exception:"+e.getMessage()); + throw new CloudRuntimeException("updateSystemVmTemplates:Exception:"+e.getMessage(), e); + } +// // Mark the old system templates as removed // pstmt = conn.prepareStatement("UPDATE `cloud`.`vm_template` SET removed = now() WHERE hypervisor_type = ? AND type = 'SYSTEM' AND removed is null"); // pstmt.setString(1, hypervisorAndTemplateName.getKey().toString()); // pstmt.executeUpdate(); // pstmt.close(); // change template type to SYSTEM - pstmt = conn.prepareStatement("update `cloud`.`vm_template` set type='SYSTEM' where id = ?"); - pstmt.setLong(1, templateId); - pstmt.executeUpdate(); - pstmt.close(); - // update templete ID of system Vms - pstmt = conn.prepareStatement("update `cloud`.`vm_instance` set vm_template_id = ? where type <> 'User' and hypervisor_type = ?"); - pstmt.setLong(1, templateId); - pstmt.setString(2, hypervisorAndTemplateName.getKey().toString()); - pstmt.executeUpdate(); - pstmt.close(); - // Change value of global configuration parameter router.template.* for the corresponding hypervisor - pstmt = conn.prepareStatement("UPDATE `cloud`.`configuration` SET value = ? WHERE name = ?"); - pstmt.setString(1, hypervisorAndTemplateName.getValue()); - pstmt.setString(2, routerTemplateConfigurationNames.get(hypervisorAndTemplateName.getKey())); - pstmt.executeUpdate(); - pstmt.close(); - } else { - if (hypervisorsListInUse.contains(hypervisorAndTemplateName.getKey())){ - throw new CloudRuntimeException("4.3.0 " + hypervisorAndTemplateName.getKey() + " SystemVm template not found. Cannot upgrade system Vms"); + if (templateId != -1) + { + try(PreparedStatement templ_type_pstmt = conn.prepareStatement("update `cloud`.`vm_template` set type='SYSTEM' where id = ?");) + { + templ_type_pstmt.setLong(1, templateId); + templ_type_pstmt.executeUpdate(); + } + catch (Exception e) + { + s_logger.error("updateSystemVmTemplates:Exception:"+e.getMessage()); + throw new CloudRuntimeException("updateSystemVmTemplates:Exception:"+e.getMessage(), e); + } + // update templete ID of system Vms + try(PreparedStatement update_templ_id_pstmt = conn.prepareStatement("update `cloud`.`vm_instance` set vm_template_id = ? where type <> 'User' and hypervisor_type = ?");) + { + update_templ_id_pstmt.setLong(1, templateId); + update_templ_id_pstmt.setString(2, hypervisorAndTemplateName.getKey().toString()); + update_templ_id_pstmt.executeUpdate(); + }catch (Exception e) + { + s_logger.error("updateSystemVmTemplates:Exception:"+e.getMessage()); + throw new CloudRuntimeException("updateSystemVmTemplates:Exception:"+e.getMessage(), e); + } + + // Change value of global configuration parameter router.template.* for the corresponding hypervisor + try(PreparedStatement update_pstmt = conn.prepareStatement("UPDATE `cloud`.`configuration` SET value = ? WHERE name = ?");) { + update_pstmt.setString(1, hypervisorAndTemplateName.getValue()); + update_pstmt.setString(2, routerTemplateConfigurationNames.get(hypervisorAndTemplateName.getKey())); + update_pstmt.executeUpdate(); + }catch (Exception e) + { + s_logger.error("updateSystemVmTemplates:Exception:"+e.getMessage()); + throw new CloudRuntimeException("updateSystemVmTemplates:Exception:"+e.getMessage(), e); + } + } else { - s_logger.warn("4.3.0 " + hypervisorAndTemplateName.getKey() + " SystemVm template not found. " + hypervisorAndTemplateName.getKey() + " hypervisor is not used, so not failing upgrade"); - // Update the latest template URLs for corresponding hypervisor - pstmt = conn.prepareStatement("UPDATE `cloud`.`vm_template` SET url = ? , checksum = ? WHERE hypervisor_type = ? AND type = 'SYSTEM' AND removed is null order by id desc limit 1"); - pstmt.setString(1, newTemplateUrl.get(hypervisorAndTemplateName.getKey())); - pstmt.setString(2, newTemplateChecksum.get(hypervisorAndTemplateName.getKey())); - pstmt.setString(3, hypervisorAndTemplateName.getKey().toString()); - pstmt.executeUpdate(); - pstmt.close(); + if (hypervisorsListInUse.contains(hypervisorAndTemplateName.getKey())){ + throw new CloudRuntimeException("4.3.0 " + hypervisorAndTemplateName.getKey() + " SystemVm template not found. Cannot upgrade system Vms"); + } else { + s_logger.warn("4.3.0 " + hypervisorAndTemplateName.getKey() + " SystemVm template not found. " + hypervisorAndTemplateName.getKey() + " hypervisor is not used, so not failing upgrade"); + // Update the latest template URLs for corresponding hypervisor + try(PreparedStatement update_templ_url_pstmt = conn.prepareStatement("UPDATE `cloud`.`vm_template` SET url = ? , checksum = ? WHERE hypervisor_type = ? AND type = 'SYSTEM' AND removed is null order by id desc limit 1");) { + update_templ_url_pstmt.setString(1, newTemplateUrl.get(hypervisorAndTemplateName.getKey())); + update_templ_url_pstmt.setString(2, newTemplateChecksum.get(hypervisorAndTemplateName.getKey())); + update_templ_url_pstmt.setString(3, hypervisorAndTemplateName.getKey().toString()); + update_templ_url_pstmt.executeUpdate(); + }catch (Exception e) + { + s_logger.error("updateSystemVmTemplates:Exception:"+e.getMessage()); + throw new CloudRuntimeException("updateSystemVmTemplates:Exception:"+e.getMessage(), e); + } + } } - } } catch (SQLException e) { + s_logger.error("updateSystemVmTemplates:Exception:"+e.getMessage()); throw new CloudRuntimeException("Error while updating "+ hypervisorAndTemplateName.getKey() +" systemVm template", e); } } s_logger.debug("Updating System Vm Template IDs Complete"); - } finally { - try { - if (rs != null) { - rs.close(); - } - - if (pstmt != null) { - pstmt.close(); - } - } catch (SQLException e) { - } + } + catch (Exception e) { + s_logger.error("updateSystemVmTemplates:Exception:"+e.getMessage()); + throw new CloudRuntimeException("updateSystemVmTemplates:Exception:"+e.getMessage(), e); } } private void encryptImageStoreDetails(Connection conn) { s_logger.debug("Encrypting image store details"); - PreparedStatement pstmt = null; - ResultSet rs = null; - try { - pstmt = conn.prepareStatement("select id, value from `cloud`.`image_store_details` where name = 'key' or name = 'secretkey'"); - rs = pstmt.executeQuery(); + try (PreparedStatement sel_image_store_det_pstmt = conn.prepareStatement("select id, value from `cloud`.`image_store_details` where name = 'key' or name = 'secretkey'"); + ResultSet rs = sel_image_store_det_pstmt.executeQuery();) + { while (rs.next()) { long id = rs.getLong(1); String value = rs.getString(2); @@ -334,26 +359,21 @@ private void encryptImageStoreDetails(Connection conn) { continue; } String encryptedValue = DBEncryptionUtil.encrypt(value); - pstmt = conn.prepareStatement("update `cloud`.`image_store_details` set value=? where id=?"); - pstmt.setBytes(1, encryptedValue.getBytes("UTF-8")); - pstmt.setLong(2, id); - pstmt.executeUpdate(); + try( PreparedStatement update_image_store_det_pstmt = conn.prepareStatement("update `cloud`.`image_store_details` set value=? where id=?");) { + update_image_store_det_pstmt.setBytes(1, encryptedValue.getBytes("UTF-8")); + update_image_store_det_pstmt.setLong(2, id); + update_image_store_det_pstmt.executeUpdate(); + }catch (UnsupportedEncodingException e) { + s_logger.error("encryptImageStoreDetails:Exception:" + e.getMessage()); + throw new CloudRuntimeException("encryptImageStoreDetails:Exception:" + e.getMessage(),e); + } } } catch (SQLException e) { + s_logger.error("encryptImageStoreDetails:Exception:"+e.getMessage()); throw new CloudRuntimeException("Unable encrypt image_store_details values ", e); - } catch (UnsupportedEncodingException e) { + } catch (Exception e) { + s_logger.error("encryptImageStoreDetails:Exception:"+e.getMessage()); throw new CloudRuntimeException("Unable encrypt image_store_details values ", e); - } finally { - try { - if (rs != null) { - rs.close(); - } - - if (pstmt != null) { - pstmt.close(); - } - } catch (SQLException e) { - } } s_logger.debug("Done encrypting image_store_details"); } diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade430to440.java b/engine/schema/src/com/cloud/upgrade/dao/Upgrade430to440.java index 922a892be0..51494e7aff 100644 --- a/engine/schema/src/com/cloud/upgrade/dao/Upgrade430to440.java +++ b/engine/schema/src/com/cloud/upgrade/dao/Upgrade430to440.java @@ -26,6 +26,7 @@ import org.apache.log4j.Logger; import com.cloud.network.Network; +import com.cloud.network.Networks.BroadcastDomainType; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.script.Script; @@ -59,73 +60,45 @@ public File[] getPrepareScripts() { @Override public void performDataMigration(Connection conn) { - populateIAMGroupAccountMap(conn); secondaryIpsAccountAndDomainIdsUpdate(conn); + moveCidrsToTheirOwnTable(conn); + addExtractTemplateAndVolumeColumns(conn); + updateVlanUris(conn); } - // populate iam_group_account_map table for existing accounts - private void populateIAMGroupAccountMap(Connection conn) { - PreparedStatement acctInsert = null; - PreparedStatement acctQuery = null; - ResultSet rs = null; - - s_logger.debug("Populating iam_group_account_map table for existing accounts..."); - try { - acctInsert = conn - .prepareStatement("INSERT INTO `cloud`.`iam_group_account_map` (group_id, account_id, created) values(?, ?, Now())"); - acctQuery = conn - .prepareStatement("select id, type from `cloud`.`account` where removed is null"); - rs = acctQuery.executeQuery(); - - while (rs.next()) { - Long acct_id = rs.getLong("id"); - short type = rs.getShort("type"); - - // insert entry in iam_group_account_map table - acctInsert.setLong(1, type + 1); - acctInsert.setLong(2, acct_id); - acctInsert.executeUpdate(); + private void addExtractTemplateAndVolumeColumns(Connection conn) { + + try (PreparedStatement selectTemplateInfostmt = conn.prepareStatement("SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = 'cloud' AND TABLE_NAME = 'template_store_ref' AND COLUMN_NAME = 'download_url_created'"); + ResultSet templateInfoResults = selectTemplateInfostmt.executeQuery(); + PreparedStatement addDownloadUrlCreatedToTemplateStorerefstatement = conn.prepareStatement("ALTER TABLE `cloud`.`template_store_ref` ADD COLUMN `download_url_created` datetime"); + PreparedStatement addDownloadUrlToTemplateStorerefstatement = conn.prepareStatement("ALTER TABLE `cloud`.`template_store_ref` ADD COLUMN `download_url` varchar(255)"); + PreparedStatement selectVolumeInfostmt = conn.prepareStatement("SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = 'cloud' AND TABLE_NAME = 'volume_store_ref' AND COLUMN_NAME = 'download_url_created'"); + ResultSet volumeInfoResults = selectVolumeInfostmt.executeQuery(); + PreparedStatement addDownloadUrlCreatedToVolumeStorerefstatement = conn.prepareStatement("ALTER TABLE `cloud`.`volume_store_ref` ADD COLUMN `download_url_created` datetime"); + ) { + + // Add download_url_created, download_url to template_store_ref + if (!templateInfoResults.next()) { + addDownloadUrlCreatedToTemplateStorerefstatement.executeUpdate(); + addDownloadUrlToTemplateStorerefstatement.executeUpdate(); } - } catch (SQLException e) { - String msg = "Unable to populate iam_group_account_map for existing accounts." + e.getMessage(); - s_logger.error(msg); - throw new CloudRuntimeException(msg, e); - } finally { - try { - if (rs != null) { - rs.close(); - } - if (acctInsert != null) { - acctInsert.close(); - } - if (acctQuery != null) { - acctQuery.close(); - } - } catch (SQLException e) { + // Add download_url_created to volume_store_ref - note download_url already exists + if (!volumeInfoResults.next()) { + addDownloadUrlCreatedToVolumeStorerefstatement.executeUpdate(); } + + } catch (SQLException e) { + throw new CloudRuntimeException("Adding columns for Extract Template And Volume functionality failed"); } - s_logger.debug("Completed populate iam_group_account_map for existing accounts."); } - - private void secondaryIpsAccountAndDomainIdsUpdate(Connection conn) { - PreparedStatement pstmt = null; - PreparedStatement pstmtVm = null; - PreparedStatement pstmtNw = null; - PreparedStatement pstmtUpdate = null; - - ResultSet rs1 = null; - ResultSet vmRs = null; - ResultSet networkRs = null; - String secondIpsSql = "SELECT id, vmId, network_id, account_id, domain_id, ip4_address FROM `cloud`.`nic_secondary_ips`"; - try { - pstmt = conn.prepareStatement(secondIpsSql); - rs1 = pstmt.executeQuery(); - + try (PreparedStatement pstmt = conn.prepareStatement(secondIpsSql); + ResultSet rs1 = pstmt.executeQuery(); + ) { while(rs1.next()) { long ipId = rs1.getLong(1); long vmId = rs1.getLong(2); @@ -134,119 +107,126 @@ private void secondaryIpsAccountAndDomainIdsUpdate(Connection conn) { long domainId = rs1.getLong(5); String ipAddr = rs1.getString(6); - pstmtVm = conn.prepareStatement("SELECT account_id, domain_id FROM `cloud`.`vm_instance` where id = ?"); - pstmtVm.setLong(1,vmId); - - vmRs = pstmtVm.executeQuery(); - - if (vmRs.next()) { - long vmAccountId = vmRs.getLong(1); - long vmDomainId = vmRs.getLong(2); - - if (vmAccountId != accountId && vmAccountId != domainId) { - // update the secondary ip accountid and domainid to vm accountid domainid - // check the network type. If network is shared accountid doaminid needs to be updated in - // in both nic_secondary_ips table and user_ip_address table - - pstmtUpdate = conn.prepareStatement("UPDATE `cloud`.`nic_secondary_ips` SET account_id = ?, domain_id= ? WHERE id = ?"); - pstmtUpdate.setLong(1, vmAccountId); - pstmtUpdate.setLong(2,vmDomainId); - pstmtUpdate.setLong(3,ipId); - pstmtUpdate.executeUpdate(); - pstmtUpdate.close(); - - pstmtNw = conn.prepareStatement("SELECT guest_type FROM `cloud`.`networks` where id = ?"); - pstmtNw.setLong(1,networkId); - - networkRs = pstmtNw.executeQuery(); - if (networkRs.next()) { - String guesttype = networkRs.getString(1); - - if (guesttype.equals(Network.GuestType.Shared.toString())) { - pstmtUpdate = conn.prepareStatement("UPDATE `cloud`.`user_ip_address` SET account_id = ?, domain_id= ? WHERE public_ip_address = ?"); - pstmtUpdate.setLong(1,vmAccountId); - pstmtUpdate.setLong(2,vmDomainId); - pstmtUpdate.setString(3,ipAddr); - pstmtUpdate.executeUpdate(); - pstmtUpdate.close(); - - } - } - networkRs.close(); - networkRs = null; - pstmtNw.close(); - pstmtNw = null; + try(PreparedStatement pstmtVm = conn.prepareStatement("SELECT account_id, domain_id FROM `cloud`.`vm_instance` where id = ?");) { + pstmtVm.setLong(1,vmId); + + try(ResultSet vmRs = pstmtVm.executeQuery();) { + + if (vmRs.next()) { + long vmAccountId = vmRs.getLong(1); + long vmDomainId = vmRs.getLong(2); + + if (vmAccountId != accountId && vmAccountId != domainId) { + // update the secondary ip accountid and domainid to vm accountid domainid + // check the network type. If network is shared accountid doaminid needs to be updated in + // in both nic_secondary_ips table and user_ip_address table + + try(PreparedStatement pstmtUpdate = conn.prepareStatement("UPDATE `cloud`.`nic_secondary_ips` SET account_id = ?, domain_id= ? WHERE id = ?");) { + pstmtUpdate.setLong(1, vmAccountId); + pstmtUpdate.setLong(2,vmDomainId); + pstmtUpdate.setLong(3,ipId); + pstmtUpdate.executeUpdate(); + } catch (SQLException e) { + throw new CloudRuntimeException("Exception while updating secondary ip for nic " + ipId, e); + } + + try(PreparedStatement pstmtNw = conn.prepareStatement("SELECT guest_type FROM `cloud`.`networks` where id = ?");) { + pstmtNw.setLong(1,networkId); + + try(ResultSet networkRs = pstmtNw.executeQuery();) { + if (networkRs.next()) { + String guesttype = networkRs.getString(1); + + if (guesttype.equals(Network.GuestType.Shared.toString())) { + try(PreparedStatement pstmtUpdate = conn.prepareStatement("UPDATE `cloud`.`user_ip_address` SET account_id = ?, domain_id= ? WHERE public_ip_address = ?");) { + pstmtUpdate.setLong(1,vmAccountId); + pstmtUpdate.setLong(2,vmDomainId); + pstmtUpdate.setString(3,ipAddr); + pstmtUpdate.executeUpdate(); + } catch (SQLException e) { + throw new CloudRuntimeException("Exception while updating public ip " + ipAddr, e); + } + } + } + } catch (SQLException e) { + throw new CloudRuntimeException("Exception while retrieving guest type for network " + networkId, e); + } + + } catch (SQLException e) { + throw new CloudRuntimeException("Exception while retrieving guest type for network " + networkId, e); + } + } // if + } // if } - } //if - - pstmtVm.close(); - pstmtVm = null; - vmRs.close(); - vmRs = null; + } } // while - - } catch (SQLException e) { throw new CloudRuntimeException("Exception while Moving private zone information to dedicated resources", e); - } finally { + } + s_logger.debug("Done updating vm nic secondary ip account and domain ids"); + } - if (pstmt != null) { - try { - pstmt.close(); - } catch (SQLException e) { - } - } + private void moveCidrsToTheirOwnTable(Connection conn) { + s_logger.debug("Moving network acl item cidrs to a row per cidr"); + String networkAclItemSql = "SELECT id, cidr FROM `cloud`.`network_acl_item`"; + String networkAclItemCidrSql = "INSERT INTO `cloud`.`network_acl_item_cidrs` (network_acl_item_id, cidr) VALUES (?,?)"; - if (rs1 != null) { - try { - rs1.close(); - } catch (SQLException e) { - } - } - + try (PreparedStatement pstmtItem = conn.prepareStatement(networkAclItemSql); + ResultSet rsItems = pstmtItem.executeQuery(); + PreparedStatement pstmtCidr = conn.prepareStatement(networkAclItemCidrSql); + ) { - if (pstmtVm != null) { - try { - pstmtVm.close(); - } catch (SQLException e) { + // for each network acl item + while(rsItems.next()) { + long itemId = rsItems.getLong(1); + // get the source cidr list + String cidrList = rsItems.getString(2); + s_logger.debug("Moving '" + cidrList + "' to a row per cidr"); + // split it + String[] cidrArray = cidrList.split(","); + // insert a record per cidr + pstmtCidr.setLong(1, itemId); + for (String cidr : cidrArray) { + pstmtCidr.setString(2, cidr); + pstmtCidr.executeUpdate(); } } + } catch (SQLException e) { + throw new CloudRuntimeException("Exception while Moving network acl item cidrs to a row per cidr", e); + } + s_logger.debug("Done moving network acl item cidrs to a row per cidr"); + } - if (vmRs != null) { - try { - vmRs.close(); - } catch (SQLException e) { - } - } - - - - if (pstmtNw != null) { - try { - pstmtNw.close(); + private void updateVlanUris(Connection conn) { + s_logger.debug("updating vlan URIs"); + try(PreparedStatement selectstatement = conn.prepareStatement("SELECT id, vlan_id FROM `cloud`.`vlan` where vlan_id not like '%:%'"); + ResultSet results = selectstatement.executeQuery()) { - } catch (SQLException e) { + while (results.next()) { + long id = results.getLong(1); + String vlan = results.getString(2); + if (vlan == null || "".equals(vlan)) { + continue; } - } - - - if (networkRs != null) { - try { - networkRs.close(); + String vlanUri = BroadcastDomainType.Vlan.toUri(vlan).toString(); + try(PreparedStatement updatestatement = conn.prepareStatement("update `cloud`.`vlan` set vlan_id=? where id=?");) + { + updatestatement.setString(1, vlanUri); + updatestatement.setLong(2, id); + updatestatement.executeUpdate(); } catch (SQLException e) { + throw new CloudRuntimeException("Unable to update vlan URI " + vlanUri + " for vlan record " + id, e); } } + } catch (SQLException e) { + throw new CloudRuntimeException("Unable to update vlan URIs ", e); } - s_logger.debug("Done updating vm nic secondary ip account and domain ids"); + s_logger.debug("Done updateing vlan URIs"); } - - - - @Override public File[] getCleanupScripts() { String script = Script.findScript("", "db/schema-430to440-cleanup.sql"); diff --git a/engine/schema/src/com/cloud/usage/UsageVMInstanceVO.java b/engine/schema/src/com/cloud/usage/UsageVMInstanceVO.java index 06d4876c1b..1e7b424050 100644 --- a/engine/schema/src/com/cloud/usage/UsageVMInstanceVO.java +++ b/engine/schema/src/com/cloud/usage/UsageVMInstanceVO.java @@ -86,6 +86,23 @@ public UsageVMInstanceVO(int usageType, long zoneId, long accountId, long vmInst this.endDate = endDate; } + public UsageVMInstanceVO(int usageType, long zoneId, long accountId, long vmInstanceId, String vmName, long serviceOfferingId, long templateId, + Long cpuSpeed, Long cpuCores, Long memory, String hypervisorType, Date startDate, Date endDate) { + this.usageType = usageType; + this.zoneId = zoneId; + this.accountId = accountId; + this.vmInstanceId = vmInstanceId; + this.vmName = vmName; + this.serviceOfferingId = serviceOfferingId; + this.templateId = templateId; + this.cpuSpeed = cpuSpeed; + this.cpuCores = cpuCores; + this.memory = memory; + this.hypervisorType = hypervisorType; + this.startDate = startDate; + this.endDate = endDate; + } + public int getUsageType() { return usageType; } diff --git a/engine/schema/src/com/cloud/usage/UsageVO.java b/engine/schema/src/com/cloud/usage/UsageVO.java index 67014ef4fd..c46abb3a9b 100644 --- a/engine/schema/src/com/cloud/usage/UsageVO.java +++ b/engine/schema/src/com/cloud/usage/UsageVO.java @@ -65,6 +65,15 @@ public class UsageVO implements Usage, InternalIdentity { @Column(name = "vm_name") private String vmName = null; + @Column(name = "cpu_cores") + private Long cpuCores = null; + + @Column(name = "memory") + private Long memory = null; + + @Column(name = "cpu_speed") + private Long cpuSpeed = null; + @Column(name = "offering_id") private Long offeringId = null; @@ -171,6 +180,28 @@ public UsageVO(Long zoneId, Long accountId, Long domainId, String description, S this.endDate = endDate; } + public UsageVO(Long zoneId, Long accountId, Long domainId, String description, String usageDisplay, int usageType, Double rawUsage, Long vmId, String vmName, + Long cpuCores, Long cpuSpeed, Long memory, Long offeringId, Long templateId, Long usageId, Date startDate, Date endDate, String type) { + this.zoneId = zoneId; + this.accountId = accountId; + this.domainId = domainId; + this.description = description; + this.usageDisplay = usageDisplay; + this.usageType = usageType; + this.rawUsage = rawUsage; + this.vmInstanceId = vmId; + this.vmName = vmName; + this.cpuCores = cpuCores; + this.cpuSpeed = cpuSpeed; + this.memory = memory; + this.offeringId = offeringId; + this.templateId = templateId; + this.usageId = usageId; + this.type = type; + this.startDate = startDate; + this.endDate = endDate; + } + //IPAddress Usage public UsageVO(Long zoneId, Long accountId, Long domainId, String description, String usageDisplay, int usageType, Double rawUsage, Long usageId, long size, String type, Date startDate, Date endDate) { @@ -238,6 +269,21 @@ public String getVmName() { return vmName; } + @Override + public Long getCpuCores() { + return cpuCores; + } + + @Override + public Long getCpuSpeed() { + return cpuSpeed; + } + + @Override + public Long getMemory() { + return memory; + } + @Override public Long getOfferingId() { return offeringId; diff --git a/engine/schema/src/com/cloud/usage/dao/UsageVMInstanceDaoImpl.java b/engine/schema/src/com/cloud/usage/dao/UsageVMInstanceDaoImpl.java index b94e12f9c5..930ad89999 100644 --- a/engine/schema/src/com/cloud/usage/dao/UsageVMInstanceDaoImpl.java +++ b/engine/schema/src/com/cloud/usage/dao/UsageVMInstanceDaoImpl.java @@ -42,8 +42,8 @@ public class UsageVMInstanceDaoImpl extends GenericDaoBase= ?)))"; public UsageVMInstanceDaoImpl() { @@ -113,11 +113,23 @@ public List getUsageRecords(long accountId, Date startDate, D long r_accountId = rs.getLong(3); long r_vmId = rs.getLong(4); String r_vmName = rs.getString(5); - long r_soId = rs.getLong(6); - long r_tId = rs.getLong(7); - String hypervisorType = rs.getString(8); - String r_startDate = rs.getString(9); - String r_endDate = rs.getString(10); + Long r_cpuSpeed = rs.getLong(6); + if (rs.wasNull()) { + r_cpuSpeed = null; + } + Long r_cpuCores = rs.getLong(7); + if (rs.wasNull()) { + r_cpuCores = null; + } + Long r_memory = rs.getLong(8); + if (rs.wasNull()) { + r_memory = null; + } + long r_soId = rs.getLong(9); + long r_tId = rs.getLong(10); + String hypervisorType = rs.getString(11); + String r_startDate = rs.getString(12); + String r_endDate = rs.getString(13); Date instanceStartDate = null; Date instanceEndDate = null; if (r_startDate != null) { @@ -127,7 +139,7 @@ public List getUsageRecords(long accountId, Date startDate, D instanceEndDate = DateUtil.parseDateString(s_gmtTimeZone, r_endDate); } UsageVMInstanceVO usageInstance = - new UsageVMInstanceVO(r_usageType, r_zoneId, r_accountId, r_vmId, r_vmName, r_soId, r_tId, hypervisorType, instanceStartDate, instanceEndDate); + new UsageVMInstanceVO(r_usageType, r_zoneId, r_accountId, r_vmId, r_vmName, r_soId, r_tId, r_cpuSpeed, r_cpuCores, r_memory, hypervisorType, instanceStartDate, instanceEndDate); usageInstances.add(usageInstance); } } catch (Exception ex) { diff --git a/engine/schema/src/com/cloud/user/AccountVO.java b/engine/schema/src/com/cloud/user/AccountVO.java index 674cdb9101..0f5a0446e9 100644 --- a/engine/schema/src/com/cloud/user/AccountVO.java +++ b/engine/schema/src/com/cloud/user/AccountVO.java @@ -28,8 +28,6 @@ import javax.persistence.Id; import javax.persistence.Table; -import org.apache.cloudstack.acl.IAMEntityType; - import com.cloud.utils.db.GenericDao; @Entity @@ -190,7 +188,7 @@ public boolean isDefault() { } @Override - public IAMEntityType getEntityType() { - return IAMEntityType.Account; + public Class getEntityType() { + return Account.class; } } diff --git a/engine/schema/src/com/cloud/user/SSHKeyPairVO.java b/engine/schema/src/com/cloud/user/SSHKeyPairVO.java index 4dc03c45b0..fd7173ee7a 100644 --- a/engine/schema/src/com/cloud/user/SSHKeyPairVO.java +++ b/engine/schema/src/com/cloud/user/SSHKeyPairVO.java @@ -24,8 +24,6 @@ import javax.persistence.Table; import javax.persistence.Transient; -import org.apache.cloudstack.acl.IAMEntityType; - @Entity @Table(name = "ssh_keypairs") public class SSHKeyPairVO implements SSHKeyPair { @@ -117,7 +115,7 @@ public void setPrivateKey(String privateKey) { } @Override - public IAMEntityType getEntityType() { - return IAMEntityType.SSHKeyPair; + public Class getEntityType() { + return SSHKeyPair.class; } } diff --git a/engine/schema/src/com/cloud/user/dao/AccountDao.java b/engine/schema/src/com/cloud/user/dao/AccountDao.java index 2f737cd4a1..4c7ce8e31b 100644 --- a/engine/schema/src/com/cloud/user/dao/AccountDao.java +++ b/engine/schema/src/com/cloud/user/dao/AccountDao.java @@ -63,4 +63,13 @@ public interface AccountDao extends GenericDao { Account findActiveNonProjectAccount(String accountName, Long domainId); List getAccountIdsForDomains(List ids); + + /* + @Desc: Retrieves the DomainId for a given Account Id + @Input: id : Id of the Account + @Output: DomainId matching for the given Account Id. Returns -1 + in case of no match; + */ + long getDomainIdForGivenAccountId(long id); + } diff --git a/engine/schema/src/com/cloud/user/dao/AccountDaoImpl.java b/engine/schema/src/com/cloud/user/dao/AccountDaoImpl.java index 4bc23ed3ed..99bd7ee6d3 100755 --- a/engine/schema/src/com/cloud/user/dao/AccountDaoImpl.java +++ b/engine/schema/src/com/cloud/user/dao/AccountDaoImpl.java @@ -278,4 +278,20 @@ public List getAccountIdsForDomains(List domainIds) { return customSearch(sc, null); } + @Override + public long getDomainIdForGivenAccountId(long id) { + long domain_id = -1; + try { + AccountVO account_vo = findById(id); + domain_id = account_vo.getDomainId(); + } + catch (Exception e) { + s_logger.warn("getDomainIdForGivenAccountId: Exception :" + e.getMessage()); + } + finally { + return domain_id; + } + } + + } diff --git a/engine/schema/src/com/cloud/vm/InstanceGroupVO.java b/engine/schema/src/com/cloud/vm/InstanceGroupVO.java index 9b463d3428..395751b705 100644 --- a/engine/schema/src/com/cloud/vm/InstanceGroupVO.java +++ b/engine/schema/src/com/cloud/vm/InstanceGroupVO.java @@ -28,8 +28,6 @@ import javax.persistence.SecondaryTable; import javax.persistence.Table; -import org.apache.cloudstack.acl.IAMEntityType; - import com.cloud.utils.db.GenericDao; @Entity @@ -120,7 +118,7 @@ public Short getAccountType() { } @Override - public IAMEntityType getEntityType() { - return IAMEntityType.InstanceGroup; + public Class getEntityType() { + return InstanceGroup.class; } } diff --git a/engine/schema/src/com/cloud/vm/VMInstanceVO.java b/engine/schema/src/com/cloud/vm/VMInstanceVO.java index ddeebfeb75..90d13b2d2b 100644 --- a/engine/schema/src/com/cloud/vm/VMInstanceVO.java +++ b/engine/schema/src/com/cloud/vm/VMInstanceVO.java @@ -36,8 +36,6 @@ import javax.persistence.TemporalType; import javax.persistence.Transient; -import org.apache.cloudstack.acl.IAMEntityType; - import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.utils.db.Encrypt; import com.cloud.utils.db.GenericDao; @@ -185,7 +183,7 @@ public class VMInstanceVO implements VirtualMachine, FiniteStateObject details) { @Override public String toString() { if (toString == null) { - toString = new StringBuilder("VM[").append(type.toString()).append("|").append(hostName).append("]").toString(); + toString = new StringBuilder("VM[").append(type.toString()).append("|").append(getInstanceName()).append("]").toString(); } return toString; } @@ -506,8 +510,8 @@ public Boolean isDynamicallyScalable() { } @Override - public IAMEntityType getEntityType() { - return IAMEntityType.VirtualMachine; + public Class getEntityType() { + return VirtualMachine.class; } public VirtualMachine.PowerState getPowerState() { diff --git a/engine/schema/src/com/cloud/vm/dao/DomainRouterDao.java b/engine/schema/src/com/cloud/vm/dao/DomainRouterDao.java index e3f75fabd7..72ff8a91dd 100755 --- a/engine/schema/src/com/cloud/vm/dao/DomainRouterDao.java +++ b/engine/schema/src/com/cloud/vm/dao/DomainRouterDao.java @@ -108,6 +108,8 @@ public interface DomainRouterDao extends GenericDao { */ List listByStateAndNetworkType(State state, Network.GuestType type, long mgmtSrvrId); + List listByStateAndManagementServer(State state, long mgmtSrvrId); + List findByNetworkOutsideThePod(long networkId, long podId, State state, Role role); List listByNetworkAndPodAndRole(long networkId, long podId, Role role); diff --git a/engine/schema/src/com/cloud/vm/dao/DomainRouterDaoImpl.java b/engine/schema/src/com/cloud/vm/dao/DomainRouterDaoImpl.java index 6b62f56873..ea919ac536 100755 --- a/engine/schema/src/com/cloud/vm/dao/DomainRouterDaoImpl.java +++ b/engine/schema/src/com/cloud/vm/dao/DomainRouterDaoImpl.java @@ -60,6 +60,7 @@ public class DomainRouterDaoImpl extends GenericDaoBase im protected SearchBuilder StateNetworkTypeSearch; protected SearchBuilder OutsidePodSearch; protected SearchBuilder clusterSearch; + protected SearchBuilder SearchByStateAndManagementServerId; @Inject HostDao _hostsDao; @Inject @@ -130,6 +131,14 @@ protected void init() { StateNetworkTypeSearch.join("host", joinHost, joinHost.entity().getId(), StateNetworkTypeSearch.entity().getHostId(), JoinType.INNER); StateNetworkTypeSearch.done(); + SearchByStateAndManagementServerId = createSearchBuilder(); + SearchByStateAndManagementServerId.and("state", SearchByStateAndManagementServerId.entity().getState(), Op.EQ); + + SearchBuilder joinHost2 = _hostsDao.createSearchBuilder(); + joinHost2.and("mgmtServerId", joinHost2.entity().getManagementServerId(), Op.EQ); + SearchByStateAndManagementServerId.join("host", joinHost2, joinHost2.entity().getId(), SearchByStateAndManagementServerId.entity().getHostId(), JoinType.INNER); + SearchByStateAndManagementServerId.done(); + OutsidePodSearch = createSearchBuilder(); SearchBuilder joinRouterNetwork2 = _routerNetworkDao.createSearchBuilder(); joinRouterNetwork2.and("networkId", joinRouterNetwork2.entity().getNetworkId(), Op.EQ); @@ -293,6 +302,15 @@ public List listByStateAndNetworkType(State state, Network.Guest return routers; } + @Override + public List listByStateAndManagementServer(State state, long mgmtSrvrId) { + SearchCriteria sc = SearchByStateAndManagementServerId.create(); + sc.setParameters("state", state); + sc.setJoinParameters("host", "mgmtServerId", mgmtSrvrId); + + return listBy(sc); + } + @Override public List findByNetworkOutsideThePod(long networkId, long podId, State state, Role role) { SearchCriteria sc = OutsidePodSearch.create(); diff --git a/engine/schema/src/com/cloud/vm/dao/NicIpAliasVO.java b/engine/schema/src/com/cloud/vm/dao/NicIpAliasVO.java index 3df9909620..2f000fde8a 100644 --- a/engine/schema/src/com/cloud/vm/dao/NicIpAliasVO.java +++ b/engine/schema/src/com/cloud/vm/dao/NicIpAliasVO.java @@ -28,8 +28,6 @@ import javax.persistence.Id; import javax.persistence.Table; -import org.apache.cloudstack.acl.IAMEntityType; - import com.cloud.utils.db.GenericDao; import com.cloud.utils.net.NetUtils; import com.cloud.vm.NicIpAlias; @@ -235,7 +233,7 @@ public String getStartIpOfSubnet() { } @Override - public IAMEntityType getEntityType() { - return IAMEntityType.NicIpAlias; + public Class getEntityType() { + return NicIpAlias.class; } } diff --git a/engine/schema/src/com/cloud/vm/dao/NicSecondaryIpVO.java b/engine/schema/src/com/cloud/vm/dao/NicSecondaryIpVO.java index 995da17ddc..f8730aac5d 100644 --- a/engine/schema/src/com/cloud/vm/dao/NicSecondaryIpVO.java +++ b/engine/schema/src/com/cloud/vm/dao/NicSecondaryIpVO.java @@ -26,8 +26,6 @@ import javax.persistence.Id; import javax.persistence.Table; -import org.apache.cloudstack.acl.IAMEntityType; - import com.cloud.utils.db.GenericDao; import com.cloud.vm.NicSecondaryIp; @@ -128,7 +126,7 @@ public long getVmId() { } @Override - public IAMEntityType getEntityType() { - return IAMEntityType.NicSecondaryIp; + public Class getEntityType() { + return NicSecondaryIp.class; } } diff --git a/engine/schema/src/com/cloud/vm/dao/UserVmDaoImpl.java b/engine/schema/src/com/cloud/vm/dao/UserVmDaoImpl.java index 7a05be8f60..8c460b59f4 100755 --- a/engine/schema/src/com/cloud/vm/dao/UserVmDaoImpl.java +++ b/engine/schema/src/com/cloud/vm/dao/UserVmDaoImpl.java @@ -297,6 +297,7 @@ public List listByNetworkIdAndStates(long networkId, State... states) if (UserVmSearch == null) { SearchBuilder nicSearch = _nicDao.createSearchBuilder(); nicSearch.and("networkId", nicSearch.entity().getNetworkId(), SearchCriteria.Op.EQ); + nicSearch.and("removed", nicSearch.entity().getRemoved(), SearchCriteria.Op.NULL); nicSearch.and().op("ip4Address", nicSearch.entity().getIp4Address(), SearchCriteria.Op.NNULL); nicSearch.or("ip6Address", nicSearch.entity().getIp6Address(), SearchCriteria.Op.NNULL); nicSearch.cp(); @@ -355,91 +356,139 @@ public void saveDetails(UserVmVO vm) { @Override public List listPodIdsHavingVmsforAccount(long zoneId, long accountId) { TransactionLegacy txn = TransactionLegacy.currentTxn(); - PreparedStatement pstmt = null; List result = new ArrayList(); + String sql = LIST_PODS_HAVING_VMS_FOR_ACCOUNT; - try { - String sql = LIST_PODS_HAVING_VMS_FOR_ACCOUNT; - pstmt = txn.prepareAutoCloseStatement(sql); + try(PreparedStatement pstmt = txn.prepareStatement(sql)) { pstmt.setLong(1, zoneId); pstmt.setLong(2, accountId); - - ResultSet rs = pstmt.executeQuery(); - while (rs.next()) { - result.add(rs.getLong(1)); + try(ResultSet rs = pstmt.executeQuery();) + { + while (rs.next()) { + result.add(rs.getLong(1)); + } } + catch (Exception e) { + s_logger.error("listPodIdsHavingVmsforAccount:Exception: " + e.getMessage()); + throw new CloudRuntimeException("listPodIdsHavingVmsforAccount:Exception: " + e.getMessage(), e); + } + txn.commit(); return result; - } catch (SQLException e) { - throw new CloudRuntimeException("DB Exception on: " + LIST_PODS_HAVING_VMS_FOR_ACCOUNT, e); - } catch (Throwable e) { - throw new CloudRuntimeException("Caught: " + LIST_PODS_HAVING_VMS_FOR_ACCOUNT, e); + } catch (Exception e) { + s_logger.error("listPodIdsHavingVmsforAccount:Exception : " + e.getMessage()); + throw new CloudRuntimeException("listPodIdsHavingVmsforAccount:Exception: " + e.getMessage(), e); + } + finally { + try{ + if (txn != null) + { + txn.close(); + } + } + catch (Exception e) + { + s_logger.error("listVmDetails:Exception:" + e.getMessage()); + } } + } @Override public Hashtable listVmDetails(Hashtable userVmDataHash) { TransactionLegacy txn = TransactionLegacy.currentTxn(); - PreparedStatement pstmt = null; - try { int curr_index = 0; - List userVmDataList = new ArrayList(userVmDataHash.values()); - - if (userVmDataList.size() > VM_DETAILS_BATCH_SIZE) { - pstmt = txn.prepareStatement(VM_DETAILS + getQueryBatchAppender(VM_DETAILS_BATCH_SIZE)); - while ((curr_index + VM_DETAILS_BATCH_SIZE) <= userVmDataList.size()) { - // set the vars value - for (int k = 1, j = curr_index; j < curr_index + VM_DETAILS_BATCH_SIZE; j++, k++) { - pstmt.setLong(k, userVmDataList.get(j).getId()); - } - ResultSet rs = pstmt.executeQuery(); - while (rs.next()) { - long vm_id = rs.getLong("vm_instance.id"); - //check if the entry is already there - UserVmData uvm = userVmDataHash.get(vm_id); - if (uvm == null) { - uvm = new UserVmData(); - uvm.setId(vm_id); + if (userVmDataList.size() > VM_DETAILS_BATCH_SIZE) + { + try (PreparedStatement pstmt = txn.prepareStatement(VM_DETAILS + getQueryBatchAppender(VM_DETAILS_BATCH_SIZE));) + { + while ((curr_index + VM_DETAILS_BATCH_SIZE) <= userVmDataList.size()) { + // set the vars value + for (int k = 1, j = curr_index; j < curr_index + VM_DETAILS_BATCH_SIZE; j++, k++) { + pstmt.setLong(k, userVmDataList.get(j).getId()); + } + try(ResultSet rs = pstmt.executeQuery();) + { + while (rs.next()) { + long vm_id = rs.getLong("vm_instance.id"); + //check if the entry is already there + UserVmData uvm = userVmDataHash.get(vm_id); + if (uvm == null) { + uvm = new UserVmData(); + uvm.setId(vm_id); + } + // initialize the data with this row + setUserVmData(uvm, rs); + } } - // initialize the data with this row - setUserVmData(uvm, rs); + catch (Exception e) + { + s_logger.error("listVmDetails:Exception:" + e.getMessage()); + throw new CloudRuntimeException("listVmDetails: Exception:" + e.getMessage(),e); + } + curr_index += VM_DETAILS_BATCH_SIZE; } - rs.close(); - curr_index += VM_DETAILS_BATCH_SIZE; + } + catch (Exception e) + { + s_logger.error("listVmDetails:Exception:" + e.getMessage()); + throw new CloudRuntimeException("listVmDetails: Exception:" + e.getMessage(),e); } } if (curr_index < userVmDataList.size()) { int batch_size = (userVmDataList.size() - curr_index); - pstmt = txn.prepareStatement(VM_DETAILS + getQueryBatchAppender(batch_size)); - // set the vars value - for (int k = 1, j = curr_index; j < curr_index + batch_size; j++, k++) { - pstmt.setLong(k, userVmDataList.get(j).getId()); - } - ResultSet rs = pstmt.executeQuery(); - while (rs.next()) { - long vm_id = rs.getLong("vm_instance.id"); - //check if the entry is already there - UserVmData uvm = userVmDataHash.get(vm_id); - if (uvm == null) { - uvm = new UserVmData(); - uvm.setId(vm_id); + try (PreparedStatement vm_details_pstmt = txn.prepareStatement(VM_DETAILS + getQueryBatchAppender(batch_size))) + { + // set the vars value + for (int k = 1, j = curr_index; j < curr_index + batch_size; j++, k++) { + vm_details_pstmt.setLong(k, userVmDataList.get(j).getId()); + } + try(ResultSet rs = vm_details_pstmt.executeQuery();) { + while (rs.next()) { + long vm_id = rs.getLong("vm_instance.id"); + //check if the entry is already there + UserVmData uvm = userVmDataHash.get(vm_id); + if (uvm == null) { + uvm = new UserVmData(); + uvm.setId(vm_id); + } + // initialize the data with this row + setUserVmData(uvm, rs); + } + } + catch (Exception e) + { + s_logger.error("listVmDetails: Exception:" + e.getMessage()); + throw new CloudRuntimeException("listVmDetails: Exception:" + e.getMessage(),e); } - // initialize the data with this row - setUserVmData(uvm, rs); } - rs.close(); + catch (Exception e) + { + s_logger.error("listVmDetails:Exception:" + e.getMessage()); + throw new CloudRuntimeException("listVmDetails: Exception:" + e.getMessage(),e); + } } - - if (pstmt != null) - pstmt.close(); + txn.commit(); return userVmDataHash; - } catch (SQLException e) { - throw new CloudRuntimeException("DB Exception on: " + VM_DETAILS, e); - } catch (Throwable e) { - throw new CloudRuntimeException("Caught: " + VM_DETAILS, e); + } catch (Exception e) { + s_logger.error("listVmDetails:Exception:" + e.getMessage()); + throw new CloudRuntimeException("listVmDetails:Exception : ", e); } + finally { + try{ + if (txn != null) + { + txn.close(); + } + } + catch (Exception e) + { + s_logger.error("listVmDetails:Exception:" + e.getMessage()); + } + } + } public static UserVmData setUserVmData(UserVmData userVmData, ResultSet rs) throws SQLException { diff --git a/engine/schema/src/com/cloud/vm/dao/VMInstanceDao.java b/engine/schema/src/com/cloud/vm/dao/VMInstanceDao.java index 453d222cdf..6ba7c36521 100644 --- a/engine/schema/src/com/cloud/vm/dao/VMInstanceDao.java +++ b/engine/schema/src/com/cloud/vm/dao/VMInstanceDao.java @@ -17,6 +17,7 @@ package com.cloud.vm.dao; import java.util.Date; +import java.util.HashMap; import java.util.List; import java.util.Map; @@ -133,4 +134,6 @@ public interface VMInstanceDao extends GenericDao, StateDao< void resetVmPowerStateTracking(long instanceId); void resetHostPowerStateTracking(long hostId); + + HashMap countVgpuVMs(Long dcId, Long podId, Long clusterId); } diff --git a/engine/schema/src/com/cloud/vm/dao/VMInstanceDaoImpl.java b/engine/schema/src/com/cloud/vm/dao/VMInstanceDaoImpl.java index 2f25f577f4..bcd6fa78a7 100644 --- a/engine/schema/src/com/cloud/vm/dao/VMInstanceDaoImpl.java +++ b/engine/schema/src/com/cloud/vm/dao/VMInstanceDaoImpl.java @@ -115,6 +115,13 @@ public class VMInstanceDaoImpl extends GenericDaoBase implem private static final String ORDER_HOSTS_NUMBER_OF_VMS_FOR_ACCOUNT_PART2 = " GROUP BY host.id ORDER BY 2 ASC "; + private static final String COUNT_VMS_BASED_ON_VGPU_TYPES1 = + "SELECT pci, type, SUM(vmcount) FROM (SELECT MAX(IF(offering.name = 'pciDevice',value,'')) AS pci, MAX(IF(offering.name = 'vgpuType', value,'')) " + + "AS type, COUNT(DISTINCT vm.id) AS vmcount FROM service_offering_details offering INNER JOIN vm_instance vm ON offering.service_offering_id = vm.service_offering_id " + + "INNER JOIN `cloud`.`host` ON vm.host_id = host.id WHERE vm.state = 'Running' AND host.data_center_id = ? "; + private static final String COUNT_VMS_BASED_ON_VGPU_TYPES2 = + "GROUP BY offering.service_offering_id) results GROUP BY pci, type"; + @Inject protected HostDao _hostDao; @@ -437,6 +444,9 @@ public boolean updateState(State oldState, Event event, State newState, VirtualM return true; } + // lock the target row at beginning to avoid lock-promotion caused deadlock + lockRow(vm.getId(), true); + SearchCriteria sc = StateChangeSearch.create(); sc.setParameters("id", vmi.getId()); sc.setParameters("states", oldState); @@ -452,41 +462,29 @@ public boolean updateState(State oldState, Event event, State newState, VirtualM ub.set(vmi, _updateTimeAttr, new Date()); int result = update(vmi, sc); - if (result == 0 && s_logger.isDebugEnabled()) { - + if (result == 0) { VMInstanceVO vo = findByIdIncludingRemoved(vm.getId()); - if (vo != null) { - StringBuilder str = new StringBuilder("Unable to update ").append(vo.toString()); - str.append(": DB Data={Host=") - .append(vo.getHostId()) - .append("; State=") - .append(vo.getState().toString()) - .append("; updated=") - .append(vo.getUpdated()) - .append("; time=") - .append(vo.getUpdateTime()); - str.append("} New Data: {Host=") - .append(vm.getHostId()) - .append("; State=") - .append(vm.getState().toString()) - .append("; updated=") - .append(vmi.getUpdated()) - .append("; time=") - .append(vo.getUpdateTime()); - str.append("} Stale Data: {Host=") - .append(oldHostId) - .append("; State=") - .append(oldState) - .append("; updated=") - .append(oldUpdated) - .append("; time=") - .append(oldUpdateDate) - .append("}"); - s_logger.debug(str.toString()); - - } else { - s_logger.debug("Unable to update the vm id=" + vm.getId() + "; the vm either doesn't exist or already removed"); + if (s_logger.isDebugEnabled()) { + if (vo != null) { + StringBuilder str = new StringBuilder("Unable to update ").append(vo.toString()); + str.append(": DB Data={Host=").append(vo.getHostId()).append("; State=").append(vo.getState().toString()).append("; updated=").append(vo.getUpdated()) + .append("; time=").append(vo.getUpdateTime()); + str.append("} New Data: {Host=").append(vm.getHostId()).append("; State=").append(vm.getState().toString()).append("; updated=").append(vmi.getUpdated()) + .append("; time=").append(vo.getUpdateTime()); + str.append("} Stale Data: {Host=").append(oldHostId).append("; State=").append(oldState).append("; updated=").append(oldUpdated).append("; time=") + .append(oldUpdateDate).append("}"); + s_logger.debug(str.toString()); + + } else { + s_logger.debug("Unable to update the vm id=" + vm.getId() + "; the vm either doesn't exist or already removed"); + } + } + + if (vo != null && vo.getState() == newState) { + // allow for concurrent update if target state has already been matched + s_logger.debug("VM " + vo.getInstanceName() + " state has been already been updated to " + newState); + return true; } } return result > 0; @@ -649,6 +647,45 @@ public List listHostIdsByVmCount(long dcId, Long podId, Long clusterId, lo } } + @Override + public HashMap countVgpuVMs(Long dcId, Long podId, Long clusterId) { + StringBuilder finalQuery = new StringBuilder(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); + PreparedStatement pstmt = null; + List resourceIdList = new ArrayList(); + HashMap result = new HashMap(); + + resourceIdList.add(dcId); + finalQuery.append(COUNT_VMS_BASED_ON_VGPU_TYPES1); + + if (podId != null) { + finalQuery.append(" AND host.pod_id = ?"); + resourceIdList.add(podId); + } + + if (clusterId != null) { + finalQuery.append(" AND host.cluster_id = ?"); + resourceIdList.add(clusterId); + } + finalQuery.append(COUNT_VMS_BASED_ON_VGPU_TYPES2); + + try { + pstmt = txn.prepareAutoCloseStatement(finalQuery.toString()); + for (int i = 0; i < resourceIdList.size(); i++) { + pstmt.setLong(1 + i, resourceIdList.get(i)); + } + ResultSet rs = pstmt.executeQuery(); + while (rs.next()) { + result.put(rs.getString(1).concat(rs.getString(2)), rs.getLong(3)); + } + return result; + } catch (SQLException e) { + throw new CloudRuntimeException("DB Exception on: " + finalQuery, e); + } catch (Throwable e) { + throw new CloudRuntimeException("Caught: " + finalQuery, e); + } + } + @Override public Long countRunningByAccount(long accountId) { SearchCriteria sc = CountRunningByAccount.create(); diff --git a/engine/schema/src/com/cloud/vm/snapshot/VMSnapshotVO.java b/engine/schema/src/com/cloud/vm/snapshot/VMSnapshotVO.java index 042b276fe4..df2966d45b 100644 --- a/engine/schema/src/com/cloud/vm/snapshot/VMSnapshotVO.java +++ b/engine/schema/src/com/cloud/vm/snapshot/VMSnapshotVO.java @@ -33,7 +33,6 @@ import javax.persistence.TemporalType; import javax.persistence.Transient; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.engine.subsystem.api.storage.VMSnapshotOptions; import com.cloud.utils.db.GenericDao; @@ -246,7 +245,7 @@ public void setRemoved(Date removed) { } @Override - public IAMEntityType getEntityType() { - return IAMEntityType.VMSnapshot; + public Class getEntityType() { + return VMSnapshot.class; } } diff --git a/engine/schema/src/org/apache/cloudstack/affinity/AffinityGroupVO.java b/engine/schema/src/org/apache/cloudstack/affinity/AffinityGroupVO.java index b9fda8e9e3..03274ad438 100644 --- a/engine/schema/src/org/apache/cloudstack/affinity/AffinityGroupVO.java +++ b/engine/schema/src/org/apache/cloudstack/affinity/AffinityGroupVO.java @@ -28,7 +28,6 @@ import javax.persistence.Table; import org.apache.cloudstack.acl.ControlledEntity; -import org.apache.cloudstack.acl.IAMEntityType; @Entity @Table(name = ("affinity_group")) @@ -126,8 +125,8 @@ public String toString() { } @Override - public IAMEntityType getEntityType() { - return IAMEntityType.AffinityGroup; + public Class getEntityType() { + return AffinityGroup.class; } } diff --git a/engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/VMEntityVO.java b/engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/VMEntityVO.java index 7403d62fcf..b20cae320e 100644 --- a/engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/VMEntityVO.java +++ b/engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/VMEntityVO.java @@ -37,8 +37,6 @@ import javax.persistence.TemporalType; import javax.persistence.Transient; -import org.apache.cloudstack.acl.IAMEntityType; - import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.utils.db.Encrypt; import com.cloud.utils.db.GenericDao; @@ -175,6 +173,9 @@ public class VMEntityVO implements VirtualMachine, FiniteStateObject getEntityType() { + return VirtualMachine.class; + } + + @Override + public boolean isDisplay() { + return display; + } + + public void setDisplay(boolean display) { + this.display = display; } } diff --git a/engine/schema/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerRuleVO.java b/engine/schema/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerRuleVO.java index a37fec2d51..88cd0003a2 100644 --- a/engine/schema/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerRuleVO.java +++ b/engine/schema/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerRuleVO.java @@ -28,8 +28,6 @@ import javax.persistence.Id; import javax.persistence.Table; -import org.apache.cloudstack.acl.IAMEntityType; - import com.cloud.region.ha.GlobalLoadBalancerRule; @Entity @@ -191,7 +189,7 @@ public GlobalLoadBalancerRule.State getState() { } @Override - public IAMEntityType getEntityType() { - return IAMEntityType.GlobalLoadBalancerRule; + public Class getEntityType() { + return GlobalLoadBalancerRule.class; } } diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/LBHealthCheckPolicyDetailVO.java b/engine/schema/src/org/apache/cloudstack/resourcedetail/LBHealthCheckPolicyDetailVO.java new file mode 100644 index 0000000000..52b30ff18b --- /dev/null +++ b/engine/schema/src/org/apache/cloudstack/resourcedetail/LBHealthCheckPolicyDetailVO.java @@ -0,0 +1,78 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package org.apache.cloudstack.resourcedetail; + +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.ResourceDetail; + +@Entity +@Table(name = "load_balancer_healthcheck_policy_details") +public class LBHealthCheckPolicyDetailVO implements ResourceDetail{ + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private long id; + + @Column(name = "lb_policy_id") + private long resourceId; + + @Column(name = "name") + private String name; + + @Column(name = "value", length = 1024) + private String value; + + @Column(name = "display") + private boolean display = true; + + public LBHealthCheckPolicyDetailVO() { + } + + public LBHealthCheckPolicyDetailVO(long id, String name, String value, boolean display) { + this.resourceId = id; + this.name = name; + this.value = value; + this.display = display; + } + + @Override + public long getId() { + return id; + } + + @Override + public String getName() { + return name; + } + + @Override + public String getValue() { + return value; + } + + @Override + public long getResourceId() { + return resourceId; + } + + @Override + public boolean isDisplay() { + return display; + } +} diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/LBStickinessPolicyDetailVO.java b/engine/schema/src/org/apache/cloudstack/resourcedetail/LBStickinessPolicyDetailVO.java new file mode 100644 index 0000000000..caa2d90000 --- /dev/null +++ b/engine/schema/src/org/apache/cloudstack/resourcedetail/LBStickinessPolicyDetailVO.java @@ -0,0 +1,82 @@ +// 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.resourcedetail; + +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.ResourceDetail; + +@Entity +@Table(name = "load_balancer_stickiness_policy_details") +public class LBStickinessPolicyDetailVO implements ResourceDetail { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private long id; + + @Column(name = "lb_policy_id") + private long resourceId; + + @Column(name = "name") + private String name; + + @Column(name = "value", length = 1024) + private String value; + + @Column(name = "display") + private boolean display = true; + + public LBStickinessPolicyDetailVO() { + } + + public LBStickinessPolicyDetailVO(long id, String name, String value, boolean display) { + this.resourceId = id; + this.name = name; + this.value = value; + this.display = display; + } + + @Override + public long getId() { + return id; + } + + @Override + public String getName() { + return name; + } + + @Override + public String getValue() { + return value; + } + + @Override + public long getResourceId() { + return resourceId; + } + + @Override + public boolean isDisplay() { + return display; + } +} diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/ResourceDetailsDao.java b/engine/schema/src/org/apache/cloudstack/resourcedetail/ResourceDetailsDao.java index 5002683791..5d2d919a68 100644 --- a/engine/schema/src/org/apache/cloudstack/resourcedetail/ResourceDetailsDao.java +++ b/engine/schema/src/org/apache/cloudstack/resourcedetail/ResourceDetailsDao.java @@ -32,6 +32,15 @@ public interface ResourceDetailsDao extends GenericDao */ public R findDetail(long resourceId, String name); + /** + * Find details by key,value pair + * @param key + * @param value + * @param display + * @return + */ + public List findDetails(String key, String value, Boolean display); + /** * Removes all details for the resource specified * @param resourceId diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/ResourceDetailsDaoBase.java b/engine/schema/src/org/apache/cloudstack/resourcedetail/ResourceDetailsDaoBase.java index 60d7f162f2..b3e7ea2758 100644 --- a/engine/schema/src/org/apache/cloudstack/resourcedetail/ResourceDetailsDaoBase.java +++ b/engine/schema/src/org/apache/cloudstack/resourcedetail/ResourceDetailsDaoBase.java @@ -34,6 +34,7 @@ public ResourceDetailsDaoBase() { AllFieldsSearch = createSearchBuilder(); AllFieldsSearch.and("resourceId", AllFieldsSearch.entity().getResourceId(), SearchCriteria.Op.EQ); AllFieldsSearch.and("name", AllFieldsSearch.entity().getName(), SearchCriteria.Op.EQ); + AllFieldsSearch.and("value", AllFieldsSearch.entity().getValue(), SearchCriteria.Op.EQ); // FIXME SnapshotDetailsVO doesn't have a display field if (_allAttributes.containsKey("display")) { AllFieldsSearch.and("display", AllFieldsSearch.entity().isDisplay(), SearchCriteria.Op.EQ); @@ -49,6 +50,25 @@ public R findDetail(long resourceId, String name) { return findOneBy(sc); } + public List findDetails(String name, String value, Boolean display) { + SearchCriteria sc = AllFieldsSearch.create(); + + if(display != null){ + sc.setParameters("display", display); + } + + if(name != null){ + sc.setParameters("name", name); + } + + if(value != null){ + sc.setParameters("value", value); + } + + List results = search(sc, null); + return results; + } + public Map listDetailsKeyPairs(long resourceId) { SearchCriteria sc = AllFieldsSearch.create(); sc.setParameters("resourceId", resourceId); diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/SnapshotPolicyDetailVO.java b/engine/schema/src/org/apache/cloudstack/resourcedetail/SnapshotPolicyDetailVO.java new file mode 100644 index 0000000000..9c9fc20898 --- /dev/null +++ b/engine/schema/src/org/apache/cloudstack/resourcedetail/SnapshotPolicyDetailVO.java @@ -0,0 +1,65 @@ +package org.apache.cloudstack.resourcedetail; + +import org.apache.cloudstack.api.ResourceDetail; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "snapshot_policy_details") +public class SnapshotPolicyDetailVO implements ResourceDetail { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private long id; + + @Column(name = "policy_id") + private long resourceId; + + @Column(name = "name") + private String name; + + @Column(name = "value", length = 1024) + private String value; + + @Column(name = "display") + private boolean display = true; + + public SnapshotPolicyDetailVO() { + } + + public SnapshotPolicyDetailVO(long id, String name, String value) { + this.resourceId = id; + this.name = name; + this.value = value; + } + + @Override + public long getId() { + return id; + } + + @Override + public String getName() { + return name; + } + + @Override + public String getValue() { + return value; + } + + @Override + public long getResourceId() { + return resourceId; + } + + @Override + public boolean isDisplay() { + return display; + } +} diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/LBHealthCheckPolicyDetailsDao.java b/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/LBHealthCheckPolicyDetailsDao.java new file mode 100644 index 0000000000..9f8fcddd1d --- /dev/null +++ b/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/LBHealthCheckPolicyDetailsDao.java @@ -0,0 +1,22 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package org.apache.cloudstack.resourcedetail.dao; + +import org.apache.cloudstack.resourcedetail.LBHealthCheckPolicyDetailVO; +import org.apache.cloudstack.resourcedetail.ResourceDetailsDao; + +import com.cloud.utils.db.GenericDao; + +public interface LBHealthCheckPolicyDetailsDao extends GenericDao, ResourceDetailsDao{ + +} diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/LBHealthCheckPolicyDetailsDaoImpl.java b/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/LBHealthCheckPolicyDetailsDaoImpl.java new file mode 100644 index 0000000000..ab2e07f50d --- /dev/null +++ b/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/LBHealthCheckPolicyDetailsDaoImpl.java @@ -0,0 +1,29 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package org.apache.cloudstack.resourcedetail.dao; + +import javax.ejb.Local; + +import org.apache.cloudstack.resourcedetail.LBHealthCheckPolicyDetailVO; +import org.apache.cloudstack.resourcedetail.ResourceDetailsDaoBase; +import org.springframework.stereotype.Component; + +@Component +@Local(value = {LBHealthCheckPolicyDetailsDao.class}) +public class LBHealthCheckPolicyDetailsDaoImpl extends ResourceDetailsDaoBase implements LBHealthCheckPolicyDetailsDao { + + @Override + public void addDetail(long resourceId, String key, String value, boolean display) { + super.addDetail(new LBHealthCheckPolicyDetailVO(resourceId, key, value, display)); + } +} \ No newline at end of file diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/LBStickinessPolicyDetailsDao.java b/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/LBStickinessPolicyDetailsDao.java new file mode 100644 index 0000000000..512debc38c --- /dev/null +++ b/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/LBStickinessPolicyDetailsDao.java @@ -0,0 +1,22 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package org.apache.cloudstack.resourcedetail.dao; + +import org.apache.cloudstack.resourcedetail.LBStickinessPolicyDetailVO; +import org.apache.cloudstack.resourcedetail.ResourceDetailsDao; + +import com.cloud.utils.db.GenericDao; + +public interface LBStickinessPolicyDetailsDao extends GenericDao, ResourceDetailsDao{ + +} diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/LBStickinessPolicyDetailsDaoImpl.java b/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/LBStickinessPolicyDetailsDaoImpl.java new file mode 100644 index 0000000000..a9afa2280c --- /dev/null +++ b/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/LBStickinessPolicyDetailsDaoImpl.java @@ -0,0 +1,29 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package org.apache.cloudstack.resourcedetail.dao; + +import javax.ejb.Local; + +import org.apache.cloudstack.resourcedetail.LBStickinessPolicyDetailVO; +import org.apache.cloudstack.resourcedetail.ResourceDetailsDaoBase; +import org.springframework.stereotype.Component; + +@Component +@Local(value = {LBStickinessPolicyDetailsDao.class}) +public class LBStickinessPolicyDetailsDaoImpl extends ResourceDetailsDaoBase implements LBStickinessPolicyDetailsDao { + + @Override + public void addDetail(long resourceId, String key, String value, boolean display) { + super.addDetail(new LBStickinessPolicyDetailVO(resourceId, key, value, display)); + } +} \ No newline at end of file diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/SnapshotPolicyDetailsDao.java b/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/SnapshotPolicyDetailsDao.java new file mode 100644 index 0000000000..4556688027 --- /dev/null +++ b/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/SnapshotPolicyDetailsDao.java @@ -0,0 +1,8 @@ +package org.apache.cloudstack.resourcedetail.dao; + +import com.cloud.utils.db.GenericDao; +import org.apache.cloudstack.resourcedetail.ResourceDetailsDao; +import org.apache.cloudstack.resourcedetail.SnapshotPolicyDetailVO; + +public interface SnapshotPolicyDetailsDao extends GenericDao, ResourceDetailsDao { +} diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/SnapshotPolicyDetailsDaoImpl.java b/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/SnapshotPolicyDetailsDaoImpl.java new file mode 100644 index 0000000000..ead76809ea --- /dev/null +++ b/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/SnapshotPolicyDetailsDaoImpl.java @@ -0,0 +1,17 @@ +package org.apache.cloudstack.resourcedetail.dao; + +import org.apache.cloudstack.resourcedetail.ResourceDetailsDaoBase; +import org.apache.cloudstack.resourcedetail.SnapshotPolicyDetailVO; +import org.springframework.stereotype.Component; + +import javax.ejb.Local; + + @Component + @Local(value = {SnapshotPolicyDetailsDao.class}) + public class SnapshotPolicyDetailsDaoImpl extends ResourceDetailsDaoBase implements SnapshotPolicyDetailsDao { + + @Override + public void addDetail(long resourceId, String key, String value, boolean display) { + super.addDetail(new SnapshotPolicyDetailVO(resourceId, key, value)); + } +} \ No newline at end of file diff --git a/engine/schema/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDao.java b/engine/schema/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDao.java index 2c4369d047..a976bfbf6f 100644 --- a/engine/schema/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDao.java +++ b/engine/schema/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDao.java @@ -113,4 +113,6 @@ public interface PrimaryDataStoreDao extends GenericDao { List findZoneWideStoragePoolsByTags(long dcId, String[] tags); List findZoneWideStoragePoolsByHypervisor(long dataCenterId, HypervisorType hypervisorType); + + List findLocalStoragePoolsByHostAndTags(long hostId, String[] tags); } diff --git a/engine/schema/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java b/engine/schema/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java index 57afa16b50..92793f1fb1 100644 --- a/engine/schema/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java +++ b/engine/schema/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java @@ -31,10 +31,13 @@ import com.cloud.host.Status; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.storage.ScopeType; +import com.cloud.storage.StoragePoolHostVO; import com.cloud.storage.StoragePoolStatus; +import com.cloud.storage.dao.StoragePoolHostDao; import com.cloud.utils.db.DB; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.GenericSearchBuilder; +import com.cloud.utils.db.JoinBuilder; import com.cloud.utils.db.QueryBuilder; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; @@ -54,6 +57,8 @@ public class PrimaryDataStoreDaoImpl extends GenericDaoBase @Inject protected StoragePoolDetailsDao _detailsDao; + @Inject + protected StoragePoolHostDao _hostDao; private final String DetailsSqlPrefix = "SELECT storage_pool.* from storage_pool LEFT JOIN storage_pool_details ON storage_pool.id = storage_pool_details.pool_id WHERE storage_pool.removed is null and storage_pool.status = 'Up' and storage_pool.data_center_id = ? and (storage_pool.pod_id = ? or storage_pool.pod_id is null) and storage_pool.scope = ? and ("; @@ -314,6 +319,41 @@ public List findLocalStoragePoolsByTags(long dcId, long podId, Lo return storagePools; } + @Override + public List findLocalStoragePoolsByHostAndTags(long hostId, String[] tags) { + SearchBuilder hostSearch = createSearchBuilder(); + SearchBuilder hostPoolSearch = _hostDao.createSearchBuilder(); + SearchBuilder tagPoolSearch = _detailsDao.createSearchBuilder();; + + // Search for pools on the host + hostPoolSearch.and("hostId", hostPoolSearch.entity().getHostId(), Op.EQ); + // Set criteria for pools + hostSearch.and("scope", hostSearch.entity().getScope(), Op.EQ); + hostSearch.and("removed", hostSearch.entity().getRemoved(), Op.NULL); + hostSearch.and("status", hostSearch.entity().getStatus(), Op.EQ); + hostSearch.join("hostJoin", hostPoolSearch, hostSearch.entity().getId(), hostPoolSearch.entity().getPoolId(), JoinBuilder.JoinType.INNER); + + if (!(tags == null || tags.length == 0 )) { + tagPoolSearch.and("name", tagPoolSearch.entity().getName(), Op.EQ); + tagPoolSearch.and("value", tagPoolSearch.entity().getValue(), Op.EQ); + hostSearch.join("tagJoin", tagPoolSearch, hostSearch.entity().getId(), tagPoolSearch.entity().getResourceId(), JoinBuilder.JoinType.INNER); + } + + SearchCriteria sc = hostSearch.create(); + sc.setJoinParameters("hostJoin", "hostId", hostId ); + sc.setParameters("scope", ScopeType.HOST.toString()); + sc.setParameters("status", Status.Up.toString()); + + if (!(tags == null || tags.length == 0 )) { + Map details = tagsToDetails(tags); + for (Map.Entry detail : details.entrySet()) { + sc.setJoinParameters("tagJoin","name", detail.getKey()); + sc.setJoinParameters("tagJoin", "value", detail.getValue()); + } + } + return listBy(sc); + } + @Override public List findZoneWideStoragePoolsByTags(long dcId, String[] tags) { List storagePools = null; diff --git a/engine/schema/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreDao.java b/engine/schema/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreDao.java index ab458895e4..cb159499eb 100644 --- a/engine/schema/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreDao.java +++ b/engine/schema/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreDao.java @@ -65,6 +65,8 @@ public interface TemplateDataStoreDao extends GenericDao listByTemplate(long templateId); + TemplateDataStoreVO findByTemplateZoneReady(long templateId, Long zoneId); + void duplicateCacheRecordsOnRegionStore(long storeId); TemplateDataStoreVO findReadyOnCache(long templateId); @@ -72,4 +74,6 @@ public interface TemplateDataStoreDao extends GenericDao listOnCache(long templateId); void updateStoreRoleToCachce(long storeId); + + List listTemplateDownloadUrls(); } diff --git a/engine/schema/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java b/engine/schema/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java index bb40bf5d11..bb05300e21 100755 --- a/engine/schema/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java +++ b/engine/schema/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java @@ -98,6 +98,13 @@ public class TemplateDataStoreVO implements StateObject, List listDestroyed(long storeId); void duplicateCacheRecordsOnRegionStore(long storeId); + + List listVolumeDownloadUrls(); } diff --git a/engine/schema/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreVO.java b/engine/schema/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreVO.java index 588eae8ba5..aa57e74214 100755 --- a/engine/schema/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreVO.java +++ b/engine/schema/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreVO.java @@ -102,6 +102,10 @@ public class VolumeDataStoreVO implements StateObject getEntityType() { + return VirtualMachineTemplate.class; } } diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java index a8f1a56735..da8d341e49 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java @@ -24,7 +24,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; @@ -383,7 +382,7 @@ public boolean delete() { } @Override - public IAMEntityType getEntityType() { - return IAMEntityType.Snapshot; + public Class getEntityType() { + return Snapshot.class; } } diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java index 8331012d1e..684b5bd29c 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java @@ -302,6 +302,10 @@ protected Void copySnapshotAsyncCallback(AsyncCallbackDispatcher params) throws ConfigurationException { @@ -108,7 +116,6 @@ public VMSnapshot takeVMSnapshot(VMSnapshot vmSnapshot) { boolean result = false; try { GuestOSVO guestOS = guestOSDao.findById(userVm.getGuestOSId()); - List volumeTOs = vmSnapshotHelper.getVolumeTOList(userVm.getId()); VMSnapshotTO current = null; @@ -126,7 +133,14 @@ public VMSnapshot takeVMSnapshot(VMSnapshot vmSnapshot) { else vmSnapshotVO.setParent(current.getId()); + HostVO host = hostDao.findById(hostId); + GuestOSHypervisorVO guestOsMapping = guestOsHypervisorDao.findByOsIdAndHypervisor(guestOS.getId(), host.getHypervisorType().toString(), host.getHypervisorVersion()); CreateVMSnapshotCommand ccmd = new CreateVMSnapshotCommand(userVm.getInstanceName(), target, volumeTOs, guestOS.getDisplayName(), userVm.getState()); + if (guestOsMapping == null) { + ccmd.setPlatformEmulator(null); + } else { + ccmd.setPlatformEmulator(guestOsMapping.getGuestOsName()); + } ccmd.setWait(_wait); answer = (CreateVMSnapshotAnswer)agentMgr.send(hostId, ccmd); @@ -334,7 +348,14 @@ public boolean revertVMSnapshot(VMSnapshot vmSnapshot) { snapshot.getCurrent(), parent, true); Long hostId = vmSnapshotHelper.pickRunningHost(vmSnapshot.getVmId()); GuestOSVO guestOS = guestOSDao.findById(userVm.getGuestOSId()); + HostVO host = hostDao.findById(hostId); + GuestOSHypervisorVO guestOsMapping = guestOsHypervisorDao.findByOsIdAndHypervisor(guestOS.getId(), host.getHypervisorType().toString(), host.getHypervisorVersion()); RevertToVMSnapshotCommand revertToSnapshotCommand = new RevertToVMSnapshotCommand(vmInstanceName, vmSnapshotTO, volumeTOs, guestOS.getDisplayName()); + if (guestOsMapping == null) { + revertToSnapshotCommand.setPlatformEmulator(null); + } else { + revertToSnapshotCommand.setPlatformEmulator(guestOsMapping.getGuestOsName()); + } RevertToVMSnapshotAnswer answer = (RevertToVMSnapshotAnswer)agentMgr.send(hostId, revertToSnapshotCommand); if (answer != null && answer.getResult()) { diff --git a/engine/storage/snapshot/test/src/VMSnapshotStrategyTest.java b/engine/storage/snapshot/test/src/VMSnapshotStrategyTest.java index 9eaa7e19c1..6100c598f0 100644 --- a/engine/storage/snapshot/test/src/VMSnapshotStrategyTest.java +++ b/engine/storage/snapshot/test/src/VMSnapshotStrategyTest.java @@ -58,9 +58,14 @@ import com.cloud.agent.api.VMSnapshotTO; import com.cloud.exception.AgentUnavailableException; import com.cloud.exception.OperationTimedoutException; +import com.cloud.host.HostVO; +import com.cloud.host.dao.HostDao; +import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.storage.GuestOSHypervisorVO; import com.cloud.storage.GuestOSVO; import com.cloud.storage.dao.DiskOfferingDao; import com.cloud.storage.dao.GuestOSDao; +import com.cloud.storage.dao.GuestOSHypervisorDao; import com.cloud.storage.dao.VolumeDao; import com.cloud.utils.component.ComponentContext; import com.cloud.utils.exception.CloudRuntimeException; @@ -83,9 +88,13 @@ public class VMSnapshotStrategyTest extends TestCase { @Inject GuestOSDao guestOSDao; @Inject + GuestOSHypervisorDao guestOsHypervisorDao; + @Inject AgentManager agentMgr; @Inject VMSnapshotDao vmSnapshotDao; + @Inject + HostDao hostDao; @Override @Before @@ -98,6 +107,9 @@ public void testCreateVMSnapshot() throws AgentUnavailableException, OperationTi Long hostId = 1L; Long vmId = 1L; Long guestOsId = 1L; + HypervisorType hypervisorType = HypervisorType.Any; + String hypervisorVersion = "default"; + String guestOsName = "Other"; List volumeObjectTOs = new ArrayList(); VMSnapshotVO vmSnapshot = Mockito.mock(VMSnapshotVO.class); UserVmVO userVmVO = Mockito.mock(UserVmVO.class); @@ -108,7 +120,15 @@ public void testCreateVMSnapshot() throws AgentUnavailableException, OperationTi Mockito.when(userVmDao.findById(Matchers.anyLong())).thenReturn(userVmVO); GuestOSVO guestOSVO = Mockito.mock(GuestOSVO.class); Mockito.when(guestOSDao.findById(Matchers.anyLong())).thenReturn(guestOSVO); + GuestOSHypervisorVO guestOSHypervisorVO = Mockito.mock(GuestOSHypervisorVO.class); + Mockito.when(guestOSHypervisorVO.getGuestOsName()).thenReturn(guestOsName); + Mockito.when(guestOsHypervisorDao.findById(Matchers.anyLong())).thenReturn(guestOSHypervisorVO); + Mockito.when(guestOsHypervisorDao.findByOsIdAndHypervisor(Matchers.anyLong(), Matchers.anyString(), Matchers.anyString())).thenReturn(guestOSHypervisorVO); Mockito.when(agentMgr.send(Matchers.anyLong(), Matchers.any(Command.class))).thenReturn(null); + HostVO hostVO = Mockito.mock(HostVO.class); + Mockito.when(hostDao.findById(Matchers.anyLong())).thenReturn(hostVO); + Mockito.when(hostVO.getHypervisorType()).thenReturn(hypervisorType); + Mockito.when(hostVO.getHypervisorVersion()).thenReturn(hypervisorVersion); Exception e = null; try { vmSnapshotStrategy.takeVMSnapshot(vmSnapshot); @@ -131,6 +151,9 @@ public void testRevertSnapshot() throws AgentUnavailableException, OperationTime Long hostId = 1L; Long vmId = 1L; Long guestOsId = 1L; + HypervisorType hypervisorType = HypervisorType.Any; + String hypervisorVersion = "default"; + String guestOsName = "Other"; List volumeObjectTOs = new ArrayList(); VMSnapshotVO vmSnapshot = Mockito.mock(VMSnapshotVO.class); UserVmVO userVmVO = Mockito.mock(UserVmVO.class); @@ -141,12 +164,20 @@ public void testRevertSnapshot() throws AgentUnavailableException, OperationTime Mockito.when(userVmDao.findById(Matchers.anyLong())).thenReturn(userVmVO); GuestOSVO guestOSVO = Mockito.mock(GuestOSVO.class); Mockito.when(guestOSDao.findById(Matchers.anyLong())).thenReturn(guestOSVO); + GuestOSHypervisorVO guestOSHypervisorVO = Mockito.mock(GuestOSHypervisorVO.class); + Mockito.when(guestOsHypervisorDao.findById(Matchers.anyLong())).thenReturn(guestOSHypervisorVO); + Mockito.when(guestOsHypervisorDao.findByOsIdAndHypervisor(Matchers.anyLong(), Matchers.anyString(), Matchers.anyString())).thenReturn(guestOSHypervisorVO); + Mockito.when(guestOSHypervisorVO.getGuestOsName()).thenReturn(guestOsName); VMSnapshotTO vmSnapshotTO = Mockito.mock(VMSnapshotTO.class); Mockito.when(vmSnapshotHelper.getSnapshotWithParents(Matchers.any(VMSnapshotVO.class))).thenReturn(vmSnapshotTO); Mockito.when(vmSnapshotDao.findById(Matchers.anyLong())).thenReturn(vmSnapshot); Mockito.when(vmSnapshot.getId()).thenReturn(1L); Mockito.when(vmSnapshot.getCreated()).thenReturn(new Date()); Mockito.when(agentMgr.send(Matchers.anyLong(), Matchers.any(Command.class))).thenReturn(null); + HostVO hostVO = Mockito.mock(HostVO.class); + Mockito.when(hostDao.findById(Matchers.anyLong())).thenReturn(hostVO); + Mockito.when(hostVO.getHypervisorType()).thenReturn(hypervisorType); + Mockito.when(hostVO.getHypervisorVersion()).thenReturn(hypervisorVersion); Exception e = null; try { vmSnapshotStrategy.revertVMSnapshot(vmSnapshot); @@ -168,6 +199,9 @@ public void testDeleteVMSnapshot() throws AgentUnavailableException, OperationTi Long hostId = 1L; Long vmId = 1L; Long guestOsId = 1L; + HypervisorType hypervisorType = HypervisorType.Any; + String hypervisorVersion = "default"; + String guestOsName = "Other"; List volumeObjectTOs = new ArrayList(); VMSnapshotVO vmSnapshot = Mockito.mock(VMSnapshotVO.class); UserVmVO userVmVO = Mockito.mock(UserVmVO.class); @@ -178,13 +212,20 @@ public void testDeleteVMSnapshot() throws AgentUnavailableException, OperationTi Mockito.when(userVmDao.findById(Matchers.anyLong())).thenReturn(userVmVO); GuestOSVO guestOSVO = Mockito.mock(GuestOSVO.class); Mockito.when(guestOSDao.findById(Matchers.anyLong())).thenReturn(guestOSVO); + GuestOSHypervisorVO guestOSHypervisorVO = Mockito.mock(GuestOSHypervisorVO.class); + Mockito.when(guestOSHypervisorVO.getGuestOsName()).thenReturn(guestOsName); + Mockito.when(guestOsHypervisorDao.findById(Matchers.anyLong())).thenReturn(guestOSHypervisorVO); + Mockito.when(guestOsHypervisorDao.findByOsIdAndHypervisor(Matchers.anyLong(), Matchers.anyString(), Matchers.anyString())).thenReturn(guestOSHypervisorVO); VMSnapshotTO vmSnapshotTO = Mockito.mock(VMSnapshotTO.class); Mockito.when(vmSnapshotHelper.getSnapshotWithParents(Matchers.any(VMSnapshotVO.class))).thenReturn(vmSnapshotTO); Mockito.when(vmSnapshotDao.findById(Matchers.anyLong())).thenReturn(vmSnapshot); Mockito.when(vmSnapshot.getId()).thenReturn(1L); Mockito.when(vmSnapshot.getCreated()).thenReturn(new Date()); Mockito.when(agentMgr.send(Matchers.anyLong(), Matchers.any(Command.class))).thenReturn(null); - + HostVO hostVO = Mockito.mock(HostVO.class); + Mockito.when(hostDao.findById(Matchers.anyLong())).thenReturn(hostVO); + Mockito.when(hostVO.getHypervisorType()).thenReturn(hypervisorType); + Mockito.when(hostVO.getHypervisorVersion()).thenReturn(hypervisorVersion); Exception e = null; try { vmSnapshotStrategy.deleteVMSnapshot(vmSnapshot); @@ -227,6 +268,11 @@ public GuestOSDao guestOSDao() { return Mockito.mock(GuestOSDao.class); } + @Bean + public GuestOSHypervisorDao guestOsHypervisorDao() { + return Mockito.mock(GuestOSHypervisorDao.class); + } + @Bean public UserVmDao userVmDao() { return Mockito.mock(UserVmDao.class); @@ -256,5 +302,10 @@ public VolumeDao volumeDao() { public DiskOfferingDao diskOfferingDao() { return Mockito.mock(DiskOfferingDao.class); } + + @Bean + public HostDao hostDao() { + return Mockito.mock(HostDao.class); + } } } diff --git a/engine/storage/src/org/apache/cloudstack/storage/RemoteHostEndPoint.java b/engine/storage/src/org/apache/cloudstack/storage/RemoteHostEndPoint.java index 34f9c9d906..c54430fedb 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/RemoteHostEndPoint.java +++ b/engine/storage/src/org/apache/cloudstack/storage/RemoteHostEndPoint.java @@ -25,8 +25,7 @@ import javax.inject.Inject; import org.apache.log4j.Logger; -import com.cloud.vm.SecondaryStorageVmVO; -import com.cloud.vm.dao.SecondaryStorageVmDao; + import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.managed.context.ManagedContextRunnable; @@ -43,11 +42,15 @@ import com.cloud.exception.ConnectionException; import com.cloud.exception.OperationTimedoutException; import com.cloud.host.Host; +import com.cloud.host.HostVO; import com.cloud.host.Status; +import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.HypervisorGuruManager; import com.cloud.utils.component.ComponentContext; import com.cloud.utils.concurrency.NamedThreadFactory; import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.vm.SecondaryStorageVmVO; +import com.cloud.vm.dao.SecondaryStorageVmDao; public class RemoteHostEndPoint implements EndPoint { private static final Logger s_logger = Logger.getLogger(RemoteHostEndPoint.class); @@ -60,6 +63,8 @@ public class RemoteHostEndPoint implements EndPoint { protected HypervisorGuruManager _hvGuruMgr; @Inject protected SecondaryStorageVmDao vmDao; + @Inject + protected HostDao _hostDao; private ScheduledExecutorService executor; public RemoteHostEndPoint() { @@ -67,14 +72,14 @@ public RemoteHostEndPoint() { } private void configure(Host host) { - this.hostId = host.getId(); - this.hostAddress = host.getPrivateIpAddress(); - this.publicAddress = host.getPublicIpAddress(); + hostId = host.getId(); + hostAddress = host.getPrivateIpAddress(); + publicAddress = host.getPublicIpAddress(); if (Host.Type.SecondaryStorageVM == host.getType()) { String vmName = host.getName(); SecondaryStorageVmVO ssvm = vmDao.findByInstanceName(vmName); if (ssvm != null) { - this.publicAddress = ssvm.getPublicIpAddress(); + publicAddress = ssvm.getPublicIpAddress(); } } } @@ -87,17 +92,25 @@ public static RemoteHostEndPoint getHypervisorHostEndPoint(Host host) { @Override public String getHostAddr() { - return this.hostAddress; + return hostAddress; } @Override public String getPublicAddr() { - return this.publicAddress; + return publicAddress; } @Override public long getId() { - return this.hostId; + return hostId; + } + + // used when HypervisorGuruManager choose a different host to send command + private void setId(long id) { + HostVO host = _hostDao.findById(hostId); + if (host != null) { + configure(host); + } } @Override @@ -105,6 +118,10 @@ public Answer sendMessage(Command cmd) { String errMsg = null; try { long newHostId = _hvGuruMgr.getGuruProcessedCommandTargetHost(hostId, cmd); + if (newHostId != hostId) { + // update endpoint with new host if changed + setId(newHostId); + } return agentMgr.send(newHostId, cmd); } catch (AgentUnavailableException e) { errMsg = e.toString(); @@ -126,7 +143,7 @@ public CmdRunner(AsyncCompletionCallback callback) { @Override public boolean processAnswers(long agentId, long seq, Answer[] answers) { - this.answer = answers[0]; + answer = answers[0]; executor.schedule(this, 10, TimeUnit.SECONDS); return true; } @@ -182,7 +199,11 @@ protected void runInContext() { @Override public void sendMessageAsync(Command cmd, AsyncCompletionCallback callback) { try { - long newHostId = _hvGuruMgr.getGuruProcessedCommandTargetHost(this.hostId, cmd); + long newHostId = _hvGuruMgr.getGuruProcessedCommandTargetHost(hostId, cmd); + if (newHostId != hostId) { + // update endpoint with new host if changed + setId(newHostId); + } if (s_logger.isDebugEnabled()) { s_logger.debug("Sending command " + cmd.toString() + " to host: " + newHostId); } diff --git a/engine/storage/src/org/apache/cloudstack/storage/allocator/AbstractStoragePoolAllocator.java b/engine/storage/src/org/apache/cloudstack/storage/allocator/AbstractStoragePoolAllocator.java index ddbb5a467b..894b4d44a4 100755 --- a/engine/storage/src/org/apache/cloudstack/storage/allocator/AbstractStoragePoolAllocator.java +++ b/engine/storage/src/org/apache/cloudstack/storage/allocator/AbstractStoragePoolAllocator.java @@ -27,11 +27,12 @@ import javax.inject.Inject; import javax.naming.ConfigurationException; +import org.apache.log4j.Logger; + import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; -import org.apache.log4j.Logger; import com.cloud.dc.ClusterVO; import com.cloud.dc.dao.ClusterDao; @@ -171,10 +172,17 @@ protected boolean filter(ExcludeList avoid, StoragePool pool, DiskProfile dskCh, } Long clusterId = pool.getClusterId(); - ClusterVO cluster = _clusterDao.findById(clusterId); - if (!(cluster.getHypervisorType() == dskCh.getHypervisorType())) { + if (clusterId != null) { + ClusterVO cluster = _clusterDao.findById(clusterId); + if (!(cluster.getHypervisorType() == dskCh.getHypervisorType())) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("StoragePool's Cluster does not have required hypervisorType, skipping this pool"); + } + return false; + } + } else if (pool.getHypervisor() != null && !(pool.getHypervisor() == dskCh.getHypervisorType())) { if (s_logger.isDebugEnabled()) { - s_logger.debug("StoragePool's Cluster does not have required hypervisorType, skipping this pool"); + s_logger.debug("StoragePool does not have required hypervisorType, skipping this pool"); } return false; } diff --git a/engine/storage/src/org/apache/cloudstack/storage/allocator/LocalStoragePoolAllocator.java b/engine/storage/src/org/apache/cloudstack/storage/allocator/LocalStoragePoolAllocator.java index 678b2a3807..446e101141 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/allocator/LocalStoragePoolAllocator.java +++ b/engine/storage/src/org/apache/cloudstack/storage/allocator/LocalStoragePoolAllocator.java @@ -25,20 +25,17 @@ import javax.inject.Inject; import javax.naming.ConfigurationException; -import org.apache.log4j.Logger; -import org.springframework.stereotype.Component; - import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; import com.cloud.capacity.dao.CapacityDao; import com.cloud.deploy.DeploymentPlan; import com.cloud.deploy.DeploymentPlanner.ExcludeList; import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.storage.StoragePool; -import com.cloud.storage.StoragePoolHostVO; -import com.cloud.storage.Volume; import com.cloud.storage.dao.StoragePoolHostDao; import com.cloud.utils.NumbersUtil; import com.cloud.vm.DiskProfile; @@ -75,10 +72,9 @@ protected List select(DiskProfile dskCh, VirtualMachineProfile vmPr List suitablePools = new ArrayList(); // data disk and host identified from deploying vm (attach volume case) - if (dskCh.getType() == Volume.Type.DATADISK && plan.getHostId() != null) { - List hostPools = _poolHostDao.listByHostId(plan.getHostId()); - for (StoragePoolHostVO hostPool : hostPools) { - StoragePoolVO pool = _storagePoolDao.findById(hostPool.getPoolId()); + if (plan.getHostId() != null) { + List hostTagsPools = _storagePoolDao.findLocalStoragePoolsByHostAndTags(plan.getHostId(), dskCh.getTags()); + for (StoragePoolVO pool : hostTagsPools) { if (pool != null && pool.isLocal()) { StoragePool storagePool = (StoragePool)this.dataStoreMgr.getPrimaryDataStore(pool.getId()); if (filter(avoid, storagePool, dskCh, plan)) { diff --git a/engine/storage/src/org/apache/cloudstack/storage/helper/HypervisorHelperImpl.java b/engine/storage/src/org/apache/cloudstack/storage/helper/HypervisorHelperImpl.java index b41c1fa14a..ff62fb8680 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/helper/HypervisorHelperImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/helper/HypervisorHelperImpl.java @@ -44,8 +44,12 @@ import com.cloud.agent.api.to.DataTO; import com.cloud.exception.AgentUnavailableException; import com.cloud.exception.OperationTimedoutException; +import com.cloud.host.HostVO; +import com.cloud.host.dao.HostDao; +import com.cloud.storage.GuestOSHypervisorVO; import com.cloud.storage.GuestOSVO; import com.cloud.storage.dao.GuestOSDao; +import com.cloud.storage.dao.GuestOSHypervisorDao; import com.cloud.utils.NumbersUtil; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.VirtualMachine; @@ -60,9 +64,13 @@ public class HypervisorHelperImpl implements HypervisorHelper { @Inject GuestOSDao guestOSDao; @Inject + GuestOSHypervisorDao guestOsHypervisorDao; + @Inject ConfigurationDao configurationDao; @Inject AgentManager agentMgr; + @Inject + HostDao hostDao; @Override public DataTO introduceObject(DataTO object, Scope scope, Long storeId) { @@ -117,6 +125,9 @@ public VMSnapshotTO quiesceVm(VirtualMachine virtualMachine) { List volumeTOs = vmSnapshotHelper.getVolumeTOList(virtualMachine.getId()); CreateVMSnapshotCommand ccmd = new CreateVMSnapshotCommand(virtualMachine.getInstanceName(), vmSnapshotTO, volumeTOs, guestOS.getDisplayName(), virtualMachine.getState()); + HostVO host = hostDao.findById(hostId); + GuestOSHypervisorVO guestOsMapping = guestOsHypervisorDao.findByOsIdAndHypervisor(guestOS.getId(), host.getHypervisorType().toString(), host.getHypervisorVersion()); + ccmd.setPlatformEmulator(guestOsMapping.getGuestOsName()); ccmd.setWait(wait); try { Answer answer = agentMgr.send(hostId, ccmd); diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/BaseImageStoreDriverImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/BaseImageStoreDriverImpl.java index 7ed11ecd0e..25aa8e80e0 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/BaseImageStoreDriverImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/BaseImageStoreDriverImpl.java @@ -25,6 +25,7 @@ import javax.inject.Inject; +import com.cloud.storage.Upload; import org.apache.log4j.Logger; import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; @@ -271,4 +272,8 @@ public boolean canCopy(DataObject srcData, DataObject destData) { @Override public void resize(DataObject data, AsyncCompletionCallback callback) { } + + @Override + public void deleteEntityExtractUrl(DataStore store, String installPath, String url, Upload.Type entityType){ + } } diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/ImageStoreDriver.java b/engine/storage/src/org/apache/cloudstack/storage/image/ImageStoreDriver.java index fa7ea372f7..e71529edb8 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/ImageStoreDriver.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/ImageStoreDriver.java @@ -18,6 +18,7 @@ */ package org.apache.cloudstack.storage.image; +import com.cloud.storage.Upload; import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreDriver; @@ -26,4 +27,6 @@ public interface ImageStoreDriver extends DataStoreDriver { String createEntityExtractUrl(DataStore store, String installPath, ImageFormat format, DataObject dataObject); + + void deleteEntityExtractUrl(DataStore store, String installPath, String url, Upload.Type entityType); } diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/TemplateEntityImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/TemplateEntityImpl.java index fde13e17c8..c1aa8c2f0d 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/TemplateEntityImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/TemplateEntityImpl.java @@ -23,7 +23,6 @@ import java.util.List; import java.util.Map; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.engine.cloud.entity.api.TemplateEntity; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; import org.apache.cloudstack.storage.image.datastore.ImageStoreInfo; @@ -31,6 +30,7 @@ import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Storage.TemplateType; +import com.cloud.template.VirtualMachineTemplate; public class TemplateEntityImpl implements TemplateEntity { protected TemplateInfo templateInfo; @@ -287,7 +287,7 @@ public long getVirtualSize() { } @Override - public IAMEntityType getEntityType() { - return IAMEntityType.VirtualMachineTemplate; + public Class getEntityType() { + return VirtualMachineTemplate.class; } } diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java index d4b0445be7..50334f4644 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java @@ -63,6 +63,7 @@ public class TemplateDataStoreDaoImpl extends GenericDaoBase storeTemplateSearch; private SearchBuilder storeTemplateStateSearch; private SearchBuilder storeTemplateDownloadStatusSearch; + private SearchBuilder downloadTemplateSearch; @Inject private DataStoreManager _storeMgr; @@ -131,6 +132,11 @@ public boolean configure(String name, Map params) throws Configu storeTemplateSearch.and("destroyed", storeTemplateSearch.entity().getDestroyed(), SearchCriteria.Op.EQ); storeTemplateSearch.done(); + downloadTemplateSearch = createSearchBuilder(); + downloadTemplateSearch.and("download_url", downloadTemplateSearch.entity().getExtractUrl(), Op.NNULL); + downloadTemplateSearch.and("destroyed", downloadTemplateSearch.entity().getDestroyed(), SearchCriteria.Op.EQ); + downloadTemplateSearch.done(); + return true; } @@ -400,6 +406,22 @@ public TemplateDataStoreVO findByTemplateZone(long templateId, Long zoneId, Data return null; } + @Override + public TemplateDataStoreVO findByTemplateZoneReady(long templateId, Long zoneId) { + List imgStores = null; + imgStores = _storeMgr.getImageStoresByScope(new ZoneScope(zoneId)); + if (imgStores != null) { + Collections.shuffle(imgStores); + for (DataStore store : imgStores) { + List sRes = listByTemplateStoreStatus(templateId, store.getId(), State.Ready); + if (sRes != null && sRes.size() > 0) { + return sRes.get(0); + } + } + } + return null; + } + /** * Duplicate all image cache store entries */ @@ -472,4 +494,11 @@ public void updateStoreRoleToCachce(long storeId) { } + @Override + public List listTemplateDownloadUrls() { + SearchCriteria sc = downloadTemplateSearch.create(); + sc.setParameters("destroyed", false); + return listBy(sc); + } + } diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/VolumeDataStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/VolumeDataStoreDaoImpl.java index e906d95be6..9309f6ef3c 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/db/VolumeDataStoreDaoImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/VolumeDataStoreDaoImpl.java @@ -50,6 +50,7 @@ public class VolumeDataStoreDaoImpl extends GenericDaoBase storeSearch; private SearchBuilder cacheSearch; private SearchBuilder storeVolumeSearch; + private SearchBuilder downloadVolumeSearch; @Inject DataStoreManager storeMgr; @@ -85,6 +86,12 @@ public boolean configure(String name, Map params) throws Configu updateStateSearch.and("state", updateStateSearch.entity().getState(), Op.EQ); updateStateSearch.and("updatedCount", updateStateSearch.entity().getUpdatedCount(), Op.EQ); updateStateSearch.done(); + + downloadVolumeSearch = createSearchBuilder(); + downloadVolumeSearch.and("download_url", downloadVolumeSearch.entity().getExtractUrl(), Op.NNULL); + downloadVolumeSearch.and("destroyed", downloadVolumeSearch.entity().getDestroyed(), SearchCriteria.Op.EQ); + downloadVolumeSearch.done(); + return true; } @@ -253,4 +260,11 @@ public void duplicateCacheRecordsOnRegionStore(long storeId) { } } + + @Override + public List listVolumeDownloadUrls() { + SearchCriteria sc = downloadVolumeSearch.create(); + sc.setParameters("destroyed", false); + return listBy(sc); + } } diff --git a/engine/storage/src/org/apache/cloudstack/storage/snapshot/SnapshotEntityImpl.java b/engine/storage/src/org/apache/cloudstack/storage/snapshot/SnapshotEntityImpl.java index 848b165893..a660f41211 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/snapshot/SnapshotEntityImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/snapshot/SnapshotEntityImpl.java @@ -21,10 +21,10 @@ import java.util.List; import java.util.Map; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.engine.cloud.entity.api.SnapshotEntity; import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.storage.Snapshot; public class SnapshotEntityImpl implements SnapshotEntity { @@ -185,7 +185,7 @@ public Type getRecurringType() { } @Override - public IAMEntityType getEntityType() { - return IAMEntityType.Snapshot; + public Class getEntityType() { + return Snapshot.class; } } diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java index 4fb37e2a18..f3c9e79027 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java @@ -24,8 +24,6 @@ import javax.inject.Inject; -import org.apache.log4j.Logger; - import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope; import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreDriver; @@ -47,6 +45,7 @@ import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.cloudstack.storage.to.PrimaryDataStoreTO; import org.apache.cloudstack.storage.volume.VolumeObject; +import org.apache.log4j.Logger; import com.cloud.agent.api.to.DataObjectType; import com.cloud.agent.api.to.DataStoreTO; @@ -391,6 +390,11 @@ public boolean isInMaintenance() { getStatus() == StoragePoolStatus.ErrorInMaintenance || getRemoved() != null; } + @Override + public HypervisorType getHypervisor() { + return pdsv.getHypervisor(); + } + @Override public String getStorageProviderName() { return pdsv.getStorageProviderName(); diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/DefaultHostListener.java b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/DefaultHostListener.java index fffd1e815c..46d8db9420 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/DefaultHostListener.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/DefaultHostListener.java @@ -53,7 +53,7 @@ public class DefaultHostListener implements HypervisorHostListener { @Override public boolean hostConnect(long hostId, long poolId) { - StoragePool pool = (StoragePool)this.dataStoreMgr.getDataStore(poolId, DataStoreRole.Primary); + StoragePool pool = (StoragePool)dataStoreMgr.getDataStore(poolId, DataStoreRole.Primary); ModifyStoragePoolCommand cmd = new ModifyStoragePoolCommand(true, pool); final Answer answer = agentMgr.easySend(hostId, cmd); @@ -80,8 +80,8 @@ public boolean hostConnect(long hostId, long poolId) { poolHost.setLocalPath(mspAnswer.getPoolInfo().getLocalPath().replaceAll("//", "/")); } - StoragePoolVO poolVO = this.primaryStoreDao.findById(poolId); - poolVO.setUsedBytes(mspAnswer.getPoolInfo().getAvailableBytes()); + StoragePoolVO poolVO = primaryStoreDao.findById(poolId); + poolVO.setUsedBytes(mspAnswer.getPoolInfo().getCapacityBytes() - mspAnswer.getPoolInfo().getAvailableBytes()); poolVO.setCapacityBytes(mspAnswer.getPoolInfo().getCapacityBytes()); primaryStoreDao.update(pool.getId(), poolVO); diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java index 1f05be21f2..0e7d5cc368 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java @@ -22,7 +22,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; @@ -168,6 +167,11 @@ public boolean isDisplayVolume() { return volumeVO.isDisplayVolume(); } + @Override + public boolean isDisplay() { + return volumeVO.isDisplay(); + } + public long getVolumeId() { return volumeVO.getId(); } @@ -670,7 +674,7 @@ public Long getVmSnapshotChainSize() { } @Override - public IAMEntityType getEntityType() { - return IAMEntityType.Volume; + public Class getEntityType() { + return Volume.class; } } 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 68e5a5680e..3a71147f8a 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 @@ -527,7 +527,10 @@ protected Void managedCopyBaseImageCallback(AsyncCallbackDispatcher createManagedStorageAndVolumeFromTemplat details.put(PrimaryDataStore.MANAGED, Boolean.TRUE.toString()); details.put(PrimaryDataStore.STORAGE_HOST, destPrimaryDataStore.getHostAddress()); + details.put(PrimaryDataStore.STORAGE_PORT, String.valueOf(destPrimaryDataStore.getPort())); // for managed storage, the storage repository (XenServer) or datastore (ESX) name is based off of the iScsiName property of a volume details.put(PrimaryDataStore.MANAGED_STORE_TARGET, volumeInfo.get_iScsiName()); details.put(PrimaryDataStore.MANAGED_STORE_TARGET_ROOT_VOLUME, volumeInfo.getName()); diff --git a/framework/db/src/com/cloud/utils/crypt/EncryptionSecretKeyChanger.java b/framework/db/src/com/cloud/utils/crypt/EncryptionSecretKeyChanger.java index 58584f93a1..ae103ff34f 100755 --- a/framework/db/src/com/cloud/utils/crypt/EncryptionSecretKeyChanger.java +++ b/framework/db/src/com/cloud/utils/crypt/EncryptionSecretKeyChanger.java @@ -105,8 +105,8 @@ public static void main(String[] args) { PropertiesConfiguration backupDBProps = null; System.out.println("Parsing db.properties file"); - try { - dbProps.load(new FileInputStream(dbPropsFile)); + try(FileInputStream db_prop_fstream = new FileInputStream(dbPropsFile);) { + dbProps.load(db_prop_fstream); backupDBProps = new PropertiesConfiguration(dbPropsFile); } catch (FileNotFoundException e) { System.out.println("db.properties file not found while reading DB secret key" + e.getMessage()); @@ -142,11 +142,10 @@ public static void main(String[] args) { //db.properties updated successfully if (encryptionType.equals("file")) { //update key file with new MS key - try { - FileWriter fwriter = new FileWriter(keyFile); - BufferedWriter bwriter = new BufferedWriter(fwriter); + try (FileWriter fwriter = new FileWriter(keyFile); + BufferedWriter bwriter = new BufferedWriter(fwriter);) + { bwriter.write(newMSKey); - bwriter.close(); } catch (IOException e) { System.out.println("Failed to write new secret to file. Please update the file manually"); } @@ -180,11 +179,10 @@ public static void main(String[] args) { } if (encryptionType.equals("file")) { //revert secret key in file - try { - FileWriter fwriter = new FileWriter(keyFile); - BufferedWriter bwriter = new BufferedWriter(fwriter); + try (FileWriter fwriter = new FileWriter(keyFile); + BufferedWriter bwriter = new BufferedWriter(fwriter);) + { bwriter.write(oldMSKey); - bwriter.close(); } catch (IOException e) { System.out.println("Failed to revert to old secret to file. Please update the file manually"); } @@ -266,11 +264,10 @@ private String migrateValue(String value) { private void migrateConfigValues(Connection conn) { System.out.println("Begin migrate config values"); - PreparedStatement pstmt = null; - ResultSet rs = null; - try { - pstmt = conn.prepareStatement("select name, value from configuration where category in ('Hidden', 'Secure')"); - rs = pstmt.executeQuery(); + try(PreparedStatement select_pstmt = conn.prepareStatement("select name, value from configuration where category in ('Hidden', 'Secure')"); + ResultSet rs = select_pstmt.executeQuery(); + PreparedStatement update_pstmt = conn.prepareStatement("update configuration set value=? where name=?"); + ) { while (rs.next()) { String name = rs.getString(1); String value = rs.getString(2); @@ -278,37 +275,25 @@ private void migrateConfigValues(Connection conn) { continue; } String encryptedValue = migrateValue(value); - pstmt = conn.prepareStatement("update configuration set value=? where name=?"); - pstmt.setBytes(1, encryptedValue.getBytes("UTF-8")); - pstmt.setString(2, name); - pstmt.executeUpdate(); + update_pstmt.setBytes(1, encryptedValue.getBytes("UTF-8")); + update_pstmt.setString(2, name); + update_pstmt.executeUpdate(); } } catch (SQLException e) { throw new CloudRuntimeException("Unable to update configuration values ", e); } catch (UnsupportedEncodingException e) { throw new CloudRuntimeException("Unable to update configuration values ", e); - } finally { - try { - if (rs != null) { - rs.close(); - } - - if (pstmt != null) { - pstmt.close(); - } - } catch (SQLException e) { - } } System.out.println("End migrate config values"); } private void migrateHostDetails(Connection conn) { System.out.println("Begin migrate host details"); - PreparedStatement pstmt = null; - ResultSet rs = null; - try { - pstmt = conn.prepareStatement("select id, value from host_details where name = 'password'"); - rs = pstmt.executeQuery(); + + try( PreparedStatement sel_pstmt = conn.prepareStatement("select id, value from host_details where name = 'password'"); + ResultSet rs = sel_pstmt.executeQuery(); + PreparedStatement pstmt = conn.prepareStatement("update host_details set value=? where id=?"); + ) { while (rs.next()) { long id = rs.getLong(1); String value = rs.getString(2); @@ -316,7 +301,6 @@ private void migrateHostDetails(Connection conn) { continue; } String encryptedValue = migrateValue(value); - pstmt = conn.prepareStatement("update host_details set value=? where id=?"); pstmt.setBytes(1, encryptedValue.getBytes("UTF-8")); pstmt.setLong(2, id); pstmt.executeUpdate(); @@ -325,28 +309,16 @@ private void migrateHostDetails(Connection conn) { throw new CloudRuntimeException("Unable update host_details values ", e); } catch (UnsupportedEncodingException e) { throw new CloudRuntimeException("Unable update host_details values ", e); - } finally { - try { - if (rs != null) { - rs.close(); - } - - if (pstmt != null) { - pstmt.close(); - } - } catch (SQLException e) { - } } System.out.println("End migrate host details"); } private void migrateVNCPassword(Connection conn) { System.out.println("Begin migrate VNC password"); - PreparedStatement pstmt = null; - ResultSet rs = null; - try { - pstmt = conn.prepareStatement("select id, vnc_password from vm_instance"); - rs = pstmt.executeQuery(); + try(PreparedStatement select_pstmt = conn.prepareStatement("select id, vnc_password from vm_instance"); + ResultSet rs = select_pstmt.executeQuery(); + PreparedStatement pstmt = conn.prepareStatement("update vm_instance set vnc_password=? where id=?"); + ) { while (rs.next()) { long id = rs.getLong(1); String value = rs.getString(2); @@ -354,7 +326,7 @@ private void migrateVNCPassword(Connection conn) { continue; } String encryptedValue = migrateValue(value); - pstmt = conn.prepareStatement("update vm_instance set vnc_password=? where id=?"); + pstmt.setBytes(1, encryptedValue.getBytes("UTF-8")); pstmt.setLong(2, id); pstmt.executeUpdate(); @@ -363,28 +335,16 @@ private void migrateVNCPassword(Connection conn) { throw new CloudRuntimeException("Unable update vm_instance vnc_password ", e); } catch (UnsupportedEncodingException e) { throw new CloudRuntimeException("Unable update vm_instance vnc_password ", e); - } finally { - try { - if (rs != null) { - rs.close(); - } - - if (pstmt != null) { - pstmt.close(); - } - } catch (SQLException e) { - } } System.out.println("End migrate VNC password"); } private void migrateUserCredentials(Connection conn) { System.out.println("Begin migrate user credentials"); - PreparedStatement pstmt = null; - ResultSet rs = null; - try { - pstmt = conn.prepareStatement("select id, secret_key from user"); - rs = pstmt.executeQuery(); + try(PreparedStatement select_pstmt = conn.prepareStatement("select id, secret_key from user"); + ResultSet rs = select_pstmt.executeQuery(); + PreparedStatement pstmt = conn.prepareStatement("update user set secret_key=? where id=?"); + ) { while (rs.next()) { long id = rs.getLong(1); String secretKey = rs.getString(2); @@ -392,7 +352,6 @@ private void migrateUserCredentials(Connection conn) { continue; } String encryptedSecretKey = migrateValue(secretKey); - pstmt = conn.prepareStatement("update user set secret_key=? where id=?"); pstmt.setBytes(1, encryptedSecretKey.getBytes("UTF-8")); pstmt.setLong(2, id); pstmt.executeUpdate(); @@ -401,17 +360,6 @@ private void migrateUserCredentials(Connection conn) { throw new CloudRuntimeException("Unable update user secret key ", e); } catch (UnsupportedEncodingException e) { throw new CloudRuntimeException("Unable update user secret key ", e); - } finally { - try { - if (rs != null) { - rs.close(); - } - - if (pstmt != null) { - pstmt.close(); - } - } catch (SQLException e) { - } } System.out.println("End migrate user credentials"); } diff --git a/framework/db/src/com/cloud/utils/db/Merovingian2.java b/framework/db/src/com/cloud/utils/db/Merovingian2.java index 6eeea9f385..4e2c684a8a 100644 --- a/framework/db/src/com/cloud/utils/db/Merovingian2.java +++ b/framework/db/src/com/cloud/utils/db/Merovingian2.java @@ -444,14 +444,12 @@ public void cleanupThread() { @Override public boolean releaseLockAsLastResortAndIReallyKnowWhatIAmDoing(String key) { s_logger.info("Releasing a lock from JMX lck-" + key); - PreparedStatement pstmt = null; - try { - pstmt = _concierge.conn().prepareStatement(RELEASE_LOCK_SQL); + try(PreparedStatement pstmt = _concierge.conn().prepareStatement(RELEASE_LOCK_SQL);) { pstmt.setString(1, key); int rows = pstmt.executeUpdate(); return rows > 0; - } catch (SQLException e) { - s_logger.error("Unable to release lock " + key, e); + } catch (Exception e) { + s_logger.error("releaseLockAsLastResortAndIReallyKnowWhatIAmDoing : Exception: " + e.getMessage()); return false; } } diff --git a/framework/db/src/com/cloud/utils/db/ScriptRunner.java b/framework/db/src/com/cloud/utils/db/ScriptRunner.java index 66145277bf..45494b9391 100644 --- a/framework/db/src/com/cloud/utils/db/ScriptRunner.java +++ b/framework/db/src/com/cloud/utils/db/ScriptRunner.java @@ -131,52 +131,44 @@ private void runScript(Connection conn, Reader reader) throws IOException, SQLEx } else if (!fullLineDelimiter && trimmedLine.endsWith(getDelimiter()) || fullLineDelimiter && trimmedLine.equals(getDelimiter())) { command.append(line.substring(0, line.lastIndexOf(getDelimiter()))); command.append(" "); - Statement statement = conn.createStatement(); - - println(command); - - boolean hasResults = false; - if (stopOnError) { - hasResults = statement.execute(command.toString()); - } else { - try { - statement.execute(command.toString()); - } catch (SQLException e) { - e.fillInStackTrace(); - printlnError("Error executing: " + command); - printlnError(e); + try (Statement statement = conn.createStatement();) { + println(command); + boolean hasResults = false; + if (stopOnError) { + hasResults = statement.execute(command.toString()); + } else { + try { + statement.execute(command.toString()); + } catch (SQLException e) { + e.fillInStackTrace(); + printlnError("Error executing: " + command); + printlnError(e); + } } - } - - if (autoCommit && !conn.getAutoCommit()) { - conn.commit(); - } - - ResultSet rs = statement.getResultSet(); - if (hasResults && rs != null) { - ResultSetMetaData md = rs.getMetaData(); - int cols = md.getColumnCount(); - for (int i = 0; i < cols; i++) { - String name = md.getColumnLabel(i); - print(name + "\t"); + if (autoCommit && !conn.getAutoCommit()) { + conn.commit(); } - println(""); - while (rs.next()) { - for (int i = 0; i < cols; i++) { - String value = rs.getString(i); - print(value + "\t"); + try(ResultSet rs = statement.getResultSet();) { + if (hasResults && rs != null) { + ResultSetMetaData md = rs.getMetaData(); + int cols = md.getColumnCount(); + for (int i = 0; i < cols; i++) { + String name = md.getColumnLabel(i); + print(name + "\t"); + } + println(""); + while (rs.next()) { + for (int i = 1; i <= cols; i++) { + String value = rs.getString(i); + print(value + "\t"); + } + println(""); + } } - println(""); + command = null; + Thread.yield(); } } - - command = null; - try { - statement.close(); - } catch (Exception e) { - // Ignore to workaround a bug in Jakarta DBCP - } - Thread.yield(); } else { int idx = line.indexOf("--"); if (idx != -1) diff --git a/framework/db/src/com/cloud/utils/db/SearchBase.java b/framework/db/src/com/cloud/utils/db/SearchBase.java index 4ec9a41fd4..d19918a3d5 100644 --- a/framework/db/src/com/cloud/utils/db/SearchBase.java +++ b/framework/db/src/com/cloud/utils/db/SearchBase.java @@ -235,17 +235,7 @@ protected Attribute getSpecifiedAttribute() { if (_entity == null || _specifiedAttrs == null || _specifiedAttrs.size() != 1) { throw new RuntimeException("Now now, better specify an attribute or else we can't help you"); } - if (_specifiedAttrs.size() > 0) { - return _specifiedAttrs.get(0); - } - // look for attributes from joins - for (JoinBuilder> join : _joins.values()) { - SearchBase sb = join.getT(); - if (sb.getSpecifiedAttribute() != null) { - return sb.getSpecifiedAttribute(); - } - } - throw new CloudRuntimeException("Unable to find any specified attributes. You sure you know what you're doing?"); + return _specifiedAttrs.get(0); } protected List getSpecifiedAttributes() { diff --git a/framework/db/src/com/cloud/utils/db/TransactionLegacy.java b/framework/db/src/com/cloud/utils/db/TransactionLegacy.java index ac0ea21d1f..aedf93982b 100755 --- a/framework/db/src/com/cloud/utils/db/TransactionLegacy.java +++ b/framework/db/src/com/cloud/utils/db/TransactionLegacy.java @@ -791,7 +791,7 @@ protected void removeUpTo(String type, Object ref) { it.remove(); try { - if (item.type == type && (ref == null || item.ref == ref)) { + if ( (type == null || type.equals(item.type)) && (ref == null || ref.equals(item.ref))) { break; } diff --git a/framework/ipc/src/org/apache/cloudstack/framework/async/AsyncCallbackDispatcher.java b/framework/ipc/src/org/apache/cloudstack/framework/async/AsyncCallbackDispatcher.java index 06cfcff8b0..b9aa12bc5b 100644 --- a/framework/ipc/src/org/apache/cloudstack/framework/async/AsyncCallbackDispatcher.java +++ b/framework/ipc/src/org/apache/cloudstack/framework/async/AsyncCallbackDispatcher.java @@ -21,10 +21,11 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; -import net.sf.cglib.proxy.Callback; -import net.sf.cglib.proxy.CallbackFilter; import net.sf.cglib.proxy.Enhancer; +import net.sf.cglib.proxy.Factory; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; @@ -39,6 +40,7 @@ public class AsyncCallbackDispatcher implements AsyncCompletionCallback { private Object _contextObject; private Object _resultObject; private AsyncCallbackDriver _driver = new InplaceAsyncCallbackDriver(); + private static Map enMap = new HashMap(); private AsyncCallbackDispatcher(T target) { assert (target != null); @@ -58,39 +60,45 @@ public Method getCallbackMethod() { @SuppressWarnings("unchecked") public T getTarget() { - Enhancer en = new Enhancer(); - Class clz = _targetObject.getClass(); String clzName = clz.getName(); if (clzName.contains("EnhancerByCloudStack")) clz = clz.getSuperclass(); - en.setSuperclass(clz); - en.setCallbacks(new Callback[] {new MethodInterceptor() { - @Override - public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable { - _callbackMethod = arg1; - _callbackMethod.setAccessible(true); - return null; - } - }, new MethodInterceptor() { - @Override - public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable { - return null; - } - }}); - en.setCallbackFilter(new CallbackFilter() { - @Override - public int accept(Method method) { - if (method.getParameterTypes().length == 0 && method.getName().equals("finalize")) { - return 1; - } - return 0; + + Enhancer en = null; + synchronized (enMap) { + en = enMap.get(clz); + if (en == null) { + en = new Enhancer(); + + en.setSuperclass(clz); + en.setCallback(new MethodInterceptor() { + @Override + public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable { + return null; + } + }); + enMap.put(clz, en); } - }); + } try { - return (T)en.create(); + T t = (T)en.create(); + Factory factory = (Factory)t; + factory.setCallback(0, new MethodInterceptor() { + @Override + public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable { + if (arg1.getParameterTypes().length == 0 && arg1.getName().equals("finalize")) { + return null; + } else { + _callbackMethod = arg1; + _callbackMethod.setAccessible(true); + return null; + } + } + }); + return t; } catch (Throwable e) { s_logger.error("Unexpected exception", e); } diff --git a/framework/ipc/src/org/apache/cloudstack/framework/messagebus/MessageBusBase.java b/framework/ipc/src/org/apache/cloudstack/framework/messagebus/MessageBusBase.java index a9c433c62c..9432da0a72 100644 --- a/framework/ipc/src/org/apache/cloudstack/framework/messagebus/MessageBusBase.java +++ b/framework/ipc/src/org/apache/cloudstack/framework/messagebus/MessageBusBase.java @@ -58,10 +58,13 @@ public void subscribe(String subject, MessageSubscriber subscriber) { assert (subject != null); assert (subscriber != null); if (_gate.enter()) { - SubscriptionNode current = locate(subject, null, true); - assert (current != null); - current.addSubscriber(subscriber); - _gate.leave(); + try { + SubscriptionNode current = locate(subject, null, true); + assert (current != null); + current.addSubscriber(subscriber); + } finally { + _gate.leave(); + } } else { synchronized (_pendingActions) { _pendingActions.add(new ActionRecord(ActionType.Subscribe, subject, subscriber)); @@ -72,14 +75,17 @@ public void subscribe(String subject, MessageSubscriber subscriber) { @Override public void unsubscribe(String subject, MessageSubscriber subscriber) { if (_gate.enter()) { - if (subject != null) { - SubscriptionNode current = locate(subject, null, false); - if (current != null) - current.removeSubscriber(subscriber, false); - } else { - _subscriberRoot.removeSubscriber(subscriber, true); + try { + if (subject != null) { + SubscriptionNode current = locate(subject, null, false); + if (current != null) + current.removeSubscriber(subscriber, false); + } else { + _subscriberRoot.removeSubscriber(subscriber, true); + } + } finally { + _gate.leave(); } - _gate.leave(); } else { synchronized (_pendingActions) { _pendingActions.add(new ActionRecord(ActionType.Unsubscribe, subject, subscriber)); @@ -90,9 +96,12 @@ public void unsubscribe(String subject, MessageSubscriber subscriber) { @Override public void clearAll() { if (_gate.enter()) { - _subscriberRoot.clearAll(); - doPrune(); - _gate.leave(); + try { + _subscriberRoot.clearAll(); + doPrune(); + } finally { + _gate.leave(); + } } else { synchronized (_pendingActions) { _pendingActions.add(new ActionRecord(ActionType.ClearAll, null, null)); @@ -103,8 +112,11 @@ public void clearAll() { @Override public void prune() { if (_gate.enter()) { - doPrune(); - _gate.leave(); + try { + doPrune(); + } finally { + _gate.leave(); + } } else { synchronized (_pendingActions) { _pendingActions.add(new ActionRecord(ActionType.Prune, null, null)); @@ -132,18 +144,19 @@ private void doPrune() { public void publish(String senderAddress, String subject, PublishScope scope, Object args) { if (_gate.enter(true)) { + try { + List chainFromTop = new ArrayList(); + SubscriptionNode current = locate(subject, chainFromTop, false); - List chainFromTop = new ArrayList(); - SubscriptionNode current = locate(subject, chainFromTop, false); - - if (current != null) - current.notifySubscribers(senderAddress, subject, args); - - Collections.reverse(chainFromTop); - for (SubscriptionNode node : chainFromTop) - node.notifySubscribers(senderAddress, subject, args); + if (current != null) + current.notifySubscribers(senderAddress, subject, args); - _gate.leave(); + Collections.reverse(chainFromTop); + for (SubscriptionNode node : chainFromTop) + node.notifySubscribers(senderAddress, subject, args); + } finally { + _gate.leave(); + } } } diff --git a/framework/ipc/src/org/apache/cloudstack/framework/messagebus/MessageDetector.java b/framework/ipc/src/org/apache/cloudstack/framework/messagebus/MessageDetector.java index 3fb620c1b3..1dcd6bd268 100644 --- a/framework/ipc/src/org/apache/cloudstack/framework/messagebus/MessageDetector.java +++ b/framework/ipc/src/org/apache/cloudstack/framework/messagebus/MessageDetector.java @@ -18,27 +18,31 @@ */ package org.apache.cloudstack.framework.messagebus; +import org.apache.log4j.Logger; + public class MessageDetector implements MessageSubscriber { + private static final Logger s_logger = Logger.getLogger(MessageDetector.class); private MessageBus _messageBus; private String[] _subjects; - private volatile boolean _signalled = false; - public MessageDetector() { _messageBus = null; _subjects = null; } - public boolean waitAny(long timeoutInMiliseconds) { - _signalled = false; + public void waitAny(long timeoutInMiliseconds) { + if (timeoutInMiliseconds < 100) { + s_logger.warn("waitAny is passed with a too short time-out interval. " + timeoutInMiliseconds + "ms"); + timeoutInMiliseconds = 100; + } + synchronized (this) { try { wait(timeoutInMiliseconds); } catch (InterruptedException e) { } } - return _signalled; } public void open(MessageBus messageBus, String[] subjects) { @@ -67,9 +71,20 @@ public void close() { @Override public void onPublishMessage(String senderAddress, String subject, Object args) { - synchronized (this) { - _signalled = true; - notifyAll(); + if (subjectMatched(subject)) { + synchronized (this) { + notifyAll(); + } + } + } + + private boolean subjectMatched(String subject) { + if (_subjects != null) { + for (String sub : _subjects) { + if (sub.equals(subject)) + return true; + } } + return false; } } diff --git a/framework/ipc/test/org/apache/cloudstack/messagebus/TestMessageBus.java b/framework/ipc/test/org/apache/cloudstack/messagebus/TestMessageBus.java index c81d8aa994..cfa552ca2b 100644 --- a/framework/ipc/test/org/apache/cloudstack/messagebus/TestMessageBus.java +++ b/framework/ipc/test/org/apache/cloudstack/messagebus/TestMessageBus.java @@ -138,12 +138,7 @@ public void run() { try { int count = 0; while (count < 2) { - if (detector.waitAny(1000)) { - System.out.println("Detected signal on bus"); - count++; - } else { - System.out.println("Waiting timed out"); - } + detector.waitAny(1000); } } finally { detector.close(); diff --git a/framework/jobs/pom.xml b/framework/jobs/pom.xml index 529eebc876..3ecee56d2b 100644 --- a/framework/jobs/pom.xml +++ b/framework/jobs/pom.xml @@ -56,6 +56,21 @@ org.apache.cloudstack cloud-framework-config ${project.version} - + + + org.apache.cloudstack + cloud-framework-events + ${project.version} + + + org.apache.cloudstack + cloud-engine-schema + ${project.version} + + + commons-io + commons-io + test + diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/AsyncJob.java b/framework/jobs/src/org/apache/cloudstack/framework/jobs/AsyncJob.java index e62482193a..0ad49e1e7b 100644 --- a/framework/jobs/src/org/apache/cloudstack/framework/jobs/AsyncJob.java +++ b/framework/jobs/src/org/apache/cloudstack/framework/jobs/AsyncJob.java @@ -30,6 +30,7 @@ public enum JournalType { public static interface Topics { public static final String JOB_HEARTBEAT = "job.heartbeat"; public static final String JOB_STATE = "job.state"; + public static final String JOB_EVENT_PUBLISH = "job.eventpublish"; } public static interface Constants { diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/AsyncJobJoinMapDaoImpl.java b/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/AsyncJobJoinMapDaoImpl.java index 7bc29db8cb..fcdea76a25 100644 --- a/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/AsyncJobJoinMapDaoImpl.java +++ b/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/AsyncJobJoinMapDaoImpl.java @@ -214,12 +214,14 @@ public List findJobsToWake(long joinedJobId) { List standaloneList = new ArrayList(); TransactionLegacy txn = TransactionLegacy.currentTxn(); String sql = "SELECT job_id FROM async_job_join_map WHERE join_job_id = ? AND job_id NOT IN (SELECT content_id FROM sync_queue_item)"; - try { - PreparedStatement pstmt = txn.prepareStatement(sql); + try (PreparedStatement pstmt = txn.prepareStatement(sql);){ pstmt.setLong(1, joinedJobId); - ResultSet rs = pstmt.executeQuery(); - while (rs.next()) { - standaloneList.add(rs.getLong(1)); + try(ResultSet rs = pstmt.executeQuery();) { + while (rs.next()) { + standaloneList.add(rs.getLong(1)); + } + }catch (SQLException e) { + throw new CloudRuntimeException("Unable to execute " + sql, e); } } catch (SQLException e) { throw new CloudRuntimeException("Unable to execute " + sql, e); @@ -231,23 +233,26 @@ public List findJobsToWake(long joinedJobId) { public List findJobsToWakeBetween(Date cutDate) { List standaloneList = new ArrayList(); TransactionLegacy txn = TransactionLegacy.currentTxn(); - try { - String sql = "SELECT job_id FROM async_job_join_map WHERE next_wakeup < ? AND expiration > ? AND job_id NOT IN (SELECT content_id FROM sync_queue_item)"; - PreparedStatement pstmt = txn.prepareStatement(sql); + String sql = "SELECT job_id FROM async_job_join_map WHERE next_wakeup < ? AND expiration > ? AND job_id NOT IN (SELECT content_id FROM sync_queue_item)"; + try (PreparedStatement pstmt = txn.prepareStatement(sql);){ pstmt.setString(1, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), cutDate)); pstmt.setString(2, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), cutDate)); - ResultSet rs = pstmt.executeQuery(); - while (rs.next()) { - standaloneList.add(rs.getLong(1)); + try(ResultSet rs = pstmt.executeQuery();) { + while (rs.next()) { + standaloneList.add(rs.getLong(1)); + } + }catch (SQLException e) { + throw new CloudRuntimeException("Unable to handle SQL exception", e); } - // update for next wake-up sql = "UPDATE async_job_join_map SET next_wakeup=DATE_ADD(next_wakeup, INTERVAL wakeup_interval SECOND) WHERE next_wakeup < ? AND expiration > ?"; - pstmt = txn.prepareStatement(sql); - pstmt.setString(1, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), cutDate)); - pstmt.setString(2, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), cutDate)); - pstmt.executeUpdate(); - + try(PreparedStatement update_pstmt = txn.prepareStatement(sql);) { + update_pstmt.setString(1, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), cutDate)); + update_pstmt.setString(2, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), cutDate)); + update_pstmt.executeUpdate(); + }catch (SQLException e) { + throw new CloudRuntimeException("Unable to handle SQL exception", e); + } return standaloneList; } catch (SQLException e) { throw new CloudRuntimeException("Unable to handle SQL exception", e); diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/VmWorkJobDaoImpl.java b/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/VmWorkJobDaoImpl.java index cf3e17392b..ee8748adee 100644 --- a/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/VmWorkJobDaoImpl.java +++ b/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/VmWorkJobDaoImpl.java @@ -20,9 +20,10 @@ import java.sql.SQLException; import java.util.Date; import java.util.List; -import java.util.TimeZone; - import javax.annotation.PostConstruct; +import javax.inject.Inject; + +import org.apache.log4j.Logger; import org.apache.cloudstack.framework.jobs.impl.VmWorkJobVO; import org.apache.cloudstack.framework.jobs.impl.VmWorkJobVO.Step; @@ -41,9 +42,14 @@ import com.cloud.vm.VirtualMachine; public class VmWorkJobDaoImpl extends GenericDaoBase implements VmWorkJobDao { + private static final Logger s_logger = Logger.getLogger(VmWorkJobDaoImpl.class); protected SearchBuilder PendingWorkJobSearch; protected SearchBuilder PendingWorkJobByCommandSearch; + protected SearchBuilder ExpungingWorkJobSearch; + + @Inject + protected AsyncJobDao _baseJobDao; public VmWorkJobDaoImpl() { } @@ -63,6 +69,12 @@ public void init() { PendingWorkJobByCommandSearch.and("step", PendingWorkJobByCommandSearch.entity().getStep(), Op.NEQ); PendingWorkJobByCommandSearch.and("cmd", PendingWorkJobByCommandSearch.entity().getCmd(), Op.EQ); PendingWorkJobByCommandSearch.done(); + + ExpungingWorkJobSearch = createSearchBuilder(); + ExpungingWorkJobSearch.and("jobStatus", ExpungingWorkJobSearch.entity().getStatus(), Op.NEQ); + ExpungingWorkJobSearch.and("cutDate", ExpungingWorkJobSearch.entity().getLastUpdated(), Op.LT); + ExpungingWorkJobSearch.and("dispatcher", ExpungingWorkJobSearch.entity().getDispatcher(), Op.EQ); + ExpungingWorkJobSearch.done(); } @Override @@ -124,33 +136,19 @@ public void expungeCompletedWorkJobs(final Date cutDate) { expunge(sc); */ - Transaction.execute(new TransactionCallbackNoReturn() { - @Override - public void doInTransactionWithoutResult(TransactionStatus status) { - TransactionLegacy txn = TransactionLegacy.currentTxn(); - PreparedStatement pstmt = null; - try { - pstmt = txn.prepareAutoCloseStatement( - "DELETE FROM vm_work_job WHERE id IN (SELECT id FROM async_job WHERE job_dispatcher='VmWorkJobDispatcher' AND job_status != 0 AND last_updated < ?)"); - pstmt.setString(1, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), cutDate)); - - pstmt.execute(); - } catch (SQLException e) { - } catch (Throwable e) { - } - - try { - pstmt = txn.prepareAutoCloseStatement( - "DELETE FROM async_job WHERE job_dispatcher='VmWorkJobDispatcher' AND job_status != 0 AND last_updated < ?"); - pstmt.setString(1, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), cutDate)); - - pstmt.execute(); - } catch (SQLException e) { - } catch (Throwable e) { - } - } - }); + // loop at application level to avoid mysql deadlock issues + SearchCriteria sc = ExpungingWorkJobSearch.create(); + sc.setParameters("jobStatus", JobInfo.Status.IN_PROGRESS); + sc.setParameters("lastUpdated", cutDate); + sc.setParameters("dispatcher", "VmWorkJobDispatcher"); + List expungeList = listBy(sc); + for (VmWorkJobVO job : expungeList) { + if (s_logger.isDebugEnabled()) + s_logger.debug("Expunge completed work job-" + job.getId()); + expunge(job.getId()); + _baseJobDao.expunge(job.getId()); + } } @Override diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobManagerImpl.java b/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobManagerImpl.java index 49c3032b12..c6dd73274f 100644 --- a/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobManagerImpl.java +++ b/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobManagerImpl.java @@ -60,6 +60,7 @@ import com.cloud.cluster.ClusterManagerListener; import com.cloud.cluster.ManagementServerHost; import com.cloud.utils.DateUtil; +import com.cloud.utils.Pair; import com.cloud.utils.Predicate; import com.cloud.utils.component.ManagerBase; import com.cloud.utils.concurrency.NamedThreadFactory; @@ -171,6 +172,7 @@ public long submitAsyncJob(AsyncJob job, boolean scheduleJobExecutionInContext) job.setSyncSource(null); // no sync source originally dao.persist(job); + publishOnEventBus(job, "submit"); scheduleExecution(job, scheduleJobExecutionInContext); if (s_logger.isDebugEnabled()) { s_logger.debug("submit async job-" + job.getId() + ", details: " + job.toString()); @@ -192,6 +194,7 @@ public Long doInTransaction(TransactionStatus status) { job.setInitMsid(getMsid()); dao.persist(job); + publishOnEventBus(job, "submit"); syncAsyncJobExecution(job, syncObjType, syncObjId, 1); return job.getId(); @@ -229,6 +232,7 @@ public void completeAsyncJob(final long jobId, final Status jobStatus, final int return; } + publishOnEventBus(job, "complete"); // publish before the instance type and ID are wiped out List wakeupList = Transaction.execute(new TransactionCallback>() { @Override public List doInTransaction(TransactionStatus status) { @@ -256,13 +260,17 @@ public List doInTransaction(TransactionStatus status) { } }); - for (Long id : wakeupList) { - // TODO, we assume that all jobs in this category is API job only - AsyncJobVO jobToWakeup = _jobDao.findById(id); - if (jobToWakeup != null && (jobToWakeup.getPendingSignals() & AsyncJob.Constants.SIGNAL_MASK_WAKEUP) != 0) - scheduleExecution(jobToWakeup, false); - } - + // + // disable wakeup scheduling now, since all API jobs are currently using block-waiting for sub-jobs + // + /* + for (Long id : wakeupList) { + // TODO, we assume that all jobs in this category is API job only + AsyncJobVO jobToWakeup = _jobDao.findById(id); + if (jobToWakeup != null && (jobToWakeup.getPendingSignals() & AsyncJob.Constants.SIGNAL_MASK_WAKEUP) != 0) + scheduleExecution(jobToWakeup, false); + } + */ _messageBus.publish(null, AsyncJob.Topics.JOB_STATE, PublishScope.GLOBAL, jobId); } @@ -282,6 +290,7 @@ public void updateAsyncJobStatus(final long jobId, final int processStatus, fina return; } + publishOnEventBus(job, "update"); Transaction.execute(new TransactionCallbackNoReturn() { @Override public void doInTransactionWithoutResult(TransactionStatus status) { @@ -302,6 +311,9 @@ public void updateAsyncJobAttachment(final long jobId, final String instanceType s_logger.debug("Update async-job attachment, job-" + jobId + ", instanceType: " + instanceType + ", instanceId: " + instanceId); } + final AsyncJobVO job = _jobDao.findById(jobId); + publishOnEventBus(job, "update"); + Transaction.execute(new TransactionCallbackNoReturn() { @Override public void doInTransactionWithoutResult(TransactionStatus status) { @@ -441,9 +453,9 @@ public void run() { CallContext.registerPlaceHolderContext(); if (job.getRelated() != null && !job.getRelated().isEmpty()) - NDC.push("Job-" + job.getRelated() + "/" + "Job-" + job.getId()); + NDC.push("job-" + job.getRelated() + "/" + "job-" + job.getId()); else - NDC.push("Job-" + job.getId()); + NDC.push("job-" + job.getId()); try { super.run(); } finally { @@ -556,17 +568,41 @@ private void executeQueueItem(SyncQueueItemVO item, boolean fromPreviousSession) job.setSyncSource(item); - job.setExecutingMsid(getMsid()); - _jobDao.update(job.getId(), job); + // + // TODO: a temporary solution to work-around DB deadlock situation + // + // to live with DB deadlocks, we will give a chance for job to be rescheduled + // in case of exceptions (most-likely DB deadlock exceptions) + try { + job.setExecutingMsid(getMsid()); + _jobDao.update(job.getId(), job); + } catch (Exception e) { + s_logger.warn("Unexpected exception while dispatching job-" + item.getContentId(), e); + + try { + _queueMgr.returnItem(item.getId()); + } catch (Throwable thr) { + s_logger.error("Unexpected exception while returning job-" + item.getContentId() + " to queue", thr); + } + } try { scheduleExecution(job); } catch (RejectedExecutionException e) { s_logger.warn("Execution for job-" + job.getId() + " is rejected, return it to the queue for next turn"); - _queueMgr.returnItem(item.getId()); - job.setExecutingMsid(null); - _jobDao.update(job.getId(), job); + try { + _queueMgr.returnItem(item.getId()); + } catch (Exception e2) { + s_logger.error("Unexpected exception while returning job-" + item.getContentId() + " to queue", e2); + } + + try { + job.setExecutingMsid(null); + _jobDao.update(job.getId(), job); + } catch (Exception e3) { + s_logger.warn("Unexpected exception while update job-" + item.getContentId() + " msid for bookkeeping"); + } } } else { @@ -981,4 +1017,8 @@ protected AsyncJobManagerImpl() { } + private void publishOnEventBus(AsyncJob job, String jobEvent) { + _messageBus.publish(null, AsyncJob.Topics.JOB_EVENT_PUBLISH, PublishScope.LOCAL, + new Pair(job, jobEvent)); + } } diff --git a/framework/jobs/test/org/apache/cloudstack/framework/jobs/AsyncJobManagerTest.java b/framework/jobs/test/org/apache/cloudstack/framework/jobs/AsyncJobManagerTest.java new file mode 100644 index 0000000000..62a8d81ced --- /dev/null +++ b/framework/jobs/test/org/apache/cloudstack/framework/jobs/AsyncJobManagerTest.java @@ -0,0 +1,129 @@ +// 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.framework.jobs; + +/* + * This integration test requires real DB setup, it is not meant to run at per-build + * basis, it can only be opened in developer's run + * + * + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(locations = "classpath:/AsyncJobManagerTestContext.xml") +public class AsyncJobManagerTest extends TestCase { + private static final Logger s_logger = + Logger.getLogger(AsyncJobManagerTest.class); + + @Inject + AsyncJobManager _jobMgr; + + @Inject + AsyncJobTestDashboard _testDashboard; + + @Override + @Before + public void setUp() throws Exception { + try { + ComponentContext.initComponentsLifeCycle(); + } catch (Exception ex) { + ex.printStackTrace(); + s_logger.error(ex.getMessage()); + } + } + + @Override + @After + public void tearDown() throws Exception { + } + + public void testWaitBehave() { + + final Object me = this; + new Thread(new Runnable() { + + @Override + public void run() { + s_logger.info("Sleeping..."); + try { + Thread.sleep(3000); + } catch (InterruptedException e) { + } + + s_logger.info("wakeup"); + synchronized (me) { + me.notifyAll(); + } + } + + }).start(); + + s_logger.info("First wait"); + synchronized (me) { + try { + wait(5000); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + s_logger.info("First wait done"); + + s_logger.info("Second wait"); + synchronized (me) { + try { + wait(5000); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + s_logger.info("Second wait done"); + } + + @Test + public void test() { + final int TOTAL_JOBS_PER_QUEUE = 5; + final int TOTAL_QUEUES = 100; + + for (int i = 0; i < TOTAL_QUEUES; i++) { + for (int j = 0; j < TOTAL_JOBS_PER_QUEUE; j++) { + AsyncJobVO job = new AsyncJobVO(); + job.setCmd("TestCmd"); + job.setDispatcher("TestJobDispatcher"); + job.setCmdInfo("TestCmd info"); + + _jobMgr.submitAsyncJob(job, "fakequeue", i); + + s_logger.info("Job submitted. job " + job.getId() + ", queue: " + i); + } + } + + while (true) { + if (_testDashboard.getCompletedJobCount() == TOTAL_JOBS_PER_QUEUE * TOTAL_QUEUES) + break; + + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + } + } + + s_logger.info("Test done with " + _testDashboard.getCompletedJobCount() + " job executed"); + } +} + +*/ diff --git a/framework/jobs/test/org/apache/cloudstack/framework/jobs/AsyncJobManagerTestConfiguration.java b/framework/jobs/test/org/apache/cloudstack/framework/jobs/AsyncJobManagerTestConfiguration.java new file mode 100644 index 0000000000..a70913cd98 --- /dev/null +++ b/framework/jobs/test/org/apache/cloudstack/framework/jobs/AsyncJobManagerTestConfiguration.java @@ -0,0 +1,54 @@ +/* + * 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.framework.jobs; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import org.apache.cloudstack.framework.config.ConfigDepot; +import org.apache.cloudstack.framework.config.ScopedConfigStorage; +import org.apache.cloudstack.framework.config.dao.ConfigurationDao; +import org.apache.cloudstack.framework.config.dao.ConfigurationDaoImpl; +import org.apache.cloudstack.framework.config.impl.ConfigDepotImpl; + +import com.cloud.storage.dao.StoragePoolDetailsDaoImpl; + +@Configuration +public class AsyncJobManagerTestConfiguration { + + @Bean + public ConfigDepot configDepot() { + return new ConfigDepotImpl(); + } + + @Bean + public ConfigurationDao configDao() { + return new ConfigurationDaoImpl(); + } + + @Bean + public ScopedConfigStorage scopedConfigStorage() { + return new StoragePoolDetailsDaoImpl(); + } + + @Bean + public AsyncJobTestDashboard testDashboard() { + return new AsyncJobTestDashboard(); + } +} diff --git a/framework/jobs/test/org/apache/cloudstack/framework/jobs/AsyncJobTestDashboard.java b/framework/jobs/test/org/apache/cloudstack/framework/jobs/AsyncJobTestDashboard.java new file mode 100644 index 0000000000..728138d2b4 --- /dev/null +++ b/framework/jobs/test/org/apache/cloudstack/framework/jobs/AsyncJobTestDashboard.java @@ -0,0 +1,47 @@ +/* + * 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.framework.jobs; + +public class AsyncJobTestDashboard { + int _completedJobCount = 0; + int _concurrencyCount = 0; + + public AsyncJobTestDashboard() { + } + + public synchronized int getCompletedJobCount() { + return _completedJobCount; + } + + public synchronized void jobCompleted() { + _completedJobCount++; + } + + public synchronized int getConcurrencyCount() { + return _concurrencyCount; + } + + public synchronized void increaseConcurrency() { + _concurrencyCount++; + } + + public synchronized void decreaseConcurrency() { + _concurrencyCount--; + } +} diff --git a/framework/jobs/test/org/apache/cloudstack/framework/jobs/AsyncJobTestDispatcher.java b/framework/jobs/test/org/apache/cloudstack/framework/jobs/AsyncJobTestDispatcher.java new file mode 100644 index 0000000000..34351a6c93 --- /dev/null +++ b/framework/jobs/test/org/apache/cloudstack/framework/jobs/AsyncJobTestDispatcher.java @@ -0,0 +1,62 @@ +// 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.framework.jobs; + +import java.util.Random; + +import javax.inject.Inject; + +import org.apache.log4j.Logger; + +import org.apache.cloudstack.jobs.JobInfo.Status; + +import com.cloud.utils.component.AdapterBase; + +public class AsyncJobTestDispatcher extends AdapterBase implements AsyncJobDispatcher { + private static final Logger s_logger = + Logger.getLogger(AsyncJobTestDispatcher.class); + + @Inject + private AsyncJobManager _asyncJobMgr; + + @Inject + private AsyncJobTestDashboard _testDashboard; + + Random _random = new Random(); + + public AsyncJobTestDispatcher() { + } + + @Override + public void runJob(final AsyncJob job) { + _testDashboard.increaseConcurrency(); + + s_logger.info("Execute job " + job.getId() + ", current concurrency " + _testDashboard.getConcurrencyCount()); + + int interval = 3000; + + try { + Thread.sleep(interval); + } catch (InterruptedException e) { + } + + _asyncJobMgr.completeAsyncJob(job.getId(), Status.SUCCEEDED, 0, null); + + _testDashboard.decreaseConcurrency(); + _testDashboard.jobCompleted(); + } +} diff --git a/framework/jobs/test/resources/AsyncJobManagerTestContext.xml b/framework/jobs/test/resources/AsyncJobManagerTestContext.xml new file mode 100644 index 0000000000..fd5db304c2 --- /dev/null +++ b/framework/jobs/test/resources/AsyncJobManagerTestContext.xml @@ -0,0 +1,38 @@ + + + + + + + + + + diff --git a/framework/jobs/test/resources/commonContext.xml b/framework/jobs/test/resources/commonContext.xml new file mode 100644 index 0000000000..6c3ca75b45 --- /dev/null +++ b/framework/jobs/test/resources/commonContext.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + diff --git a/framework/jobs/test/resources/db.properties b/framework/jobs/test/resources/db.properties new file mode 100644 index 0000000000..e07d80c112 --- /dev/null +++ b/framework/jobs/test/resources/db.properties @@ -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. + +cluster.servlet.port=9090 + +# CloudStack database settings +db.cloud.username=cloud +db.cloud.password=cloud +db.root.password= +db.cloud.host=localhost +db.cloud.port=3306 +db.cloud.name=cloud + +# CloudStack database tuning parameters +db.cloud.maxActive=250 +db.cloud.maxIdle=30 +db.cloud.maxWait=10000 +db.cloud.autoReconnect=true +db.cloud.validationQuery=SELECT 1 +db.cloud.testOnBorrow=true +db.cloud.testWhileIdle=true +db.cloud.timeBetweenEvictionRunsMillis=40000 +db.cloud.minEvictableIdleTimeMillis=240000 +db.cloud.poolPreparedStatements=false +db.cloud.url.params=prepStmtCacheSize=517&cachePrepStmts=true&prepStmtCacheSqlLimit=4096 + +# usage database settings +db.usage.username=cloud +db.usage.password=cloud +db.usage.host=localhost +db.usage.port=3306 +db.usage.name=cloud_usage + +# usage database tuning parameters +db.usage.maxActive=100 +db.usage.maxIdle=30 +db.usage.maxWait=10000 +db.usage.autoReconnect=true + +# awsapi database settings +db.awsapi.name=cloudbridge + +# Simulator database settings +db.simulator.username=cloud +db.simulator.password=cloud +db.simulator.host=localhost +db.simulator.port=3306 +db.simulator.name=simulator +db.simulator.maxActive=250 +db.simulator.maxIdle=30 +db.simulator.maxWait=10000 +db.simulator.autoReconnect=true diff --git a/framework/jobs/test/resources/log4j.properties b/framework/jobs/test/resources/log4j.properties new file mode 100644 index 0000000000..1119ecbba0 --- /dev/null +++ b/framework/jobs/test/resources/log4j.properties @@ -0,0 +1,35 @@ +# 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. + +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.Target=System.out +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n +log4j.appender.stdout.threshold=DEBUG +log4j.rootLogger=INFO, rolling +log4j.appender.rolling=org.apache.log4j.DailyRollingFileAppender +log4j.appender.rolling.layout=org.apache.log4j.PatternLayout +log4j.appender.rolling.layout.ConversionPattern=%d %-5p [%c{3}] (%t:%x) %m%n +log4j.appender.rolling.file.threshold=DEBUG +log4j.appender.rolling.File_testDashboard=./logs/testclient.log +log4j.appender.rolling.DatePattern='.'yyy-MM-dd +log4j.appender.rolling.file.append=false +log4j.category.org.apache=DEBUG, rolling, stdout +#log4j.category.com.cloud.utils.db.Transaction=ALL +log4j.category.org.apache.cloudstack.network.contrail=ALL +log4j.category.com.cloud.network=ALL + diff --git a/framework/security/src/org/apache/cloudstack/framework/security/keys/KeysManagerImpl.java b/framework/security/src/org/apache/cloudstack/framework/security/keys/KeysManagerImpl.java index 550bd155c9..15bb49c65f 100644 --- a/framework/security/src/org/apache/cloudstack/framework/security/keys/KeysManagerImpl.java +++ b/framework/security/src/org/apache/cloudstack/framework/security/keys/KeysManagerImpl.java @@ -61,7 +61,7 @@ public class KeysManagerImpl implements KeysManager, Configurable { public String getHashKey() { String value = HashKey.value(); if (value == null) { - _configDepot.set(HashKey, getBase64EncodedRandomKey(128)); + _configDao.getValueAndInitIfNotExist(HashKey.key(), HashKey.category(), getBase64EncodedRandomKey(128), HashKey.description()); } return HashKey.value(); @@ -71,7 +71,8 @@ public String getHashKey() { public String getEncryptionKey() { String value = EncryptionKey.value(); if (value == null) { - _configDepot.set(EncryptionKey, getBase64EncodedRandomKey(128)); + _configDao.getValueAndInitIfNotExist(EncryptionKey.key(), EncryptionKey.category(), getBase64EncodedRandomKey(128), + EncryptionKey.description()); } return EncryptionKey.value(); } @@ -80,7 +81,8 @@ public String getEncryptionKey() { public String getEncryptionIV() { String value = EncryptionIV.value(); if (value == null) { - _configDepot.set(EncryptionIV, getBase64EncodedRandomKey(128)); + _configDao.getValueAndInitIfNotExist(EncryptionIV.key(), EncryptionIV.category(), getBase64EncodedRandomKey(128), + EncryptionIV.description()); } return EncryptionIV.value(); } diff --git a/framework/security/src/org/apache/cloudstack/framework/security/keystore/KeystoreDao.java b/framework/security/src/org/apache/cloudstack/framework/security/keystore/KeystoreDao.java index e60e4b004c..67eea92886 100644 --- a/framework/security/src/org/apache/cloudstack/framework/security/keystore/KeystoreDao.java +++ b/framework/security/src/org/apache/cloudstack/framework/security/keystore/KeystoreDao.java @@ -28,4 +28,6 @@ public interface KeystoreDao extends GenericDao { void save(String alias, String certificate, Integer index, String domainSuffix); List findCertChain(); + + List findCertChain(String domainSuffix); } diff --git a/framework/security/src/org/apache/cloudstack/framework/security/keystore/KeystoreDaoImpl.java b/framework/security/src/org/apache/cloudstack/framework/security/keystore/KeystoreDaoImpl.java index cd24611a86..b856582ac1 100644 --- a/framework/security/src/org/apache/cloudstack/framework/security/keystore/KeystoreDaoImpl.java +++ b/framework/security/src/org/apache/cloudstack/framework/security/keystore/KeystoreDaoImpl.java @@ -38,6 +38,7 @@ public class KeystoreDaoImpl extends GenericDaoBase implements KeystoreDao { protected final SearchBuilder FindByNameSearch; protected final SearchBuilder CertChainSearch; + protected final SearchBuilder CertChainSearchForDomainSuffix; public KeystoreDaoImpl() { FindByNameSearch = createSearchBuilder(); @@ -47,6 +48,11 @@ public KeystoreDaoImpl() { CertChainSearch = createSearchBuilder(); CertChainSearch.and("key", CertChainSearch.entity().getKey(), Op.NULL); CertChainSearch.done(); + + CertChainSearchForDomainSuffix = createSearchBuilder(); + CertChainSearchForDomainSuffix.and("key", CertChainSearchForDomainSuffix.entity().getKey(), Op.NULL); + CertChainSearchForDomainSuffix.and("domainSuffix", CertChainSearchForDomainSuffix.entity().getDomainSuffix(), Op.EQ); + CertChainSearchForDomainSuffix.done(); } @Override @@ -64,6 +70,19 @@ public int compare(Object o1, Object o2) { return ks; } + @Override + public List findCertChain(String domainSuffix) { + SearchCriteria sc = CertChainSearchForDomainSuffix.create(); + sc.setParameters("domainSuffix", domainSuffix); + List ks = listBy(sc); + Collections.sort(ks, new Comparator() { public int compare(Object o1, Object o2) { + Integer seq1 = ((KeystoreVO)o1).getIndex(); + Integer seq2 = ((KeystoreVO)o2).getIndex(); + return seq1.compareTo(seq2); + }}); + return ks; + } + @Override public KeystoreVO findByName(String name) { assert (name != null); diff --git a/framework/security/src/org/apache/cloudstack/framework/security/keystore/KeystoreManager.java b/framework/security/src/org/apache/cloudstack/framework/security/keystore/KeystoreManager.java index 3b99947c4b..c44347c85e 100644 --- a/framework/security/src/org/apache/cloudstack/framework/security/keystore/KeystoreManager.java +++ b/framework/security/src/org/apache/cloudstack/framework/security/keystore/KeystoreManager.java @@ -28,15 +28,18 @@ public static class Certificates { private String privCert; @LogLevel(Log4jLevel.Off) private String certChain; + @LogLevel(Log4jLevel.Off) + private String rootCACert; public Certificates() { } - public Certificates(String prvKey, String privCert, String certChain) { - privKey = prvKey; + public Certificates(String prvKey, String privCert, String certChain, String rootCACert) { + this.privKey = prvKey; this.privCert = privCert; this.certChain = certChain; + this.rootCACert = rootCACert; } public String getPrivKey() { @@ -50,6 +53,10 @@ public String getPrivCert() { public String getCertChain() { return certChain; } + + public String getRootCACert() { + return rootCACert; + } } boolean validateCertificate(String certificate, String key, String domainSuffix); diff --git a/framework/security/src/org/apache/cloudstack/framework/security/keystore/KeystoreManagerImpl.java b/framework/security/src/org/apache/cloudstack/framework/security/keystore/KeystoreManagerImpl.java index 306083492a..374c080413 100644 --- a/framework/security/src/org/apache/cloudstack/framework/security/keystore/KeystoreManagerImpl.java +++ b/framework/security/src/org/apache/cloudstack/framework/security/keystore/KeystoreManagerImpl.java @@ -23,6 +23,7 @@ import java.security.cert.CertificateException; import java.security.spec.InvalidKeySpecException; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -30,6 +31,7 @@ import javax.ejb.Local; import javax.inject.Inject; +import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -129,17 +131,22 @@ public Certificates getCertificates(String name) { } String prvKey = ksVo.getKey(); String prvCert = ksVo.getCertificate(); + String domainSuffix = ksVo.getDomainSuffix(); String certChain = null; - List certchains = _ksDao.findCertChain(); + String rootCert = null; + List certchains = _ksDao.findCertChain(domainSuffix); if (certchains.size() > 0) { - StringBuilder chains = new StringBuilder(); + ArrayList chains = new ArrayList(); for (KeystoreVO cert : certchains) { - chains.append(cert.getCertificate()); - chains.append("\n"); + if (chains.size() == 0) {// For the first time it will be length 0 + rootCert = cert.getCertificate(); + } + chains.add(cert.getCertificate()); } - certChain = chains.toString(); + Collections.reverse(chains); + certChain = StringUtils.join(chains, "\n"); } - Certificates certs = new Certificates(prvKey, prvCert, certChain); + Certificates certs = new Certificates(prvKey, prvCert, certChain, rootCert); return certs; } diff --git a/packaging/centos63/cloud-agent.rc b/packaging/centos63/cloud-agent.rc index ece4c2732f..1f371e9fc2 100755 --- a/packaging/centos63/cloud-agent.rc +++ b/packaging/centos63/cloud-agent.rc @@ -26,7 +26,7 @@ # set environment variables -SHORTNAME=`basename $0` +SHORTNAME=$(basename $0 | sed -e 's/^[SK][0-9][0-9]//') PIDFILE=/var/run/"$SHORTNAME".pid LOCKFILE=/var/lock/subsys/"$SHORTNAME" LOGDIR=/var/log/cloudstack/agent diff --git a/packaging/centos63/cloud-usage.rc b/packaging/centos63/cloud-usage.rc index a9b6047887..7768d2b7ac 100755 --- a/packaging/centos63/cloud-usage.rc +++ b/packaging/centos63/cloud-usage.rc @@ -47,7 +47,7 @@ unset OPTIONS [ -r /etc/sysconfig/default/"$SHORTNAME" ] && source /etc/sysconfig/default/"$SHORTNAME" # The first existing directory is used for JAVA_HOME (if JAVA_HOME is not defined in $DEFAULT) -JDK_DIRS="/usr/lib/jvm/java-6-openjdk /usr/lib/jvm/java-6-openjdk-i386 /usr/lib/jvm/java-6-openjdk-amd64 /usr/lib/jvm/java-6-sun /usr/lib/jvm/jre-1.6.0 /usr/lib/j2sdk1.5-sun /usr/lib/jre-openjdk" +JDK_DIRS="/usr/lib/jvm/java-7-openjdk /usr/lib/jvm/java-7-openjdk-i386 /usr/lib/jvm/java-7-openjdk-amd64 /usr/lib/jvm/java-7-sun /usr/lib/jvm/jre-1.7.0 /usr/lib/j2sdk1.5-sun /usr/lib/jre-openjdk" for jdir in $JDK_DIRS; do if [ -r "$jdir/bin/java" -a -z "${JAVA_HOME}" ]; then @@ -59,9 +59,9 @@ export JAVA_HOME SCP="" DCP="" UCP=`ls /usr/share/cloudstack-usage/cloud-usage-*.jar`":"`ls /usr/share/cloudstack-usage/lib/*.jar | tr '\n' ':'` -JCP="/usr/share/java/commons-daemon.jar" +JCP="/usr/share/java/commons-daemon.jar":"/usr/share/java/mysql-connector-java.jar" -# We need to append the JSVC daemon JAR to the classpath +# We need to append the JSVC daemon and mysql-connector JAR to the classpath # AgentShell implements the JSVC daemon methods export CLASSPATH="$SCP:$DCP:$UCP:$JCP:/etc/cloudstack/usage" diff --git a/packaging/centos63/cloud.spec b/packaging/centos63/cloud.spec index 83c598b07a..e10aeaae66 100644 --- a/packaging/centos63/cloud.spec +++ b/packaging/centos63/cloud.spec @@ -60,7 +60,7 @@ intelligent IaaS cloud implementation. %package management Summary: CloudStack management server UI Requires: tomcat6 -Requires: java >= 1.7.0 +Requires: java7 Requires: python Requires: bash Requires: bzip2 @@ -112,7 +112,7 @@ The Apache CloudStack files shared between agent and management server %package agent Summary: CloudStack Agent for KVM hypervisors Requires: openssh-clients -Requires: java >= 1.7.0 +Requires: java7 Requires: %{name}-common = %{_ver} Requires: libvirt Requires: bridge-utils @@ -136,9 +136,21 @@ Group: System Environment/Libraries %description agent The CloudStack agent for KVM hypervisors +%package baremetal-agent +Summary: CloudStack baremetal agent +Requires: tftp-server +Requires: xinetd +Requires: syslinux +Requires: chkconfig +Requires: dhcp +Requires: httpd +Group: System Environment/Libraries +%description baremetal-agent +The CloudStack baremetal agent + %package usage Summary: CloudStack Usage calculation server -Requires: java >= 1.7.0 +Requires: java7 Requires: jsvc Requires: jakarta-commons-daemon Requires: jakarta-commons-daemon-jsvc @@ -225,7 +237,6 @@ mkdir -p ${RPM_BUILD_ROOT}%{_datadir}/%{name}-management/setup mkdir -p ${RPM_BUILD_ROOT}%{_localstatedir}/log/%{name}/management mkdir -p ${RPM_BUILD_ROOT}%{_localstatedir}/log/%{name}/awsapi mkdir -p ${RPM_BUILD_ROOT}%{_sysconfdir}/%{name}/management -mkdir -p ${RPM_BUILD_ROOT}%{_localstatedir}/log/%{name}-management # Specific for tomcat mkdir -p ${RPM_BUILD_ROOT}%{_sysconfdir}/%{name}/management/Catalina/localhost/client @@ -244,6 +255,7 @@ install -D client/target/utilities/bin/cloud-set-guest-sshkey ${RPM_BUILD_ROOT}% install -D client/target/utilities/bin/cloud-setup-databases ${RPM_BUILD_ROOT}%{_bindir}/%{name}-setup-databases install -D client/target/utilities/bin/cloud-setup-encryption ${RPM_BUILD_ROOT}%{_bindir}/%{name}-setup-encryption install -D client/target/utilities/bin/cloud-setup-management ${RPM_BUILD_ROOT}%{_bindir}/%{name}-setup-management +install -D client/target/utilities/bin/cloud-setup-baremetal ${RPM_BUILD_ROOT}%{_bindir}/%{name}-setup-baremetal install -D client/target/utilities/bin/cloud-sysvmadm ${RPM_BUILD_ROOT}%{_bindir}/%{name}-sysvmadm install -D client/target/utilities/bin/cloud-update-xenserver-licenses ${RPM_BUILD_ROOT}%{_bindir}/%{name}-update-xenserver-licenses @@ -282,7 +294,6 @@ chmod 770 ${RPM_BUILD_ROOT}%{_localstatedir}/cache/%{name}/management/work chmod 770 ${RPM_BUILD_ROOT}%{_localstatedir}/cache/%{name}/management/temp chmod 770 ${RPM_BUILD_ROOT}%{_localstatedir}/log/%{name}/management chmod 770 ${RPM_BUILD_ROOT}%{_localstatedir}/log/%{name}/agent -chmod 770 ${RPM_BUILD_ROOT}%{_localstatedir}/log/%{name}-management # KVM Agent mkdir -p ${RPM_BUILD_ROOT}%{_sysconfdir}/%{name}/agent @@ -571,7 +582,6 @@ fi %attr(0755,root,root) %{_bindir}/%{name}-external-ipallocator.py %attr(0755,root,root) %{_initrddir}/%{name}-ipallocator %dir %attr(0770,root,root) %{_localstatedir}/log/%{name}/ipallocator -%dir %attr(0770,root,root) %{_localstatedir}/log/%{name}-management %{_defaultdocdir}/%{name}-management-%{version}/LICENSE %{_defaultdocdir}/%{name}-management-%{version}/NOTICE %attr(0644,cloud,cloud) %{_localstatedir}/log/%{name}/management/catalina.out @@ -633,6 +643,9 @@ fi %{_defaultdocdir}/%{name}-awsapi-%{version}/LICENSE %{_defaultdocdir}/%{name}-awsapi-%{version}/NOTICE +%files baremetal-agent +%attr(0755,root,root) %{_bindir}/cloudstack-setup-baremetal + %changelog * Fri Oct 03 2012 Hugo Trippaers 4.1.0 diff --git a/packaging/debian/init/cloud-agent b/packaging/debian/init/cloud-agent index e7338752f3..ff550bb8f6 100755 --- a/packaging/debian/init/cloud-agent +++ b/packaging/debian/init/cloud-agent @@ -96,7 +96,7 @@ start() { wait_for_network - if start_daemon -p $PIDFILE $DAEMON -cp "$CLASSPATH" -pidfile "$PIDFILE" -errfile SYSLOG $CLASS + if start_daemon -p $PIDFILE $DAEMON -cp "$CLASSPATH" -Djna.nosys=true -pidfile "$PIDFILE" -errfile SYSLOG $CLASS RETVAL=$? then rc=0 diff --git a/plugins/database/mysql-ha/pom.xml b/plugins/database/mysql-ha/pom.xml index 5ce6d6f52b..28f136c5af 100644 --- a/plugins/database/mysql-ha/pom.xml +++ b/plugins/database/mysql-ha/pom.xml @@ -16,7 +16,7 @@ org.apache.cloudstack cloudstack-plugins 4.4.0-SNAPSHOT - ../pom.xml + ../../pom.xml diff --git a/plugins/event-bus/rabbitmq/src/org/apache/cloudstack/mom/rabbitmq/RabbitMQEventBus.java b/plugins/event-bus/rabbitmq/src/org/apache/cloudstack/mom/rabbitmq/RabbitMQEventBus.java index 8403271af8..a1f4c2b8b2 100644 --- a/plugins/event-bus/rabbitmq/src/org/apache/cloudstack/mom/rabbitmq/RabbitMQEventBus.java +++ b/plugins/event-bus/rabbitmq/src/org/apache/cloudstack/mom/rabbitmq/RabbitMQEventBus.java @@ -60,6 +60,18 @@ public class RabbitMQEventBus extends ManagerBase implements EventBus { private static String username; private static String password; + public static void setVirtualHost(String virtualHost) { + RabbitMQEventBus.virtualHost = virtualHost; + } + + private static String virtualHost; + + public static void setUseSsl(String useSsl) { + RabbitMQEventBus.useSsl = useSsl; + } + + private static String useSsl; + // AMQP exchange name where all CloudStack events will be published private static String amqpExchangeName; @@ -104,6 +116,12 @@ public boolean configure(String name, Map params) throws Configu throw new ConfigurationException("Unable to get the port details of AMQP server"); } + if (useSsl != null && !useSsl.isEmpty()) { + if (!useSsl.equalsIgnoreCase("true") && !useSsl.equalsIgnoreCase("false")) { + throw new ConfigurationException("Invalid configuration parameter for 'ssl'."); + } + } + if (retryInterval == null) { retryInterval = 10000;// default to 10s to try out reconnect } @@ -345,9 +363,18 @@ private synchronized Connection createConnection() throws Exception { ConnectionFactory factory = new ConnectionFactory(); factory.setUsername(username); factory.setPassword(password); - factory.setVirtualHost("/"); factory.setHost(amqpHost); factory.setPort(port); + + if (virtualHost != null && !virtualHost.isEmpty()) { + factory.setVirtualHost(virtualHost); + } else { + factory.setVirtualHost("/"); + } + + if (useSsl != null && !useSsl.isEmpty() && useSsl.equalsIgnoreCase("true")) { + factory.useSslProtocol(); + } Connection connection = factory.newConnection(); connection.addShutdownListener(disconnectHandler); s_connection = connection; diff --git a/plugins/hypervisors/baremetal/pom.xml b/plugins/hypervisors/baremetal/pom.xml index eb2a0d1870..8f1237e480 100755 --- a/plugins/hypervisors/baremetal/pom.xml +++ b/plugins/hypervisors/baremetal/pom.xml @@ -27,11 +27,11 @@ cloud-plugin-hypervisor-baremetal Apache CloudStack Plugin - Hypervisor Baremetal - - commons-lang - commons-lang - 2.6 - + + commons-lang + commons-lang + 2.6 + diff --git a/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-compute/spring-baremetal-compute-context.xml b/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-compute/spring-baremetal-compute-context.xml index cce6805123..d0b52a1bb0 100644 --- a/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-compute/spring-baremetal-compute-context.xml +++ b/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-compute/spring-baremetal-compute-context.xml @@ -31,5 +31,5 @@ - + diff --git a/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-discoverer/spring-baremetal-discoverer-context.xml b/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-discoverer/spring-baremetal-discoverer-context.xml index 8792909ffe..c01d9c62af 100644 --- a/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-discoverer/spring-baremetal-discoverer-context.xml +++ b/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-discoverer/spring-baremetal-discoverer-context.xml @@ -30,5 +30,5 @@ - + diff --git a/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-network/spring-baremetal-network-context.xml b/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-network/spring-baremetal-network-context.xml index 40d9f50577..c5068e7b14 100644 --- a/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-network/spring-baremetal-network-context.xml +++ b/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-network/spring-baremetal-network-context.xml @@ -42,5 +42,5 @@ - + diff --git a/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-planner/spring-baremetal-planner-context.xml b/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-planner/spring-baremetal-planner-context.xml index 8c14c3e290..046aca67e8 100644 --- a/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-planner/spring-baremetal-planner-context.xml +++ b/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-planner/spring-baremetal-planner-context.xml @@ -30,5 +30,5 @@ - + diff --git a/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/core/spring-baremetal-core-context.xml b/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/core/spring-baremetal-core-context.xml index 11cc6c89e3..a77406d98d 100644 --- a/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/core/spring-baremetal-core-context.xml +++ b/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/core/spring-baremetal-core-context.xml @@ -38,5 +38,5 @@ - + diff --git a/plugins/hypervisors/baremetal/resources/security_group_agent/cs-sgagent b/plugins/hypervisors/baremetal/resources/security_group_agent/cs-sgagent index 02426d0aa1..f8a5d7d2c9 100755 --- a/plugins/hypervisors/baremetal/resources/security_group_agent/cs-sgagent +++ b/plugins/hypervisors/baremetal/resources/security_group_agent/cs-sgagent @@ -18,9 +18,9 @@ # 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 @@ -29,31 +29,31 @@ # under the License. check_status() { - pidfile='/var/run/cssgagent.pid' - if [ ! -f $pidfile ]; then - echo "cloudstack baremetal security group agent is stopped" - exit 1 - else - pid=`cat $pidfile` - ps -p $pid > /dev/null - if [ $? -eq 0 ]; then - echo "cloudstack baremetal security group agent is running, pid is $pid" - exit 0 - else - echo "cloudstack baremetal security group agent is stopped, but pidfile at $pidfile is not cleaned. It may be caused by the agent crashed at last time, manually cleaning it would be ok" - exit 1 - fi - fi + pidfile='/var/run/cssgagent.pid' + if [ ! -f $pidfile ]; then + echo "cloudstack baremetal security group agent is stopped" + exit 1 + else + pid=`cat $pidfile` + ps -p $pid > /dev/null + if [ $? -eq 0 ]; then + echo "cloudstack baremetal security group agent is running, pid is $pid" + exit 0 + else + echo "cloudstack baremetal security group agent is stopped, but pidfile at $pidfile is not cleaned. It may be caused by the agent crashed at last time, manually cleaning it would be ok" + exit 1 + fi + fi } if [ $# -eq 0 ]; then - echo "usage: $0 + echo "usage: $0 [start|stop|restart|status]" - exit 1 + exit 1 fi if [ "$@" = "status" ]; then - check_status + check_status else python -c "from security_group_agent import cs_sg_agent; cs_sg_agent.main()" $@ fi diff --git a/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/__init__.py b/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/__init__.py index f7f5f60ff0..76bd5c1b21 100644 --- a/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/__init__.py +++ b/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/__init__.py @@ -5,14 +5,14 @@ # 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. -# +# # Automatically generated by addcopyright.py at 01/29/2013 diff --git a/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/cs_sg_agent.py b/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/cs_sg_agent.py index a292c0bcfb..0c49a3f786 100755 --- a/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/cs_sg_agent.py +++ b/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/cs_sg_agent.py @@ -5,16 +5,16 @@ # 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. -# +# # Automatically generated by addcopyright.py at 01/29/2013 ''' Created on Jan 2, 2013 @@ -234,4 +234,3 @@ def main(): agentdaemon.restart() sys.exit(0) - \ No newline at end of file diff --git a/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/sglib.py b/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/sglib.py index bf64effa19..bc675b540a 100755 --- a/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/sglib.py +++ b/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/sglib.py @@ -6,16 +6,16 @@ # 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. -# +# # Automatically generated by addcopyright.py at 01/29/2013 import sys, os, time, atexit @@ -31,7 +31,7 @@ def __init__(self): self.body = None self.method = None self.query_string = None - + @staticmethod def from_cherrypy_request(creq): req = Request() @@ -40,10 +40,10 @@ def from_cherrypy_request(creq): req.method = copy.copy(creq.method) req.query_string = copy.copy(creq.query_string) if creq.query_string else None return req - + class ShellError(Exception): '''shell error''' - + class ShellCmd(object): ''' classdocs @@ -57,11 +57,11 @@ def __init__(self, cmd, workdir=None, pipe=True): self.process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE, executable='/bin/sh', cwd=workdir) else: self.process = subprocess.Popen(cmd, shell=True, executable='/bin/sh', cwd=workdir) - + self.stdout = None self.stderr = None self.return_code = None - + def __call__(self, is_exception=True): (self.stdout, self.stderr) = self.process.communicate() if is_exception and self.process.returncode != 0: @@ -71,18 +71,18 @@ def __call__(self, is_exception=True): err.append('stdout: %s' % self.stdout) err.append('stderr: %s' % self.stderr) raise ShellError('\n'.join(err)) - + self.return_code = self.process.returncode return self.stdout class Daemon(object): """ A generic daemon class. - + Usage: subclass the Daemon class and override the run() method """ atexit_hooks = [] - + def __init__(self, pidfile, stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'): self.stdin = stdin self.stdout = stdout @@ -102,37 +102,37 @@ def _atexit(): content = traceback.format_exc() err = 'Exception when calling atexit hook[%s]\n%s' % (hook.__name__, content) #logger.error(err) - + def daemonize(self): """ - do the UNIX double-fork magic, see Stevens' "Advanced + do the UNIX double-fork magic, see Stevens' "Advanced Programming in the UNIX Environment" for details (ISBN 0201563177) http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16 """ - try: - pid = os.fork() + try: + pid = os.fork() if pid > 0: # exit first parent - sys.exit(0) - except OSError, e: + sys.exit(0) + except OSError, e: sys.stderr.write("fork #1 failed: %d (%s)\n" % (e.errno, e.strerror)) sys.exit(1) - + # decouple from parent environment - os.chdir("/") - os.setsid() - os.umask(0) - + os.chdir("/") + os.setsid() + os.umask(0) + # do second fork - try: - pid = os.fork() + try: + pid = os.fork() if pid > 0: # exit from second parent - sys.exit(0) - except OSError, e: + sys.exit(0) + except OSError, e: sys.stderr.write("fork #2 failed: %d (%s)\n" % (e.errno, e.strerror)) - sys.exit(1) - + sys.exit(1) + # redirect standard file descriptors sys.stdout.flush() sys.stderr.flush() @@ -142,13 +142,13 @@ def daemonize(self): os.dup2(si.fileno(), sys.stdin.fileno()) os.dup2(so.fileno(), sys.stdout.fileno()) os.dup2(se.fileno(), sys.stderr.fileno()) - + # write pidfile Daemon.register_atexit_hook(self.delpid) atexit.register(Daemon._atexit) pid = str(os.getpid()) file(self.pidfile,'w').write("%s\n" % pid) - + def delpid(self): os.remove(self.pidfile) @@ -163,7 +163,7 @@ def start(self): pf.close() except IOError: pid = None - + if pid: pscmd = ShellCmd('ps -p %s > /dev/null' % pid) pscmd(is_exception=False) @@ -171,7 +171,7 @@ def start(self): message = "Daemon already running, pid is %s\n" sys.stderr.write(message % pid) sys.exit(0) - + # Start the daemon self.daemonize() try: @@ -192,13 +192,13 @@ def stop(self): pf.close() except IOError: pid = None - + if not pid: message = "pidfile %s does not exist. Daemon not running?\n" sys.stderr.write(message % self.pidfile) return # not an error in a restart - # Try killing the daemon process + # Try killing the daemon process try: while 1: os.kill(pid, SIGTERM) diff --git a/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/xmlobject.py b/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/xmlobject.py index cb66d265a5..175349958c 100755 --- a/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/xmlobject.py +++ b/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/xmlobject.py @@ -5,16 +5,16 @@ # 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. -# +# # Automatically generated by addcopyright.py at 01/29/2013 ''' Created on Dec 25, 2012 diff --git a/plugins/hypervisors/baremetal/resources/security_group_agent/setup.py b/plugins/hypervisors/baremetal/resources/security_group_agent/setup.py index 384e04d6a9..ed106313ff 100755 --- a/plugins/hypervisors/baremetal/resources/security_group_agent/setup.py +++ b/plugins/hypervisors/baremetal/resources/security_group_agent/setup.py @@ -5,16 +5,16 @@ # 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. -# +# # Automatically generated by addcopyright.py at 01/29/2013 from setuptools import setup, find_packages import sys, os diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BareMetalDiscoverer.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BareMetalDiscoverer.java index c312df7b79..8b4b45348f 100755 --- a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BareMetalDiscoverer.java +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BareMetalDiscoverer.java @@ -80,8 +80,8 @@ public boolean stop() { } @Override - public Map> - find(long dcId, Long podId, Long clusterId, URI url, String username, String password, List hostTags) throws DiscoveryException { + public Map> find(long dcId, Long podId, Long clusterId, URI url, String username, String password, List hostTags) + throws DiscoveryException { /* Enable this after we decide to use addBaremetalHostCmd instead of addHostCmd String discoverName = _params.get(ApiConstants.BAREMETAL_DISCOVER_NAME); @@ -130,18 +130,18 @@ public boolean stop() { String injectScript = "scripts/util/ipmi.py"; String scriptPath = Script.findScript("", injectScript); if (scriptPath == null) { - throw new CloudRuntimeException("Unable to find key ipmi script " + injectScript); + throw new CloudRuntimeException("Unable to find key ipmi script " + + injectScript); } final Script2 command = new Script2(scriptPath, s_logger); command.add("ping"); - command.add("hostname=" + ipmiIp); - command.add("usrname=" + username); - command.add("password=" + password, ParamType.PASSWORD); + command.add("hostname="+ipmiIp); + command.add("usrname="+username); + command.add("password="+password, ParamType.PASSWORD); final String result = command.execute(); if (result != null) { - s_logger.warn(String.format("Can not set up ipmi connection(ip=%1$s, username=%2$s, password=%3$s, args) because %4$s", ipmiIp, username, "******", - result)); + s_logger.warn(String.format("Can not set up ipmi connection(ip=%1$s, username=%2$s, password=%3$s, args) because %4$s", ipmiIp, username, "******", result)); return null; } @@ -155,21 +155,22 @@ public boolean stop() { params.putAll(_params); params.put("zone", Long.toString(dcId)); params.put("pod", Long.toString(podId)); - params.put("cluster", Long.toString(clusterId)); + params.put("cluster", Long.toString(clusterId)); params.put("guid", guid); params.put(ApiConstants.PRIVATE_IP, ipmiIp); params.put(ApiConstants.USERNAME, username); params.put(ApiConstants.PASSWORD, password); + params.put("vmDao", _vmDao); + params.put("configDao", _configDao); String resourceClassName = _configDao.getValue(Config.ExternalBaremetalResourceClassName.key()); BareMetalResourceBase resource = null; if (resourceClassName != null) { Class clazz = Class.forName(resourceClassName); - resource = (BareMetalResourceBase)clazz.newInstance(); + resource = (BareMetalResourceBase) clazz.newInstance(); String externalUrl = _configDao.getValue(Config.ExternalBaremetalSystemUrl.key()); if (externalUrl == null) { - throw new IllegalArgumentException( - String.format("You must specify ExternalBaremetalSystemUrl in global config page as ExternalBaremetalResourceClassName is not null")); + throw new IllegalArgumentException(String.format("You must specify ExternalBaremetalSystemUrl in global config page as ExternalBaremetalResourceClassName is not null")); } details.put(BaremetalManager.ExternalBaremetalSystemUrl, externalUrl); } else { @@ -206,8 +207,8 @@ public boolean stop() { zone.setDhcpProvider(Network.Provider.ExternalDhcpServer.getName()); _dcDao.update(zone.getId(), zone); - s_logger.debug(String.format("Discover Bare Metal host successfully(ip=%1$s, username=%2$s, password=%3%s," - + "cpuNum=%4$s, cpuCapacity-%5$s, memCapacity=%6$s)", ipmiIp, username, "******", cpuNum, cpuCapacity, memCapacity)); + s_logger.debug(String.format("Discover Bare Metal host successfully(ip=%1$s, username=%2$s, password=%3%s," + + "cpuNum=%4$s, cpuCapacity-%5$s, memCapacity=%6$s)", ipmiIp, username, "******", cpuNum, cpuCapacity, memCapacity)); return resources; } catch (Exception e) { s_logger.warn("Can not set up bare metal agent", e); @@ -217,7 +218,8 @@ public boolean stop() { } @Override - public void postDiscovery(List hosts, long msId) throws DiscoveryException { + public void postDiscovery(List hosts, long msId) + throws DiscoveryException { } @Override @@ -273,6 +275,8 @@ protected HashMap buildConfigParams(HostVO host) { HashMap params = super.buildConfigParams(host); params.put("hostId", host.getId()); params.put("ipaddress", host.getPrivateIpAddress()); + params.put("vmDao", _vmDao); + params.put("configDao", _configDao); return params; } diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BareMetalResourceBase.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BareMetalResourceBase.java index b729d9bb3e..828533708e 100755 --- a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BareMetalResourceBase.java +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BareMetalResourceBase.java @@ -22,18 +22,6 @@ // Automatically generated by addcopyright.py at 04/03/2012 package com.cloud.baremetal.networkservice; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.TimeUnit; - -import javax.ejb.Local; -import javax.naming.ConfigurationException; - -import org.apache.log4j.Logger; - -import org.apache.cloudstack.api.ApiConstants; - import com.cloud.agent.IAgentControl; import com.cloud.agent.api.Answer; import com.cloud.agent.api.CheckNetworkAnswer; @@ -48,6 +36,7 @@ import com.cloud.agent.api.MigrateCommand; import com.cloud.agent.api.PingCommand; import com.cloud.agent.api.PingRoutingCommand; +import com.cloud.agent.api.PingRoutingWithNwGroupsCommand; import com.cloud.agent.api.PrepareForMigrationAnswer; import com.cloud.agent.api.PrepareForMigrationCommand; import com.cloud.agent.api.ReadyAnswer; @@ -66,10 +55,11 @@ import com.cloud.agent.api.baremetal.IpmiBootorResetCommand; import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.baremetal.manager.BaremetalManager; +import com.cloud.configuration.Config; import com.cloud.host.Host.Type; import com.cloud.hypervisor.Hypervisor; import com.cloud.resource.ServerResource; -import com.cloud.utils.component.ComponentContext; +import com.cloud.utils.Pair; import com.cloud.utils.component.ManagerBase; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.script.OutputInterpreter; @@ -81,6 +71,16 @@ import com.cloud.vm.VirtualMachine.PowerState; import com.cloud.vm.VirtualMachine.State; import com.cloud.vm.dao.VMInstanceDao; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.framework.config.dao.ConfigurationDao; +import org.apache.log4j.Logger; + +import javax.ejb.Local; +import javax.naming.ConfigurationException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; @Local(value = ServerResource.class) public class BareMetalResourceBase extends ManagerBase implements ServerResource { @@ -111,6 +111,9 @@ public class BareMetalResourceBase extends ManagerBase implements ServerResource protected Script2 _forcePowerOffCommand; protected Script2 _bootOrRebootCommand; protected String _vmName; + protected int ipmiRetryTimes = 5; + + protected ConfigurationDao configDao; protected VMInstanceDao vmDao; private void changeVmState(String vmName, VirtualMachine.State state) { @@ -128,27 +131,29 @@ private State removeVmState(String vmName) { @Override public boolean configure(String name, Map params) throws ConfigurationException { _name = name; - _uuid = (String)params.get("guid"); + _uuid = (String) params.get("guid"); try { - _memCapacity = Long.parseLong((String)params.get(ApiConstants.MEMORY)) * 1024L * 1024L; - _cpuCapacity = Long.parseLong((String)params.get(ApiConstants.CPU_SPEED)); - _cpuNum = Long.parseLong((String)params.get(ApiConstants.CPU_NUMBER)); + _memCapacity = Long.parseLong((String) params.get(ApiConstants.MEMORY)) * 1024L * 1024L; + _cpuCapacity = Long.parseLong((String) params.get(ApiConstants.CPU_SPEED)); + _cpuNum = Long.parseLong((String) params.get(ApiConstants.CPU_NUMBER)); } catch (NumberFormatException e) { throw new ConfigurationException(String.format("Unable to parse number of CPU or memory capacity " - + "or cpu capacity(cpu number = %1$s memCapacity=%2$s, cpuCapacity=%3$s", params.get(ApiConstants.CPU_NUMBER), params.get(ApiConstants.MEMORY), - params.get(ApiConstants.CPU_SPEED))); + + "or cpu capacity(cpu number = %1$s memCapacity=%2$s, cpuCapacity=%3$s", params.get(ApiConstants.CPU_NUMBER), + params.get(ApiConstants.MEMORY), params.get(ApiConstants.CPU_SPEED))); } - _zone = (String)params.get("zone"); - _pod = (String)params.get("pod"); - _cluster = (String)params.get("cluster"); - hostId = (Long)params.get("hostId"); - _ip = (String)params.get(ApiConstants.PRIVATE_IP); - _mac = (String)params.get(ApiConstants.HOST_MAC); - _username = (String)params.get(ApiConstants.USERNAME); - _password = (String)params.get(ApiConstants.PASSWORD); - _vmName = (String)params.get("vmName"); - String echoScAgent = (String)params.get(BaremetalManager.EchoSecurityGroupAgent); + _zone = (String) params.get("zone"); + _pod = (String) params.get("pod"); + _cluster = (String) params.get("cluster"); + hostId = (Long) params.get("hostId"); + _ip = (String) params.get(ApiConstants.PRIVATE_IP); + _mac = (String) params.get(ApiConstants.HOST_MAC); + _username = (String) params.get(ApiConstants.USERNAME); + _password = (String) params.get(ApiConstants.PASSWORD); + _vmName = (String) params.get("vmName"); + String echoScAgent = (String) params.get(BaremetalManager.EchoSecurityGroupAgent); + vmDao = (VMInstanceDao) params.get("vmDao"); + configDao = (ConfigurationDao) params.get("configDao"); if (_pod == null) { throw new ConfigurationException("Unable to get the pod"); @@ -167,7 +172,8 @@ public boolean configure(String name, Map params) throws Configu } if (_mac.split(":").length != 6) { - throw new ConfigurationException("Wrong MAC format(" + _mac + "). It must be in format of for example 00:11:ba:33:aa:dd which is not case sensitive"); + throw new ConfigurationException("Wrong MAC format(" + _mac + + "). It must be in format of for example 00:11:ba:33:aa:dd which is not case sensitive"); } if (_uuid == null) { @@ -178,6 +184,19 @@ public boolean configure(String name, Map params) throws Configu _isEchoScAgent = Boolean.valueOf(echoScAgent); } + String ipmiIface = "default"; + try { + ipmiIface = configDao.getValue(Config.BaremetalIpmiLanInterface.key()); + } catch (Exception e) { + s_logger.debug(e.getMessage(), e); + } + + try { + ipmiRetryTimes = Integer.valueOf(configDao.getValue(Config.BaremetalIpmiRetryTimes.key())); + } catch (Exception e) { + s_logger.debug(e.getMessage(), e); + } + String injectScript = "scripts/util/ipmi.py"; String scriptPath = Script.findScript("", injectScript); if (scriptPath == null) { @@ -187,6 +206,7 @@ public boolean configure(String name, Map params) throws Configu _pingCommand = new Script2(pythonPath, s_logger); _pingCommand.add(scriptPath); _pingCommand.add("ping"); + _pingCommand.add("interface=" + ipmiIface); _pingCommand.add("hostname=" + _ip); _pingCommand.add("usrname=" + _username); _pingCommand.add("password=" + _password, ParamType.PASSWORD); @@ -194,6 +214,7 @@ public boolean configure(String name, Map params) throws Configu _setPxeBootCommand = new Script2(pythonPath, s_logger); _setPxeBootCommand.add(scriptPath); _setPxeBootCommand.add("boot_dev"); + _setPxeBootCommand.add("interface=" + ipmiIface); _setPxeBootCommand.add("hostname=" + _ip); _setPxeBootCommand.add("usrname=" + _username); _setPxeBootCommand.add("password=" + _password, ParamType.PASSWORD); @@ -202,6 +223,7 @@ public boolean configure(String name, Map params) throws Configu _setDiskBootCommand = new Script2(pythonPath, s_logger); _setDiskBootCommand.add(scriptPath); _setDiskBootCommand.add("boot_dev"); + _setDiskBootCommand.add("interface=" + ipmiIface); _setDiskBootCommand.add("hostname=" + _ip); _setDiskBootCommand.add("usrname=" + _username); _setDiskBootCommand.add("password=" + _password, ParamType.PASSWORD); @@ -210,6 +232,7 @@ public boolean configure(String name, Map params) throws Configu _rebootCommand = new Script2(pythonPath, s_logger); _rebootCommand.add(scriptPath); _rebootCommand.add("reboot"); + _rebootCommand.add("interface=" + ipmiIface); _rebootCommand.add("hostname=" + _ip); _rebootCommand.add("usrname=" + _username); _rebootCommand.add("password=" + _password, ParamType.PASSWORD); @@ -217,6 +240,7 @@ public boolean configure(String name, Map params) throws Configu _getStatusCommand = new Script2(pythonPath, s_logger); _getStatusCommand.add(scriptPath); _getStatusCommand.add("ping"); + _getStatusCommand.add("interface=" + ipmiIface); _getStatusCommand.add("hostname=" + _ip); _getStatusCommand.add("usrname=" + _username); _getStatusCommand.add("password=" + _password, ParamType.PASSWORD); @@ -224,6 +248,7 @@ public boolean configure(String name, Map params) throws Configu _powerOnCommand = new Script2(pythonPath, s_logger); _powerOnCommand.add(scriptPath); _powerOnCommand.add("power"); + _powerOnCommand.add("interface=" + ipmiIface); _powerOnCommand.add("hostname=" + _ip); _powerOnCommand.add("usrname=" + _username); _powerOnCommand.add("password=" + _password, ParamType.PASSWORD); @@ -232,6 +257,7 @@ public boolean configure(String name, Map params) throws Configu _powerOffCommand = new Script2(pythonPath, s_logger); _powerOffCommand.add(scriptPath); _powerOffCommand.add("power"); + _powerOffCommand.add("interface=" + ipmiIface); _powerOffCommand.add("hostname=" + _ip); _powerOffCommand.add("usrname=" + _username); _powerOffCommand.add("password=" + _password, ParamType.PASSWORD); @@ -240,6 +266,7 @@ public boolean configure(String name, Map params) throws Configu _forcePowerOffCommand = new Script2(pythonPath, s_logger); _forcePowerOffCommand.add(scriptPath); _forcePowerOffCommand.add("power"); + _forcePowerOffCommand.add("interface=" + ipmiIface); _forcePowerOffCommand.add("hostname=" + _ip); _forcePowerOffCommand.add("usrname=" + _username); _forcePowerOffCommand.add("password=" + _password, ParamType.PASSWORD); @@ -248,6 +275,7 @@ public boolean configure(String name, Map params) throws Configu _bootOrRebootCommand = new Script2(pythonPath, s_logger); _bootOrRebootCommand.add(scriptPath); _bootOrRebootCommand.add("boot_or_reboot"); + _bootOrRebootCommand.add("interface=" + ipmiIface); _bootOrRebootCommand.add("hostname=" + _ip); _bootOrRebootCommand.add("usrname=" + _username); _bootOrRebootCommand.add("password=" + _password, ParamType.PASSWORD); @@ -259,8 +287,15 @@ protected boolean doScript(Script cmd) { return doScript(cmd, null); } + protected boolean doScript(Script cmd, int retry) { + return doScript(cmd, null, retry); + } + protected boolean doScript(Script cmd, OutputInterpreter interpreter) { - int retry = 5; + return doScript(cmd, interpreter, ipmiRetryTimes); + } + + protected boolean doScript(Script cmd, OutputInterpreter interpreter, int retry) { String res = null; while (retry-- > 0) { if (interpreter == null) { @@ -270,6 +305,10 @@ protected boolean doScript(Script cmd, OutputInterpreter interpreter) { } if (res != null && res.startsWith("Error: Unable to establish LAN")) { s_logger.warn("IPMI script timeout(" + cmd.toString() + "), will retry " + retry + " times"); + try { + TimeUnit.SECONDS.sleep(1); + } catch (InterruptedException e) { + } continue; } else if (res == null) { return true; @@ -318,7 +357,6 @@ protected State getVmState() { protected Map fullSync() { Map states = new HashMap(); if (hostId != null) { - vmDao = ComponentContext.getComponent(VMInstanceDao.class); final List vms = vmDao.listByHostId(hostId); for (VMInstanceVO vm : vms) { states.put(vm.getInstanceName(), vm.getState()); @@ -337,10 +375,14 @@ protected Map fullSync() { protected Map getHostVmStateReport() { Map states = new HashMap(); if (hostId != null) { - vmDao = ComponentContext.getComponent(VMInstanceDao.class); final List vms = vmDao.listByHostId(hostId); for (VMInstanceVO vm : vms) { - states.put(vm.getInstanceName(), new HostVmStateReportEntry(vm.getState() == State.Running ? PowerState.PowerOn : PowerState.PowerOff, "host-" + hostId)); + states.put( + vm.getInstanceName(), + new HostVmStateReportEntry( + vm.getState() == State.Running ? PowerState.PowerOn : PowerState.PowerOff, "host-" + hostId + ) + ); } } /* @@ -355,7 +397,8 @@ protected Map getHostVmStateReport() { @Override public StartupCommand[] initialize() { - StartupRoutingCommand cmd = new StartupRoutingCommand(0, 0, 0, 0, null, Hypervisor.HypervisorType.BareMetal, new HashMap(), null, null); + StartupRoutingCommand cmd = new StartupRoutingCommand(0, 0, 0, 0, null, Hypervisor.HypervisorType.BareMetal, + new HashMap(), null, null); cmd.setDataCenter(_zone); cmd.setPod(_pod); @@ -365,13 +408,13 @@ public StartupCommand[] initialize() { cmd.setPrivateIpAddress(_ip); cmd.setStorageIpAddress(_ip); cmd.setVersion(BareMetalResourceBase.class.getPackage().getImplementationVersion()); - cmd.setCpus((int)_cpuNum); + cmd.setCpus((int) _cpuNum); cmd.setSpeed(_cpuCapacity); cmd.setMemory(_memCapacity); cmd.setPrivateMacAddress(_mac); cmd.setPublicMacAddress(_mac); cmd.setStateChanges(fullSync()); - return new StartupCommand[] {cmd}; + return new StartupCommand[] { cmd }; } private boolean ipmiPing() { @@ -393,7 +436,19 @@ public PingCommand getCurrentStatus(long id) { return null; } - return new PingRoutingCommand(getType(), id, deltaSync(), getHostVmStateReport()); + if (hostId != null) { + final List vms = vmDao.listByHostId(hostId); + if (vms.isEmpty()) { + return new PingRoutingCommand(getType(), id, deltaSync(), getHostVmStateReport()); + } else { + VMInstanceVO vm = vms.get(0); + SecurityGroupHttpClient client = new SecurityGroupHttpClient(); + HashMap> nwGrpStates = client.sync(vm.getInstanceName(), vm.getId(), vm.getPrivateIpAddress()); + return new PingRoutingWithNwGroupsCommand(getType(), id, null, getHostVmStateReport(), nwGrpStates); + } + } else { + return new PingRoutingCommand(getType(), id, deltaSync(), getHostVmStateReport()); + } } protected Answer execute(IpmISetBootDevCommand cmd) { @@ -456,29 +511,29 @@ protected Answer execute(SecurityGroupRulesCmd cmd) { public Answer executeRequest(Command cmd) { try { if (cmd instanceof ReadyCommand) { - return execute((ReadyCommand)cmd); + return execute((ReadyCommand) cmd); } else if (cmd instanceof StartCommand) { - return execute((StartCommand)cmd); + return execute((StartCommand) cmd); } else if (cmd instanceof StopCommand) { - return execute((StopCommand)cmd); + return execute((StopCommand) cmd); } else if (cmd instanceof RebootCommand) { - return execute((RebootCommand)cmd); + return execute((RebootCommand) cmd); } else if (cmd instanceof IpmISetBootDevCommand) { - return execute((IpmISetBootDevCommand)cmd); + return execute((IpmISetBootDevCommand) cmd); } else if (cmd instanceof MaintainCommand) { - return execute((MaintainCommand)cmd); + return execute((MaintainCommand) cmd); } else if (cmd instanceof PrepareForMigrationCommand) { - return execute((PrepareForMigrationCommand)cmd); + return execute((PrepareForMigrationCommand) cmd); } else if (cmd instanceof MigrateCommand) { - return execute((MigrateCommand)cmd); + return execute((MigrateCommand) cmd); } else if (cmd instanceof CheckVirtualMachineCommand) { - return execute((CheckVirtualMachineCommand)cmd); + return execute((CheckVirtualMachineCommand) cmd); } else if (cmd instanceof IpmiBootorResetCommand) { - return execute((IpmiBootorResetCommand)cmd); + return execute((IpmiBootorResetCommand) cmd); } else if (cmd instanceof SecurityGroupRulesCmd) { - return execute((SecurityGroupRulesCmd)cmd); + return execute((SecurityGroupRulesCmd) cmd); } else if (cmd instanceof CheckNetworkCommand) { - return execute((CheckNetworkCommand)cmd); + return execute((CheckNetworkCommand) cmd); } else { return Answer.createUnsupportedCommandAnswer(cmd); } @@ -499,8 +554,17 @@ protected boolean isPowerOn(String str) { } protected RebootAnswer execute(final RebootCommand cmd) { - if (!doScript(_rebootCommand)) { - return new RebootAnswer(cmd, "IPMI reboot failed", false); + String infoStr = "Command not supported in present state"; + OutputInterpreter.AllLinesParser interpreter = new OutputInterpreter.AllLinesParser(); + if (!doScript(_rebootCommand, interpreter, 10)) { + if (interpreter.getLines().contains(infoStr)) { + // try again, this error should be temporary + if (!doScript(_rebootCommand, interpreter, 10)) { + return new RebootAnswer(cmd, "IPMI reboot failed", false); + } + } else { + return new RebootAnswer(cmd, "IPMI reboot failed", false); + } } return new RebootAnswer(cmd, "reboot succeeded", true); @@ -524,7 +588,8 @@ protected StopAnswer execute(final StopCommand cmd) { OutputInterpreter.AllLinesParser interpreter = new OutputInterpreter.AllLinesParser(); if (!doScript(_getStatusCommand, interpreter)) { - s_logger.warn("Cannot get power status of " + _name + ", assume VM state was not changed"); + success = true; + s_logger.warn("Cannot get power status of " + _name + ", assume VM state changed successfully"); break; } diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeManagerImpl.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeManagerImpl.java index ca2f8fe703..261534a3dd 100755 --- a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeManagerImpl.java +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeManagerImpl.java @@ -193,7 +193,7 @@ public List listPxeServers(ListBaremetalPxeServersCmd cmd) @Override public boolean addUserData(NicProfile nic, VirtualMachineProfile profile) { - UserVmVO vm = (UserVmVO)profile.getVirtualMachine(); + UserVmVO vm = _vmDao.findById(profile.getVirtualMachine().getId()); _vmDao.loadDetails(vm); String serviceOffering = _serviceOfferingDao.findByIdIncludingRemoved(vm.getId(), vm.getServiceOfferingId()).getDisplayText(); diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/SecurityGroupHttpClient.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/SecurityGroupHttpClient.java index a3998a3bc7..b9e4858895 100755 --- a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/SecurityGroupHttpClient.java +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/SecurityGroupHttpClient.java @@ -1,38 +1,205 @@ -// 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. -// -// Automatically generated by addcopyright.py at 01/29/2013 -// Apache License, Version 2.0 (the "License"); you may not use this -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -package com.cloud.baremetal.networkservice; - -import com.cloud.agent.api.Answer; -import com.cloud.agent.api.SecurityGroupRulesCmd; - -public class SecurityGroupHttpClient { - - public Answer call(String guestIp, SecurityGroupRulesCmd cmd) { - // TODO Auto-generated method stub - return null; - } - - public boolean echo(String ip, long millis, long millis2) { - // TODO Auto-generated method stub - return false; - } - -} +// 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. +// +// Automatically generated by addcopyright.py at 01/29/2013 +// Apache License, Version 2.0 (the "License"); you may not use this +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// Automatically generated by addcopyright.py at 04/03/2012 + +package com.cloud.baremetal.networkservice; + +import com.cloud.agent.api.SecurityGroupRuleAnswer; +import com.cloud.agent.api.SecurityGroupRulesCmd; +import com.cloud.agent.api.SecurityGroupRulesCmd.IpPortAndProto; +import com.cloud.baremetal.networkservice.schema.SecurityGroupRule; +import com.cloud.baremetal.networkservice.schema.SecurityGroupVmRuleSet; +import com.cloud.utils.Pair; +import com.cloud.utils.exception.CloudRuntimeException; +import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager; +import org.apache.commons.httpclient.methods.PostMethod; +import org.apache.commons.httpclient.methods.StringRequestEntity; +import org.apache.log4j.Logger; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.Marshaller; +import java.io.StringWriter; +import java.net.SocketTimeoutException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.concurrent.TimeUnit; + +public class SecurityGroupHttpClient { + private static final Logger logger = Logger.getLogger(SecurityGroupHttpClient.class); + private static final String ARG_NAME = "args"; + private static final String COMMAND = "command"; + private JAXBContext context; + private int port; + private static HttpClient httpClient; + static { + MultiThreadedHttpConnectionManager connman = new MultiThreadedHttpConnectionManager(); + httpClient = new HttpClient(connman); + httpClient.setConnectionTimeout(5000); + } + + private enum OpConstant { + setRules, echo, + } + + public SecurityGroupHttpClient() { + try { + context = JAXBContext.newInstance(SecurityGroupRule.class, SecurityGroupVmRuleSet.class); + port = 9988; + } catch (Exception e) { + throw new CloudRuntimeException( + "Unable to create JAXBContext for security group", e); + } + } + + private List generateRules(IpPortAndProto[] ipps) { + List rules = new ArrayList( + ipps.length); + for (SecurityGroupRulesCmd.IpPortAndProto ipp : ipps) { + SecurityGroupRule r = new SecurityGroupRule(); + r.setProtocol(ipp.getProto()); + r.setStartPort(ipp.getStartPort()); + r.setEndPort(ipp.getEndPort()); + for (String cidr : ipp.getAllowedCidrs()) { + r.getIp().add(cidr); + } + rules.add(r); + } + return rules; + } + + public HashMap> sync(String vmName, Long vmId, String agentIp) { + HashMap> states = new HashMap>(); + PostMethod post = new PostMethod(String.format("http://%s:%s/", agentIp, getPort())); + try { + post.addRequestHeader("command", "sync"); + if (httpClient.executeMethod(post) != 200) { + logger.debug(String.format("echoing baremetal security group agent on %s got error: %s", agentIp, post.getResponseBodyAsString())); + } else { + String res = post.getResponseBodyAsString(); + // res = ';'.join([vmName, vmId, seqno]) + String[] rulelogs = res.split(","); + if (rulelogs.length != 6) { + logger.debug(String.format("host[%s] returns invalid security group sync document[%s], reset rules", agentIp, res)); + states.put(vmName, new Pair(vmId, -1L)); + return states; + } + Pair p = new Pair(Long.valueOf(rulelogs[1]), Long.valueOf(rulelogs[5])); + states.put(rulelogs[0], p); + return states; + } + } catch (SocketTimeoutException se) { + logger.warn(String.format("unable to sync security group rules on host[%s], %s", agentIp, se.getMessage())); + } catch (Exception e) { + logger.warn(String.format("unable to sync security group rules on host[%s]", agentIp), e); + } finally { + if (post != null) { + post.releaseConnection(); + } + } + return states; + } + + + public boolean echo(String agentIp, long l, long m) { + boolean ret = false; + int count = 1; + while (true) { + try { + Thread.sleep(m); + count++; + } catch (InterruptedException e1) { + logger.warn("", e1); + break; + } + PostMethod post = new PostMethod(String.format("http://%s:%s/", agentIp, getPort())); + try { + post.addRequestHeader("command", "echo"); + if (httpClient.executeMethod(post) != 200) { + logger.debug(String.format("echoing baremetal security group agent on %s got error: %s", agentIp, post.getResponseBodyAsString())); + } else { + ret = true; + } + break; + } catch (Exception e) { + if (count*m >= l) { + logger.debug(String.format("ping security group agent on vm[%s] timeout after %s minutes, starting vm failed, count=%s", agentIp, TimeUnit.MILLISECONDS.toSeconds(l), count)); + break; + } else { + logger.debug(String.format("Having pinged security group agent on vm[%s] %s times, continue to wait...", agentIp, count)); + } + } finally { + if (post != null) { + post.releaseConnection(); + } + } + } + return ret; + } + + public SecurityGroupRuleAnswer call(String agentIp, SecurityGroupRulesCmd cmd) { + PostMethod post = new PostMethod(String.format( + "http://%s:%s", agentIp, getPort())); + try { + SecurityGroupVmRuleSet rset = new SecurityGroupVmRuleSet(); + rset.getEgressRules().addAll(generateRules(cmd.getEgressRuleSet())); + rset.getIngressRules().addAll( + generateRules(cmd.getIngressRuleSet())); + rset.setVmName(cmd.getVmName()); + rset.setVmIp(cmd.getGuestIp()); + rset.setVmMac(cmd.getGuestMac()); + rset.setVmId(cmd.getVmId()); + rset.setSignature(cmd.getSignature()); + rset.setSequenceNumber(cmd.getSeqNum()); + Marshaller marshaller = context.createMarshaller(); + StringWriter writer = new StringWriter(); + marshaller.marshal(rset, writer); + String xmlContents = writer.toString(); + logger.debug(xmlContents); + + post.addRequestHeader("command", "set_rules"); + StringRequestEntity entity = new StringRequestEntity(xmlContents); + post.setRequestEntity(entity); + if (httpClient.executeMethod(post) != 200) { + return new SecurityGroupRuleAnswer(cmd, false, + post.getResponseBodyAsString()); + } else { + return new SecurityGroupRuleAnswer(cmd); + } + } catch (Exception e) { + return new SecurityGroupRuleAnswer(cmd, false, e.getMessage()); + } finally { + if (post != null) { + post.releaseConnection(); + } + } + } + + public int getPort() { + return port; + } + + public void setPort(int port) { + this.port = port; + } +} diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/schema/ObjectFactory.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/schema/ObjectFactory.java new file mode 100644 index 0000000000..b5bc694516 --- /dev/null +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/schema/ObjectFactory.java @@ -0,0 +1,55 @@ +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.10 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2012.07.11 at 03:24:15 PM PDT +// + + +package com.cloud.baremetal.networkservice.schema; + +import javax.xml.bind.annotation.XmlRegistry; + + +/** + * This object contains factory methods for each + * Java content interface and Java element interface + * generated in the com.cloud.network.security.schema package. + *

An ObjectFactory allows you to programatically + * construct new instances of the Java representation + * for XML content. The Java representation of XML + * content can consist of schema derived interfaces + * and classes representing the binding of schema + * type definitions, element declarations and model + * groups. Factory methods for each of these are + * provided in this class. + * + */ +@XmlRegistry +public class ObjectFactory { + + + /** + * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: com.cloud.network.security.schema + * + */ + public ObjectFactory() { + } + + /** + * Create an instance of {@link SecurityGroupRule } + * + */ + public SecurityGroupRule createSecurityGroupRule() { + return new SecurityGroupRule(); + } + + /** + * Create an instance of {@link SecurityGroupVmRuleSet } + * + */ + public SecurityGroupVmRuleSet createSecurityGroupVmRuleSet() { + return new SecurityGroupVmRuleSet(); + } + +} diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/schema/SecurityGroupRule.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/schema/SecurityGroupRule.java new file mode 100644 index 0000000000..050c3fdee7 --- /dev/null +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/schema/SecurityGroupRule.java @@ -0,0 +1,146 @@ +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.10 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2012.07.11 at 03:24:15 PM PDT +// + + +package com.cloud.baremetal.networkservice.schema; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlSchemaType; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for SecurityGroupRule complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="SecurityGroupRule">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="protocol" type="{http://www.w3.org/2001/XMLSchema}string"/>
+ *         <element name="startPort" type="{http://www.w3.org/2001/XMLSchema}unsignedInt"/>
+ *         <element name="endPort" type="{http://www.w3.org/2001/XMLSchema}unsignedInt"/>
+ *         <sequence maxOccurs="unbounded" minOccurs="0">
+ *           <element name="ip" type="{http://www.w3.org/2001/XMLSchema}string"/>
+ *         </sequence>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "SecurityGroupRule", propOrder = { + "protocol", + "startPort", + "endPort", + "ip" +}) +public class SecurityGroupRule { + + @XmlElement(required = true) + protected String protocol; + @XmlSchemaType(name = "unsignedInt") + protected long startPort; + @XmlSchemaType(name = "unsignedInt") + protected long endPort; + protected List ip; + + /** + * Gets the value of the protocol property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getProtocol() { + return protocol; + } + + /** + * Sets the value of the protocol property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setProtocol(String value) { + this.protocol = value; + } + + /** + * Gets the value of the startPort property. + * + */ + public long getStartPort() { + return startPort; + } + + /** + * Sets the value of the startPort property. + * + */ + public void setStartPort(long value) { + this.startPort = value; + } + + /** + * Gets the value of the endPort property. + * + */ + public long getEndPort() { + return endPort; + } + + /** + * Sets the value of the endPort property. + * + */ + public void setEndPort(long value) { + this.endPort = value; + } + + /** + * Gets the value of the ip property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the ip property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getIp().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link String } + * + * + */ + public List getIp() { + if (ip == null) { + ip = new ArrayList(); + } + return this.ip; + } + +} diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/schema/SecurityGroupVmRuleSet.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/schema/SecurityGroupVmRuleSet.java new file mode 100644 index 0000000000..2c50c0e24d --- /dev/null +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/schema/SecurityGroupVmRuleSet.java @@ -0,0 +1,263 @@ +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.10 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2012.07.11 at 03:24:15 PM PDT +// + + +package com.cloud.baremetal.networkservice.schema; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for anonymous complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType>
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="vmName" type="{http://www.w3.org/2001/XMLSchema}string"/>
+ *         <element name="vmId" type="{http://www.w3.org/2001/XMLSchema}long"/>
+ *         <element name="vmIp" type="{http://www.w3.org/2001/XMLSchema}string"/>
+ *         <element name="vmMac" type="{http://www.w3.org/2001/XMLSchema}string"/>
+ *         <element name="signature" type="{http://www.w3.org/2001/XMLSchema}string"/>
+ *         <element name="sequenceNumber" type="{http://www.w3.org/2001/XMLSchema}long"/>
+ *         <sequence maxOccurs="unbounded" minOccurs="0">
+ *           <element name="ingressRules" type="{}SecurityGroupRule"/>
+ *         </sequence>
+ *         <sequence maxOccurs="unbounded" minOccurs="0">
+ *           <element name="egressRules" type="{}SecurityGroupRule"/>
+ *         </sequence>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { + "vmName", + "vmId", + "vmIp", + "vmMac", + "signature", + "sequenceNumber", + "ingressRules", + "egressRules" +}) +@XmlRootElement(name = "SecurityGroupVmRuleSet") +public class SecurityGroupVmRuleSet { + + @XmlElement(required = true) + protected String vmName; + protected long vmId; + @XmlElement(required = true) + protected String vmIp; + @XmlElement(required = true) + protected String vmMac; + @XmlElement(required = true) + protected String signature; + protected long sequenceNumber; + protected List ingressRules; + protected List egressRules; + + /** + * Gets the value of the vmName property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getVmName() { + return vmName; + } + + /** + * Sets the value of the vmName property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setVmName(String value) { + this.vmName = value; + } + + /** + * Gets the value of the vmId property. + * + */ + public long getVmId() { + return vmId; + } + + /** + * Sets the value of the vmId property. + * + */ + public void setVmId(long value) { + this.vmId = value; + } + + /** + * Gets the value of the vmIp property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getVmIp() { + return vmIp; + } + + /** + * Sets the value of the vmIp property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setVmIp(String value) { + this.vmIp = value; + } + + /** + * Gets the value of the vmMac property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getVmMac() { + return vmMac; + } + + /** + * Sets the value of the vmMac property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setVmMac(String value) { + this.vmMac = value; + } + + /** + * Gets the value of the signature property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getSignature() { + return signature; + } + + /** + * Sets the value of the signature property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setSignature(String value) { + this.signature = value; + } + + /** + * Gets the value of the sequenceNumber property. + * + */ + public long getSequenceNumber() { + return sequenceNumber; + } + + /** + * Sets the value of the sequenceNumber property. + * + */ + public void setSequenceNumber(long value) { + this.sequenceNumber = value; + } + + /** + * Gets the value of the ingressRules property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the ingressRules property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getIngressRules().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link SecurityGroupRule } + * + * + */ + public List getIngressRules() { + if (ingressRules == null) { + ingressRules = new ArrayList(); + } + return this.ingressRules; + } + + /** + * Gets the value of the egressRules property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the egressRules property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getEgressRules().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link SecurityGroupRule } + * + * + */ + public List getEgressRules() { + if (egressRules == null) { + egressRules = new ArrayList(); + } + return this.egressRules; + } + +} diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/.nuget/NuGet.Config b/plugins/hypervisors/hyperv/DotNet/ServerResource/.nuget/NuGet.Config index 5181cb8103..3bdbf2e7f0 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/.nuget/NuGet.Config +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/.nuget/NuGet.Config @@ -1,13 +1,4 @@ - - + diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/AgentService.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/AgentService.cs index 9d66a5cd1b..febd10abb4 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/AgentService.cs +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/AgentService.cs @@ -72,8 +72,6 @@ public static void ConfigServerResource() // use of VisualStudio settings designer. The designer allows us to avoid // accessing config using their key strings. HypervResourceControllerConfig rsrcCnf = new HypervResourceControllerConfig(); - rsrcCnf.PrivateIpAddress = AgentSettings.Default.private_ip_address; - rsrcCnf.GatewayIpAddress = AgentSettings.Default.gateway_ip_address; rsrcCnf.RootDeviceReservedSpaceBytes = AgentSettings.Default.RootDeviceReservedSpaceBytes; rsrcCnf.RootDeviceName = AgentSettings.Default.RootDeviceName; rsrcCnf.ParentPartitionMinMemoryMb = AgentSettings.Default.dom0MinMemory; diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/AgentSettings.settings b/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/AgentSettings.settings index fb5b962fca..695ebe2ce9 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/AgentSettings.settings +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/AgentSettings.settings @@ -1,23 +1,4 @@ - - - + diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/AgentShell.csproj b/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/AgentShell.csproj index a4c6b1fc07..f804ef6f67 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/AgentShell.csproj +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/AgentShell.csproj @@ -137,6 +137,10 @@ + + + + + + 4.0.0 + cloud-plugin-storage-volume-cloudbyte + Apache CloudStack Plugin - Storage Volume CloudByte Provider + + org.apache.cloudstack + cloudstack-plugins + 4.4.0-SNAPSHOT + ../../../pom.xml + + + + org.apache.cloudstack + cloud-plugin-storage-volume-default + ${project.version} + + + org.apache.cloudstack + cloud-engine-storage-volume + ${project.version} + + + mysql + mysql-connector-java + ${cs.mysql.version} + provided + + + com.google.code.gson + gson + ${cs.gson.version} + + + com.sun.jersey + jersey-bundle + 1.17.1 + + + + install + src + test + + + maven-surefire-plugin + + true + + + + integration-test + + test + + + + + + + diff --git a/plugins/storage/volume/cloudbyte/resources/META-INF/cloudstack/storage-volume-cloudbyte/module.properties b/plugins/storage/volume/cloudbyte/resources/META-INF/cloudstack/storage-volume-cloudbyte/module.properties new file mode 100755 index 0000000000..730e376c92 --- /dev/null +++ b/plugins/storage/volume/cloudbyte/resources/META-INF/cloudstack/storage-volume-cloudbyte/module.properties @@ -0,0 +1,18 @@ +# 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. +name=storage-volume-cloudbyte +parent=storage \ No newline at end of file diff --git a/plugins/storage/volume/cloudbyte/resources/META-INF/cloudstack/storage-volume-cloudbyte/spring-storage-volume-cloudbyte-context.xml b/plugins/storage/volume/cloudbyte/resources/META-INF/cloudstack/storage-volume-cloudbyte/spring-storage-volume-cloudbyte-context.xml new file mode 100755 index 0000000000..87c5f51393 --- /dev/null +++ b/plugins/storage/volume/cloudbyte/resources/META-INF/cloudstack/storage-volume-cloudbyte/spring-storage-volume-cloudbyte-context.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + diff --git a/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/driver/ElastistorPrimaryDataStoreDriver.java b/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/driver/ElastistorPrimaryDataStoreDriver.java new file mode 100755 index 0000000000..99d1e2aaa4 --- /dev/null +++ b/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/driver/ElastistorPrimaryDataStoreDriver.java @@ -0,0 +1,97 @@ +/* + * 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.storage.datastore.driver; + + +import javax.inject.Inject; + +import org.apache.cloudstack.engine.subsystem.api.storage.ChapInfo; +import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; +import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; +import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; +import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver; +import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; +import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; +import org.apache.cloudstack.framework.async.AsyncCompletionCallback; +import org.apache.cloudstack.storage.command.CommandResult; +import org.apache.log4j.Logger; + +import com.cloud.agent.api.to.DataStoreTO; +import com.cloud.agent.api.to.DataTO; +import com.cloud.storage.dao.DiskOfferingDao; +import com.cloud.user.AccountManager; + +public class ElastistorPrimaryDataStoreDriver extends CloudStackPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver{ + + private static final Logger s_logger = Logger.getLogger(ElastistorPrimaryDataStoreDriver.class); + + @Inject + AccountManager _accountMgr; + @Inject + DiskOfferingDao _diskOfferingDao; + @Override + public DataTO getTO(DataObject data) { + return null; + } + + @Override + public DataStoreTO getStoreTO(DataStore store) { + return null; + } + + public void createAsync(DataStore dataStore, DataObject dataObject, AsyncCompletionCallback callback) { + super.createAsync(dataStore, dataObject, callback); + } + + public void deleteAsync(DataStore dataStore, DataObject dataObject, AsyncCompletionCallback callback) { + super.deleteAsync(dataStore, dataObject, callback); + } + + @Override + public void copyAsync(DataObject srcdata, DataObject destData, AsyncCompletionCallback callback) { + throw new UnsupportedOperationException(); + + } + + @Override + public boolean canCopy(DataObject srcData, DataObject destData) { + return false; + } + + @Override + public void resize(DataObject data, AsyncCompletionCallback callback) { + throw new UnsupportedOperationException(); + } + + public ChapInfo getChapInfo(VolumeInfo volumeInfo) { + return super.getChapInfo(volumeInfo); + } + + @Override + public void takeSnapshot(SnapshotInfo snapshot, AsyncCompletionCallback callback) { + throw new UnsupportedOperationException(); + } + + @Override + public void revertSnapshot(SnapshotInfo snapshot, AsyncCompletionCallback callback) { + throw new UnsupportedOperationException(); + } + +} diff --git a/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/lifecycle/ElastistorPrimaryDataStoreLifeCycle.java b/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/lifecycle/ElastistorPrimaryDataStoreLifeCycle.java new file mode 100755 index 0000000000..aa33b2f1d1 --- /dev/null +++ b/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/lifecycle/ElastistorPrimaryDataStoreLifeCycle.java @@ -0,0 +1,497 @@ +/* + * 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.storage.datastore.lifecycle; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.StringTokenizer; + +import javax.inject.Inject; + +import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; +import org.apache.cloudstack.engine.subsystem.api.storage.HostScope; +import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo; +import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreLifeCycle; +import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreParameters; +import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; +import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao; +import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; +import org.apache.cloudstack.storage.datastore.util.ElastistorUtil; +import org.apache.cloudstack.storage.datastore.util.ElastistorUtil.CreateTsmCmdResponse; +import org.apache.cloudstack.storage.datastore.util.ElastistorUtil.CreateVolumeCmdResponse; +import org.apache.cloudstack.storage.volume.datastore.PrimaryDataStoreHelper; +import org.apache.log4j.Logger; + +import com.cloud.agent.AgentManager; +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.CreateStoragePoolCommand; +import com.cloud.agent.api.DeleteStoragePoolCommand; +import com.cloud.agent.api.StoragePoolInfo; +import com.cloud.dc.dao.DataCenterDao; +import com.cloud.host.Host; +import com.cloud.host.HostVO; +import com.cloud.host.dao.HostDao; +import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.resource.ResourceManager; +import com.cloud.storage.Storage.StoragePoolType; +import com.cloud.storage.StorageManager; +import com.cloud.storage.StoragePool; +import com.cloud.storage.StoragePoolAutomation; +import com.cloud.storage.StoragePoolHostVO; +import com.cloud.storage.dao.StoragePoolHostDao; +import com.cloud.utils.exception.CloudRuntimeException; + +public class ElastistorPrimaryDataStoreLifeCycle implements PrimaryDataStoreLifeCycle { + private static final Logger s_logger = Logger.getLogger(ElastistorPrimaryDataStoreLifeCycle.class); + + @Inject + HostDao _hostDao; + @Inject + StoragePoolHostDao _storagePoolHostDao; + @Inject + protected ResourceManager _resourceMgr; + @Inject + PrimaryDataStoreDao primaryDataStoreDao; + @Inject + AgentManager agentMgr; + @Inject + StorageManager storageMgr; + @Inject + PrimaryDataStoreHelper dataStoreHelper; + @Inject + PrimaryDataStoreDao _storagePoolDao; + @Inject + PrimaryDataStoreHelper _dataStoreHelper; + @Inject + StoragePoolAutomation _storagePoolAutomation; + @Inject + StoragePoolDetailsDao _storagePoolDetailsDao; + @Inject + DataCenterDao _zoneDao; + + @Override + public DataStore initialize(Map dsInfos) { + + String url = (String) dsInfos.get("url"); + Long zoneId = (Long) dsInfos.get("zoneId"); + Long podId = (Long) dsInfos.get("podId"); + Long clusterId = (Long) dsInfos.get("clusterId"); + String storagePoolName = (String) dsInfos.get("name"); + String providerName = (String) dsInfos.get("providerName"); + Long capacityBytes = (Long) dsInfos.get("capacityBytes"); + Long capacityIops = (Long) dsInfos.get("capacityIops"); + String tags = (String) dsInfos.get("tags"); + Map details = (Map) dsInfos.get("details"); + String storageIp = getStorageIp(url); + int storagePort = getDefaultStoragePort(url); + StoragePoolType storagetype = getStorageType(url); + String accesspath = getAccessPath(url); + String protocoltype = getProtocolType(url); + String[] mp = accesspath.split("/"); + String mountpoint = mp[1]; + String uuid = null ; + + /** + * if the elastistor params which are required for plugin configuration + * are not injected through spring-storage-volume-cloudbyte-context.xml, it can be set from details map. + */ + if(details.get("esaccountid") != null) + ElastistorUtil.setElastistorAccountId(details.get("esaccountid")); + if(details.get("esapikey") != null) + ElastistorUtil.setElastistorApiKey(details.get("esapikey")); + if(details.get("esdefaultgateway") != null) + ElastistorUtil.setElastistorGateway(details.get("esdefaultgateway")); + if(details.get("estntinterface") != null) + ElastistorUtil.setElastistorInterface(details.get("estntinterface")); + if(details.get("esmanagementip") != null) + ElastistorUtil.setElastistorManagementIp(details.get("esmanagementip")); + if(details.get("espoolid") != null) + ElastistorUtil.setElastistorPoolId(details.get("espoolid")); + if(details.get("essubnet") != null) + ElastistorUtil.setElastistorSubnet(details.get("essubnet")); + + if (capacityBytes == null || capacityBytes <= 0) { + throw new IllegalArgumentException("'capacityBytes' must be present and greater than 0."); + } + + if (capacityIops == null || capacityIops <= 0) { + throw new IllegalArgumentException("'capacityIops' must be present and greater than 0."); + } + + // elastistor does not allow same name and ip pools. + List storagePoolVO = _storagePoolDao.listAll(); + for(StoragePoolVO poolVO : storagePoolVO){ + if (storagePoolName.equals(poolVO.getName())) { + throw new IllegalArgumentException("storage pool with that name already exists in elastistor,please specify a unique name ."); + } + if (storageIp.equals(poolVO.getHostAddress())) { + throw new IllegalArgumentException("storage pool with that ip already exists in elastistor,please specify a unique ip ."); + } + } + + PrimaryDataStoreParameters parameters = new PrimaryDataStoreParameters(); + + // creates the volume in elastistor + parameters = createElastistorVolume(parameters, storagePoolName, storageIp, capacityBytes, capacityIops, protocoltype, mountpoint); + + parameters.setHost(storageIp); + parameters.setPort(storagePort); + if(protocoltype.contentEquals("nfs")){ + parameters.setPath(accesspath); + } + parameters.setType(storagetype); + parameters.setZoneId(zoneId); + parameters.setPodId(podId); + parameters.setName(storagePoolName); + parameters.setProviderName(providerName); + parameters.setManaged(false); + parameters.setCapacityBytes(capacityBytes); + parameters.setUsedBytes(0); + parameters.setCapacityIops(capacityIops); + parameters.setHypervisorType(HypervisorType.Any); + parameters.setTags(tags); + parameters.setDetails(details); + parameters.setClusterId(clusterId); + + return _dataStoreHelper.createPrimaryDataStore(parameters); + } + + private PrimaryDataStoreParameters createElastistorVolume(PrimaryDataStoreParameters parameters, String storagePoolName, String storageIp, Long capacityBytes, Long capacityIops, String protocoltype, String mountpoint){ + + s_logger.info("creation of elastistor volume started"); + try { + + CreateTsmCmdResponse tsmCmdResponse = ElastistorUtil.createElastistorTsm(storagePoolName, storageIp, capacityBytes, capacityIops); + + String uuid = tsmCmdResponse.getTsm().getUuid(); + parameters.setUuid(uuid); + + CreateVolumeCmdResponse volumeCmdResponse = ElastistorUtil.createElastistorVolume(storagePoolName, tsmCmdResponse, capacityBytes, capacityIops, protocoltype ,mountpoint); + + if(protocoltype.contentEquals("iscsi")){ + String accesspath = "/"+volumeCmdResponse.getFileSystem().getIqn()+"/0"; + parameters.setPath(accesspath); + } + s_logger.info("creation of elastistor volume complete"); + + return parameters; + } catch (Throwable e) { + throw new CloudRuntimeException("Failed to create volume in elastistor" + e.toString()); + } + + } + + private String getAccessPath(String url) { + StringTokenizer st = new StringTokenizer(url ,"/"); + int count = 0; + while (st.hasMoreElements()) { + if(count == 2) + { String s = "/" ; + return s.concat(st.nextElement().toString()); + } + st.nextElement(); + count++; + } + return null; + } + + + private StoragePoolType getStorageType(String url) { + + StringTokenizer st = new StringTokenizer(url ,":"); + + while (st.hasMoreElements()) + { + String accessprotocol = st.nextElement().toString(); + + if(accessprotocol.contentEquals("nfs")) + { + return StoragePoolType.NetworkFilesystem; + } + else if(accessprotocol.contentEquals("iscsi")) + { + return StoragePoolType.IscsiLUN; + } + + else + + break; + + } + return null; + } + + private String getProtocolType(String url) { + StringTokenizer st = new StringTokenizer(url ,":"); + + while (st.hasMoreElements()) + { + String accessprotocol = st.nextElement().toString(); + + if(accessprotocol.contentEquals("nfs")){ + return "nfs"; + }else if(accessprotocol.contentEquals("iscsi")){ + return "iscsi"; + } else + break; + } + return null; + } + + // this method parses the url and gets the default storage port based on access protocol + private int getDefaultStoragePort(String url) { + + StringTokenizer st = new StringTokenizer(url ,":"); + + while (st.hasMoreElements()) + { + + String accessprotocol = st.nextElement().toString(); + + if(accessprotocol.contentEquals("nfs")){ + return 2049; + } + else if(accessprotocol.contentEquals("iscsi")){ + return 3260; + } + else + break; + + } + return -1; + + } + + // parses the url and returns the storage volume ip + private String getStorageIp(String url) { + + StringTokenizer st = new StringTokenizer(url ,"/"); + int count = 0; + + while (st.hasMoreElements()) { + if(count == 1) + return st.nextElement().toString(); + + st.nextElement(); + count++; + } + return null; + } + + @Override + public boolean attachCluster(DataStore store, ClusterScope scope) { + + dataStoreHelper.attachCluster(store); + + PrimaryDataStoreInfo primarystore = (PrimaryDataStoreInfo) store; + // Check if there is host up in this cluster + List allHosts = _resourceMgr.listAllUpAndEnabledHosts(Host.Type.Routing, primarystore.getClusterId(), + primarystore.getPodId(), primarystore.getDataCenterId()); + if (allHosts.isEmpty()) { + primaryDataStoreDao.expunge(primarystore.getId()); + throw new CloudRuntimeException("No host up to associate a storage pool with in cluster " + + primarystore.getClusterId()); + } + + + boolean success = false; + for (HostVO h : allHosts) { + success = createStoragePool(h.getId(), primarystore); + if (success) { + break; + } + } + + s_logger.debug("In createPool Adding the pool to each of the hosts"); + List poolHosts = new ArrayList(); + for (HostVO h : allHosts) { + try { + storageMgr.connectHostToSharedPool(h.getId(), primarystore.getId()); + poolHosts.add(h); + } catch (Exception e) { + s_logger.warn("Unable to establish a connection between " + h + " and " + primarystore, e); + } + + if (poolHosts.isEmpty()) { + s_logger.warn("No host can access storage pool " + primarystore + " on cluster " + + primarystore.getClusterId()); + primaryDataStoreDao.expunge(primarystore.getId()); + throw new CloudRuntimeException("Failed to access storage pool"); + } + } + + return true; + } + + private boolean createStoragePool(long hostId, StoragePool pool) { + s_logger.debug("creating pool " + pool.getName() + " on host " + hostId); + if (pool.getPoolType() != StoragePoolType.NetworkFilesystem && pool.getPoolType() != StoragePoolType.Filesystem + && pool.getPoolType() != StoragePoolType.IscsiLUN && pool.getPoolType() != StoragePoolType.Iscsi + && pool.getPoolType() != StoragePoolType.VMFS && pool.getPoolType() != StoragePoolType.SharedMountPoint + && pool.getPoolType() != StoragePoolType.PreSetup && pool.getPoolType() != StoragePoolType.OCFS2 + && pool.getPoolType() != StoragePoolType.RBD && pool.getPoolType() != StoragePoolType.CLVM) { + s_logger.warn(" Doesn't support storage pool type " + pool.getPoolType()); + return false; + } + CreateStoragePoolCommand cmd = new CreateStoragePoolCommand(true, pool); + final Answer answer = agentMgr.easySend(hostId, cmd); + if (answer != null && answer.getResult()) { + return true; + } else { + primaryDataStoreDao.expunge(pool.getId()); + String msg = ""; + if (answer != null) { + msg = "Can not create storage pool through host " + hostId + " due to " + answer.getDetails(); + s_logger.warn(msg); + } else { + msg = "Can not create storage pool through host " + hostId + " due to CreateStoragePoolCommand returns null"; + s_logger.warn(msg); + } + throw new CloudRuntimeException(msg); + } + } + + + @Override + public boolean attachHost(DataStore store, HostScope scope, StoragePoolInfo existingInfo) { + _dataStoreHelper.attachHost(store, scope, existingInfo); + return true; + } + + @Override + public boolean attachZone(DataStore dataStore, ZoneScope scope, HypervisorType hypervisorType) { + List hosts = _resourceMgr.listAllUpAndEnabledHostsInOneZoneByHypervisor(hypervisorType, scope.getScopeId()); + s_logger.debug("In createPool. Attaching the pool to each of the hosts."); + List poolHosts = new ArrayList(); + for (HostVO host : hosts) { + try { + storageMgr.connectHostToSharedPool(host.getId(), dataStore.getId()); + poolHosts.add(host); + } catch (Exception e) { + s_logger.warn("Unable to establish a connection between " + host + " and " + dataStore, e); + } + } + if (poolHosts.isEmpty()) { + s_logger.warn("No host can access storage pool " + dataStore + " in this zone."); + primaryDataStoreDao.expunge(dataStore.getId()); + throw new CloudRuntimeException("Failed to create storage pool as it is not accessible to hosts."); + } + dataStoreHelper.attachZone(dataStore, hypervisorType); + return true; + } + + @Override + public boolean maintain(DataStore store) { + _storagePoolAutomation.maintain(store); + _dataStoreHelper.maintain(store); + return true; + } + + @Override + public boolean cancelMaintain(DataStore store) { + _dataStoreHelper.cancelMaintain(store); + _storagePoolAutomation.cancelMaintain(store); + return true; + } + + @SuppressWarnings("finally") + @Override + public boolean deleteDataStore(DataStore store) { + List hostPoolRecords = _storagePoolHostDao.listByPoolId(store.getId()); + StoragePool pool = (StoragePool) store; + + // find the hypervisor where the storage is attached to. + HypervisorType hType = null; + if(hostPoolRecords.size() > 0 ){ + hType = getHypervisorType(hostPoolRecords.get(0).getHostId()); + } + + // Remove the SR associated with the Xenserver + for (StoragePoolHostVO host : hostPoolRecords) { + DeleteStoragePoolCommand deleteCmd = new DeleteStoragePoolCommand(pool); + final Answer answer = agentMgr.easySend(host.getHostId(), deleteCmd); + + if (answer != null && answer.getResult()) { + // if host is KVM hypervisor then send deleteStoragepoolcmd to all the kvm hosts. + if (HypervisorType.KVM != hType) { + break; + } + } else { + if (answer != null) { + s_logger.error("Failed to delete storage pool: " + answer.getResult()); + } + } + } + + //delete the Elastistor volume at backend + deleteElastistorVolume(pool); + + return _dataStoreHelper.deletePrimaryDataStore(store); + } + + private void deleteElastistorVolume(StoragePool pool){ + + String poolip = pool.getHostAddress(); + String esip = null; + String apikey = null; + + // check if apikey and managentip is empty, if so getting it from stragepooldetails + if(ElastistorUtil.s_esIPVAL == "" && ElastistorUtil.s_esAPIKEYVAL == ""){ + Map detailsMap = _storagePoolDetailsDao.listDetailsKeyPairs(pool.getId()); + ElastistorUtil.setElastistorManagementIp(detailsMap.get("esmanagementip")); + esip=ElastistorUtil.s_esIPVAL; + ElastistorUtil.setElastistorApiKey(detailsMap.get("esapikey")); + apikey = ElastistorUtil.s_esAPIKEYVAL; + }else{ + esip = ElastistorUtil.s_esIPVAL; + apikey = ElastistorUtil.s_esAPIKEYVAL; + } + + boolean status; + try { + status = ElastistorUtil.deleteElastistorVolume(poolip,esip,apikey); + } catch (Throwable e) { + throw new CloudRuntimeException("Failed to delete primary storage on elastistor" + e); + } + + if(status == true){ + s_logger.info("deletion of elastistor primary storage complete"); + }else{ + s_logger.error("deletion of elastistor volume failed"); + } + + } + + private HypervisorType getHypervisorType(long hostId) { + HostVO host = _hostDao.findById(hostId); + if (host != null) + return host.getHypervisorType(); + return HypervisorType.None; + } + + @Override + public boolean migrateToObjectStore(DataStore store) { + return false; + } + + +} diff --git a/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/provider/ElastistorHostListener.java b/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/provider/ElastistorHostListener.java new file mode 100755 index 0000000000..de4711a140 --- /dev/null +++ b/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/provider/ElastistorHostListener.java @@ -0,0 +1,87 @@ +/* + * 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.storage.datastore.provider; + +import javax.inject.Inject; + +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; +import org.apache.cloudstack.engine.subsystem.api.storage.HypervisorHostListener; +import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; +import org.apache.log4j.Logger; + +import com.cloud.agent.AgentManager; +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.ModifyStoragePoolAnswer; +import com.cloud.agent.api.ModifyStoragePoolCommand; +import com.cloud.alert.AlertManager; +import com.cloud.storage.DataStoreRole; +import com.cloud.storage.StoragePool; +import com.cloud.storage.StoragePoolHostVO; +import com.cloud.storage.dao.StoragePoolHostDao; +import com.cloud.utils.exception.CloudRuntimeException; + +public class ElastistorHostListener implements HypervisorHostListener { + private static final Logger s_logger = Logger.getLogger(DefaultHostListener.class); + @Inject + AgentManager agentMgr; + @Inject + DataStoreManager dataStoreMgr; + @Inject + AlertManager alertMgr; + @Inject + StoragePoolHostDao storagePoolHostDao; + @Inject + PrimaryDataStoreDao primaryStoreDao; + + @Override + public boolean hostConnect(long hostId, long poolId) { + StoragePool pool = (StoragePool) this.dataStoreMgr.getDataStore(poolId, DataStoreRole.Primary); + ModifyStoragePoolCommand cmd = new ModifyStoragePoolCommand(true, pool); + final Answer answer = agentMgr.easySend(hostId, cmd); + + if (answer == null) { + throw new CloudRuntimeException("Unable to get an answer to the modify storage pool command" + pool.getId()); + } + + if (!answer.getResult()) { + String msg = "Unable to attach storage pool" + poolId + " to the host" + hostId; + + alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_HOST,pool.getDataCenterId(), pool.getPodId(), msg, msg); + + throw new CloudRuntimeException("Unable establish connection from storage head to storage pool " + pool.getId() + " due to " + answer.getDetails() + pool.getId()); + } + + assert (answer instanceof ModifyStoragePoolAnswer) : "Well, now why won't you actually return the ModifyStoragePoolAnswer when it's ModifyStoragePoolCommand? Pool=" + pool.getId() + "Host=" + hostId; + + s_logger.info("Connection established between " + pool + " host + " + hostId); + return true; + } + + @Override + public boolean hostDisconnected(long hostId, long poolId) { + StoragePoolHostVO storagePoolHost = storagePoolHostDao.findByPoolHost( + poolId, hostId); + + if (storagePoolHost != null) { + storagePoolHostDao.deleteStoragePoolHostDetails(hostId, poolId); + } + return false; + } + +} diff --git a/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/provider/ElastistorPrimaryDataStoreProvider.java b/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/provider/ElastistorPrimaryDataStoreProvider.java new file mode 100755 index 0000000000..e59108299a --- /dev/null +++ b/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/provider/ElastistorPrimaryDataStoreProvider.java @@ -0,0 +1,175 @@ +/* + * 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.storage.datastore.provider; + +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import javax.inject.Inject; + +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreLifeCycle; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; +import org.apache.cloudstack.engine.subsystem.api.storage.HypervisorHostListener; +import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver; +import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreProvider; +import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; +import org.apache.cloudstack.storage.datastore.driver.ElastistorPrimaryDataStoreDriver; +import org.apache.cloudstack.storage.datastore.lifecycle.ElastistorPrimaryDataStoreLifeCycle; +import org.apache.cloudstack.storage.datastore.util.ElastistorUtil; +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; + +import com.cloud.agent.AgentManager; +import com.cloud.alert.AlertManager; +import com.cloud.storage.dao.StoragePoolHostDao; +import com.cloud.utils.component.ComponentContext; + +@Component +public class ElastistorPrimaryDataStoreProvider implements PrimaryDataStoreProvider { + + private static final Logger s_logger = Logger.getLogger(DefaultHostListener.class); + + //these classes will be injected by spring + private ElastistorPrimaryDataStoreLifeCycle lifecycle; + private PrimaryDataStoreDriver driver; + private HypervisorHostListener listener; + + // these params will be initialized with respective values given in spring-storage-volume-cloudbyte-context.xml bean for the elastistor porpose only. + private String esmanagementip; + private String esapikey; + private String esaccountid; + private String espoolid; + private String esdefaultgateway; + private String essubnet; + private String estntinterface; + + @Inject + AgentManager agentMgr; + @Inject + DataStoreManager dataStoreMgr; + @Inject + AlertManager alertMgr; + @Inject + StoragePoolHostDao storagePoolHostDao; + @Inject + PrimaryDataStoreDao primaryStoreDao; + + + @Override + public String getName() { + return ElastistorUtil.ES_PROVIDER_NAME; + } + + @Override + public DataStoreLifeCycle getDataStoreLifeCycle() { + return lifecycle; + } + + @Override + public PrimaryDataStoreDriver getDataStoreDriver() { + return driver; + } + + @Override + public HypervisorHostListener getHostListener() { + return listener; + } + + @Override + public boolean configure(Map params) { + + lifecycle = ComponentContext.inject(ElastistorPrimaryDataStoreLifeCycle.class); + driver = ComponentContext.inject(ElastistorPrimaryDataStoreDriver.class); + listener = ComponentContext.inject(ElastistorHostListener.class); + + ElastistorUtil.setElastistorAccountId(esaccountid); + ElastistorUtil.setElastistorApiKey(esapikey); + ElastistorUtil.setElastistorManagementIp(esmanagementip); + ElastistorUtil.setElastistorPoolId(espoolid); + ElastistorUtil.setElastistorGateway(esdefaultgateway); + ElastistorUtil.setElastistorInterface(estntinterface); + ElastistorUtil.setElastistorSubnet(essubnet); + + return true; + } + + @Override + public Set getTypes() { + Set types = new HashSet(); + + types.add(DataStoreProviderType.PRIMARY); + + return types; + } + public String getEspoolid() { + return espoolid; + } + + public void setEspoolid(String espoolid) { + this.espoolid = espoolid; + } + + public String getEsmanagementip() { + return esmanagementip; + } + + public void setEsmanagementip(String esmanagementip) { + this.esmanagementip = esmanagementip; + } + + public String getEsaccountid() { + return esaccountid; + } + + public void setEsaccountid(String esaccountid) { + this.esaccountid = esaccountid; + } + + public String getEsapikey() { + return esapikey; + } + + public void setEsapikey(String esapikey) { + this.esapikey = esapikey; + } + + public String getesdefaultgateway() { + return esdefaultgateway; + } + + public void setesdefaultgateway(String esdefaultgateway) { + this.esdefaultgateway = esdefaultgateway; + } + public String getEssubnet() { + return essubnet; + } + + public void setEssubnet(String essubnet) { + this.essubnet = essubnet; + } + + public String getEstntinterface(){ + return estntinterface; + } + + public void setEstntinterface(String estntinterface){ + this.estntinterface = estntinterface; + } +} diff --git a/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ElastistorUtil.java b/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ElastistorUtil.java new file mode 100755 index 0000000000..b75d12a6a4 --- /dev/null +++ b/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ElastistorUtil.java @@ -0,0 +1,1156 @@ +/* + * 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.storage.datastore.util; + +import java.net.ConnectException; +import java.security.InvalidParameterException; +import java.security.SecureRandom; +import java.security.cert.X509Certificate; +import java.util.HashMap; + +import javax.naming.ServiceUnavailableException; +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLHandshakeException; +import javax.net.ssl.SSLSession; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.core.UriBuilder; + +import org.apache.http.auth.InvalidCredentialsException; +import org.apache.log4j.Logger; + +import com.cloud.utils.exception.CloudRuntimeException; +import com.google.gson.Gson; +import com.google.gson.annotations.SerializedName; +import com.sun.jersey.api.client.Client; +import com.sun.jersey.api.client.ClientResponse; +import com.sun.jersey.api.client.WebResource; +import com.sun.jersey.api.client.config.ClientConfig; +import com.sun.jersey.api.client.config.DefaultClientConfig; +import com.sun.jersey.core.util.MultivaluedMapImpl; + +public class ElastistorUtil { + + private static final Logger s_logger = Logger.getLogger(ElastistorUtil.class); + + + /** + * Elastistor REST API Param Keys. These should match exactly with the + * elastistor API commands' params. + */ + public static final String REST_PARAM_COMMAND = "command"; + public static final String REST_PARAM_APIKEY = "apikey"; + public static final String REST_PARAM_KEYWORD = "keyword"; + public static final String REST_PARAM_ID = "id"; + public static final String REST_PARAM_QUOTA_SIZE = "quotasize"; + public static final String REST_PARAM_READONLY = "readonly"; + public static final String REST_PARAM_RESPONSE = "response"; + public static final String REST_PARAM_POOLID = "poolid"; + public static final String REST_PARAM_ACCOUNTID = "accountid"; + public static final String REST_PARAM_GATEWAY = "router"; + public static final String REST_PARAM_SUBNET = "subnet"; + public static final String REST_PARAM_INTERFACE = "tntinterface"; + public static final String REST_PARAM_IPADDRESS = "ipaddress"; + public static final String REST_PARAM_JOBID = "jobId"; + public static final String REST_PARAM_FORECEDELETE = "forcedelete"; + public static final String REST_PARAM_TSM_THROUGHPUT = "totalthroughput"; + public static final String REST_PARAM_NAME = "name"; + public static final String REST_PARAM_NOOFCOPIES = "noofcopies"; + public static final String REST_PARAM_RECORDSIZE = "recordsize"; + public static final String REST_PARAM_TOTALIOPS = "totaliops"; + public static final String REST_PARAM_LATENCY = "latency"; + public static final String REST_PARAM_BLOCKSIZE = "blocksize"; + public static final String REST_PARAM_GRACEALLOWED = "graceallowed"; + public static final String REST_PARAM_IOPS = "iops"; + public static final String REST_PARAM_THROUGHPUT = "throughput"; + public static final String REST_PARAM_MEMLIMIT= "memlimit"; + public static final String REST_PARAM_NETWORKSPEED = "networkspeed"; + public static final String REST_PARAM_TSMID = "tsmid"; + public static final String REST_PARAM_DATASETID = "datasetid"; + public static final String REST_PARAM_QOSGROUPID = "qosgroupid"; + public static final String REST_PARAM_DEDUPLICATION = "deduplication"; + public static final String REST_PARAM_COMPRESSION = "compression"; + public static final String REST_PARAM_SYNC = "sync"; + public static final String REST_PARAM_MOUNTPOINT= "mountpoint"; + public static final String REST_PARAM_CASESENSITIVITY = "casesensitivity"; + public static final String REST_PARAM_UNICODE = "unicode"; + public static final String REST_PARAM_PROTOCOLTYPE= "protocoltype"; + public static final String REST_PARAM_AUTHNETWORK = "authnetwork"; + public static final String REST_PARAM_MAPUSERSTOROOT = "mapuserstoroot"; + + /** + * Constants related to elastistor which are persisted in cloudstack + * databases as keys. + */ + public static final String ES_SUBNET = "essubnet"; + public static final String ES_INTERFACE = "estntinterface"; + public static final String ES_GATEWAY = "esdefaultgateway"; + public static final String ES_PROVIDER_NAME = "elastistor"; + public static final String ES_ACCOUNT_ID = "esAccountId"; + public static final String ES_POOL_ID = "esPoolId"; + public static final String ES_ACCOUNT_NAME = "esAccountName"; + public static final String ES_STORAGE_IP = "esStorageIp"; + public static final String ES_STORAGE_PORT = "esStoragePort"; + public static final String ES_STORAGE_TYPE = "esStorageType"; + public static final String ES_MANAGEMENT_IP = "esMgmtIp"; + public static final String ES_MANAGEMENT_PORT = "esMgmtPort"; + public static final String ES_API_KEY = "esApiKey"; + public static final String ES_VOLUME_ID = "esVolumeId"; + public static final String ES_VOLUME_GROUP_ID = "esVolumeGroupId"; + public static final String ES_FILE_SYSTEM_ID = "esFilesystemId"; + + /** + * Values from configuration that are required for every invocation of + * ElastiCenter API. These might in turn be saved as DB updates along with + * above keys. + */ + public static String s_esIPVAL = ""; + public static String s_esAPIKEYVAL = ""; + public static String s_esACCOUNTIDVAL = ""; + public static String s_esPOOLIDVAL = ""; + public static String s_esSUBNETVAL = ""; + public static String s_esINTERFACEVAL = ""; + public static String s_esGATEWAYVAL = ""; + + /** + * hardcoded constants for elastistor api calls. + */ + private static final String ES_NOOFCOPIES_VAL = "1"; + private static final String ES_BLOCKSIZE_VAL = "4K"; + private static final String ES_LATENCY_VAL = "15"; + private static final String ES_GRACEALLOWED_VAL = "false"; + private static final String ES_MEMLIMIT_VAL = "0"; + private static final String ES_NETWORKSPEED_VAL = "0"; + private static final String ES_DEDUPLICATION_VAL = "off"; + private static final String ES_COMPRESSION_VAL = "off"; + private static final String ES_CASESENSITIVITY_VAL = "sensitive"; + private static final String ES_READONLY_VAL = "off"; + private static final String ES_UNICODE_VAL = "off"; + private static final String ES_AUTHNETWORK_VAL = "all"; + private static final String ES_MAPUSERSTOROOT_VAL = "yes"; + private static final String ES_SYNC_VAL = "always"; + + + /** + * Private constructor s.t. its never instantiated. + */ + private ElastistorUtil() { + + } + + /** + * This intializes a new jersey restclient for http call with elasticenter + */ + public static ElastiCenterClient getElastistorRestClient(String managementIp , String apiKey) { + ElastiCenterClient restclient = null; + try { + + restclient = new ElastiCenterClient(managementIp, apiKey); + + } catch (InvalidCredentialsException e) { + throw new CloudRuntimeException("InvalidCredentialsException", e); + } catch (InvalidParameterException e) { + throw new CloudRuntimeException("InvalidParameterException", e); + } catch (SSLHandshakeException e) { + throw new CloudRuntimeException("SSLHandshakeException", e); + } catch (ServiceUnavailableException e) { + throw new CloudRuntimeException("ServiceUnavailableException", e); + } + return restclient; + } + + public static void setElastistorApiKey(String value) { + s_esAPIKEYVAL = value; + } + + public static void setElastistorManagementIp(String value) { + s_esIPVAL = value; + } + + public static void setElastistorPoolId(String value) { + s_esPOOLIDVAL = value; + } + + public static void setElastistorAccountId(String value) { + s_esACCOUNTIDVAL = value; + } + + public static void setElastistorGateway(String value) { + s_esGATEWAYVAL = value; + } + + public static void setElastistorInterface(String value) { + s_esINTERFACEVAL = value; + } + + public static void setElastistorSubnet(String value) { + s_esSUBNETVAL = value; + } + + /** + * This creates a new tenant storage machine(TSM) for the given storagepool ip in elastistor. + */ + public static CreateTsmCmdResponse createElastistorTsm(String storagePoolName, String storageIp, Long capacityBytes, Long capacityIops) throws Throwable { + + String totalthroughput = String.valueOf(capacityIops*4); + String totaliops = String.valueOf(capacityIops); + + String quotasize = convertCapacityBytes(capacityBytes); + + CreateTsmCmd createTsmCmd = new CreateTsmCmd(); + + if ( null != ElastistorUtil.s_esACCOUNTIDVAL ) createTsmCmd.putCommandParameter(ElastistorUtil.REST_PARAM_ACCOUNTID, ElastistorUtil.s_esACCOUNTIDVAL); + if ( null != totalthroughput ) createTsmCmd.putCommandParameter(ElastistorUtil.REST_PARAM_TSM_THROUGHPUT, totalthroughput); + if ( null != ElastistorUtil.s_esPOOLIDVAL ) createTsmCmd.putCommandParameter(ElastistorUtil.REST_PARAM_POOLID, ElastistorUtil.s_esPOOLIDVAL); + if ( null != storagePoolName ) createTsmCmd.putCommandParameter(ElastistorUtil.REST_PARAM_NAME, "TSM"+storagePoolName); + if ( null != quotasize ) createTsmCmd.putCommandParameter(ElastistorUtil.REST_PARAM_QUOTA_SIZE, quotasize); + if ( null != storageIp ) createTsmCmd.putCommandParameter(ElastistorUtil.REST_PARAM_IPADDRESS, storageIp); + if ( null != ElastistorUtil.s_esSUBNETVAL ) createTsmCmd.putCommandParameter(ElastistorUtil.REST_PARAM_SUBNET, ElastistorUtil.s_esSUBNETVAL); + if ( null != ElastistorUtil.s_esGATEWAYVAL ) createTsmCmd.putCommandParameter(ElastistorUtil.REST_PARAM_GATEWAY, ElastistorUtil.s_esGATEWAYVAL); + if ( null != ElastistorUtil.s_esINTERFACEVAL ) createTsmCmd.putCommandParameter(ElastistorUtil.REST_PARAM_INTERFACE, ElastistorUtil.s_esINTERFACEVAL); + if ( null != ElastistorUtil.ES_NOOFCOPIES_VAL ) createTsmCmd.putCommandParameter(ElastistorUtil.REST_PARAM_NOOFCOPIES, ElastistorUtil.ES_NOOFCOPIES_VAL); + if ( null != ElastistorUtil.ES_BLOCKSIZE_VAL ) createTsmCmd.putCommandParameter(ElastistorUtil.REST_PARAM_RECORDSIZE, ElastistorUtil.ES_BLOCKSIZE_VAL); + if ( null != totaliops ) createTsmCmd.putCommandParameter(ElastistorUtil.REST_PARAM_TOTALIOPS, totaliops); + if ( null != ElastistorUtil.ES_LATENCY_VAL ) createTsmCmd.putCommandParameter(ElastistorUtil.REST_PARAM_LATENCY, ElastistorUtil.ES_LATENCY_VAL); + if ( null != ElastistorUtil.ES_BLOCKSIZE_VAL ) createTsmCmd.putCommandParameter(ElastistorUtil.REST_PARAM_BLOCKSIZE, ElastistorUtil.ES_BLOCKSIZE_VAL); + if ( null != ElastistorUtil.ES_GRACEALLOWED_VAL ) createTsmCmd.putCommandParameter(ElastistorUtil.REST_PARAM_GRACEALLOWED, ElastistorUtil.ES_GRACEALLOWED_VAL); + + CreateTsmCmdResponse cmdResponse; + + try { + cmdResponse = (CreateTsmCmdResponse) getElastistorRestClient(s_esIPVAL, s_esAPIKEYVAL).executeCommand(createTsmCmd); + + if ( cmdResponse.getTsm().getUuid() == null ){ + throw new CloudRuntimeException("tsm creation failed , contact elatistor admin"); + } + return cmdResponse; + } catch (Exception e) { + throw new CloudRuntimeException("tsm creation failed , contact elatistor admin" + e.toString()); + } + + } + + /** + * This creates the specified volume on the created tsm. + */ + public static CreateVolumeCmdResponse createElastistorVolume(String storagePoolName, CreateTsmCmdResponse cmdResponse, Long capacityBytes, Long capacityIops,String protocoltype, String mountpoint) throws Throwable { + + String datasetid; + String tsmid; + String qosgroupid; + String VolumeName = storagePoolName; + String totaliops = String.valueOf(capacityIops); + String totalthroughput = String.valueOf(capacityIops*4); + + String quotasize = convertCapacityBytes(capacityBytes); + + AddQosGroupCmd addQosGroupCmd = new AddQosGroupCmd(); + + + tsmid = cmdResponse.getTsm().getUuid(); + datasetid = cmdResponse.getTsm().getDatasetid(); + + if (null != VolumeName)addQosGroupCmd.putCommandParameter(ElastistorUtil.REST_PARAM_NAME, "QOS_" + VolumeName); + if (null != totaliops)addQosGroupCmd.putCommandParameter(ElastistorUtil.REST_PARAM_IOPS, totaliops); + if (null != ElastistorUtil.ES_LATENCY_VAL)addQosGroupCmd.putCommandParameter(ElastistorUtil.REST_PARAM_LATENCY, ElastistorUtil.ES_LATENCY_VAL); + if (null != ElastistorUtil.ES_BLOCKSIZE_VAL)addQosGroupCmd.putCommandParameter(ElastistorUtil.REST_PARAM_BLOCKSIZE, ElastistorUtil.ES_BLOCKSIZE_VAL); + if (null != totalthroughput)addQosGroupCmd.putCommandParameter(ElastistorUtil.REST_PARAM_THROUGHPUT, totalthroughput); + if (null != ElastistorUtil.ES_MEMLIMIT_VAL)addQosGroupCmd.putCommandParameter(ElastistorUtil.REST_PARAM_MEMLIMIT, ElastistorUtil.ES_MEMLIMIT_VAL); + if (null != ElastistorUtil.ES_NETWORKSPEED_VAL)addQosGroupCmd.putCommandParameter(ElastistorUtil.REST_PARAM_NETWORKSPEED, ElastistorUtil.ES_NETWORKSPEED_VAL); + if (null != tsmid)addQosGroupCmd.putCommandParameter(ElastistorUtil.REST_PARAM_TSMID, tsmid); + if (null != datasetid)addQosGroupCmd.putCommandParameter(ElastistorUtil.REST_PARAM_DATASETID, datasetid); + if (null != ElastistorUtil.ES_GRACEALLOWED_VAL)addQosGroupCmd.putCommandParameter(ElastistorUtil.REST_PARAM_GRACEALLOWED, ElastistorUtil.ES_GRACEALLOWED_VAL); + + AddQosGroupCmdResponse addQosGroupCmdResponse = (AddQosGroupCmdResponse) getElastistorRestClient(s_esIPVAL, s_esAPIKEYVAL).executeCommand(addQosGroupCmd); + + if (addQosGroupCmdResponse.getQoSGroup().getUuid() == null) { + + throw new CloudRuntimeException("adding qos group failed , contact elatistor admin"); + + } + + else { + + CreateVolumeCmd createVolumeCmd = new CreateVolumeCmd(); + + qosgroupid = addQosGroupCmdResponse.getQoSGroup().getUuid(); + + if (null != ElastistorUtil.s_esACCOUNTIDVAL)createVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_ACCOUNTID,ElastistorUtil.s_esACCOUNTIDVAL); + if (null != qosgroupid)createVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_QOSGROUPID, qosgroupid); + if (null != tsmid)createVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_TSMID, tsmid); + if (null != ElastistorUtil.s_esPOOLIDVAL)createVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_POOLID,ElastistorUtil.s_esPOOLIDVAL); + if (null != VolumeName)createVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_NAME, VolumeName); + if (null != quotasize)createVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_QUOTA_SIZE, quotasize); + if(protocoltype.equalsIgnoreCase("nfs")){ + if ( null != ElastistorUtil.ES_BLOCKSIZE_VAL ) createVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_BLOCKSIZE, ElastistorUtil.ES_BLOCKSIZE_VAL); + if ( null != ElastistorUtil.ES_BLOCKSIZE_VAL ) createVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_RECORDSIZE, ElastistorUtil.ES_BLOCKSIZE_VAL); + } + else{ + if ( null != ElastistorUtil.ES_BLOCKSIZE_VAL ) createVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_BLOCKSIZE, "512B"); + if ( null != ElastistorUtil.ES_BLOCKSIZE_VAL ) createVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_RECORDSIZE, "512B"); + } + if (null != ElastistorUtil.ES_DEDUPLICATION_VAL)createVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_DEDUPLICATION, ElastistorUtil.ES_DEDUPLICATION_VAL); + if (null != ElastistorUtil.ES_SYNC_VAL)createVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_SYNC, ElastistorUtil.ES_SYNC_VAL); + if (null != ElastistorUtil.ES_COMPRESSION_VAL)createVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_COMPRESSION, ElastistorUtil.ES_COMPRESSION_VAL); + if (null != ElastistorUtil.ES_NOOFCOPIES_VAL)createVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_NOOFCOPIES, ElastistorUtil.ES_NOOFCOPIES_VAL); + createVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_MOUNTPOINT, mountpoint); + if (null != ElastistorUtil.ES_CASESENSITIVITY_VAL)createVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_CASESENSITIVITY, ElastistorUtil.ES_CASESENSITIVITY_VAL); + if (null != ElastistorUtil.ES_READONLY_VAL)createVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_READONLY, ElastistorUtil.ES_READONLY_VAL); + if (null != datasetid)createVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_DATASETID, datasetid); + if (null != ElastistorUtil.ES_UNICODE_VAL)createVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_UNICODE, ElastistorUtil.ES_UNICODE_VAL); + createVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_PROTOCOLTYPE, protocoltype); + if (null != ElastistorUtil.ES_AUTHNETWORK_VAL)createVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_AUTHNETWORK, ElastistorUtil.ES_AUTHNETWORK_VAL); + if (null != ElastistorUtil.ES_MAPUSERSTOROOT_VAL)createVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_MAPUSERSTOROOT, ElastistorUtil.ES_MAPUSERSTOROOT_VAL); + + CreateVolumeCmdResponse createVolumeCmdResponse; + try { + createVolumeCmdResponse = (CreateVolumeCmdResponse) getElastistorRestClient(s_esIPVAL, s_esAPIKEYVAL).executeCommand(createVolumeCmd); + + if (createVolumeCmdResponse.getFileSystem().getUuid() == null) { + + throw new CloudRuntimeException("creating volume failed , contact elatistor admin"); + + } else { + return createVolumeCmdResponse; + } + + } catch (Exception e) { + throw new CloudRuntimeException("creating volume failed , contact elatistor admin", e); + } + + } + + } + + /** + * This deletes both the volume and the tsm in elastistor. + */ + public static boolean deleteElastistorVolume(String poolip, String esmanagementip, String esapikey) throws Throwable { + + String esvolumeid = null; + String estsmid = null; + + ListTsmsResponse listTsmsResponse = listTsm(poolip); + + if (listTsmsResponse.getTsmsCount() != 0) { + int i; + + for (i = 0; i < listTsmsResponse.getTsmsCount(); i++) { + if (poolip.compareTo(listTsmsResponse.getTsms().getTsm(i).getIpaddress()) == 0) { + estsmid = listTsmsResponse.getTsms().getTsm(i).getUuid(); + break; + } + } + + if (listTsmsResponse.getTsms().getTsm(i).checkvolume()) { + esvolumeid = listTsmsResponse.getTsms().getTsm(i).getVolumeProperties(0).getid(); + DeleteVolumeResponse deleteVolumeResponse = deleteVolume(esvolumeid, null); + + if (deleteVolumeResponse != null) { + String jobid = deleteVolumeResponse.getJobId(); + int jobstatus = queryAsyncJobResult(jobid); + + if (jobstatus == 1) { + s_logger.info("elastistor volume successfully deleted"); + } else { + s_logger.info("now farce deleting the volume"); + + while (jobstatus != 1) { + DeleteVolumeResponse deleteVolumeResponse1 = deleteVolume(esvolumeid, "true"); + + if (deleteVolumeResponse1 != null) { + String jobid1 = deleteVolumeResponse1.getJobId(); + jobstatus = queryAsyncJobResult(jobid1); + } + } + s_logger.info("elastistor volume successfully deleted"); + } + } + } else { + s_logger.info("no volume present in on the given tsm"); + } + s_logger.info("now trying to delete elastistor tsm"); + + if (estsmid != null) { + DeleteTsmCmd deleteTsmCmd = new DeleteTsmCmd(); + deleteTsmCmd.putCommandParameter(ElastistorUtil.REST_PARAM_ID,estsmid); + DeleteTsmResponse deleteTsmResponse = (DeleteTsmResponse) getElastistorRestClient(s_esIPVAL, s_esAPIKEYVAL).executeCommand(deleteTsmCmd); + + if (deleteTsmResponse != null) { + String jobstatus = deleteTsmResponse.getJobStatus(); + + if (jobstatus.equalsIgnoreCase("true")) { + s_logger.info("deletion of elastistor tsm successful"); + return true; + } else { + s_logger.info("failed to delete elastistor tsm"); + return false; + } + } else { + s_logger.info("elastistor tsm id not present"); + } + } + else { + s_logger.error("no volume is present in the tsm"); + } + } else { + s_logger.error("List tsm failed, no tsm present in the eastistor for the given IP "); + return false; + } + return false; + + } + + /** + * This give a json response containing the list of tsm's in elastistor. + */ + private static ListTsmsResponse listTsm(String poolip) throws Throwable { + + ListTsmCmd listTsmCmd = new ListTsmCmd(); + + listTsmCmd.putCommandParameter(ElastistorUtil.REST_PARAM_IPADDRESS,poolip); + + ListTsmsResponse listTsmsResponse = (ListTsmsResponse) getElastistorRestClient(s_esIPVAL, s_esAPIKEYVAL).executeCommand(listTsmCmd); + + return listTsmsResponse; + } + + private static DeleteVolumeResponse deleteVolume(String esvolumeid, String forcedelete)throws Throwable { + + DeleteVolumeCmd deleteVolumeCmd = new DeleteVolumeCmd(); + + deleteVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_ID,esvolumeid); + deleteVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_FORECEDELETE, forcedelete); + + DeleteVolumeResponse deleteVolumeResponse = (DeleteVolumeResponse) getElastistorRestClient(s_esIPVAL, s_esAPIKEYVAL).executeCommand(deleteVolumeCmd); + + return deleteVolumeResponse; + } + + private static int queryAsyncJobResult(String jobid) throws Throwable { + + QueryAsyncJobResultCmd asyncJobResultCmd = new QueryAsyncJobResultCmd(); + ElastiCenterClient restclient = getElastistorRestClient(s_esIPVAL, s_esAPIKEYVAL); + + asyncJobResultCmd.putCommandParameter(ElastistorUtil.REST_PARAM_JOBID, jobid); + + QueryAsyncJobResultResponse asyncJobResultResponse = (QueryAsyncJobResultResponse) restclient.executeCommand(asyncJobResultCmd); + + if (asyncJobResultResponse != null) { + int jobstatus = asyncJobResultResponse.getAsync().getJobStatus(); + + while (jobstatus == 0) { + + QueryAsyncJobResultResponse jobResultResponse = (QueryAsyncJobResultResponse) restclient.executeCommand(asyncJobResultCmd); + + jobstatus = jobResultResponse.getAsync().getJobStatus(); + } + return jobstatus; + } + return 0; + + } + + /** + * this method converts the long capacitybytes to string format, which is feasible for elastistor rest api + * 214748364800 = 200G. + */ + private static String convertCapacityBytes(Long capacityBytes){ + + String quotasize; + + if((1099511627776L)>capacityBytes &&(capacityBytes>(1073741824))){ + return quotasize =(String.valueOf(capacityBytes/(1024*1024*1024))+"G"); + }else + { int temp1 = (int) (capacityBytes/(1024*1024*1024)); + int temp2 = temp1/1024; + return quotasize =(String.valueOf(temp2)+"T"); + } + } + + static interface ElastiCenterCommand { + + /* + * Returns the command string to be sent to the ElastiCenter + */ + public String getCommandName(); + + /* + * Utility method to allow the client to validate the input parameters + * before sending to the ElastiCenter. + * + * This command will be executed by the ElastiCenterClient only this method + * returns true. + */ + public boolean validate(); + + /* + * Returns the query parameters that have to be passed to execute the + * command. + * + * Returns null if there are query parameters associated with the command + */ + public MultivaluedMap getCommandParameters(); + + /* + * Adds new key-value pair to the query paramters lists. + */ + public void putCommandParameter(String key, String value); + + /* + * Return an instance of the Response Object Type. + * + * Return null if no response is expected. + */ + public Object getResponseObject(); + } + + private static class BaseCommand implements ElastiCenterCommand { + + private String commandName = null; + private MultivaluedMap commandParameters = null; + private Object responseObject = null; + + /* + * Enforce the Commands to be initialized with command name and optional + * response object + */ + protected BaseCommand(String cmdName, Object responseObj) { + commandName = cmdName; + responseObject = responseObj; + } + + @Override + public String getCommandName() { + return commandName; + } + + @Override + public boolean validate() { + // TODO This method can be extended to do some generic + // validations. + return true; + } + + @Override + public MultivaluedMap getCommandParameters() { + return commandParameters; + } + + @Override + public void putCommandParameter(String key, String value) { + if (null == commandParameters) { + commandParameters = new MultivaluedMapImpl(); + } + commandParameters.add(key, value); + } + + @Override + public Object getResponseObject() { + return responseObject; + } + + } + +/** + * this is a rest client which is used to call the http rest calls to elastistor + * @author punith + * + */ + private static final class ElastiCenterClient { + + public static boolean debug = false; + + private boolean initialized = false; + + private String apiKey = null; + private String elastiCenterAddress = null; + private String responseType = "json"; + private boolean ignoreSSLCertificate = false; + + private String restprotocol = "https://"; + private String restpath = "/client/api"; + private String restdefaultcommand = "listCapabilities"; + + private String queryparamcommand = "command"; + private String queryparamapikey = "apikey"; + private String queryparamresponse = "response"; + + public ElastiCenterClient(String address, String key)throws InvalidCredentialsException, InvalidParameterException,SSLHandshakeException, ServiceUnavailableException { + this.elastiCenterAddress = address; + this.apiKey = key; + this.initialize(); + } + + public void initialize() throws InvalidParameterException, + SSLHandshakeException, InvalidCredentialsException, + ServiceUnavailableException { + + if (apiKey == null || apiKey.trim().isEmpty()) { + throw new InvalidParameterException("Unable to initialize. Please specify a valid API Key."); + } + + if (elastiCenterAddress == null || elastiCenterAddress.trim().isEmpty()) { + // TODO : Validate the format, like valid IP address or hostname. + throw new InvalidParameterException("Unable to initialize. Please specify a valid ElastiCenter IP Address or Hostname."); + } + + if (ignoreSSLCertificate) { + // Create a trust manager that does not validate certificate chains + TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() { + public X509Certificate[] getAcceptedIssuers() { + return null; + } + + public void checkClientTrusted(X509Certificate[] certs, + String authType) { + } + + public void checkServerTrusted(X509Certificate[] certs, + String authType) { + } + } }; + + HostnameVerifier hv = new HostnameVerifier() { + @Override + public boolean verify(String urlHostName, SSLSession session) { + return true; + } + }; + + // Install the all-trusting trust manager + try { + SSLContext sc = SSLContext.getInstance("TLS"); + sc.init(null, trustAllCerts, new SecureRandom()); + HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); + HttpsURLConnection.setDefaultHostnameVerifier(hv); + } catch (Exception e) { + ; + } + } + + ListCapabilitiesResponse listCapabilitiesResponse = null; + try { + initialized = true; + listCapabilitiesResponse = (ListCapabilitiesResponse) executeCommand(restdefaultcommand, null, new ListCapabilitiesResponse()); + + } catch (Throwable t) { + initialized = false; + if (t instanceof InvalidCredentialsException) { + throw (InvalidCredentialsException) t; + } else if (t instanceof ServiceUnavailableException) { + throw (ServiceUnavailableException) t; + } else if (t.getCause() instanceof SSLHandshakeException) { + throw new SSLHandshakeException( + "Unable to initialize. An untrusted SSL Certificate was received from " + + elastiCenterAddress + + ". Please verify your truststore or configure ElastiCenterClient to skip the SSL Validation. "); + } else if (t.getCause() instanceof ConnectException) { + throw new ServiceUnavailableException( + "Unable to initialize. Failed to connect to " + + elastiCenterAddress + + ". Please verify the IP Address, Network Connectivity and ensure that Services are running on the ElastiCenter Server. "); + } + throw new ServiceUnavailableException("Unable to initialize. Please contact your ElastiCenter Administrator. Exception " + t.getMessage()); + } + + if (null == listCapabilitiesResponse || null == listCapabilitiesResponse.getCapabilities() || null == listCapabilitiesResponse.getCapabilities().getVersion()) { + initialized = false; + throw new ServiceUnavailableException("Unable to execute command on the server"); + } + + } + + public Object executeCommand(ElastiCenterCommand cmd) throws Throwable { + return executeCommand(cmd.getCommandName(), cmd.getCommandParameters(),cmd.getResponseObject()); + } + + public Object executeCommand(String command,MultivaluedMap params, Object responeObj) throws Throwable { + + if (!initialized) { + throw new IllegalStateException("Error : ElastiCenterClient is not initialized."); + } + + if (command == null || command.trim().isEmpty()) { + throw new InvalidParameterException("No command to execute."); + } + + try { + ClientConfig config = new DefaultClientConfig(); + Client client = Client.create(config); + WebResource webResource = client.resource(UriBuilder.fromUri(restprotocol + elastiCenterAddress + restpath).build()); + + MultivaluedMap queryParams = new MultivaluedMapImpl(); + queryParams.add(queryparamapikey, apiKey); + queryParams.add(queryparamresponse, responseType); + + queryParams.add(queryparamcommand, command); + + if (null != params) { + for (String key : params.keySet()) { + queryParams.add(key, params.getFirst(key)); + } + } + if (debug) { + System.out.println("Command Sent " + command + " : "+ queryParams); + } + ClientResponse response = webResource.queryParams(queryParams).accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); + + if (response.getStatus() >= 300) { + if (debug) + System.out.println("ElastiCenter returned error code : " + response.getStatus()); + if (401 == response.getStatus()) { + throw new InvalidCredentialsException("Please specify a valid API Key."); + } else if (431 == response.getStatus()) { + throw new InvalidParameterException(response.getHeaders().getFirst("X-Description")); + } else if (432 == response.getStatus()) { + throw new InvalidParameterException(command + " does not exist on the ElastiCenter server. Please specify a valid command or contact your ElastiCenter Administrator."); + } else { + throw new ServiceUnavailableException("Internal Error. Please contact your ElastiCenter Administrator."); + } + } else if (null != responeObj) { + String jsonResponse = response.getEntity(String.class); + if (debug) { + System.out.println("Command Response : " + jsonResponse); + } + Gson gson = new Gson(); + return gson.fromJson(jsonResponse, responeObj.getClass()); + } else { + return "Success"; + } + } catch (Throwable t) { + throw t; + } + } + } + + /** + * these are the list of Elastistor rest commands being called from the plugin. + * + */ + private static final class CreateTsmCmd extends BaseCommand { + + public CreateTsmCmd() { + super("createTsm", new CreateTsmCmdResponse()); + + } + + } + + private static final class AddQosGroupCmd extends BaseCommand { + + public AddQosGroupCmd() { + + super("addQosGroup", new AddQosGroupCmdResponse()); + + } + + } + + private static final class CreateVolumeCmd extends BaseCommand { + + public CreateVolumeCmd() { + super("createVolume", new CreateVolumeCmdResponse()); + + } + + } + + private static final class DeleteTsmCmd extends BaseCommand { + + public DeleteTsmCmd() { + super("deleteTsm", new DeleteTsmResponse()); + } + + } + + private static final class DeleteVolumeCmd extends BaseCommand { + + public DeleteVolumeCmd() { + super("deleteFileSystem", new DeleteVolumeResponse()); + } + + } + + private static final class QueryAsyncJobResultCmd extends BaseCommand { + + public QueryAsyncJobResultCmd() { + super("queryAsyncJobResult", new QueryAsyncJobResultResponse()); + } + + } + + private static final class ListTsmCmd extends BaseCommand { + + public ListTsmCmd() { + super("listTsm", new ListTsmsResponse()); + } + + } + + /** + * these are the list of Elastistor rest json response classes for parsing the json response sent by elastistor. + * + */ + public static final class CreateTsmCmdResponse { + + @SerializedName("createTsmResponse") + private TsmWrapper tsmWrapper; + + public Tsm getTsm() { + return tsmWrapper.getTsm(); + } + + } + + public static final class Tsm { + + @SerializedName("id") + private String uuid; + + @SerializedName("name") + private String name; + + @SerializedName("datasetid") + private String datasetid; + + @SerializedName("ipaddress") + private String ipaddress; + + @SerializedName("volumes") + private VolumeProperties[] volumeProperties; + + public String getUuid() { + return uuid; + } + + public String getName() { + return name; + } + + public String getIpaddress() { + return ipaddress; + } + + public String getDatasetid() { + return datasetid; + } + + public boolean checkvolume() { + + if(volumeProperties != null){ + return true; + } + else{ + return false; + } + + } + + public VolumeProperties getVolumeProperties(int i) { + return volumeProperties[i]; + } + + } + + public static final class VolumeProperties { + + @SerializedName("id") + private String id; + + @SerializedName("groupid") + private String groupid; + + @SerializedName("iops") + private String iops; + + @SerializedName("name") + private String name; + + public String getid() { + return id; + } + + public String getQosgroupid() { + return groupid; + } + + public String getName() { + return name; + } + + public String getIops() { + return iops; + } + } + + public static final class TsmWrapper { + + @SerializedName("tsm") + private Tsm tsm; + + public Tsm getTsm() { + return tsm; + } + + } + + public static final class AddQosGroupCmdResponse { + + @SerializedName("addqosgroupresponse") + private QoSGroupWrapper qosGroupWrapper; + + public QoSGroup getQoSGroup() { + return qosGroupWrapper.getQosGroup(); + } + } + + public static final class QoSGroupWrapper { + + @SerializedName("qosgroup") + private QoSGroup qoSGroup; + + public QoSGroup getQosGroup() { + + return qoSGroup; + } + + } + + public static final class QoSGroup { + + @SerializedName("id") + private String uuid; + + @SerializedName("name") + private String name; + + @SerializedName("qosgroupproperties") + private HashMap qosGroupProperties; + + public String getName() { + return name; + } + + public String getUuid() { + return uuid; + } + + public String getIops() { + return qosGroupProperties.get("iops"); + } + + public String getThroughput() { + return qosGroupProperties.get("throughput"); + } + + public String getLatency() { + return qosGroupProperties.get("latency"); + } + } + + public static final class CreateVolumeCmdResponse { + + @SerializedName("adddatasetresponse") + private FileSystemWrapper fileSystemWrapper; + + public FileSystem getFileSystem() { + + return fileSystemWrapper.getFileSystem(); + } + + } + + public static final class FileSystemWrapper { + + @SerializedName("filesystem") + private FileSystem fileSystem; + + public FileSystem getFileSystem() { + return fileSystem; + } + + } + + public static final class FileSystem { + + @SerializedName("id") + private String uuid; + + @SerializedName("name") + private String name; + + @SerializedName("quota") + private String quota; + + @SerializedName("timestamp") + private String timestamp; + + @SerializedName("iqnname") + private String iqnname; + + @SerializedName("filesystemproperties") + private HashMap[] filesystemproperties; + + public String getUuid() { + return uuid; + } + + public String getName() { + return name; + } + + public String getIqn() { + return iqnname; + } + + public String getQuota() { + return quota; + } + + public String getTimestamp() { + return timestamp; + } + + } + + public static final class DeleteTsmResponse { + + @SerializedName("deleteTsmResponse") + private JobId jobId; + + public String getJobStatus() { + return jobId.getJobStatus(); + } + + } + + public static final class JobId { + + @SerializedName("jobid") + private String jobid; + + @SerializedName("success") + private String jobStatus; + + public String getJobid() { + return jobid; + } + + public String getJobStatus() { + return jobStatus; + } + + } + + public static final class DeleteVolumeResponse { + + @SerializedName("deleteFileSystemResponse") + private JobId jobId; + + public String getJobId() { + return jobId.getJobid(); + } + + } + + public static final class ListCapabilitiesResponse { + + @SerializedName("listcapabilitiesresponse") + private Capabilities capabilities; + + public Capabilities getCapabilities() { + return capabilities; + } + } + + public static final class ListTsmsResponse { + + @SerializedName("listTsmResponse") + private Tsms tsms; + + public int getTsmsCount() { + return tsms.getCount(); + } + + public Tsms getTsms() { + return tsms; + } + } + + public static final class Tsms { + + @SerializedName("count") + private int count; + + @SerializedName("listTsm") + private Tsm[] tsms; + + public int getCount() { + return count; + } + + public Tsm getTsm(int i) { + return tsms[i]; + } + } + + public static final class QueryAsyncJobResultResponse { + + @SerializedName("queryasyncjobresultresponse") + private Async async; + + public Async getAsync() { + return async; + } + } + + public static final class Async { + + @SerializedName("jobstatus") + private int jobstatus; + + @SerializedName("cmd") + private String cmd; + + public int getJobStatus() { + return jobstatus; + } + + public String getCmd() { + return cmd; + } + + } + + public static final class Capabilities { + + @SerializedName("capability") + private HashMap capabilites; + + public String getVersion() { + return capabilites.get("cloudByteVersion"); + } + } +} diff --git a/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java b/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java index ae217b6359..5983a05a53 100644 --- a/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java +++ b/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java @@ -24,7 +24,6 @@ import javax.inject.Inject; -import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService; import org.apache.cloudstack.engine.subsystem.api.storage.ChapInfo; import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; @@ -99,8 +98,6 @@ public Map getCapabilities() { @Inject StorageManager storageMgr; @Inject - VolumeOrchestrationService volumeMgr; - @Inject VMInstanceDao vmDao; @Inject SnapshotDao snapshotDao; @@ -151,10 +148,13 @@ public ChapInfo getChapInfo(VolumeInfo volumeInfo) { } @Override - public boolean connectVolumeToHost(VolumeInfo volumeInfo, Host host, DataStore dataStore) { return false; } + public boolean connectVolumeToHost(VolumeInfo volumeInfo, Host host, DataStore dataStore) { + return false; + } @Override - public void disconnectVolumeFromHost(VolumeInfo volumeInfo, Host host, DataStore dataStore) {} + public void disconnectVolumeFromHost(VolumeInfo volumeInfo, Host host, DataStore dataStore) { + } @Override public long getVolumeSizeIncludingHypervisorSnapshotReserve(Volume volume, StoragePool pool) { @@ -168,7 +168,7 @@ public void createAsync(DataStore dataStore, DataObject data, AsyncCompletionCal CreateCmdResult result = new CreateCmdResult(null, null); if (data.getType() == DataObjectType.VOLUME) { try { - answer = createVolume((VolumeInfo)data); + answer = createVolume((VolumeInfo) data); if ((answer == null) || (!answer.getResult())) { result.setSuccess(false); if (answer != null) { @@ -260,7 +260,7 @@ public boolean canCopy(DataObject srcData, DataObject destData) { DataStore store = destData.getDataStore(); if (store.getRole() == DataStoreRole.Primary) { if ((srcData.getType() == DataObjectType.TEMPLATE && destData.getType() == DataObjectType.TEMPLATE) || - (srcData.getType() == DataObjectType.TEMPLATE && destData.getType() == DataObjectType.VOLUME)) { + (srcData.getType() == DataObjectType.TEMPLATE && destData.getType() == DataObjectType.VOLUME)) { StoragePoolVO storagePoolVO = primaryStoreDao.findById(store.getId()); if (storagePoolVO != null && storagePoolVO.getPoolType() == Storage.StoragePoolType.CLVM) { return true; @@ -274,10 +274,10 @@ public boolean canCopy(DataObject srcData, DataObject destData) { public void takeSnapshot(SnapshotInfo snapshot, AsyncCompletionCallback callback) { CreateCmdResult result = null; try { - SnapshotObjectTO snapshotTO = (SnapshotObjectTO)snapshot.getTO(); + SnapshotObjectTO snapshotTO = (SnapshotObjectTO) snapshot.getTO(); Object payload = snapshot.getPayload(); if (payload != null && payload instanceof CreateSnapshotPayload) { - CreateSnapshotPayload snapshotPayload = (CreateSnapshotPayload)payload; + CreateSnapshotPayload snapshotPayload = (CreateSnapshotPayload) payload; snapshotTO.setQuiescevm(snapshotPayload.getQuiescevm()); } @@ -285,7 +285,7 @@ public void takeSnapshot(SnapshotInfo snapshot, AsyncCompletionCallback callback) { - VolumeObject vol = (VolumeObject)data; - StoragePool pool = (StoragePool)data.getDataStore(); - ResizeVolumePayload resizeParameter = (ResizeVolumePayload)vol.getpayload(); + VolumeObject vol = (VolumeObject) data; + StoragePool pool = (StoragePool) data.getDataStore(); + ResizeVolumePayload resizeParameter = (ResizeVolumePayload) vol.getpayload(); ResizeVolumeCommand resizeCmd = - new ResizeVolumeCommand(vol.getPath(), new StorageFilerTO(pool), vol.getSize(), resizeParameter.newSize, resizeParameter.shrinkOk, - resizeParameter.instanceName); + new ResizeVolumeCommand(vol.getPath(), new StorageFilerTO(pool), vol.getSize(), resizeParameter.newSize, resizeParameter.shrinkOk, + resizeParameter.instanceName); CreateCmdResult result = new CreateCmdResult(null, null); try { - ResizeVolumeAnswer answer = (ResizeVolumeAnswer)storageMgr.sendToPool(pool, resizeParameter.hosts, resizeCmd); + ResizeVolumeAnswer answer = (ResizeVolumeAnswer) storageMgr.sendToPool(pool, resizeParameter.hosts, resizeCmd); if (answer != null && answer.getResult()) { long finalSize = answer.getNewSize(); s_logger.debug("Resize: volume started at size " + vol.getSize() + " and ended at size " + finalSize); diff --git a/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackPrimaryDataStoreLifeCycleImpl.java b/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackPrimaryDataStoreLifeCycleImpl.java index 3c1b76a62d..65236d9629 100644 --- a/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackPrimaryDataStoreLifeCycleImpl.java +++ b/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackPrimaryDataStoreLifeCycleImpl.java @@ -255,7 +255,6 @@ public DataStore initialize(Map dsInfos) { if (clusterId == null) { throw new IllegalArgumentException("IscsiLUN need to have clusters specified"); } - hostPath = hostPath.replaceFirst("/", ""); parameters.setType(StoragePoolType.IscsiLUN); parameters.setHost(storageHost); parameters.setPort(port); diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LdapCreateAccountCmd.java b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LdapCreateAccountCmd.java index 626bb8fee6..b753952aec 100644 --- a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LdapCreateAccountCmd.java +++ b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LdapCreateAccountCmd.java @@ -23,9 +23,6 @@ import javax.inject.Inject; import javax.naming.NamingException; -import org.apache.log4j.Logger; -import org.bouncycastle.util.encoders.Base64; - import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.ApiErrorCode; @@ -38,13 +35,16 @@ import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.ldap.LdapManager; import org.apache.cloudstack.ldap.LdapUser; +import org.apache.log4j.Logger; +import org.bouncycastle.util.encoders.Base64; +import com.cloud.domain.DomainVO; import com.cloud.user.Account; import com.cloud.user.AccountService; +import com.cloud.user.User; import com.cloud.user.UserAccount; -@APICommand(name = "ldapCreateAccount", description = "Creates an account from an LDAP user", responseObject = AccountResponse.class, since = "4.2.0", - requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) +@APICommand(name = "ldapCreateAccount", description = "Creates an account from an LDAP user", responseObject = AccountResponse.class, since = "4.2.0", requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class LdapCreateAccountCmd extends BaseCmd { public static final Logger s_logger = Logger.getLogger(LdapCreateAccountCmd.class.getName()); private static final String s_name = "createaccountresponse"; @@ -52,23 +52,16 @@ public class LdapCreateAccountCmd extends BaseCmd { @Inject private LdapManager _ldapManager; - @Parameter(name = ApiConstants.ACCOUNT, - type = CommandType.STRING, - description = "Creates the user under the specified account. If no account is specified, the username will be used as the account name.") + @Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "Creates the user under the specified account. If no account is specified, the username will be used as the account name.") private String accountName; - @Parameter(name = ApiConstants.ACCOUNT_TYPE, - type = CommandType.SHORT, - required = true, - description = "Type of the account. Specify 0 for user, 1 for root admin, and 2 for domain admin") + @Parameter(name = ApiConstants.ACCOUNT_TYPE, type = CommandType.SHORT, required = true, description = "Type of the account. Specify 0 for user, 1 for root admin, and 2 for domain admin") private Short accountType; @Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, entityType = DomainResponse.class, description = "Creates the user under the specified domain.") private Long domainId; - @Parameter(name = ApiConstants.TIMEZONE, - type = CommandType.STRING, - description = "Specifies a timezone for this command. For more information on the timezone parameter, see Time Zone Format.") + @Parameter(name = ApiConstants.TIMEZONE, type = CommandType.STRING, description = "Specifies a timezone for this command. For more information on the timezone parameter, see Time Zone Format.") private String timezone; @Parameter(name = ApiConstants.USERNAME, type = CommandType.STRING, required = true, description = "Unique username.") @@ -96,22 +89,46 @@ public LdapCreateAccountCmd(final LdapManager ldapManager, final AccountService _accountService = accountService; } - UserAccount createCloudstackUserAccount(final LdapUser user) { - return _accountService.createUserAccount(username, generatePassword(), user.getFirstname(), user.getLastname(), user.getEmail(), timezone, accountName, - accountType, domainId, networkDomain, details, accountUUID, userUUID); + UserAccount createCloudstackUserAccount(final LdapUser user, String accountName, Long domainId) { + Account account = _accountService.getActiveAccountByName(accountName, domainId); + if (account == null) { + return _accountService.createUserAccount(username, generatePassword(), user.getFirstname(), user.getLastname(), user.getEmail(), timezone, accountName, accountType, + domainId, networkDomain, details, accountUUID, userUUID); + } else { + User newUser = _accountService.createUser(username, generatePassword(), user.getFirstname(), user.getLastname(), user.getEmail(), timezone, accountName, domainId, + userUUID); + return _accountService.getUserAccountById(newUser.getId()); + } + } + + private String getAccountName() { + String name = accountName; + if (accountName == null) { + name = username; + } + return name; + } + + private Long getDomainId() { + Long id = domainId; + if (id == null) { + id = DomainVO.ROOT_DOMAIN; + } + return id; } @Override public void execute() throws ServerApiException { final CallContext callContext = getCurrentContext(); - callContext.setEventDetails("Account Name: " + accountName + ", Domain Id:" + domainId); + String finalAccountName = getAccountName(); + Long finalDomainId = getDomainId(); + callContext.setEventDetails("Account Name: " + finalAccountName + ", Domain Id:" + finalDomainId); try { final LdapUser user = _ldapManager.getUser(username); validateUser(user); - final UserAccount userAccount = createCloudstackUserAccount(user); + final UserAccount userAccount = createCloudstackUserAccount(user, finalAccountName, finalDomainId); if (userAccount != null) { - final AccountResponse response = _responseGenerator - .createUserAccountResponse(ResponseView.Full, userAccount); + final AccountResponse response = _responseGenerator.createUserAccountResponse(ResponseView.Full, userAccount); response.setResponseName(getCommandName()); setResponseObject(response); } else { @@ -159,4 +176,4 @@ private boolean validateUser(final LdapUser user) throws ServerApiException { } return true; } -} \ No newline at end of file +} diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LdapImportUsersCmd.java b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LdapImportUsersCmd.java index 887ad009fd..6f7be90fd2 100644 --- a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LdapImportUsersCmd.java +++ b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LdapImportUsersCmd.java @@ -25,6 +25,7 @@ import javax.inject.Inject; +import com.cloud.user.Account; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.ApiErrorCode; @@ -87,6 +88,9 @@ public class LdapImportUsersCmd extends BaseListCmd { private Domain _domain; + @Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "Creates the user under the specified account. If no account is specified, the username will be used as the account name.") + private String accountName; + @Inject private LdapManager _ldapManager; @@ -101,6 +105,17 @@ public LdapImportUsersCmd(final LdapManager ldapManager, final DomainService dom _accountService = accountService; } + private void createCloudstackUserAccount(LdapUser user, String accountName, Domain domain) { + Account account = _accountService.getActiveAccountByName(accountName, domain.getId()); + if (account == null) { + _accountService.createUserAccount(user.getUsername(), generatePassword(), user.getFirstname(), user.getLastname(), user.getEmail(), timezone, accountName, accountType, + domain.getId(), domain.getNetworkDomain(), details, UUID.randomUUID().toString(), UUID.randomUUID().toString()); + } else { + _accountService.createUser(user.getUsername(), generatePassword(), user.getFirstname(), user.getLastname(), user.getEmail(), timezone, accountName, domain.getId(), + UUID.randomUUID().toString()); + } + } + @Override public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException { @@ -122,8 +137,7 @@ public void execute() throws ResourceUnavailableException, InsufficientCapacityE for (LdapUser user : users) { Domain domain = getDomain(user); try { - _accountService.createUserAccount(user.getUsername(), generatePassword(), user.getFirstname(), user.getLastname(), user.getEmail(), timezone, - user.getUsername(), accountType, domain.getId(), domain.getNetworkDomain(), details, UUID.randomUUID().toString(), UUID.randomUUID().toString()); + createCloudstackUserAccount(user, getAccountName(user), domain); addedUsers.add(user); } catch (InvalidParameterValueException ex) { s_logger.error("Failed to create user with username: " + user.getUsername() + " ::: " + ex.getMessage()); @@ -135,6 +149,14 @@ public void execute() throws ResourceUnavailableException, InsufficientCapacityE setResponseObject(response); } + private String getAccountName(LdapUser user) { + String finalAccountName = accountName; + if(finalAccountName == null ) { + finalAccountName = user.getUsername(); + } + return finalAccountName; + } + private Domain getDomainForName(String name) { Domain domain = null; if (StringUtils.isNotBlank(name)) { diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapContextFactory.java b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapContextFactory.java index 4f6bb618c2..5811c32a3e 100644 --- a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapContextFactory.java +++ b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapContextFactory.java @@ -53,9 +53,10 @@ private DirContext createInitialDirContext(final String principal, final String return createInitialDirContext(principal, password, null, isSystemContext); } - private DirContext createInitialDirContext(final String principal, final String password, final String providerUrl, final boolean isSystemContext) - throws NamingException { - return new InitialDirContext(getEnvironment(principal, password, providerUrl, isSystemContext)); + private DirContext createInitialDirContext(final String principal, final String password, final String providerUrl, final boolean isSystemContext) throws NamingException { + Hashtable environment = getEnvironment(principal, password, providerUrl, isSystemContext); + s_logger.debug("initializing ldap with provider url: " + environment.get(Context.PROVIDER_URL)); + return new InitialDirContext(environment); } public DirContext createUserContext(final String principal, final String password) throws NamingException { diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapManagerImpl.java b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapManagerImpl.java index 6d71f4f17d..0e3bde840f 100644 --- a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapManagerImpl.java +++ b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapManagerImpl.java @@ -81,6 +81,7 @@ public LdapConfigurationResponse addConfiguration(final String hostname, final i s_logger.info("Added new ldap server with hostname: " + hostname); return new LdapConfigurationResponse(hostname, port); } catch (final NamingException e) { + s_logger.debug("NamingException while doing an LDAP bind", e); throw new InvalidParameterValueException("Unable to bind to the given LDAP server"); } } else { @@ -98,6 +99,7 @@ public boolean canAuthenticate(final String username, final String password) { closeContext(context); return true; } catch (final NamingException e) { + s_logger.debug("NamingException: while doing an LDAP bind for user "+" "+username, e); s_logger.info("Failed to authenticate user: " + username + ". incorrect password."); return false; } @@ -109,7 +111,7 @@ private void closeContext(final DirContext context) { context.close(); } } catch (final NamingException e) { - s_logger.warn(e.getMessage()); + s_logger.warn(e.getMessage(),e); } } @@ -183,6 +185,7 @@ public List getUsers() throws NoLdapUserMatchingQueryException { context = _ldapContextFactory.createBindContext(); return _ldapUserManager.getUsers(context); } catch (final NamingException e) { + s_logger.debug("ldap NamingException: ",e); throw new NoLdapUserMatchingQueryException("*"); } finally { closeContext(context); @@ -196,6 +199,7 @@ public List getUsersInGroup(String groupName) throws NoLdapUserMatchin context = _ldapContextFactory.createBindContext(); return _ldapUserManager.getUsersInGroup(groupName, context); } catch (final NamingException e) { + s_logger.debug("ldap NamingException: ",e); throw new NoLdapUserMatchingQueryException("groupName=" + groupName); } finally { closeContext(context); @@ -223,6 +227,7 @@ public List searchUsers(final String username) throws NoLdapUserMatchi final String escapedUsername = LdapUtils.escapeLDAPSearchFilter(username); return _ldapUserManager.getUsers("*" + escapedUsername + "*", context); } catch (final NamingException e) { + s_logger.debug("ldap NamingException: ",e); throw new NoLdapUserMatchingQueryException(username); } finally { closeContext(context); diff --git a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapImportUsersCmdSpec.groovy b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapImportUsersCmdSpec.groovy index a66da1f3cf..79eba93d89 100644 --- a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapImportUsersCmdSpec.groovy +++ b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapImportUsersCmdSpec.groovy @@ -19,9 +19,14 @@ package groovy.org.apache.cloudstack.ldap import com.cloud.domain.Domain import com.cloud.domain.DomainVO import com.cloud.user.AccountService +import com.cloud.user.AccountVO import com.cloud.user.DomainService +import com.cloud.user.UserAccountVO +import com.cloud.user.UserVO +import org.apache.cloudstack.api.command.LdapCreateAccountCmd import org.apache.cloudstack.api.command.LdapImportUsersCmd import org.apache.cloudstack.api.response.LdapUserResponse +import org.apache.cloudstack.context.CallContext import org.apache.cloudstack.ldap.LdapManager import org.apache.cloudstack.ldap.LdapUser @@ -193,4 +198,59 @@ class LdapImportUsersCmdSpec extends spock.lang.Specification { } + + def "Test create ldap import account for an already existing cloudstack account"() { + given: "We have an LdapManager, DomainService, two users and a LdapImportUsersCmd" + def ldapManager = Mock(LdapManager) + List users = new ArrayList() + users.add(new LdapUser("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,ou=engineering,dc=cloudstack,dc=org", "engineering")) + ldapManager.getUsers() >> users + LdapUserResponse response1 = new LdapUserResponse("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,ou=engineering,dc=cloudstack,dc=org", "engineering") + ldapManager.createLdapUserResponse(_) >>> response1 + + def domainService = Mock(DomainService) + 1 * domainService.getDomain(1L) >> new DomainVO("DOMAIN", 1L, 1L, "DOMAIN", UUID.randomUUID().toString());; + + def accountService = Mock(AccountService) + 1 * accountService.getActiveAccountByName('ACCOUNT', 0) >> Mock(AccountVO) + 1 * accountService.createUser('rmurphy', _ , 'Ryan', 'Murphy', 'rmurphy@test.com', null, 'ACCOUNT', 0, _) >> Mock(UserVO) + 0 * accountService.createUserAccount('rmurphy', _, 'Ryan', 'Murphy', 'rmurphy@test.com', null, 'ACCOUNT', 2, 0, 'DOMAIN', null, _, _) + + def ldapImportUsersCmd = new LdapImportUsersCmd(ldapManager, domainService, accountService) + ldapImportUsersCmd.accountName = "ACCOUNT" + ldapImportUsersCmd.accountType = 2; + ldapImportUsersCmd.domainId = 1L; + + when: "create account is called" + ldapImportUsersCmd.execute() + then: "expect 1 call on accountService createUser and 0 on account service create user account" + } + + def "Test create ldap import account for a new cloudstack account"() { + given: "We have an LdapManager, DomainService, two users and a LdapImportUsersCmd" + def ldapManager = Mock(LdapManager) + List users = new ArrayList() + users.add(new LdapUser("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,ou=engineering,dc=cloudstack,dc=org", "engineering")) + ldapManager.getUsers() >> users + LdapUserResponse response1 = new LdapUserResponse("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,ou=engineering,dc=cloudstack,dc=org", "engineering") + ldapManager.createLdapUserResponse(_) >>> response1 + + def domainService = Mock(DomainService) + 1 * domainService.getDomain(1L) >> new DomainVO("DOMAIN", 1L, 1L, "DOMAIN", UUID.randomUUID().toString());; + + def accountService = Mock(AccountService) + 1 * accountService.getActiveAccountByName('ACCOUNT', 0) >> null + 0 * accountService.createUser('rmurphy', _ , 'Ryan', 'Murphy', 'rmurphy@test.com', null, 'ACCOUNT', 0, _) + 1 * accountService.createUserAccount('rmurphy', _, 'Ryan', 'Murphy', 'rmurphy@test.com', null, 'ACCOUNT', 2, 0, 'DOMAIN', null, _, _) + + def ldapImportUsersCmd = new LdapImportUsersCmd(ldapManager, domainService, accountService) + ldapImportUsersCmd.accountName = "ACCOUNT" + ldapImportUsersCmd.accountType = 2; + ldapImportUsersCmd.domainId = 1L; + + when: "create account is called" + ldapImportUsersCmd.execute() + then: "expect 1 call on accountService createUser and 0 on account service create user account" + } + } diff --git a/pom.xml b/pom.xml index 02b1808727..b9067575d3 100644 --- a/pom.xml +++ b/pom.xml @@ -58,7 +58,7 @@ 1.9.0 build213-svnkit-1.3-patch 2.6.6 - 1.7.1 + 1.7.2 14.0-rc1 6.2.0-1-SNAPSHOT 3.1 @@ -86,7 +86,7 @@ 0.10 build/replace.properties 0.5.1 - 0.1.3 + 0.1.4 target 1.0.10 4.0.0 @@ -746,6 +746,7 @@ plugins/hypervisors/hyperv/DotNet/ServerResource/**/packages.config plugins/hypervisors/hyperv/DotNet/ServerResource/**/App.config plugins/hypervisors/hyperv/DotNet/ServerResource/**/*.csproj + plugins/hypervisors/hyperv/DotNet/ServerResource/**/*.settings plugins/hypervisors/hyperv/conf/agent.properties scripts/vm/systemvm/id_rsa.cloud services/console-proxy/server/conf/agent.properties diff --git a/python/lib/cloudutils/serviceConfig.py b/python/lib/cloudutils/serviceConfig.py index d7c7e78c3a..3c23334292 100755 --- a/python/lib/cloudutils/serviceConfig.py +++ b/python/lib/cloudutils/serviceConfig.py @@ -763,9 +763,6 @@ def config(self): for port in self.ports: self.allowPort(port) - #FIXME: urgly make /root writable - bash("sudo chmod 0777 /root") - return True except: raise diff --git a/scripts/vm/hypervisor/xenserver/check_heartbeat.sh b/scripts/vm/hypervisor/xenserver/check_heartbeat.sh index 22befe9165..e1b18278dd 100755 --- a/scripts/vm/hypervisor/xenserver/check_heartbeat.sh +++ b/scripts/vm/hypervisor/xenserver/check_heartbeat.sh @@ -72,3 +72,4 @@ do done echo "=====> DEAD <======" +exit 1 diff --git a/scripts/vm/hypervisor/xenserver/cloudstack_pluginlib.py b/scripts/vm/hypervisor/xenserver/cloudstack_pluginlib.py index 4ebb435a82..44812b2e51 100644 --- a/scripts/vm/hypervisor/xenserver/cloudstack_pluginlib.py +++ b/scripts/vm/hypervisor/xenserver/cloudstack_pluginlib.py @@ -22,6 +22,7 @@ import os import subprocess import simplejson as json +import copy from time import localtime, asctime @@ -38,6 +39,23 @@ OFCTL_PATH = "/usr/bin/ovs-ofctl" XE_PATH = "/opt/xensource/bin/xe" +# OpenFlow tables set in a pipeline processing fashion for the bridge created for a VPC's that are enabled for +# distributed routing. +# L2 path (intra-tier traffic) CLASSIFIER-> L2 lookup -> L2 flooding tables +# L3 path (inter-tier traffic) CLASSIFIER-> EGRESS ACL -> L3 lookup -> INGRESS ACL-> L2 lookup -> L2 flooding tables + +# Classifier table has the rules to separate broadcast/multi-cast traffic, inter-tier traffic, intra-tier traffic +CLASSIFIER_TABLE=0 +# Lookup table to determine the output port (vif/tunnel port) based on the MAC address +L2_LOOKUP_TABLE=1 +# flooding table has the rules to flood on ports (both VIF, tunnel ports) except on the port on which packet arrived +L2_FLOOD_TABLE=2 +# table has flow rules derived from egress ACL's +EGRESS_ACL_TABLE=3 +# Lookup table to determine the output port (vif/tunnel port) based on the IP address +L3_LOOKUP_TABLE=4 +# table has flow rules derived from egress ACL's +INGRESS_ACL_TABLE=5 class PluginError(Exception): """Base Exception class for all plugin errors.""" @@ -178,9 +196,10 @@ def _build_flow_expr(**kwargs): nw_src = 'nw_src' in kwargs and ",nw_src=%s" % kwargs['nw_src'] or '' nw_dst = 'nw_dst' in kwargs and ",nw_dst=%s" % kwargs['nw_dst'] or '' table = 'table' in kwargs and ",table=%s" % kwargs['table'] or '' + cookie = 'cookie' in kwargs and ",cookie=%s" % kwargs['cookie'] or '' proto = 'proto' in kwargs and ",%s" % kwargs['proto'] or '' ip = ('nw_src' in kwargs or 'nw_dst' in kwargs) and ',ip' or '' - flow = (flow + in_port + dl_type + dl_src + dl_dst + + flow = (flow + cookie+ in_port + dl_type + dl_src + dl_dst + (ip or proto) + nw_src + nw_dst + table) return flow @@ -224,7 +243,9 @@ def del_port(bridge, port): def get_network_id_for_vif(vif_name): domain_id, device_id = vif_name[3:len(vif_name)].split(".") - dom_uuid = do_cmd([XE_PATH, "vm-list", "dom-id=%s" % domain_id, "--minimal"]) + hostname = do_cmd(["/bin/bash", "-c", "hostname"]) + this_host_uuid = do_cmd([XE_PATH, "host-list", "hostname=%s" % hostname, "--minimal"]) + dom_uuid = do_cmd([XE_PATH, "vm-list", "dom-id=%s" % domain_id, "resident-on=%s" %this_host_uuid, "--minimal"]) vif_uuid = do_cmd([XE_PATH, "vif-list", "vm-uuid=%s" % dom_uuid, "device=%s" % device_id, "--minimal"]) vnet = do_cmd([XE_PATH, "vif-param-get", "uuid=%s" % vif_uuid, "param-name=other-config", "param-key=cloudstack-network-id"]) @@ -235,11 +256,14 @@ def get_network_id_for_tunnel_port(tunnelif_name): return vnet def clear_flooding_rules_for_port(bridge, ofport): - del_flows(bridge, in_port=ofport, table=2) + del_flows(bridge, in_port=ofport, table=L2_FLOOD_TABLE) + +def clear_flooding_rules_for_all_ports(bridge): + del_flows(bridge, cookie=111, table=L2_FLOOD_TABLE) def add_flooding_rules_for_port(bridge, in_ofport, out_ofports): action = "".join("output:%s," %ofport for ofport in out_ofports)[:-1] - add_flow(bridge, priority=1100, in_port=in_ofport, table=2, actions=action) + add_flow(bridge, cookie=111, priority=1100, in_port=in_ofport, table=L2_FLOOD_TABLE, actions=action) def get_ofport_for_vif(vif_name): return do_cmd([VSCTL_PATH, "get", "interface", vif_name, "ofport"]) @@ -260,18 +284,18 @@ def get_vif_name_from_macaddress(macaddress): def add_mac_lookup_table_entry(bridge, mac_address, out_of_port): action = "output=%s" %out_of_port - add_flow(bridge, priority=1100, dl_dst=mac_address, table=1, actions=action) + add_flow(bridge, priority=1100, dl_dst=mac_address, table=L2_LOOKUP_TABLE, actions=action) def delete_mac_lookup_table_entry(bridge, mac_address): - del_flows(bridge, dl_dst=mac_address, table=1) + del_flows(bridge, dl_dst=mac_address, table=L2_LOOKUP_TABLE) def add_ip_lookup_table_entry(bridge, ip, dst_tier_gateway_mac, dst_vm_mac): - action_str = "mod_dl_src:%s" % dst_tier_gateway_mac + ",mod_dl_dst:%s" % dst_vm_mac + ",resubmit(,5)" - action_str = "table=4, ip, nw_dst=%s" % ip + ", actions=%s" %action_str + action_str = "mod_dl_src:%s" % dst_tier_gateway_mac + ",mod_dl_dst:%s" % dst_vm_mac + ",resubmit(,%s)"%INGRESS_ACL_TABLE + action_str = "table=%s"%L3_LOOKUP_TABLE + ", ip, nw_dst=%s" % ip + ", actions=%s" %action_str addflow = [OFCTL_PATH, "add-flow", bridge, action_str] do_cmd(addflow) -def get_vms_on_host(vpc, host_id): +def get_vpc_vms_on_host(vpc, host_id): all_vms = vpc.vms vms_on_host = [] for vm in all_vms: @@ -313,44 +337,184 @@ def __repr__(self): def __str__(self): return '{%s}' % str(', '.join('%s : %s' % (k, repr(v)) for (k, v) in self.__dict__.iteritems())) +def get_acl(vpcconfig, required_acl_id): + acls = vpcconfig.acls + for acl in acls: + if acl.id == required_acl_id: + return acl + return None -def configure_bridge_for_network_topology(bridge, this_host_id, json_config): - vpconfig = jsonLoader(json.loads(json_config)).vpc +def check_tunnel_exists(bridge, tunnel_name): + try: + res = do_cmd([VSCTL_PATH, "port-to-br", tunnel_name]) + return res == bridge + except: + return False + +def create_tunnel(bridge, remote_ip, gre_key, src_host, dst_host, network_uuid): + + logging.debug("Creating tunnel from host %s" %src_host + " to host %s" %dst_host + " with GRE key %s" %gre_key) + + res = check_switch() + if res != "SUCCESS": + logging.debug("Openvswitch running: NO") + return "FAILURE:%s" % res + + # We need to keep the name below 14 characters + # src and target are enough - consider a fixed length hash + name = "t%s-%s-%s" % (gre_key, src_host, dst_host) + + # Verify the xapi bridge to be created + # NOTE: Timeout should not be necessary anymore + wait = [VSCTL_PATH, "--timeout=30", "wait-until", "bridge", + bridge, "--", "get", "bridge", bridge, "name"] + res = do_cmd(wait) + if bridge not in res: + logging.debug("WARNING:Can't find bridge %s for creating " + + "tunnel!" % bridge) + return "FAILURE:NO_BRIDGE" + logging.debug("bridge %s for creating tunnel - VERIFIED" % bridge) + tunnel_setup = False + drop_flow_setup = False + try: + # Create a port and configure the tunnel interface for it + add_tunnel = [VSCTL_PATH, "add-port", bridge, + name, "--", "set", "interface", + name, "type=gre", "options:key=%s" % gre_key, + "options:remote_ip=%s" % remote_ip] + do_cmd(add_tunnel) + tunnel_setup = True + # verify port + verify_port = [VSCTL_PATH, "get", "port", name, "interfaces"] + res = do_cmd(verify_port) + # Expecting python-style list as output + iface_list = [] + if len(res) > 2: + iface_list = res.strip()[1:-1].split(',') + if len(iface_list) != 1: + logging.debug("WARNING: Unexpected output while verifying " + + "port %s on bridge %s" % (name, bridge)) + return "FAILURE:VERIFY_PORT_FAILED" + + # verify interface + iface_uuid = iface_list[0] + verify_interface_key = [VSCTL_PATH, "get", "interface", + iface_uuid, "options:key"] + verify_interface_ip = [VSCTL_PATH, "get", "interface", + iface_uuid, "options:remote_ip"] + + key_validation = do_cmd(verify_interface_key) + ip_validation = do_cmd(verify_interface_ip) + + if not gre_key in key_validation or not remote_ip in ip_validation: + logging.debug("WARNING: Unexpected output while verifying " + + "interface %s on bridge %s" % (name, bridge)) + return "FAILURE:VERIFY_INTERFACE_FAILED" + logging.debug("Tunnel interface validated:%s" % verify_interface_ip) + cmd_tun_ofport = [VSCTL_PATH, "get", "interface", + iface_uuid, "ofport"] + tun_ofport = do_cmd(cmd_tun_ofport) + # Ensure no trailing LF + if tun_ofport.endswith('\n'): + tun_ofport = tun_ofport[:-1] + # find xs network for this bridge, verify is used for ovs tunnel network + xs_nw_uuid = do_cmd([XE_PATH, "network-list", + "bridge=%s" % bridge, "--minimal"]) + + ovs_tunnel_network = is_regular_tunnel_network(xs_nw_uuid) + ovs_vpc_distributed_vr_network = is_vpc_network_with_distributed_routing(xs_nw_uuid) + + if ovs_tunnel_network == 'True': + # add flow entryies for dropping broadcast coming in from gre tunnel + add_flow(bridge, priority=1000, in_port=tun_ofport, + dl_dst='ff:ff:ff:ff:ff:ff', actions='drop') + add_flow(bridge, priority=1000, in_port=tun_ofport, + nw_dst='224.0.0.0/24', actions='drop') + drop_flow_setup = True + logging.debug("Broadcast drop rules added") + + if ovs_vpc_distributed_vr_network == 'True': + # add flow rules for dropping broadcast coming in from tunnel ports + add_flow(bridge, priority=1000, in_port=tun_ofport, table=0, + dl_dst='ff:ff:ff:ff:ff:ff', actions='drop') + add_flow(bridge, priority=1000, in_port=tun_ofport, table=0, + nw_dst='224.0.0.0/24', actions='drop') + + # add flow rule to send the traffic from tunnel ports to L2 switching table only + add_flow(bridge, priority=1100, in_port=tun_ofport, table=0, actions='resubmit(,1)') + + # mark tunnel interface with network id for which this tunnel was created + do_cmd([VSCTL_PATH, "set", "interface", name, "options:cloudstack-network-id=%s" % network_uuid]) + update_flooding_rules_on_port_plug_unplug(bridge, name, 'online', network_uuid) + + logging.debug("Successfully created tunnel from host %s" %src_host + " to host %s" %dst_host + + " with GRE key %s" %gre_key) + return "SUCCESS:%s" % name + except: + logging.debug("An unexpected error occured. Rolling back") + if tunnel_setup: + logging.debug("Deleting GRE interface") + # Destroy GRE port and interface + del_port(bridge, name) + if drop_flow_setup: + # Delete flows + logging.debug("Deleting flow entries from GRE interface") + del_flows(bridge, in_port=tun_ofport) + # This will not cancel the original exception + raise + +# Configures the bridge created for a VPC that is enabled for distributed routing. Management server sends VPC +# physical topology details (which VM from which tier running on which host etc). Based on the VPC physical topology L2 +# lookup table and L3 lookup tables are updated by this function. +def configure_vpc_bridge_for_network_topology(bridge, this_host_id, json_config, sequence_no): + vpconfig = jsonLoader(json.loads(json_config)).vpc if vpconfig is None: - logging.debug("WARNING:Can't find VPC info in json config file") + logging.debug("WARNING:Can't find VPC topology information in the json configuration file") return "FAILURE:IMPROPER_JSON_CONFG_FILE" try: - # get the list of Vm's in the VPC from the JSON config - this_host_vms = get_vms_on_host(vpconfig, this_host_id) + if not os.path.exists('/var/run/cloud'): + os.makedirs('/var/run/cloud') + + # create a temporary file to store OpenFlow rules corresponding to L2 and L3 lookup table updates + ofspec_filename = "/var/run/cloud/" + bridge + sequence_no + ".ofspec" + ofspec = open(ofspec_filename, 'w+') + + # get the list of VM's in all the tiers of VPC running in this host from the JSON config + this_host_vms = get_vpc_vms_on_host(vpconfig, this_host_id) for vm in this_host_vms: for nic in vm.nics: mac_addr = nic.macaddress ip = nic.ipaddress vif_name = get_vif_name_from_macaddress(mac_addr) - of_port = get_ofport_for_vif(vif_name) - network = get_network_details(vpconfig, nic.networkuuid) - - # Add flow rule in L2 look up table, if the destination mac = MAC of the nic send packet on the found OFPORT - add_mac_lookup_table_entry(bridge, mac_addr, of_port) - - # Add flow rule in L3 look up table: if the destination IP = VM's IP then modify the packet - # to set DST MAC = VM's MAC, SRC MAC=tier gateway MAC and send to egress table - add_ip_lookup_table_entry(bridge, ip, network.gatewaymac, mac_addr) - - # Add flow entry to send with intra tier traffic from the NIC to L2 lookup path) - action_str = "table=0, in_port=%s," %of_port + " ip, nw_dst=%s," %network.cidr + " actions=resubmit(,1)" - addflow = [OFCTL_PATH, "add-flow", bridge, action_str] - do_cmd(addflow) - - #add flow entry to send inter-tier traffic from the NIC to egress ACL table(to L3 lookup path) - action_str = "table=0, in_port=%s," % of_port + " ip, dl_dst=%s," %network.gatewaymac +\ - "nw_dst=%s," %vpconfig.cidr + "actions=resubmit(,3)" - addflow = [OFCTL_PATH, "add-flow", bridge, action_str] - - do_cmd(addflow) + of_port = get_ofport_for_vif(vif_name) + network = get_network_details(vpconfig, nic.networkuuid) + + # Add OF rule in L2 look up table, if packet's destination mac matches MAC of the VM's nic + # then send packet on the found OFPORT + ofspec.write("table=%s" %L2_LOOKUP_TABLE + " priority=1100 dl_dst=%s " %mac_addr + + " actions=output:%s" %of_port + "\n") + + # Add OF rule in L3 look up table: if packet's destination IP matches VM's IP then modify the packet + # to set DST MAC = VM's MAC, SRC MAC= destination tier gateway MAC and send to egress table. This step + # emulates steps VPC virtual router would have done on the current host itself. + action_str = " mod_dl_src:%s"%network.gatewaymac + ",mod_dl_dst:%s" % mac_addr \ + + ",resubmit(,%s)"%INGRESS_ACL_TABLE + action_str = "table=%s"%L3_LOOKUP_TABLE + " ip nw_dst=%s"%ip + " actions=%s" %action_str + ofspec.write(action_str + "\n") + + # Add OF rule to send intra-tier traffic from this nic of the VM to L2 lookup path (L2 switching) + action_str = "table=%s" %CLASSIFIER_TABLE + " priority=1200 in_port=%s " %of_port + \ + " ip nw_dst=%s " %network.cidr + " actions=resubmit(,%s)" %L2_LOOKUP_TABLE + ofspec.write(action_str + "\n") + + # Add OF rule to send inter-tier traffic from this nic of the VM to egress ACL table(L3 lookup path) + action_str = "table=%s "%CLASSIFIER_TABLE + " priority=1100 in_port=%s " %of_port +\ + " ip dl_dst=%s " %network.gatewaymac + " nw_dst=%s " %vpconfig.cidr + \ + " actions=resubmit(,%s)" %EGRESS_ACL_TABLE + ofspec.write(action_str + "\n") # get the list of hosts on which VPC spans from the JSON config vpc_spanning_hosts = vpconfig.hosts @@ -358,7 +522,9 @@ def configure_bridge_for_network_topology(bridge, this_host_id, json_config): for host in vpc_spanning_hosts: if str(this_host_id) == str(host.hostid): continue - other_host_vms = get_vms_on_host(vpconfig, host.hostid) + + other_host_vms = get_vpc_vms_on_host(vpconfig, str(host.hostid)) + for vm in other_host_vms: for nic in vm.nics: mac_addr = nic.macaddress @@ -366,42 +532,78 @@ def configure_bridge_for_network_topology(bridge, this_host_id, json_config): network = get_network_details(vpconfig, nic.networkuuid) gre_key = network.grekey - # generate tunnel name from tunnel naming convention + # generate tunnel name as per the tunnel naming convention tunnel_name = "t%s-%s-%s" % (gre_key, this_host_id, host.hostid) + + # check if tunnel exists already, if not create a tunnel from this host to remote host + if not check_tunnel_exists(bridge, tunnel_name): + create_tunnel(bridge, str(host.ipaddress), str(gre_key), this_host_id, + host.hostid, network.networkuuid) + of_port = get_ofport_for_vif(tunnel_name) - # Add flow rule in L2 look up table, if the destination mac = MAC of the nic send packet tunnel port - add_mac_lookup_table_entry(bridge, mac_addr, of_port) + # Add flow rule in L2 look up table, if packet's destination mac matches MAC of the VM's nic + # on the remote host then send packet on the found OFPORT corresponding to the tunnel + ofspec.write("table=%s" %L2_LOOKUP_TABLE + " priority=1100 dl_dst=%s " %mac_addr + + " actions=output:%s" %of_port + "\n") - # Add flow tule in L3 look up table: if the destination IP = VM's IP then modify the packet - # set DST MAC = VM's MAC, SRC MAC=tier gateway MAC and send to egress table - add_ip_lookup_table_entry(bridge, ip, network.gatewaymac, mac_addr) + # Add flow rule in L3 look up table. if packet's destination IP matches VM's IP then modify the + # packet to set DST MAC = VM's MAC, SRC MAC=tier gateway MAC and send to ingress table. This step + # emulates steps VPC virtual router would have done on the current host itself. + action_str = "mod_dl_src:%s"%network.gatewaymac + ",mod_dl_dst:%s" % mac_addr + \ + ",resubmit(,%s)"%INGRESS_ACL_TABLE + action_str = "table=%s"%L3_LOOKUP_TABLE + " ip nw_dst=%s"%ip + " actions=%s" %action_str + ofspec.write(action_str + "\n") - return "SUCCESS: successfully configured bridge as per the VPC topology" - except: - logging.debug("An unexpected error occurred while configuring bridge as per VPC topology.") - raise + # add a default rule in L2_LOOKUP_TABLE to send unknown mac address to L2 flooding table + ofspec.write("table=%s "%L2_LOOKUP_TABLE + " priority=0 " + " actions=resubmit(,%s)"%L2_FLOOD_TABLE + "\n") -def get_acl(vpcconfig, required_acl_id): - acls = vpcconfig.acls - for acl in acls: - if acl.id == required_acl_id: - return acl - return None + # add a default rule in L3 lookup table to forward (unknown destination IP) packets to L2 lookup table. This + # is fallback option to send the packet to VPC VR, when routing can not be performed at the host + ofspec.write("table=%s "%L3_LOOKUP_TABLE + " priority=0 " + " actions=resubmit(,%s)"%L2_LOOKUP_TABLE + "\n") -def configure_ovs_bridge_for_routing_policies(bridge, json_config): - vpconfig = jsonLoader(json.loads(json_config)).vpc + # First flush current L2_LOOKUP_TABLE & L3_LOOKUP_TABLE before re-applying L2 & L3 lookup entries + del_flows(bridge, table=L2_LOOKUP_TABLE) + del_flows(bridge, table=L3_LOOKUP_TABLE) + + ofspec.seek(0) + logging.debug("Adding below flows rules in L2 & L3 lookup tables:\n" + ofspec.read()) + ofspec.close() + + # update bridge with the flow-rules for L2 lookup and L3 lookup in the file in one attempt + do_cmd([OFCTL_PATH, 'add-flows', bridge, ofspec_filename]) + + # now that we updated the bridge with flow rules close and delete the file. + os.remove(ofspec_filename) + + return "SUCCESS: successfully configured bridge as per the VPC topology update with sequence no: %s"%sequence_no + + except Exception,e: + error_message = "An unexpected error occurred while configuring bridge " + bridge + \ + " as per latest VPC topology update with sequence no: %s" %sequence_no + logging.debug(error_message + " due to " + str(e)) + if os.path.isfile(ofspec_filename): + os.remove(ofspec_filename) + raise error_message +# Configures the bridge created for a VPC that is enabled for distributed firewall. Management server sends VPC routing +# policy (network ACL applied on the tiers etc) details. Based on the VPC routing policies ingress ACL table and +# egress ACL tables are updated by this function. +def configure_vpc_bridge_for_routing_policies(bridge, json_config, sequence_no): + + vpconfig = jsonLoader(json.loads(json_config)).vpc if vpconfig is None: - logging.debug("WARNING:Can't find VPC info in json config file") + logging.debug("WARNING: Can't find VPC routing policies info in json config file") return "FAILURE:IMPROPER_JSON_CONFG_FILE" try: - # First flush current egress ACL's before re-applying the ACL's - del_flows(bridge, table=3) - egress_rules_added = False - ingress_rules_added = False + if not os.path.exists('/var/run/cloud'): + os.makedirs('/var/run/cloud') + + # create a temporary file to store OpenFlow rules corresponding to ingress and egress ACL table updates + ofspec_filename = "/var/run/cloud/" + bridge + sequence_no + ".ofspec" + ofspec = open(ofspec_filename, 'w+') tiers = vpconfig.tiers for tier in tiers: @@ -416,64 +618,273 @@ def configure_ovs_bridge_for_routing_policies(bridge, json_config): source_port_start = acl_item.sourceportstart source_port_end = acl_item.sourceportend protocol = acl_item.protocol + if protocol == "all": + protocol = "*" + elif protocol == "tcp": + protocol = "6" + elif protocol == "udp": + protocol == "17" + elif protocol == "icmp": + protocol == "1" source_cidrs = acl_item.sourcecidrs acl_priority = 1000 + number + if direction == "ingress": + matching_table = INGRESS_ACL_TABLE + resubmit_table = L2_LOOKUP_TABLE + elif direction == "egress": + matching_table = EGRESS_ACL_TABLE + resubmit_table = L3_LOOKUP_TABLE + for source_cidr in source_cidrs: - if direction is "ingress": - ingress_rules_added = True - - if source_port_start is None and source_port_end is None: - if action is "deny": - add_flow(bridge, priority= acl_priority, table=5, nw_src=source_cidr, nw_dst=tier_cidr, - nw_proto=protocol, actions='drop') - if action is "allow": - add_flow(bridge, priority= acl_priority,table=5, nw_src=source_cidr, nw_dst=tier_cidr, - nw_proto=protocol, actions='resubmit(,1)') - continue - - # add flow rule to do action (allow/deny) for flows where source IP of the packet is in - # source_cidr and destination ip is in tier_cidr - port = source_port_start - while (port < source_port_end): - if action is "deny": - add_flow(bridge, priority= acl_priority, table=5, nw_src=source_cidr, nw_dst=tier_cidr, tp_dst=port, - nw_proto=protocol, actions='drop') - if action is "allow": - add_flow(bridge, priority= acl_priority,table=5, nw_src=source_cidr, nw_dst=tier_cidr, tp_dst=port, - nw_proto=protocol, actions='resubmit(,1)') - port = port + 1 - - elif direction in "egress": - egress_rules_added = True - - if source_port_start is None and source_port_end is None: - if action is "deny": - add_flow(bridge, priority= acl_priority, table=3, nw_src=source_cidr, nw_dst=tier_cidr, - nw_proto=protocol, actions='drop') - if action is "allow": - add_flow(bridge, priority= acl_priority,table=3, nw_src=source_cidr, nw_dst=tier_cidr, - nw_proto=protocol, actions='resubmit(,1)') - continue - - # add flow rule to do action (allow/deny) for flows where destination IP of the packet is in - # source_cidr and source ip is in tier_cidr - port = source_port_start - while (port < source_port_end): - if action is "deny": - add_flow(bridge, priority= acl_priority, table=3, nw_src=tier_cidr, nw_dst=source_cidr, tp_dst=port, - nw_proto=protocol, actions='drop') - if action is "allow": - add_flow(bridge, priority= acl_priority, table=3, nw_src=tier_cidr, nw_dst=source_cidr, tp_dst=port, - nw_proto=protocol, actions='resubmit(,1)') - port = port + 1 - - if egress_rules_added is False: - # add a default rule in egress table to forward packet to L3 lookup table - add_flow(bridge, priority=0, table=3, actions='resubmit(,4)') - - if ingress_rules_added is False: - # add a default rule in egress table drop packets - add_flow(bridge, priority=0, table=5, actions='drop') - except: - logging.debug("An unexpected error occurred while configuring bridge as per VPC's routing policies.") - raise \ No newline at end of file + if source_port_start is None and source_port_end is None: + if source_cidr.startswith('0.0.0.0'): + if action == "deny": + if direction == "ingress": + ofspec.write("table=%s "%matching_table + " priority=%s " %acl_priority + " ip " + + " nw_dst=%s " %tier_cidr + " nw_proto=%s " %protocol + + " actions=drop" + "\n") + else: + ofspec.write("table=%s "%matching_table + " priority=%s " %acl_priority + " ip " + + " nw_src=%s " %tier_cidr + " nw_proto=%s " %protocol + + " actions=drop" + "\n") + if action == "allow": + if direction == "ingress": + ofspec.write("table=%s "%matching_table + " priority=%s " %acl_priority + " ip " + + " nw_dst=%s " %tier_cidr + " nw_proto=%s " %protocol + + " actions=resubmit(,%s)"%resubmit_table + "\n") + else: + ofspec.write("table=%s "%matching_table + " priority=%s " %acl_priority + " ip " + + " nw_src=%s " %tier_cidr + " nw_proto=%s " %protocol + + " actions=resubmit(,%s)"%resubmit_table + "\n") + else: + if action == "deny": + if direction == "ingress": + ofspec.write("table=%s "%matching_table + " priority=%s " %acl_priority + " ip " + + " nw_src=%s " %source_cidr + " nw_dst=%s " %tier_cidr + + " nw_proto=%s " %protocol + " actions=drop" + "\n") + else: + ofspec.write("table=%s "%matching_table + " priority=%s " %acl_priority + " ip " + + " nw_src=%s " %tier_cidr + " nw_dst=%s " %source_cidr + + " nw_proto=%s " %protocol + " actions=drop" + "\n") + if action == "allow": + if direction == "ingress": + ofspec.write("table=%s "%matching_table + " priority=%s " %acl_priority + " ip " + + " nw_src=%s "%source_cidr + " nw_dst=%s " %tier_cidr + + " nw_proto=%s " %protocol + + " actions=resubmit(,%s)"%resubmit_table + "\n") + else: + ofspec.write("table=%s "%matching_table + " priority=%s " %acl_priority + " ip " + + " nw_src=%s "%tier_cidr + " nw_dst=%s " %source_cidr + + " nw_proto=%s " %protocol + + " actions=resubmit(,%s)"%resubmit_table + "\n") + continue + + # add flow rule to do action (allow/deny) for flows where source IP of the packet is in + # source_cidr and destination ip is in tier_cidr + port = int(source_port_start) + while (port <= int(source_port_end)): + if source_cidr.startswith('0.0.0.0'): + if action == "deny": + if direction == "ingress": + ofspec.write("table=%s "%matching_table + " priority=%s " %acl_priority + " ip " + + " tp_dst=%s " %port + " nw_dst=%s " %tier_cidr + + " nw_proto=%s " %protocol + " actions=drop" + "\n") + else: + ofspec.write("table=%s "%matching_table + " priority=%s " %acl_priority + " ip " + + " tp_dst=%s " %port + " nw_src=%s " %tier_cidr + + " nw_proto=%s " %protocol + " actions=drop" + "\n") + if action == "allow": + if direction == "ingress": + ofspec.write("table=%s "%matching_table + " priority=%s " %acl_priority + " ip " + + " tp_dst=%s " %port + " nw_dst=%s " %tier_cidr + + " nw_proto=%s " %protocol + + " actions=resubmit(,%s)"%resubmit_table + "\n") + else: + ofspec.write("table=%s "%matching_table + " priority=%s " %acl_priority + " ip " + + " tp_dst=%s " %port + " nw_src=%s " %tier_cidr + + " nw_proto=%s " %protocol + + " actions=resubmit(,%s)"%resubmit_table + "\n") + else: + if action == "deny": + if direction == "ingress": + ofspec.write("table=%s "%matching_table + " priority=%s " %acl_priority + " ip " + + " tp_dst=%s " %port + " nw_src=%s " %source_cidr + + " nw_dst=%s " %tier_cidr + + " nw_proto=%s " %protocol + " actions=drop" + "\n") + else: + ofspec.write("table=%s "%matching_table + " priority=%s " %acl_priority + " ip " + + " tp_dst=%s " %port + " nw_src=%s " %tier_cidr + + " nw_dst=%s " %source_cidr + + " nw_proto=%s " %protocol + " actions=drop" + "\n") + if action == "allow": + if direction == "ingress": + ofspec.write("table=%s "%matching_table + " priority=%s " %acl_priority + " ip " + + " tp_dst=%s " %port + " nw_src=%s "%source_cidr + + " nw_dst=%s " %tier_cidr + + " nw_proto=%s " %protocol + + " actions=resubmit(,%s)"%resubmit_table + "\n") + else: + ofspec.write("table=%s "%matching_table + " priority=%s " %acl_priority + " ip " + + " tp_dst=%s " %port + " nw_src=%s "%tier_cidr + + " nw_dst=%s " %source_cidr + + " nw_proto=%s " %protocol + + " actions=resubmit(,%s)"%resubmit_table + "\n") + port = port + 1 + + # add a default rule in egress table to allow packets (so forward packet to L3 lookup table) + ofspec.write("table=%s " %EGRESS_ACL_TABLE + " priority=0 actions=resubmit(,%s)" %L3_LOOKUP_TABLE + "\n") + + # add a default rule in ingress table to drop packets + ofspec.write("table=%s " %INGRESS_ACL_TABLE + " priority=0 actions=drop" + "\n") + + # First flush current ingress and egress ACL's before re-applying the ACL's + del_flows(bridge, table=EGRESS_ACL_TABLE) + del_flows(bridge, table=INGRESS_ACL_TABLE) + + ofspec.seek(0) + logging.debug("Adding below flows rules Ingress & Egress ACL tables:\n" + ofspec.read()) + ofspec.close() + + # update bridge with the flow-rules for ingress and egress ACL's added in the file in one attempt + do_cmd([OFCTL_PATH, 'add-flows', bridge, ofspec_filename]) + + # now that we updated the bridge with flow rules delete the file. + os.remove(ofspec_filename) + + return "SUCCESS: successfully configured bridge as per the latest routing policies update with " \ + "sequence no: %s"%sequence_no + + except Exception,e: + error_message = "An unexpected error occurred while configuring bridge " + bridge + \ + " as per latest VPC's routing policy update with sequence number %s." %sequence_no + logging.debug(error_message + " due to " + str(e)) + if os.path.isfile(ofspec_filename): + os.remove(ofspec_filename) + raise error_message + +# configures bridge L2 flooding rules stored in table=2. Single bridge is used for all the tiers of VPC. So controlled +# flooding is required to restrict the broadcast to only to the ports (vifs and tunnel interfaces) in the tier. Also +# packets arrived from the tunnel ports should not be flooded on the other tunnel ports. +def update_flooding_rules_on_port_plug_unplug(bridge, interface, command, if_network_id): + + class tier_ports: + tier_vif_ofports = [] + tier_tunnelif_ofports = [] + tier_all_ofports = [] + + logging.debug("Updating the flooding rules on bridge " + bridge + " as interface %s" %interface + + " is %s"%command + " now.") + try: + + if not os.path.exists('/var/run/cloud'): + os.makedirs('/var/run/cloud') + + # create a temporary file to store OpenFlow rules corresponding L2 flooding table + ofspec_filename = "/var/run/cloud/" + bridge + "-" +interface + "-" + command + ".ofspec" + ofspec = open(ofspec_filename, 'w+') + + all_tiers = dict() + + vsctl_output = do_cmd([VSCTL_PATH, 'list-ports', bridge]) + ports = vsctl_output.split('\n') + + for port in ports: + + if_ofport = do_cmd([VSCTL_PATH, 'get', 'Interface', port, 'ofport']) + + if port.startswith('vif'): + network_id = get_network_id_for_vif(port) + if network_id not in all_tiers.keys(): + all_tiers[network_id] = tier_ports() + tier_ports_info = all_tiers[network_id] + tier_ports_info.tier_vif_ofports.append(if_ofport) + tier_ports_info.tier_all_ofports.append(if_ofport) + all_tiers[network_id] = tier_ports_info + + if port.startswith('t'): + network_id = get_network_id_for_tunnel_port(port)[1:-1] + if network_id not in all_tiers.keys(): + all_tiers[network_id] = tier_ports() + tier_ports_info = all_tiers[network_id] + tier_ports_info.tier_tunnelif_ofports.append(if_ofport) + tier_ports_info.tier_all_ofports.append(if_ofport) + all_tiers[network_id] = tier_ports_info + + for network_id, tier_ports_info in all_tiers.items(): + if len(tier_ports_info.tier_all_ofports) == 1 : + continue + + # for a packet arrived from tunnel port, flood only on to VIF ports connected to bridge for this tier + for port in tier_ports_info.tier_tunnelif_ofports: + action = "".join("output:%s," %ofport for ofport in tier_ports_info.tier_vif_ofports)[:-1] + ofspec.write("table=%s " %L2_FLOOD_TABLE + " priority=1100 in_port=%s " %port + + "actions=%s " %action + "\n") + + # for a packet arrived from VIF port send on all VIF and tunnel ports corresponding to the tier excluding + # the port on which packet arrived + for port in tier_ports_info.tier_vif_ofports: + tier_all_ofports_copy = copy.copy(tier_ports_info.tier_all_ofports) + tier_all_ofports_copy.remove(port) + action = "".join("output:%s," %ofport for ofport in tier_all_ofports_copy)[:-1] + ofspec.write("table=%s " %L2_FLOOD_TABLE + " priority=1100 in_port=%s " %port + + "actions=%s " %action + "\n") + + # add a default rule in L2 flood table to drop packet + ofspec.write("table=%s " %L2_FLOOD_TABLE + " priority=0 actions=drop") + + # First flush current L2 flooding table before re-populating the tables + del_flows(bridge, table=L2_FLOOD_TABLE) + + ofspec.seek(0) + logging.debug("Adding below flows rules L2 flooding table: \n" + ofspec.read()) + ofspec.close() + + # update bridge with the flow-rules for broadcast rules added in the file in one attempt + do_cmd([OFCTL_PATH, 'add-flows', bridge, ofspec_filename]) + + # now that we updated the bridge with flow rules delete the file. + os.remove(ofspec_filename) + + logging.debug("successfully configured bridge %s as per the latest flooding rules " %bridge) + + except Exception,e: + if os.path.isfile(ofspec_filename): + os.remove(ofspec_filename) + error_message = "An unexpected error occurred while updating the flooding rules for the bridge " + \ + bridge + " when interface " + " %s" %interface + " is %s" %command + logging.debug(error_message + " due to " + str(e)) + raise error_message + + +def is_regular_tunnel_network(xs_nw_uuid): + cmd = [XE_PATH,"network-param-get", "uuid=%s" % xs_nw_uuid, "param-name=other-config", + "param-key=is-ovs-tun-network", "--minimal"] + logging.debug("Executing:%s", cmd) + pipe = subprocess.PIPE + proc = subprocess.Popen(cmd, shell=False, stdin=pipe, stdout=pipe, + stderr=pipe, close_fds=True) + ret_code = proc.wait() + if ret_code: + return False + + output = proc.stdout.read() + if output.endswith('\n'): + output = output[:-1] + return output + + +def is_vpc_network_with_distributed_routing(xs_nw_uuid): + cmd = [XE_PATH,"network-param-get", "uuid=%s" % xs_nw_uuid, "param-name=other-config", + "param-key=is-ovs-vpc-distributed-vr-network", "--minimal"] + logging.debug("Executing:%s", cmd) + pipe = subprocess.PIPE + proc = subprocess.Popen(cmd, shell=False, stdin=pipe, stdout=pipe, + stderr=pipe, close_fds=True) + ret_code = proc.wait() + if ret_code: + return False + + output = proc.stdout.read() + if output.endswith('\n'): + output = output[:-1] + return output \ No newline at end of file diff --git a/scripts/vm/hypervisor/xenserver/hostvmstats.py b/scripts/vm/hypervisor/xenserver/hostvmstats.py deleted file mode 100644 index 61cf2de99f..0000000000 --- a/scripts/vm/hypervisor/xenserver/hostvmstats.py +++ /dev/null @@ -1,61 +0,0 @@ -#!/usr/bin/python -# 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. -# $Id: hostvmstats.py 10054 2010-06-29 22:09:31Z abhishek $ $HeadURL: svn://svn.lab.vmops.com/repos/vmdev/java/scripts/vm/hypervisor/xenserver/hostvmstats.py $ - -import XenAPI -import urllib -import time -import logging -import logging.handlers - -LOG_FILENAME = '/tmp/xapilog' -logging.basicConfig(filename=LOG_FILENAME,level=logging.DEBUG) -stats_logger = logging.getLogger('statsLogger') -stats_logger.setLevel(logging.DEBUG) - -#handler with maxBytes=10MiB -handler = logging.handlers.RotatingFileHandler(LOG_FILENAME, maxBytes=10*1024*1024, backupCount=5) -stats_logger.addHandler(handler) - -def get_stats(session, collect_host_stats, consolidation_function, interval, start_time): - try: - - if collect_host_stats == "true" : - url = "http://localhost/rrd_updates?" - url += "session_id=" + session._session - url += "&host=" + collect_host_stats - url += "&cf=" + consolidation_function - url += "&interval=" + str(interval) - url += "&start=" + str(int(time.time())-100) - else : - url = "http://localhost/rrd_updates?" - url += "session_id=" + session._session - url += "&host=" + collect_host_stats - url += "&cf=" + consolidation_function - url += "&interval=" + str(interval) - url += "&start=" + str(int(time.time())-100) - - stats_logger.debug("Calling URL: %s",url) - sock = urllib.URLopener().open(url) - xml = sock.read() - sock.close() - stats_logger.debug("Size of returned XML: %s",len(xml)) - return xml - except Exception,e: - stats_logger.exception("get_stats() failed") - raise diff --git a/scripts/vm/hypervisor/xenserver/ovs-vif-flows.py b/scripts/vm/hypervisor/xenserver/ovs-vif-flows.py index 1445d940ef..62601bf187 100644 --- a/scripts/vm/hypervisor/xenserver/ovs-vif-flows.py +++ b/scripts/vm/hypervisor/xenserver/ovs-vif-flows.py @@ -15,8 +15,8 @@ # specific language governing permissions and limitations # under the License. -# A simple script for enabling and disabling per-vif rules for explicitly -# allowing broadcast/multicast traffic on the port where the VIF is attached +# A simple script for enabling and disabling per-vif and tunnel interface rules for explicitly +# allowing broadcast/multicast traffic from the tunnel ports and on the port where the VIF is attached import copy import os @@ -28,9 +28,11 @@ pluginlib.setup_logging("/var/log/cloud/ovstunnel.log") def clear_flows(bridge, this_vif_ofport, vif_ofports): + action = "".join("output:%s," %ofport + for ofport in vif_ofports)[:-1] # Remove flow entries originating from given ofport pluginlib.del_flows(bridge, in_port=this_vif_ofport) - # The following will remove the port being delete from actions + # The following will remove the port being delete from actions pluginlib.add_flow(bridge, priority=1100, dl_dst='ff:ff:ff:ff:ff:ff', actions=action) pluginlib.add_flow(bridge, priority=1100, @@ -40,7 +42,7 @@ def clear_flows(bridge, this_vif_ofport, vif_ofports): def apply_flows(bridge, this_vif_ofport, vif_ofports): action = "".join("output:%s," %ofport for ofport in vif_ofports)[:-1] - # Ensure {b|m}casts sent from VIF ports are always allowed + # Ensure {b|m}casts sent from VIF ports are always allowed pluginlib.add_flow(bridge, priority=1200, in_port=this_vif_ofport, dl_dst='ff:ff:ff:ff:ff:ff', @@ -49,7 +51,7 @@ def apply_flows(bridge, this_vif_ofport, vif_ofports): in_port=this_vif_ofport, nw_dst='224.0.0.0/24', actions='NORMAL') - # Ensure {b|m}casts are always propagated to VIF ports + # Ensure {b|m}casts are always propagated to VIF ports pluginlib.add_flow(bridge, priority=1100, dl_dst='ff:ff:ff:ff:ff:ff', actions=action) pluginlib.add_flow(bridge, priority=1100, @@ -88,24 +90,10 @@ def main(command, vif_raw): # find xs network for this bridge, verify is used for ovs tunnel network xs_nw_uuid = pluginlib.do_cmd([pluginlib.XE_PATH, "network-list", "bridge=%s" % bridge, "--minimal"]) - ovs_tunnel_network = False - try: - ovs_tunnel_network = pluginlib.do_cmd([pluginlib.XE_PATH,"network-param-get", - "uuid=%s" % xs_nw_uuid, - "param-name=other-config", - "param-key=is-ovs-tun-network", "--minimal"]) - except: - pass - ovs_vpc_distributed_vr_network = False - try: - ovs_vpc_distributed_vr_network = pluginlib.do_cmd([pluginlib.XE_PATH,"network-param-get", - "uuid=%s" % xs_nw_uuid, - "param-name=other-config", - "param-key=is-ovs_vpc_distributed_vr_network", "--minimal"]) - except: - pass + ovs_tunnel_network = pluginlib.is_regular_tunnel_network(xs_nw_uuid) + # handle case where network is reguar tunnel network if ovs_tunnel_network == 'True': vlan = pluginlib.do_cmd([pluginlib.VSCTL_PATH, 'br-to-vlan', bridge]) if vlan != '0': @@ -116,6 +104,7 @@ def main(command, vif_raw): 'list-ports', bridge]) vifs = vsctl_output.split('\n') vif_ofports = [] + vif_other_ofports = [] for vif in vifs: vif_ofport = pluginlib.do_cmd([pluginlib.VSCTL_PATH, 'get', 'Interface', vif, 'ofport']) @@ -125,82 +114,24 @@ def main(command, vif_raw): vif_ofports.append(vif_ofport) if command == 'offline': - clear_flows(bridge, this_vif_ofport, vif_ofports) + vif_other_ofports = copy.copy(vif_ofports) + vif_other_ofports.remove(this_vif_ofport) + clear_flows(bridge, this_vif_ofport, vif_other_ofports) if command == 'online': apply_flows(bridge, this_vif_ofport, vif_ofports) - # handle case where brdige is setup for VPC and VPC is enabled for distributed routing + # handle case where bridge is setup for VPC which is enabled for distributed routing + ovs_vpc_distributed_vr_network = pluginlib.is_vpc_network_with_distributed_routing(xs_nw_uuid) if ovs_vpc_distributed_vr_network == 'True': vlan = pluginlib.do_cmd([pluginlib.VSCTL_PATH, 'br-to-vlan', bridge]) if vlan != '0': # We need the REAL bridge name bridge = pluginlib.do_cmd([pluginlib.VSCTL_PATH, 'br-to-parent', bridge]) - vsctl_output = pluginlib.do_cmd([pluginlib.VSCTL_PATH, - 'list-ports', bridge]) vif_network_id = pluginlib.get_network_id_for_vif(this_vif) - vnet_vif_ofports = [] - vnet_tunnelif_ofports = [] - vnet_all_ofports = [] - - ports = vsctl_output.split('\n') - for port in ports: - if_ofport = pluginlib.do_cmd([pluginlib.VSCTL_PATH, 'get', 'Interface', port, 'ofport']) - if port.startswith('vif'): - # check VIF is in same network as that of plugged vif - if vif_network_id != pluginlib.get_network_id_for_vif(port): - continue - vnet_vif_ofports.append(if_ofport) - vnet_all_ofports.append(if_ofport) - - if port.startswith('t'): - # check tunnel port is in same network as that of plugged vif - if vif_network_id != pluginlib.get_network_id_for_tunnel_port(port): - continue - vnet_tunnelif_ofports.append(if_ofport) - vnet_all_ofports.append(if_ofport) - - if command == 'online': - for port in vnet_all_ofports: - pluginlib.clear_flooding_rules_for_port(bridge, port) - - # for a packet arrived from tunnel port, flood only on VIF ports - for port in vnet_tunnelif_ofports: - pluginlib.add_flooding_rules_for_port(bridge, port, vnet_vif_ofports) - - # for a packet arrived from VIF port send on all VIF and tunnel port excluding the port - # on which packet arrived - for port in vnet_vif_ofports: - vnet_all_ofports_copy = copy.copy(vnet_all_ofports) - vnet_all_ofports_copy.remove(port) - pluginlib.add_flooding_rules_for_port(bridge, port, vnet_all_ofports_copy) - - #learn that MAC is reachable through the VIF port - mac = pluginlib.get_macaddress_of_vif(this_vif) - this_vif_ofport = pluginlib.do_cmd([pluginlib.VSCTL_PATH, 'get', 'Interface', this_vif, 'ofport']) - pluginlib.add_mac_lookup_table_entry(bridge, mac, this_vif_ofport) - - if command == 'offline': - for port in vnet_all_ofports: - pluginlib.clear_flooding_rules_for_port(bridge, port) - vnet_all_ofports.remove(this_vif_ofport) - vnet_vif_ofports.remove(this_vif_ofport) - - # for a packet arrived from tunnel port, flood only on VIF ports - for port in vnet_tunnelif_ofports: - pluginlib.add_flooding_rules_for_port(bridge, port, vnet_vif_ofports) - - # for a packet from VIF port send on all VIF's and tunnel ports excluding the port on which packet arrived - for port in vnet_vif_ofports: - vnet_all_ofports_copy = copy.copy(vnet_all_ofports) - vnet_all_ofports_copy.remove(port) - pluginlib.add_flooding_rules_for_port(bridge, port, vnet_all_ofports_copy) - - #un-learn that MAC is reachable through the VIF port - mac = pluginlib.get_macaddress_of_vif(this_vif) - pluginlib.delete_mac_lookup_table_entry(bridge, mac) + pluginlib.update_flooding_rules_on_port_plug_unplug(bridge, this_vif, command, vif_network_id) return diff --git a/scripts/vm/hypervisor/xenserver/ovstunnel b/scripts/vm/hypervisor/xenserver/ovstunnel index 98a9d0b82f..0ae99f595b 100755 --- a/scripts/vm/hypervisor/xenserver/ovstunnel +++ b/scripts/vm/hypervisor/xenserver/ovstunnel @@ -37,7 +37,6 @@ from time import localtime as _localtime, asctime as _asctime xePath = "/opt/xensource/bin/xe" lib.setup_logging("/var/log/cloud/ovstunnel.log") - def block_ipv6_v5(bridge): lib.add_flow(bridge, priority=65000, dl_type='0x86dd', actions='drop') @@ -97,16 +96,16 @@ def setup_ovs_bridge(session, args): result = "SUCCESS:%s" % bridge else: result = "FAILURE:%s" % res + lib.do_cmd([lib.XE_PATH, "network-param-set", "uuid=%s" % xs_nw_uuid, + "other-config:is-ovs-tun-network=True"]) # Finally note in the xenapi network object that the network has # been configured xs_nw_uuid = lib.do_cmd([lib.XE_PATH, "network-list", "bridge=%s" % bridge, "--minimal"]) - lib.do_cmd([lib.XE_PATH, "network-param-set", "uuid=%s" % xs_nw_uuid, - "other-config:is-ovs-tun-network=True"]) conf_hosts = lib.do_cmd([lib.XE_PATH, "network-param-get", "uuid=%s" % xs_nw_uuid, "param-name=other-config", - "param-key=ovs-host-setup", "--minimal"]) + "param-key=ovs-host-setup"]) conf_hosts = cs_host_id + (conf_hosts and ',%s' % conf_hosts or '') lib.do_cmd([lib.XE_PATH, "network-param-set", "uuid=%s" % xs_nw_uuid, "other-config:ovs-host-setup=%s" % conf_hosts]) @@ -124,6 +123,7 @@ def setup_ovs_bridge(session, args): logging.debug("Setup_ovs_bridge completed with result:%s" % result) return result + @echo def setup_ovs_bridge_for_distributed_routing(session, args): bridge = args.pop("bridge") @@ -156,36 +156,45 @@ def setup_ovs_bridge_for_distributed_routing(session, args): xs_nw_uuid = lib.do_cmd([lib.XE_PATH, "network-list", "bridge=%s" % bridge, "--minimal"]) lib.do_cmd([lib.XE_PATH, "network-param-set", "uuid=%s" % xs_nw_uuid, - "other-config:is-ovs_vpc_distributed_vr_network=True"]) + "other-config:is-ovs-vpc-distributed-vr-network=True"]) conf_hosts = lib.do_cmd([lib.XE_PATH, "network-param-get", "uuid=%s" % xs_nw_uuid, "param-name=other-config", - "param-key=ovs-host-setup", "--minimal"]) + "param-key=ovs-host-setup"]) conf_hosts = cs_host_id + (conf_hosts and ',%s' % conf_hosts or '') lib.do_cmd([lib.XE_PATH, "network-param-set", "uuid=%s" % xs_nw_uuid, "other-config:ovs-host-setup=%s" % conf_hosts]) + # first clear the default rule (rule for 'NORMAL' processing which makes a bridge simple L2 learn & flood switch) + lib.del_flows(bridge, table=0) + # add a default flow rule to send broadcast and multi-cast packets to L2 flooding table - lib.add_flow(bridge, priority=1000, dl_dst='ff:ff:ff:ff:ff:ff', table=0, actions='resubmit(,2)') - lib.add_flow(bridge, priority=1000, nw_dst='224.0.0.0/24', table=0, actions='resubmit(,2)') + lib.add_flow(bridge, priority=1200, dl_dst='ff:ff:ff:ff:ff:ff', table=lib.CLASSIFIER_TABLE, + actions='resubmit(,%s)'%lib.L2_FLOOD_TABLE) + lib.add_flow(bridge, priority=1200, nw_dst='224.0.0.0/24', table=lib.CLASSIFIER_TABLE, + actions='resubmit(,%s)'%lib.L2_FLOOD_TABLE) # add a default flow rule to send uni-cast traffic to L2 lookup table - lib.add_flow(bridge, priority=0, table=0, actions='resubmit(,1)') + lib.add_flow(bridge, priority=0, table=lib.CLASSIFIER_TABLE, actions='resubmit(,%s)'%lib.L2_LOOKUP_TABLE) # add a default rule to send unknown mac address to L2 flooding table - lib.add_flow(bridge, priority=0, table=1, actions='resubmit(,2)') + lib.add_flow(bridge, priority=0, table=lib.L2_LOOKUP_TABLE, actions='resubmit(,%s)'%lib.L2_FLOOD_TABLE) # add a default rule in L2 flood table to drop packet - lib.add_flow(bridge, priority=0, table=2, actions='drop') + lib.add_flow(bridge, priority=0, table=lib.L2_FLOOD_TABLE, actions='drop') - # add a default rule in egress table to forward packet to L3 lookup table - lib.add_flow(bridge, priority=0, table=3, actions='resubmit(,4)') + # add a default rule in egress ACL table to forward packet to L3 lookup table + lib.add_flow(bridge, priority=0, table=lib.EGRESS_ACL_TABLE, actions='resubmit(,%s)'%lib.L3_LOOKUP_TABLE) # add a default rule in L3 lookup table to forward packet to L2 lookup table - lib.add_flow(bridge, priority=0, table=4, actions='resubmit(,1)') + lib.add_flow(bridge, priority=0, table=lib.L3_LOOKUP_TABLE, actions='resubmit(,%s)'%lib.L2_LOOKUP_TABLE) # add a default rule in ingress table to drop in bound packets - lib.add_flow(bridge, priority=0, table=5, actions='drop') + lib.add_flow(bridge, priority=0, table=lib.INGRESS_ACL_TABLE, actions='drop') + + # initialize the sequence number for the bridge + lib.do_cmd([lib.VSCTL_PATH, "set", "bridge", bridge, "other-config:topology-update-sequence-number=0"]) + lib.do_cmd([lib.VSCTL_PATH, "set", "bridge", bridge, "other-config:route-policy-update-sequence-number=0"]) result = "SUCCESS: successfully setup bridge with flow rules" @@ -195,6 +204,7 @@ def setup_ovs_bridge_for_distributed_routing(session, args): @echo def destroy_ovs_bridge(session, args): bridge = args.pop("bridge") + this_host_id = args.pop("cs_host_id") res = lib.check_switch() if res != "SUCCESS": return res @@ -204,11 +214,21 @@ def destroy_ovs_bridge(session, args): result = "FAILURE:%s" % res else: # Note that the bridge has been removed on xapi network object - xs_nw_uuid = lib.do_cmd([xePath, "network-list", + xs_nw_uuid = lib.do_cmd([lib.XE_PATH, "network-list", "bridge=%s" % bridge, "--minimal"]) - #FIXME: WOW, this an error - #lib.do_cmd([xePath,"network-param-set", "uuid=%s" % xs_nw_uuid, - # "other-config:ovs-setup=False"]) + conf_hosts = lib.do_cmd([lib.XE_PATH, "network-param-get", + "uuid=%s" % xs_nw_uuid, + "param-name=other-config", + "param-key=ovs-host-setup"]) + new_conf_hosts = "" + hosts = conf_hosts.split(',') + for host in hosts: + if str(host) == str(this_host_id): + continue + new_conf_hosts = host + "," + new_conf_hosts + new_conf_hosts = new_conf_hosts[:-1] + lib.do_cmd([lib.XE_PATH, "network-param-set", "uuid=%s" % xs_nw_uuid, + "other-config:ovs-host-setup=%s" % new_conf_hosts]) result = "SUCCESS:%s" % bridge logging.debug("Destroy_ovs_bridge completed with result:%s" % result) @@ -224,115 +244,7 @@ def create_tunnel(session, args): dst_host = args.pop("to") network_uuid = args.pop("cloudstack-network-id") - logging.debug("Entering create_tunnel") - - res = lib.check_switch() - if res != "SUCCESS": - logging.debug("Openvswitch running: NO") - return "FAILURE:%s" % res - - # We need to keep the name below 14 characters - # src and target are enough - consider a fixed length hash - name = "t%s-%s-%s" % (gre_key, src_host, dst_host) - - # Verify the xapi bridge to be created - # NOTE: Timeout should not be necessary anymore - wait = [lib.VSCTL_PATH, "--timeout=30", "wait-until", "bridge", - bridge, "--", "get", "bridge", bridge, "name"] - res = lib.do_cmd(wait) - if bridge not in res: - logging.debug("WARNING:Can't find bridge %s for creating " + - "tunnel!" % bridge) - return "FAILURE:NO_BRIDGE" - logging.debug("bridge %s for creating tunnel - VERIFIED" % bridge) - tunnel_setup = False - drop_flow_setup = False - try: - # Create a port and configure the tunnel interface for it - add_tunnel = [lib.VSCTL_PATH, "add-port", bridge, - name, "--", "set", "interface", - name, "type=gre", "options:key=%s" % gre_key, - "options:remote_ip=%s" % remote_ip] - lib.do_cmd(add_tunnel) - tunnel_setup = True - # verify port - verify_port = [lib.VSCTL_PATH, "get", "port", name, "interfaces"] - res = lib.do_cmd(verify_port) - # Expecting python-style list as output - iface_list = [] - if len(res) > 2: - iface_list = res.strip()[1:-1].split(',') - if len(iface_list) != 1: - logging.debug("WARNING: Unexpected output while verifying " + - "port %s on bridge %s" % (name, bridge)) - return "FAILURE:VERIFY_PORT_FAILED" - - # verify interface - iface_uuid = iface_list[0] - verify_interface_key = [lib.VSCTL_PATH, "get", "interface", - iface_uuid, "options:key"] - verify_interface_ip = [lib.VSCTL_PATH, "get", "interface", - iface_uuid, "options:remote_ip"] - - key_validation = lib.do_cmd(verify_interface_key) - ip_validation = lib.do_cmd(verify_interface_ip) - - if not gre_key in key_validation or not remote_ip in ip_validation: - logging.debug("WARNING: Unexpected output while verifying " + - "interface %s on bridge %s" % (name, bridge)) - return "FAILURE:VERIFY_INTERFACE_FAILED" - logging.debug("Tunnel interface validated:%s" % verify_interface_ip) - cmd_tun_ofport = [lib.VSCTL_PATH, "get", "interface", - iface_uuid, "ofport"] - tun_ofport = lib.do_cmd(cmd_tun_ofport) - # Ensure no trailing LF - if tun_ofport.endswith('\n'): - tun_ofport = tun_ofport[:-1] - # find xs network for this bridge, verify is used for ovs tunnel network - xs_nw_uuid = lib.do_cmd([lib.XE_PATH, "network-list", - "bridge=%s" % bridge, "--minimal"]) - ovs_tunnel_network = lib.do_cmd([lib.XE_PATH,"network-param-get", - "uuid=%s" % xs_nw_uuid, - "param-name=other-config", - "param-key=is-ovs-tun-network", "--minimal"]) - ovs_vpc_distributed_vr_network = lib.do_cmd([lib.XE_PATH,"network-param-get", - "uuid=%s" % xs_nw_uuid, - "param-name=other-config", - "param-key=is-ovs_vpc_distributed_vr_network", "--minimal"]) - if ovs_tunnel_network == 'True': - # add flow entryies for dropping broadcast coming in from gre tunnel - lib.add_flow(bridge, priority=1000, in_port=tun_ofport, - dl_dst='ff:ff:ff:ff:ff:ff', actions='drop') - lib.add_flow(bridge, priority=1000, in_port=tun_ofport, - nw_dst='224.0.0.0/24', actions='drop') - drop_flow_setup = True - logging.debug("Broadcast drop rules added") - - if ovs_vpc_distributed_vr_network == 'True': - # add flow rules for dropping broadcast coming in from tunnel ports - lib.add_flow(bridge, priority=1000, in_port=tun_ofport, table=0, - dl_dst='ff:ff:ff:ff:ff:ff', actions='drop') - lib.add_flow(bridge, priority=1000, in_port=tun_ofport, table=0, - nw_dst='224.0.0.0/24', actions='drop') - - # add flow rule to send the traffic from tunnel ports to L2 switching table only - lib.add_flow(bridge, priority=1000, in_port=tun_ofport, table=0, actions='resubmit(,1)') - lib.do_cmd([lib.VSCTL_PATH, "set", "interface", name, "options:cloudstack-network-id=%s" % network_uuid]) - - return "SUCCESS:%s" % name - except: - logging.debug("An unexpected error occured. Rolling back") - if tunnel_setup: - logging.debug("Deleting GRE interface") - # Destroy GRE port and interface - lib.del_port(bridge, name) - if drop_flow_setup: - # Delete flows - logging.debug("Deleting flow entries from GRE interface") - lib.del_flows(bridge, in_port=tun_ofport) - # This will not cancel the original exception - raise - + return lib.create_tunnel(bridge, remote_ip, gre_key, src_host, dst_host, network_uuid) @echo def destroy_tunnel(session, args): @@ -390,15 +302,36 @@ def configure_ovs_bridge_for_network_topology(session, args): bridge = args.pop("bridge") json_config = args.pop("config") this_host_id = args.pop("host-id") - - return lib.configure_bridge_for_network_topology(bridge, this_host_id, json_config) + sequence_no = args.pop("seq-no") + + # get the last update sequence number + last_seq_no = lib.do_cmd([lib.VSCTL_PATH, "get", "bridge", bridge, "other-config:topology-update-sequence-number"]) + last_seq_no = last_seq_no[1:-1] + if long(sequence_no) > long(last_seq_no): + lib.do_cmd([lib.VSCTL_PATH, "set", "bridge", bridge, + "other-config:topology-update-sequence-number=%s"%sequence_no]) + return lib.configure_vpc_bridge_for_network_topology(bridge, this_host_id, json_config, sequence_no) + else: + return "SUCCESS: Ignoring the update with the sequence number %s" %sequence_no + " as there is already recent" \ + " update received and applied with sequence number %s" %last_seq_no @echo def configure_ovs_bridge_for_routing_policies(session, args): bridge = args.pop("bridge") json_config = args.pop("config") - - return lib.configure_ovs_bridge_for_router_policies(bridge, json_config) + sequence_no = args.pop("seq-no") + + # get the last update sequence number + last_seq_no = lib.do_cmd([lib.VSCTL_PATH, "get", "bridge", bridge, + "other-config:route-policy-update-sequence-number"]) + last_seq_no = last_seq_no[1:-1] + if long(sequence_no) > long(last_seq_no): + lib.do_cmd([lib.VSCTL_PATH, "set", "bridge", bridge, + "other-config:route-policy-update-sequence-number=%s"%sequence_no]) + return lib.configure_vpc_bridge_for_routing_policies(bridge, json_config, sequence_no) + else: + return "SUCCESS: Ignoring the update with the sequence number %s" %sequence_no + " as there is already recent" \ + " update received and applied with sequence number %s" %last_seq_no if __name__ == "__main__": XenAPIPlugin.dispatch({"create_tunnel": create_tunnel, @@ -409,4 +342,4 @@ if __name__ == "__main__": "getLabel": getLabel, "setup_ovs_bridge_for_distributed_routing": setup_ovs_bridge_for_distributed_routing, "configure_ovs_bridge_for_network_topology": configure_ovs_bridge_for_network_topology, - "configure_ovs_bridge_for_routing_policies": "configure_ovs_bridge_for_routing_policies"}) + "configure_ovs_bridge_for_routing_policies": configure_ovs_bridge_for_routing_policies}) \ No newline at end of file diff --git a/scripts/vm/hypervisor/xenserver/vmops b/scripts/vm/hypervisor/xenserver/vmops index 4174ef24f7..3f25a2e7f9 100755 --- a/scripts/vm/hypervisor/xenserver/vmops +++ b/scripts/vm/hypervisor/xenserver/vmops @@ -27,7 +27,6 @@ if os.path.exists("/opt/xensource/sm"): if os.path.exists("/usr/lib/xcp/sm"): sys.path.extend(["/usr/lib/xcp/sm/", "/usr/local/sbin/", "/sbin/"]) import base64 -import hostvmstats import socket import stat import tempfile @@ -61,15 +60,6 @@ def add_to_VCPUs_params_live(session, args): return 'false' return 'true' -@echo -def gethostvmstats(session, args): - collect_host_stats = args['collectHostStats'] - consolidation_function = args['consolidationFunction'] - interval = args['interval'] - start_time = args['startTime'] - result = hostvmstats.get_stats(session, collect_host_stats, consolidation_function, interval, start_time) - return result - @echo def setup_iscsi(session, args): uuid=args['uuid'] @@ -207,20 +197,6 @@ def setLinkLocalIP(session, args): txt = 'success' return txt -@echo -def routerProxy(session, args): - sargs = args['args'] - cmd = sargs.split(' ') - cmd.insert(0, "/opt/cloud/bin/router_proxy.sh") - cmd.insert(0, "/bin/bash") - try: - txt = util.pread2(cmd) - txt = 'succ#' + txt - except: - logging.debug("routerProxy command " + sargs + " failed " ) - txt = 'fail#' + txt - return txt - @echo def createFile(session, args): file_path = args['filepath'] @@ -1502,10 +1478,9 @@ def network_rules(session, args): logging.debug("Failed to network rule !") if __name__ == "__main__": - XenAPIPlugin.dispatch({"pingtest": pingtest, "setup_iscsi":setup_iscsi, "gethostvmstats": gethostvmstats, + XenAPIPlugin.dispatch({"pingtest": pingtest, "setup_iscsi":setup_iscsi, "getgateway": getgateway, "preparemigration": preparemigration, "setIptables": setIptables, "pingdomr": pingdomr, "pingxenserver": pingxenserver, - "routerProxy": routerProxy, "createFile": createFile, "deleteFile": deleteFile, "network_rules":network_rules, "can_bridge_firewall":can_bridge_firewall, "default_network_rules":default_network_rules, diff --git a/scripts/vm/hypervisor/xenserver/vmopspremium b/scripts/vm/hypervisor/xenserver/vmopspremium index 06b0a51f7e..2887436670 100755 --- a/scripts/vm/hypervisor/xenserver/vmopspremium +++ b/scripts/vm/hypervisor/xenserver/vmopspremium @@ -123,18 +123,7 @@ def setup_heartbeat_file(session, args): txt = '' return txt -@echo -def check_heartbeat(session, args): - host = args['host'] - interval = args['interval'] - try: - cmd = ["bash", "/opt/cloud/bin/check_heartbeat.sh", host, interval] - txt = util.pread2(cmd) - except: - txt='' - return txt - - + @echo def heartbeat(session, args): host = args['host'] @@ -156,5 +145,4 @@ def asmonitor(session, args): return 'fail' if __name__ == "__main__": - XenAPIPlugin.dispatch({"forceShutdownVM":forceShutdownVM, "upgrade_snapshot":upgrade_snapshot, "create_privatetemplate_from_snapshot":create_privatetemplate_from_snapshot, "copy_vhd_to_secondarystorage":copy_vhd_to_secondarystorage, "copy_vhd_from_secondarystorage":copy_vhd_from_secondarystorage, "setup_heartbeat_sr":setup_heartbeat_sr, "setup_heartbeat_file":setup_heartbeat_file, "check_heartbeat":check_heartbeat, "heartbeat": heartbeat, "asmonitor": asmonitor}) - + XenAPIPlugin.dispatch({"forceShutdownVM":forceShutdownVM, "upgrade_snapshot":upgrade_snapshot, "create_privatetemplate_from_snapshot":create_privatetemplate_from_snapshot, "copy_vhd_to_secondarystorage":copy_vhd_to_secondarystorage, "copy_vhd_from_secondarystorage":copy_vhd_from_secondarystorage, "setup_heartbeat_sr":setup_heartbeat_sr, "setup_heartbeat_file":setup_heartbeat_file, "heartbeat": heartbeat, "asmonitor": asmonitor}) diff --git a/scripts/vm/hypervisor/xenserver/xcposs/copy_vhd_from_secondarystorage.sh b/scripts/vm/hypervisor/xenserver/xcposs/copy_vhd_from_secondarystorage.sh new file mode 100755 index 0000000000..a4e977bdd5 --- /dev/null +++ b/scripts/vm/hypervisor/xenserver/xcposs/copy_vhd_from_secondarystorage.sh @@ -0,0 +1,188 @@ +#!/bin/bash +# 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. + +#set -x + +usage() { + printf "Usage: %s [vhd file in secondary storage] [uuid of the source sr] [name label] \n" $(basename $0) +} + +cleanup() +{ + if [ ! -z $localmp ]; then + umount -fl $localmp + if [ $? -eq 0 ]; then + rmdir $localmp + fi + fi +} + +if [ -z $1 ]; then + usage + echo "2#no mountpoint" + exit 0 +else + mountpoint=${1%/*} + vhdfilename=${1##*/} +fi + +if [ -z $2 ]; then + usage + echo "3#no uuid of the source sr" + exit 0 +else + sruuid=$2 +fi + +type=$(xe sr-param-get uuid=$sruuid param-name=type) +if [ $? -ne 0 ]; then + echo "4#sr $sruuid doesn't exist" + exit 0 +fi + +if [ -z $3 ]; then + usage + echo "3#no namelabel" + exit 0 +else + namelabel=$3 +fi + +localmp=/var/run/cloud_mount/$(uuidgen -r) + +mkdir -p $localmp +if [ $? -ne 0 ]; then + echo "5#can't make dir $localmp" + exit 0 +fi + +mount -o tcp,soft,ro,timeo=133,retrans=1 $mountpoint $localmp +if [ $? -ne 0 ]; then + echo "6#can't mount $mountpoint to $localmp" + exit 0 +fi + +vhdfile=$localmp/$vhdfilename +if [ ${vhdfile%.vhd} == ${vhdfile} ] ; then + vhdfile=$(ls $vhdfile/*.vhd) + if [ $? -ne 0 ]; then + echo "7#There is no vhd file under $mountpoint" + cleanup + exit 0 + fi +fi + + + +VHDUTIL="/usr/bin/vhd-util" + +copyvhd() +{ + local desvhd=$1 + local srcvhd=$2 + local vsize=$3 + local type=$4 + local parent=`$VHDUTIL query -p -n $srcvhd` + if [ $? -ne 0 ]; then + echo "30#failed to query $srcvhd" + cleanup + exit 0 + fi + if [ "${parent##*vhd has}" = " no parent" ]; then + dd if=$srcvhd of=$desvhd bs=2M + if [ $? -ne 0 ]; then + echo "31#failed to dd $srcvhd to $desvhd" + cleanup + exit 0 + fi + if [ $type != "nfs" -a $type != "ext" -a $type != "file" ]; then + dd if=$srcvhd of=$desvhd bs=512 seek=$(($(($vsize/512))-1)) count=1 + $VHDUTIL modify -s $vsize -n $desvhd + if [ $? -ne 0 ]; then + echo "32#failed to set new vhd physical size for vdi vdi $uuid" + cleanup + exit 0 + fi + fi + else + copyvhd $desvhd $parent $vsize $type + $VHDUTIL coalesce -p $desvhd -n $srcvhd + if [ $? -ne 0 ]; then + echo "32#failed to coalesce $desvhd to $srcvhd" + cleanup + exit 0 + fi + fi +} + +size=$($VHDUTIL query -v -n $vhdfile) +uuid=$(xe vdi-create sr-uuid=$sruuid virtual-size=${size}MiB type=user name-label=$namelabel) +if [ $? -ne 0 ]; then + echo "9#can not create vdi in sr $sruuid" + cleanup + exit 0 +fi + + +if [ $type == "nfs" -o $type == "ext" ]; then + desvhd=/run/sr-mount/$sruuid/$uuid.vhd + copyvhd $desvhd $vhdfile 0 $type + +elif [ $type == "lvmoiscsi" -o $type == "lvm" -o $type == "lvmohba" ]; then + lvsize=$(xe vdi-param-get uuid=$uuid param-name=physical-utilisation) + if [ $? -ne 0 ]; then + echo "12#failed to get physical size of vdi $uuid" + cleanup + exit 0 + fi + desvhd=/dev/VG_XenStorage-$sruuid/VHD-$uuid + lvchange -ay $desvhd + if [ $? -ne 0 ]; then + echo "10#lvm can not make VDI $uuid visible" + cleanup + exit 0 + fi + copyvhd $desvhd $vhdfile $lvsize $type +elif [ $type == "file" ]; then + pbd=`xe sr-param-list uuid=$sruuid |grep PBDs | awk '{print $3}'` + path=`xe pbd-param-list uuid=$pbd |grep device-config |awk '{print $4}'` + desvhd=$path/$uuid.vhd + copyvhd $desvhd $vhdfile 0 $type + +else + echo "15#doesn't support sr type $type" + cleanup + exit 0 +fi + +$VHDUTIL set -n $desvhd -f "hidden" -v "0" > /dev/null +if [ $? -ne 0 ]; then + echo "21#failed to set hidden to 0 $desvhd" + cleanup + exit 0 +fi +xe sr-scan uuid=$sruuid +if [ $? -ne 0 ]; then + echo "14#failed to scan sr $sruuid" + cleanup + exit 0 +fi + +echo "0#$uuid" +cleanup +exit 0 diff --git a/scripts/vm/hypervisor/xenserver/xcposs/copy_vhd_to_secondarystorage.sh b/scripts/vm/hypervisor/xenserver/xcposs/copy_vhd_to_secondarystorage.sh new file mode 100755 index 0000000000..b315c07b35 --- /dev/null +++ b/scripts/vm/hypervisor/xenserver/xcposs/copy_vhd_to_secondarystorage.sh @@ -0,0 +1,130 @@ +#!/bin/bash +# 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. + +#set -x + +usage() { + printf "Usage: %s [mountpoint in secondary storage] [uuid of the source vdi] [uuid of the source sr]\n" $(basename $0) +} + +cleanup() +{ + if [ ! -z $localmp ]; then + umount $localmp + if [ $? -eq 0 ]; then + rmdir $localmp + fi + fi +} + +if [ -z $1 ]; then + usage + echo "1#no mountpoint" + exit 0 +else + mountpoint=$1 +fi + +if [ -z $2 ]; then + usage + echo "2#no uuid of the source sr" + exit 0 +else + vdiuuid=$2 +fi + + +if [ -z $3 ]; then + usage + echo "3#no uuid of the source sr" + exit 0 +else + sruuid=$3 +fi + +type=$(xe sr-param-get uuid=$sruuid param-name=type) +if [ $? -ne 0 ]; then + echo "4#sr $sruuid doesn't exist" + exit 0 +fi + +localmp=/var/run/cloud_mount/$(uuidgen -r) + +mkdir -p $localmp +if [ $? -ne 0 ]; then + echo "5#can't make dir $localmp" + exit 0 +fi + +mount -o tcp,soft,timeo=133,retrans=1 $mountpoint $localmp +if [ $? -ne 0 ]; then + echo "6#can't mount $mountpoint to $localmp" + exit 0 +fi + +vhdfile=$localmp/${vdiuuid}.vhd + +if [ $type == "nfs" -o $type == "ext" ]; then + dd if=/var/run/sr-mount/$sruuid/${vdiuuid}.vhd of=$vhdfile bs=2M + if [ $? -ne 0 ]; then + rm -f $vhdfile + echo "8#failed to copy /var/run/sr-mount/$sruuid/${vdiuuid}.vhd to secondarystorage" + cleanup + exit 0 + fi +elif [ $type == "lvmoiscsi" -o $type == "lvm" -o $type == "lvmohba" ]; then + lvchange -ay /dev/VG_XenStorage-$sruuid/VHD-$vdiuuid + if [ $? -ne 0 ]; then + echo "9#lvm can not make VDI $vdiuuid visible" + cleanup + exit 0 + fi + size=$(vhd-util query -s -n /dev/VG_XenStorage-$sruuid/VHD-$vdiuuid) + if [ $? -ne 0 ]; then + echo "10#can not get physical size of /dev/VG_XenStorage-$sruuid/VHD-$vdiuuid" + cleanup + exit 0 + fi +#in 2M unit + size=$((size>>21)) + size=$((size+1)) + dd if=/dev/VG_XenStorage-$sruuid/VHD-$vdiuuid of=$vhdfile bs=2M count=$size + if [ $? -ne 0 ]; then + rm -f $vhdfile + echo "8#failed to copy /dev/VG_XenStorage-$sruuid/VHD-$vdiuuid to secondarystorage" + cleanup + exit 0 + fi +#in byte unit + size=$((size<<21)) + vhd-util modify -s $size -n $vhdfile + if [ $? -ne 0 ]; then + rm -f $vhdfile + echo "11#failed to change $vhdfile physical size" + cleanup + exit 0 + fi +else + echo "15#doesn't support sr type $type" + cleanup + exit 0 +fi + +echo "0#$vdiuuid" +cleanup +exit 0 diff --git a/scripts/vm/hypervisor/xenserver/xcposs/patch b/scripts/vm/hypervisor/xenserver/xcposs/patch index 08da883e54..ac04a3e14d 100644 --- a/scripts/vm/hypervisor/xenserver/xcposs/patch +++ b/scripts/vm/hypervisor/xenserver/xcposs/patch @@ -27,11 +27,12 @@ # If [source path] starts with '~', then it is path relative to management server home directory. # If [source path] does not start with '/' or '~', then it is relative path to the location of the patch file. NFSSR.py=/usr/lib/xcp/sm -vmops=..,0755,/usr/lib/xcp/plugins +vmops=,0755,/usr/lib/xcp/plugins +cloudstack_pluginlib.py=..,0755,/usr/lib/xcp/plugins +cloudstack_plugins.conf=..,0644,/etc/xcp ovsgre=..,0755,/usr/lib/xcp/plugins ovstunnel=..,0755,/usr/lib/xcp/plugins -vmopsSnapshot=..,0755,/usr/lib/xcp/plugins -hostvmstats.py=..,0755,/usr/lib/xcp/sm +vmopsSnapshot=,0755,/usr/lib/xcp/plugins systemvm.iso=../../../../../vms,0644,/usr/share/xcp/packages/iso/ id_rsa.cloud=../../../systemvm,0600,/root/.ssh network_info.sh=..,0755,/opt/cloud/bin @@ -40,8 +41,8 @@ make_migratable.sh=..,0755,/opt/cloud/bin setup_iscsi.sh=..,0755,/opt/cloud/bin pingtest.sh=../../..,0755,/opt/cloud/bin cloud-setup-bonding.sh=..,0755,/opt/cloud/bin -copy_vhd_to_secondarystorage.sh=..,0755,/opt/cloud/bin -copy_vhd_from_secondarystorage.sh=..,0755,/opt/cloud/bin +copy_vhd_to_secondarystorage.sh=,0755,/opt/cloud/bin +copy_vhd_from_secondarystorage.sh=,0755,/opt/cloud/bin setup_heartbeat_sr.sh=..,0755,/opt/cloud/bin setup_heartbeat_file.sh=..,0755,/opt/cloud/bin check_heartbeat.sh=..,0755,/opt/cloud/bin diff --git a/scripts/vm/hypervisor/xenserver/xcposs/vmops b/scripts/vm/hypervisor/xenserver/xcposs/vmops new file mode 100644 index 0000000000..1792a46773 --- /dev/null +++ b/scripts/vm/hypervisor/xenserver/xcposs/vmops @@ -0,0 +1,1476 @@ +#!/usr/bin/python +# 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. + +# Version @VERSION@ +# +# A plugin for executing script needed by vmops cloud + +import os, sys, time +import XenAPIPlugin +sys.path.extend(["/usr/lib/xcp/sm/", "/usr/local/sbin/", "/sbin/"]) +import base64 +import hostvmstats +import socket +import stat +import tempfile +import util +import subprocess +import zlib +from util import CommandException + +def echo(fn): + def wrapped(*v, **k): + name = fn.__name__ + util.SMlog("#### VMOPS enter %s ####" % name ) + res = fn(*v, **k) + util.SMlog("#### VMOPS exit %s ####" % name ) + return res + return wrapped + +@echo +def gethostvmstats(session, args): + collect_host_stats = args['collectHostStats'] + consolidation_function = args['consolidationFunction'] + interval = args['interval'] + start_time = args['startTime'] + result = hostvmstats.get_stats(session, collect_host_stats, consolidation_function, interval, start_time) + return result + +@echo +def setup_iscsi(session, args): + uuid=args['uuid'] + try: + cmd = ["b", "/opt/cloud/bin/setup_iscsi.sh", uuid] + txt = util.pread2(cmd) + except: + txt = '' + return '> DONE <' + + +@echo +def getgateway(session, args): + mgmt_ip = args['mgmtIP'] + try: + cmd = ["bash", "/opt/cloud/bin/network_info.sh", "-g", mgmt_ip] + txt = util.pread2(cmd) + except: + txt = '' + + return txt + +@echo +def preparemigration(session, args): + uuid = args['uuid'] + try: + cmd = ["/opt/cloud/bin/make_migratable.sh", uuid] + util.pread2(cmd) + txt = 'success' + except: + util.SMlog("Catch prepare migration exception" ) + txt = '' + + return txt + +@echo +def setIptables(session, args): + try: + '''cmd = ["/bin/bash", "/opt/cloud/bin/setupxenserver.sh"] + txt = util.pread2(cmd)''' + txt = 'success' + except: + util.SMlog(" setIptables execution failed " ) + txt = '' + + return txt + +@echo +def pingdomr(session, args): + host = args['host'] + port = args['port'] + socket.setdefaulttimeout(3) + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + try: + s.connect((host,int(port))) + txt = 'success' + except: + txt = '' + + s.close() + + return txt + +@echo +def kill_copy_process(session, args): + namelabel = args['namelabel'] + try: + cmd = ["bash", "/opt/cloud/bin/kill_copy_process.sh", namelabel] + txt = util.pread2(cmd) + except: + txt = 'false' + return txt + +@echo +def pingxenserver(session, args): + txt = 'success' + return txt + +@echo +def ipassoc(session, args): + sargs = args['args'] + cmd = sargs.split(' ') + cmd.insert(0, "/opt/cloud/bin/ipassoc.sh") + cmd.insert(0, "/bin/bash") + try: + txt = util.pread2(cmd) + txt = 'success' + except: + util.SMlog(" ip associate failed " ) + txt = '' + + return txt + +def pingtest(session, args): + sargs = args['args'] + cmd = sargs.split(' ') + cmd.insert(0, "/opt/cloud/bin/pingtest.sh") + cmd.insert(0, "/bin/bash") + try: + txt = util.pread2(cmd) + txt = 'success' + except: + util.SMlog(" pingtest failed " ) + txt = '' + + return txt + +@echo +def savePassword(session, args): + sargs = args['args'] + cmd = sargs.split(' ') + cmd.insert(0, "/opt/cloud/bin/save_password_to_domr.sh") + cmd.insert(0, "/bin/bash") + try: + txt = util.pread2(cmd) + txt = 'success' + except: + util.SMlog(" save password to domr failed " ) + txt = '' + + return txt + +@echo +def saveDhcpEntry(session, args): + sargs = args['args'] + cmd = sargs.split(' ') + cmd.insert(0, "/opt/cloud/bin/dhcp_entry.sh") + cmd.insert(0, "/bin/bash") + try: + txt = util.pread2(cmd) + txt = 'success' + except: + util.SMlog(" save dhcp entry failed " ) + txt = '' + + return txt + +@echo +def lt2p_vpn(session, args): + sargs = args['args'] + cmd = sargs.split(' ') + cmd.insert(0, "/opt/cloud/bin/l2tp_vpn.sh") + cmd.insert(0, "/bin/bash") + try: + txt = util.pread2(cmd) + txt = 'success' + except: + util.SMlog("l2tp vpn failed " ) + txt = '' + + return txt + +@echo +def setLinkLocalIP(session, args): + brName = args['brName'] + try: + cmd = ["ip", "route", "del", "169.254.0.0/16"] + txt = util.pread2(cmd) + except: + txt = '' + try: + cmd = ["ifconfig", brName, "169.254.0.1", "netmask", "255.255.0.0"] + txt = util.pread2(cmd) + except: + + try: + cmd = ["brctl", "addbr", brName] + txt = util.pread2(cmd) + except: + pass + + try: + cmd = ["ifconfig", brName, "169.254.0.1", "netmask", "255.255.0.0"] + txt = util.pread2(cmd) + except: + pass + try: + cmd = ["ip", "route", "add", "169.254.0.0/16", "dev", brName, "src", "169.254.0.1"] + txt = util.pread2(cmd) + except: + txt = '' + txt = 'success' + return txt + +@echo +def setFirewallRule(session, args): + sargs = args['args'] + cmd = sargs.split(' ') + cmd.insert(0, "/opt/cloud/bin/call_firewall.sh") + cmd.insert(0, "/bin/bash") + try: + txt = util.pread2(cmd) + txt = 'success' + except: + util.SMlog(" set firewall rule failed " ) + txt = '' + + return txt + +@echo +def setLoadBalancerRule(session, args): + sargs = args['args'] + cmd = sargs.split(' ') + cmd.insert(0, "/opt/cloud/bin/call_loadbalancer.sh") + cmd.insert(0, "/bin/bash") + try: + txt = util.pread2(cmd) + txt = 'success' + except: + util.SMlog(" set loadbalancer rule failed " ) + txt = '' + + return txt + +@echo +def createFile(session, args): + file_path = args['filepath'] + file_contents = args['filecontents'] + + try: + f = open(file_path, "w") + f.write(file_contents) + f.close() + txt = 'success' + except: + util.SMlog(" failed to create HA proxy cfg file ") + txt = '' + + return txt + +@echo +def deleteFile(session, args): + file_path = args["filepath"] + + try: + if os.path.isfile(file_path): + os.remove(file_path) + txt = 'success' + except: + util.SMlog(" failed to remove HA proxy cfg file ") + txt = '' + + return txt + + +@echo +def networkUsage(session, args): + sargs = args['args'] + cmd = sargs.split(' ') + cmd.insert(0, "/opt/cloud/bin/networkUsage.sh") + cmd.insert(0, "/bin/bash") + try: + txt = util.pread2(cmd) + except: + util.SMlog(" network usage error " ) + txt = '' + + return txt + +def get_private_nic(session, args): + vms = session.xenapi.VM.get_all() + host_uuid = args.get('host_uuid') + host = session.xenapi.host.get_by_uuid(host_uuid) + piflist = session.xenapi.host.get_PIFs(host) + mgmtnic = 'eth0' + for pif in piflist: + pifrec = session.xenapi.PIF.get_record(pif) + network = pifrec.get('network') + nwrec = session.xenapi.network.get_record(network) + if nwrec.get('name_label') == 'cloud-guest': + return pifrec.get('device') + if pifrec.get('management'): + mgmtnic = pifrec.get('device') + + return mgmtnic + +def chain_name(vm_name): + if vm_name.startswith('i-') or vm_name.startswith('r-'): + if vm_name.endswith('untagged'): + return '-'.join(vm_name.split('-')[:-1]) + return vm_name + +def chain_name_def(vm_name): + if vm_name.startswith('i-'): + if vm_name.endswith('untagged'): + return '-'.join(vm_name.split('-')[:-2]) + "-def" + return '-'.join(vm_name.split('-')[:-1]) + "-def" + return vm_name + +def egress_chain_name(vm_name): + return chain_name(vm_name) + "-eg" + +@echo +def can_bridge_firewall(session, args): + try: + util.pread2(['ebtables', '-V']) + util.pread2(['ipset', '-V']) + except: + return 'false' + + host_uuid = args.get('host_uuid') + try: + util.pread2(['iptables', '-N', 'BRIDGE-FIREWALL']) + util.pread2(['iptables', '-I', 'BRIDGE-FIREWALL', '-m', 'state', '--state', 'RELATED,ESTABLISHED', '-j', 'ACCEPT']) + util.pread2(['iptables', '-A', 'BRIDGE-FIREWALL', '-m', 'physdev', '--physdev-is-bridged', '-p', 'udp', '--dport', '67', '--sport', '68', '-j', 'ACCEPT']) + util.pread2(['iptables', '-A', 'BRIDGE-FIREWALL', '-m', 'physdev', '--physdev-is-bridged', '-p', 'udp', '--dport', '68', '--sport', '67', '-j', 'ACCEPT']) + util.pread2(['iptables', '-D', 'FORWARD', '-j', 'RH-Firewall-1-INPUT']) + except: + util.SMlog('Chain BRIDGE-FIREWALL already exists') + privnic = get_private_nic(session, args) + result = 'true' + try: + util.pread2(['/bin/bash', '-c', 'iptables -n -L FORWARD | grep BRIDGE-FIREWALL']) + except: + try: + util.pread2(['iptables', '-I', 'FORWARD', '-m', 'physdev', '--physdev-is-bridged', '-j', 'BRIDGE-FIREWALL']) + util.pread2(['iptables', '-A', 'FORWARD', '-m', 'physdev', '--physdev-is-bridged', '--physdev-out', privnic, '-j', 'ACCEPT']) + util.pread2(['iptables', '-A', 'FORWARD', '-j', 'DROP']) + except: + return 'false' + default_ebtables_rules() + allow_egress_traffic(session) + if not os.path.exists('/var/run/cloud'): + os.makedirs('/var/run/cloud') + if not os.path.exists('/var/cache/cloud'): + os.makedirs('/var/cache/cloud') + #get_ipset_keyword() + + cleanup_rules_for_dead_vms(session) + cleanup_rules(session, args) + + return result + +@echo +def default_ebtables_rules(): + try: + util.pread2(['ebtables', '-N', 'DEFAULT_EBTABLES']) + util.pread2(['ebtables', '-A', 'FORWARD', '-j' 'DEFAULT_EBTABLES']) + util.pread2(['ebtables', '-A', 'DEFAULT_EBTABLES', '-p', 'IPv4', '--ip-dst', '255.255.255.255', '--ip-proto', 'udp', '--ip-dport', '67', '-j', 'ACCEPT']) + util.pread2(['ebtables', '-A', 'DEFAULT_EBTABLES', '-p', 'ARP', '--arp-op', 'Request', '-j', 'ACCEPT']) + util.pread2(['ebtables', '-A', 'DEFAULT_EBTABLES', '-p', 'ARP', '--arp-op', 'Reply', '-j', 'ACCEPT']) + # deny mac broadcast and multicast + util.pread2(['ebtables', '-A', 'DEFAULT_EBTABLES', '-p', 'IPv4', '-d', 'Broadcast', '-j', 'DROP']) + util.pread2(['ebtables', '-A', 'DEFAULT_EBTABLES', '-p', 'IPv4', '-d', 'Multicast', '-j', 'DROP']) + # deny ip broadcast and multicast + util.pread2(['ebtables', '-A', 'DEFAULT_EBTABLES', '-p', 'IPv4', '--ip-dst', '255.255.255.255', '-j', 'DROP']) + util.pread2(['ebtables', '-A', 'DEFAULT_EBTABLES', '-p', 'IPv4', '--ip-dst', '224.0.0.0/4', '-j', 'DROP']) + util.pread2(['ebtables', '-A', 'DEFAULT_EBTABLES', '-p', 'IPv4', '-j', 'RETURN']) + # deny ipv6 + util.pread2(['ebtables', '-A', 'DEFAULT_EBTABLES', '-p', 'IPv6', '-j', 'DROP']) + # deny vlan + util.pread2(['ebtables', '-A', 'DEFAULT_EBTABLES', '-p', '802_1Q', '-j', 'DROP']) + # deny all others (e.g., 802.1d, CDP) + util.pread2(['ebtables', '-A', 'DEFAULT_EBTABLES', '-j', 'DROP']) + except: + util.SMlog('Chain DEFAULT_EBTABLES already exists') + + +@echo +def allow_egress_traffic(session): + devs = [] + for pif in session.xenapi.PIF.get_all(): + pif_rec = session.xenapi.PIF.get_record(pif) + vlan = pif_rec.get('VLAN') + dev = pif_rec.get('device') + if vlan == '-1': + devs.append(dev) + else: + devs.append(dev + "." + vlan) + for d in devs: + try: + util.pread2(['/bin/bash', '-c', "iptables -n -L FORWARD | grep '%s '" % d]) + except: + try: + util.pread2(['iptables', '-I', 'FORWARD', '2', '-m', 'physdev', '--physdev-is-bridged', '--physdev-out', d, '-j', 'ACCEPT']) + except: + util.SMlog("Failed to add FORWARD rule through to %s" % d) + return 'false' + return 'true' + + +def ipset(ipsetname, proto, start, end, ips): + try: + util.pread2(['ipset', '-N', ipsetname, 'iptreemap']) + except: + util.SMlog("ipset chain already exists" + ipsetname) + + result = True + ipsettmp = ''.join(''.join(ipsetname.split('-')).split('_')) + str(int(time.time()) % 1000) + + try: + util.pread2(['ipset', '-N', ipsettmp, 'iptreemap']) + except: + util.SMlog("Failed to create temp ipset, reusing old name= " + ipsettmp) + try: + util.pread2(['ipset', '-F', ipsettmp]) + except: + util.SMlog("Failed to clear old temp ipset name=" + ipsettmp) + return False + + try: + for ip in ips: + try: + util.pread2(['ipset', '-A', ipsettmp, ip]) + except CommandException, cex: + if cex.reason.rfind('already in set') == -1: + raise + except: + util.SMlog("Failed to program ipset " + ipsetname) + util.pread2(['ipset', '-F', ipsettmp]) + util.pread2(['ipset', '-X', ipsettmp]) + return False + + try: + util.pread2(['ipset', '-W', ipsettmp, ipsetname]) + except: + util.SMlog("Failed to swap ipset " + ipsetname) + result = False + + try: + util.pread2(['ipset', '-F', ipsettmp]) + util.pread2(['ipset', '-X', ipsettmp]) + except: + # if the temporary name clashes next time we'll just reuse it + util.SMlog("Failed to delete temp ipset " + ipsettmp) + + return result + +@echo +def destroy_network_rules_for_vm(session, args): + vm_name = args.pop('vmName') + vmchain = chain_name(vm_name) + vmchain_egress = egress_chain_name(vm_name) + vmchain_default = chain_name_def(vm_name) + + delete_rules_for_vm_in_bridge_firewall_chain(vm_name) + if vm_name.startswith('i-') or vm_name.startswith('r-') or vm_name.startswith('l-'): + try: + util.pread2(['iptables', '-F', vmchain_default]) + util.pread2(['iptables', '-X', vmchain_default]) + except: + util.SMlog("Ignoring failure to delete chain " + vmchain_default) + + destroy_ebtables_rules(vmchain) + + try: + util.pread2(['iptables', '-F', vmchain]) + util.pread2(['iptables', '-X', vmchain]) + except: + util.SMlog("Ignoring failure to delete ingress chain " + vmchain) + + + try: + util.pread2(['iptables', '-F', vmchain_egress]) + util.pread2(['iptables', '-X', vmchain_egress]) + except: + util.SMlog("Ignoring failure to delete egress chain " + vmchain_egress) + + remove_rule_log_for_vm(vm_name) + + if 1 in [ vm_name.startswith(c) for c in ['r-', 's-', 'v-', 'l-'] ]: + return 'true' + + try: + setscmd = "ipset --save | grep " + vmchain + " | grep '^-N' | awk '{print $2}'" + setsforvm = util.pread2(['/bin/bash', '-c', setscmd]).split('\n') + for set in setsforvm: + if set != '': + util.pread2(['ipset', '-F', set]) + util.pread2(['ipset', '-X', set]) + except: + util.SMlog("Failed to destroy ipsets for %" % vm_name) + + + return 'true' + +@echo +def destroy_ebtables_rules(vm_chain): + + delcmd = "ebtables-save | grep " + vm_chain + " | sed 's/-A/-D/'" + delcmds = util.pread2(['/bin/bash', '-c', delcmd]).split('\n') + delcmds.pop() + for cmd in delcmds: + try: + dc = cmd.split(' ') + dc.insert(0, 'ebtables') + util.pread2(dc) + except: + util.SMlog("Ignoring failure to delete ebtables rules for vm " + vm_chain) + try: + util.pread2(['ebtables', '-F', vm_chain]) + util.pread2(['ebtables', '-X', vm_chain]) + except: + util.SMlog("Ignoring failure to delete ebtables chain for vm " + vm_chain) + +@echo +def destroy_arptables_rules(vm_chain): + delcmd = "arptables -vL FORWARD | grep " + vm_chain + " | sed 's/-i any//' | sed 's/-o any//' | awk '{print $1,$2,$3,$4}' " + delcmds = util.pread2(['/bin/bash', '-c', delcmd]).split('\n') + delcmds.pop() + for cmd in delcmds: + try: + dc = cmd.split(' ') + dc.insert(0, 'arptables') + dc.insert(1, '-D') + dc.insert(2, 'FORWARD') + util.pread2(dc) + except: + util.SMlog("Ignoring failure to delete arptables rules for vm " + vm_chain) + + try: + util.pread2(['arptables', '-F', vm_chain]) + util.pread2(['arptables', '-X', vm_chain]) + except: + util.SMlog("Ignoring failure to delete arptables chain for vm " + vm_chain) + +@echo +def default_ebtables_antispoof_rules(vm_chain, vifs, vm_ip, vm_mac): + if vm_mac == 'ff:ff:ff:ff:ff:ff': + util.SMlog("Ignoring since mac address is not valid") + return 'true' + + try: + util.pread2(['ebtables', '-N', vm_chain]) + except: + try: + util.pread2(['ebtables', '-F', vm_chain]) + except: + util.SMlog("Failed to create ebtables antispoof chain, skipping") + return 'true' + + # note all rules for packets into the bridge (-i) precede all output rules (-o) + # always start after the first rule in the FORWARD chain that jumps to DEFAULT_EBTABLES chain + try: + for vif in vifs: + util.pread2(['ebtables', '-I', 'FORWARD', '2', '-i', vif, '-j', vm_chain]) + util.pread2(['ebtables', '-A', 'FORWARD', '-o', vif, '-j', vm_chain]) + except: + util.SMlog("Failed to program default ebtables FORWARD rules for %s" % vm_chain) + return 'false' + + try: + for vif in vifs: + # only allow source mac that belongs to the vm + util.pread2(['ebtables', '-A', vm_chain, '-i', vif, '-s', '!', vm_mac, '-j', 'DROP']) + # do not allow fake dhcp responses + util.pread2(['ebtables', '-A', vm_chain, '-i', vif, '-p', 'IPv4', '--ip-proto', 'udp', '--ip-dport', '68', '-j', 'DROP']) + # do not allow snooping of dhcp requests + util.pread2(['ebtables', '-A', vm_chain, '-o', vif, '-p', 'IPv4', '--ip-proto', 'udp', '--ip-dport', '67', '-j', 'DROP']) + except: + util.SMlog("Failed to program default ebtables antispoof rules for %s" % vm_chain) + return 'false' + + return 'true' + +@echo +def default_arp_antispoof(vm_chain, vifs, vm_ip, vm_mac): + if vm_mac == 'ff:ff:ff:ff:ff:ff': + util.SMlog("Ignoring since mac address is not valid") + return 'true' + + try: + util.pread2(['arptables', '-N', vm_chain]) + except: + try: + util.pread2(['arptables', '-F', vm_chain]) + except: + util.SMlog("Failed to create arptables rule, skipping") + return 'true' + + # note all rules for packets into the bridge (-i) precede all output rules (-o) + try: + for vif in vifs: + util.pread2(['arptables', '-I', 'FORWARD', '-i', vif, '-j', vm_chain]) + util.pread2(['arptables', '-A', 'FORWARD', '-o', vif, '-j', vm_chain]) + except: + util.SMlog("Failed to program default arptables rules in FORWARD chain vm=" + vm_chain) + return 'false' + + try: + for vif in vifs: + #accept arp replies into the bridge as long as the source mac and ips match the vm + util.pread2(['arptables', '-A', vm_chain, '-i', vif, '--opcode', 'Reply', '--source-mac', vm_mac, '--source-ip', vm_ip, '-j', 'ACCEPT']) + #accept any arp requests from this vm. In the future this can be restricted to deny attacks on hosts + #also important to restrict source ip and src mac in these requests as they can be used to update arp tables on destination + util.pread2(['arptables', '-A', vm_chain, '-i', vif, '--opcode', 'Request', '--source-mac', vm_mac, '--source-ip', vm_ip, '-j', 'RETURN']) + #accept any arp requests to this vm as long as the request is for this vm's ip + util.pread2(['arptables', '-A', vm_chain, '-o', vif, '--opcode', 'Request', '--destination-ip', vm_ip, '-j', 'ACCEPT']) + #accept any arp replies to this vm as long as the mac and ip matches + util.pread2(['arptables', '-A', vm_chain, '-o', vif, '--opcode', 'Reply', '--destination-mac', vm_mac, '--destination-ip', vm_ip, '-j', 'ACCEPT']) + util.pread2(['arptables', '-A', vm_chain, '-j', 'DROP']) + + except: + util.SMlog("Failed to program default arptables rules") + return 'false' + + return 'true' + +@echo +def default_network_rules_systemvm(session, args): + vm_name = args.pop('vmName') + try: + vm = session.xenapi.VM.get_by_name_label(vm_name) + if len(vm) != 1: + return 'false' + vm_rec = session.xenapi.VM.get_record(vm[0]) + vm_vifs = vm_rec.get('VIFs') + vifnums = [session.xenapi.VIF.get_record(vif).get('device') for vif in vm_vifs] + domid = vm_rec.get('domid') + except: + util.SMlog("### Failed to get domid or vif list for vm ##" + vm_name) + return 'false' + + if domid == '-1': + util.SMlog("### Failed to get domid for vm (-1): " + vm_name) + return 'false' + + vifs = ["vif" + domid + "." + v for v in vifnums] + #vm_name = '-'.join(vm_name.split('-')[:-1]) + vmchain = chain_name(vm_name) + + + delete_rules_for_vm_in_bridge_firewall_chain(vm_name) + + try: + util.pread2(['iptables', '-N', vmchain]) + except: + util.pread2(['iptables', '-F', vmchain]) + + allow_egress_traffic(session) + + for vif in vifs: + try: + util.pread2(['iptables', '-A', 'BRIDGE-FIREWALL', '-m', 'physdev', '--physdev-is-bridged', '--physdev-out', vif, '-j', vmchain]) + util.pread2(['iptables', '-I', 'BRIDGE-FIREWALL', '4', '-m', 'physdev', '--physdev-is-bridged', '--physdev-in', vif, '-j', vmchain]) + util.pread2(['iptables', '-I', vmchain, '-m', 'physdev', '--physdev-is-bridged', '--physdev-in', vif, '-j', 'RETURN']) + except: + util.SMlog("Failed to program default rules") + return 'false' + + + util.pread2(['iptables', '-A', vmchain, '-j', 'ACCEPT']) + + if write_rule_log_for_vm(vm_name, '-1', '_ignore_', domid, '_initial_', '-1') == False: + util.SMlog("Failed to log default network rules for systemvm, ignoring") + return 'true' + + +@echo +def default_network_rules(session, args): + vm_name = args.pop('vmName') + vm_ip = args.pop('vmIP') + vm_id = args.pop('vmID') + vm_mac = args.pop('vmMAC') + + try: + vm = session.xenapi.VM.get_by_name_label(vm_name) + if len(vm) != 1: + util.SMlog("### Failed to get record for vm " + vm_name) + return 'false' + vm_rec = session.xenapi.VM.get_record(vm[0]) + domid = vm_rec.get('domid') + except: + util.SMlog("### Failed to get domid for vm " + vm_name) + return 'false' + if domid == '-1': + util.SMlog("### Failed to get domid for vm (-1): " + vm_name) + return 'false' + + vif = "vif" + domid + ".0" + tap = "tap" + domid + ".0" + vifs = [vif] + try: + util.pread2(['ifconfig', tap]) + vifs.append(tap) + except: + pass + + delete_rules_for_vm_in_bridge_firewall_chain(vm_name) + + + vmchain = chain_name(vm_name) + vmchain_egress = egress_chain_name(vm_name) + vmchain_default = chain_name_def(vm_name) + + destroy_ebtables_rules(vmchain) + + + try: + util.pread2(['iptables', '-N', vmchain]) + except: + util.pread2(['iptables', '-F', vmchain]) + + try: + util.pread2(['iptables', '-N', vmchain_egress]) + except: + util.pread2(['iptables', '-F', vmchain_egress]) + + try: + util.pread2(['iptables', '-N', vmchain_default]) + except: + util.pread2(['iptables', '-F', vmchain_default]) + + try: + for v in vifs: + util.pread2(['iptables', '-A', 'BRIDGE-FIREWALL', '-m', 'physdev', '--physdev-is-bridged', '--physdev-out', v, '-j', vmchain_default]) + util.pread2(['iptables', '-I', 'BRIDGE-FIREWALL', '2', '-m', 'physdev', '--physdev-is-bridged', '--physdev-in', v, '-j', vmchain_default]) + util.pread2(['iptables', '-A', vmchain_default, '-m', 'state', '--state', 'RELATED,ESTABLISHED', '-j', 'ACCEPT']) + #allow dhcp + for v in vifs: + util.pread2(['iptables', '-A', vmchain_default, '-m', 'physdev', '--physdev-is-bridged', '--physdev-in', v, '-p', 'udp', '--dport', '67', '--sport', '68', '-j', 'ACCEPT']) + util.pread2(['iptables', '-A', vmchain_default, '-m', 'physdev', '--physdev-is-bridged', '--physdev-out', v, '-p', 'udp', '--dport', '68', '--sport', '67', '-j', 'ACCEPT']) + + #don't let vm spoof its ip address + for v in vifs: + util.pread2(['iptables', '-A', vmchain_default, '-m', 'physdev', '--physdev-is-bridged', '--physdev-in', v, '--source', vm_ip,'-p', 'udp', '--dport', '53', '-j', 'RETURN']) + util.pread2(['iptables', '-A', vmchain_default, '-m', 'physdev', '--physdev-is-bridged', '--physdev-in', v, '--source', '!', vm_ip, '-j', 'DROP']) + util.pread2(['iptables', '-A', vmchain_default, '-m', 'physdev', '--physdev-is-bridged', '--physdev-out', v, '--destination', '!', vm_ip, '-j', 'DROP']) + util.pread2(['iptables', '-A', vmchain_default, '-m', 'physdev', '--physdev-is-bridged', '--physdev-in', v, '--source', vm_ip, '-j', vmchain_egress]) + + for v in vifs: + util.pread2(['iptables', '-A', vmchain_default, '-m', 'physdev', '--physdev-is-bridged', '--physdev-out', v, '-j', vmchain]) + except: + util.SMlog("Failed to program default rules for vm " + vm_name) + return 'false' + + default_arp_antispoof(vmchain, vifs, vm_ip, vm_mac) + default_ebtables_antispoof_rules(vmchain, vifs, vm_ip, vm_mac) + + if write_rule_log_for_vm(vm_name, vm_id, vm_ip, domid, '_initial_', '-1', vm_mac) == False: + util.SMlog("Failed to log default network rules, ignoring") + + util.SMlog("Programmed default rules for vm " + vm_name) + return 'true' + +@echo +def check_domid_changed(session, vmName): + curr_domid = '-1' + try: + vm = session.xenapi.VM.get_by_name_label(vmName) + if len(vm) != 1: + util.SMlog("### Could not get record for vm ## " + vmName) + else: + vm_rec = session.xenapi.VM.get_record(vm[0]) + curr_domid = vm_rec.get('domid') + except: + util.SMlog("### Failed to get domid for vm ## " + vmName) + + + logfilename = "/var/run/cloud/" + vmName +".log" + if not os.path.exists(logfilename): + return ['-1', curr_domid] + + lines = (line.rstrip() for line in open(logfilename)) + + [_vmName,_vmID,_vmIP,old_domid,_signature,_seqno, _vmMac] = ['_', '-1', '_', '-1', '_', '-1', 'ff:ff:ff:ff:ff:ff'] + for line in lines: + try: + [_vmName,_vmID,_vmIP,old_domid,_signature,_seqno,_vmMac] = line.split(',') + except ValueError,v: + [_vmName,_vmID,_vmIP,old_domid,_signature,_seqno] = line.split(',') + break + + return [curr_domid, old_domid] + +@echo +def delete_rules_for_vm_in_bridge_firewall_chain(vmName): + vm_name = vmName + vmchain = chain_name_def(vm_name) + + delcmd = "iptables-save | grep '\-A BRIDGE-FIREWALL' | grep " + vmchain + " | sed 's/-A/-D/'" + delcmds = util.pread2(['/bin/bash', '-c', delcmd]).split('\n') + delcmds.pop() + for cmd in delcmds: + try: + dc = cmd.split(' ') + dc.insert(0, 'iptables') + dc.pop() + util.pread2(filter(None, dc)) + except: + util.SMlog("Ignoring failure to delete rules for vm " + vmName) + + +@echo +def network_rules_for_rebooted_vm(session, vmName): + vm_name = vmName + [curr_domid, old_domid] = check_domid_changed(session, vm_name) + + if curr_domid == old_domid: + return True + + if old_domid == '-1': + return True + + if curr_domid == '-1': + return True + + util.SMlog("Found a rebooted VM -- reprogramming rules for " + vm_name) + + delete_rules_for_vm_in_bridge_firewall_chain(vm_name) + if 1 in [ vm_name.startswith(c) for c in ['r-', 's-', 'v-', 'l-'] ]: + default_network_rules_systemvm(session, {"vmName":vm_name}) + return True + + vif = "vif" + curr_domid + ".0" + tap = "tap" + curr_domid + ".0" + vifs = [vif] + try: + util.pread2(['ifconfig', tap]) + vifs.append(tap) + except: + pass + vmchain = chain_name(vm_name) + vmchain_default = chain_name_def(vm_name) + + for v in vifs: + util.pread2(['iptables', '-A', 'BRIDGE-FIREWALL', '-m', 'physdev', '--physdev-is-bridged', '--physdev-out', v, '-j', vmchain_default]) + util.pread2(['iptables', '-I', 'BRIDGE-FIREWALL', '2', '-m', 'physdev', '--physdev-is-bridged', '--physdev-in', v, '-j', vmchain_default]) + + #change antispoof rule in vmchain + try: + delcmd = "iptables-save | grep '\-A " + vmchain_default + "' | grep physdev-in | sed 's/-A/-D/'" + delcmd2 = "iptables-save | grep '\-A " + vmchain_default + "' | grep physdev-out | sed 's/-A/-D/'" + inscmd = "iptables-save | grep '\-A " + vmchain_default + "' | grep physdev-in | grep vif | sed -r 's/vif[0-9]+.0/" + vif + "/' " + inscmd2 = "iptables-save| grep '\-A " + vmchain_default + "' | grep physdev-in | grep tap | sed -r 's/tap[0-9]+.0/" + tap + "/' " + inscmd3 = "iptables-save | grep '\-A " + vmchain_default + "' | grep physdev-out | grep vif | sed -r 's/vif[0-9]+.0/" + vif + "/' " + inscmd4 = "iptables-save| grep '\-A " + vmchain_default + "' | grep physdev-out | grep tap | sed -r 's/tap[0-9]+.0/" + tap + "/' " + + ipts = [] + for cmd in [delcmd, delcmd2, inscmd, inscmd2, inscmd3, inscmd4]: + cmds = util.pread2(['/bin/bash', '-c', cmd]).split('\n') + cmds.pop() + for c in cmds: + ipt = c.split(' ') + ipt.insert(0, 'iptables') + ipt.pop() + ipts.append(ipt) + + for ipt in ipts: + try: + util.pread2(filter(None,ipt)) + except: + util.SMlog("Failed to rewrite antispoofing rules for vm " + vm_name) + + util.pread2(['/bin/bash', '-c', 'iptables -D ' + vmchain_default + " -j " + vmchain]) + util.pread2(['/bin/bash', '-c', 'iptables -A ' + vmchain_default + " -j " + vmchain]) + except: + util.SMlog("No rules found for vm " + vm_name) + + destroy_ebtables_rules(vmchain) + destroy_arptables_rules(vmchain) + [vm_ip, vm_mac] = get_vm_mac_ip_from_log(vmchain) + default_arp_antispoof(vmchain, vifs, vm_ip, vm_mac) + default_ebtables_antispoof_rules(vmchain, vifs, vm_ip, vm_mac) + rewrite_rule_log_for_vm(vm_name, curr_domid) + return True + +def rewrite_rule_log_for_vm(vm_name, new_domid): + logfilename = "/var/run/cloud/" + vm_name +".log" + if not os.path.exists(logfilename): + return + lines = (line.rstrip() for line in open(logfilename)) + + [_vmName,_vmID,_vmIP,_domID,_signature,_seqno,_vmMac] = ['_', '-1', '_', '-1', '_', '-1','ff:ff:ff:ff:ff:ff'] + for line in lines: + try: + [_vmName,_vmID,_vmIP,_domID,_signature,_seqno,_vmMac] = line.split(',') + break + except ValueError,v: + [_vmName,_vmID,_vmIP,_domID,_signature,_seqno] = line.split(',') + + write_rule_log_for_vm(_vmName, _vmID, _vmIP, new_domid, _signature, '-1', _vmMac) + +def get_rule_log_for_vm(session, vmName): + vm_name = vmName; + logfilename = "/var/run/cloud/" + vm_name +".log" + if not os.path.exists(logfilename): + return '' + + lines = (line.rstrip() for line in open(logfilename)) + + [_vmName,_vmID,_vmIP,_domID,_signature,_seqno,_vmMac] = ['_', '-1', '_', '-1', '_', '-1', 'ff:ff:ff:ff:ff:ff'] + for line in lines: + try: + [_vmName,_vmID,_vmIP,_domID,_signature,_seqno,_vmMac] = line.split(',') + break + except ValueError,v: + [_vmName,_vmID,_vmIP,_domID,_signature,_seqno] = line.split(',') + + return ','.join([_vmName, _vmID, _vmIP, _domID, _signature, _seqno]) + +@echo +def get_vm_mac_ip_from_log(vm_name): + [_vmName,_vmID,_vmIP,_domID,_signature,_seqno,_vmMac] = ['_', '-1', '0.0.0.0', '-1', '_', '-1','ff:ff:ff:ff:ff:ff'] + logfilename = "/var/run/cloud/" + vm_name +".log" + if not os.path.exists(logfilename): + return ['_', '_'] + + lines = (line.rstrip() for line in open(logfilename)) + for line in lines: + try: + [_vmName,_vmID,_vmIP,_domID,_signature,_seqno,_vmMac] = line.split(',') + break + except ValueError,v: + [_vmName,_vmID,_vmIP,_domID,_signature,_seqno] = line.split(',') + + return [ _vmIP, _vmMac] + +@echo +def get_rule_logs_for_vms(session, args): + host_uuid = args.pop('host_uuid') + try: + thishost = session.xenapi.host.get_by_uuid(host_uuid) + hostrec = session.xenapi.host.get_record(thishost) + vms = hostrec.get('resident_VMs') + except: + util.SMlog("Failed to get host from uuid " + host_uuid) + return ' ' + + result = [] + try: + for name in [session.xenapi.VM.get_name_label(x) for x in vms]: + if 1 not in [ name.startswith(c) for c in ['r-', 's-', 'v-', 'i-', 'l-'] ]: + continue + network_rules_for_rebooted_vm(session, name) + if name.startswith('i-'): + log = get_rule_log_for_vm(session, name) + result.append(log) + except: + util.SMlog("Failed to get rule logs, better luck next time!") + + return ";".join(result) + +@echo +def cleanup_rules_for_dead_vms(session): + try: + vms = session.xenapi.VM.get_all() + cleaned = 0 + for vm_name in [session.xenapi.VM.get_name_label(x) for x in vms]: + if 1 in [ vm_name.startswith(c) for c in ['r-', 'i-', 's-', 'v-', 'l-'] ]: + vm = session.xenapi.VM.get_by_name_label(vm_name) + if len(vm) != 1: + continue + vm_rec = session.xenapi.VM.get_record(vm[0]) + state = vm_rec.get('power_state') + if state != 'Running' and state != 'Paused': + util.SMlog("vm " + vm_name + " is not running, cleaning up") + destroy_network_rules_for_vm(session, {'vmName':vm_name}) + cleaned = cleaned+1 + + util.SMlog("Cleaned up rules for " + str(cleaned) + " vms") + except: + util.SMlog("Failed to cleanup rules for dead vms!") + + +@echo +def cleanup_rules(session, args): + instance = args.get('instance') + if not instance: + instance = 'VM' + resident_vms = [] + try: + hostname = util.pread2(['/bin/bash', '-c', 'hostname']).split('\n') + if len(hostname) < 1: + raise Exception('Could not find hostname of this host') + thishost = session.xenapi.host.get_by_name_label(hostname[0]) + if len(thishost) < 1: + raise Exception("Could not find host record from hostname %s of this host"%hostname[0]) + hostrec = session.xenapi.host.get_record(thishost[0]) + vms = hostrec.get('resident_VMs') + resident_vms = [session.xenapi.VM.get_name_label(x) for x in vms] + util.SMlog('cleanup_rules: found %s resident vms on this host %s' % (len(resident_vms)-1, hostname[0])) + + chainscmd = "iptables-save | grep '^:' | awk '{print $1}' | cut -d':' -f2 | sed 's/-def/-%s/'| sed 's/-eg//' | sort|uniq" % instance + chains = util.pread2(['/bin/bash', '-c', chainscmd]).split('\n') + vmchains = [ch for ch in chains if 1 in [ ch.startswith(c) for c in ['r-', 'i-', 's-', 'v-', 'l-']]] + util.SMlog('cleanup_rules: found %s iptables chains for vms on this host %s' % (len(vmchains), hostname[0])) + cleaned = 0 + cleanup = [] + for chain in vmchains: + vm = session.xenapi.VM.get_by_name_label(chain) + if len(vm) != 1: + vm = session.xenapi.VM.get_by_name_label(chain + "-untagged") + if len(vm) != 1: + util.SMlog("chain " + chain + " does not correspond to a vm, cleaning up") + cleanup.append(chain) + continue + if chain not in resident_vms: + util.SMlog("vm " + chain + " is not running, cleaning up") + cleanup.append(chain) + + for vm_name in cleanup: + destroy_network_rules_for_vm(session, {'vmName':vm_name}) + + util.SMlog("Cleaned up rules for " + str(len(cleanup)) + " chains") + return str(len(cleanup)) + except Exception, ex: + util.SMlog("Failed to cleanup rules, reason= " + str(ex)) + return '-1'; + +@echo +def check_rule_log_for_vm(vmName, vmID, vmIP, domID, signature, seqno): + vm_name = vmName; + logfilename = "/var/run/cloud/" + vm_name +".log" + if not os.path.exists(logfilename): + util.SMlog("Failed to find logfile %s" %logfilename) + return [True, True, True] + + lines = (line.rstrip() for line in open(logfilename)) + + [_vmName,_vmID,_vmIP,_domID,_signature,_seqno,_vmMac] = ['_', '-1', '_', '-1', '_', '-1', 'ff:ff:ff:ff:ff:ff'] + try: + for line in lines: + try: + [_vmName,_vmID,_vmIP,_domID,_signature,_seqno, _vmMac] = line.split(',') + except ValueError,v: + [_vmName,_vmID,_vmIP,_domID,_signature,_seqno] = line.split(',') + break + except: + util.SMlog("Failed to parse log file for vm " + vmName) + remove_rule_log_for_vm(vmName) + return [True, True, True] + + reprogramDefault = False + if (domID != _domID) or (vmID != _vmID) or (vmIP != _vmIP): + util.SMlog("Change in default info set of vm %s" % vmName) + return [True, True, True] + else: + util.SMlog("No change in default info set of vm %s" % vmName) + + reprogramChain = False + rewriteLog = True + if (int(seqno) > int(_seqno)): + if (_signature != signature): + reprogramChain = True + util.SMlog("Seqno increased from %s to %s: reprogamming "\ + "ingress rules for vm %s" % (_seqno, seqno, vmName)) + else: + util.SMlog("Seqno increased from %s to %s: but no change "\ + "in signature for vm: skip programming ingress "\ + "rules %s" % (_seqno, seqno, vmName)) + elif (int(seqno) < int(_seqno)): + util.SMlog("Seqno decreased from %s to %s: ignoring these "\ + "ingress rules for vm %s" % (_seqno, seqno, vmName)) + rewriteLog = False + elif (signature != _signature): + util.SMlog("Seqno %s stayed the same but signature changed from "\ + "%s to %s for vm %s" % (seqno, _signature, signature, vmName)) + rewriteLog = True + reprogramChain = True + else: + util.SMlog("Seqno and signature stayed the same: %s : ignoring these "\ + "ingress rules for vm %s" % (seqno, vmName)) + rewriteLog = False + + return [reprogramDefault, reprogramChain, rewriteLog] + + +@echo +def write_rule_log_for_vm(vmName, vmID, vmIP, domID, signature, seqno, vmMac='ff:ff:ff:ff:ff:ff'): + vm_name = vmName + logfilename = "/var/run/cloud/" + vm_name +".log" + util.SMlog("Writing log to " + logfilename) + logf = open(logfilename, 'w') + output = ','.join([vmName, vmID, vmIP, domID, signature, seqno, vmMac]) + result = True + try: + logf.write(output) + logf.write('\n') + except: + util.SMlog("Failed to write to rule log file " + logfilename) + result = False + + logf.close() + + return result + +@echo +def remove_rule_log_for_vm(vmName): + vm_name = vmName + logfilename = "/var/run/cloud/" + vm_name +".log" + + result = True + try: + os.remove(logfilename) + except: + util.SMlog("Failed to delete rule log file " + logfilename) + result = False + + return result + +@echo +def inflate_rules (zipped): + return zlib.decompress(base64.b64decode(zipped)) + +@echo +def cache_ipset_keyword(): + tmpname = 'ipsetqzvxtmp' + try: + util.pread2(['/bin/bash', '-c', 'ipset -N ' + tmpname + ' iptreemap']) + except: + util.pread2(['/bin/bash', '-c', 'ipset -F ' + tmpname]) + + try: + util.pread2(['/bin/bash', '-c', 'iptables -A INPUT -m set --set ' + tmpname + ' src' + ' -j ACCEPT']) + util.pread2(['/bin/bash', '-c', 'iptables -D INPUT -m set --set ' + tmpname + ' src' + ' -j ACCEPT']) + keyword = 'set' + except: + keyword = 'match-set' + + try: + util.pread2(['/bin/bash', '-c', 'ipset -X ' + tmpname]) + except: + pass + + cachefile = "/var/cache/cloud/ipset.keyword" + util.SMlog("Writing ipset keyword to " + cachefile) + cachef = open(cachefile, 'w') + try: + cachef.write(keyword) + cachef.write('\n') + except: + util.SMlog("Failed to write to cache file " + cachef) + + cachef.close() + return keyword + +@echo +def get_ipset_keyword(): + cachefile = "/var/cache/cloud/ipset.keyword" + keyword = 'match-set' + + if not os.path.exists(cachefile): + util.SMlog("Failed to find ipset keyword cachefile %s" %cachefile) + keyword = cache_ipset_keyword() + else: + lines = (line.rstrip() for line in open(cachefile)) + for line in lines: + keyword = line + break + + return keyword + +@echo +def network_rules(session, args): + try: + vm_name = args.get('vmName') + vm_ip = args.get('vmIP') + vm_id = args.get('vmID') + vm_mac = args.get('vmMAC') + signature = args.pop('signature') + seqno = args.pop('seqno') + deflated = 'false' + if 'deflated' in args: + deflated = args.pop('deflated') + + try: + vm = session.xenapi.VM.get_by_name_label(vm_name) + if len(vm) != 1: + util.SMlog("### Could not get record for vm ## " + vm_name) + return 'false' + vm_rec = session.xenapi.VM.get_record(vm[0]) + domid = vm_rec.get('domid') + except: + util.SMlog("### Failed to get domid for vm ## " + vm_name) + return 'false' + if domid == '-1': + util.SMlog("### Failed to get domid for vm (-1): " + vm_name) + return 'false' + + vif = "vif" + domid + ".0" + tap = "tap" + domid + ".0" + vifs = [vif] + try: + util.pread2(['ifconfig', tap]) + vifs.append(tap) + except: + pass + + + reason = 'seqno_change_or_sig_change' + [reprogramDefault, reprogramChain, rewriteLog] = \ + check_rule_log_for_vm (vm_name, vm_id, vm_ip, domid, signature, seqno) + + if not reprogramDefault and not reprogramChain: + util.SMlog("No changes detected between current state and received state") + reason = 'seqno_same_sig_same' + if rewriteLog: + reason = 'seqno_increased_sig_same' + write_rule_log_for_vm(vm_name, vm_id, vm_ip, domid, signature, seqno, vm_mac) + util.SMlog("Programming network rules for vm %s seqno=%s signature=%s guestIp=%s,"\ + " do nothing, reason=%s" % (vm_name, seqno, signature, vm_ip, reason)) + return 'true' + + if not reprogramChain: + util.SMlog("###Not programming any ingress rules since no changes detected?") + return 'true' + + if reprogramDefault: + util.SMlog("Change detected in vmId or vmIp or domId, resetting default rules") + default_network_rules(session, args) + reason = 'domid_change' + + rules = args.pop('rules') + if deflated.lower() == 'true': + rules = inflate_rules (rules) + keyword = '--' + get_ipset_keyword() + lines = rules.split(' ') + + util.SMlog("Programming network rules for vm %s seqno=%s numrules=%s signature=%s guestIp=%s,"\ + " update iptables, reason=%s" % (vm_name, seqno, len(lines), signature, vm_ip, reason)) + + cmds = [] + egressrules = 0 + for line in lines: + tokens = line.split(':') + if len(tokens) != 5: + continue + type = tokens[0] + protocol = tokens[1] + start = tokens[2] + end = tokens[3] + cidrs = tokens.pop(); + ips = cidrs.split(",") + ips.pop() + allow_any = False + + if type == 'E': + vmchain = egress_chain_name(vm_name) + action = "RETURN" + direction = "dst" + egressrules = egressrules + 1 + else: + vmchain = chain_name(vm_name) + action = "ACCEPT" + direction = "src" + if '0.0.0.0/0' in ips: + i = ips.index('0.0.0.0/0') + del ips[i] + allow_any = True + range = start + ":" + end + if ips: + ipsetname = vmchain + "_" + protocol + "_" + start + "_" + end + if start == "-1": + ipsetname = vmchain + "_" + protocol + "_any" + + if ipset(ipsetname, protocol, start, end, ips) == False: + util.SMlog(" failed to create ipset for rule " + str(tokens)) + + if protocol == 'all': + iptables = ['iptables', '-I', vmchain, '-m', 'state', '--state', 'NEW', '-m', 'set', keyword, ipsetname, direction, '-j', action] + elif protocol != 'icmp': + iptables = ['iptables', '-I', vmchain, '-p', protocol, '-m', protocol, '--dport', range, '-m', 'state', '--state', 'NEW', '-m', 'set', keyword, ipsetname, direction, '-j', action] + else: + range = start + "/" + end + if start == "-1": + range = "any" + iptables = ['iptables', '-I', vmchain, '-p', 'icmp', '--icmp-type', range, '-m', 'set', keyword, ipsetname, direction, '-j', action] + + cmds.append(iptables) + util.SMlog(iptables) + + if allow_any and protocol != 'all': + if protocol != 'icmp': + iptables = ['iptables', '-I', vmchain, '-p', protocol, '-m', protocol, '--dport', range, '-m', 'state', '--state', 'NEW', '-j', action] + else: + range = start + "/" + end + if start == "-1": + range = "any" + iptables = ['iptables', '-I', vmchain, '-p', 'icmp', '--icmp-type', range, '-j', action] + cmds.append(iptables) + util.SMlog(iptables) + + vmchain = chain_name(vm_name) + util.pread2(['iptables', '-F', vmchain]) + egress_vmchain = egress_chain_name(vm_name) + util.pread2(['iptables', '-F', egress_vmchain]) + + for cmd in cmds: + util.pread2(cmd) + + if egressrules == 0 : + util.pread2(['iptables', '-A', egress_vmchain, '-j', 'RETURN']) + else: + util.pread2(['iptables', '-A', egress_vmchain, '-j', 'DROP']) + + util.pread2(['iptables', '-A', vmchain, '-j', 'DROP']) + + if write_rule_log_for_vm(vm_name, vm_id, vm_ip, domid, signature, seqno, vm_mac) == False: + return 'false' + + return 'true' + except: + util.SMlog("Failed to network rule !") + +@echo +def checkRouter(session, args): + sargs = args['args'] + cmd = sargs.split(' ') + cmd.insert(0, "/opt/cloud/bin/getRouterStatus.sh") + cmd.insert(0, "/bin/bash") + try: + txt = util.pread2(cmd) + except: + util.SMlog(" check router status fail! ") + txt = '' + + return txt + +@echo +def bumpUpPriority(session, args): + sargs = args['args'] + cmd = sargs.split(' ') + cmd.insert(0, "/opt/cloud/bin/bumpUpPriority.sh") + cmd.insert(0, "/bin/bash") + try: + txt = util.pread2(cmd) + txt = 'success' + except: + util.SMlog("bump up priority fail! ") + txt = '' + + return txt + +@echo +def setDNATRule(session, args): + add = args["add"] + if add == "false": + util.pread2(["iptables", "-t", "nat", "-F"]) + else: + ip = args["ip"] + port = args["port"] + util.pread2(["iptables", "-t", "nat", "-F"]) + util.pread2(["iptables", "-t", "nat", "-A", "PREROUTING", "-i", "xenbr0", "-p", "tcp", "--dport", port, "-m", "state", "--state", "NEW", "-j", "DNAT", "--to-destination", ip +":443"]) + return "" + +@echo +def createISOVHD(session, args): + # Should not create the VDI if the systemvm.iso does not exist + if not os.path.exists('/usr/share/xcp/packages/iso/systemvm.iso'): + return "Failed" + #hack for XCP on ubuntu 12.04, as can't attach iso to a vm + vdis = session.xenapi.VDI.get_by_name_label("systemvm-vdi"); + util.SMlog(vdis) + if len(vdis) > 0: + vdi_record = session.xenapi.VDI.get_record(vdis[0]) + vdi_uuid = vdi_record['uuid'] + return vdi_uuid + localsrUUid = args['uuid']; + sr = session.xenapi.SR.get_by_uuid(localsrUUid) + data = {'name_label': "systemvm-vdi", + 'SR': sr, + 'virtual_size': '50000000', + 'type': 'user', + 'sharable':False, + 'read_only':False, + 'other_config':{}, + } + vdi = session.xenapi.VDI.create(data); + vdi_record = session.xenapi.VDI.get_record(vdi) + + vdi_uuid = vdi_record['uuid'] + + vms = session.xenapi.VM.get_all() + ctrldom = None + for vm in vms: + dom0 = session.xenapi.VM.get_is_control_domain(vm) + if dom0 is False: + continue + else: + ctrldom = vm + + if ctrldom is None: + return "Failed" + + vbds = session.xenapi.VM.get_VBDs(ctrldom) + if len(vbds) == 0: + vbd = session.xenapi.VBD.create({"VDI": vdi, "VM": ctrldom, "type":"Disk", "device": "xvda4", "bootable": False, "mode": "RW", "userdevice": "4", "empty":False, + "other_config":{}, "qos_algorithm_type":"", "qos_algorithm_params":{}}) + else: + vbd = vbds[0] + + vbdr = session.xenapi.VBD.get_record(vbd) + if session.xenapi.VBD.get_currently_attached(vbd) is False: + session.xenapi.VBD.plug(vbd) + vbdr = session.xenapi.VBD.get_record(vbd) + util.pread2(["dd", "if=/usr/share/xcp/packages/iso/systemvm.iso", "of=" + "/dev/" + vbdr["device"]]) + session.xenapi.VBD.unplug(vbd) + session.xenapi.VBD.destroy(vbd) + return vdi_uuid + +@echo +def getDomRVersion(session, args): + sargs = args['args'] + cmd = sargs.split(' ') + cmd.insert(0, "/opt/cloud/bin/getDomRVersion.sh") + cmd.insert(0, "/bin/bash") + try: + txt = util.pread2(cmd) + except: + util.SMlog(" get domR version fail! ") + txt = '' + + return txt + +if __name__ == "__main__": + XenAPIPlugin.dispatch({"pingtest": pingtest, "setup_iscsi":setup_iscsi, "gethostvmstats": gethostvmstats, + "getgateway": getgateway, "preparemigration": preparemigration, + "setIptables": setIptables, "pingdomr": pingdomr, "pingxenserver": pingxenserver, + "ipassoc": ipassoc, "savePassword": savePassword, + "saveDhcpEntry": saveDhcpEntry, "setFirewallRule": setFirewallRule, + "setLoadBalancerRule": setLoadBalancerRule, "createFile": createFile, "deleteFile": deleteFile, + "networkUsage": networkUsage, "network_rules":network_rules, + "can_bridge_firewall":can_bridge_firewall, "default_network_rules":default_network_rules, + "destroy_network_rules_for_vm":destroy_network_rules_for_vm, + "default_network_rules_systemvm":default_network_rules_systemvm, + "get_rule_logs_for_vms":get_rule_logs_for_vms, + "setLinkLocalIP":setLinkLocalIP, "lt2p_vpn":lt2p_vpn, + "cleanup_rules":cleanup_rules, "checkRouter":checkRouter, + "bumpUpPriority":bumpUpPriority, "getDomRVersion":getDomRVersion, + "kill_copy_process":kill_copy_process, + "createISOVHD":createISOVHD, + "setDNATRule":setDNATRule}) diff --git a/scripts/vm/hypervisor/xenserver/xcposs/vmopsSnapshot b/scripts/vm/hypervisor/xenserver/xcposs/vmopsSnapshot new file mode 100644 index 0000000000..53f31a99ee --- /dev/null +++ b/scripts/vm/hypervisor/xenserver/xcposs/vmopsSnapshot @@ -0,0 +1,601 @@ +#!/usr/bin/python +# 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. + +# Version @VERSION@ +# +# A plugin for executing script needed by vmops cloud + +import os, sys, time +import XenAPIPlugin +sys.path.append("/usr/lib/xcp/sm/") +import SR, VDI, SRCommand, util, lvutil +from util import CommandException +import vhdutil +import shutil +import lvhdutil +import errno +import subprocess +import xs_errors +import cleanup +import stat +import random + +VHD_UTIL = 'vhd-util' +VHD_PREFIX = 'VHD-' +CLOUD_DIR = '/run/cloud_mount' + +def echo(fn): + def wrapped(*v, **k): + name = fn.__name__ + util.SMlog("#### VMOPS enter %s ####" % name ) + res = fn(*v, **k) + util.SMlog("#### VMOPS exit %s ####" % name ) + return res + return wrapped + + +@echo +def create_secondary_storage_folder(session, args): + local_mount_path = None + + util.SMlog("create_secondary_storage_folder, args: " + str(args)) + + try: + try: + # Mount the remote resource folder locally + remote_mount_path = args["remoteMountPath"] + local_mount_path = os.path.join(CLOUD_DIR, util.gen_uuid()) + mount(remote_mount_path, local_mount_path) + + # Create the new folder + new_folder = local_mount_path + "/" + args["newFolder"] + if not os.path.isdir(new_folder): + current_umask = os.umask(0) + os.makedirs(new_folder) + os.umask(current_umask) + except OSError, (errno, strerror): + errMsg = "create_secondary_storage_folder failed: errno: " + str(errno) + ", strerr: " + strerror + util.SMlog(errMsg) + raise xs_errors.XenError(errMsg) + except: + errMsg = "create_secondary_storage_folder failed." + util.SMlog(errMsg) + raise xs_errors.XenError(errMsg) + finally: + if local_mount_path != None: + # Unmount the local folder + umount(local_mount_path) + # Remove the local folder + os.system("rmdir " + local_mount_path) + + return "1" + +@echo +def delete_secondary_storage_folder(session, args): + local_mount_path = None + + util.SMlog("delete_secondary_storage_folder, args: " + str(args)) + + try: + try: + # Mount the remote resource folder locally + remote_mount_path = args["remoteMountPath"] + local_mount_path = os.path.join(CLOUD_DIR, util.gen_uuid()) + mount(remote_mount_path, local_mount_path) + + # Delete the specified folder + folder = local_mount_path + "/" + args["folder"] + if os.path.isdir(folder): + os.system("rm -f " + folder + "/*") + os.system("rmdir " + folder) + except OSError, (errno, strerror): + errMsg = "delete_secondary_storage_folder failed: errno: " + str(errno) + ", strerr: " + strerror + util.SMlog(errMsg) + raise xs_errors.XenError(errMsg) + except: + errMsg = "delete_secondary_storage_folder failed." + util.SMlog(errMsg) + raise xs_errors.XenError(errMsg) + finally: + if local_mount_path != None: + # Unmount the local folder + umount(local_mount_path) + # Remove the local folder + os.system("rmdir " + local_mount_path) + + return "1" + +@echo +def post_create_private_template(session, args): + local_mount_path = None + try: + try: + # get local template folder + templatePath = args["templatePath"] + local_mount_path = os.path.join(CLOUD_DIR, util.gen_uuid()) + mount(templatePath, local_mount_path) + # Retrieve args + filename = args["templateFilename"] + name = args["templateName"] + description = args["templateDescription"] + checksum = args["checksum"] + file_size = args["size"] + virtual_size = args["virtualSize"] + template_id = args["templateId"] + + # Create the template.properties file + template_properties_install_path = local_mount_path + "/template.properties" + f = open(template_properties_install_path, "w") + f.write("filename=" + filename + "\n") + f.write("vhd=true\n") + f.write("id=" + template_id + "\n") + f.write("vhd.filename=" + filename + "\n") + f.write("public=false\n") + f.write("uniquename=" + name + "\n") + f.write("vhd.virtualsize=" + virtual_size + "\n") + f.write("virtualsize=" + virtual_size + "\n") + f.write("checksum=" + checksum + "\n") + f.write("hvm=true\n") + f.write("description=" + description + "\n") + f.write("vhd.size=" + str(file_size) + "\n") + f.write("size=" + str(file_size) + "\n") + f.close() + util.SMlog("Created template.properties file") + + # Set permissions + permissions = stat.S_IREAD | stat.S_IWRITE | stat.S_IRGRP | stat.S_IWGRP | stat.S_IROTH | stat.S_IWOTH + os.chmod(template_properties_install_path, permissions) + util.SMlog("Set permissions on template and template.properties") + + except: + errMsg = "post_create_private_template failed." + util.SMlog(errMsg) + raise xs_errors.XenError(errMsg) + + finally: + if local_mount_path != None: + # Unmount the local folder + umount(local_mount_path) + # Remove the local folder + os.system("rmdir " + local_mount_path) + return "1" + +def isfile(path, isISCSI): + errMsg = '' + exists = True + if isISCSI: + exists = checkVolumeAvailablility(path) + else: + exists = os.path.isfile(path) + + if not exists: + errMsg = "File " + path + " does not exist." + util.SMlog(errMsg) + raise xs_errors.XenError(errMsg) + return errMsg + +def copyfile(fromFile, toFile, isISCSI): + util.SMlog("Starting to copy " + fromFile + " to " + toFile) + errMsg = '' + try: + cmd = ['dd', 'if=' + fromFile, 'of=' + toFile, 'bs=4M'] + txt = util.pread2(cmd) + except: + try: + os.system("rm -f " + toFile) + except: + txt = '' + txt = '' + errMsg = "Error while copying " + fromFile + " to " + toFile + " in secondary storage" + util.SMlog(errMsg) + raise xs_errors.XenError(errMsg) + + util.SMlog("Successfully copied " + fromFile + " to " + toFile) + return errMsg + +def chdir(path): + try: + os.chdir(path) + except OSError, (errno, strerror): + errMsg = "Unable to chdir to " + path + " because of OSError with errno: " + str(errno) + " and strerr: " + strerror + util.SMlog(errMsg) + raise xs_errors.XenError(errMsg) + util.SMlog("Chdired to " + path) + return + +def scanParent(path): + # Do a scan for the parent for ISCSI volumes + # Note that the parent need not be visible on the XenServer + parentUUID = '' + try: + lvName = os.path.basename(path) + dirname = os.path.dirname(path) + vgName = os.path.basename(dirname) + vhdInfo = vhdutil.getVHDInfoLVM(lvName, lvhdutil.extractUuid, vgName) + parentUUID = vhdInfo.parentUuid + except: + errMsg = "Could not get vhd parent of " + path + util.SMlog(errMsg) + raise xs_errors.XenError(errMsg) + return parentUUID + +def getParent(path, isISCSI): + parentUUID = '' + try : + if isISCSI: + parentUUID = vhdutil.getParent(path, lvhdutil.extractUuid) + else: + parentUUID = vhdutil.getParent(path, cleanup.FileVDI.extractUuid) + except: + errMsg = "Could not get vhd parent of " + path + util.SMlog(errMsg) + raise xs_errors.XenError(errMsg) + return parentUUID + +def getParentOfSnapshot(snapshotUuid, primarySRPath, isISCSI): + snapshotVHD = getVHD(snapshotUuid, isISCSI) + snapshotPath = os.path.join(primarySRPath, snapshotVHD) + + baseCopyUuid = '' + if isISCSI: + checkVolumeAvailablility(snapshotPath) + baseCopyUuid = scanParent(snapshotPath) + else: + baseCopyUuid = getParent(snapshotPath, isISCSI) + + util.SMlog("Base copy of snapshotUuid: " + snapshotUuid + " is " + baseCopyUuid) + return baseCopyUuid + +def setParent(parent, child): + try: + cmd = [VHD_UTIL, "modify", "-p", parent, "-n", child] + txt = util.pread2(cmd) + except: + errMsg = "Unexpected error while trying to set parent of " + child + " to " + parent + util.SMlog(errMsg) + raise xs_errors.XenError(errMsg) + util.SMlog("Successfully set parent of " + child + " to " + parent) + return + +def rename(originalVHD, newVHD): + try: + os.rename(originalVHD, newVHD) + except OSError, (errno, strerror): + errMsg = "OSError while renaming " + origiinalVHD + " to " + newVHD + "with errno: " + str(errno) + " and strerr: " + strerror + util.SMlog(errMsg) + raise xs_errors.XenError(errMsg) + return + +def makedirs(path): + if not os.path.isdir(path): + try: + os.makedirs(path) + except OSError, (errno, strerror): + umount(path) + if os.path.isdir(path): + return + errMsg = "OSError while creating " + path + " with errno: " + str(errno) + " and strerr: " + strerror + util.SMlog(errMsg) + raise xs_errors.XenError(errMsg) + return + +def mount(remoteDir, localDir): + makedirs(localDir) + options = "soft,tcp,timeo=133,retrans=1" + try: + cmd = ['mount', '-o', options, remoteDir, localDir] + txt = util.pread2(cmd) + except: + txt = '' + errMsg = "Unexpected error while trying to mount " + remoteDir + " to " + localDir + util.SMlog(errMsg) + raise xs_errors.XenError(errMsg) + util.SMlog("Successfully mounted " + remoteDir + " to " + localDir) + + return + +def umount(localDir): + try: + cmd = ['umount', localDir] + util.pread2(cmd) + except CommandException: + errMsg = "CommandException raised while trying to umount " + localDir + util.SMlog(errMsg) + raise xs_errors.XenError(errMsg) + + util.SMlog("Successfully unmounted " + localDir) + return + +def mountSnapshotsDir(secondaryStorageMountPath, localMountPointPath, path): + # The aim is to mount secondaryStorageMountPath on + # And create / dir on it, if it doesn't exist already. + # Assuming that secondaryStorageMountPath exists remotely + + # Just mount secondaryStorageMountPath//SecondaryStorageHost/ everytime + # Never unmount. + # path is like "snapshots/account/volumeId", we mount secondary_storage:/snapshots + relativeDir = path.split("/")[0] + restDir = "/".join(path.split("/")[1:]) + snapshotsDir = os.path.join(secondaryStorageMountPath, relativeDir) + + makedirs(localMountPointPath) + # if something is not mounted already on localMountPointPath, + # mount secondaryStorageMountPath on localMountPath + if os.path.ismount(localMountPointPath): + # There is more than one secondary storage per zone. + # And we are mounting each sec storage under a zone-specific directory + # So two secondary storage snapshot dirs will never get mounted on the same point on the same XenServer. + util.SMlog("The remote snapshots directory has already been mounted on " + localMountPointPath) + else: + mount(snapshotsDir, localMountPointPath) + + # Create accountId/instanceId dir on localMountPointPath, if it doesn't exist + backupsDir = os.path.join(localMountPointPath, restDir) + makedirs(backupsDir) + return backupsDir + +def unmountAll(path): + try: + for dir in os.listdir(path): + if dir.isdigit(): + util.SMlog("Unmounting Sub-Directory: " + dir) + localMountPointPath = os.path.join(path, dir) + umount(localMountPointPath) + except: + util.SMlog("Ignoring the error while trying to unmount the snapshots dir") + +@echo +def unmountSnapshotsDir(session, args): + dcId = args['dcId'] + localMountPointPath = os.path.join(CLOUD_DIR, dcId) + localMountPointPath = os.path.join(localMountPointPath, "snapshots") + unmountAll(localMountPointPath) + try: + umount(localMountPointPath) + except: + util.SMlog("Ignoring the error while trying to unmount the snapshots dir.") + + return "1" + +def getPrimarySRPath(session, primaryStorageSRUuid, isISCSI): + sr = session.xenapi.SR.get_by_uuid(primaryStorageSRUuid) + srrec = session.xenapi.SR.get_record(sr) + srtype = srrec["type"] + if srtype == "file": + pbd = session.xenapi.SR.get_PBDs(sr)[0] + pbdrec = session.xenapi.PBD.get_record(pbd) + primarySRPath = pbdrec["device_config"]["location"] + return primarySRPath + elif isISCSI: + primarySRDir = lvhdutil.VG_PREFIX + primaryStorageSRUuid + return os.path.join(lvhdutil.VG_LOCATION, primarySRDir) + else: + return os.path.join(SR.MOUNT_BASE, primaryStorageSRUuid) + +def getBackupVHD(UUID): + return UUID + '.' + SR.DEFAULT_TAP + +def getVHD(UUID, isISCSI): + if isISCSI: + return VHD_PREFIX + UUID + else: + return UUID + '.' + SR.DEFAULT_TAP + +def getIsTrueString(stringValue): + booleanValue = False + if (stringValue and stringValue == 'true'): + booleanValue = True + return booleanValue + +def makeUnavailable(uuid, primarySRPath, isISCSI): + if not isISCSI: + return + VHD = getVHD(uuid, isISCSI) + path = os.path.join(primarySRPath, VHD) + manageAvailability(path, '-an') + return + +def manageAvailability(path, value): + if path.__contains__("/var/run/sr-mount"): + return + util.SMlog("Setting availability of " + path + " to " + value) + try: + cmd = ['/usr/sbin/lvchange', value, path] + util.pread2(cmd) + except: #CommandException, (rc, cmdListStr, stderr): + #errMsg = "CommandException thrown while executing: " + cmdListStr + " with return code: " + str(rc) + " and stderr: " + stderr + errMsg = "Unexpected exception thrown by lvchange" + util.SMlog(errMsg) + if value == "-ay": + # Raise an error only if we are trying to make it available. + # Just warn if we are trying to make it unavailable after the + # snapshot operation is done. + raise xs_errors.XenError(errMsg) + return + + +def checkVolumeAvailablility(path): + try: + if not isVolumeAvailable(path): + # The VHD file is not available on XenSever. The volume is probably + # inactive or detached. + # Do lvchange -ay to make it available on XenServer + manageAvailability(path, '-ay') + except: + errMsg = "Could not determine status of ISCSI path: " + path + util.SMlog(errMsg) + raise xs_errors.XenError(errMsg) + + success = False + i = 0 + while i < 6: + i = i + 1 + # Check if the vhd is actually visible by checking for the link + # set isISCSI to true + success = isVolumeAvailable(path) + if success: + util.SMlog("Made vhd: " + path + " available and confirmed that it is visible") + break + + # Sleep for 10 seconds before checking again. + time.sleep(10) + + # If not visible within 1 min fail + if not success: + util.SMlog("Could not make vhd: " + path + " available despite waiting for 1 minute. Does it exist?") + + return success + +def isVolumeAvailable(path): + # Check if iscsi volume is available on this XenServer. + status = "0" + try: + p = subprocess.Popen(["/bin/bash", "-c", "if [ -L " + path + " ]; then echo 1; else echo 0;fi"], stdout=subprocess.PIPE) + status = p.communicate()[0].strip("\n") + except: + errMsg = "Could not determine status of ISCSI path: " + path + util.SMlog(errMsg) + raise xs_errors.XenError(errMsg) + + return (status == "1") + +def getVhdParent(session, args): + util.SMlog("getParent with " + str(args)) + primaryStorageSRUuid = args['primaryStorageSRUuid'] + snapshotUuid = args['snapshotUuid'] + isISCSI = getIsTrueString(args['isISCSI']) + + primarySRPath = getPrimarySRPath(session, primaryStorageSRUuid, isISCSI) + util.SMlog("primarySRPath: " + primarySRPath) + + baseCopyUuid = getParentOfSnapshot(snapshotUuid, primarySRPath, isISCSI) + + return baseCopyUuid + + +def backupSnapshot(session, args): + util.SMlog("Called backupSnapshot with " + str(args)) + primaryStorageSRUuid = args['primaryStorageSRUuid'] + secondaryStorageMountPath = args['secondaryStorageMountPath'] + snapshotUuid = args['snapshotUuid'] + prevBackupUuid = args['prevBackupUuid'] + backupUuid = args['backupUuid'] + isISCSI = getIsTrueString(args['isISCSI']) + path = args['path'] + localMountPoint = args['localMountPoint'] + primarySRPath = getPrimarySRPath(session, primaryStorageSRUuid, isISCSI) + util.SMlog("primarySRPath: " + primarySRPath) + + baseCopyUuid = getParentOfSnapshot(snapshotUuid, primarySRPath, isISCSI) + baseCopyVHD = getVHD(baseCopyUuid, isISCSI) + baseCopyPath = os.path.join(primarySRPath, baseCopyVHD) + util.SMlog("Base copy path: " + baseCopyPath) + + + # Mount secondary storage mount path on XenServer along the path + # /var/run/sr-mount//snapshots/ and create / dir + # on it. + backupsDir = mountSnapshotsDir(secondaryStorageMountPath, localMountPoint, path) + util.SMlog("Backups dir " + backupsDir) + prevBackupUuid = prevBackupUuid.split("/")[-1] + # Check existence of snapshot on primary storage + isfile(baseCopyPath, isISCSI) + if prevBackupUuid: + # Check existence of prevBackupFile + prevBackupVHD = getBackupVHD(prevBackupUuid) + prevBackupFile = os.path.join(backupsDir, prevBackupVHD) + isfile(prevBackupFile, False) + + # copy baseCopyPath to backupsDir with new uuid + backupVHD = getBackupVHD(backupUuid) + backupFile = os.path.join(backupsDir, backupVHD) + util.SMlog("Back up " + baseCopyUuid + " to Secondary Storage as " + backupUuid) + copyfile(baseCopyPath, backupFile, isISCSI) + vhdutil.setHidden(backupFile, False) + + # Because the primary storage is always scanned, the parent of this base copy is always the first base copy. + # We don't want that, we want a chain of VHDs each of which is a delta from the previous. + # So set the parent of the current baseCopyVHD to prevBackupVHD + if prevBackupUuid: + # If there was a previous snapshot + setParent(prevBackupFile, backupFile) + + txt = "1#" + backupUuid + return txt + +@echo +def deleteSnapshotBackup(session, args): + util.SMlog("Calling deleteSnapshotBackup with " + str(args)) + secondaryStorageMountPath = args['secondaryStorageMountPath'] + backupUUID = args['backupUUID'] + path = args['path'] + localMountPoint = args['localMountPoint'] + + backupsDir = mountSnapshotsDir(secondaryStorageMountPath, localMountPoint, path) + # chdir to the backupsDir for convenience + chdir(backupsDir) + + backupVHD = getBackupVHD(backupUUID) + util.SMlog("checking existence of " + backupVHD) + + # The backupVHD is on secondary which is NFS and not ISCSI. + if not os.path.isfile(backupVHD): + util.SMlog("backupVHD " + backupVHD + "does not exist. Not trying to delete it") + return "1" + util.SMlog("backupVHD " + backupVHD + " exists.") + + # Just delete the backupVHD + try: + os.remove(backupVHD) + except OSError, (errno, strerror): + errMsg = "OSError while removing " + backupVHD + " with errno: " + str(errno) + " and strerr: " + strerror + util.SMlog(errMsg) + raise xs_errors.XenError(errMsg) + + return "1" + +@echo +def revert_memory_snapshot(session, args): + util.SMlog("Calling revert_memory_snapshot with " + str(args)) + vmName = args['vmName'] + snapshotUUID = args['snapshotUUID'] + oldVmUuid = args['oldVmUuid'] + snapshotMemory = args['snapshotMemory'] + hostUUID = args['hostUUID'] + try: + cmd = '''xe vbd-list vm-uuid=%s | grep 'vdi-uuid' | grep -v 'not in database' | sed -e 's/vdi-uuid ( RO)://g' ''' % oldVmUuid + vdiUuids = os.popen(cmd).read().split() + cmd2 = '''xe vm-param-get param-name=power-state uuid=''' + oldVmUuid + if os.popen(cmd2).read().split()[0] != 'halted': + os.system("xe vm-shutdown force=true vm=" + vmName) + os.system("xe vm-destroy uuid=" + oldVmUuid) + os.system("xe snapshot-revert snapshot-uuid=" + snapshotUUID) + if snapshotMemory == 'true': + os.system("xe vm-resume vm=" + vmName + " on=" + hostUUID) + for vdiUuid in vdiUuids: + os.system("xe vdi-destroy uuid=" + vdiUuid) + except OSError, (errno, strerror): + errMsg = "OSError while reverting vm " + vmName + " to snapshot " + snapshotUUID + " with errno: " + str(errno) + " and strerr: " + strerror + util.SMlog(errMsg) + raise xs_errors.XenError(errMsg) + return "0" + +if __name__ == "__main__": + XenAPIPlugin.dispatch({"getVhdParent":getVhdParent, "create_secondary_storage_folder":create_secondary_storage_folder, "delete_secondary_storage_folder":delete_secondary_storage_folder, "post_create_private_template":post_create_private_template, "backupSnapshot": backupSnapshot, "deleteSnapshotBackup": deleteSnapshotBackup, "unmountSnapshotsDir": unmountSnapshotsDir, "revert_memory_snapshot":revert_memory_snapshot}) + + diff --git a/scripts/vm/hypervisor/xenserver/xcpserver/patch b/scripts/vm/hypervisor/xenserver/xcpserver/patch index 2376424ff5..0f9d9a0cec 100644 --- a/scripts/vm/hypervisor/xenserver/xcpserver/patch +++ b/scripts/vm/hypervisor/xenserver/xcpserver/patch @@ -31,7 +31,6 @@ NFSSR.py=/opt/xensource/sm vmops=..,0755,/etc/xapi.d/plugins ovstunnel=..,0755,/etc/xapi.d/plugins vmopsSnapshot=..,0755,/etc/xapi.d/plugins -hostvmstats.py=..,0755,/opt/xensource/sm systemvm.iso=../../../../../vms,0644,/opt/xensource/packages/iso id_rsa.cloud=../../../systemvm,0600,/root/.ssh network_info.sh=..,0755,/opt/cloud/bin diff --git a/scripts/vm/hypervisor/xenserver/xenserver56/patch b/scripts/vm/hypervisor/xenserver/xenserver56/patch index 16dcb5746a..e24136d8ea 100644 --- a/scripts/vm/hypervisor/xenserver/xenserver56/patch +++ b/scripts/vm/hypervisor/xenserver/xenserver56/patch @@ -30,7 +30,6 @@ NFSSR.py=/opt/xensource/sm vmops=..,0755,/etc/xapi.d/plugins vmopsSnapshot=..,0755,/etc/xapi.d/plugins cloudstack_pluginlib.py=..,0755,/etc/xapi.d/plugins -hostvmstats.py=..,0755,/opt/xensource/sm systemvm.iso=../../../../../vms,0644,/opt/xensource/packages/iso id_rsa.cloud=../../../systemvm,0600,/root/.ssh network_info.sh=..,0755,/opt/cloud/bin diff --git a/scripts/vm/hypervisor/xenserver/xenserver56fp1/patch b/scripts/vm/hypervisor/xenserver/xenserver56fp1/patch index 11bda07369..5e1559898d 100644 --- a/scripts/vm/hypervisor/xenserver/xenserver56fp1/patch +++ b/scripts/vm/hypervisor/xenserver/xenserver56fp1/patch @@ -30,7 +30,6 @@ NFSSR.py=/opt/xensource/sm vmops=..,0755,/etc/xapi.d/plugins vmopsSnapshot=..,0755,/etc/xapi.d/plugins cloudstack_pluginlib.py=..,0755,/etc/xapi.d/plugins -hostvmstats.py=..,0755,/opt/xensource/sm systemvm.iso=../../../../../vms,0644,/opt/xensource/packages/iso id_rsa.cloud=../../../systemvm,0600,/root/.ssh network_info.sh=..,0755,/opt/cloud/bin diff --git a/scripts/vm/hypervisor/xenserver/xenserver60/patch b/scripts/vm/hypervisor/xenserver/xenserver60/patch index 662327b6a8..84472a608d 100644 --- a/scripts/vm/hypervisor/xenserver/xenserver60/patch +++ b/scripts/vm/hypervisor/xenserver/xenserver60/patch @@ -34,7 +34,6 @@ cloudstack_plugins.conf=..,0644,/etc/xensource cloudstack_pluginlib.py=..,0755,/etc/xapi.d/plugins ovstunnel=..,0755,/etc/xapi.d/plugins vmopsSnapshot=..,0755,/etc/xapi.d/plugins -hostvmstats.py=..,0755,/opt/xensource/sm systemvm.iso=../../../../../vms,0644,/opt/xensource/packages/iso id_rsa.cloud=../../../systemvm,0600,/root/.ssh network_info.sh=..,0755,/opt/cloud/bin diff --git a/scripts/vm/hypervisor/xenserver/xenserver62/patch b/scripts/vm/hypervisor/xenserver/xenserver62/patch index 05c619b70c..03cdfadbb2 100644 --- a/scripts/vm/hypervisor/xenserver/xenserver62/patch +++ b/scripts/vm/hypervisor/xenserver/xenserver62/patch @@ -28,13 +28,13 @@ # If [source path] does not start with '/' or '~', then it is relative path to the location of the patch file. vmops=..,0755,/etc/xapi.d/plugins vmopspremium=..,0755,/etc/xapi.d/plugins +vmopsSnapshot=..,0755,/etc/xapi.d/plugins xen-ovs-vif-flows.rules=..,0644,/etc/udev/rules.d ovs-vif-flows.py=..,0755,/etc/xapi.d/plugins cloudstack_plugins.conf=..,0644,/etc/xensource cloudstack_pluginlib.py=..,0755,/etc/xapi.d/plugins ovstunnel=..,0755,/etc/xapi.d/plugins cloud-plugin-storage=,0755,/etc/xapi.d/plugins -hostvmstats.py=..,0755,/opt/xensource/sm systemvm.iso=../../../../../vms,0644,/opt/xensource/packages/iso id_rsa.cloud=../../../systemvm,0600,/root/.ssh network_info.sh=..,0755,/opt/cloud/bin @@ -50,7 +50,6 @@ setup_heartbeat_file.sh=..,0755,/opt/cloud/bin check_heartbeat.sh=..,0755,/opt/cloud/bin xenheartbeat.sh=..,0755,/opt/cloud/bin launch_hb.sh=..,0755,/opt/cloud/bin -vhd-util=..,0755,/opt/cloud/bin upgrade_snapshot.sh=..,0755,/opt/cloud/bin cloud-clean-vlan.sh=..,0755,/opt/cloud/bin cloud-prepare-upgrade.sh=..,0755,/opt/cloud/bin diff --git a/scripts/vm/network/security_group.py b/scripts/vm/network/security_group.py index 1d94de3d60..704b279820 100755 --- a/scripts/vm/network/security_group.py +++ b/scripts/vm/network/security_group.py @@ -978,7 +978,7 @@ def addFWFramework(brname): execute("iptables -N " + brfwin) try: - refs = execute("""iptables -n -L " + brfw + " | awk '/%s(.*)references/ {gsub(/\(/, "") ;print $3}'""" % brfw).strip() + refs = execute("""iptables -n -L %s | awk '/%s(.*)references/ {gsub(/\(/, "") ;print $3}'""" % (brfw,brfw)).strip() if refs == "0": execute("iptables -I FORWARD -i " + brname + " -j DROP") execute("iptables -I FORWARD -o " + brname + " -j DROP") diff --git a/scripts/vm/network/vnet/ovstunnel.py b/scripts/vm/network/vnet/ovstunnel.py index 57085d8592..c108c2952f 100755 --- a/scripts/vm/network/vnet/ovstunnel.py +++ b/scripts/vm/network/vnet/ovstunnel.py @@ -27,7 +27,7 @@ import sys import subprocess import time -import simplejson as json +import json from optparse import OptionParser, OptionGroup, OptParseError, BadOptionError, OptionError, OptionConflictError, OptionValueError from time import localtime as _localtime, asctime as _asctime @@ -73,7 +73,6 @@ def setup_ovs_bridge(bridge, key, cs_host_id): logging.debug("Setup_ovs_bridge completed with result:%s" % result) return result -@echo def setup_ovs_bridge_for_distributed_routing(bridge, cs_host_id): res = lib.check_switch() @@ -281,7 +280,7 @@ def get_field_of_interface(iface_name, field): parser.add_option("--src_host", dest="src_host") parser.add_option("--dst_host", dest="dst_host") parser.add_option("--iface_name", dest="iface_name") - parser.ad_option("--config", dest="config") + parser.add_option("--config", dest="config") (option, args) = parser.parse_args() if len(args) == 0: logging.debug("No command to execute") diff --git a/server/resources/META-INF/cloudstack/core/spring-server-core-misc-context.xml b/server/resources/META-INF/cloudstack/core/spring-server-core-misc-context.xml index 91401e3354..479dc9ce96 100644 --- a/server/resources/META-INF/cloudstack/core/spring-server-core-misc-context.xml +++ b/server/resources/META-INF/cloudstack/core/spring-server-core-misc-context.xml @@ -52,7 +52,9 @@ - + + + diff --git a/server/src/com/cloud/acl/DomainChecker.java b/server/src/com/cloud/acl/DomainChecker.java index cb6921d9fa..729a0d1e2a 100755 --- a/server/src/com/cloud/acl/DomainChecker.java +++ b/server/src/com/cloud/acl/DomainChecker.java @@ -328,6 +328,39 @@ else if (_accountService.isDomainAdmin(account.getId())) { @Override public boolean checkAccess(Account caller, ControlledEntity entity, AccessType accessType, String action) throws PermissionDeniedException { + + if (action != null && ("SystemCapability".equals(action))) { + if (caller != null && caller.getType() == Account.ACCOUNT_TYPE_ADMIN) { + return true; + } else { + return false; + } + } else if (action != null && ("DomainCapability".equals(action))) { + if (caller != null && caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) { + return true; + } else { + return false; + } + } else if (action != null && ("DomainResourceCapability".equals(action))) { + if (caller != null && caller.getType() == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) { + return true; + } else { + return false; + } + } return checkAccess(caller, entity, accessType); } + + @Override + public boolean checkAccess(Account caller, AccessType accessType, String action, ControlledEntity... entities) + throws PermissionDeniedException { + + // returns true only if access to all entities is granted + for (ControlledEntity entity : entities) { + if (!checkAccess(caller, entity, accessType, action)) { + return false; + } + } + return true; + } } diff --git a/server/src/com/cloud/agent/manager/allocator/impl/FirstFitAllocator.java b/server/src/com/cloud/agent/manager/allocator/impl/FirstFitAllocator.java index 37368846da..3bd5c94377 100755 --- a/server/src/com/cloud/agent/manager/allocator/impl/FirstFitAllocator.java +++ b/server/src/com/cloud/agent/manager/allocator/impl/FirstFitAllocator.java @@ -243,7 +243,7 @@ protected List allocateTo(DeploymentPlan plan, ServiceOffering offering, V // We will try to reorder the host lists such that we give priority to hosts that have // the minimums to support a VM's requirements - hosts = prioritizeHosts(template, hosts); + hosts = prioritizeHosts(template, offering, hosts); if (s_logger.isDebugEnabled()) { s_logger.debug("Found " + hosts.size() + " hosts for allocation after prioritization: " + hosts); @@ -278,10 +278,12 @@ protected List allocateTo(DeploymentPlan plan, ServiceOffering offering, V } // Check if GPU device is required by offering and host has the availability - if ((offeringDetails = _serviceOfferingDetailsDao.findDetail(serviceOfferingId, GPU.Keys.vgpuType.toString())) != null - && !_resourceMgr.isGPUDeviceAvailable(host.getId(), offeringDetails.getValue())){ - s_logger.info("Host name: " + host.getName() + ", hostId: "+ host.getId() +" does not have required GPU devices available"); - continue; + if ((offeringDetails = _serviceOfferingDetailsDao.findDetail(serviceOfferingId, GPU.Keys.vgpuType.toString())) != null) { + ServiceOfferingDetailsVO groupName = _serviceOfferingDetailsDao.findDetail(serviceOfferingId, GPU.Keys.pciDevice.toString()); + if(!_resourceMgr.isGPUDeviceAvailable(host.getId(), groupName.getValue(), offeringDetails.getValue())){ + s_logger.info("Host name: " + host.getName() + ", hostId: "+ host.getId() +" does not have required GPU devices available"); + continue; + } } int cpu_requested = offering.getCpu() * offering.getSpeed(); @@ -353,7 +355,7 @@ public boolean isVirtualMachineUpgradable(VirtualMachine vm, ServiceOffering off return true; } - protected List prioritizeHosts(VMTemplateVO template, List hosts) { + protected List prioritizeHosts(VMTemplateVO template, ServiceOffering offering, List hosts) { if (template == null) { return hosts; } @@ -416,6 +418,22 @@ protected List prioritizeHosts(VMTemplateVO template, List gpuEnabledHosts = new ArrayList(); + // Check for GPU enabled hosts. + for (Host host : prioritizedHosts) { + if (_resourceMgr.isHostGpuEnabled(host.getId())) { + gpuEnabledHosts.add(host); + } + } + // Move GPU enabled hosts to the end of list + if(!gpuEnabledHosts.isEmpty()) { + prioritizedHosts.removeAll(gpuEnabledHosts); + prioritizedHosts.addAll(gpuEnabledHosts); + } + } return prioritizedHosts; } diff --git a/server/src/com/cloud/api/ApiAsyncJobDispatcher.java b/server/src/com/cloud/api/ApiAsyncJobDispatcher.java index f037f2e81a..71adf2ad34 100644 --- a/server/src/com/cloud/api/ApiAsyncJobDispatcher.java +++ b/server/src/com/cloud/api/ApiAsyncJobDispatcher.java @@ -75,6 +75,9 @@ public void runJob(final AsyncJob job) { // whenever we deserialize, the UserContext needs to be updated String userIdStr = params.get("ctxUserId"); String acctIdStr = params.get("ctxAccountId"); + String contextDetails = params.get("ctxDetails"); + + Long userId = null; Account accountObject = null; @@ -94,7 +97,12 @@ public void runJob(final AsyncJob job) { accountObject = _entityMgr.findById(Account.class, Long.parseLong(acctIdStr)); } - CallContext.register(user, accountObject); + CallContext ctx = CallContext.register(user, accountObject); + if(contextDetails != null){ + Type objectMapType = new TypeToken>() {}.getType(); + ctx.putContextParameters((Map) gson.fromJson(contextDetails, objectMapType)); + } + try { // dispatch could ultimately queue the job _dispatcher.dispatch(cmdObj, params, true); diff --git a/server/src/com/cloud/api/ApiDBUtils.java b/server/src/com/cloud/api/ApiDBUtils.java index 432eb941ab..90a09a0436 100755 --- a/server/src/com/cloud/api/ApiDBUtils.java +++ b/server/src/com/cloud/api/ApiDBUtils.java @@ -18,7 +18,9 @@ import java.util.ArrayList; import java.util.EnumSet; +import java.util.HashMap; import java.util.List; +import java.util.ListIterator; import java.util.Map; import java.util.Set; @@ -63,6 +65,7 @@ import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; +import com.cloud.agent.api.VgpuTypesInfo; import com.cloud.api.query.dao.AccountJoinDao; import com.cloud.api.query.dao.AffinityGroupJoinDao; import com.cloud.api.query.dao.AsyncJobJoinDao; @@ -236,6 +239,7 @@ import com.cloud.storage.Snapshot; import com.cloud.storage.SnapshotVO; import com.cloud.storage.Storage.ImageFormat; +import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.StorageManager; import com.cloud.storage.StoragePool; import com.cloud.storage.StorageStats; @@ -896,7 +900,11 @@ public static String findClusterDetails(long clusterId, String name) { } public static DiskOfferingVO findDiskOfferingById(Long diskOfferingId) { - return s_diskOfferingDao.findByIdIncludingRemoved(diskOfferingId); + DiskOfferingVO off = s_diskOfferingDao.findByIdIncludingRemoved(diskOfferingId); + if (off.getType() == DiskOfferingVO.Type.Disk) { + return off; + } + return null; } public static DomainVO findDomainById(Long domainId) { @@ -1071,6 +1079,26 @@ public static HypervisorType getHypervisorTypeFromFormat(long dcId, ImageFormat if (xenClusters.isEmpty()) { type = HypervisorType.Hyperv; } + } if (format == ImageFormat.RAW) { + // Currently, KVM only suppoorts RBD images of type RAW. + // This results in a weird collision with OVM volumes which + // can only be raw, thus making KVM RBD volumes show up as OVM + // rather than RBD. This block of code can (hopefuly) by checking to + // see if the pool is using either RBD or NFS. However, it isn't + // quite clear what to do if both storage types are used. If the image + // format is RAW, it narrows the hypervisor choice down to OVM and KVM / RBD or KVM / CLVM + // This would be better implemented at a cluster level. + List pools = s_storagePoolDao.listByDataCenterId(dcId); + ListIterator itr = pools.listIterator(); + while(itr.hasNext()) { + StoragePoolVO pool = itr.next(); + if(pool.getPoolType() == StoragePoolType.RBD || pool.getPoolType() == StoragePoolType.CLVM) { + // This case will note the presence of non-qcow2 primary stores, suggesting KVM without NFS. Otherwse, + // If this check is not passed, the hypervisor type will remain OVM. + type = HypervisorType.KVM; + break; + } + } } return type; } @@ -1079,6 +1107,14 @@ public static List getGpuGroups(long hostId) { return s_hostGpuGroupsDao.listByHostId(hostId); } + public static List getGpuCapacites(Long zoneId, Long podId, Long clusterId) { + return s_vgpuTypesDao.listGPUCapacities(zoneId, podId, clusterId); + } + + public static HashMap getVgpuVmsCount(Long zoneId, Long podId, Long clusterId) { + return s_vmDao.countVgpuVMs(zoneId, podId, clusterId); + } + public static List getVgpus(long groupId) { return s_vgpuTypesDao.listByGroupId(groupId); } @@ -1091,6 +1127,16 @@ public static List listUserVMsByHostId(long hostId) { return s_userVmDao.listByHostId(hostId); } + public static List listUserVMsByNetworkId(long networkId) { + return s_userVmDao.listByNetworkIdAndStates(networkId, VirtualMachine.State.Running, + VirtualMachine.State.Starting, VirtualMachine.State.Stopping, VirtualMachine.State.Unknown, + VirtualMachine.State.Migrating); + } + + public static List listDomainRoutersByNetworkId(long networkId) { + return s_domainRouterDao.findByNetwork(networkId); + } + public static List listZones() { return s_zoneDao.listAll(); } @@ -1400,6 +1446,12 @@ public static String findJobInstanceUuid(AsyncJob job) { String jobInstanceId = null; ApiCommandJobType jobInstanceType = EnumUtils.fromString(ApiCommandJobType.class, job.getInstanceType(), ApiCommandJobType.None); + if (job.getInstanceId() == null) { + // when assert is hit, implement 'getInstanceId' of BaseAsyncCmd and return appropriate instance id + assert (false); + return null; + } + if (jobInstanceType == ApiCommandJobType.Volume) { VolumeVO volume = ApiDBUtils.findVolumeById(job.getInstanceId()); if (volume != null) { @@ -1819,7 +1871,7 @@ public static Map getResourceDetails(long resourceId, ResourceOb } public static boolean isAdmin(Account account) { - return s_accountService.isAdmin(account.getType()); + return s_accountService.isAdmin(account.getId()); } public static List listResourceTagViewByResourceUUID(String resourceUUID, ResourceObjectType resourceType) { diff --git a/server/src/com/cloud/api/ApiDispatcher.java b/server/src/com/cloud/api/ApiDispatcher.java index 95074e24bb..3447662b2b 100755 --- a/server/src/com/cloud/api/ApiDispatcher.java +++ b/server/src/com/cloud/api/ApiDispatcher.java @@ -40,11 +40,8 @@ import com.cloud.api.dispatch.DispatchChain; import com.cloud.api.dispatch.DispatchChainFactory; import com.cloud.api.dispatch.DispatchTask; -import com.cloud.event.EventTypes; import com.cloud.user.Account; import com.cloud.user.AccountManager; -import com.cloud.utils.ReflectUtil; -import com.cloud.vm.VirtualMachine; public class ApiDispatcher { private static final Logger s_logger = Logger.getLogger(ApiDispatcher.class.getName()); @@ -80,7 +77,6 @@ public void setCreateSnapshotQueueSizeLimit(final Long snapshotLimit) { public void dispatchCreateCmd(final BaseAsyncCreateCmd cmd, final Map params) throws Exception { asyncCreationDispatchChain.dispatch(new DispatchTask(cmd, params)); - CallContext.current().setEventDisplayEnabled(cmd.isDisplayResourceEnabled()); } private void doAccessChecks(BaseCmd cmd, Map entitiesToAccess) { @@ -105,26 +101,15 @@ public void dispatch(final BaseCmd cmd, final Map params, final standardDispatchChain.dispatch(new DispatchTask(cmd, params)); final CallContext ctx = CallContext.current(); - ctx.setEventDisplayEnabled(cmd.isDisplayResourceEnabled()); + ctx.setEventDisplayEnabled(cmd.isDisplay()); // TODO This if shouldn't be here. Use polymorphism and move it to validateSpecificParameters if (cmd instanceof BaseAsyncCmd) { final BaseAsyncCmd asyncCmd = (BaseAsyncCmd)cmd; final String startEventId = params.get(ApiConstants.CTX_START_EVENT_ID); - String uuid = params.get(ApiConstants.UUID); ctx.setStartEventId(Long.valueOf(startEventId)); - // Fow now use the key from EventTypes.java rather than getInstanceType bcz the later doesn't refer to the interfaces - // Add the resource id in the call context, also add some other first class object ids (for now vm) if available. - // TODO - this should be done for all the uuids passed in the cmd - so should be moved where uuid to id conversion happens. - if(EventTypes.getEntityForEvent(asyncCmd.getEventType()) != null){ - ctx.putContextParameter(EventTypes.getEntityForEvent(asyncCmd.getEventType()), uuid); - } - if(params.get(ApiConstants.VIRTUAL_MACHINE_ID) != null){ - ctx.putContextParameter(ReflectUtil.getEntityName(VirtualMachine.class), params.get(ApiConstants.VIRTUAL_MACHINE_ID)); - } - // Synchronise job on the object if needed if (asyncCmd.getJob() != null && asyncCmd.getSyncObjId() != null && asyncCmd.getSyncObjType() != null) { Long queueSizeLimit = null; diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index a37bf7b2d4..c07d454966 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -150,6 +150,7 @@ import org.apache.cloudstack.usage.UsageService; import org.apache.cloudstack.usage.UsageTypes; +import com.cloud.agent.api.VgpuTypesInfo; import com.cloud.api.query.ViewResponseHelper; import com.cloud.api.query.vo.AccountJoinVO; import com.cloud.api.query.vo.AsyncJobJoinVO; @@ -193,6 +194,7 @@ import com.cloud.event.Event; import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.PermissionDeniedException; +import com.cloud.gpu.GPU; import com.cloud.host.Host; import com.cloud.host.HostVO; import com.cloud.hypervisor.HypervisorCapabilities; @@ -517,6 +519,7 @@ public SnapshotPolicyResponse createSnapshotPolicyResponse(SnapshotPolicy policy policyResponse.setIntervalType(policy.getInterval()); policyResponse.setMaxSnaps(policy.getMaxSnaps()); policyResponse.setTimezone(policy.getTimezone()); + policyResponse.setForDisplay(policy.isDisplay()); policyResponse.setObjectName("snapshotpolicy"); return policyResponse; @@ -1207,8 +1210,8 @@ public SystemVmResponse createSystemVmResponse(VirtualMachine vm) { NetworkOffering networkOffering = ApiDBUtils.findNetworkOfferingById(network.getNetworkOfferingId()); if (networkOffering.getElasticIp()) { IpAddress ip = ApiDBUtils.findIpByAssociatedVmId(vm.getId()); - Vlan vlan = ApiDBUtils.findVlanById(ip.getVlanId()); if (ip != null) { + Vlan vlan = ApiDBUtils.findVlanById(ip.getVlanId()); vmResponse.setPublicIp(ip.getAddress().addr()); vmResponse.setPublicNetmask(vlan.getVlanNetmask()); vmResponse.setGateway(vlan.getVlanGateway()); @@ -1248,6 +1251,7 @@ public VolumeVO findVolumeById(Long volumeId) { return ApiDBUtils.findVolumeById(volumeId); } + @Override public Account findAccountByNameDomain(String accountName, Long domainId) { return ApiDBUtils.findAccountByNameDomain(accountName, domainId); @@ -1735,6 +1739,48 @@ public List createCapacityResponse(List re capacityResponses.add(capacityResponse); } + List gpuCapacities; + if (result.size() > 1 && (gpuCapacities = ApiDBUtils.getGpuCapacites(result.get(0).getDataCenterId(), result.get(0).getPodId(), result.get(0).getClusterId())) != null) { + HashMap vgpuVMs = ApiDBUtils.getVgpuVmsCount(result.get(0).getDataCenterId(), result.get(0).getPodId(), result.get(0).getClusterId()); + + float capacityUsed = 0; + long capacityMax = 0; + for (VgpuTypesInfo capacity : gpuCapacities) { + if (vgpuVMs.containsKey(capacity.getGroupName().concat(capacity.getModelName()))) { + capacityUsed += (float)vgpuVMs.get(capacity.getGroupName().concat(capacity.getModelName())) / capacity.getMaxVpuPerGpu(); + } + if (capacity.getModelName().equals(GPU.vGPUType.passthrough.toString())) { + capacityMax += capacity.getMaxCapacity(); + } + } + + DataCenter zone = ApiDBUtils.findZoneById(result.get(0).getDataCenterId()); + CapacityResponse capacityResponse = new CapacityResponse(); + if (zone != null) { + capacityResponse.setZoneId(zone.getUuid()); + capacityResponse.setZoneName(zone.getName()); + } + if (result.get(0).getPodId() != null) { + HostPodVO pod = ApiDBUtils.findPodById(result.get(0).getPodId()); + capacityResponse.setPodId(pod.getUuid()); + capacityResponse.setPodName(pod.getName()); + } + if (result.get(0).getClusterId() != null) { + ClusterVO cluster = ApiDBUtils.findClusterById(result.get(0).getClusterId()); + capacityResponse.setClusterId(cluster.getUuid()); + capacityResponse.setClusterName(cluster.getName()); + } + capacityResponse.setCapacityType(Capacity.CAPACITY_TYPE_GPU); + capacityResponse.setCapacityUsed((long)Math.ceil(capacityUsed)); + capacityResponse.setCapacityTotal(capacityMax); + if (capacityMax > 0) { + capacityResponse.setPercentUsed(format.format(capacityUsed / capacityMax * 100f)); + } else { + capacityResponse.setPercentUsed(format.format(0)); + } + capacityResponse.setObjectName("capacity"); + capacityResponses.add(capacityResponse); + } return capacityResponses; } @@ -1901,6 +1947,7 @@ public NetworkOfferingResponse createNetworkOfferingResponse(NetworkOffering off response.setNetworkRate(ApiDBUtils.getNetworkRate(offering.getId())); response.setEgressDefaultPolicy(offering.getEgressDefaultPolicy()); response.setConcurrentConnections(offering.getConcurrentConnections()); + response.setSupportsStrechedL2Subnet(offering.getSupportsStrechedL2()); Long so = null; if (offering.getServiceOfferingId() != null) { so = offering.getServiceOfferingId(); @@ -2204,6 +2251,18 @@ public NetworkResponse createNetworkResponse(ResponseView view, Network network) } } + response.setStrechedL2Subnet(network.isStrechedL2Network()); + if (network.isStrechedL2Network()) { + Set networkSpannedZones = new HashSet(); + List vmInstances = new ArrayList(); + vmInstances.addAll(ApiDBUtils.listUserVMsByNetworkId(network.getId())); + vmInstances.addAll(ApiDBUtils.listDomainRoutersByNetworkId(network.getId())); + for (VirtualMachine vm : vmInstances) { + DataCenter vmZone = ApiDBUtils.findZoneById(vm.getDataCenterId()); + networkSpannedZones.add(vmZone.getUuid()); + } + response.setNetworkSpannedZones(networkSpannedZones); + } response.setObjectName("network"); return response; } @@ -2766,6 +2825,7 @@ public VpcOfferingResponse createVpcOfferingResponse(VpcOffering offering) { response.setIsDefault(offering.isDefault()); response.setState(offering.getState().name()); response.setSupportsDistributedRouter(offering.supportsDistributedRouter()); + response.setSupportsRegionLevelVpc(offering.offersRegionLevelVPC()); Map> serviceProviderMap = ApiDBUtils.listVpcOffServices(offering.getId()); List serviceResponses = new ArrayList(); @@ -2809,6 +2869,7 @@ public VpcResponse createVpcResponse(ResponseView view, Vpc vpc) { response.setNetworkDomain(vpc.getNetworkDomain()); response.setForDisplay(vpc.isDisplay()); response.setUsesDistributedRouter(vpc.usesDistributedRouter()); + response.setRegionLevelVpc(vpc.isRegionLevelVpc()); Map> serviceProviderMap = ApiDBUtils.listVpcOffServices(vpc.getVpcOfferingId()); List serviceResponses = new ArrayList(); @@ -3143,6 +3204,7 @@ public GuestOSResponse createGuestOSResponse(GuestOS guestOS) { GuestOSResponse response = new GuestOSResponse(); response.setDescription(guestOS.getDisplayName()); response.setId(guestOS.getUuid()); + response.setIsUserDefined(Boolean.valueOf(guestOS.getIsUserDefined()).toString()); GuestOSCategoryVO category = ApiDBUtils.findGuestOsCategoryById(guestOS.getCategoryId()); if (category != null) { response.setOsCategoryId(category.getUuid()); @@ -3159,6 +3221,7 @@ public GuestOsMappingResponse createGuestOSMappingResponse(GuestOSHypervisor gue response.setHypervisor(guestOSHypervisor.getHypervisorType()); response.setHypervisorVersion(guestOSHypervisor.getHypervisorVersion()); response.setOsNameForHypervisor((guestOSHypervisor.getGuestOsName())); + response.setIsUserDefined(Boolean.valueOf(guestOSHypervisor.getIsUserDefined()).toString()); GuestOS guestOs = ApiDBUtils.findGuestOSById(guestOSHypervisor.getGuestOsId()); if (guestOs != null) { response.setOsStdName(guestOs.getDisplayName()); @@ -3221,8 +3284,10 @@ public UsageRecordResponse createUsageResponse(Usage usageRecord) { usageRecResponse.setUsage(usageRecord.getUsageDisplay()); usageRecResponse.setUsageType(usageRecord.getUsageType()); if (usageRecord.getVmInstanceId() != null) { - VMInstanceVO vm = _entityMgr.findById(VMInstanceVO.class, usageRecord.getVmInstanceId()); - usageRecResponse.setVirtualMachineId(vm.getUuid()); + VMInstanceVO vm = _entityMgr.findByIdIncludingRemoved(VMInstanceVO.class, usageRecord.getVmInstanceId()); + if (vm != null) { + usageRecResponse.setVirtualMachineId(vm.getUuid()); + } } usageRecResponse.setVmName(usageRecord.getVmName()); if (usageRecord.getTemplateId() != null) { @@ -3233,14 +3298,20 @@ public UsageRecordResponse createUsageResponse(Usage usageRecord) { } if (usageRecord.getUsageType() == UsageTypes.RUNNING_VM || usageRecord.getUsageType() == UsageTypes.ALLOCATED_VM) { - ServiceOfferingVO svcOffering = _entityMgr.findById(ServiceOfferingVO.class, usageRecord.getOfferingId().toString()); + ServiceOfferingVO svcOffering = _entityMgr.findByIdIncludingRemoved(ServiceOfferingVO.class, usageRecord.getOfferingId().toString()); //Service Offering Id usageRecResponse.setOfferingId(svcOffering.getUuid()); //VM Instance ID - VMInstanceVO vm = _entityMgr.findById(VMInstanceVO.class, usageRecord.getUsageId().toString()); - usageRecResponse.setUsageId(vm.getUuid()); + VMInstanceVO vm = _entityMgr.findByIdIncludingRemoved(VMInstanceVO.class, usageRecord.getUsageId().toString()); + if (vm != null) { + usageRecResponse.setUsageId(vm.getUuid()); + } //Hypervisor Type usageRecResponse.setType(usageRecord.getType()); + //Dynamic compute offerings details + usageRecResponse.setCpuNumber(usageRecord.getCpuCores()); + usageRecResponse.setCpuSpeed(usageRecord.getCpuSpeed()); + usageRecResponse.setMemory(usageRecord.getMemory()); } else if (usageRecord.getUsageType() == UsageTypes.IP_ADDRESS) { //isSourceNAT @@ -3248,52 +3319,69 @@ public UsageRecordResponse createUsageResponse(Usage usageRecord) { //isSystem usageRecResponse.setSystem((usageRecord.getSize() == 1) ? true : false); //IP Address ID - IPAddressVO ip = _entityMgr.findById(IPAddressVO.class, usageRecord.getUsageId().toString()); - usageRecResponse.setUsageId(ip.getUuid()); + IPAddressVO ip = _entityMgr.findByIdIncludingRemoved(IPAddressVO.class, usageRecord.getUsageId().toString()); + if (ip != null) { + usageRecResponse.setUsageId(ip.getUuid()); + } } 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")) { //Domain Router Id - VMInstanceVO vm = _entityMgr.findById(VMInstanceVO.class, usageRecord.getUsageId().toString()); - usageRecResponse.setUsageId(vm.getUuid()); + VMInstanceVO vm = _entityMgr.findByIdIncludingRemoved(VMInstanceVO.class, usageRecord.getUsageId().toString()); + if (vm != null) { + usageRecResponse.setUsageId(vm.getUuid()); + } } else { //External Device Host Id - HostVO host = _entityMgr.findById(HostVO.class, usageRecord.getUsageId().toString()); - usageRecResponse.setUsageId(host.getUuid()); + HostVO host = _entityMgr.findByIdIncludingRemoved(HostVO.class, usageRecord.getUsageId().toString()); + if (host != null) { + usageRecResponse.setUsageId(host.getUuid()); + } } //Network ID - NetworkVO network = _entityMgr.findById(NetworkVO.class, usageRecord.getNetworkId().toString()); - usageRecResponse.setNetworkId(network.getUuid()); + NetworkVO network = _entityMgr.findByIdIncludingRemoved(NetworkVO.class, usageRecord.getNetworkId().toString()); + if (network != null) { + usageRecResponse.setNetworkId(network.getUuid()); + } } else if (usageRecord.getUsageType() == UsageTypes.VM_DISK_IO_READ || usageRecord.getUsageType() == UsageTypes.VM_DISK_IO_WRITE || usageRecord.getUsageType() == UsageTypes.VM_DISK_BYTES_READ || usageRecord.getUsageType() == UsageTypes.VM_DISK_BYTES_WRITE) { //Device Type usageRecResponse.setType(usageRecord.getType()); //VM Instance Id - VMInstanceVO vm = _entityMgr.findById(VMInstanceVO.class, usageRecord.getVmInstanceId().toString()); - usageRecResponse.setVirtualMachineId(vm.getUuid()); + VMInstanceVO vm = _entityMgr.findByIdIncludingRemoved(VMInstanceVO.class, usageRecord.getVmInstanceId().toString()); + if (vm != null) { + usageRecResponse.setVirtualMachineId(vm.getUuid()); + } //Volume ID - VolumeVO volume = _entityMgr.findById(VolumeVO.class, usageRecord.getUsageId().toString()); - usageRecResponse.setUsageId(volume.getUuid()); + VolumeVO volume = _entityMgr.findByIdIncludingRemoved(VolumeVO.class, usageRecord.getUsageId().toString()); + if (volume != null) { + usageRecResponse.setUsageId(volume.getUuid()); + } } else if (usageRecord.getUsageType() == UsageTypes.VOLUME) { //Volume ID - VolumeVO volume = _entityMgr.findById(VolumeVO.class, usageRecord.getUsageId().toString()); - usageRecResponse.setUsageId(volume.getUuid()); + VolumeVO volume = _entityMgr.findByIdIncludingRemoved(VolumeVO.class, usageRecord.getUsageId().toString()); + if (volume != null) { + usageRecResponse.setUsageId(volume.getUuid()); + } //Volume Size usageRecResponse.setSize(usageRecord.getSize()); //Disk Offering Id if (usageRecord.getOfferingId() != null) { - DiskOfferingVO diskOff = _entityMgr.findById(DiskOfferingVO.class, usageRecord.getOfferingId().toString()); + DiskOfferingVO diskOff = _entityMgr.findByIdIncludingRemoved(DiskOfferingVO.class, usageRecord.getOfferingId().toString()); usageRecResponse.setOfferingId(diskOff.getUuid()); } } else if (usageRecord.getUsageType() == UsageTypes.TEMPLATE || usageRecord.getUsageType() == UsageTypes.ISO) { //Template/ISO ID - VMTemplateVO tmpl = _entityMgr.findById(VMTemplateVO.class, usageRecord.getUsageId().toString()); + VMTemplateVO tmpl = _entityMgr.findByIdIncludingRemoved(VMTemplateVO.class, usageRecord.getUsageId().toString()); usageRecResponse.setUsageId(tmpl.getUuid()); + if (tmpl != null) { + usageRecResponse.setUsageId(tmpl.getUuid()); + } //Template/ISO Size usageRecResponse.setSize(usageRecord.getSize()); if (usageRecord.getUsageType() == UsageTypes.ISO) { @@ -3304,46 +3392,52 @@ public UsageRecordResponse createUsageResponse(Usage usageRecord) { } else if (usageRecord.getUsageType() == UsageTypes.SNAPSHOT) { //Snapshot ID - SnapshotVO snap = _entityMgr.findById(SnapshotVO.class, usageRecord.getUsageId().toString()); - usageRecResponse.setUsageId(snap.getUuid()); + SnapshotVO snap = _entityMgr.findByIdIncludingRemoved(SnapshotVO.class, usageRecord.getUsageId().toString()); + if (snap != null) { + usageRecResponse.setUsageId(snap.getUuid()); + } //Snapshot Size usageRecResponse.setSize(usageRecord.getSize()); } else if (usageRecord.getUsageType() == UsageTypes.LOAD_BALANCER_POLICY) { //Load Balancer Policy ID - LoadBalancerVO lb = _entityMgr.findById(LoadBalancerVO.class, usageRecord.getUsageId().toString()); + LoadBalancerVO lb = _entityMgr.findByIdIncludingRemoved(LoadBalancerVO.class, usageRecord.getUsageId().toString()); if (lb != null) { usageRecResponse.setUsageId(lb.getUuid()); } } else if (usageRecord.getUsageType() == UsageTypes.PORT_FORWARDING_RULE) { //Port Forwarding Rule ID - PortForwardingRuleVO pf = _entityMgr.findById(PortForwardingRuleVO.class, usageRecord.getUsageId().toString()); + PortForwardingRuleVO pf = _entityMgr.findByIdIncludingRemoved(PortForwardingRuleVO.class, usageRecord.getUsageId().toString()); if (pf != null) { usageRecResponse.setUsageId(pf.getUuid()); } } else if (usageRecord.getUsageType() == UsageTypes.NETWORK_OFFERING) { //Network Offering Id - NetworkOfferingVO netOff = _entityMgr.findById(NetworkOfferingVO.class, usageRecord.getOfferingId().toString()); + NetworkOfferingVO netOff = _entityMgr.findByIdIncludingRemoved(NetworkOfferingVO.class, usageRecord.getOfferingId().toString()); usageRecResponse.setOfferingId(netOff.getUuid()); //is Default usageRecResponse.setDefault((usageRecord.getUsageId() == 1) ? true : false); } else if (usageRecord.getUsageType() == UsageTypes.VPN_USERS) { //VPN User ID - VpnUserVO vpnUser = _entityMgr.findById(VpnUserVO.class, usageRecord.getUsageId().toString()); + VpnUserVO vpnUser = _entityMgr.findByIdIncludingRemoved(VpnUserVO.class, usageRecord.getUsageId().toString()); if (vpnUser != null) { usageRecResponse.setUsageId(vpnUser.getUuid()); } } else if (usageRecord.getUsageType() == UsageTypes.SECURITY_GROUP) { //Security Group Id - SecurityGroupVO sg = _entityMgr.findById(SecurityGroupVO.class, usageRecord.getUsageId().toString()); - usageRecResponse.setUsageId(sg.getUuid()); + SecurityGroupVO sg = _entityMgr.findByIdIncludingRemoved(SecurityGroupVO.class, usageRecord.getUsageId().toString()); + if (sg != null) { + usageRecResponse.setUsageId(sg.getUuid()); + } } else if (usageRecord.getUsageType() == UsageTypes.VM_SNAPSHOT) { - VMInstanceVO vm = _entityMgr.findById(VMInstanceVO.class, usageRecord.getVmInstanceId().toString()); - usageRecResponse.setVmName(vm.getInstanceName()); - usageRecResponse.setUsageId(vm.getUuid()); + VMInstanceVO vm = _entityMgr.findByIdIncludingRemoved(VMInstanceVO.class, usageRecord.getVmInstanceId().toString()); + if (vm != null) { + usageRecResponse.setVmName(vm.getInstanceName()); + usageRecResponse.setUsageId(vm.getUuid()); + } usageRecResponse.setSize(usageRecord.getSize()); if (usageRecord.getOfferingId() != null) { usageRecResponse.setOfferingId(usageRecord.getOfferingId().toString()); @@ -3481,9 +3575,15 @@ public NicSecondaryIpResponse createSecondaryIPToNicResponse(NicSecondaryIp resu public NicResponse createNicResponse(Nic result) { NicResponse response = new NicResponse(); NetworkVO network = _entityMgr.findById(NetworkVO.class, result.getNetworkId()); + VMInstanceVO vm = _entityMgr.findById(VMInstanceVO.class, result.getInstanceId()); response.setId(result.getUuid()); response.setNetworkid(network.getUuid()); + + if (vm != null) { + response.setVmId(vm.getUuid()); + } + response.setIpaddress(result.getIp4Address()); if (result.getSecondaryIp()) { diff --git a/server/src/com/cloud/api/ApiServer.java b/server/src/com/cloud/api/ApiServer.java index e4486c1fee..800b78200b 100755 --- a/server/src/com/cloud/api/ApiServer.java +++ b/server/src/com/cloud/api/ApiServer.java @@ -82,6 +82,7 @@ import org.apache.http.protocol.ResponseDate; import org.apache.http.protocol.ResponseServer; import org.apache.log4j.Logger; +import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.stereotype.Component; import org.apache.cloudstack.acl.APIChecker; @@ -95,10 +96,14 @@ import org.apache.cloudstack.api.ResponseObject; import org.apache.cloudstack.api.ResponseObject.ResponseView; import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.command.admin.account.ListAccountsCmdByAdmin; import org.apache.cloudstack.api.command.admin.host.ListHostsCmd; import org.apache.cloudstack.api.command.admin.router.ListRoutersCmd; import org.apache.cloudstack.api.command.admin.storage.ListStoragePoolsCmd; import org.apache.cloudstack.api.command.admin.user.ListUsersCmd; +import org.apache.cloudstack.api.command.admin.vm.ListVMsCmdByAdmin; +import org.apache.cloudstack.api.command.admin.volume.ListVolumesCmdByAdmin; +import org.apache.cloudstack.api.command.admin.zone.ListZonesCmdByAdmin; import org.apache.cloudstack.api.command.user.account.ListAccountsCmd; import org.apache.cloudstack.api.command.user.account.ListProjectAccountsCmd; import org.apache.cloudstack.api.command.user.event.ListEventsCmd; @@ -119,9 +124,14 @@ import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.cloudstack.framework.config.impl.ConfigurationVO; +import org.apache.cloudstack.framework.events.EventBus; +import org.apache.cloudstack.framework.events.EventBusException; import org.apache.cloudstack.framework.jobs.AsyncJob; import org.apache.cloudstack.framework.jobs.AsyncJobManager; import org.apache.cloudstack.framework.jobs.impl.AsyncJobVO; +import org.apache.cloudstack.framework.messagebus.MessageBus; +import org.apache.cloudstack.framework.messagebus.MessageDispatcher; +import org.apache.cloudstack.framework.messagebus.MessageHandler; import org.apache.cloudstack.managed.context.ManagedContextRunnable; import com.cloud.api.dispatch.DispatchChainFactory; @@ -130,7 +140,9 @@ import com.cloud.configuration.Config; import com.cloud.domain.Domain; import com.cloud.domain.DomainVO; +import com.cloud.domain.dao.DomainDao; import com.cloud.event.ActionEventUtils; +import com.cloud.event.EventCategory; import com.cloud.event.EventTypes; import com.cloud.exception.AccountLimitException; import com.cloud.exception.CloudAuthenticationException; @@ -148,7 +160,6 @@ import com.cloud.user.UserVO; import com.cloud.utils.NumbersUtil; import com.cloud.utils.Pair; -import com.cloud.utils.ReflectUtil; import com.cloud.utils.StringUtils; import com.cloud.utils.component.ComponentContext; import com.cloud.utils.component.ManagerBase; @@ -159,7 +170,6 @@ import com.cloud.utils.db.TransactionLegacy; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.exception.ExceptionProxyObject; -import com.cloud.vm.VirtualMachine; @Component public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiServerService { @@ -183,6 +193,9 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer private AccountManager _accountMgr; @Inject private DomainManager _domainMgr; + @Inject + private DomainDao _domainDao; + @Inject private AsyncJobManager _asyncMgr; @Inject @@ -201,16 +214,98 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer private static Map>> s_apiNameCmdClassMap = new HashMap>>(); private static ExecutorService s_executor = new ThreadPoolExecutor(10, 150, 60, TimeUnit.SECONDS, new LinkedBlockingQueue(), new NamedThreadFactory( - "ApiServer")); + "ApiServer")); + @Inject + MessageBus _messageBus; public ApiServer() { } @Override public boolean configure(final String name, final Map params) throws ConfigurationException { + _messageBus.subscribe(AsyncJob.Topics.JOB_EVENT_PUBLISH, MessageDispatcher.getDispatcher(this)); return true; } + @MessageHandler(topic = AsyncJob.Topics.JOB_EVENT_PUBLISH) + private void handleAsyncJobPublishEvent(String subject, String senderAddress, Object args) { + assert (args != null); + + @SuppressWarnings("unchecked") + Pair eventInfo = (Pair)args; + AsyncJob job = eventInfo.first(); + String jobEvent = eventInfo.second(); + + if (s_logger.isTraceEnabled()) + s_logger.trace("Handle asyjob publish event " + jobEvent); + + EventBus eventBus = null; + try { + eventBus = ComponentContext.getComponent(EventBus.class); + } catch (NoSuchBeanDefinitionException nbe) { + return; // no provider is configured to provide events bus, so just return + } + + if (!job.getDispatcher().equalsIgnoreCase("ApiAsyncJobDispatcher")) { + return; + } + + User userJobOwner = _accountMgr.getUserIncludingRemoved(job.getUserId()); + Account jobOwner = _accountMgr.getAccount(userJobOwner.getAccountId()); + + // Get the event type from the cmdInfo json string + String info = job.getCmdInfo(); + String cmdEventType = "unknown"; + if (info != null) { + String marker = "\"cmdEventType\""; + int begin = info.indexOf(marker); + if (begin >= 0) { + cmdEventType = info.substring(begin + marker.length() + 2, info.indexOf(",", begin) - 1); + + if (s_logger.isDebugEnabled()) + s_logger.debug("Retrieved cmdEventType from job info: " + cmdEventType); + } else { + if (s_logger.isDebugEnabled()) + s_logger.debug("Unable to locate cmdEventType marker in job info. publish as unknown event"); + } + } + // For some reason, the instanceType / instanceId are not abstract, which means we may get null values. + org.apache.cloudstack.framework.events.Event event = new org.apache.cloudstack.framework.events.Event( + "management-server", + EventCategory.ASYNC_JOB_CHANGE_EVENT.getName(), + jobEvent, + (job.getInstanceType() != null ? job.getInstanceType().toString() : "unknown"), null); + + Map eventDescription = new HashMap(); + eventDescription.put("command", job.getCmd()); + eventDescription.put("user", userJobOwner.getUuid()); + eventDescription.put("account", jobOwner.getUuid()); + eventDescription.put("processStatus", "" + job.getProcessStatus()); + eventDescription.put("resultCode", "" + job.getResultCode()); + eventDescription.put("instanceUuid", ApiDBUtils.findJobInstanceUuid(job)); + eventDescription.put("instanceType", (job.getInstanceType() != null ? job.getInstanceType().toString() : "unknown")); + eventDescription.put("commandEventType", cmdEventType); + eventDescription.put("jobId", job.getUuid()); + // If the event.accountinfo boolean value is set, get the human readable value for the username / domainname + Map configs = _configDao.getConfiguration("management-server", new HashMap()); + if (Boolean.valueOf(configs.get("event.accountinfo"))) { + DomainVO domain = _domainDao.findById(jobOwner.getDomainId()); + eventDescription.put("username", userJobOwner.getUsername()); + eventDescription.put("domainname", domain.getName()); + } + event.setDescription(eventDescription); + + try { + eventBus.publish(event); + } catch (EventBusException evx) { + String errMsg = "F" + + "" + + "ailed to publish async job event on the the event bus."; + s_logger.warn(errMsg, evx); + throw new CloudRuntimeException(errMsg); + } + } + @Override public boolean start() { Integer apiPort = null; // api port, null by default @@ -356,7 +451,7 @@ public void checkCharacterInkParams(final Map params) { final Matcher matcher = pattern.matcher(value[0]); if (matcher.find()) { throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Received value " + value[0] + " for parameter " + key + - " is invalid, contains illegal ASCII non-printable characters"); + " is invalid, contains illegal ASCII non-printable characters"); } } stringMap.put(key, value[0]); @@ -420,7 +515,7 @@ public String handleRequest(final Map params, final String responseType, final S StringUtils.cleanString(response)); } else - buildAuditTrail(auditTrailSb, command[0], response); + buildAuditTrail(auditTrailSb, command[0], response); } else { if (!command[0].equalsIgnoreCase("login") && !command[0].equalsIgnoreCase("logout")) { final String errorString = "Unknown API command: " + command[0]; @@ -511,7 +606,6 @@ private String queueCommand(final BaseCmd cmdObj, final Map para final CallContext ctx = CallContext.current(); final Long callerUserId = ctx.getCallingUserId(); final Account caller = ctx.getCallingAccount(); - String vmUUID = params.get(ApiConstants.VIRTUAL_MACHINE_ID); // Queue command based on Cmd super class: // BaseCmd: cmd is dispatched to ApiDispatcher, executed, serialized and returned. @@ -526,6 +620,9 @@ private String queueCommand(final BaseCmd cmdObj, final Map para objectId = createCmd.getEntityId(); objectUuid = createCmd.getEntityUuid(); params.put("id", objectId.toString()); + Class entityClass = EventTypes.getEntityClassForEvent(createCmd.getEventType()); + if (entityClass != null) + ctx.putContextParameter(entityClass.getName(), objectUuid); } else { // Extract the uuid before params are processed and id reflects internal db id objectUuid = params.get(ApiConstants.ID); @@ -540,26 +637,17 @@ private String queueCommand(final BaseCmd cmdObj, final Map para if (caller != null) { params.put("ctxAccountId", String.valueOf(caller.getId())); } - if(objectUuid != null){ + if (objectUuid != null) { params.put("uuid", objectUuid); } long startEventId = ctx.getStartEventId(); asyncCmd.setStartEventId(startEventId); - // Add the resource id in the call context, also add some other first class object ids (for now vm) if available. - // TODO - this should be done for all the uuids passed in the cmd - so should be moved where uuid to id conversion happens. - if(EventTypes.getEntityForEvent(asyncCmd.getEventType()) != null){ - ctx.putContextParameter(EventTypes.getEntityForEvent(asyncCmd.getEventType()), objectUuid); - } - if(vmUUID != null){ - ctx.putContextParameter(ReflectUtil.getEntityName(VirtualMachine.class), vmUUID); - } - // save the scheduled event final Long eventId = - ActionEventUtils.onScheduledActionEvent((callerUserId == null) ? User.UID_SYSTEM : callerUserId, asyncCmd.getEntityOwnerId(), asyncCmd.getEventType(), - asyncCmd.getEventDescription(), asyncCmd.isDisplayResourceEnabled(), startEventId); + ActionEventUtils.onScheduledActionEvent((callerUserId == null) ? User.UID_SYSTEM : callerUserId, asyncCmd.getEntityOwnerId(), asyncCmd.getEventType(), + asyncCmd.getEventDescription(), asyncCmd.isDisplay(), startEventId); if (startEventId == 0) { // There was no create event before, set current event id as start eventId startEventId = eventId; @@ -567,6 +655,7 @@ private String queueCommand(final BaseCmd cmdObj, final Map para params.put("ctxStartEventId", String.valueOf(startEventId)); params.put("cmdEventType", asyncCmd.getEventType().toString()); + params.put("ctxDetails", ApiGsonHelper.getBuilder().create().toJson(ctx.getContextParameters())); Long instanceId = (objectId == null) ? asyncCmd.getInstanceId() : objectId; AsyncJobVO job = new AsyncJobVO("", callerUserId, caller.getId(), cmdObj.getClass().getName(), @@ -595,13 +684,15 @@ private String queueCommand(final BaseCmd cmdObj, final Map para // if the command is of the listXXXCommand, we will need to also return the // the job id and status if possible // For those listXXXCommand which we have already created DB views, this step is not needed since async job is joined in their db views. - if (cmdObj instanceof BaseListCmd && !(cmdObj instanceof ListVMsCmd) && !(cmdObj instanceof ListRoutersCmd) && !(cmdObj instanceof ListSecurityGroupsCmd) && - !(cmdObj instanceof ListTagsCmd) && !(cmdObj instanceof ListEventsCmd) && !(cmdObj instanceof ListVMGroupsCmd) && !(cmdObj instanceof ListProjectsCmd) && - !(cmdObj instanceof ListProjectAccountsCmd) && !(cmdObj instanceof ListProjectInvitationsCmd) && !(cmdObj instanceof ListHostsCmd) && - !(cmdObj instanceof ListVolumesCmd) && !(cmdObj instanceof ListUsersCmd) && !(cmdObj instanceof ListAccountsCmd) && - !(cmdObj instanceof ListStoragePoolsCmd) && !(cmdObj instanceof ListDiskOfferingsCmd) && !(cmdObj instanceof ListServiceOfferingsCmd) && - !(cmdObj instanceof ListZonesCmd)) { - buildAsyncListResponse((BaseListCmd) cmdObj, caller); + if (cmdObj instanceof BaseListCmd && !(cmdObj instanceof ListVMsCmd) && !(cmdObj instanceof ListVMsCmdByAdmin) && !(cmdObj instanceof ListRoutersCmd) + && !(cmdObj instanceof ListSecurityGroupsCmd) && + !(cmdObj instanceof ListTagsCmd) && !(cmdObj instanceof ListEventsCmd) && !(cmdObj instanceof ListVMGroupsCmd) && !(cmdObj instanceof ListProjectsCmd) && + !(cmdObj instanceof ListProjectAccountsCmd) && !(cmdObj instanceof ListProjectInvitationsCmd) && !(cmdObj instanceof ListHostsCmd) && + !(cmdObj instanceof ListVolumesCmd) && !(cmdObj instanceof ListVolumesCmdByAdmin) && !(cmdObj instanceof ListUsersCmd) && !(cmdObj instanceof ListAccountsCmd) + && !(cmdObj instanceof ListAccountsCmdByAdmin) && + !(cmdObj instanceof ListStoragePoolsCmd) && !(cmdObj instanceof ListDiskOfferingsCmd) && !(cmdObj instanceof ListServiceOfferingsCmd) && + !(cmdObj instanceof ListZonesCmd) && !(cmdObj instanceof ListZonesCmdByAdmin)) { + buildAsyncListResponse((BaseListCmd)cmdObj, caller); } SerializationContext.current().setUuidTranslation(true); @@ -775,7 +866,7 @@ public boolean verifyRequest(final Map requestParameters, fina if (user.getState() != Account.State.enabled || !account.getState().equals(Account.State.enabled)) { s_logger.info("disabled or locked user accessing the api, userid = " + user.getId() + "; name = " + user.getUsername() + "; state: " + user.getState() + - "; accountState: " + account.getState()); + "; accountState: " + account.getState()); return false; } @@ -831,7 +922,7 @@ public Long fetchDomainId(final String domainUUID) { @Override public void loginUser(final HttpSession session, final String username, final String password, Long domainId, final String domainPath, final String loginIpAddress, - final Map requestParameters) throws CloudAuthenticationException { + final Map requestParameters) throws CloudAuthenticationException { // We will always use domainId first. If that does not exist, we will use domain name. If THAT doesn't exist // we will default to ROOT if (domainId == null) { @@ -920,7 +1011,7 @@ public boolean verifyUser(final Long userId) { } if ((user == null) || (user.getRemoved() != null) || !user.getState().equals(Account.State.enabled) || (account == null) || - !account.getState().equals(Account.State.enabled)) { + !account.getState().equals(Account.State.enabled)) { s_logger.warn("Deleted/Disabled/Locked user with id=" + userId + " attempting to access public API"); return false; } @@ -1016,10 +1107,10 @@ public ListenerThread(final ApiServer requestHandler, final int port) { _params = new BasicHttpParams(); _params.setIntParameter(CoreConnectionPNames.SO_TIMEOUT, 30000) - .setIntParameter(CoreConnectionPNames.SOCKET_BUFFER_SIZE, 8 * 1024) - .setBooleanParameter(CoreConnectionPNames.STALE_CONNECTION_CHECK, false) - .setBooleanParameter(CoreConnectionPNames.TCP_NODELAY, true) - .setParameter(CoreProtocolPNames.ORIGIN_SERVER, "HttpComponents/1.1"); + .setIntParameter(CoreConnectionPNames.SOCKET_BUFFER_SIZE, 8 * 1024) + .setBooleanParameter(CoreConnectionPNames.STALE_CONNECTION_CHECK, false) + .setBooleanParameter(CoreConnectionPNames.TCP_NODELAY, true) + .setParameter(CoreProtocolPNames.ORIGIN_SERVER, "HttpComponents/1.1"); // Set up the HTTP protocol processor final BasicHttpProcessor httpproc = new BasicHttpProcessor(); diff --git a/server/src/com/cloud/api/dispatch/CommandCreationWorker.java b/server/src/com/cloud/api/dispatch/CommandCreationWorker.java index 30d4637d37..25846f9083 100644 --- a/server/src/com/cloud/api/dispatch/CommandCreationWorker.java +++ b/server/src/com/cloud/api/dispatch/CommandCreationWorker.java @@ -23,6 +23,7 @@ import org.apache.cloudstack.api.ServerApiException; import com.cloud.exception.ResourceAllocationException; +import org.apache.cloudstack.context.CallContext; /** @@ -42,6 +43,7 @@ public void handle(final DispatchTask task) { if (cmd instanceof BaseAsyncCreateCmd) { try { + CallContext.current().setEventDisplayEnabled(cmd.isDisplay()); ((BaseAsyncCreateCmd)cmd).create(); } catch (final ResourceAllocationException e) { throw new ServerApiException(ApiErrorCode.RESOURCE_ALLOCATION_ERROR, diff --git a/server/src/com/cloud/api/dispatch/ParamGenericValidationWorker.java b/server/src/com/cloud/api/dispatch/ParamGenericValidationWorker.java index 7a73b8aef9..7aaafbb55f 100644 --- a/server/src/com/cloud/api/dispatch/ParamGenericValidationWorker.java +++ b/server/src/com/cloud/api/dispatch/ParamGenericValidationWorker.java @@ -63,6 +63,7 @@ public class ParamGenericValidationWorker implements DispatchWorker { defaultParamNames.add(ApiConstants.CTX_ACCOUNT_ID); defaultParamNames.add(ApiConstants.CTX_START_EVENT_ID); defaultParamNames.add(ApiConstants.CTX_USER_ID); + defaultParamNames.add(ApiConstants.CTX_DETAILS); defaultParamNames.add(ApiConstants.UUID); defaultParamNames.add(ApiConstants.ID); defaultParamNames.add("_"); @@ -80,9 +81,17 @@ public void handle(final DispatchTask task) { final StringBuilder errorMsg = new StringBuilder(ERROR_MSG_PREFIX); boolean foundUnknownParam = false; - for (final Object paramName : params.keySet()) { - if (!expectedParamNames.contains(paramName)) { - errorMsg.append(" ").append(paramName); + for (final Object actualParamName : params.keySet()) { + // If none of the expected params matches, we have an unknown param + boolean matchedCurrentParam = false; + for (final String expectedName : expectedParamNames) { + if (expectedName.equalsIgnoreCase((String) actualParamName)) { + matchedCurrentParam = true; + break; + } + } + if (!matchedCurrentParam) { + errorMsg.append(" ").append(actualParamName); foundUnknownParam= true; } } diff --git a/server/src/com/cloud/api/dispatch/ParamProcessWorker.java b/server/src/com/cloud/api/dispatch/ParamProcessWorker.java index e9bdd8b107..1592b93fe2 100644 --- a/server/src/com/cloud/api/dispatch/ParamProcessWorker.java +++ b/server/src/com/cloud/api/dispatch/ParamProcessWorker.java @@ -37,16 +37,17 @@ import org.apache.cloudstack.acl.ControlledEntity; import org.apache.cloudstack.acl.InfrastructureEntity; +import org.apache.cloudstack.acl.SecurityChecker; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ACL; import org.apache.cloudstack.api.ApiErrorCode; import org.apache.cloudstack.api.BaseAsyncCreateCmd; import org.apache.cloudstack.api.BaseCmd; +import org.apache.cloudstack.api.BaseCmd.CommandType; import org.apache.cloudstack.api.EntityReference; import org.apache.cloudstack.api.InternalIdentity; import org.apache.cloudstack.api.Parameter; import org.apache.cloudstack.api.ServerApiException; -import org.apache.cloudstack.api.BaseCmd.CommandType; import org.apache.cloudstack.api.command.admin.resource.ArchiveAlertsCmd; import org.apache.cloudstack.api.command.admin.resource.DeleteAlertsCmd; import org.apache.cloudstack.api.command.user.event.ArchiveEventsCmd; @@ -71,6 +72,17 @@ public class ParamProcessWorker implements DispatchWorker { @Inject protected EntityManager _entityMgr; + List _secChecker; + + public List getSecChecker() { + return _secChecker; + } + + @Inject + public void setSecChecker(List secChecker) { + _secChecker = secChecker; + } + @Override public void handle(final DispatchTask task) { processParameters(task.getCmd(), task.getParams()); @@ -130,71 +142,63 @@ public void processParameters(final BaseCmd cmd, final Map params) { final CommandType fieldType = parameterAnnotation.type(); if (checkAccess != null) { - // Verify that caller can perform actions in behalf of vm owner - //acumulate all Controlled Entities together. - - //parse the array of resource types and in case of map check access on key or value or both as specified in @acl - //implement external dao for classes that need findByName - //for maps, specify access to be checkd on key or value. - - // find the controlled entity DBid by uuid - if (parameterAnnotation.entityType() != null) { + // Verify that caller can perform actions in behalf of vm + // owner acumulate all Controlled Entities together. + // parse the array of resource types and in case of map + // check access on key or value or both as specified in @acl + // implement external dao for classes that need findByName + // for maps, specify access to be checkd on key or value. + // Find the controlled entity DBid by uuid + + if (parameterAnnotation.entityType() != null && parameterAnnotation.entityType().length > 0 + && parameterAnnotation.entityType()[0].getAnnotation(EntityReference.class) != null) { final Class[] entityList = parameterAnnotation.entityType()[0].getAnnotation(EntityReference.class).value(); - for (final Class entity : entityList) { - // Check if the parameter type is a single - // Id or list of id's/name's - switch (fieldType) { - case LIST: - final CommandType listType = parameterAnnotation.collectionType(); - switch (listType) { - case LONG: - case UUID: - final List listParam = (List)field.get(cmd); - for (final Long entityId : listParam) { + // Check if the parameter type is a single + // Id or list of id's/name's + switch (fieldType) { + case LIST: + final CommandType listType = parameterAnnotation.collectionType(); + switch (listType) { + case LONG: + case UUID: + final List listParam = (List) field.get(cmd); + for (final Long entityId : listParam) { + for (final Class entity : entityList) { final Object entityObj = _entityMgr.findById(entity, entityId); - entitiesToAccess.put(entityObj, checkAccess.accessType()); + if(entityObj != null){ + entitiesToAccess.put(entityObj, checkAccess.accessType()); + break; + } } - break; - /* - * case STRING: List listParam = - * new ArrayList(); listParam = - * (List)field.get(cmd); for(String - * entityName: listParam){ - * ControlledEntity entityObj = - * (ControlledEntity - * )daoClassInstance(entityId); - * entitiesToAccess.add(entityObj); } - * break; - */ - default: - break; - } - break; - case LONG: - case UUID: - final Object entityObj = _entityMgr.findById(entity, (Long)field.get(cmd)); - entitiesToAccess.put(entityObj, checkAccess.accessType()); - break; - default: - break; - } - - if (ControlledEntity.class.isAssignableFrom(entity)) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("ControlledEntity name is:" + entity.getName()); + } + break; + /* + * case STRING: List listParam = new + * ArrayList(); listParam = + * (List)field.get(cmd); for(String entityName: + * listParam){ ControlledEntity entityObj = + * (ControlledEntity )daoClassInstance(entityId); + * entitiesToAccess.add(entityObj); } break; + */ + default: + break; } - } - - if (InfrastructureEntity.class.isAssignableFrom(entity)) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("InfrastructureEntity name is:" + entity.getName()); + break; + case LONG: + case UUID: + for (final Class entity : entityList) { + final Object entityObj = _entityMgr.findById(entity, (Long) field.get(cmd)); + if(entityObj != null){ + entitiesToAccess.put(entityObj, checkAccess.accessType()); + break; + } } - } + break; + default: + break; } - } - } } catch (final IllegalArgumentException e) { @@ -213,29 +217,29 @@ public void processParameters(final BaseCmd cmd, final Map params) { } - private void doAccessChecks(final BaseCmd cmd, final Map entitiesToAccess) { - final Account caller = CallContext.current().getCallingAccount(); - final Account owner = _accountMgr.getActiveAccountById(cmd.getEntityOwnerId()); + private void doAccessChecks(BaseCmd cmd, Map entitiesToAccess) { + Account caller = CallContext.current().getCallingAccount(); + Account owner = _accountMgr.getActiveAccountById(cmd.getEntityOwnerId()); if (cmd instanceof BaseAsyncCreateCmd) { - //check that caller can access the owner account. + // check that caller can access the owner account. _accountMgr.checkAccess(caller, null, true, owner); } if (!entitiesToAccess.isEmpty()) { - //check that caller can access the owner account. + // check that caller can access the owner account. _accountMgr.checkAccess(caller, null, true, owner); - for (final Object entity : entitiesToAccess.keySet()) { + for (Object entity : entitiesToAccess.keySet()) { if (entity instanceof ControlledEntity) { - _accountMgr.checkAccess(caller, entitiesToAccess.get(entity), true, (ControlledEntity)entity); + _accountMgr.checkAccess(caller, entitiesToAccess.get(entity), true, (ControlledEntity) entity); } else if (entity instanceof InfrastructureEntity) { - //FIXME: Move this code in adapter, remove code from Account manager + // FIXME: Move this code in adapter, remove code from + // Account manager } } } } - @SuppressWarnings({"unchecked", "rawtypes"}) private void setFieldValue(final Field field, final BaseCmd cmdObj, final Object paramObj, final Parameter annotation) throws IllegalArgumentException, ParseException { try { @@ -384,6 +388,11 @@ private Long translateUuidToInternalId(final String uuid, final Parameter annota // Enforce that it's uuid for newly added apis from version 3.x if (!isPre3x && !isUuid) return null; + + // There may be multiple entities defined on the @EntityReference of a Response.class + // UUID CommandType would expect only one entityType, so use the first entityType + final Class[] entities = annotation.entityType()[0].getAnnotation(EntityReference.class).value(); + // Allow both uuid and internal id for pre3x apis if (isPre3x && !isUuid) { try { @@ -391,12 +400,15 @@ private Long translateUuidToInternalId(final String uuid, final Parameter annota } catch (final NumberFormatException e) { internalId = null; } - if (internalId != null) + if (internalId != null){ + // Populate CallContext for each of the entity. + for (final Class entity : entities) { + CallContext.current().putContextParameter(entity.getName(), internalId); + } return internalId; + } } - // There may be multiple entities defined on the @EntityReference of a Response.class - // UUID CommandType would expect only one entityType, so use the first entityType - final Class[] entities = annotation.entityType()[0].getAnnotation(EntityReference.class).value(); + // Go through each entity which is an interface to a VO class and get a VO object // Try to getId() for the object using reflection, break on first non-null value for (final Class entity : entities) { @@ -407,15 +419,17 @@ private Long translateUuidToInternalId(final String uuid, final Parameter annota continue; } // Invoke the getId method, get the internal long ID - // If that fails hide exceptions as the uuid may not exist + // If that fails hide exceptions as the uuid may not exist s try { internalId = ((InternalIdentity)objVO).getId(); } catch (final IllegalArgumentException e) { } catch (final NullPointerException e) { } // Return on first non-null Id for the uuid entity - if (internalId != null) + if (internalId != null){ + CallContext.current().putContextParameter(entity.getName(), uuid); break; + } } if (internalId == null) { if (s_logger.isDebugEnabled()) diff --git a/server/src/com/cloud/api/doc/ApiXmlDocWriter.java b/server/src/com/cloud/api/doc/ApiXmlDocWriter.java index c19f7af8c3..0194f07c2c 100644 --- a/server/src/com/cloud/api/doc/ApiXmlDocWriter.java +++ b/server/src/com/cloud/api/doc/ApiXmlDocWriter.java @@ -105,10 +105,21 @@ public static void main(String[] args) { for (Class cmdClass : cmdClasses) { String apiName = cmdClass.getAnnotation(APICommand.class).name(); if (s_apiNameCmdClassMap.containsKey(apiName)) { - System.out.println("Warning, API Cmd class " + cmdClass.getName() + " has non-unique apiname" + apiName); - continue; + // handle API cmd separation into admin cmd and user cmd with the common api name + Class curCmd = s_apiNameCmdClassMap.get(apiName); + if (curCmd.isAssignableFrom(cmdClass)) { + // api_cmd map always keep the admin cmd class to get full response and parameters + s_apiNameCmdClassMap.put(apiName, cmdClass); + } else if (cmdClass.isAssignableFrom(curCmd)) { + // just skip this one without warning + continue; + } else { + System.out.println("Warning, API Cmd class " + cmdClass.getName() + " has non-unique apiname " + apiName); + continue; + } + } else { + s_apiNameCmdClassMap.put(apiName, cmdClass); } - s_apiNameCmdClassMap.put(apiName, cmdClass); } LinkedProperties preProcessedCommands = new LinkedProperties(); diff --git a/server/src/com/cloud/api/query/QueryManagerImpl.java b/server/src/com/cloud/api/query/QueryManagerImpl.java index b932d422db..1182be575a 100644 --- a/server/src/com/cloud/api/query/QueryManagerImpl.java +++ b/server/src/com/cloud/api/query/QueryManagerImpl.java @@ -92,6 +92,7 @@ import org.apache.cloudstack.api.response.ZoneResponse; import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreCapabilities; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreDriver; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateState; @@ -477,9 +478,7 @@ public ListResponse searchForEvents(ListEventsCmd cmd) { private Pair, Integer> searchForEventsInternal(ListEventsCmd cmd) { Account caller = CallContext.current().getCallingAccount(); - List permittedDomains = new ArrayList(); List permittedAccounts = new ArrayList(); - List permittedResources = new ArrayList(); Long id = cmd.getId(); String type = cmd.getType(); @@ -492,14 +491,16 @@ private Pair, Integer> searchForEventsInternal(ListEventsCmd c Ternary domainIdRecursiveListProject = new Ternary( cmd.getDomainId(), cmd.isRecursive(), null); - _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedDomains, permittedAccounts, permittedResources, - domainIdRecursiveListProject, cmd.listAll(), false, "listEvents"); - //Long domainId = domainIdRecursiveListProject.first(); + _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, + domainIdRecursiveListProject, cmd.listAll(), false); + Long domainId = domainIdRecursiveListProject.first(); Boolean isRecursive = domainIdRecursiveListProject.second(); ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third(); Filter searchFilter = new Filter(EventJoinVO.class, "createDate", false, cmd.getStartIndex(), cmd.getPageSizeVal()); SearchBuilder sb = _eventJoinDao.createSearchBuilder(); + _accountMgr.buildACLViewSearchBuilder(sb, domainId, isRecursive, permittedAccounts, + listProjectResourcesCriteria); sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); sb.and("levelL", sb.entity().getLevel(), SearchCriteria.Op.LIKE); @@ -515,9 +516,9 @@ private Pair, Integer> searchForEventsInternal(ListEventsCmd c sb.and("archived", sb.entity().getArchived(), SearchCriteria.Op.EQ); SearchCriteria sc = sb.create(); - SearchCriteria aclSc = _eventJoinDao.createSearchCriteria(); - // building ACL search criteria - _accountMgr.buildACLViewSearchCriteria(sc, aclSc, isRecursive, permittedDomains, permittedAccounts, permittedResources, listProjectResourcesCriteria); + // building ACL condition + _accountMgr.buildACLViewSearchCriteria(sc, domainId, isRecursive, permittedAccounts, + listProjectResourcesCriteria); // For end users display only enabled events if (!_accountMgr.isRootAdmin(caller.getId())) { @@ -596,9 +597,7 @@ public ListResponse listTags(ListTagsCmd cmd) { private Pair, Integer> listTagsInternal(ListTagsCmd cmd) { Account caller = CallContext.current().getCallingAccount(); - List permittedDomains = new ArrayList(); List permittedAccounts = new ArrayList(); - List permittedResources = new ArrayList(); String key = cmd.getKey(); String value = cmd.getValue(); String resourceId = cmd.getResourceId(); @@ -609,14 +608,16 @@ private Pair, Integer> listTagsInternal(ListTagsCmd cmd) Ternary domainIdRecursiveListProject = new Ternary(cmd.getDomainId(), cmd.isRecursive(), null); - _accountMgr.buildACLSearchParameters(caller, null, cmd.getAccountName(), cmd.getProjectId(), permittedDomains, permittedAccounts, permittedResources, - domainIdRecursiveListProject, listAll, false, "listTags"); + _accountMgr.buildACLSearchParameters(caller, null, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, + domainIdRecursiveListProject, listAll, false); Long domainId = domainIdRecursiveListProject.first(); Boolean isRecursive = domainIdRecursiveListProject.second(); ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third(); Filter searchFilter = new Filter(ResourceTagJoinVO.class, "resourceType", false, cmd.getStartIndex(), cmd.getPageSizeVal()); SearchBuilder sb = _resourceTagJoinDao.createSearchBuilder(); + _accountMgr.buildACLViewSearchBuilder(sb, domainId, isRecursive, permittedAccounts, + listProjectResourcesCriteria); sb.and("key", sb.entity().getKey(), SearchCriteria.Op.EQ); sb.and("value", sb.entity().getValue(), SearchCriteria.Op.EQ); @@ -632,9 +633,8 @@ private Pair, Integer> listTagsInternal(ListTagsCmd cmd) // now set the SC criteria... SearchCriteria sc = sb.create(); - SearchCriteria aclSc = _resourceTagJoinDao.createSearchCriteria(); - // building ACL search criteria - _accountMgr.buildACLViewSearchCriteria(sc, aclSc, isRecursive, permittedDomains, permittedAccounts, permittedResources, listProjectResourcesCriteria); + _accountMgr.buildACLViewSearchCriteria(sc, domainId, isRecursive, permittedAccounts, + listProjectResourcesCriteria); if (key != null) { sc.setParameters("key", key); @@ -676,14 +676,12 @@ private Pair, Integer> searchForVmGroupsInternal(ListV String keyword = cmd.getKeyword(); Account caller = CallContext.current().getCallingAccount(); - List permittedDomains = new ArrayList(); List permittedAccounts = new ArrayList(); - List permittedResources = new ArrayList(); Ternary domainIdRecursiveListProject = new Ternary( cmd.getDomainId(), cmd.isRecursive(), null); - _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedDomains, permittedAccounts, permittedResources, - domainIdRecursiveListProject, cmd.listAll(), false, "listInstanceGroups"); + _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, + domainIdRecursiveListProject, cmd.listAll(), false); Long domainId = domainIdRecursiveListProject.first(); Boolean isRecursive = domainIdRecursiveListProject.second(); ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third(); @@ -691,14 +689,15 @@ private Pair, Integer> searchForVmGroupsInternal(ListV Filter searchFilter = new Filter(InstanceGroupJoinVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal()); SearchBuilder sb = _vmGroupJoinDao.createSearchBuilder(); + _accountMgr.buildACLViewSearchBuilder(sb, domainId, isRecursive, permittedAccounts, + listProjectResourcesCriteria); sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); sb.and("name", sb.entity().getName(), SearchCriteria.Op.LIKE); SearchCriteria sc = sb.create(); - SearchCriteria aclSc = _vmGroupJoinDao.createSearchCriteria(); - // building ACL search criteria - _accountMgr.buildACLViewSearchCriteria(sc, aclSc, isRecursive, permittedDomains, permittedAccounts, permittedResources, listProjectResourcesCriteria); + _accountMgr.buildACLViewSearchCriteria(sc, domainId, isRecursive, permittedAccounts, + listProjectResourcesCriteria); if (keyword != null) { @@ -735,9 +734,7 @@ public ListResponse searchForUserVMs(ListVMsCmd cmd) { private Pair, Integer> searchForUserVMsInternal(ListVMsCmd cmd) { Account caller = CallContext.current().getCallingAccount(); - List permittedDomains = new ArrayList(); List permittedAccounts = new ArrayList(); - List permittedResources = new ArrayList(); boolean listAll = cmd.listAll(); Long id = cmd.getId(); @@ -745,9 +742,9 @@ private Pair, Integer> searchForUserVMsInternal(ListVMsCmd cm Boolean display = cmd.getDisplay(); Ternary domainIdRecursiveListProject = new Ternary( cmd.getDomainId(), cmd.isRecursive(), null); - _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedDomains, permittedAccounts, permittedResources, - domainIdRecursiveListProject, listAll, false, "listVirtualMachines"); - //Long domainId = domainIdRecursiveListProject.first(); + _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, + domainIdRecursiveListProject, listAll, false); + Long domainId = domainIdRecursiveListProject.first(); Boolean isRecursive = domainIdRecursiveListProject.second(); ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third(); @@ -769,6 +766,9 @@ private Pair, Integer> searchForUserVMsInternal(ListVMsCmd cm SearchBuilder sb = _userVmJoinDao.createSearchBuilder(); sb.select(null, Func.DISTINCT, sb.entity().getId()); // select distinct ids + _accountMgr.buildACLViewSearchBuilder(sb, domainId, isRecursive, permittedAccounts, + listProjectResourcesCriteria); + String hypervisor = cmd.getHypervisor(); Object name = cmd.getName(); Object state = cmd.getState(); @@ -776,7 +776,7 @@ private Pair, Integer> searchForUserVMsInternal(ListVMsCmd cm Object keyword = cmd.getKeyword(); boolean isAdmin = false; boolean isRootAdmin = false; - if (_accountMgr.isAdmin(caller.getType())) { + if (_accountMgr.isAdmin(caller.getId())) { isAdmin = true; } if (_accountMgr.isRootAdmin(caller.getId())) { @@ -850,11 +850,10 @@ private Pair, Integer> searchForUserVMsInternal(ListVMsCmd cm // populate the search criteria with the values passed in SearchCriteria sc = sb.create(); - SearchCriteria aclSc = _userVmJoinDao.createSearchCriteria(); - - // building ACL search criteria - _accountMgr.buildACLViewSearchCriteria(sc, aclSc, isRecursive, permittedDomains, permittedAccounts, permittedResources, listProjectResourcesCriteria); + // building ACL condition + _accountMgr.buildACLViewSearchCriteria(sc, domainId, isRecursive, permittedAccounts, + listProjectResourcesCriteria); if (tags != null && !tags.isEmpty()) { SearchCriteria tagSc = _userVmJoinDao.createSearchCriteria(); @@ -995,9 +994,7 @@ private Pair, Integer> searchForSecurityGroupsInternal String securityGroup = cmd.getSecurityGroupName(); Long id = cmd.getId(); Object keyword = cmd.getKeyword(); - List permittedDomains = new ArrayList(); List permittedAccounts = new ArrayList(); - List permittedResources = new ArrayList(); Map tags = cmd.getTags(); if (instanceId != null) { @@ -1011,8 +1008,8 @@ private Pair, Integer> searchForSecurityGroupsInternal Ternary domainIdRecursiveListProject = new Ternary( cmd.getDomainId(), cmd.isRecursive(), null); - _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedDomains, permittedAccounts, permittedResources, - domainIdRecursiveListProject, cmd.listAll(), false, "listSecurityGroups"); + _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, + domainIdRecursiveListProject, cmd.listAll(), false); Long domainId = domainIdRecursiveListProject.first(); Boolean isRecursive = domainIdRecursiveListProject.second(); ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third(); @@ -1021,13 +1018,15 @@ private Pair, Integer> searchForSecurityGroupsInternal SearchBuilder sb = _securityGroupJoinDao.createSearchBuilder(); sb.select(null, Func.DISTINCT, sb.entity().getId()); // select distinct // ids + _accountMgr.buildACLViewSearchBuilder(sb, domainId, isRecursive, permittedAccounts, + listProjectResourcesCriteria); + sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ); SearchCriteria sc = sb.create(); - SearchCriteria aclSc = _securityGroupJoinDao.createSearchCriteria(); - // building ACL search criteria - _accountMgr.buildACLViewSearchCriteria(sc, aclSc, isRecursive, permittedDomains, permittedAccounts, permittedResources, listProjectResourcesCriteria); + _accountMgr.buildACLViewSearchCriteria(sc, domainId, isRecursive, permittedAccounts, + listProjectResourcesCriteria); if (id != null) { sc.setParameters("id", id); @@ -1119,19 +1118,12 @@ private Pair, Integer> searchForRoutersInternal(BaseLis Long podId, Long clusterId, Long hostId, String keyword, Long networkId, Long vpcId, Boolean forVpc, String role, String version) { Account caller = CallContext.current().getCallingAccount(); - List permittedDomains = new ArrayList(); List permittedAccounts = new ArrayList(); - List permittedResources = new ArrayList(); Ternary domainIdRecursiveListProject = new Ternary( cmd.getDomainId(), cmd.isRecursive(), null); - String action = "listRouters"; - if (cmd instanceof ListInternalLBVMsCmd) { - action = "listInternalLoadBalancerVMs"; - } - _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedDomains, permittedAccounts, permittedResources, - domainIdRecursiveListProject, cmd.listAll(), false, action); - + _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, + domainIdRecursiveListProject, cmd.listAll(), false); Long domainId = domainIdRecursiveListProject.first(); Boolean isRecursive = domainIdRecursiveListProject.second(); ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third(); @@ -1144,6 +1136,8 @@ private Pair, Integer> searchForRoutersInternal(BaseLis // number of // records with // pagination + _accountMgr.buildACLViewSearchBuilder(sb, domainId, isRecursive, permittedAccounts, + listProjectResourcesCriteria); sb.and("name", sb.entity().getInstanceName(), SearchCriteria.Op.LIKE); sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); @@ -1170,9 +1164,8 @@ private Pair, Integer> searchForRoutersInternal(BaseLis } SearchCriteria sc = sb.create(); - SearchCriteria aclSc = _routerJoinDao.createSearchCriteria(); - // building ACL search criteria - _accountMgr.buildACLViewSearchCriteria(sc, aclSc, isRecursive, permittedDomains, permittedAccounts, permittedResources, listProjectResourcesCriteria); + _accountMgr.buildACLViewSearchCriteria(sc, domainId, isRecursive, permittedAccounts, + listProjectResourcesCriteria); if (keyword != null) { SearchCriteria ssc = _routerJoinDao.createSearchCriteria(); @@ -1278,7 +1271,7 @@ private Pair, Integer> listProjectsInternal(ListProjectsCmd sb.select(null, Func.DISTINCT, sb.entity().getId()); // select distinct // ids - if (_accountMgr.isAdmin(caller.getType())) { + if (_accountMgr.isAdmin(caller.getId())) { if (domainId != null) { DomainVO domain = _domainDao.findById(domainId); if (domain == null) { @@ -1405,21 +1398,20 @@ public Pair, Integer> listProjectInvitationsIntern boolean listAll = cmd.listAll(); Account caller = CallContext.current().getCallingAccount(); - List permittedDomains = new ArrayList(); List permittedAccounts = new ArrayList(); - List permittedResources = new ArrayList(); Ternary domainIdRecursiveListProject = new Ternary( domainId, isRecursive, null); - _accountMgr.buildACLSearchParameters(caller, id, accountName, projectId, permittedDomains, permittedAccounts, permittedResources, - domainIdRecursiveListProject, listAll, true, "listProjectInvitations"); - //domainId = domainIdRecursiveListProject.first(); - + _accountMgr.buildACLSearchParameters(caller, id, accountName, projectId, permittedAccounts, + domainIdRecursiveListProject, listAll, true); + domainId = domainIdRecursiveListProject.first(); isRecursive = domainIdRecursiveListProject.second(); ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third(); Filter searchFilter = new Filter(ProjectInvitationJoinVO.class, "id", true, startIndex, pageSizeVal); SearchBuilder sb = _projectInvitationJoinDao.createSearchBuilder(); + _accountMgr.buildACLViewSearchBuilder(sb, domainId, isRecursive, permittedAccounts, + listProjectResourcesCriteria); sb.and("projectId", sb.entity().getProjectId(), SearchCriteria.Op.EQ); sb.and("state", sb.entity().getState(), SearchCriteria.Op.EQ); @@ -1427,9 +1419,8 @@ public Pair, Integer> listProjectInvitationsIntern sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); SearchCriteria sc = sb.create(); - SearchCriteria aclSc = _projectInvitationJoinDao.createSearchCriteria(); - // building ACL search criteria - _accountMgr.buildACLViewSearchCriteria(sc, aclSc, isRecursive, permittedDomains, permittedAccounts, permittedResources, listProjectResourcesCriteria); + _accountMgr.buildACLViewSearchCriteria(sc, domainId, isRecursive, permittedAccounts, + listProjectResourcesCriteria); if (projectId != null) { sc.setParameters("projectId", projectId); @@ -1482,7 +1473,7 @@ public Pair, Integer> listProjectAccountsInternal(Lis // verify permissions - only accounts belonging to the project can list // project's account - if (!_accountMgr.isAdmin(caller.getType()) && _projectAccountDao.findByProjectIdAccountId(projectId, caller.getAccountId()) == null) { + if (!_accountMgr.isAdmin(caller.getId()) && _projectAccountDao.findByProjectIdAccountId(projectId, caller.getAccountId()) == null) { throw new PermissionDeniedException("Account " + caller + " is not authorized to list users of the project id=" + projectId); } @@ -1643,6 +1634,28 @@ public ListResponse searchForVolumes(ListVolumesCmd cmd) { List volumeResponses = ViewResponseHelper.createVolumeResponse(respView, result.first().toArray( new VolumeJoinVO[result.first().size()])); + for(VolumeResponse vr : volumeResponses) { + String poolId = vr.getStoragePoolId(); + if (poolId == null) { + continue; + } + + DataStore store = dataStoreManager.getPrimaryDataStore(poolId); + if (store == null) { + continue; + } + + DataStoreDriver driver = store.getDriver(); + if (driver == null) { + continue; + } + + Map caps = driver.getCapabilities(); + if (caps != null) { + boolean quiescevm = Boolean.parseBoolean(caps.get(DataStoreCapabilities.VOLUME_SNAPSHOT_QUIESCEVM.toString())); + vr.setNeedQuiescevm(quiescevm); + } + } response.setResponses(volumeResponses, result.second()); return response; } @@ -1650,9 +1663,7 @@ public ListResponse searchForVolumes(ListVolumesCmd cmd) { private Pair, Integer> searchForVolumesInternal(ListVolumesCmd cmd) { Account caller = CallContext.current().getCallingAccount(); - List permittedDomains = new ArrayList(); List permittedAccounts = new ArrayList(); - List permittedResources = new ArrayList(); Long id = cmd.getId(); Long vmInstanceId = cmd.getVirtualMachineId(); @@ -1669,9 +1680,9 @@ private Pair, Integer> searchForVolumesInternal(ListVolumesCm Ternary domainIdRecursiveListProject = new Ternary( cmd.getDomainId(), cmd.isRecursive(), null); - _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedDomains, permittedAccounts, permittedResources, - domainIdRecursiveListProject, cmd.listAll(), false, "listVolumes"); -// Long domainId = domainIdRecursiveListProject.first(); + _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, + domainIdRecursiveListProject, cmd.listAll(), false); + Long domainId = domainIdRecursiveListProject.first(); Boolean isRecursive = domainIdRecursiveListProject.second(); ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third(); Filter searchFilter = new Filter(VolumeJoinVO.class, "created", false, cmd.getStartIndex(), cmd.getPageSizeVal()); @@ -1685,6 +1696,8 @@ private Pair, Integer> searchForVolumesInternal(ListVolumesCm // number of // records with // pagination + _accountMgr.buildACLViewSearchBuilder(sb, domainId, isRecursive, permittedAccounts, + listProjectResourcesCriteria); sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ); sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); @@ -1708,10 +1721,8 @@ private Pair, Integer> searchForVolumesInternal(ListVolumesCm // now set the SC criteria... SearchCriteria sc = sb.create(); - SearchCriteria aclSc = _volumeJoinDao.createSearchCriteria(); - - // building ACL search criteria - _accountMgr.buildACLViewSearchCriteria(sc, aclSc, isRecursive, permittedDomains, permittedAccounts, permittedResources, listProjectResourcesCriteria); + _accountMgr.buildACLViewSearchCriteria(sc, domainId, isRecursive, permittedAccounts, + listProjectResourcesCriteria); if (keyword != null) { SearchCriteria ssc = _volumeJoinDao.createSearchCriteria(); @@ -1726,7 +1737,7 @@ private Pair, Integer> searchForVolumesInternal(ListVolumesCm } if (display != null) { - sc.setParameters("display", display); + sc.setParameters("displayVolume", display); } sc.setParameters("systemUse", 1); @@ -1839,20 +1850,21 @@ private Pair, Integer> searchForAccountsInternal(ListAccount if (accountName != null) { Account account = _accountDao.findActiveAccount(accountName, domainId); if (account == null || account.getId() == Account.ACCOUNT_ID_SYSTEM) { - throw new InvalidParameterValueException("Unable to find account by name " + accountName + " in domain " + domainId); + throw new InvalidParameterValueException("Unable to find account by name " + accountName + + " in domain " + domainId); } _accountMgr.checkAccess(caller, null, true, account); } } if (accountId == null) { - if (_accountMgr.isAdmin(caller.getType()) && listAll && domainId == null) { + if (_accountMgr.isAdmin(caller.getId()) && listAll && domainId == null) { listForDomain = true; isRecursive = true; if (domainId == null) { domainId = caller.getDomainId(); } - } else if (_accountMgr.isAdmin(caller.getType()) && domainId != null) { + } else if (_accountMgr.isAdmin(caller.getId()) && domainId != null) { listForDomain = true; } else { accountId = caller.getAccountId(); @@ -1939,20 +1951,17 @@ private Pair, Integer> searchForAsyncJobsInternal(ListAsync Account caller = CallContext.current().getCallingAccount(); - List permittedDomains = new ArrayList(); List permittedAccounts = new ArrayList(); - List permittedResources = new ArrayList(); Ternary domainIdRecursiveListProject = new Ternary( cmd.getDomainId(), cmd.isRecursive(), null); - _accountMgr.buildACLSearchParameters(caller, null, cmd.getAccountName(), null, permittedDomains, permittedAccounts, permittedResources, domainIdRecursiveListProject, - cmd.listAll(), false, "listAsyncJobs"); + _accountMgr.buildACLSearchParameters(caller, null, cmd.getAccountName(), null, permittedAccounts, + domainIdRecursiveListProject, cmd.listAll(), false); Long domainId = domainIdRecursiveListProject.first(); Boolean isRecursive = domainIdRecursiveListProject.second(); ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third(); Filter searchFilter = new Filter(AsyncJobJoinVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal()); - /* SearchBuilder sb = _jobJoinDao.createSearchBuilder(); sb.and("accountIdIN", sb.entity().getAccountId(), SearchCriteria.Op.IN); boolean accountJoinIsDone = false; @@ -1976,7 +1985,8 @@ private Pair, Integer> searchForAsyncJobsInternal(ListAsync } } - + Object keyword = cmd.getKeyword(); + Object startDate = cmd.getStartDate(); SearchCriteria sc = sb.create(); if (listProjectResourcesCriteria != null) { @@ -1993,17 +2003,6 @@ private Pair, Integer> searchForAsyncJobsInternal(ListAsync sc.setParameters("domainId", domainId); } } - */ - - Object keyword = cmd.getKeyword(); - Object startDate = cmd.getStartDate(); - - // populate the search criteria with the values passed in - SearchCriteria sc = _jobJoinDao.createSearchCriteria(); - SearchCriteria aclSc = _jobJoinDao.createSearchCriteria(); - - // building ACL search criteria - _accountMgr.buildACLViewSearchCriteria(sc, aclSc, isRecursive, permittedDomains, permittedAccounts, permittedResources, listProjectResourcesCriteria); if (keyword != null) { sc.addAnd("cmd", SearchCriteria.Op.LIKE, "%" + keyword + "%"); @@ -2547,7 +2546,7 @@ private Pair, Integer> searchForServiceOfferingsInte } if (vmTypeStr != null) { - sc.addAnd("vm_type", SearchCriteria.Op.EQ, vmTypeStr); + sc.addAnd("vmType", SearchCriteria.Op.EQ, vmTypeStr); } return _srvOfferingJoinDao.searchAndCount(sc, searchFilter); @@ -2806,6 +2805,7 @@ public ListResponse listTemplates(ListTemplatesCmd cmd) { return response; } + private Pair, Integer> searchForTemplatesInternal(ListTemplatesCmd cmd) { TemplateFilter templateFilter = TemplateFilter.valueOf(cmd.getTemplateFilter()); Long id = cmd.getId(); @@ -2813,41 +2813,38 @@ private Pair, Integer> searchForTemplatesInternal(ListTempl boolean showRemovedTmpl = cmd.getShowRemoved(); Account caller = CallContext.current().getCallingAccount(); - // TODO: listAll flag has some conflicts with TemplateFilter parameter boolean listAll = false; if (templateFilter != null && templateFilter == TemplateFilter.all) { - if (_accountMgr.isNormalUser(caller.getId())) { + if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL) { throw new InvalidParameterValueException("Filter " + TemplateFilter.all + " can be specified by admin only"); } listAll = true; } - List permittedDomains = new ArrayList(); - List permittedAccounts = new ArrayList(); - List permittedResources = new ArrayList(); - + List permittedAccountIds = new ArrayList(); Ternary domainIdRecursiveListProject = new Ternary( cmd.getDomainId(), cmd.isRecursive(), null); - _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedDomains, permittedAccounts, permittedResources, - domainIdRecursiveListProject, listAll, false, "listTemplates"); - - Boolean isRecursive = domainIdRecursiveListProject.second(); + _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccountIds, + domainIdRecursiveListProject, listAll, false); ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third(); + List permittedAccounts = new ArrayList(); + for (Long accountId : permittedAccountIds) { + permittedAccounts.add(_accountMgr.getAccount(accountId)); + } boolean showDomr = ((templateFilter != TemplateFilter.selfexecutable) && (templateFilter != TemplateFilter.featured)); HypervisorType hypervisorType = HypervisorType.getType(cmd.getHypervisor()); return searchForTemplatesInternal(id, cmd.getTemplateName(), cmd.getKeyword(), templateFilter, false, null, cmd.getPageSizeVal(), cmd.getStartIndex(), cmd.getZoneId(), hypervisorType, showDomr, - cmd.listInReadyState(), permittedDomains, permittedAccounts, permittedResources, isRecursive, caller, listProjectResourcesCriteria, tags, showRemovedTmpl); + cmd.listInReadyState(), permittedAccounts, caller, listProjectResourcesCriteria, tags, showRemovedTmpl); } private Pair, Integer> searchForTemplatesInternal(Long templateId, String name, String keyword, TemplateFilter templateFilter, boolean isIso, Boolean bootable, Long pageSize, Long startIndex, Long zoneId, HypervisorType hyperType, boolean showDomr, boolean onlyReady, - List permittedDomains, List permittedAccounts, List permittedResources, boolean isRecursive, Account caller, - ListProjectResourcesCriteria listProjectResourcesCriteria, + List permittedAccounts, Account caller, ListProjectResourcesCriteria listProjectResourcesCriteria, Map tags, boolean showRemovedTmpl) { // check if zone is configured, if not, just return empty list @@ -2877,19 +2874,21 @@ private Pair, Integer> searchForTemplatesInternal(Long temp }// If ISO requested then it should be ISO. if (isIso && template.getFormat() != ImageFormat.ISO) { s_logger.error("Template Id " + templateId + " is not an ISO"); - InvalidParameterValueException ex = new InvalidParameterValueException("Specified Template Id is not an ISO"); + InvalidParameterValueException ex = new InvalidParameterValueException( + "Specified Template Id is not an ISO"); ex.addProxyObject(template.getUuid(), "templateId"); throw ex; }// If ISO not requested then it shouldn't be an ISO. if (!isIso && template.getFormat() == ImageFormat.ISO) { s_logger.error("Incorrect format of the template id " + templateId); - InvalidParameterValueException ex = new InvalidParameterValueException("Incorrect format " + template.getFormat() + " of the specified template id"); + InvalidParameterValueException ex = new InvalidParameterValueException("Incorrect format " + + template.getFormat() + " of the specified template id"); ex.addProxyObject(template.getUuid(), "templateId"); throw ex; } // if template is not public, perform permission check here - if (!template.isPublicTemplate() && !_accountMgr.isRootAdmin(caller.getId())) { + if (!template.isPublicTemplate() && caller.getType() != Account.ACCOUNT_TYPE_ADMIN) { Account owner = _accountMgr.getAccount(template.getAccountId()); _accountMgr.checkAccess(caller, null, true, owner); } @@ -2898,6 +2897,64 @@ private Pair, Integer> searchForTemplatesInternal(Long temp // search and ignore other query parameters sc.addAnd("id", SearchCriteria.Op.EQ, templateId); } else { + + DomainVO domain = null; + if (!permittedAccounts.isEmpty()) { + domain = _domainDao.findById(permittedAccounts.get(0).getDomainId()); + } else { + domain = _domainDao.findById(Domain.ROOT_DOMAIN); + } + + // List hypers = null; + // if (!isIso) { + // hypers = _resourceMgr.listAvailHypervisorInZone(null, null); + // } + + // add criteria for project or not + if (listProjectResourcesCriteria == ListProjectResourcesCriteria.SkipProjectResources) { + sc.addAnd("accountType", SearchCriteria.Op.NEQ, Account.ACCOUNT_TYPE_PROJECT); + } else if (listProjectResourcesCriteria == ListProjectResourcesCriteria.ListProjectResourcesOnly) { + sc.addAnd("accountType", SearchCriteria.Op.EQ, Account.ACCOUNT_TYPE_PROJECT); + } + + // add criteria for domain path in case of domain admin + if ((templateFilter == TemplateFilter.self || templateFilter == TemplateFilter.selfexecutable) + && (caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN || caller.getType() == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN)) { + sc.addAnd("domainPath", SearchCriteria.Op.LIKE, domain.getPath() + "%"); + } + + List relatedDomainIds = new ArrayList(); + List permittedAccountIds = new ArrayList(); + if (!permittedAccounts.isEmpty()) { + for (Account account : permittedAccounts) { + permittedAccountIds.add(account.getId()); + boolean publicTemplates = (templateFilter == TemplateFilter.featured || templateFilter == TemplateFilter.community); + + // get all parent domain ID's all the way till root domain + DomainVO domainTreeNode = null; + //if template filter is featured, or community, all child domains should be included in search + if (publicTemplates) { + domainTreeNode = _domainDao.findById(Domain.ROOT_DOMAIN); + + } else { + domainTreeNode = _domainDao.findById(account.getDomainId()); + } + relatedDomainIds.add(domainTreeNode.getId()); + while (domainTreeNode.getParent() != null) { + domainTreeNode = _domainDao.findById(domainTreeNode.getParent()); + relatedDomainIds.add(domainTreeNode.getId()); + } + + // get all child domain ID's + if (_accountMgr.isAdmin(account.getId()) || publicTemplates) { + List allChildDomains = _domainDao.findAllChildren(domainTreeNode.getPath(), domainTreeNode.getId()); + for (DomainVO childDomain : allChildDomains) { + relatedDomainIds.add(childDomain.getId()); + } + } + } + } + if (!isIso) { // add hypervisor criteria for template case if (hypers != null && !hypers.isEmpty()) { @@ -2910,7 +2967,6 @@ private Pair, Integer> searchForTemplatesInternal(Long temp } // control different template filters - DomainVO callerDomain = _domainDao.findById(caller.getDomainId()); if (templateFilter == TemplateFilter.featured || templateFilter == TemplateFilter.community) { sc.addAnd("publicTemplate", SearchCriteria.Op.EQ, true); if (templateFilter == TemplateFilter.featured) { @@ -2918,59 +2974,24 @@ private Pair, Integer> searchForTemplatesInternal(Long temp } else { sc.addAnd("featured", SearchCriteria.Op.EQ, false); } - - /* We don't need this any more to check domain id, based on CLOUDSTACK-5987 - // for public templates, we should get all public templates from all domains in the system - // get all parent domain ID's all the way till root domain - List domainTree = new ArrayList(); - DomainVO domainTreeNode = _domainDao.findById(Domain.ROOT_DOMAIN); // fix for CLOUDSTACK-5987 - domainTree.add(domainTreeNode.getId()); - - // get all child domain ID's under root - List allChildDomains = _domainDao.findAllChildren(domainTreeNode.getPath(), domainTreeNode.getId()); - for (DomainVO childDomain : allChildDomains) { - domainTree.add(childDomain.getId()); + if (!permittedAccounts.isEmpty()) { + SearchCriteria scc = _templateJoinDao.createSearchCriteria(); + scc.addOr("domainId", SearchCriteria.Op.IN, relatedDomainIds.toArray()); + scc.addOr("domainId", SearchCriteria.Op.NULL); + sc.addAnd("domainId", SearchCriteria.Op.SC, scc); } - - SearchCriteria scc = _templateJoinDao.createSearchCriteria(); - scc.addOr("domainId", SearchCriteria.Op.IN, domainTree.toArray()); - scc.addOr("domainId", SearchCriteria.Op.NULL); - sc.addAnd("domainId", SearchCriteria.Op.SC, scc); - */ } else if (templateFilter == TemplateFilter.self || templateFilter == TemplateFilter.selfexecutable) { - if (permittedDomains.contains(caller.getDomainId())) { - // this caller acts like a domain admin - - sc.addAnd("domainPath", SearchCriteria.Op.LIKE, callerDomain.getPath() + "%"); - } else { - // only display templates owned by caller for resource owner only - sc.addAnd("accountId", SearchCriteria.Op.EQ, caller.getAccountId()); + if (!permittedAccounts.isEmpty()) { + sc.addAnd("accountId", SearchCriteria.Op.IN, permittedAccountIds.toArray()); } } else if (templateFilter == TemplateFilter.sharedexecutable || templateFilter == TemplateFilter.shared) { - // exclude the caller, only include those granted and not owned by self - permittedDomains.remove(caller.getDomainId()); - permittedAccounts.remove(caller.getAccountId()); - for (Long tid : permittedResources) { - // remove it if it is owned by the caller - VMTemplateVO tmpl = _templateDao.findById(tid); - if (tmpl != null && tmpl.getAccountId() == caller.getAccountId()) { - permittedResources.remove(tid); - } - } - // building ACL search criteria - SearchCriteria aclSc = _templateJoinDao.createSearchCriteria(); - _accountMgr.buildACLViewSearchCriteria(sc, aclSc, isRecursive, permittedDomains, permittedAccounts, permittedResources, listProjectResourcesCriteria); + // only show templates shared by others + sc.addAnd("sharedAccountId", SearchCriteria.Op.IN, permittedAccountIds.toArray()); } else if (templateFilter == TemplateFilter.executable) { - // public template + self template SearchCriteria scc = _templateJoinDao.createSearchCriteria(); scc.addOr("publicTemplate", SearchCriteria.Op.EQ, true); - // plus self owned templates or domain tree templates for domain admin - if (permittedDomains.contains(caller.getDomainId())) { - // this caller acts like a domain admin - sc.addOr("domainPath", SearchCriteria.Op.LIKE, callerDomain.getPath() + "%"); - } else { - // only display templates owned by caller for resource owner only - sc.addOr("accountId", SearchCriteria.Op.EQ, caller.getAccountId()); + if (!permittedAccounts.isEmpty()) { + scc.addOr("accountId", SearchCriteria.Op.IN, permittedAccountIds.toArray()); } sc.addAnd("publicTemplate", SearchCriteria.Op.SC, scc); } @@ -3051,7 +3072,7 @@ private Pair, Integer> searchForTemplatesInternal(Long temp // search unique templates and find details by Ids Pair, Integer> uniqueTmplPair = null; - if(showRemovedTmpl){ + if (showRemovedTmpl) { uniqueTmplPair = _templateJoinDao.searchIncludingRemovedAndCount(sc, searchFilter); } else { sc.addAnd("templateState", SearchCriteria.Op.EQ, State.Active); @@ -3104,35 +3125,32 @@ private Pair, Integer> searchForIsosInternal(ListIsosCmd cm boolean listAll = false; if (isoFilter != null && isoFilter == TemplateFilter.all) { - if (_accountMgr.isNormalUser(caller.getId())) { + if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL) { throw new InvalidParameterValueException("Filter " + TemplateFilter.all + " can be specified by admin only"); } listAll = true; } - List permittedDomains = new ArrayList(); - List permittedAccounts = new ArrayList(); - List permittedResources = new ArrayList(); - + List permittedAccountIds = new ArrayList(); Ternary domainIdRecursiveListProject = new Ternary( cmd.getDomainId(), cmd.isRecursive(), null); - _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedDomains, permittedAccounts, permittedResources, - domainIdRecursiveListProject, cmd.listAll(), false, "listIsos"); - Boolean isRecursive = domainIdRecursiveListProject.second(); + _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccountIds, + domainIdRecursiveListProject, listAll, false); ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third(); -// List permittedAccounts = new ArrayList(); -// for (Long accountId : permittedAccountIds) { -// permittedAccounts.add(_accountMgr.getAccount(accountId)); -// } + List permittedAccounts = new ArrayList(); + for (Long accountId : permittedAccountIds) { + permittedAccounts.add(_accountMgr.getAccount(accountId)); + } HypervisorType hypervisorType = HypervisorType.getType(cmd.getHypervisor()); return searchForTemplatesInternal(cmd.getId(), cmd.getIsoName(), cmd.getKeyword(), isoFilter, true, cmd.isBootable(), cmd.getPageSizeVal(), cmd.getStartIndex(), cmd.getZoneId(), hypervisorType, true, - cmd.listInReadyState(), permittedDomains, permittedAccounts, permittedResources, isRecursive, caller, listProjectResourcesCriteria, tags, showRemovedISO); + cmd.listInReadyState(), permittedAccounts, caller, listProjectResourcesCriteria, tags, showRemovedISO); } + @Override public ListResponse listAffinityGroups(Long affinityGroupId, String affinityGroupName, String affinityGroupType, Long vmId, String accountName, Long domainId, boolean isRecursive, @@ -3157,28 +3175,28 @@ public Pair, Integer> listAffinityGroupsInternal(Long if (vmId != null) { UserVmVO userVM = _userVmDao.findById(vmId); if (userVM == null) { - throw new InvalidParameterValueException("Unable to list affinity groups for virtual machine instance " + vmId + "; instance not found."); + throw new InvalidParameterValueException("Unable to list affinity groups for virtual machine instance " + + vmId + "; instance not found."); } _accountMgr.checkAccess(caller, null, true, userVM); return listAffinityGroupsByVM(vmId.longValue(), startIndex, pageSize); } - List permittedDomains = new ArrayList(); List permittedAccounts = new ArrayList(); - List permittedResources = new ArrayList(); Ternary domainIdRecursiveListProject = new Ternary( domainId, isRecursive, null); - _accountMgr.buildACLSearchParameters(caller, affinityGroupId, accountName, null, permittedDomains, permittedAccounts, permittedResources, - domainIdRecursiveListProject, listAll, true, "listAffinityGroups"); - //domainId = domainIdRecursiveListProject.first(); + _accountMgr.buildACLSearchParameters(caller, affinityGroupId, accountName, null, permittedAccounts, + domainIdRecursiveListProject, listAll, true); + domainId = domainIdRecursiveListProject.first(); isRecursive = domainIdRecursiveListProject.second(); ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third(); Filter searchFilter = new Filter(AffinityGroupJoinVO.class, "id", true, startIndex, pageSize); - SearchCriteria sc = buildAffinityGroupSearchCriteria(isRecursive, - permittedDomains, permittedAccounts, permittedResources, listProjectResourcesCriteria, affinityGroupId, affinityGroupName, affinityGroupType, keyword); + SearchCriteria sc = buildAffinityGroupSearchCriteria(domainId, isRecursive, + permittedAccounts, listProjectResourcesCriteria, affinityGroupId, affinityGroupName, affinityGroupType, keyword); - Pair, Integer> uniqueGroupsPair = _affinityGroupJoinDao.searchAndCount(sc, searchFilter); + Pair, Integer> uniqueGroupsPair = _affinityGroupJoinDao.searchAndCount(sc, + searchFilter); // search group details by ids List vrs = new ArrayList(); Integer count = uniqueGroupsPair.second(); @@ -3192,7 +3210,6 @@ public Pair, Integer> listAffinityGroupsInternal(Long vrs = _affinityGroupJoinDao.searchByIds(vrIds); } - /* TODO: confirm with Prachi if we still need this complicated logic with new ACL model if (!permittedAccounts.isEmpty()) { // add domain level affinity groups if (domainId != null) { @@ -3218,24 +3235,66 @@ public Pair, Integer> listAffinityGroupsInternal(Long affinityGroupType, keyword); vrs.addAll(listDomainLevelAffinityGroups(scDomain, searchFilter, domainId)); } - */ return new Pair, Integer>(vrs, vrs.size()); } - private SearchCriteria buildAffinityGroupSearchCriteria(boolean isRecursive, - List permittedDomains, List permittedAccounts, List permittedResources, ListProjectResourcesCriteria listProjectResourcesCriteria, + private void buildAffinityGroupViewSearchBuilder(SearchBuilder sb, Long domainId, + boolean isRecursive, List permittedAccounts, ListProjectResourcesCriteria listProjectResourcesCriteria) { + + sb.and("accountIdIN", sb.entity().getAccountId(), SearchCriteria.Op.IN); + sb.and("domainId", sb.entity().getDomainId(), SearchCriteria.Op.EQ); + + if (((permittedAccounts.isEmpty()) && (domainId != null) && isRecursive)) { + // if accountId isn't specified, we can do a domain match for the + // admin case if isRecursive is true + sb.and("domainPath", sb.entity().getDomainPath(), SearchCriteria.Op.LIKE); + } + + if (listProjectResourcesCriteria != null) { + if (listProjectResourcesCriteria == Project.ListProjectResourcesCriteria.ListProjectResourcesOnly) { + sb.and("accountType", sb.entity().getAccountType(), SearchCriteria.Op.EQ); + } else if (listProjectResourcesCriteria == Project.ListProjectResourcesCriteria.SkipProjectResources) { + sb.and("accountType", sb.entity().getAccountType(), SearchCriteria.Op.NEQ); + } + } + + } + + private void buildAffinityGroupViewSearchCriteria(SearchCriteria sc, + Long domainId, boolean isRecursive, List permittedAccounts, ListProjectResourcesCriteria listProjectResourcesCriteria) { + + if (listProjectResourcesCriteria != null) { + sc.setParameters("accountType", Account.ACCOUNT_TYPE_PROJECT); + } + + if (!permittedAccounts.isEmpty()) { + sc.setParameters("accountIdIN", permittedAccounts.toArray()); + } else if (domainId != null) { + DomainVO domain = _domainDao.findById(domainId); + if (isRecursive) { + sc.setParameters("domainPath", domain.getPath() + "%"); + } else { + sc.setParameters("domainId", domainId); + } + } + } + + private SearchCriteria buildAffinityGroupSearchCriteria(Long domainId, boolean isRecursive, + List permittedAccounts, ListProjectResourcesCriteria listProjectResourcesCriteria, Long affinityGroupId, String affinityGroupName, String affinityGroupType, String keyword) { SearchBuilder groupSearch = _affinityGroupJoinDao.createSearchBuilder(); + buildAffinityGroupViewSearchBuilder(groupSearch, domainId, isRecursive, permittedAccounts, + listProjectResourcesCriteria); + groupSearch.select(null, Func.DISTINCT, groupSearch.entity().getId()); // select // distinct SearchCriteria sc = groupSearch.create(); - SearchCriteria aclSc = _affinityGroupJoinDao.createSearchCriteria(); - // building ACL search criteria - _accountMgr.buildACLViewSearchCriteria(sc, aclSc, isRecursive, permittedDomains, permittedAccounts, permittedResources, listProjectResourcesCriteria); + buildAffinityGroupViewSearchCriteria(sc, domainId, isRecursive, permittedAccounts, + listProjectResourcesCriteria); if (affinityGroupId != null) { sc.addAnd("id", SearchCriteria.Op.EQ, affinityGroupId); @@ -3258,7 +3317,6 @@ private SearchCriteria buildAffinityGroupSearchCriteria(boo } return sc; - } private Pair, Integer> listAffinityGroupsByVM(long vmId, long pageInd, long pageSize) { @@ -3321,26 +3379,43 @@ private List listDomainLevelAffinityGroups(SearchCriteria listResourceDetails(ListResourceDetailsCmd cmd) { String key = cmd.getKey(); - Boolean forDisplay = cmd.forDisplay(); + Boolean forDisplay = cmd.getDisplay(); ResourceTag.ResourceObjectType resourceType = cmd.getResourceType(); String resourceIdStr = cmd.getResourceId(); + String value = cmd.getValue(); Long resourceId = null; + + //Validation - 1.1 - resourceId and value cant be null. + if(resourceIdStr == null && value == null){ + throw new InvalidParameterValueException("Insufficient parameters passed for listing by resourceId OR key,value pair. Please check your params and try again."); + } + + //Validation - 1.2 - Value has to be passed along with key. + if(value != null && key == null){ + throw new InvalidParameterValueException("Listing by (key, value) but key is null. Please check the params and try again"); + } + + //Validation - 1.3 if (resourceIdStr != null) { resourceId = _taggedResourceMgr.getResourceId(resourceIdStr, resourceType); + if (resourceId == null) { + throw new InvalidParameterValueException("Cannot find resource with resourceId " + resourceIdStr + " and of resource type " + resourceType); + } } - if (resourceId == null) { - throw new InvalidParameterValueException("Cannot find resource with resourceId " + resourceIdStr + " and of resource type " + resourceType); - } + + List detailList = new ArrayList(); ResourceDetail requestedDetail = null; if (key == null) { detailList = _resourceMetaDataMgr.getDetailsList(resourceId, resourceType, forDisplay); - } else { + } else if (value == null){ requestedDetail = _resourceMetaDataMgr.getDetail(resourceId, resourceType, key); - if (forDisplay != null && requestedDetail.isDisplay() != forDisplay) { + if (requestedDetail != null && forDisplay != null && requestedDetail.isDisplay() != forDisplay) { requestedDetail = null; } + }else { + detailList = _resourceMetaDataMgr.getDetails(resourceType, key, value, forDisplay); } List responseList = new ArrayList(); diff --git a/server/src/com/cloud/api/query/dao/HostJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/HostJoinDaoImpl.java index 6c890fc830..9a4b38efbb 100644 --- a/server/src/com/cloud/api/query/dao/HostJoinDaoImpl.java +++ b/server/src/com/cloud/api/query/dao/HostJoinDaoImpl.java @@ -108,7 +108,13 @@ public HostResponse newHostResponse(HostJoinVO host, EnumSet detail for (VGPUTypesVO vgpuType : vgpuTypes) { VgpuResponse vgpuResponse = new VgpuResponse(); vgpuResponse.setName(vgpuType.getVgpuType()); - vgpuResponse.setCapacity(vgpuType.getRemainingCapacity()); + vgpuResponse.setVideoRam(vgpuType.getVideoRam()); + vgpuResponse.setMaxHeads(vgpuType.getMaxHeads()); + vgpuResponse.setMaxResolutionX(vgpuType.getMaxResolutionX()); + vgpuResponse.setMaxResolutionY(vgpuType.getMaxResolutionY()); + vgpuResponse.setMaxVgpuPerPgpu(vgpuType.getMaxVgpuPerPgpu()); + vgpuResponse.setRemainingCapacity(vgpuType.getRemainingCapacity()); + vgpuResponse.setmaxCapacity(vgpuType.getMaxCapacity()); vgpus.add(vgpuResponse); } gpuResponse.setVgpu(vgpus); diff --git a/server/src/com/cloud/api/query/dao/TemplateJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/TemplateJoinDaoImpl.java index 1cab6e8040..80ef0f6ed7 100644 --- a/server/src/com/cloud/api/query/dao/TemplateJoinDaoImpl.java +++ b/server/src/com/cloud/api/query/dao/TemplateJoinDaoImpl.java @@ -302,7 +302,7 @@ public TemplateResponse newIsoResponse(TemplateJoinVO iso) { Account caller = CallContext.current().getCallingAccount(); boolean isAdmin = false; - if ((caller == null) || _accountService.isAdmin(caller.getType())) { + if ((caller == null) || _accountService.isAdmin(caller.getId())) { isAdmin = true; } diff --git a/server/src/com/cloud/api/query/dao/VolumeJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/VolumeJoinDaoImpl.java index 8a0431baaa..24d09220a8 100644 --- a/server/src/com/cloud/api/query/dao/VolumeJoinDaoImpl.java +++ b/server/src/com/cloud/api/query/dao/VolumeJoinDaoImpl.java @@ -22,13 +22,12 @@ import javax.ejb.Local; import javax.inject.Inject; -import org.apache.log4j.Logger; -import org.springframework.stereotype.Component; - import org.apache.cloudstack.api.ResponseObject.ResponseView; import org.apache.cloudstack.api.response.VolumeResponse; import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; import com.cloud.api.ApiDBUtils; import com.cloud.api.ApiResponseHelper; @@ -152,19 +151,28 @@ public VolumeResponse newVolumeResponse(ResponseView view, VolumeJoinVO volume) // DiskOfferingVO diskOffering = // ApiDBUtils.findDiskOfferingById(volume.getDiskOfferingId()); if (volume.getDiskOfferingId() > 0) { + boolean isServiceOffering = false; if (volume.getVolumeType().equals(Volume.Type.ROOT)) { - volResponse.setServiceOfferingId(volume.getDiskOfferingUuid()); + isServiceOffering = true; } else { - volResponse.setDiskOfferingId(volume.getDiskOfferingUuid()); + // can't rely on the fact that the volume is the datadisk as it might have been created as a root, and + // then detached later + long offeringId = volume.getDiskOfferingId(); + if (ApiDBUtils.findDiskOfferingById(offeringId) == null) { + isServiceOffering = true; + } } - if (volume.getVolumeType().equals(Volume.Type.ROOT)) { + if (isServiceOffering) { + volResponse.setServiceOfferingId(volume.getDiskOfferingUuid()); volResponse.setServiceOfferingName(volume.getDiskOfferingName()); volResponse.setServiceOfferingDisplayText(volume.getDiskOfferingDisplayText()); } else { + volResponse.setDiskOfferingId(volume.getDiskOfferingUuid()); volResponse.setDiskOfferingName(volume.getDiskOfferingName()); volResponse.setDiskOfferingDisplayText(volume.getDiskOfferingDisplayText()); } + volResponse.setStorageType(volume.isUseLocalStorage() ? ServiceOffering.StorageType.local.toString() : ServiceOffering.StorageType.shared.toString()); volResponse.setBytesReadRate(volume.getBytesReadRate()); volResponse.setBytesWriteRate(volume.getBytesReadRate()); @@ -215,6 +223,14 @@ public VolumeResponse newVolumeResponse(ResponseView view, VolumeJoinVO volume) volResponse.setDisplayVolume(volume.isDisplayVolume()); volResponse.setChainInfo(volume.getChainInfo()); + volResponse.setTemplateId(volume.getTemplateUuid()); + volResponse.setTemplateName(volume.getTemplateName()); + volResponse.setTemplateDisplayText(volume.getTemplateDisplayText()); + + volResponse.setIsoId(volume.getIsoUuid()); + volResponse.setIsoName(volume.getIsoName()); + volResponse.setIsoDisplayText(volume.getIsoDisplayText()); + // set async job if (volume.getJobId() != null) { volResponse.setJobId(volume.getJobUuid()); diff --git a/server/src/com/cloud/api/query/vo/AffinityGroupJoinVO.java b/server/src/com/cloud/api/query/vo/AffinityGroupJoinVO.java index f659ed95bb..bcd0fdcbb9 100644 --- a/server/src/com/cloud/api/query/vo/AffinityGroupJoinVO.java +++ b/server/src/com/cloud/api/query/vo/AffinityGroupJoinVO.java @@ -24,7 +24,7 @@ import javax.persistence.Table; import org.apache.cloudstack.acl.ControlledEntity; -import org.apache.cloudstack.acl.IAMEntityType; +import org.apache.cloudstack.affinity.AffinityGroup; import com.cloud.vm.VirtualMachine; @@ -194,8 +194,8 @@ public ControlledEntity.ACLType getAclType() { } @Override - public IAMEntityType getEntityType() { - return IAMEntityType.AffinityGroup; + public Class getEntityType() { + return AffinityGroup.class; } } diff --git a/server/src/com/cloud/api/query/vo/AsyncJobJoinVO.java b/server/src/com/cloud/api/query/vo/AsyncJobJoinVO.java index 7889b760a1..be85c2a62b 100644 --- a/server/src/com/cloud/api/query/vo/AsyncJobJoinVO.java +++ b/server/src/com/cloud/api/query/vo/AsyncJobJoinVO.java @@ -25,8 +25,8 @@ import javax.persistence.Id; import javax.persistence.Table; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.ApiCommandJobType; +import org.apache.cloudstack.framework.jobs.AsyncJob; import com.cloud.utils.db.GenericDao; @@ -203,8 +203,8 @@ public String getInstanceUuid() { } @Override - public IAMEntityType getEntityType() { - return IAMEntityType.AsyncJob; + public Class getEntityType() { + return AsyncJob.class; } @Override diff --git a/server/src/com/cloud/api/query/vo/DomainRouterJoinVO.java b/server/src/com/cloud/api/query/vo/DomainRouterJoinVO.java index ac32859ea1..79eb3bfb70 100644 --- a/server/src/com/cloud/api/query/vo/DomainRouterJoinVO.java +++ b/server/src/com/cloud/api/query/vo/DomainRouterJoinVO.java @@ -26,13 +26,12 @@ import javax.persistence.Id; import javax.persistence.Table; -import org.apache.cloudstack.acl.IAMEntityType; - import com.cloud.network.Network.GuestType; import com.cloud.network.Networks.TrafficType; import com.cloud.network.router.VirtualRouter; import com.cloud.network.router.VirtualRouter.RedundantState; import com.cloud.utils.db.GenericDao; +import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachine.State; @Entity @@ -514,7 +513,7 @@ public VirtualRouter.Role getRole() { } @Override - public IAMEntityType getEntityType() { - return IAMEntityType.VirtualMachine; + public Class getEntityType() { + return VirtualMachine.class; } } diff --git a/server/src/com/cloud/api/query/vo/EventJoinVO.java b/server/src/com/cloud/api/query/vo/EventJoinVO.java index b6b023ef6e..8fba938876 100644 --- a/server/src/com/cloud/api/query/vo/EventJoinVO.java +++ b/server/src/com/cloud/api/query/vo/EventJoinVO.java @@ -25,8 +25,7 @@ import javax.persistence.Id; import javax.persistence.Table; -import org.apache.cloudstack.acl.IAMEntityType; - +import com.cloud.event.Event; import com.cloud.event.Event.State; import com.cloud.utils.db.GenericDao; @@ -227,7 +226,7 @@ public boolean getDisplay() { } @Override - public IAMEntityType getEntityType() { - return IAMEntityType.Event; + public Class getEntityType() { + return Event.class; } } diff --git a/server/src/com/cloud/api/query/vo/InstanceGroupJoinVO.java b/server/src/com/cloud/api/query/vo/InstanceGroupJoinVO.java index 98d1a523e7..857cebf75f 100644 --- a/server/src/com/cloud/api/query/vo/InstanceGroupJoinVO.java +++ b/server/src/com/cloud/api/query/vo/InstanceGroupJoinVO.java @@ -23,9 +23,8 @@ import javax.persistence.Id; import javax.persistence.Table; -import org.apache.cloudstack.acl.IAMEntityType; - import com.cloud.utils.db.GenericDao; +import com.cloud.vm.InstanceGroup; @Entity @Table(name = "instance_group_view") @@ -160,7 +159,7 @@ public Date getCreated() { } @Override - public IAMEntityType getEntityType() { - return IAMEntityType.InstanceGroup; + public Class getEntityType() { + return InstanceGroup.class; } } diff --git a/server/src/com/cloud/api/query/vo/ProjectInvitationJoinVO.java b/server/src/com/cloud/api/query/vo/ProjectInvitationJoinVO.java index ba619a9a08..8b4918561c 100644 --- a/server/src/com/cloud/api/query/vo/ProjectInvitationJoinVO.java +++ b/server/src/com/cloud/api/query/vo/ProjectInvitationJoinVO.java @@ -25,8 +25,7 @@ import javax.persistence.Id; import javax.persistence.Table; -import org.apache.cloudstack.acl.IAMEntityType; - +import com.cloud.projects.ProjectInvitation; import com.cloud.projects.ProjectInvitation.State; import com.cloud.utils.db.GenericDao; @@ -164,7 +163,7 @@ public String getDomainPath() { } @Override - public IAMEntityType getEntityType() { - return IAMEntityType.ProjectInvitation; + public Class getEntityType() { + return ProjectInvitation.class; } } diff --git a/server/src/com/cloud/api/query/vo/ResourceTagJoinVO.java b/server/src/com/cloud/api/query/vo/ResourceTagJoinVO.java index e1b8b812ae..2c1ff47509 100644 --- a/server/src/com/cloud/api/query/vo/ResourceTagJoinVO.java +++ b/server/src/com/cloud/api/query/vo/ResourceTagJoinVO.java @@ -23,8 +23,7 @@ import javax.persistence.Id; import javax.persistence.Table; -import org.apache.cloudstack.acl.IAMEntityType; - +import com.cloud.server.ResourceTag; import com.cloud.server.ResourceTag.ResourceObjectType; @Entity @@ -182,7 +181,7 @@ public String getCustomer() { } @Override - public IAMEntityType getEntityType() { - return IAMEntityType.ResourceTag; + public Class getEntityType() { + return ResourceTag.class; } } diff --git a/server/src/com/cloud/api/query/vo/SecurityGroupJoinVO.java b/server/src/com/cloud/api/query/vo/SecurityGroupJoinVO.java index 3c9e3bf87a..69604e8286 100644 --- a/server/src/com/cloud/api/query/vo/SecurityGroupJoinVO.java +++ b/server/src/com/cloud/api/query/vo/SecurityGroupJoinVO.java @@ -23,8 +23,7 @@ import javax.persistence.Id; import javax.persistence.Table; -import org.apache.cloudstack.acl.IAMEntityType; - +import com.cloud.network.security.SecurityGroup; import com.cloud.network.security.SecurityRule.SecurityRuleType; import com.cloud.server.ResourceTag.ResourceObjectType; @@ -306,7 +305,7 @@ public String getTagCustomer() { } @Override - public IAMEntityType getEntityType() { - return IAMEntityType.SecurityGroup; + public Class getEntityType() { + return SecurityGroup.class; } } diff --git a/server/src/com/cloud/api/query/vo/TemplateJoinVO.java b/server/src/com/cloud/api/query/vo/TemplateJoinVO.java index de0da2f1e5..834a9cedd0 100644 --- a/server/src/com/cloud/api/query/vo/TemplateJoinVO.java +++ b/server/src/com/cloud/api/query/vo/TemplateJoinVO.java @@ -27,7 +27,6 @@ import javax.persistence.Temporal; import javax.persistence.TemporalType; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; import com.cloud.hypervisor.Hypervisor.HypervisorType; @@ -35,6 +34,7 @@ import com.cloud.storage.ScopeType; import com.cloud.storage.Storage; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; +import com.cloud.template.VirtualMachineTemplate; import com.cloud.template.VirtualMachineTemplate.State; import com.cloud.utils.db.GenericDao; @@ -544,7 +544,7 @@ public State getTemplateState() { } @Override - public IAMEntityType getEntityType() { - return IAMEntityType.VirtualMachineTemplate; + public Class getEntityType() { + return VirtualMachineTemplate.class; } } diff --git a/server/src/com/cloud/api/query/vo/UserVmJoinVO.java b/server/src/com/cloud/api/query/vo/UserVmJoinVO.java index fcee393207..f3f48fc9ae 100644 --- a/server/src/com/cloud/api/query/vo/UserVmJoinVO.java +++ b/server/src/com/cloud/api/query/vo/UserVmJoinVO.java @@ -28,8 +28,6 @@ import javax.persistence.Table; import javax.persistence.Transient; -import org.apache.cloudstack.acl.IAMEntityType; - import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.network.Network.GuestType; import com.cloud.network.Networks.TrafficType; @@ -913,7 +911,7 @@ public String getDetailValue() { } @Override - public IAMEntityType getEntityType() { - return IAMEntityType.VirtualMachine; + public Class getEntityType() { + return VirtualMachine.class; } } diff --git a/server/src/com/cloud/api/query/vo/VolumeJoinVO.java b/server/src/com/cloud/api/query/vo/VolumeJoinVO.java index 289b0b85af..cb6dc4d1b6 100644 --- a/server/src/com/cloud/api/query/vo/VolumeJoinVO.java +++ b/server/src/com/cloud/api/query/vo/VolumeJoinVO.java @@ -27,8 +27,6 @@ import javax.persistence.Temporal; import javax.persistence.TemporalType; -import org.apache.cloudstack.acl.IAMEntityType; - import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.server.ResourceTag.ResourceObjectType; import com.cloud.storage.Storage; @@ -214,12 +212,30 @@ public class VolumeJoinVO extends BaseViewVO implements ControlledViewEntity { @Column(name = "template_uuid") private String templateUuid; + @Column(name = "template_name") + private String templateName; + + @Column(name = "template_display_text", length = 4096) + private String templateDisplayText; + @Column(name = "extractable") private boolean extractable; @Column(name = "template_type") private Storage.TemplateType templateType; + @Column(name = "iso_id", updatable = true, nullable = true, length = 17) + private long isoId; + + @Column(name = "iso_uuid") + private String isoUuid; + + @Column(name = "iso_name") + private String isoName; + + @Column(name = "iso_display_text", length = 4096) + private String isoDisplayText; + @Column(name = "job_id") private Long jobId; @@ -496,6 +512,30 @@ public Storage.TemplateType getTemplateType() { return templateType; } + public String getTemplateName() { + return templateName; + } + + public String getTemplateDisplayText() { + return templateDisplayText; + } + + public long getIsoId() { + return isoId; + } + + public String getIsoUuid() { + return isoUuid; + } + + public String getIsoName() { + return isoName; + } + + public String getIsoDisplayText() { + return isoDisplayText; + } + public Long getJobId() { return jobId; } @@ -578,7 +618,7 @@ public String getChainInfo() { } @Override - public IAMEntityType getEntityType() { - return IAMEntityType.Volume; + public Class getEntityType() { + return Volume.class; } } diff --git a/server/src/com/cloud/api/response/SecurityGroupResultObject.java b/server/src/com/cloud/api/response/SecurityGroupResultObject.java index 66ba487641..c2cd423bef 100644 --- a/server/src/com/cloud/api/response/SecurityGroupResultObject.java +++ b/server/src/com/cloud/api/response/SecurityGroupResultObject.java @@ -22,7 +22,6 @@ import java.util.Map; import org.apache.cloudstack.acl.ControlledEntity; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.InternalIdentity; import com.cloud.api.ApiDBUtils; @@ -212,7 +211,7 @@ public static List transposeNetworkGroups(List getEntityType() { + return SecurityGroup.class; } } diff --git a/server/src/com/cloud/capacity/CapacityManagerImpl.java b/server/src/com/cloud/capacity/CapacityManagerImpl.java index 69e8cfa169..14fbe7f80b 100755 --- a/server/src/com/cloud/capacity/CapacityManagerImpl.java +++ b/server/src/com/cloud/capacity/CapacityManagerImpl.java @@ -182,6 +182,10 @@ public boolean stop() { @DB @Override public boolean releaseVmCapacity(VirtualMachine vm, final boolean moveFromReserved, final boolean moveToReservered, final Long hostId) { + if (hostId == null) { + return true; + } + final ServiceOfferingVO svo = _offeringsDao.findById(vm.getId(), vm.getServiceOfferingId()); CapacityVO capacityCpu = _capacityDao.findByHostIdType(hostId, Capacity.CAPACITY_TYPE_CPU); CapacityVO capacityMemory = _capacityDao.findByHostIdType(hostId, Capacity.CAPACITY_TYPE_MEMORY); @@ -544,7 +548,7 @@ public long getAllocatedPoolCapacity(StoragePoolVO pool, VMTemplateVO templateFo // if the storage pool is managed, the used bytes can be larger than the sum of the sizes of all of the non-destroyed volumes // in this case, call getUsedBytes(StoragePoolVO) if (pool.isManaged()) { - totalAllocatedSize = getUsedBytes(pool); + return getUsedBytes(pool); } else { // Get size for all the non-destroyed volumes diff --git a/server/src/com/cloud/configuration/Config.java b/server/src/com/cloud/configuration/Config.java index f2fe68a78a..bf72dc2246 100755 --- a/server/src/com/cloud/configuration/Config.java +++ b/server/src/com/cloud/configuration/Config.java @@ -16,15 +16,6 @@ // under the License. package com.cloud.configuration; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.StringTokenizer; - -import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; -import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator; -import org.apache.cloudstack.framework.config.ConfigKey; - import com.cloud.agent.AgentManager; import com.cloud.consoleproxy.ConsoleProxyManager; import com.cloud.ha.HighAvailabilityManager; @@ -38,6 +29,14 @@ import com.cloud.template.TemplateManager; import com.cloud.vm.UserVmManager; import com.cloud.vm.snapshot.VMSnapshotManager; +import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; +import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator; +import org.apache.cloudstack.framework.config.ConfigKey; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.StringTokenizer; public enum Config { @@ -702,7 +701,7 @@ public enum Config { "system.vm.use.local.storage", "false", "Indicates whether to use local storage pools or shared storage pools for system VMs.", - null), + null, ConfigKey.Scope.Zone.toString()), SystemVMAutoReserveCapacity( "Advanced", ManagementServer.class, @@ -1803,6 +1802,23 @@ public enum Config { "Timeout to echo baremetal security group agent, in seconds, the provisioning process will be treated as a failure", null), + BaremetalIpmiLanInterface( + "Advanced", + ManagementServer.class, + String.class, + "baremetal.ipmi.lan.interface", + "default", + "option specified in -I option of impitool. candidates are: open/bmc/lipmi/lan/lanplus/free/imb, see ipmitool man page for details. default valule 'default' means using default option of ipmitool", + null), + + BaremetalIpmiRetryTimes("Advanced", + ManagementServer.class, + String.class, + "baremetal.ipmi.fail.retry", + "5", + "ipmi interface will be temporary out of order after power opertions(e.g. cycle, on), it leads following commands fail immediately. The value specifies retry times before accounting it as real failure", + null), + ApiLimitEnabled("Advanced", ManagementServer.class, Boolean.class, "api.throttling.enabled", "false", "Enable/disable Api rate limit", null), ApiLimitInterval("Advanced", ManagementServer.class, Integer.class, "api.throttling.interval", "1", "Time interval (in seconds) to reset API count", null), ApiLimitMax("Advanced", ManagementServer.class, Integer.class, "api.throttling.max", "25", "Max allowed number of APIs within fixed interval", null), @@ -1898,6 +1914,24 @@ public enum Config { "the interval cloudstack sync with UCS manager for available blades in case user remove blades from chassis without notifying CloudStack", null), + RedundantRouterVrrpInterval( + "Advanced", + NetworkOrchestrationService.class, + Integer.class, + "router.redundant.vrrp.interval", + "1", + "seconds between VRRP broadcast. It would 3 times broadcast fail to trigger fail-over mechanism of redundant router", + null), + + RouterAggregationCommandEachTimeout( + "Advanced", + NetworkOrchestrationService.class, + Integer.class, + "router.aggregation.command.each.timeout", + "3", + "timeout in seconds for each Virtual Router command being aggregated. The final aggregation command timeout would be determined by this timeout * commands counts ", + null), + ManagementServerVendor("Advanced", ManagementServer.class, String.class, "mgt.server.vendor", "ACS", "the vendor of management server", null); private final String _category; diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java index 9b9bd13d26..010ca7a085 100755 --- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java +++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java @@ -17,6 +17,7 @@ package com.cloud.configuration; import java.net.URI; +import java.sql.Date; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; @@ -36,8 +37,9 @@ import javax.inject.Inject; import javax.naming.ConfigurationException; -import org.apache.log4j.Logger; +import com.cloud.storage.StorageManager; +import org.apache.log4j.Logger; import org.apache.cloudstack.acl.SecurityChecker; import org.apache.cloudstack.affinity.AffinityGroup; import org.apache.cloudstack.affinity.AffinityGroupService; @@ -153,6 +155,7 @@ import com.cloud.network.dao.PhysicalNetworkTrafficTypeDao; import com.cloud.network.dao.PhysicalNetworkTrafficTypeVO; import com.cloud.network.dao.PhysicalNetworkVO; +import com.cloud.network.element.NetworkElement; import com.cloud.network.rules.LoadBalancerContainer.Scheme; import com.cloud.network.vpc.VpcManager; import com.cloud.offering.DiskOffering; @@ -175,6 +178,7 @@ import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.service.dao.ServiceOfferingDetailsDao; import com.cloud.storage.DiskOfferingVO; +import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.dao.DiskOfferingDao; import com.cloud.test.IPRangeConfig; import com.cloud.user.Account; @@ -313,6 +317,8 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati AffinityGroupDao _affinityGroupDao; @Inject AffinityGroupService _affinityGroupService; + @Inject + StorageManager _storageManager; // FIXME - why don't we have interface for DataCenterLinkLocalIpAddressDao? @Inject @@ -466,6 +472,11 @@ public String updateConfiguration(long userId, String name, String category, Str if (pool == null) { throw new InvalidParameterValueException("unable to find storage pool by id " + resourceId); } + if(name.equals(CapacityManager.StorageOverprovisioningFactor.key())) { + if(pool.getPoolType() != StoragePoolType.NetworkFilesystem && pool.getPoolType() != StoragePoolType.VMFS) { + throw new InvalidParameterValueException("Unable to update storage pool with id " + resourceId + ". Overprovision not supported for " + pool.getPoolType()); + } + } _storagePoolDetailsDao.addDetail(resourceId, name, value, true); break; @@ -583,6 +594,27 @@ public String updateConfiguration(long userId, String name, String category, Str throw new CloudRuntimeException("Failed to update SecondaryStorage offering's use_local_storage option to value:" + useLocalStorage); } } + }else if (Config.SecStorageSecureCopyCert.key().equalsIgnoreCase(name)) { + //FIXME - Ideally there should be a listener model to listen to global config changes and be able to take action gracefully. + //Expire the download urls + String sqlTemplate = "update template_store_ref set download_url_created=?"; + String sqlVolume = "update volume_store_ref set download_url_created=?"; + try { + // Change for templates + pstmt = txn.prepareAutoCloseStatement(sqlTemplate); + pstmt.setDate(1, new Date(-1l));// Set the time before the epoch time. + pstmt.executeUpdate(); + // Change for volumes + pstmt = txn.prepareAutoCloseStatement(sqlVolume); + pstmt.setDate(1, new Date(-1l));// Set the time before the epoch time. + pstmt.executeUpdate(); + // Cleanup the download urls + _storageManager.cleanupDownloadUrls(); + } catch (Throwable e) { + throw new CloudRuntimeException("Failed to clean up download URLs in template_store_ref or volume_store_ref due to exception ", e); + } + + } txn.commit(); @@ -675,12 +707,19 @@ private String validateConfigurationValue(String name, String value, String scop return "Invalid scope id provided for the parameter " + name; } } + Class type = null; Config c = Config.getConfig(name); if (c == null) { - s_logger.warn("Did not find configuration " + name + " in Config.java. Perhaps moved to ConfigDepot?"); - return null; + s_logger.warn("Did not find configuration " + name + " in Config.java. Perhaps moved to ConfigDepot"); + ConfigKey configKey = _configDepot.get(name); + if(configKey == null) { + s_logger.warn("Did not find configuration " + name + " in ConfigDepot too."); + return null; + } + type = configKey.type(); + } else { + type = c.getType(); } - Class type = c.getType(); if (value == null) { if (type.equals(Boolean.class)) { @@ -739,6 +778,12 @@ private String validateConfigurationValue(String name, String value, String scop } } + if(c == null ) { + //range validation has to be done per case basis, for now + //return in case of Configkey parameters + return null; + } + String range = c.getRange(); if (range == null) { return null; @@ -909,9 +954,7 @@ private void checkPodAttributes(long podId, String podName, long zoneId, String } // Check if the IP range is valid - if (startIp != null || endIp != null) { - checkIpRange(startIp, endIp, cidrAddress, cidrSize); - } + checkIpRange(startIp, endIp, cidrAddress, cidrSize); // Check if the IP range overlaps with the public ip checkOverlapPublicIpRange(zoneId, startIp, endIp); @@ -971,7 +1014,7 @@ public boolean deletePod(DeletePodCmd cmd) { @Override public void doInTransactionWithoutResult(TransactionStatus status) { // Delete private ip addresses for the pod if there are any - List privateIps = _privateIpAddressDao.listByPodIdDcId(Long.valueOf(podId), pod.getDataCenterId()); + List privateIps = _privateIpAddressDao.listByPodIdDcId(podId, pod.getDataCenterId()); if (!privateIps.isEmpty()) { if (!(_privateIpAddressDao.deleteIpAddressByPod(podId))) { throw new CloudRuntimeException("Failed to cleanup private ip addresses for pod " + podId); @@ -1472,13 +1515,8 @@ private void checkOverlapPrivateIpRange(Long zoneId, String startIp, String endI @ActionEvent(eventType = EventTypes.EVENT_ZONE_DELETE, eventDescription = "deleting zone", async = false) public boolean deleteZone(DeleteZoneCmd cmd) { - Long userId = CallContext.current().getCallingUserId(); final Long zoneId = cmd.getId(); - if (userId == null) { - userId = Long.valueOf(User.UID_SYSTEM); - } - // Make sure the zone exists if (!validZone(zoneId)) { throw new InvalidParameterValueException("A zone with ID: " + zoneId + " does not exist."); @@ -1999,7 +2037,6 @@ public ServiceOffering createServiceOffering(CreateServiceOfferingCmd cmd) { } } else { allowNetworkRate = true; - ; } if (cmd.getNetworkRate() != null && !allowNetworkRate) { @@ -2083,47 +2120,36 @@ protected ServiceOfferingVO createServiceOffering(long userId, boolean isSystem, offering.setHypervisorSnapshotReserve(hypervisorSnapshotReserve); List detailsVO = null; - if (details != null) { - // Check if the user has passed the gpu-type before passing the VGPU type - if (!details.containsKey(GPU.Keys.pciDevice.toString()) && details.containsKey(GPU.Keys.vgpuType.toString())) { - throw new InvalidParameterValueException("Please specify the gpu type"); + if (details != null) { + // To have correct input, either both gpu card name and VGPU type should be passed or nothing should be passed. + // Use XOR condition to verify that. + boolean entry1 = details.containsKey(GPU.Keys.pciDevice.toString()); + boolean entry2 = details.containsKey(GPU.Keys.vgpuType.toString()); + if ((entry1 || entry2) && !(entry1 && entry2)) { + throw new InvalidParameterValueException("Please specify the pciDevice and vgpuType correctly."); } detailsVO = new ArrayList(); - for (Entry detailEntry : details.entrySet()) { + for (Entry detailEntry : details.entrySet()) { String value = null; if (detailEntry.getKey().equals(GPU.Keys.pciDevice.toString())) { - for (GPU.Type type : GPU.Type.values()) { - if (detailEntry.getValue().equals(type.toString())) { - value = detailEntry.getValue(); - } - } - if (value == null) { - throw new InvalidParameterValueException("Please specify valid gpu type"); + if (detailEntry.getValue() == null) { + throw new InvalidParameterValueException("Please specify a GPU Card."); } } if (detailEntry.getKey().equals(GPU.Keys.vgpuType.toString())) { - if (details.get(GPU.Keys.pciDevice.toString()).equals(GPU.Type.GPU_Passthrough.toString())) { - throw new InvalidParameterValueException("vgpuTypes are supported only with vGPU pciDevice"); - } if (detailEntry.getValue() == null) { - throw new InvalidParameterValueException("With vGPU as pciDevice, vGPUType value cannot be null"); + throw new InvalidParameterValueException("vGPUType value cannot be null"); } for (GPU.vGPUType entry : GPU.vGPUType.values()) { if (detailEntry.getValue().equals(entry.getType())) { value = entry.getType(); } } - if (value == null || detailEntry.getValue().equals(GPU.vGPUType.passthrough.getType())) { + if (value == null) { throw new InvalidParameterValueException("Please specify valid vGPU type"); } } - detailsVO.add(new ServiceOfferingDetailsVO(offering.getId(), detailEntry.getKey(), detailEntry.getValue(), true)); - } - // If pciDevice type is passed, put the default VGPU type as 'passthrough' - if (details.containsKey(GPU.Keys.pciDevice.toString()) - && !details.containsKey(GPU.Keys.vgpuType.toString())) { - detailsVO.add(new ServiceOfferingDetailsVO(offering.getId(), - GPU.Keys.vgpuType.toString(), GPU.vGPUType.passthrough.getType(), true)); + detailsVO.add(new ServiceOfferingDetailsVO(offering.getId(), detailEntry.getKey(), detailEntry.getValue(), true)); } } @@ -3181,7 +3207,7 @@ public boolean deleteVlanAndPublicIpRange(long userId, final long vlanDbId, Acco @Override public void doInTransactionWithoutResult(TransactionStatus status) { _publicIpAddressDao.deletePublicIPRange(vlanDbId); - _vlanDao.expunge(vlanDbId); + _vlanDao.remove(vlanDbId); } }); @@ -3814,10 +3840,21 @@ public NetworkOffering createNetworkOffering(CreateNetworkOfferingCmd cmd) { } validateStaticNatServiceCapablities(staticNatServiceCapabilityMap); + // validate the 'Connectivity' service capabilities specified in the network offering, if 'Connectivity' service + // is in the supported services of network offering + Map connectivityServiceCapabilityMap = cmd.getServiceCapabilities(Service.Connectivity); + if (!serviceProviderMap.containsKey(Service.Connectivity) && + (connectivityServiceCapabilityMap != null && !connectivityServiceCapabilityMap.isEmpty())) { + throw new InvalidParameterValueException("Capabilities for 'Connectivity' service can be specified " + + "only when Connectivity service is enabled for network offering."); + } + validateConnectivityServiceCapablities(serviceProviderMap.get(Service.Connectivity), connectivityServiceCapabilityMap); + Map> serviceCapabilityMap = new HashMap>(); serviceCapabilityMap.put(Service.Lb, lbServiceCapabilityMap); serviceCapabilityMap.put(Service.SourceNat, sourceNatServiceCapabilityMap); serviceCapabilityMap.put(Service.StaticNat, staticNatServiceCapabilityMap); + serviceCapabilityMap.put(Service.Connectivity, connectivityServiceCapabilityMap); // if Firewall service is missing, add Firewall service/provider // combination @@ -3952,6 +3989,37 @@ void validateStaticNatServiceCapablities(Map staticNatServic } } + void validateConnectivityServiceCapablities(Set providers, Map connectivityServiceCapabilityMap) { + if (connectivityServiceCapabilityMap != null && !connectivityServiceCapabilityMap.isEmpty()) { + for (Capability capability: connectivityServiceCapabilityMap.keySet()) { + if (capability == Capability.StretchedL2Subnet) { + String value = connectivityServiceCapabilityMap.get(capability).toLowerCase(); + if (!(value.contains("true") ^ value.contains("false"))) { + throw new InvalidParameterValueException("Invalid value (" + value + ") for " + capability + + " should be true/false"); + } + } else { + throw new InvalidParameterValueException("Capability " + capability.getName() + " can not be " + + " specified with connectivity service."); + } + } + + // validate connectivity service provider actually supports specified capabilities + if (providers != null && !providers.isEmpty()) { + for (Provider provider: providers) { + NetworkElement element = _networkModel.getElementImplementingProvider(provider.getName()); + Map> capabilities = element.getCapabilities(); + if (capabilities != null && !capabilities.isEmpty()) { + Map connectivityCapabilities = capabilities.get(Service.Connectivity); + if (connectivityCapabilities == null || (connectivityCapabilities != null && !connectivityCapabilities.keySet().contains(Capability.StretchedL2Subnet))) { + throw new InvalidParameterValueException("Provider: " + provider.getName() + " does not support " + + Capability.StretchedL2Subnet.getName()); + } + } + } + } + } + } @Override @DB public NetworkOfferingVO createNetworkOffering(String name, String displayText, TrafficType trafficType, String tags, boolean specifyVlan, Availability availability, @@ -4012,6 +4080,8 @@ public NetworkOfferingVO createNetworkOffering(String name, String displayText, boolean inline = false; boolean publicLb = false; boolean internalLb = false; + boolean strechedL2Subnet = false; + if (serviceCapabilityMap != null && !serviceCapabilityMap.isEmpty()) { Map lbServiceCapabilityMap = serviceCapabilityMap.get(Service.Lb); @@ -4079,6 +4149,14 @@ public NetworkOfferingVO createNetworkOffering(String name, String displayText, } } } + + Map connectivityServiceCapabilityMap = serviceCapabilityMap.get(Service.Connectivity); + if (connectivityServiceCapabilityMap != null && !connectivityServiceCapabilityMap.isEmpty()) { + String value = connectivityServiceCapabilityMap.get(Capability.StretchedL2Subnet); + if ("true".equalsIgnoreCase(value)) { + strechedL2Subnet = true; + } + } } if (serviceProviderMap != null && serviceProviderMap.containsKey(Service.Lb) && !internalLb && !publicLb) { @@ -4088,7 +4166,7 @@ public NetworkOfferingVO createNetworkOffering(String name, String displayText, final NetworkOfferingVO offeringFinal = new NetworkOfferingVO(name, displayText, trafficType, systemOnly, specifyVlan, networkRate, multicastRate, isDefault, availability, tags, type, conserveMode, dedicatedLb, sharedSourceNat, redundantRouter, elasticIp, elasticLb, specifyIpRanges, inline, isPersistent, associatePublicIp, publicLb, - internalLb, egressDefaultPolicy); + internalLb, egressDefaultPolicy, strechedL2Subnet); if (serviceOfferingId != null) { offeringFinal.setServiceOfferingId(serviceOfferingId); diff --git a/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java b/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java index 9cbbb10c84..0e02d1b75c 100644 --- a/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java +++ b/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java @@ -118,12 +118,11 @@ import com.cloud.utils.db.TransactionCallback; import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.exception.CloudRuntimeException; -import com.cloud.utils.fsm.StateListener; -import com.cloud.vm.DiskProfile; -import com.cloud.vm.ReservationContext; -import com.cloud.vm.VMInstanceVO; -import com.cloud.vm.VirtualMachine; -import com.cloud.vm.VirtualMachine.Event; +import com.cloud.utils.fsm.StateListener; +import com.cloud.vm.DiskProfile; +import com.cloud.vm.VMInstanceVO; +import com.cloud.vm.VirtualMachine; +import com.cloud.vm.VirtualMachine.Event; import com.cloud.vm.VirtualMachine.State; import com.cloud.vm.VirtualMachineProfile; import com.cloud.vm.dao.UserVmDao; @@ -198,6 +197,8 @@ public void setHostAllocators(List hostAllocators) { @Inject protected StoragePoolHostDao _poolHostDao; + @Inject + protected DataCenterDao _zoneDao; @Inject protected VolumeDao _volsDao; @Inject @@ -316,6 +317,15 @@ public DeployDestination planDeployment(VirtualMachineProfile vmProfile, Deploym host.getClusterId()); } + Pod pod = _podDao.findById(host.getPodId()); + Cluster cluster = _clusterDao.findById(host.getClusterId()); + + if (vm.getHypervisorType() == HypervisorType.BareMetal) { + DeployDestination dest = new DeployDestination(dc, pod, cluster, host, new HashMap()); + s_logger.debug("Returning Deployment Destination: " + dest); + return dest; + } + // search for storage under the zone, pod, cluster of the host. DataCenterDeployment lastPlan = new DataCenterDeployment(host.getDataCenterId(), host.getPodId(), host.getClusterId(), hostIdSpecified, plan.getPoolId(), null, @@ -333,8 +343,6 @@ public DeployDestination planDeployment(VirtualMachineProfile vmProfile, Deploym suitableHosts, suitableVolumeStoragePools, avoids, getPlannerUsage(planner, vmProfile, plan, avoids), readyAndReusedVolumes); if (potentialResources != null) { - Pod pod = _podDao.findById(host.getPodId()); - Cluster cluster = _clusterDao.findById(host.getClusterId()); Map storageVolMap = potentialResources.second(); // remove the reused vol<->pool from destination, since // we don't have to prepare this volume. @@ -363,9 +371,11 @@ public DeployDestination planDeployment(VirtualMachineProfile vmProfile, Deploym } else if (_capacityMgr.checkIfHostReachMaxGuestLimit(host)) { s_logger.debug("The last Host, hostId: " + host.getId() + " already has max Running VMs(count includes system VMs), skipping this and trying other available hosts"); - } else if ((offeringDetails = _serviceOfferingDetailsDao.findDetail(offering.getId(), GPU.Keys.vgpuType.toString())) != null - && !_resourceMgr.isGPUDeviceAvailable(host.getId(), offeringDetails.getValue())){ - s_logger.debug("The last host of this VM does not have required GPU devices available"); + } else if ((offeringDetails = _serviceOfferingDetailsDao.findDetail(offering.getId(), GPU.Keys.vgpuType.toString())) != null) { + ServiceOfferingDetailsVO groupName = _serviceOfferingDetailsDao.findDetail(offering.getId(), GPU.Keys.pciDevice.toString()); + if(!_resourceMgr.isGPUDeviceAvailable(host.getId(), groupName.getValue(), offeringDetails.getValue())){ + s_logger.debug("The last host of this VM does not have required GPU devices available"); + } } else { if (host.getStatus() == Status.Up && host.getResourceState() == ResourceState.Enabled) { boolean hostTagsMatch = true; @@ -393,10 +403,22 @@ public DeployDestination planDeployment(VirtualMachineProfile vmProfile, Deploym // search for storage under the zone, pod, cluster // of // the last host. - DataCenterDeployment lastPlan = new DataCenterDeployment(host.getDataCenterId(), - host.getPodId(), host.getClusterId(), host.getId(), plan.getPoolId(), null); - Pair>, List> result = findSuitablePoolsForVolumes( - vmProfile, lastPlan, avoids, HostAllocator.RETURN_UPTO_ALL); + + + Pod pod = _podDao.findById(host.getPodId()); + Cluster cluster = _clusterDao.findById(host.getClusterId()); + + if (vm.getHypervisorType() == HypervisorType.BareMetal) { + DeployDestination dest = new DeployDestination(dc, pod, cluster, host, new HashMap()); + s_logger.debug("Returning Deployment Destination: " + dest); + return dest; + } + + DataCenterDeployment lastPlan = new DataCenterDeployment(host.getDataCenterId(), + host.getPodId(), host.getClusterId(), host.getId(), plan.getPoolId(), null); + Pair>, List> result = findSuitablePoolsForVolumes( + vmProfile, lastPlan, avoids, HostAllocator.RETURN_UPTO_ALL); + Map> suitableVolumeStoragePools = result.first(); List readyAndReusedVolumes = result.second(); @@ -409,8 +431,6 @@ public DeployDestination planDeployment(VirtualMachineProfile vmProfile, Deploym suitableHosts, suitableVolumeStoragePools, avoids, getPlannerUsage(planner, vmProfile, plan, avoids), readyAndReusedVolumes); if (potentialResources != null) { - Pod pod = _podDao.findById(host.getPodId()); - Cluster cluster = _clusterDao.findById(host.getClusterId()); Map storageVolMap = potentialResources.second(); // remove the reused vol<->pool from // destination, since we don't have to @@ -1224,7 +1244,7 @@ protected Pair>, List> findSuitablePoolsFo if (s_logger.isDebugEnabled()) { s_logger.debug("We need to allocate new storagepool for this volume"); } - if (!isRootAdmin(plan.getReservationContext())) { + if (!isRootAdmin(vmProfile)) { if (!isEnabledForAllocation(plan.getDataCenterId(), plan.getPodId(), plan.getClusterId())) { if (s_logger.isDebugEnabled()) { s_logger.debug("Cannot allocate new storagepool for this volume in this cluster, allocation state is disabled"); @@ -1252,7 +1272,18 @@ protected Pair>, List> findSuitablePoolsFo boolean useLocalStorage = false; if (vmProfile.getType() != VirtualMachine.Type.User) { String ssvmUseLocalStorage = _configDao.getValue(Config.SystemVMUseLocalStorage.key()); - if (ssvmUseLocalStorage.equalsIgnoreCase("true")) { + + DataCenterVO zone = _zoneDao.findById(plan.getDataCenterId()); + + // It should not happen to have a "null" zone here. There can be NO instance if there is NO zone, + // so this part of the code would never be reached if no zone has been created. + // + // Added the check and the comment just to make it clear. + boolean zoneUsesLocalStorage = zone != null ? zone.isLocalStorageEnabled() : false; + + // Local storage is used for the NON User VMs if, and only if, the Zone is marked to use local storage AND + // the global settings (ssvmUseLocalStorage) is set to true. Otherwise, the global settings won't be applied. + if (ssvmUseLocalStorage.equalsIgnoreCase("true") && zoneUsesLocalStorage) { useLocalStorage = true; } } else { @@ -1340,10 +1371,10 @@ private boolean isEnabledForAllocation(long zoneId, Long podId, Long clusterId) return true; } - private boolean isRootAdmin(ReservationContext reservationContext) { - if (reservationContext != null) { - if (reservationContext.getAccount() != null) { - return _accountMgr.isRootAdmin(reservationContext.getAccount().getId()); + private boolean isRootAdmin(VirtualMachineProfile vmProfile) { + if (vmProfile != null) { + if (vmProfile.getOwner() != null) { + return _accountMgr.isRootAdmin(vmProfile.getOwner().getId()); } else { return false; } diff --git a/server/src/com/cloud/deploy/FirstFitPlanner.java b/server/src/com/cloud/deploy/FirstFitPlanner.java index 6ffe31f99a..c29101d9b6 100755 --- a/server/src/com/cloud/deploy/FirstFitPlanner.java +++ b/server/src/com/cloud/deploy/FirstFitPlanner.java @@ -56,7 +56,6 @@ import com.cloud.user.AccountManager; import com.cloud.utils.NumbersUtil; import com.cloud.utils.Pair; -import com.cloud.vm.ReservationContext; import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachineProfile; import com.cloud.vm.dao.UserVmDao; @@ -191,7 +190,7 @@ private List scanPodsForDestination(VirtualMachineProfile vmProfile, Deplo } podsWithCapacity.removeAll(avoid.getPodsToAvoid()); } - if (!isRootAdmin(plan.getReservationContext())) { + if (!isRootAdmin(vmProfile)) { List disabledPods = listDisabledPods(plan.getDataCenterId()); if (!disabledPods.isEmpty()) { if (s_logger.isDebugEnabled()) { @@ -322,7 +321,7 @@ private List scanClustersForDestinationInZoneOrPod(long id, boolean isZone prioritizedClusterIds.removeAll(avoid.getClustersToAvoid()); } - if (!isRootAdmin(plan.getReservationContext())) { + if (!isRootAdmin(vmProfile)) { List disabledClusters = new ArrayList(); if (isZone) { disabledClusters = listDisabledClusters(plan.getDataCenterId(), null); @@ -465,10 +464,10 @@ protected Pair, Map> listPodsByCapacity(long zoneId, in } - private boolean isRootAdmin(ReservationContext reservationContext) { - if(reservationContext != null){ - if(reservationContext.getAccount() != null){ - return _accountMgr.isRootAdmin(reservationContext.getAccount().getId()); + private boolean isRootAdmin(VirtualMachineProfile vmProfile) { + if (vmProfile != null) { + if (vmProfile.getOwner() != null) { + return _accountMgr.isRootAdmin(vmProfile.getOwner().getId()); }else{ return false; } diff --git a/server/src/com/cloud/event/ActionEventUtils.java b/server/src/com/cloud/event/ActionEventUtils.java index 28e5680b63..90d9b93941 100755 --- a/server/src/com/cloud/event/ActionEventUtils.java +++ b/server/src/com/cloud/event/ActionEventUtils.java @@ -26,7 +26,8 @@ import javax.inject.Inject; import com.cloud.utils.ReflectUtil; -import com.cloud.vm.VirtualMachine; +import com.cloud.utils.db.EntityManager; +import org.apache.cloudstack.api.Identity; import org.apache.log4j.Logger; import org.springframework.beans.factory.NoSuchBeanDefinitionException; @@ -54,6 +55,7 @@ public class ActionEventUtils { private static ProjectDao s_projectDao; protected static UserDao s_userDao; protected static EventBus s_eventBus = null; + protected static EntityManager s_entityMgr; public static final String EventDetails = "event_details"; public static final String EventId = "event_id"; @@ -69,6 +71,8 @@ public class ActionEventUtils { UserDao userDao; @Inject ProjectDao projectDao; + @Inject + EntityManager entityMgr; public ActionEventUtils() { } @@ -79,6 +83,7 @@ void init() { s_accountDao = accountDao; s_userDao = userDao; s_projectDao = projectDao; + s_entityMgr = entityMgr; } public static Long onActionEvent(Long userId, Long accountId, Long domainId, String type, String description) { @@ -188,19 +193,23 @@ private static void publishOnEventBus(long userId, long accountId, String eventC String entityType = null; String entityUuid = null; CallContext context = CallContext.current(); - String vmEntityName = ReflectUtil.getEntityName(VirtualMachine.class); - String vmuuid = (String) context.getContextParameter(vmEntityName); Class entityKey = getEntityKey(eventType); - if (entityKey != null) - { + if (entityKey != null){ //FIXME - Remove this since it should be covered by the else if condition below. entityUuid = (String)context.getContextParameter(entityKey); if (entityUuid != null) entityType = entityKey.getName(); - }else if (EventTypes.getEntityForEvent(eventType) != null){ - entityType = EventTypes.getEntityForEvent(eventType); - if (entityType != null){ - entityUuid = (String)context.getContextParameter(entityType); + }else if (EventTypes.getEntityClassForEvent(eventType) != null){ + //Get entity Class(Example - VirtualMachine.class) from the event Type eg. - VM.CREATE + Class entityClass = EventTypes.getEntityClassForEvent(eventType); + + //Get uuid from id + if(context.getContextParameter(entityClass.getName()) != null){ + try { + entityUuid = getEntityUuid(entityClass, context.getContextParameter(entityClass.getName())); + } catch (Exception e){ + s_logger.debug("Caught exception while finding entityUUID, moving on"); + } } } @@ -225,7 +234,7 @@ private static void publishOnEventBus(long userId, long accountId, String eventC eventDescription.put("entity", entityType); eventDescription.put("entityuuid", entityUuid); //Put all the first class entities that are touched during the action. For now atleast put in the vmid. - eventDescription.put(vmEntityName, vmuuid); + populateFirstClassEntities(eventDescription); eventDescription.put("description", description); String eventDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z").format(new Date()); @@ -240,6 +249,29 @@ private static void publishOnEventBus(long userId, long accountId, String eventC } } + private static String getEntityUuid(Class entityType, Object entityId){ + + // entityId can be internal db id or UUID so accordingly call findbyId or return uuid directly + + if (entityId instanceof Long){ + // Its internal db id - use findById + final Object objVO = s_entityMgr.findById(entityType, (Long)entityId); + return ((Identity)objVO).getUuid(); + } else if(entityId instanceof String){ + try{ + // In case its an async job the internal db id would be a string because of json deserialization + Long internalId = Long.valueOf((String) entityId); + final Object objVO = s_entityMgr.findById(entityType, internalId); + return ((Identity)objVO).getUuid(); + } catch (NumberFormatException e){ + // It is uuid - so return it + return (String)entityId; + } + } + + return null; + } + private static long getDomainId(long accountId) { AccountVO account = s_accountDao.findByIdIncludingRemoved(accountId); if (account == null) { @@ -249,6 +281,26 @@ private static long getDomainId(long accountId) { return account.getDomainId(); } + private static void populateFirstClassEntities(Map eventDescription){ + + CallContext context = CallContext.current(); + Map contextMap = context.getContextParameters(); + + for(Map.Entry entry : contextMap.entrySet()){ + try{ + Object key = entry.getKey(); + Class clz = Class.forName((String)key); + if(clz instanceof Class && Identity.class.isAssignableFrom(clz)){ + String uuid = getEntityUuid(clz, entry.getValue()); + eventDescription.put(ReflectUtil.getEntityName(clz), uuid); + } + } catch (Exception e){ + s_logger.trace("Caught exception while populating first class entities for event bus, moving on"); + } + } + + } + private static Class getEntityKey(String eventType) { // FIXME - Remove this diff --git a/server/src/com/cloud/ha/HighAvailabilityManagerImpl.java b/server/src/com/cloud/ha/HighAvailabilityManagerImpl.java index 48d998a53d..1318d9b8c7 100755 --- a/server/src/com/cloud/ha/HighAvailabilityManagerImpl.java +++ b/server/src/com/cloud/ha/HighAvailabilityManagerImpl.java @@ -72,7 +72,6 @@ import com.cloud.utils.component.ManagerBase; import com.cloud.utils.concurrency.NamedThreadFactory; import com.cloud.utils.exception.CloudRuntimeException; -import com.cloud.utils.fsm.StateListener; import com.cloud.vm.VMInstanceVO; import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachine.State; @@ -103,8 +102,7 @@ * before retrying the stop | seconds | 120 || * } **/ @Local(value = { HighAvailabilityManager.class }) -public class HighAvailabilityManagerImpl extends ManagerBase implements HighAvailabilityManager, ClusterManagerListener, - StateListener { +public class HighAvailabilityManagerImpl extends ManagerBase implements HighAvailabilityManager, ClusterManagerListener { protected static final Logger s_logger = Logger.getLogger(HighAvailabilityManagerImpl.class); WorkerThread[] _workers; @@ -236,7 +234,7 @@ public void scheduleRestartForVmsOnHost(final HostVO host, boolean investigate) return; } - s_logger.warn("Scheduling restart for VMs on host " + host.getId()); + s_logger.warn("Scheduling restart for VMs on host " + host.getId() + "-" + host.getName()); final List vms = _instanceDao.listByHostId(host.getId()); final DataCenterVO dcVO = _dcDao.findById(host.getDataCenterId()); @@ -269,12 +267,12 @@ public void scheduleRestartForVmsOnHost(final HostVO host, boolean investigate) for (VMInstanceVO vm : vms) { if (s_logger.isDebugEnabled()) { - s_logger.debug("Notifying HA Mgr of to restart vm " + vm.getId() + "-" + vm.getHostName()); + s_logger.debug("Notifying HA Mgr of to restart vm " + vm.getId() + "-" + vm.getInstanceName()); } vm = _instanceDao.findByUuid(vm.getUuid()); Long hostId = vm.getHostId(); if ( hostId != null && !hostId.equals(host.getId()) ) { - s_logger.debug("VM " + vm.getHostName() + " is not on down host " + host.getId() + " it is on other host " + s_logger.debug("VM " + vm.getInstanceName() + " is not on down host " + host.getId() + " it is on other host " + hostId + " VM HA is done"); continue; } @@ -503,7 +501,7 @@ protected Long restart(HaWorkVO work) { } else if (!alive) { fenced = true; } else { - s_logger.debug("VM " + vm.getHostName() + " is found to be alive by " + investigator.getName()); + s_logger.debug("VM " + vm.getInstanceName() + " is found to be alive by " + investigator.getName()); if (host.getStatus() == Status.Up) { s_logger.info(vm + " is alive and host is up. No need to restart it."); return null; @@ -806,7 +804,6 @@ public boolean configure(final String name, final Map xmlParams) _stopped = true; _executor = Executors.newScheduledThreadPool(count, new NamedThreadFactory("HA")); - VirtualMachine.State.getStateMachine().registerListener(this); return true; } @@ -921,6 +918,12 @@ private void runWithContext() { work.setTimeToTry(nextTime); work.setServerId(null); work.setDateTaken(null); + + // if restart failed in the middle due to exception, VM state may has been changed + // recapture into the HA worker so that it can really continue in it next turn + VMInstanceVO vm = _instanceDao.findById(work.getInstanceId()); + work.setUpdateTime(vm.getUpdated()); + work.setPreviousState(vm.getState()); } _haDao.update(work.getId(), work); } catch (final Throwable th) { @@ -962,38 +965,9 @@ public DeploymentPlanner getHAPlanner() { return _haPlanners.get(0); } - @Override - public boolean preStateTransitionEvent(State oldState, VirtualMachine.Event event, State newState, VirtualMachine vo, boolean status, Object opaque) { - return true; - } - - @Override - public boolean postStateTransitionEvent(State oldState, VirtualMachine.Event event, State newState, VirtualMachine vo, boolean status, Object opaque) { - if (oldState == State.Running && event == VirtualMachine.Event.FollowAgentPowerOffReport && newState == State.Stopped) { - final VMInstanceVO vm = _instanceDao.findById(vo.getId()); - if (vm.isHaEnabled()) { - if (vm.getState() != State.Stopped) - s_logger.warn("Sanity check failed. postStateTransitionEvent reports transited to Stopped but VM " + vm + " is still at state " + vm.getState()); - - s_logger.info("Detected out-of-band stop of a HA enabled VM " + vm.getInstanceName() + ", will schedule restart"); - _executor.submit(new ManagedContextRunnable() { - @Override - protected void runInContext() { - try { - scheduleRestart(vm, false); - } catch (Exception e) { - s_logger.warn("Unexpected exception when scheduling a HA restart", e); - } - } - }); - } - } - return true; - } - @Override public boolean hasPendingHaWork(long vmId) { - List haWorks = _haDao.listRunningHaWorkForVm(vmId); + List haWorks = _haDao.listPendingHaWorkForVm(vmId); return haWorks.size() > 0; } } diff --git a/server/src/com/cloud/ha/dao/HighAvailabilityDao.java b/server/src/com/cloud/ha/dao/HighAvailabilityDao.java index 7f532f2ae1..85135bb979 100644 --- a/server/src/com/cloud/ha/dao/HighAvailabilityDao.java +++ b/server/src/com/cloud/ha/dao/HighAvailabilityDao.java @@ -81,4 +81,6 @@ public interface HighAvailabilityDao extends GenericDao { * @return List of work items */ List listRunningHaWorkForVm(long vmId); + + List listPendingHaWorkForVm(long vmId); } diff --git a/server/src/com/cloud/ha/dao/HighAvailabilityDaoImpl.java b/server/src/com/cloud/ha/dao/HighAvailabilityDaoImpl.java index c0da88396c..d25c6a7937 100644 --- a/server/src/com/cloud/ha/dao/HighAvailabilityDaoImpl.java +++ b/server/src/com/cloud/ha/dao/HighAvailabilityDaoImpl.java @@ -49,6 +49,7 @@ public class HighAvailabilityDaoImpl extends GenericDaoBase impl private final SearchBuilder ReleaseSearch; private final SearchBuilder FutureHaWorkSearch; private final SearchBuilder RunningHaWorkSearch; + private final SearchBuilder PendingHaWorkSearch; protected HighAvailabilityDaoImpl() { super(); @@ -106,6 +107,22 @@ protected HighAvailabilityDaoImpl() { RunningHaWorkSearch.and("taken", RunningHaWorkSearch.entity().getDateTaken(), Op.NNULL); RunningHaWorkSearch.and("step", RunningHaWorkSearch.entity().getStep(), Op.NIN); RunningHaWorkSearch.done(); + + PendingHaWorkSearch = createSearchBuilder(); + PendingHaWorkSearch.and("instance", PendingHaWorkSearch.entity().getInstanceId(), Op.EQ); + PendingHaWorkSearch.and("type", PendingHaWorkSearch.entity().getType(), Op.EQ); + PendingHaWorkSearch.and("step", PendingHaWorkSearch.entity().getStep(), Op.NIN); + PendingHaWorkSearch.done(); + } + + @Override + public List listPendingHaWorkForVm(long vmId) { + SearchCriteria sc = PendingHaWorkSearch.create(); + sc.setParameters("instance", vmId); + sc.setParameters("type", WorkType.HA); + sc.setParameters("step", Step.Done, Step.Error, Step.Cancelled); + + return search(sc, null); } @Override diff --git a/server/src/com/cloud/hypervisor/HypervisorGuruBase.java b/server/src/com/cloud/hypervisor/HypervisorGuruBase.java index b643ec41fa..e2520d26ff 100644 --- a/server/src/com/cloud/hypervisor/HypervisorGuruBase.java +++ b/server/src/com/cloud/hypervisor/HypervisorGuruBase.java @@ -144,7 +144,8 @@ protected VirtualMachineTO toVirtualMachineTO(VirtualMachineProfile vmProfile) { // Set GPU details ServiceOfferingDetailsVO offeringDetail = null; if ((offeringDetail = _serviceOfferingDetailsDao.findDetail(offering.getId(), GPU.Keys.vgpuType.toString())) != null) { - to.setGpuDevice(_resourceMgr.getGPUDevice(vm.getHostId(), offeringDetail.getValue())); + ServiceOfferingDetailsVO groupName = _serviceOfferingDetailsDao.findDetail(offering.getId(), GPU.Keys.pciDevice.toString()); + to.setGpuDevice(_resourceMgr.getGPUDevice(vm.getHostId(), groupName.getValue(), offeringDetail.getValue())); } // Workaround to make sure the TO has the UUID we need for Niciri integration diff --git a/server/src/com/cloud/hypervisor/KVMGuru.java b/server/src/com/cloud/hypervisor/KVMGuru.java index e47e699b02..954ada856c 100644 --- a/server/src/com/cloud/hypervisor/KVMGuru.java +++ b/server/src/com/cloud/hypervisor/KVMGuru.java @@ -19,16 +19,28 @@ import javax.ejb.Local; import javax.inject.Inject; +import org.apache.cloudstack.storage.command.StorageSubSystemCommand; + +import com.cloud.agent.api.Command; import com.cloud.agent.api.to.VirtualMachineTO; +import com.cloud.host.HostVO; +import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.storage.GuestOSHypervisorVO; import com.cloud.storage.GuestOSVO; import com.cloud.storage.dao.GuestOSDao; +import com.cloud.storage.dao.GuestOSHypervisorDao; +import com.cloud.utils.Pair; import com.cloud.vm.VirtualMachineProfile; @Local(value = HypervisorGuru.class) public class KVMGuru extends HypervisorGuruBase implements HypervisorGuru { @Inject GuestOSDao _guestOsDao; + @Inject + GuestOSHypervisorDao _guestOsHypervisorDao; + @Inject + HostDao _hostDao; @Override public HypervisorType getHypervisorType() { @@ -40,16 +52,33 @@ protected KVMGuru() { } @Override + public VirtualMachineTO implement(VirtualMachineProfile vm) { VirtualMachineTO to = toVirtualMachineTO(vm); // Determine the VM's OS description - GuestOSVO guestOS = _guestOsDao.findById(vm.getVirtualMachine().getGuestOSId()); + GuestOSVO guestOS = _guestOsDao.findByIdIncludingRemoved(vm.getVirtualMachine().getGuestOSId()); to.setOs(guestOS.getDisplayName()); + HostVO host = _hostDao.findById(vm.getVirtualMachine().getHostId()); + GuestOSHypervisorVO guestOsMapping = _guestOsHypervisorDao.findByOsIdAndHypervisor(guestOS.getId(), getHypervisorType().toString(), host.getHypervisorVersion()); + if (guestOsMapping == null) { + to.setPlatformEmulator(null); + } else { + to.setPlatformEmulator(guestOsMapping.getGuestOsName()); + } return to; } + @Override + public Pair getCommandHostDelegation(long hostId, Command cmd) { + if (cmd instanceof StorageSubSystemCommand) { + StorageSubSystemCommand c = (StorageSubSystemCommand)cmd; + c.setExecuteInSequence(false); + } + return new Pair(false, new Long(hostId)); + } + @Override public boolean trackVmHostChange() { return false; diff --git a/server/src/com/cloud/hypervisor/kvm/discoverer/LibvirtServerDiscoverer.java b/server/src/com/cloud/hypervisor/kvm/discoverer/LibvirtServerDiscoverer.java index d127256d0f..8eb6c89e6f 100644 --- a/server/src/com/cloud/hypervisor/kvm/discoverer/LibvirtServerDiscoverer.java +++ b/server/src/com/cloud/hypervisor/kvm/discoverer/LibvirtServerDiscoverer.java @@ -16,18 +16,6 @@ // under the License. package com.cloud.hypervisor.kvm.discoverer; -import java.net.InetAddress; -import java.net.URI; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.UUID; - -import javax.inject.Inject; -import javax.naming.ConfigurationException; - -import org.apache.log4j.Logger; - import com.cloud.agent.AgentManager; import com.cloud.agent.Listener; import com.cloud.agent.api.AgentControlAnswer; @@ -55,6 +43,16 @@ import com.cloud.resource.ServerResource; import com.cloud.resource.UnableDeleteHostException; import com.cloud.utils.ssh.SSHCmdHelper; +import org.apache.log4j.Logger; + +import javax.inject.Inject; +import javax.naming.ConfigurationException; +import java.net.InetAddress; +import java.net.URI; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; public abstract class LibvirtServerDiscoverer extends DiscovererBase implements Discoverer, Listener, ResourceStateAdapter { private static final Logger s_logger = Logger.getLogger(LibvirtServerDiscoverer.class); @@ -211,6 +209,8 @@ public boolean processTimeout(long agentId, long seq) { KvmDummyResourceBase kvmResource = new KvmDummyResourceBase(); Map params = new HashMap(); + params.put("router.aggregation.command.each.timeout", _configDao.getValue(Config.RouterAggregationCommandEachTimeout.toString())); + params.put("zone", Long.toString(dcId)); params.put("pod", Long.toString(podId)); params.put("cluster", Long.toString(clusterId)); diff --git a/server/src/com/cloud/metadata/ResourceMetaDataManagerImpl.java b/server/src/com/cloud/metadata/ResourceMetaDataManagerImpl.java index d91da921eb..812630ab8b 100644 --- a/server/src/com/cloud/metadata/ResourceMetaDataManagerImpl.java +++ b/server/src/com/cloud/metadata/ResourceMetaDataManagerImpl.java @@ -36,11 +36,15 @@ import org.apache.cloudstack.resourcedetail.dao.Site2SiteCustomerGatewayDetailsDao; import org.apache.cloudstack.resourcedetail.dao.Site2SiteVpnConnectionDetailsDao; import org.apache.cloudstack.resourcedetail.dao.Site2SiteVpnGatewayDetailsDao; +import org.apache.cloudstack.resourcedetail.dao.SnapshotPolicyDetailsDao; import org.apache.cloudstack.resourcedetail.dao.UserDetailsDao; import org.apache.cloudstack.resourcedetail.dao.UserIpAddressDetailsDao; import org.apache.cloudstack.resourcedetail.dao.VpcDetailsDao; import org.apache.cloudstack.resourcedetail.dao.VpcGatewayDetailsDao; +import org.apache.cloudstack.resourcedetail.dao.LBStickinessPolicyDetailsDao; +import org.apache.cloudstack.resourcedetail.dao.LBHealthCheckPolicyDetailsDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao; + import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -113,6 +117,12 @@ public class ResourceMetaDataManagerImpl extends ManagerBase implements Resource AutoScaleVmProfileDetailsDao _autoScaleVmProfileDetailsDao; @Inject AutoScaleVmGroupDetailsDao _autoScaleVmGroupDetailsDao; + @Inject + LBStickinessPolicyDetailsDao _stickinessPolicyDetailsDao; + @Inject + LBHealthCheckPolicyDetailsDao _healthcheckPolicyDetailsDao; + @Inject + SnapshotPolicyDetailsDao _snapshotPolicyDetailsDao; private static Map> s_daoMap = new HashMap>(); @@ -142,6 +152,9 @@ public boolean configure(String name, Map params) throws Configu s_daoMap.put(ResourceObjectType.User, _userDetailsDao); s_daoMap.put(ResourceObjectType.AutoScaleVmProfile, _autoScaleVmProfileDetailsDao); s_daoMap.put(ResourceObjectType.AutoScaleVmGroup, _autoScaleVmGroupDetailsDao); + s_daoMap.put(ResourceObjectType.LBStickinessPolicy, _stickinessPolicyDetailsDao); + s_daoMap.put(ResourceObjectType.LBHealthCheckPolicy, _healthcheckPolicyDetailsDao); + s_daoMap.put(ResourceObjectType.SnapshotPolicy, _snapshotPolicyDetailsDao); return true; } @@ -215,6 +228,10 @@ private ResourceDetail getDetail(long resourceId, String key) { return dao.findDetail(resourceId, key); } + private List getDetails(String key, String value, Boolean forDisplay) { + return dao.findDetails(key, value, forDisplay); + } + private void addDetail(long resourceId, String key, String value, boolean forDisplay) { dao.addDetail(resourceId, key, value, forDisplay); } @@ -248,6 +265,12 @@ public ResourceDetail getDetail(long resourceId, ResourceObjectType resourceType return newDetailDaoHelper.getDetail(resourceId, key); } + @Override + public List getDetails(ResourceObjectType resourceType, String key, String value, Boolean forDisplay){ + DetailDaoHelper newDetailDaoHelper = new DetailDaoHelper(resourceType); + return newDetailDaoHelper.getDetails(key, value, forDisplay); + } + @Override public Map getDetailsMap(long resourceId, ResourceObjectType resourceType, Boolean forDisplay) { DetailDaoHelper newDetailDaoHelper = new DetailDaoHelper(resourceType); diff --git a/server/src/com/cloud/network/NetworkModelImpl.java b/server/src/com/cloud/network/NetworkModelImpl.java index 7b4b2bebdb..3d2b1333ef 100755 --- a/server/src/com/cloud/network/NetworkModelImpl.java +++ b/server/src/com/cloud/network/NetworkModelImpl.java @@ -736,6 +736,31 @@ public NetworkVO getSystemNetworkByZoneAndTrafficType(long zoneId, TrafficType t return networks.get(0); } + @Override + public NetworkVO getNetworkWithSGWithFreeIPs(Long zoneId) { + List networks = _networksDao.listByZoneSecurityGroup(zoneId); + if (networks == null || networks.isEmpty()) { + return null; + } + NetworkVO ret_network = null; + for (NetworkVO nw : networks) { + List vlans = _vlanDao.listVlansByNetworkId(nw.getId()); + for (VlanVO vlan : vlans) { + if (_ipAddressDao.countFreeIpsInVlan(vlan.getId()) > 0) { + ret_network = nw; + break; + } + } + if (ret_network != null) { + break; + } + } + if (ret_network == null) { + s_logger.debug("Can not find network with security group enabled with free IPs"); + } + return ret_network; + } + @Override public NetworkVO getNetworkWithSecurityGroupEnabled(Long zoneId) { List networks = _networksDao.listByZoneSecurityGroup(zoneId); diff --git a/server/src/com/cloud/network/NetworkServiceImpl.java b/server/src/com/cloud/network/NetworkServiceImpl.java index 9238a1e8ce..95d3decb10 100755 --- a/server/src/com/cloud/network/NetworkServiceImpl.java +++ b/server/src/com/cloud/network/NetworkServiceImpl.java @@ -105,6 +105,7 @@ import com.cloud.network.dao.FirewallRulesDao; import com.cloud.network.dao.IPAddressDao; import com.cloud.network.dao.IPAddressVO; +import com.cloud.network.dao.LoadBalancerVMMapDao; import com.cloud.network.dao.NetworkDao; import com.cloud.network.dao.NetworkDomainDao; import com.cloud.network.dao.NetworkDomainVO; @@ -122,6 +123,7 @@ import com.cloud.network.element.VirtualRouterElement; import com.cloud.network.element.VpcVirtualRouterElement; import com.cloud.network.guru.NetworkGuru; +import com.cloud.network.lb.LoadBalancingRulesService; import com.cloud.network.rules.FirewallRule.Purpose; import com.cloud.network.rules.FirewallRuleVO; import com.cloud.network.rules.RulesManager; @@ -307,6 +309,11 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { IpAddressManager _ipAddrMgr; @Inject EntityManager _entityMgr; + @Inject + LoadBalancerVMMapDao _lbVmMapDao; + + @Inject + LoadBalancingRulesService _lbService; int _cidrLimit; boolean _allowSubdomainNetworkAccess; @@ -806,7 +813,13 @@ public boolean releaseSecondaryIpFromNic(long ipAddressId) { s_logger.debug("VM nic IP " + secondaryIp + " is associated with the static NAT rule public IP address id " + publicIpVO.getId()); throw new InvalidParameterValueException("Can' remove the ip " + secondaryIp + "is associate with static NAT rule public IP address id " + publicIpVO.getId()); } - } else if (dc.getNetworkType() == NetworkType.Basic || ntwkOff.getGuestType() == Network.GuestType.Shared) { + + if (_lbService.isLbRuleMappedToVmGuestIp(secondaryIp)) { + s_logger.debug("VM nic IP " + secondaryIp + " is mapped to load balancing rule"); + throw new InvalidParameterValueException("Can't remove the secondary ip " + secondaryIp + " is mapped to load balancing rule"); + } + + } else if (dc.getNetworkType() == NetworkType.Basic || ntwkOff.getGuestType() == Network.GuestType.Shared) { final IPAddressVO ip = _ipAddressDao.findByIpAndSourceNetworkId(secIpVO.getNetworkId(), secIpVO.getIp4Address()); if (ip != null) { Transaction.execute(new TransactionCallbackNoReturn() { @@ -1072,14 +1085,14 @@ public Network createGuestNetwork(CreateNetworkCmd cmd) throws InsufficientCapac } // Only Admin can create Shared networks - if (ntwkOff.getGuestType() == GuestType.Shared && !_accountMgr.isAdmin(caller.getType())) { + if (ntwkOff.getGuestType() == GuestType.Shared && !_accountMgr.isAdmin(caller.getId())) { throw new InvalidParameterValueException("Only Admins can create network with guest type " + GuestType.Shared); } // Check if the network is domain specific if (aclType == ACLType.Domain) { // only Admin can create domain with aclType=Domain - if (!_accountMgr.isAdmin(caller.getType())) { + if (!_accountMgr.isAdmin(caller.getId())) { throw new PermissionDeniedException("Only admin can create networks with aclType=Domain"); } @@ -1424,7 +1437,7 @@ public Pair, Integer> searchForNetworks(ListNetworksCmd } } - if (!_accountMgr.isAdmin(caller.getType()) || (projectId != null && projectId.longValue() != -1 && domainId == null)) { + if (!_accountMgr.isAdmin(caller.getId()) || (projectId != null && projectId.longValue() != -1 && domainId == null)) { permittedAccounts.add(caller.getId()); domainId = caller.getDomainId(); } @@ -1433,7 +1446,7 @@ public Pair, Integer> searchForNetworks(ListNetworksCmd boolean skipProjectNetworks = true; if (projectId != null) { if (projectId.longValue() == -1) { - if (!_accountMgr.isAdmin(caller.getType())) { + if (!_accountMgr.isAdmin(caller.getId())) { permittedAccounts.addAll(_projectMgr.listPermittedProjectAccounts(caller.getId())); } } else { @@ -1452,7 +1465,7 @@ public Pair, Integer> searchForNetworks(ListNetworksCmd //add project account permittedAccounts.add(project.getProjectAccountId()); //add caller account (if admin) - if (_accountMgr.isAdmin(caller.getType())) { + if (_accountMgr.isAdmin(caller.getId())) { permittedAccounts.add(caller.getId()); } } @@ -2265,9 +2278,9 @@ public void doInTransactionWithoutResult(TransactionStatus status) { long isDefault = (nic.isDefaultNic()) ? 1 : 0; String nicIdString = Long.toString(nic.getId()); UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NETWORK_OFFERING_REMOVE, vm.getAccountId(), vm.getDataCenterId(), vm.getId(), nicIdString, - oldNetworkOfferingId, null, isDefault, VirtualMachine.class.getName(), vm.getUuid()); + oldNetworkOfferingId, null, isDefault, VirtualMachine.class.getName(), vm.getUuid(), vm.isDisplay()); UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NETWORK_OFFERING_ASSIGN, vm.getAccountId(), vm.getDataCenterId(), vm.getId(), nicIdString, - networkOfferingId, null, isDefault, VirtualMachine.class.getName(), vm.getUuid()); + networkOfferingId, null, isDefault, VirtualMachine.class.getName(), vm.getUuid(), vm.isDisplay()); } } }); @@ -3819,12 +3832,12 @@ private PhysicalNetworkServiceProvider addDefaultBaremetalProvidersToPhysicalNet PhysicalNetworkVO pvo = _physicalNetworkDao.findById(physicalNetworkId); DataCenterVO dvo = _dcDao.findById(pvo.getDataCenterId()); if (dvo.getNetworkType() == NetworkType.Basic) { - - Provider provider = Network.Provider.getProvider("BaremetalDhcpProvider"); - if (provider == null) { + + Provider provider = Network.Provider.getProvider("BaremetalDhcpProvider"); + if (provider == null) { // baremetal is not loaded return null; - } + } addProviderToPhysicalNetwork(physicalNetworkId, "BaremetalDhcpProvider", null, null); addProviderToPhysicalNetwork(physicalNetworkId, "BaremetalPxeProvider", null, null); @@ -3955,12 +3968,16 @@ public Network doInTransaction(TransactionStatus status) throws ResourceAllocati DataCenterVO dc = _dcDao.lockRow(pNtwk.getDataCenterId(), true); //check if we need to create guest network - Network privateNetwork = _networksDao.getPrivateNetwork(uriString, cidr, networkOwnerId, pNtwk.getDataCenterId(), networkOfferingId); + Network privateNetwork = _networksDao.getPrivateNetwork(uriString, cidr, networkOwnerId, pNtwk.getDataCenterId(), networkOfferingId); if (privateNetwork == null) { //create Guest network - privateNetwork = _networkMgr.createGuestNetwork(ntwkOffFinal.getId(), networkName, displayText, gateway, cidr, uriString, null, owner, null, pNtwk, + privateNetwork = _networkMgr.createGuestNetwork(ntwkOffFinal.getId(), networkName, displayText, gateway, cidr, uriString, null, owner, null, pNtwk, pNtwk.getDataCenterId(), ACLType.Account, null, vpcId, null, null, true, null); - s_logger.debug("Created private network " + privateNetwork); + if (privateNetwork != null) { + s_logger.debug("Successfully created guest network " + privateNetwork); + } else { + throw new CloudRuntimeException("Creating guest network failed"); + } } else { s_logger.debug("Private network already exists: " + privateNetwork); //Do not allow multiple private gateways with same Vlan within a VPC diff --git a/server/src/com/cloud/network/as/AutoScaleManagerImpl.java b/server/src/com/cloud/network/as/AutoScaleManagerImpl.java index 99189fe43a..96d82adc34 100644 --- a/server/src/com/cloud/network/as/AutoScaleManagerImpl.java +++ b/server/src/com/cloud/network/as/AutoScaleManagerImpl.java @@ -108,6 +108,7 @@ import com.cloud.uservm.UserVm; import com.cloud.utils.Pair; import com.cloud.utils.Ternary; +import com.cloud.utils.component.ComponentContext; import com.cloud.utils.component.ManagerBase; import com.cloud.utils.db.DB; import com.cloud.utils.db.EntityManager; @@ -116,9 +117,9 @@ import com.cloud.utils.db.JoinBuilder; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.TransactionCallback; import com.cloud.utils.db.SearchCriteria.Op; import com.cloud.utils.db.Transaction; -import com.cloud.utils.db.TransactionCallback; import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.net.NetUtils; import com.cloud.vm.UserVmManager; @@ -370,7 +371,7 @@ public AutoScaleVmProfile createAutoScaleVmProfile(CreateAutoScaleVmProfileCmd c * For ex. if projectId is given as a string instead of an long value, this * will be throwing an error. */ - dispatchChainFactory.getStandardDispatchChain().dispatch(new DispatchTask(new DeployVMCmd(), deployParams)); + dispatchChainFactory.getStandardDispatchChain().dispatch(new DispatchTask(ComponentContext.inject(DeployVMCmd.class), deployParams)); AutoScaleVmProfileVO profileVO = new AutoScaleVmProfileVO(cmd.getZoneId(), cmd.getDomainId(), cmd.getAccountId(), cmd.getServiceOfferingId(), cmd.getTemplateId(), cmd.getOtherDeployParams(), @@ -461,8 +462,7 @@ public List listAutoScaleVmProfiles(ListAutoScaleV Long zoneId = cmd.getZoneId(); Boolean display = cmd.getDisplay(); - SearchWrapper searchWrapper = new SearchWrapper(_autoScaleVmProfileDao, AutoScaleVmProfileVO.class, cmd, cmd.getId(), - "listAutoScaleVmProfiles"); + SearchWrapper searchWrapper = new SearchWrapper(_autoScaleVmProfileDao, AutoScaleVmProfileVO.class, cmd, cmd.getId()); SearchBuilder sb = searchWrapper.getSearchBuilder(); sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); @@ -630,14 +630,11 @@ private class SearchWrapper { SearchCriteria searchCriteria; Long domainId; boolean isRecursive; - List permittedDomains = new ArrayList(); List permittedAccounts = new ArrayList(); - List permittedResources = new ArrayList(); - ListProjectResourcesCriteria listProjectResourcesCriteria; Filter searchFilter; - public SearchWrapper(GenericDao dao, Class entityClass, BaseListAccountResourcesCmd cmd, Long id, String action) + public SearchWrapper(GenericDao dao, Class entityClass, BaseListAccountResourcesCmd cmd, Long id) { this.dao = dao; this.searchBuilder = dao.createSearchBuilder(); @@ -651,12 +648,12 @@ public SearchWrapper(GenericDao dao, Class entityClass, BaseListAc Ternary domainIdRecursiveListProject = new Ternary(domainId, isRecursive, null); - _accountMgr.buildACLSearchParameters(caller, id, accountName, null, permittedDomains, permittedAccounts, permittedResources, domainIdRecursiveListProject, listAll, - false, action); - //domainId = domainIdRecursiveListProject.first(); + _accountMgr.buildACLSearchParameters(caller, id, accountName, null, permittedAccounts, domainIdRecursiveListProject, + listAll, false); + domainId = domainIdRecursiveListProject.first(); isRecursive = domainIdRecursiveListProject.second(); ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third(); - _accountMgr.buildACLSearchBuilder(searchBuilder, isRecursive, permittedDomains, permittedAccounts, permittedResources, listProjectResourcesCriteria); + _accountMgr.buildACLSearchBuilder(searchBuilder, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); searchFilter = new Filter(entityClass, "id", false, startIndex, pageSizeVal); } @@ -666,7 +663,7 @@ public SearchBuilder getSearchBuilder() { public SearchCriteria buildSearchCriteria() { searchCriteria = searchBuilder.create(); - _accountMgr.buildACLSearchCriteria(searchCriteria, isRecursive, permittedDomains, permittedAccounts, permittedResources, listProjectResourcesCriteria); + _accountMgr.buildACLSearchCriteria(searchCriteria, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); return searchCriteria; } @@ -677,8 +674,7 @@ public List search() { @Override public List listAutoScalePolicies(ListAutoScalePoliciesCmd cmd) { - SearchWrapper searchWrapper = new SearchWrapper(_autoScalePolicyDao, AutoScalePolicyVO.class, cmd, cmd.getId(), - "listAutoScalePolicies"); + SearchWrapper searchWrapper = new SearchWrapper(_autoScalePolicyDao, AutoScalePolicyVO.class, cmd, cmd.getId()); SearchBuilder sb = searchWrapper.getSearchBuilder(); Long id = cmd.getId(); Long conditionId = cmd.getConditionId(); @@ -884,8 +880,7 @@ public List listAutoScaleVmGroups(ListAutoScaleVmGro Long zoneId = cmd.getZoneId(); Boolean forDisplay = cmd.getDisplay(); - SearchWrapper searchWrapper = new SearchWrapper(_autoScaleVmGroupDao, AutoScaleVmGroupVO.class, cmd, cmd.getId(), - "listAutoScaleVmGroups"); + SearchWrapper searchWrapper = new SearchWrapper(_autoScaleVmGroupDao, AutoScaleVmGroupVO.class, cmd, cmd.getId()); SearchBuilder sb = searchWrapper.getSearchBuilder(); sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); @@ -1176,7 +1171,7 @@ public List listConditions(ListConditionsCmd cmd) { Long id = cmd.getId(); Long counterId = cmd.getCounterId(); Long policyId = cmd.getPolicyId(); - SearchWrapper searchWrapper = new SearchWrapper(_conditionDao, ConditionVO.class, cmd, cmd.getId(), "listConditions"); + SearchWrapper searchWrapper = new SearchWrapper(_conditionDao, ConditionVO.class, cmd, cmd.getId()); SearchBuilder sb = searchWrapper.getSearchBuilder(); if (policyId != null) { SearchBuilder asPolicyConditionSearch = _autoScalePolicyConditionMapDao.createSearchBuilder(); @@ -1414,7 +1409,7 @@ private boolean assignLBruleToNewVm(long vmId, AutoScaleVmGroupVO asGroup) { } } lstVmId.add(new Long(vmId)); - return _loadBalancingRulesService.assignToLoadBalancer(lbId, lstVmId); + return _loadBalancingRulesService.assignToLoadBalancer(lbId, lstVmId, new HashMap>()); } @@ -1431,7 +1426,7 @@ private long removeLBrule(AutoScaleVmGroupVO asGroup) { List lstVmId = new ArrayList(); if (instanceId != -1) lstVmId.add(instanceId); - if (_loadBalancingRulesService.removeFromLoadBalancer(lbId, lstVmId)) + if (_loadBalancingRulesService.removeFromLoadBalancer(lbId, lstVmId, new HashMap>())) return instanceId; else return -1; diff --git a/server/src/com/cloud/network/element/VirtualRouterElement.java b/server/src/com/cloud/network/element/VirtualRouterElement.java index 3f4ba5b5d3..3b3cacd094 100755 --- a/server/src/com/cloud/network/element/VirtualRouterElement.java +++ b/server/src/com/cloud/network/element/VirtualRouterElement.java @@ -188,10 +188,16 @@ public boolean implement(Network network, NetworkOffering offering, DeployDestin Map params = new HashMap(1); params.put(VirtualMachineProfile.Param.ReProgramGuestNetworks, true); - List routers = - _routerMgr.deployVirtualRouterInGuestNetwork(network, dest, _accountMgr.getAccount(network.getAccountId()), params, offering.getRedundantRouter()); - if ((routers == null) || (routers.size() == 0)) { - throw new ResourceUnavailableException("Can't find at least one running router!", DataCenter.class, network.getDataCenterId()); + List routers = _routerMgr.deployVirtualRouterInGuestNetwork(network, dest, + _accountMgr.getAccount(network.getAccountId()), params, + offering.getRedundantRouter()); + int routerCounts = 1; + if (offering.getRedundantRouter()) { + routerCounts = 2; + } + if ((routers == null) || (routers.size() < routerCounts)) { + throw new ResourceUnavailableException("Can't find all necessary running routers!", + DataCenter.class, network.getDataCenterId()); } return true; diff --git a/server/src/com/cloud/network/firewall/FirewallManagerImpl.java b/server/src/com/cloud/network/firewall/FirewallManagerImpl.java index c312d3d1ba..dd928d8d6f 100644 --- a/server/src/com/cloud/network/firewall/FirewallManagerImpl.java +++ b/server/src/com/cloud/network/firewall/FirewallManagerImpl.java @@ -27,12 +27,13 @@ import javax.inject.Inject; import javax.naming.ConfigurationException; +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; + import org.apache.cloudstack.api.command.user.firewall.ListFirewallRulesCmd; 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.log4j.Logger; -import org.springframework.stereotype.Component; import com.cloud.configuration.Config; import com.cloud.domain.dao.DomainDao; @@ -160,7 +161,7 @@ public boolean start() { } @Override - @ActionEvent(eventType = EventTypes.EVENT_FIREWALL_OPEN, eventDescription = "creating firewall rule", create = true) + @ActionEvent(eventType = EventTypes.EVENT_FIREWALL_EGRESS_OPEN, eventDescription = "creating egress firewall rule for network", create = true) public FirewallRule createEgressFirewallRule(FirewallRule rule) throws NetworkRuleConflictException { Account caller = CallContext.current().getCallingAccount(); @@ -262,9 +263,7 @@ public Pair, Integer> listFirewallRules(ListFirewal Boolean display = cmd.getDisplay(); Account caller = CallContext.current().getCallingAccount(); - List permittedDomains = new ArrayList(); List permittedAccounts = new ArrayList(); - List permittedResources = new ArrayList(); if (ipId != null) { IPAddressVO ipAddressVO = _ipAddressDao.findById(ipId); @@ -275,13 +274,14 @@ public Pair, Integer> listFirewallRules(ListFirewal } Ternary domainIdRecursiveListProject = new Ternary(cmd.getDomainId(), cmd.isRecursive(), null); - _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedDomains, permittedAccounts, permittedResources, domainIdRecursiveListProject, cmd.listAll(), false, "listFirewallRules"); + _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, cmd.listAll(), false); + Long domainId = domainIdRecursiveListProject.first(); Boolean isRecursive = domainIdRecursiveListProject.second(); ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third(); Filter filter = new Filter(FirewallRuleVO.class, "id", false, cmd.getStartIndex(), cmd.getPageSizeVal()); SearchBuilder sb = _firewallDao.createSearchBuilder(); - _accountMgr.buildACLSearchBuilder(sb, isRecursive, permittedDomains, permittedAccounts, permittedResources, listProjectResourcesCriteria); + _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); sb.and("id", sb.entity().getId(), Op.EQ); sb.and("trafficType", sb.entity().getTrafficType(), Op.EQ); @@ -303,7 +303,7 @@ public Pair, Integer> listFirewallRules(ListFirewal } SearchCriteria sc = sb.create(); - _accountMgr.buildACLSearchCriteria(sc, isRecursive, permittedDomains, permittedAccounts, permittedResources, listProjectResourcesCriteria); + _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); if (id != null) { sc.setParameters("id", id); @@ -612,6 +612,12 @@ public void removeRule(FirewallRule rule) { _firewallDao.remove(rule.getId()); } + @Override + @ActionEvent(eventType = EventTypes.EVENT_FIREWALL_OPEN, eventDescription = "creating firewall rule", async = true) + public boolean applyIngressFwRules(long ipId, Account caller) throws ResourceUnavailableException { + return applyIngressFirewallRules(ipId, caller); + } + @Override public boolean applyIngressFirewallRules(long ipId, Account caller) throws ResourceUnavailableException { List rules = _firewallDao.listByIpAndPurpose(ipId, Purpose.Firewall); @@ -619,6 +625,7 @@ public boolean applyIngressFirewallRules(long ipId, Account caller) throws Resou } @Override + @ActionEvent(eventType = EventTypes.EVENT_FIREWALL_EGRESS_OPEN, eventDescription = "creating egress firewall rule", async = true) public boolean applyEgressFirewallRules(FirewallRule rule, Account caller) throws ResourceUnavailableException { List rules = _firewallDao.listByNetworkPurposeTrafficType(rule.getNetworkId(), Purpose.Firewall, FirewallRule.TrafficType.Egress); return applyFirewallRules(rules, false, caller); @@ -719,7 +726,21 @@ protected boolean revokeFirewallRule(long ruleId, boolean apply, Account caller, @Override @ActionEvent(eventType = EventTypes.EVENT_FIREWALL_CLOSE, eventDescription = "revoking firewall rule", async = true) - public boolean revokeFirewallRule(long ruleId, boolean apply) { + public boolean revokeIngressFwRule(long ruleId, boolean apply) { + return revokeIngressFirewallRule(ruleId, apply); + } + + + @Override + public boolean revokeIngressFirewallRule(long ruleId, boolean apply) { + Account caller = CallContext.current().getCallingAccount(); + long userId = CallContext.current().getCallingUserId(); + return revokeFirewallRule(ruleId, apply, caller, userId); + } + + @Override + @ActionEvent(eventType = EventTypes.EVENT_FIREWALL_EGRESS_CLOSE, eventDescription = "revoking egress firewall rule", async = true) + public boolean revokeEgressFirewallRule(long ruleId, boolean apply) { Account caller = CallContext.current().getCallingAccount(); long userId = CallContext.current().getCallingUserId(); return revokeFirewallRule(ruleId, apply, caller, userId); @@ -727,7 +748,14 @@ public boolean revokeFirewallRule(long ruleId, boolean apply) { @Override @ActionEvent(eventType = EventTypes.EVENT_FIREWALL_UPDATE, eventDescription = "updating firewall rule", async = true) - public FirewallRule updateFirewallRule(long ruleId, String customId, Boolean forDisplay) { + public FirewallRule updateIngressFirewallRule(long ruleId, String customId, Boolean forDisplay) { + Account caller = CallContext.current().getCallingAccount(); + return updateFirewallRule(ruleId, customId, caller, forDisplay); + } + + @Override + @ActionEvent(eventType = EventTypes.EVENT_FIREWALL_EGRESS_UPDATE, eventDescription = "updating egress firewall rule", async = true) + public FirewallRule updateEgressFirewallRule(long ruleId, String customId, Boolean forDisplay) { Account caller = CallContext.current().getCallingAccount(); return updateFirewallRule(ruleId, customId, caller, forDisplay); } @@ -881,7 +909,7 @@ public boolean revokeRelatedFirewallRule(long ruleId, boolean apply) { } s_logger.debug("Revoking Firewall rule id=" + fwRule.getId() + " as a part of rule delete id=" + ruleId + " with apply=" + apply); - return revokeFirewallRule(fwRule.getId(), apply); + return revokeIngressFirewallRule(fwRule.getId(), apply); } diff --git a/server/src/com/cloud/network/guru/DirectNetworkGuru.java b/server/src/com/cloud/network/guru/DirectNetworkGuru.java index e570dddfb9..d558a5703b 100755 --- a/server/src/com/cloud/network/guru/DirectNetworkGuru.java +++ b/server/src/com/cloud/network/guru/DirectNetworkGuru.java @@ -21,6 +21,7 @@ import javax.ejb.Local; import javax.inject.Inject; +import com.cloud.utils.exception.CloudRuntimeException; import org.apache.log4j.Logger; import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; @@ -47,10 +48,6 @@ import com.cloud.network.Networks.BroadcastDomainType; import com.cloud.network.Networks.Mode; import com.cloud.network.Networks.TrafficType; -import com.cloud.network.dao.IPAddressDao; -import com.cloud.network.dao.IPAddressVO; -import com.cloud.network.dao.NetworkVO; -import com.cloud.network.dao.UserIpv6AddressDao; import com.cloud.offering.NetworkOffering; import com.cloud.offerings.dao.NetworkOfferingDao; import com.cloud.user.Account; @@ -70,6 +67,11 @@ import com.cloud.vm.VirtualMachineProfile; import com.cloud.vm.dao.NicDao; import com.cloud.vm.dao.NicSecondaryIpDao; +import com.cloud.network.dao.IPAddressDao; +import com.cloud.network.dao.IPAddressVO; +import com.cloud.network.dao.NetworkVO; +import com.cloud.network.dao.UserIpv6AddressDao; + @Local(value = {NetworkGuru.class}) public class DirectNetworkGuru extends AdapterBase implements NetworkGuru { @@ -323,24 +325,33 @@ public void shutdown(NetworkProfile network, NetworkOffering offering) { @DB public boolean trash(Network network, NetworkOffering offering) { //Have to remove all placeholder nics - final List nics = _nicDao.listPlaceholderNicsByNetworkId(network.getId()); - Transaction.execute(new TransactionCallbackNoReturn() { - @Override - public void doInTransactionWithoutResult(TransactionStatus status) { - for (Nic nic : nics) { - if (nic.getIp4Address() != null) { - s_logger.debug("Releasing ip " + nic.getIp4Address() + " of placeholder nic " + nic); - IPAddressVO ip = _ipAddressDao.findByIpAndSourceNetworkId(nic.getNetworkId(), nic.getIp4Address()); - _ipAddrMgr.markIpAsUnavailable(ip.getId()); - _ipAddressDao.unassignIpAddress(ip.getId()); - s_logger.debug("Removing placeholder nic " + nic); - _nicDao.remove(nic.getId()); + try { + long id = network.getId(); + final List nics = _nicDao.listPlaceholderNicsByNetworkId(id); + if (nics != null) { + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + for (Nic nic : nics) { + if (nic.getIp4Address() != null) { + s_logger.debug("Releasing ip " + nic.getIp4Address() + " of placeholder nic " + nic); + IPAddressVO ip = _ipAddressDao.findByIpAndSourceNetworkId(nic.getNetworkId(), nic.getIp4Address()); + if (ip != null) { + _ipAddrMgr.markIpAsUnavailable(ip.getId()); + _ipAddressDao.unassignIpAddress(ip.getId()); + s_logger.debug("Removing placeholder nic " + nic); + _nicDao.remove(nic.getId()); + } + } + } } - } + }); } - }); - - return true; + return true; + }catch (Exception e) { + s_logger.error("trash. Exception:" + e.getMessage()); + throw new CloudRuntimeException("trash. Exception:" + e.getMessage(),e); + } } @Override diff --git a/server/src/com/cloud/network/guru/ExternalGuestNetworkGuru.java b/server/src/com/cloud/network/guru/ExternalGuestNetworkGuru.java index 13246a74a5..ddf1f9c3d8 100644 --- a/server/src/com/cloud/network/guru/ExternalGuestNetworkGuru.java +++ b/server/src/com/cloud/network/guru/ExternalGuestNetworkGuru.java @@ -127,6 +127,10 @@ public Network implement(Network config, NetworkOffering offering, DeployDestina throws InsufficientVirtualNetworkCapcityException { assert (config.getState() == State.Implementing) : "Why are we implementing " + config; + if (_networkModel.areServicesSupportedInNetwork(config.getId(), Network.Service.Connectivity)) { + return null; + } + if (!_networkModel.networkIsConfiguredForExternalNetworking(config.getDataCenterId(), config.getId())) { return super.implement(config, offering, dest, context); } diff --git a/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java b/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java index 9f280ef7a8..e29d8c39e7 100755 --- a/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java +++ b/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java @@ -30,6 +30,11 @@ import javax.ejb.Local; import javax.inject.Inject; +import org.apache.log4j.Logger; + +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; + import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.command.user.loadbalancer.CreateLBHealthCheckPolicyCmd; import org.apache.cloudstack.api.command.user.loadbalancer.CreateLBStickinessPolicyCmd; @@ -45,7 +50,6 @@ import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.cloudstack.lb.ApplicationLoadBalancerRuleVO; import org.apache.cloudstack.lb.dao.ApplicationLoadBalancerRuleDao; -import org.apache.log4j.Logger; import com.cloud.agent.api.to.LoadBalancerTO; import com.cloud.configuration.ConfigurationManager; @@ -163,9 +167,8 @@ import com.cloud.vm.UserVmVO; import com.cloud.vm.VirtualMachine.State; import com.cloud.vm.dao.NicDao; +import com.cloud.vm.dao.NicSecondaryIpDao; import com.cloud.vm.dao.UserVmDao; -import com.google.gson.Gson; -import com.google.gson.reflect.TypeToken; @Local(value = {LoadBalancingRulesManager.class, LoadBalancingRulesService.class}) public class LoadBalancingRulesManagerImpl extends ManagerBase implements LoadBalancingRulesManager, LoadBalancingRulesService { @@ -258,6 +261,9 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements @Inject LoadBalancerCertMapDao _lbCertMapDao; + @Inject + NicSecondaryIpDao _nicSecondaryIpDao; + // Will return a string. For LB Stickiness this will be a json, for // autoscale this will be "," separated values @Override @@ -551,6 +557,10 @@ public StickinessPolicy createLBStickinessPolicy(CreateLBStickinessPolicyCmd cmd /* Finally Insert into DB */ LBStickinessPolicyVO policy = new LBStickinessPolicyVO(loadBalancer.getId(), cmd.getLBStickinessPolicyName(), cmd.getStickinessMethodName(), cmd.getparamList(), cmd.getDescription()); + Boolean forDisplay = cmd.getDisplay(); + if (forDisplay != null) { + policy.setDisplay(forDisplay); + } policy = _lb2stickinesspoliciesDao.persist(policy); return policy; @@ -615,6 +625,11 @@ public HealthCheckPolicy createLBHealthCheckPolicy(CreateLBHealthCheckPolicyCmd new LBHealthCheckPolicyVO(loadBalancer.getId(), cmd.getPingPath(), cmd.getDescription(), cmd.getResponsTimeOut(), cmd.getHealthCheckInterval(), cmd.getHealthyThreshold(), cmd.getUnhealthyThreshold()); + Boolean forDisplay = cmd.getDisplay(); + if (forDisplay != null) { + policy.setDisplay(forDisplay); + } + policy = _lb2healthcheckDao.persist(policy); return policy; } @@ -882,7 +897,8 @@ public void updateLBHealthChecks(Scheme scheme) throws ResourceUnavailableExcept for (LoadBalancerVMMapVO lbVmMap : lbVmMaps) { UserVm vm = _vmDao.findById(lbVmMap.getInstanceId()); Nic nic = _nicDao.findByInstanceIdAndNetworkIdIncludingRemoved(ulb.getNetworkId(), vm.getId()); - String dstIp = nic.getIp4Address(); + String dstIp = lbVmMap.getInstanceIp() == null ? nic.getIp4Address(): lbVmMap.getInstanceIp(); + for (int i = 0; i < lbto.getDestinations().length; i++) { LoadBalancerTO.DestinationTO des = lbto.getDestinations()[i]; if (dstIp.equalsIgnoreCase(lbto.getDestinations()[i].getDestIp())) { @@ -923,7 +939,7 @@ private boolean isRollBackAllowedForProvider(LoadBalancerVO loadBalancer) { @Override @DB @ActionEvent(eventType = EventTypes.EVENT_ASSIGN_TO_LOAD_BALANCER_RULE, eventDescription = "assigning to load balancer", async = true) - public boolean assignToLoadBalancer(long loadBalancerId, List instanceIds) { + public boolean assignToLoadBalancer(long loadBalancerId, List instanceIds, Map> vmIdIpMap) { CallContext ctx = CallContext.current(); Account caller = ctx.getCallingAccount(); @@ -932,24 +948,53 @@ public boolean assignToLoadBalancer(long loadBalancerId, List instanceIds) throw new InvalidParameterValueException("Failed to assign to load balancer " + loadBalancerId + ", the load balancer was not found."); } + + if (instanceIds == null && vmIdIpMap.isEmpty()) { + throw new InvalidParameterValueException("Both instanceids and vmidipmap can't be null"); + } + + // instanceIds and vmIdipmap is passed + if (instanceIds != null && !vmIdIpMap.isEmpty()) { + for(long instanceId: instanceIds) { + if (!vmIdIpMap.containsKey(instanceId)) { + vmIdIpMap.put(instanceId, null); + } + } + } + + //only instanceids list passed + if (instanceIds != null && vmIdIpMap.isEmpty()){ + vmIdIpMap = new HashMap>(); + for (long instanceId: instanceIds){ + vmIdIpMap.put(instanceId, null); + } + } + List mappedInstances = _lb2VmMapDao.listByLoadBalancerId(loadBalancerId, false); Set mappedInstanceIds = new HashSet(); for (LoadBalancerVMMapVO mappedInstance : mappedInstances) { mappedInstanceIds.add(Long.valueOf(mappedInstance.getInstanceId())); } - final List vmsToAdd = new ArrayList(); + Map> existingVmIdIps = new HashMap>(); + // now get the ips of vm and add it to map + for (LoadBalancerVMMapVO mappedInstance : mappedInstances) { - if (instanceIds == null || instanceIds.isEmpty()) { - s_logger.warn("List of vms to assign to the lb, is empty"); - return false; + List ipsList = null; + if (existingVmIdIps.containsKey(mappedInstance.getInstanceId())) { + ipsList = existingVmIdIps.get(mappedInstance.getInstanceId()); + } else { + ipsList = new ArrayList(); + } + ipsList.add(mappedInstance.getInstanceIp()); + existingVmIdIps.put(mappedInstance.getInstanceId(), ipsList); } - for (Long instanceId : instanceIds) { - if (mappedInstanceIds.contains(instanceId)) { - throw new InvalidParameterValueException("VM " + instanceId + " is already mapped to load balancer."); - } + final List vmsToAdd = new ArrayList(); + // check for conflict + Set passedInstanceIds = vmIdIpMap.keySet(); + for (Long instanceId : passedInstanceIds) { UserVm vm = _vmDao.findById(instanceId); if (vm == null || vm.getState() == State.Destroyed || vm.getState() == State.Expunging) { InvalidParameterValueException ex = new InvalidParameterValueException("Invalid instance id specified"); @@ -985,18 +1030,75 @@ public boolean assignToLoadBalancer(long loadBalancerId, List instanceIds) throw ex; } + String priIp = nicInSameNetwork.getIp4Address(); + + if (existingVmIdIps.containsKey(instanceId)) { + // now check for ip address + List mappedIps = existingVmIdIps.get(instanceId); + List newIps = vmIdIpMap.get(instanceId); + + if (newIps == null) { + newIps = new ArrayList(); + newIps.add(priIp); + } + + for (String newIp: newIps) { + if (mappedIps.contains(newIp)) { + throw new InvalidParameterValueException("VM " + instanceId + " with " + newIp +" is already mapped to load balancer."); + } + } + } + + List vmIpsList = vmIdIpMap.get(instanceId); + String vmLbIp = null; + + if (vmIpsList != null) { + + //check if the ips belongs to nic secondary ip + for (String ip: vmIpsList) { + // skip the primary ip from vm secondary ip comparisions + if (ip.equals(priIp)) { + continue; + } + if(_nicSecondaryIpDao.findByIp4AddressAndNicId(ip,nicInSameNetwork.getId()) == null) { + throw new InvalidParameterValueException("VM ip "+ ip + " specified does not belong to " + + "nic in network " + nicInSameNetwork.getNetworkId()); + } + } + } else { + vmIpsList = new ArrayList(); + vmIpsList.add(priIp); + } + + // when vm id is passed in instance ids and in vmidipmap + // assign for primary ip and ip passed in vmidipmap + if (instanceIds != null ) { + if (instanceIds.contains(instanceId)) { + vmIpsList.add(priIp); + } + } + + vmIdIpMap.put(instanceId, vmIpsList); + if (s_logger.isDebugEnabled()) { s_logger.debug("Adding " + vm + " to the load balancer pool"); } vmsToAdd.add(vm); } + final Set vmIds = vmIdIpMap.keySet(); + final Map> newMap = vmIdIpMap; + Transaction.execute(new TransactionCallbackNoReturn() { @Override public void doInTransactionWithoutResult(TransactionStatus status) { - for (UserVm vm : vmsToAdd) { - LoadBalancerVMMapVO map = new LoadBalancerVMMapVO(loadBalancer.getId(), vm.getId(), false); - map = _lb2VmMapDao.persist(map); + + for (Long vmId : vmIds) { + final Set lbVmIps = new HashSet(newMap.get(vmId)); + for (String vmIp: lbVmIps) { + LoadBalancerVMMapVO map = new LoadBalancerVMMapVO(loadBalancer.getId(), vmId, vmIp, false); + map = _lb2VmMapDao.persist(map); + } } } }); @@ -1015,13 +1117,16 @@ public void doInTransactionWithoutResult(TransactionStatus status) { applyLoadBalancerConfig(loadBalancerId); success = true; } catch (ResourceUnavailableException e) { - if (isRollBackAllowedForProvider(loadBalancer)) { + s_logger.warn("Unable to apply the load balancer config because resource is unavaliable.", e); + success = false; + } finally { + if (!success) { final List vmInstanceIds = new ArrayList(); Transaction.execute(new TransactionCallbackNoReturn() { @Override public void doInTransactionWithoutResult(TransactionStatus status) { - for (UserVm vm : vmsToAdd) { - vmInstanceIds.add(vm.getId()); + for (Long vmId : vmIds) { + vmInstanceIds.add(vmId); } } }); @@ -1031,16 +1136,14 @@ public void doInTransactionWithoutResult(TransactionStatus status) { } loadBalancer.setState(backupState); _lbDao.persist(loadBalancer); + CloudRuntimeException ex = new CloudRuntimeException("Failed to add specified loadbalancerruleid for vms " + + instanceIds); + ex.addProxyObject(loadBalancer.getUuid(), "loadBalancerId"); + // TBD: Also pack in the instanceIds in the exception using the + // right VO object or table name. + throw ex; } - s_logger.warn("Unable to apply the load balancer config because resource is unavaliable.", e); - } - if (!success) { - CloudRuntimeException ex = new CloudRuntimeException("Failed to add specified loadbalancerruleid for vms " + instanceIds); - ex.addProxyObject(loadBalancer.getUuid(), "loadBalancerId"); - // TBD: Also pack in the instanceIds in the exception using the - // right VO object or table name. - throw ex; } return success; @@ -1056,8 +1159,8 @@ public boolean assignSSLCertToLoadBalancerRule(Long lbId, String certName, Strin @Override @ActionEvent(eventType = EventTypes.EVENT_REMOVE_FROM_LOAD_BALANCER_RULE, eventDescription = "removing from load balancer", async = true) - public boolean removeFromLoadBalancer(long loadBalancerId, List instanceIds) { - return removeFromLoadBalancerInternal(loadBalancerId, instanceIds, true); + public boolean removeFromLoadBalancer(long loadBalancerId, List instanceIds, Map> vmIdIpsMap) { + return removeFromLoadBalancerInternal(loadBalancerId, instanceIds, true, vmIdIpsMap); } @Override @@ -1191,7 +1294,7 @@ public boolean removeCertFromLoadBalancer(long lbRuleId) { return success; } - private boolean removeFromLoadBalancerInternal(long loadBalancerId, List instanceIds, boolean rollBack) { + private boolean removeFromLoadBalancerInternal(long loadBalancerId, List instanceIds, boolean rollBack, Map> vmIdIpMap) { CallContext caller = CallContext.current(); LoadBalancerVO loadBalancer = _lbDao.findById(Long.valueOf(loadBalancerId)); @@ -1201,17 +1304,65 @@ private boolean removeFromLoadBalancerInternal(long loadBalancerId, List i _accountMgr.checkAccess(caller.getCallingAccount(), null, true, loadBalancer); + if (instanceIds == null && vmIdIpMap.isEmpty()) { + throw new InvalidParameterValueException("Both instanceids and vmidipmap can't be null"); + } + + // instanceIds and vmIdipmap is passed + if (instanceIds != null && !vmIdIpMap.isEmpty()) { + for(long instanceId: instanceIds) { + if (!vmIdIpMap.containsKey(instanceId)) { + vmIdIpMap.put(instanceId, null); + } + } + } + + //only instanceids list passed + if (instanceIds != null && vmIdIpMap.isEmpty()){ + vmIdIpMap = new HashMap>(); + for (long instanceId: instanceIds){ + vmIdIpMap.put(instanceId, null); + } + } + boolean success = false; FirewallRule.State backupState = loadBalancer.getState(); + Set vmIds = vmIdIpMap.keySet(); try { loadBalancer.setState(FirewallRule.State.Add); _lbDao.persist(loadBalancer); - for (long instanceId : instanceIds) { - LoadBalancerVMMapVO map = _lb2VmMapDao.findByLoadBalancerIdAndVmId(loadBalancerId, instanceId); - map.setRevoke(true); - _lb2VmMapDao.persist(map); - s_logger.debug("Set load balancer rule for revoke: rule id " + loadBalancerId + ", vmId " + instanceId); + for (long instanceId : vmIds) { + List lbVmIps = vmIdIpMap.get(instanceId); + + if (lbVmIps == null || lbVmIps.isEmpty()) { + List lbVms = _lb2VmMapDao.listByLoadBalancerIdAndVmId(loadBalancerId, instanceId); + if (lbVms == null) { + throw new InvalidParameterValueException("The instance id: "+ instanceId +" is not configured " + + " for LB rule id " + loadBalancerId); + } + + for (LoadBalancerVMMapVO lbvm: lbVms) { + lbvm.setRevoke(true); + _lb2VmMapDao.persist(lbvm); + } + s_logger.debug("Set load balancer rule for revoke: rule id " + loadBalancerId + ", vmId " + instanceId); + + } else { + for (String vmIp: lbVmIps) { + LoadBalancerVMMapVO map = _lb2VmMapDao.findByLoadBalancerIdAndVmIdVmIp (loadBalancerId, instanceId, vmIp); + if (map == null) { + throw new InvalidParameterValueException("The instance id: "+ instanceId +" is not configured " + + " for LB rule id " + loadBalancerId); + } + map.setRevoke(true); + _lb2VmMapDao.persist(map); + s_logger.debug("Set load balancer rule for revoke: rule id " + loadBalancerId + ", vmId " + + instanceId + ", vmip " + vmIp); + + } + + } } if (_autoScaleVmGroupDao.isAutoScaleLoadBalancer(loadBalancerId)) { @@ -1233,11 +1384,23 @@ private boolean removeFromLoadBalancerInternal(long loadBalancerId, List i } catch (ResourceUnavailableException e) { if (rollBack && isRollBackAllowedForProvider(loadBalancer)) { - for (long instanceId : instanceIds) { - LoadBalancerVMMapVO map = _lb2VmMapDao.findByLoadBalancerIdAndVmId(loadBalancerId, instanceId); - map.setRevoke(false); - _lb2VmMapDao.persist(map); - s_logger.debug("LB Rollback rule id: " + loadBalancerId + ",while removing vmId " + instanceId); + for (long instanceId : vmIds) { + List lbVmIps = vmIdIpMap.get(instanceId); + + if (lbVmIps == null || lbVmIps.isEmpty()) { + LoadBalancerVMMapVO map = _lb2VmMapDao.findByLoadBalancerIdAndVmId(loadBalancerId, instanceId); + map.setRevoke(false); + _lb2VmMapDao.persist(map); + s_logger.debug("LB Rollback rule id: " + loadBalancerId + ",while removing vmId " + instanceId); + }else { + for (String vmIp: lbVmIps) { + LoadBalancerVMMapVO map = _lb2VmMapDao.findByLoadBalancerIdAndVmIdVmIp (loadBalancerId, instanceId, vmIp); + map.setRevoke(true); + _lb2VmMapDao.persist(map); + s_logger.debug("LB Rollback rule id: " + loadBalancerId + ",while removing vmId " + + instanceId + ", vmip " + vmIp); + } + } } loadBalancer.setState(backupState); @@ -1247,7 +1410,7 @@ private boolean removeFromLoadBalancerInternal(long loadBalancerId, List i s_logger.warn("Unable to apply the load balancer config because resource is unavaliable.", e); } if (!success) { - CloudRuntimeException ex = new CloudRuntimeException("Failed to remove specified load balancer rule id for vms " + instanceIds); + CloudRuntimeException ex = new CloudRuntimeException("Failed to remove specified load balancer rule id for vms " + vmIds); ex.addProxyObject(loadBalancer.getUuid(), "loadBalancerId"); throw ex; } @@ -1282,7 +1445,7 @@ public boolean removeVmFromLoadBalancers(long instanceId) { // Reapply all lbs that had the vm assigned if (lbsToReconfigure != null) { for (Map.Entry> lb : lbsToReconfigure.entrySet()) { - if (!removeFromLoadBalancerInternal(lb.getKey(), lb.getValue(), false)) { + if (!removeFromLoadBalancerInternal(lb.getKey(), lb.getValue(), false, new HashMap>())) { success = false; } } @@ -1340,7 +1503,7 @@ public List doInTransaction(TransactionStatus status) { } } - List hcPolicies = _lb2healthcheckDao.listByLoadBalancerId(loadBalancerId); + List hcPolicies = _lb2healthcheckDao.listByLoadBalancerIdAndDisplayFlag(loadBalancerId, null); for (LBHealthCheckPolicyVO lbHealthCheck : hcPolicies) { lbHealthCheck.setRevoke(true); _lb2healthcheckDao.persist(lbHealthCheck); @@ -1727,12 +1890,11 @@ public Boolean doInTransaction(TransactionStatus status) { for (LoadBalancerVMMapVO lbVmMap : lbVmMaps) { instanceIds.add(lbVmMap.getInstanceId()); + _lb2VmMapDao.remove(lb.getId(), lbVmMap.getInstanceId(), lbVmMap.getInstanceIp(), null); + s_logger.debug("Load balancer rule id " + lb.getId() + " is removed for vm " + + lbVmMap.getInstanceId() + " instance ip " + lbVmMap.getInstanceIp()); } - if (!instanceIds.isEmpty()) { - _lb2VmMapDao.remove(lb.getId(), instanceIds, null); - s_logger.debug("Load balancer rule id " + lb.getId() + " is removed for vms " + instanceIds); - } if (_lb2VmMapDao.listByLoadBalancerId(lb.getId()).isEmpty()) { lb.setState(FirewallRule.State.Add); @@ -1853,7 +2015,7 @@ public List getStickinessPolicies(long lbId) { @Override public List getHealthCheckPolicies(long lbId) { List healthCheckPolicies = new ArrayList(); - List hcDbpolicies = _lb2healthcheckDao.listByLoadBalancerId(lbId); + List hcDbpolicies = _lb2healthcheckDao.listByLoadBalancerIdAndDisplayFlag(lbId, null); for (LBHealthCheckPolicyVO policy : hcDbpolicies) { String pingpath = policy.getpingpath(); @@ -1875,7 +2037,7 @@ public List getExistingDestinations(long lbId) { for (LoadBalancerVMMapVO lbVmMap : lbVmMaps) { UserVm vm = _vmDao.findById(lbVmMap.getInstanceId()); Nic nic = _nicDao.findByInstanceIdAndNetworkIdIncludingRemoved(lb.getNetworkId(), vm.getId()); - dstIp = nic.getIp4Address(); + dstIp = lbVmMap.getInstanceIp() == null ? nic.getIp4Address(): lbVmMap.getInstanceIp(); LbDestination lbDst = new LbDestination(lb.getDefaultPortStart(), lb.getDefaultPortEnd(), dstIp, lbVmMap.isRevoke()); dstList.add(lbDst); } @@ -2022,6 +2184,18 @@ public Pair, List> listLoadBalancerInstances(List return new Pair, List>(loadBalancerInstances, serviceStates); } + @Override + public List listLbVmIpAddress (long id, long vmId) { + + List listLbvmMapVo = _lb2VmMapDao.listByLoadBalancerIdAndVmId(id, vmId); + + List vmIps = new ArrayList(); + for (LoadBalancerVMMapVO lbVmVo : listLbvmMapVo) { + vmIps.add(lbVmVo.getInstanceIp()); + } + return vmIps; + } + @Override public List getStickinessMethods(long networkid) { String capability = getLBCapability(networkid, Capability.SupportedStickinessMethods.getName()); @@ -2039,14 +2213,24 @@ public List getStickinessMethods(long networkid) { public List searchForLBStickinessPolicies(ListLBStickinessPoliciesCmd cmd) throws PermissionDeniedException { Account caller = CallContext.current().getCallingAccount(); Long loadBalancerId = cmd.getLbRuleId(); - LoadBalancerVO loadBalancer = _lbDao.findById(loadBalancerId); + Long stickinessId = cmd.getId(); + + boolean forDisplay = cmd.getDisplay(); + LoadBalancerVO loadBalancer = null; + + if (loadBalancerId == null) { + loadBalancer = findLbByStickinessId(stickinessId); + } else { + loadBalancer = _lbDao.findById(loadBalancerId); + } + if (loadBalancer == null) { return null; } _accountMgr.checkAccess(caller, null, true, loadBalancer); - List sDbpolicies = _lb2stickinesspoliciesDao.listByLoadBalancerId(cmd.getLbRuleId()); + List sDbpolicies = _lb2stickinesspoliciesDao.listByLoadBalancerIdAndDisplayFlag(loadBalancer.getId(), forDisplay); return sDbpolicies; } @@ -2055,12 +2239,19 @@ public List searchForLBStickinessPolicies(ListLBStickiness public List searchForLBHealthCheckPolicies(ListLBHealthCheckPoliciesCmd cmd) throws PermissionDeniedException { Account caller = CallContext.current().getCallingAccount(); Long loadBalancerId = cmd.getLbRuleId(); + Long policyId = cmd.getId(); + boolean forDisplay = cmd.getDisplay(); + if(loadBalancerId == null) { + loadBalancerId = findLBIdByHealtCheckPolicyId(policyId); + } LoadBalancerVO loadBalancer = _lbDao.findById(loadBalancerId); if (loadBalancer == null) { return null; } + _accountMgr.checkAccess(caller, null, true, loadBalancer); - List hcDbpolicies = _lb2healthcheckDao.listByLoadBalancerId(cmd.getLbRuleId()); + List hcDbpolicies = _lb2healthcheckDao.listByLoadBalancerIdAndDisplayFlag(loadBalancerId, forDisplay); + return hcDbpolicies; } @@ -2074,29 +2265,29 @@ public Pair, Integer> searchForLoadBalancers(ListLo Long instanceId = cmd.getVirtualMachineId(); Long networkId = cmd.getNetworkId(); Map tags = cmd.getTags(); + Boolean forDisplay = cmd.getDisplay(); Account caller = CallContext.current().getCallingAccount(); - List permittedDomains = new ArrayList(); List permittedAccounts = new ArrayList(); - List permittedResources = new ArrayList(); Ternary domainIdRecursiveListProject = new Ternary( cmd.getDomainId(), cmd.isRecursive(), null); - _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedDomains, permittedAccounts, permittedResources, - domainIdRecursiveListProject, cmd.listAll(), false, "listLoadBalancerRules"); - //Long domainId = domainIdRecursiveListProject.first(); + _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, + domainIdRecursiveListProject, cmd.listAll(), false); + Long domainId = domainIdRecursiveListProject.first(); Boolean isRecursive = domainIdRecursiveListProject.second(); ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third(); Filter searchFilter = new Filter(LoadBalancerVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal()); SearchBuilder sb = _lbDao.createSearchBuilder(); - _accountMgr.buildACLSearchBuilder(sb, isRecursive, permittedDomains, permittedAccounts, permittedResources, listProjectResourcesCriteria); + _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); sb.and("name", sb.entity().getName(), SearchCriteria.Op.LIKE); sb.and("sourceIpAddress", sb.entity().getSourceIpAddressId(), SearchCriteria.Op.EQ); sb.and("networkId", sb.entity().getNetworkId(), SearchCriteria.Op.EQ); sb.and("scheme", sb.entity().getScheme(), SearchCriteria.Op.EQ); + sb.and("display", sb.entity().isDisplay(), SearchCriteria.Op.EQ); if (instanceId != null) { SearchBuilder lbVMSearch = _lb2VmMapDao.createSearchBuilder(); @@ -2123,7 +2314,7 @@ public Pair, Integer> searchForLoadBalancers(ListLo } SearchCriteria sc = sb.create(); - _accountMgr.buildACLSearchCriteria(sc, isRecursive, permittedDomains, permittedAccounts, permittedResources, listProjectResourcesCriteria); + _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); if (keyword != null) { SearchCriteria ssc = _lbDao.createSearchCriteria(); @@ -2166,6 +2357,10 @@ public Pair, Integer> searchForLoadBalancers(ListLo } } + if (forDisplay != null) { + sc.setParameters("display", forDisplay); + } + //list only Public load balancers using this command sc.setParameters("scheme", Scheme.Public); @@ -2178,6 +2373,16 @@ public LoadBalancerVO findById(long lbId) { return _lbDao.findById(lbId); } + @Override + public LoadBalancerVO findLbByStickinessId(long stickinessPolicyId) { + LBStickinessPolicyVO stickinessPolicy = _lb2stickinesspoliciesDao.findById(stickinessPolicyId); + + if (stickinessPolicy == null) { + return null; + } + return _lbDao.findById(stickinessPolicy.getLoadBalancerId()); + } + @Override public void removeLBRule(LoadBalancer rule) { // remove the rule @@ -2241,6 +2446,15 @@ public Map getLbInstances(long lbId) { return dstList; } + @Override + public boolean isLbRuleMappedToVmGuestIp(String vmSecondaryIp) { + List lbVmMap = _lb2VmMapDao.listByInstanceIp(vmSecondaryIp); + if (lbVmMap == null || lbVmMap.isEmpty()) { + return false; + } + return true; + } + @Override public void isLbServiceSupportedInNetwork(long networkId, Scheme scheme) { Network network = _networkDao.findById(networkId); @@ -2280,4 +2494,67 @@ public void setLbProviders(List lbProviders) { this._lbProviders = lbProviders; } + @Override + @ActionEvent(eventType = EventTypes.EVENT_LB_STICKINESSPOLICY_UPDATE, eventDescription = "updating lb stickiness policy", async = true) + public StickinessPolicy updateLBStickinessPolicy(long id, String customId, Boolean forDisplay) { + LBStickinessPolicyVO policy = _lb2stickinesspoliciesDao.findById(id); + if (policy == null) { + throw new InvalidParameterValueException("Fail to find stickiness policy with " + id); + } + + LoadBalancerVO loadBalancer = _lbDao.findById(Long.valueOf(policy.getLoadBalancerId())); + if (loadBalancer == null) { + throw new InvalidParameterException("Invalid Load balancer : " + policy.getLoadBalancerId() + " for Stickiness policy id: " + id); + } + + _accountMgr.checkAccess(CallContext.current().getCallingAccount(), null, true, loadBalancer); + + if (customId != null) { + policy.setUuid(customId); + } + + if (forDisplay != null) { + policy.setDisplay(forDisplay); + } + + _lb2stickinesspoliciesDao.update(id, policy); + return _lb2stickinesspoliciesDao.findById(id); + } + + @Override + @ActionEvent(eventType = EventTypes.EVENT_LB_HEALTHCHECKPOLICY_UPDATE, eventDescription = "updating lb healthcheck policy", async = true) + public HealthCheckPolicy updateLBHealthCheckPolicy(long id, String customId, Boolean forDisplay) { + LBHealthCheckPolicyVO policy = _lb2healthcheckDao.findById(id); + if (policy == null) { + throw new InvalidParameterValueException("Fail to find stickiness policy with " + id); + } + + LoadBalancerVO loadBalancer = _lbDao.findById(Long.valueOf(policy.getLoadBalancerId())); + if (loadBalancer == null) { + throw new InvalidParameterException("Invalid Load balancer : " + policy.getLoadBalancerId() + " for Stickiness policy id: " + id); + } + + _accountMgr.checkAccess(CallContext.current().getCallingAccount(), null, true, loadBalancer); + + if (customId != null) { + policy.setUuid(customId); + } + + if (forDisplay != null) { + policy.setDisplay(forDisplay); + } + + _lb2healthcheckDao.update(id, policy); + return _lb2healthcheckDao.findById(id); + } + + @Override + public Long findLBIdByHealtCheckPolicyId(long lbHealthCheckPolicy) { + LBHealthCheckPolicyVO policy= _lb2healthcheckDao.findById(lbHealthCheckPolicy); + if(policy != null) { + return policy.getLoadBalancerId(); + } + return null; + } + } diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java index e3597acc31..ae418d239c 100644 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java @@ -51,6 +51,7 @@ public interface VirtualNetworkApplianceManager extends Manager, VirtualNetworkA static final String RouterTemplateHyperVCK = "router.template.hyperv"; static final String RouterTemplateLxcCK = "router.template.lxc"; static final String SetServiceMonitorCK = "network.router.EnableServiceMonitoring"; + static final String RouterAlertsCheckIntervalCK = "router.alerts.check.interval"; static final ConfigKey RouterTemplateXen = new ConfigKey(String.class, RouterTemplateXenCK, "Advanced", "SystemVM Template (XenServer)", "Name of the default router template on Xenserver.", true, ConfigKey.Scope.Zone, null); @@ -66,6 +67,9 @@ public interface VirtualNetworkApplianceManager extends Manager, VirtualNetworkA static final ConfigKey SetServiceMonitor = new ConfigKey(String.class, SetServiceMonitorCK, "Advanced", "true", "service monitoring in router enable/disable option, default true", true, ConfigKey.Scope.Zone, null); + static final ConfigKey RouterAlertsCheckInterval = new ConfigKey(Integer.class, RouterAlertsCheckIntervalCK, "Advanced", "1800", + "Interval (in seconds) to check for alerts in Virtual Router.", false, ConfigKey.Scope.Global, null); + public static final int DEFAULT_ROUTER_VM_RAMSIZE = 128; // 128M public static final int DEFAULT_ROUTER_CPU_MHZ = 500; // 500 MHz public static final boolean USE_POD_VLAN = false; diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java index c692491a34..2363841d36 100755 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -17,6 +17,8 @@ package com.cloud.network.router; +import java.text.ParseException; +import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; @@ -41,10 +43,15 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; + import org.apache.log4j.Logger; + +import org.apache.cloudstack.alert.AlertService; +import org.apache.cloudstack.alert.AlertService.AlertType; import org.apache.cloudstack.api.command.admin.router.RebootRouterCmd; import org.apache.cloudstack.api.command.admin.router.UpgradeRouterCmd; import org.apache.cloudstack.api.command.admin.router.UpgradeRouterTemplateCmd; +import org.apache.cloudstack.config.ApiServiceConfiguration; import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; import org.apache.cloudstack.framework.config.ConfigDepot; @@ -55,7 +62,7 @@ import org.apache.cloudstack.framework.jobs.impl.AsyncJobVO; import org.apache.cloudstack.managed.context.ManagedContextRunnable; import org.apache.cloudstack.utils.identity.ManagementServerNode; -import org.apache.cloudstack.alert.AlertService.AlertType; + import com.cloud.agent.AgentManager; import com.cloud.agent.Listener; import com.cloud.agent.api.AgentControlAnswer; @@ -69,14 +76,12 @@ import com.cloud.agent.api.Command; import com.cloud.agent.api.GetDomRVersionAnswer; import com.cloud.agent.api.GetDomRVersionCmd; +import com.cloud.agent.api.GetRouterAlertsAnswer; import com.cloud.agent.api.ModifySshKeysCommand; import com.cloud.agent.api.NetworkUsageAnswer; import com.cloud.agent.api.NetworkUsageCommand; import com.cloud.agent.api.PvlanSetupCommand; import com.cloud.agent.api.StartupCommand; -import com.cloud.agent.api.routing.GetRouterAlertsCommand; -import com.cloud.agent.api.GetRouterAlertsAnswer; -import com.cloud.agent.api.check.CheckSshAnswer; import com.cloud.agent.api.check.CheckSshCommand; import com.cloud.agent.api.routing.AggregationControlCommand; import com.cloud.agent.api.routing.AggregationControlCommand.Action; @@ -84,6 +89,7 @@ import com.cloud.agent.api.routing.DeleteIpAliasCommand; import com.cloud.agent.api.routing.DhcpEntryCommand; import com.cloud.agent.api.routing.DnsMasqConfigCommand; +import com.cloud.agent.api.routing.GetRouterAlertsCommand; import com.cloud.agent.api.routing.IpAliasTO; import com.cloud.agent.api.routing.IpAssocCommand; import com.cloud.agent.api.routing.LoadBalancerConfigCommand; @@ -183,6 +189,7 @@ import com.cloud.network.dao.NetworkDao; import com.cloud.network.dao.NetworkVO; import com.cloud.network.dao.OpRouterMonitorServiceDao; +import com.cloud.network.dao.OpRouterMonitorServiceVO; import com.cloud.network.dao.PhysicalNetworkServiceProviderDao; import com.cloud.network.dao.RemoteAccessVpnDao; import com.cloud.network.dao.Site2SiteCustomerGatewayDao; @@ -192,7 +199,6 @@ import com.cloud.network.dao.UserIpv6AddressDao; import com.cloud.network.dao.VirtualRouterProviderDao; import com.cloud.network.dao.VpnUserDao; -import com.cloud.network.dao.OpRouterMonitorServiceVO; import com.cloud.network.lb.LoadBalancingRule; import com.cloud.network.lb.LoadBalancingRule.LbDestination; import com.cloud.network.lb.LoadBalancingRule.LbHealthCheckPolicy; @@ -281,7 +287,6 @@ import com.cloud.vm.dao.UserVmDao; import com.cloud.vm.dao.UserVmDetailsDao; import com.cloud.vm.dao.VMInstanceDao; -import org.apache.cloudstack.config.ApiServiceConfiguration; /** * VirtualNetworkApplianceManagerImpl manages the different types of virtual network appliances available in the Cloud Stack. @@ -604,7 +609,7 @@ public VirtualRouter stopRouter(final long routerId, final boolean forced) throw if (router.isStopPending()) { s_logger.info("Clear the stop pending flag of router " + router.getHostName() + " after stop router successfully"); router.setStopPending(false); - router = _routerDao.persist(router); + _routerDao.persist(router); virtualRouter.setStopPending(false); } return virtualRouter; @@ -653,7 +658,7 @@ public VirtualRouter rebootRouter(final long routerId, final boolean reprogramNe _accountMgr.checkAccess(caller, null, true, router); // Can reboot domain router only in Running state - if (router == null || router.getState() != State.Running) { + if (router.getState() != State.Running) { s_logger.warn("Unable to reboot, virtual router is not in the right state " + router.getState()); throw new ResourceUnavailableException("Unable to reboot domR, it is not in right state " + router.getState(), DataCenter.class, router.getDataCenterId()); } @@ -821,6 +826,13 @@ public boolean start() { s_logger.debug("router.check.interval - " + _routerCheckInterval + " so not scheduling the redundant router checking thread"); } + int _routerAlertsCheckInterval = RouterAlertsCheckInterval.value(); + if (_routerAlertsCheckInterval > 0) { + _checkExecutor.scheduleAtFixedRate(new CheckRouterAlertsTask(), _routerAlertsCheckInterval, _routerAlertsCheckInterval, TimeUnit.SECONDS); + } else { + s_logger.debug("router.alerts.check.interval - " + _routerAlertsCheckInterval + " so not scheduling the router alerts checking thread"); + } + return true; } @@ -1101,7 +1113,7 @@ protected void updateSite2SiteVpnConnectionState(final List rout for (final Site2SiteVpnConnectionVO conn : conns) { final Site2SiteVpnConnectionVO lock = _s2sVpnConnectionDao.acquireInLockTable(conn.getId()); if (lock == null) { - throw new CloudRuntimeException("Unable to acquire lock on " + lock); + throw new CloudRuntimeException("updateSite2SiteVpnConnectionState: Unable to acquire lock"); } try { if (conn.getState() != Site2SiteVpnConnection.State.Connected && conn.getState() != Site2SiteVpnConnection.State.Disconnected) { @@ -1355,8 +1367,6 @@ protected void runInContext() { updateSite2SiteVpnConnectionState(routers); - getRouterAlerts(); - final List networks = _networkDao.listRedundantNetworks(); s_logger.debug("Found " + networks.size() + " networks to update RvR status. "); for (final NetworkVO network : networks) { @@ -1371,20 +1381,33 @@ protected void runInContext() { } } - private void getRouterAlerts() { + protected class CheckRouterAlertsTask extends ManagedContextRunnable { + public CheckRouterAlertsTask() { + } + + @Override + protected void runInContext() { + try { + getRouterAlerts(); + } catch (final Exception ex) { + s_logger.error("Fail to complete the CheckRouterAlertsTask! ", ex); + } + } + } + + protected void getRouterAlerts() { try{ - List routersInIsolatedNetwork = _routerDao.listByStateAndNetworkType(State.Running, GuestType.Isolated, mgmtSrvrId); - List routersInSharedNetwork = _routerDao.listByStateAndNetworkType(State.Running, GuestType.Shared, mgmtSrvrId); + List routers = _routerDao.listByStateAndManagementServer(State.Running, mgmtSrvrId); - List routers = new ArrayList(); - routers.addAll(routersInIsolatedNetwork); - routers.addAll(routersInSharedNetwork); s_logger.debug("Found " + routers.size() + " running routers. "); for (final DomainRouterVO router : routers) { - if (router.getVpcId() != null) { + String serviceMonitoringFlag = SetServiceMonitor.valueIn(router.getDataCenterId()); + // Skip the routers in VPC network or skip the routers where Monitor service is not enabled in the corresponding Zone + if ( !Boolean.parseBoolean(serviceMonitoringFlag) || router.getVpcId() != null) { continue; } + String privateIP = router.getPrivateIpAddress(); if (privateIP != null) { @@ -1392,23 +1415,50 @@ private void getRouterAlerts() { GetRouterAlertsCommand command = null; if (opRouterMonitorServiceVO == null) { - command = new GetRouterAlertsCommand(null); + String date_str = "1970-01-01 00:00:00"; + command = new GetRouterAlertsCommand(date_str); // To avoid sending null value } else { command = new GetRouterAlertsCommand(opRouterMonitorServiceVO.getLastAlertTimestamp()); } command.setAccessDetail(NetworkElementCommand.ROUTER_IP, router.getPrivateIpAddress()); - command.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); - GetRouterAlertsAnswer answer = null; try { - answer = (GetRouterAlertsAnswer) _agentMgr.easySend(router.getHostId(), command); + final Answer origAnswer = _agentMgr.easySend(router.getHostId(), command); + GetRouterAlertsAnswer answer = null; + + if (origAnswer == null) { + s_logger.warn("Unable to get alerts from router " + router.getHostName()); + continue; + } + if (origAnswer instanceof GetRouterAlertsAnswer) { + answer = (GetRouterAlertsAnswer)origAnswer; + } else { + s_logger.warn("Unable to get alerts from router " + router.getHostName()); + continue; + } + if (!answer.getResult()) { + s_logger.warn("Unable to get alerts from router " + router.getHostName() + " " + answer.getDetails()); + continue; + } + String alerts[] = answer.getAlerts(); - if (alerts != null ) { + if (alerts != null) { + String lastAlertTimeStamp = answer.getTimeStamp(); + SimpleDateFormat sdfrmt = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); + sdfrmt.setLenient(false); + try + { + sdfrmt.parse(lastAlertTimeStamp); + } + catch (ParseException e) + { + s_logger.warn("Invalid last alert timestamp received while collecting alerts from router: " + router.getInstanceName()); + continue; + } for (String alert: alerts) { _alertMgr.sendAlert(AlertType.ALERT_TYPE_DOMAIN_ROUTER, router.getDataCenterId(), router.getPodIdToDeployIn(), "Monitoring Service on VR " + router.getInstanceName(), alert); } - String lastAlertTimeStamp = answer.getTimeStamp(); if (opRouterMonitorServiceVO == null) { opRouterMonitorServiceVO = new OpRouterMonitorServiceVO(router.getId(), router.getHostName(), lastAlertTimeStamp); _opRouterMonitorServiceDao.persist(opRouterMonitorServiceVO); @@ -1418,7 +1468,7 @@ private void getRouterAlerts() { } } } catch (Exception e) { - s_logger.warn("Error while collecting alerts from router: " + router.getInstanceName() + " from host: " + router.getHostId(), e); + s_logger.warn("Error while collecting alerts from router: " + router.getInstanceName(), e); continue; } } @@ -1428,7 +1478,6 @@ private void getRouterAlerts() { } } - private final static int DEFAULT_PRIORITY = 100; private final static int DEFAULT_DELTA = 2; @@ -2291,6 +2340,9 @@ protected StringBuilder createGuestBootLoadArgs(final NicProfile guestNic, final buf.append(" guestbrd=").append(brd); buf.append(" guestcidrsize=").append(NetUtils.getCidrSize(guestNic.getNetmask())); buf.append(" router_pr=").append(router.getPriority()); + + int advertInt = NumbersUtil.parseInt(_configDao.getValue(Config.RedundantRouterVrrpInterval.key()), 1); + buf.append(" advert_int=").append(advertInt); } //setup network domain @@ -2299,10 +2351,12 @@ protected StringBuilder createGuestBootLoadArgs(final NicProfile guestNic, final buf.append(" domain=" + domain); } + long cidrSize = 0; + //setup dhcp range if (dc.getNetworkType() == NetworkType.Basic) { if (guestNic.isDefaultNic()) { - final long cidrSize = NetUtils.getCidrSize(guestNic.getNetmask()); + cidrSize = NetUtils.getCidrSize(guestNic.getNetmask()); final String cidr = NetUtils.getCidrSubNet(guestNic.getGateway(), cidrSize); if (cidr != null) { dhcpRange = NetUtils.getIpRangeStartIpFromCidr(cidr, cidrSize); @@ -2311,11 +2365,14 @@ protected StringBuilder createGuestBootLoadArgs(final NicProfile guestNic, final } else if (dc.getNetworkType() == NetworkType.Advanced) { final String cidr = guestNetwork.getCidr(); if (cidr != null) { + cidrSize = NetUtils.getCidrSize(NetUtils.getCidrNetmask(cidr)); dhcpRange = NetUtils.getDhcpRange(cidr); } } if (dhcpRange != null) { + // To limit DNS to the cidr range + buf.append(" cidrsize=" + String.valueOf(cidrSize)); buf.append(" dhcprange=" + dhcpRange); } @@ -2429,6 +2486,19 @@ public boolean finalizeCommandsOnStart(final Commands cmds, final VirtualMachine if (reprogramGuestNtwks) { finalizeIpAssocForNetwork(cmds, router, provider, guestNetworkId, null); finalizeNetworkRulesForNetwork(cmds, router, provider, guestNetworkId); + + NetworkOffering offering = _networkOfferingDao.findById((_networkDao.findById(guestNetworkId)).getNetworkOfferingId()); + //service monitoring is currently not added in RVR + if (!offering.getRedundantRouter()) { + String serviceMonitringSet = _configDao.getValue(Config.EnableServiceMonitoring.key()); + + if (serviceMonitringSet != null && serviceMonitringSet.equalsIgnoreCase("true")) { + finalizeMonitorServiceOnStrat(cmds, profile, router, provider, guestNetworkId, true); + } else { + finalizeMonitorServiceOnStrat(cmds, profile, router, provider, guestNetworkId, false); + } + } + } finalizeUserDataAndDhcpOnStart(cmds, router, provider, guestNetworkId); @@ -2439,15 +2509,6 @@ public boolean finalizeCommandsOnStart(final Commands cmds, final VirtualMachine } - String serviceMonitringSet = SetServiceMonitor.valueIn(router.getDataCenterId()); - //String serviceMonitringSet = _configDao.getValue(Config.EnableServiceMonitoring.key()); - - if (serviceMonitringSet != null && serviceMonitringSet.equalsIgnoreCase("true")) { - finalizeMonitorServiceOnStrat(cmds, profile, router, provider, routerGuestNtwkIds.get(0), true); - } else { - finalizeMonitorServiceOnStrat(cmds, profile, router, provider, routerGuestNtwkIds.get(0), false); - } - return true; } @@ -2751,22 +2812,23 @@ protected ArrayList getPublicIpsToApply(final Virtual public boolean finalizeStart(final VirtualMachineProfile profile, final long hostId, final Commands cmds, final ReservationContext context) { DomainRouterVO router = _routerDao.findById(profile.getId()); - boolean result = true; - - Answer answer = cmds.getAnswer("checkSsh"); - if (answer != null && answer instanceof CheckSshAnswer) { - final CheckSshAnswer sshAnswer = (CheckSshAnswer)answer; - if (sshAnswer == null || !sshAnswer.getResult()) { - s_logger.warn("Unable to ssh to the VM: " + sshAnswer.getDetails()); - result = false; + //process all the answers + for (Answer answer : cmds.getAnswers()) { + // handle any command failures + if (!answer.getResult()) { + String cmdClassName = answer.getClass().getCanonicalName().replace("Answer", "Command"); + String errorMessage = "Command: " + cmdClassName + " failed while starting virtual router"; + String errorDetails = "Details: " + answer.getDetails() + " " + answer.toString(); + //add alerts for the failed commands + _alertMgr.sendAlert(AlertService.AlertType.ALERT_TYPE_DOMAIN_ROUTER, router.getDataCenterId(), router.getPodIdToDeployIn(), errorMessage, errorDetails); + s_logger.warn(errorMessage); + //Stop the router if any of the commands failed + return false; } - } else { - result = false; - } - if (result == false) { - return result; } + // at this point, all the router command are successful. + boolean result = true; //Get guest networks info final List guestNetworks = new ArrayList(); @@ -2781,24 +2843,11 @@ public boolean finalizeStart(final VirtualMachineProfile profile, final long hos } } } - - if (!result) { - return result; - } - - answer = cmds.getAnswer("getDomRVersion"); - if (answer != null && answer instanceof GetDomRVersionAnswer) { - final GetDomRVersionAnswer versionAnswer = (GetDomRVersionAnswer)answer; - if (answer == null || !answer.getResult()) { - s_logger.warn("Unable to get the template/scripts version of router " + router.getInstanceName() + " due to: " + versionAnswer.getDetails()); - result = false; - } else { - router.setTemplateVersion(versionAnswer.getTemplateVersion()); - router.setScriptsVersion(versionAnswer.getScriptsVersion()); - router = _routerDao.persist(router, guestNetworks); - } - } else { - result = false; + if (result) { + GetDomRVersionAnswer versionAnswer = (GetDomRVersionAnswer)cmds.getAnswer("getDomRVersion"); + router.setTemplateVersion(versionAnswer.getTemplateVersion()); + router.setScriptsVersion(versionAnswer.getScriptsVersion()); + _routerDao.persist(router, guestNetworks); } return result; @@ -3342,15 +3391,28 @@ public int compare(final PublicIpAddress o1, final PublicIpAddress o2) { final IpAddressTO[] ipsToSend = new IpAddressTO[ipAddrList.size()]; int i = 0; boolean firstIP = true; + boolean isSourceNatNw = false; for (final PublicIpAddress ipAddr : ipAddrList) { final boolean add = (ipAddr.getState() == IpAddress.State.Releasing ? false : true); boolean sourceNat = ipAddr.isSourceNat(); + + //set the isSourceNatNw from the first ip of ipAddrList + //For non source network ips the isSourceNatNw is always false + if (sourceNat) { + isSourceNatNw = ipAddr.isSourceNat(); + } + /* enable sourceNAT for the first ip of the public interface */ if (firstIP) { sourceNat = true; } + + // setting sourceNat=true to make sure the snat rule of the ip is deleted + if (!isSourceNatNw && !add ) { + sourceNat = true; + } final String vlanId = ipAddr.getVlanTag(); final String vlanGateway = ipAddr.getGateway(); final String vlanNetmask = ipAddr.getNetmask(); @@ -4330,7 +4392,7 @@ public String getConfigComponentName() { @Override public ConfigKey[] getConfigKeys() { - return new ConfigKey[] {UseExternalDnsServers, routerVersionCheckEnabled, SetServiceMonitor}; + return new ConfigKey[] {UseExternalDnsServers, routerVersionCheckEnabled, SetServiceMonitor, RouterAlertsCheckInterval}; } @Override diff --git a/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java index 82964602d4..c7d4d4c5c3 100644 --- a/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java @@ -442,7 +442,7 @@ private void createVpcAssociatePublicIPCommands(final VirtualRouter router, fina String macAddress = vlanMacAddress.get(BroadcastDomainType.getValue(BroadcastDomainType.fromString(ipAddr.getVlanTag()))); IpAddressTO ip = - new IpAddressTO(ipAddr.getAccountId(), ipAddr.getAddress().addr(), add, false, ipAddr.isSourceNat(), ipAddr.getVlanTag(), ipAddr.getGateway(), + new IpAddressTO(ipAddr.getAccountId(), ipAddr.getAddress().addr(), add, false, ipAddr.isSourceNat(), BroadcastDomainType.fromString(ipAddr.getVlanTag()).toString(), ipAddr.getGateway(), ipAddr.getNetmask(), macAddress, networkRate, ipAddr.isOneToOneNat()); ip.setTrafficType(network.getTrafficType()); @@ -1265,7 +1265,7 @@ protected NicProfile createPrivateNicProfileForGateway(VpcGateway privateGateway NicProfile privateNicProfile = new NicProfile(); if (privateNic != null) { - VirtualMachine vm = _vmDao.findById(privateNic.getId()); + VirtualMachine vm = _vmDao.findById(privateNic.getInstanceId()); privateNicProfile = new NicProfile(privateNic, privateNetwork, privateNic.getBroadcastUri(), privateNic.getIsolationUri(), _networkModel.getNetworkRate( privateNetwork.getId(), vm.getId()), _networkModel.isSecurityGroupSupportedInNetwork(privateNetwork), _networkModel.getNetworkTag( diff --git a/server/src/com/cloud/network/rules/RulesManagerImpl.java b/server/src/com/cloud/network/rules/RulesManagerImpl.java index 9a76219f00..eea12625d7 100755 --- a/server/src/com/cloud/network/rules/RulesManagerImpl.java +++ b/server/src/com/cloud/network/rules/RulesManagerImpl.java @@ -25,10 +25,11 @@ import javax.ejb.Local; import javax.inject.Inject; +import org.apache.log4j.Logger; + import org.apache.cloudstack.api.command.user.firewall.ListPortForwardingRulesCmd; import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; -import org.apache.log4j.Logger; import com.cloud.configuration.ConfigurationManager; import com.cloud.domain.dao.DomainDao; @@ -193,6 +194,7 @@ public void checkRuleAndUserVm(FirewallRule rule, UserVm userVm, Account caller) throw new InvalidParameterValueException("Invalid user vm: " + userVm.getId()); } + // This same owner check is actually not needed, since multiple entities OperateEntry trick guarantee that if (rule.getAccountId() != userVm.getAccountId()) { throw new InvalidParameterValueException("New rule " + rule + " and vm id=" + userVm.getId() + " belong to different accounts"); } @@ -265,8 +267,8 @@ public PortForwardingRule createPortForwardingRule(final PortForwardingRule rule if (vm == null) { throw new InvalidParameterValueException("Unable to create port forwarding rule on address " + ipAddress + ", invalid virtual machine id specified (" + vmId + ")."); - } else { - checkRuleAndUserVm(rule, vm, caller); + } else if (vm.getState() == VirtualMachine.State.Destroyed || vm.getState() == VirtualMachine.State.Expunging) { + throw new InvalidParameterValueException("Invalid user vm: " + vm.getId()); } // Verify that vm has nic in the network @@ -782,9 +784,7 @@ public Pair, Integer> listPortForwardingRules Boolean display = cmd.getDisplay(); Account caller = CallContext.current().getCallingAccount(); - List permittedDomains = new ArrayList(); List permittedAccounts = new ArrayList(); - List permittedResources = new ArrayList(); if (ipId != null) { IPAddressVO ipAddressVO = _ipAddressDao.findById(ipId); @@ -795,14 +795,14 @@ public Pair, Integer> listPortForwardingRules } Ternary domainIdRecursiveListProject = new Ternary(cmd.getDomainId(), cmd.isRecursive(), null); - _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedDomains, permittedAccounts, permittedResources, - domainIdRecursiveListProject, cmd.listAll(), false, "listPortForwardingRules"); + _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, cmd.listAll(), false); + Long domainId = domainIdRecursiveListProject.first(); Boolean isRecursive = domainIdRecursiveListProject.second(); ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third(); Filter filter = new Filter(PortForwardingRuleVO.class, "id", false, cmd.getStartIndex(), cmd.getPageSizeVal()); SearchBuilder sb = _portForwardingDao.createSearchBuilder(); - _accountMgr.buildACLSearchBuilder(sb, isRecursive, permittedDomains, permittedAccounts, permittedResources, listProjectResourcesCriteria); + _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); sb.and("id", sb.entity().getId(), Op.EQ); sb.and("ip", sb.entity().getSourceIpAddressId(), Op.EQ); @@ -823,7 +823,7 @@ public Pair, Integer> listPortForwardingRules } SearchCriteria sc = sb.create(); - _accountMgr.buildACLSearchCriteria(sc, isRecursive, permittedDomains, permittedAccounts, permittedResources, listProjectResourcesCriteria); + _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); if (id != null) { sc.setParameters("id", id); @@ -1000,9 +1000,7 @@ public boolean applyStaticNatsForNetwork(long networkId, boolean continueOnError public Pair, Integer> searchStaticNatRules(Long ipId, Long id, Long vmId, Long start, Long size, String accountName, Long domainId, Long projectId, boolean isRecursive, boolean listAll) { Account caller = CallContext.current().getCallingAccount(); - List permittedDomains = new ArrayList(); List permittedAccounts = new ArrayList(); - List permittedResources = new ArrayList(); if (ipId != null) { IPAddressVO ipAddressVO = _ipAddressDao.findById(ipId); @@ -1013,15 +1011,14 @@ public Pair, Integer> searchStaticNatRules(Long ipI } Ternary domainIdRecursiveListProject = new Ternary(domainId, isRecursive, null); - _accountMgr.buildACLSearchParameters(caller, id, accountName, projectId, permittedDomains, permittedAccounts, permittedResources, domainIdRecursiveListProject, listAll, - false, "listIpForwardingRules"); + _accountMgr.buildACLSearchParameters(caller, id, accountName, projectId, permittedAccounts, domainIdRecursiveListProject, listAll, false); domainId = domainIdRecursiveListProject.first(); isRecursive = domainIdRecursiveListProject.second(); ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third(); Filter filter = new Filter(PortForwardingRuleVO.class, "id", false, start, size); SearchBuilder sb = _firewallDao.createSearchBuilder(); - _accountMgr.buildACLSearchBuilder(sb, isRecursive, permittedDomains, permittedAccounts, permittedResources, listProjectResourcesCriteria); + _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); sb.and("ip", sb.entity().getSourceIpAddressId(), Op.EQ); sb.and("purpose", sb.entity().getPurpose(), Op.EQ); @@ -1034,7 +1031,7 @@ public Pair, Integer> searchStaticNatRules(Long ipI } SearchCriteria sc = sb.create(); - _accountMgr.buildACLSearchCriteria(sc, isRecursive, permittedDomains, permittedAccounts, permittedResources, listProjectResourcesCriteria); + _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); sc.setParameters("purpose", Purpose.StaticNat); if (id != null) { diff --git a/server/src/com/cloud/network/security/SecurityGroupManagerImpl.java b/server/src/com/cloud/network/security/SecurityGroupManagerImpl.java index cf71b25119..f60a746e68 100755 --- a/server/src/com/cloud/network/security/SecurityGroupManagerImpl.java +++ b/server/src/com/cloud/network/security/SecurityGroupManagerImpl.java @@ -716,7 +716,7 @@ private List authorizeSecurityGroupRule(final Long security final Integer startPortOrTypeFinal = startPortOrType; final Integer endPortOrCodeFinal = endPortOrCode; final String protocolFinal = protocol; - return Transaction.execute(new TransactionCallback>() { + List newRules = Transaction.execute(new TransactionCallback>() { @Override public List doInTransaction(TransactionStatus status) { // Prevents other threads/management servers from creating duplicate security rules @@ -761,9 +761,6 @@ public List doInTransaction(TransactionStatus status) { if (s_logger.isDebugEnabled()) { s_logger.debug("Added " + newRules.size() + " rules to security group " + securityGroup.getName()); } - final ArrayList affectedVms = new ArrayList(); - affectedVms.addAll(_securityGroupVMMapDao.listVmIdsBySecurityGroup(securityGroup.getId())); - scheduleRulesetUpdateToHosts(affectedVms, true, null); return newRules; } catch (Exception e) { s_logger.warn("Exception caught when adding security group rules ", e); @@ -776,6 +773,15 @@ public List doInTransaction(TransactionStatus status) { } }); + try { + final ArrayList affectedVms = new ArrayList(); + affectedVms.addAll(_securityGroupVMMapDao.listVmIdsBySecurityGroup(securityGroup.getId())); + scheduleRulesetUpdateToHosts(affectedVms, true, null); + } catch (Exception e) { + s_logger.debug("can't update rules on host, ignore", e); + } + + return newRules; } @Override @@ -815,7 +821,8 @@ private boolean revokeSecurityGroupRule(final Long id, SecurityRuleType type) { SecurityGroup securityGroup = _securityGroupDao.findById(rule.getSecurityGroupId()); _accountMgr.checkAccess(caller, AccessType.OperateEntry, true, securityGroup); - return Transaction.execute(new TransactionCallback() { + long securityGroupId = rule.getSecurityGroupId(); + Boolean result = Transaction.execute(new TransactionCallback() { @Override public Boolean doInTransaction(TransactionStatus status) { SecurityGroupVO groupHandle = null; @@ -831,10 +838,6 @@ public Boolean doInTransaction(TransactionStatus status) { _securityGroupRuleDao.remove(id); s_logger.debug("revokeSecurityGroupRule succeeded for security rule id: " + id); - final ArrayList affectedVms = new ArrayList(); - affectedVms.addAll(_securityGroupVMMapDao.listVmIdsBySecurityGroup(groupHandle.getId())); - scheduleRulesetUpdateToHosts(affectedVms, true, null); - return true; } catch (Exception e) { s_logger.warn("Exception caught when deleting security rules ", e); @@ -846,6 +849,16 @@ public Boolean doInTransaction(TransactionStatus status) { } } }); + + try { + final ArrayList affectedVms = new ArrayList(); + affectedVms.addAll(_securityGroupVMMapDao.listVmIdsBySecurityGroup(securityGroupId)); + scheduleRulesetUpdateToHosts(affectedVms, true, null); + } catch (Exception e) { + s_logger.debug("Can't update rules for host, ignore", e); + } + + return result; } @Override @@ -1350,16 +1363,17 @@ public boolean securityGroupRulesForVmSecIp(long nicId, String secondaryIp, bool // Validate parameters List vmSgGrps = getSecurityGroupsForVm(vmId); - if (vmSgGrps == null) { + if (vmSgGrps.isEmpty()) { s_logger.debug("Vm is not in any Security group "); return true; } - for (SecurityGroupVO securityGroup : vmSgGrps) { - Account owner = _accountMgr.getAccount(securityGroup.getAccountId()); - if (owner == null) { - throw new InvalidParameterValueException("Unable to find security group owner by id=" + securityGroup.getAccountId()); - } + //If network does not support SG service, no need add SG rules for secondary ip + Network network = _networkModel.getNetwork(nic.getNetworkId()); + if (!_networkModel.isSecurityGroupSupportedInNetwork(network)) { + s_logger.debug("Network " + network + " is not enabled with security group service, "+ + "so not applying SG rules for secondary ip"); + return true; } String vmMac = vm.getPrivateMacAddress(); diff --git a/server/src/com/cloud/network/vpc/NetworkACLManagerImpl.java b/server/src/com/cloud/network/vpc/NetworkACLManagerImpl.java index ad47df14cc..de0465b8e7 100644 --- a/server/src/com/cloud/network/vpc/NetworkACLManagerImpl.java +++ b/server/src/com/cloud/network/vpc/NetworkACLManagerImpl.java @@ -271,7 +271,6 @@ public NetworkACLItem getNetworkACLItem(long ruleId) { } @Override - @ActionEvent(eventType = EventTypes.EVENT_NETWORK_ACL_DELETE, eventDescription = "revoking network acl", async = true) public boolean revokeNetworkACLItem(long ruleId) { NetworkACLItemVO rule = _networkACLItemDao.findById(ruleId); @@ -491,8 +490,12 @@ public boolean applyACLItemsToNetwork(long networkId, List rul foundProvider = true; s_logger.debug("Applying NetworkACL for network: " + network.getId() + " with Network ACL service provider"); handled = element.applyNetworkACLs(network, rules); - if (handled) + if (handled) { + // publish message on message bus, so that network elements implementing distributed routing + // capability can act on the event + _messageBus.publish(_name, "Network_ACL_Replaced", PublishScope.LOCAL, network); break; + } } if (!foundProvider) { s_logger.debug("Unable to find NetworkACL service provider for network: " + network.getId()); diff --git a/server/src/com/cloud/network/vpc/NetworkACLServiceImpl.java b/server/src/com/cloud/network/vpc/NetworkACLServiceImpl.java index e024fbe3d3..51bb71f7eb 100644 --- a/server/src/com/cloud/network/vpc/NetworkACLServiceImpl.java +++ b/server/src/com/cloud/network/vpc/NetworkACLServiceImpl.java @@ -108,6 +108,7 @@ public NetworkACL createNetworkACL(String name, String description, long vpcId, } @Override + @ActionEvent(eventType = EventTypes.EVENT_NETWORK_ACL_CREATE, eventDescription = "creating network acl list", async = true) public NetworkACL getNetworkACL(long id) { return _networkAclMgr.getNetworkACL(id); } @@ -169,26 +170,23 @@ public Pair, Integer> listNetworkACLs(ListNetworkACLL // VpcId is not specified. Find permitted VPCs for the caller // and list ACLs belonging to the permitted VPCs - List permittedDomains = new ArrayList(); List permittedAccounts = new ArrayList(); - List permittedResources = new ArrayList(); - Long domainId = cmd.getDomainId(); boolean isRecursive = cmd.isRecursive(); String accountName = cmd.getAccountName(); Long projectId = cmd.getProjectId(); boolean listAll = cmd.listAll(); Ternary domainIdRecursiveListProject = new Ternary(domainId, isRecursive, null); - _accountMgr.buildACLSearchParameters(caller, id, accountName, projectId, permittedDomains, permittedAccounts, permittedResources, domainIdRecursiveListProject, - listAll, false, "listNetworkACLLists"); - //domainId = domainIdRecursiveListProject.first(); + ListProjectResourcesCriteria>(domainId, isRecursive, null); + _accountMgr.buildACLSearchParameters(caller, id, accountName, projectId, permittedAccounts, domainIdRecursiveListProject, + listAll, false); + domainId = domainIdRecursiveListProject.first(); isRecursive = domainIdRecursiveListProject.second(); ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third(); SearchBuilder sbVpc = _vpcDao.createSearchBuilder(); - _accountMgr.buildACLSearchBuilder(sbVpc, isRecursive, permittedDomains, permittedAccounts, permittedResources, listProjectResourcesCriteria); + _accountMgr.buildACLSearchBuilder(sbVpc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); SearchCriteria scVpc = sbVpc.create(); - _accountMgr.buildACLSearchCriteria(scVpc, isRecursive, permittedDomains, permittedAccounts, permittedResources, listProjectResourcesCriteria); + _accountMgr.buildACLSearchCriteria(scVpc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); List vpcs = _vpcDao.search(scVpc, null); List vpcIds = new ArrayList(); for (VpcVO vpc : vpcs) { @@ -209,6 +207,7 @@ public Pair, Integer> listNetworkACLs(ListNetworkACLL } @Override + @ActionEvent(eventType = EventTypes.EVENT_NETWORK_ACL_DELETE, eventDescription = "Deleting Network ACL List", async = true) public boolean deleteNetworkACL(long id) { Account caller = CallContext.current().getCallingAccount(); NetworkACL acl = _networkACLDao.findById(id); @@ -474,6 +473,7 @@ public NetworkACLItem getNetworkACLItem(long ruleId) { } @Override + @ActionEvent(eventType = EventTypes.EVENT_NETWORK_ACL_ITEM_CREATE, eventDescription = "Applying Network ACL Item", async = true) public boolean applyNetworkACL(long aclId) throws ResourceUnavailableException { return _networkAclMgr.applyNetworkACL(aclId); } @@ -488,7 +488,6 @@ public Pair, Integer> listNetworkACLItems(ListNet String action = cmd.getAction(); Map tags = cmd.getTags(); Account caller = CallContext.current().getCallingAccount(); - Boolean display = cmd.getDisplay(); Filter filter = new Filter(NetworkACLItemVO.class, "id", false, cmd.getStartIndex(), cmd.getPageSizeVal()); SearchBuilder sb = _networkACLItemDao.createSearchBuilder(); @@ -498,7 +497,6 @@ public Pair, Integer> listNetworkACLItems(ListNet sb.and("trafficType", sb.entity().getTrafficType(), Op.EQ); sb.and("protocol", sb.entity().getProtocol(), Op.EQ); sb.and("action", sb.entity().getAction(), Op.EQ); - sb.and("display", sb.entity().isDisplay(), Op.EQ); if (tags != null && !tags.isEmpty()) { SearchBuilder tagSearch = _resourceTagDao.createSearchBuilder(); @@ -521,10 +519,6 @@ public Pair, Integer> listNetworkACLItems(ListNet SearchCriteria sc = sb.create(); - if (display != null) { - sc.setParameters("display", display); - } - if (id != null) { sc.setParameters("id", id); } @@ -532,6 +526,11 @@ public Pair, Integer> listNetworkACLItems(ListNet if (networkId != null) { Network network = _networkDao.findById(networkId); aclId = network.getNetworkACLId(); + if( aclId == null){ + // No aclId associated with the network. + //Return empty list + return new Pair(new ArrayList(), 0); + } } if (trafficType != null) { @@ -552,27 +551,26 @@ public Pair, Integer> listNetworkACLItems(ListNet } else { //ToDo: Add accountId to network_acl_item table for permission check + // aclId is not specified // List permitted VPCs and filter aclItems - List permittedDomains = new ArrayList(); List permittedAccounts = new ArrayList(); - List permittedResources = new ArrayList(); Long domainId = cmd.getDomainId(); boolean isRecursive = cmd.isRecursive(); String accountName = cmd.getAccountName(); Long projectId = cmd.getProjectId(); boolean listAll = cmd.listAll(); Ternary domainIdRecursiveListProject = new Ternary(domainId, isRecursive, null); - _accountMgr.buildACLSearchParameters(caller, id, accountName, projectId, permittedDomains, permittedAccounts, permittedResources, domainIdRecursiveListProject, - listAll, false, "listNetworkACLs"); + ListProjectResourcesCriteria>(domainId, isRecursive, null); + _accountMgr.buildACLSearchParameters(caller, id, accountName, projectId, permittedAccounts, domainIdRecursiveListProject, + listAll, false); domainId = domainIdRecursiveListProject.first(); isRecursive = domainIdRecursiveListProject.second(); ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third(); SearchBuilder sbVpc = _vpcDao.createSearchBuilder(); - _accountMgr.buildACLSearchBuilder(sbVpc, isRecursive, permittedDomains, permittedAccounts, permittedResources, listProjectResourcesCriteria); + _accountMgr.buildACLSearchBuilder(sbVpc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); SearchCriteria scVpc = sbVpc.create(); - _accountMgr.buildACLSearchCriteria(scVpc, isRecursive, permittedDomains, permittedAccounts, permittedResources, listProjectResourcesCriteria); + _accountMgr.buildACLSearchCriteria(scVpc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); List vpcs = _vpcDao.search(scVpc, null); List vpcIds = new ArrayList(); for (VpcVO vpc : vpcs) { @@ -606,6 +604,7 @@ public Pair, Integer> listNetworkACLItems(ListNet } @Override + @ActionEvent(eventType = EventTypes.EVENT_NETWORK_ACL_ITEM_DELETE, eventDescription = "Deleting Network ACL Item", async = true) public boolean revokeNetworkACLItem(long ruleId) { NetworkACLItemVO aclItem = _networkACLItemDao.findById(ruleId); if(aclItem != null){ @@ -625,6 +624,7 @@ public boolean revokeNetworkACLItem(long ruleId) { } @Override + @ActionEvent(eventType = EventTypes.EVENT_NETWORK_ACL_ITEM_UPDATE, eventDescription = "Updating Network ACL Item", async = true) public NetworkACLItem updateNetworkACLItem(Long id, String protocol, List sourceCidrList, NetworkACLItem.TrafficType trafficType, String action, Integer number, Integer sourcePortStart, Integer sourcePortEnd, Integer icmpCode, Integer icmpType, String newUUID, Boolean forDisplay) throws ResourceUnavailableException { NetworkACLItemVO aclItem = _networkACLItemDao.findById(id); diff --git a/server/src/com/cloud/network/vpc/PrivateGatewayProfile.java b/server/src/com/cloud/network/vpc/PrivateGatewayProfile.java index b912e227ae..3dc984e444 100644 --- a/server/src/com/cloud/network/vpc/PrivateGatewayProfile.java +++ b/server/src/com/cloud/network/vpc/PrivateGatewayProfile.java @@ -16,7 +16,6 @@ // under the License. package com.cloud.network.vpc; -import org.apache.cloudstack.acl.IAMEntityType; public class PrivateGatewayProfile implements PrivateGateway { VpcGateway vpcGateway; @@ -113,7 +112,7 @@ public long getNetworkACLId() { } @Override - public IAMEntityType getEntityType() { - return IAMEntityType.VpcGateway; + public Class getEntityType() { + return VpcGateway.class; } } diff --git a/server/src/com/cloud/network/vpc/VpcManagerImpl.java b/server/src/com/cloud/network/vpc/VpcManagerImpl.java index 2e63639c33..0d24544338 100644 --- a/server/src/com/cloud/network/vpc/VpcManagerImpl.java +++ b/server/src/com/cloud/network/vpc/VpcManagerImpl.java @@ -16,6 +16,7 @@ // under the License. package com.cloud.network.vpc; + import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -34,6 +35,8 @@ import javax.inject.Inject; import javax.naming.ConfigurationException; +import org.apache.log4j.Logger; + import org.apache.cloudstack.acl.ControlledEntity.ACLType; import org.apache.cloudstack.api.command.user.vpc.ListPrivateGatewaysCmd; import org.apache.cloudstack.api.command.user.vpc.ListStaticRoutesCmd; @@ -42,7 +45,6 @@ import org.apache.cloudstack.framework.config.ConfigDepot; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.cloudstack.managed.context.ManagedContextRunnable; -import org.apache.log4j.Logger; import com.cloud.configuration.Config; import com.cloud.configuration.ConfigurationManager; @@ -65,7 +67,6 @@ import com.cloud.exception.ResourceAllocationException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.hypervisor.Hypervisor.HypervisorType; -import com.cloud.network.element.NetworkElement; import com.cloud.network.IpAddress; import com.cloud.network.IpAddressManager; import com.cloud.network.Network; @@ -85,6 +86,7 @@ import com.cloud.network.dao.NetworkVO; import com.cloud.network.dao.PhysicalNetworkDao; import com.cloud.network.dao.Site2SiteVpnGatewayDao; +import com.cloud.network.element.NetworkElement; import com.cloud.network.element.StaticNatServiceProvider; import com.cloud.network.element.VpcProvider; import com.cloud.network.vpc.VpcOffering.State; @@ -127,7 +129,6 @@ import com.cloud.utils.db.TransactionCallback; import com.cloud.utils.db.TransactionCallbackNoReturn; import com.cloud.utils.db.TransactionCallbackWithException; -import com.cloud.utils.db.TransactionCallbackWithExceptionNoReturn; import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.exception.ExceptionUtil; @@ -220,44 +221,49 @@ public boolean configure(String name, Map params) throws Configu Transaction.execute(new TransactionCallbackNoReturn() { @Override public void doInTransactionWithoutResult(TransactionStatus status) { - if (_vpcOffDao.findByUniqueName(VpcOffering.defaultVPCOfferingName) == null) { - s_logger.debug("Creating default VPC offering " + VpcOffering.defaultVPCOfferingName); - - Map> svcProviderMap = new HashMap>(); - Set defaultProviders = new HashSet(); - defaultProviders.add(Provider.VPCVirtualRouter); - for (Service svc : getSupportedServices()) { - if (svc == Service.Lb) { - Set lbProviders = new HashSet(); - lbProviders.add(Provider.VPCVirtualRouter); - lbProviders.add(Provider.InternalLbVm); - svcProviderMap.put(svc, lbProviders); - } else { - svcProviderMap.put(svc, defaultProviders); + + if (_vpcOffDao.findByUniqueName(VpcOffering.defaultVPCOfferingName) == null) { + s_logger.debug("Creating default VPC offering " + VpcOffering.defaultVPCOfferingName); + + Map> svcProviderMap = new HashMap>(); + Set defaultProviders = new HashSet(); + defaultProviders.add(Provider.VPCVirtualRouter); + for (Service svc : getSupportedServices()) { + if (svc == Service.Lb) { + Set lbProviders = new HashSet(); + lbProviders.add(Provider.VPCVirtualRouter); + lbProviders.add(Provider.InternalLbVm); + svcProviderMap.put(svc, lbProviders); + } else { + svcProviderMap.put(svc, defaultProviders); + } + } + createVpcOffering(VpcOffering.defaultVPCOfferingName, VpcOffering.defaultVPCOfferingName, + svcProviderMap, true, State.Enabled, null, false, false); } - } - createVpcOffering(VpcOffering.defaultVPCOfferingName, VpcOffering.defaultVPCOfferingName, svcProviderMap, true, State.Enabled, null, false); - } - //configure default vpc offering with Netscaler as LB Provider + //configure default vpc offering with Netscaler as LB Provider if (_vpcOffDao.findByUniqueName(VpcOffering.defaultVPCNSOfferingName) == null) { - s_logger.debug("Creating default VPC offering with Netscaler as LB Provider" + VpcOffering.defaultVPCNSOfferingName); - Map> svcProviderMap = new HashMap>(); - Set defaultProviders = new HashSet(); - defaultProviders.add(Provider.VPCVirtualRouter); - for (Service svc : getSupportedServices()) { - if (svc == Service.Lb) { - Set lbProviders = new HashSet(); - lbProviders.add(Provider.Netscaler); - lbProviders.add(Provider.InternalLbVm); - svcProviderMap.put(svc, lbProviders); - } else { - svcProviderMap.put(svc, defaultProviders); + s_logger.debug("Creating default VPC offering with Netscaler as LB Provider" + VpcOffering.defaultVPCNSOfferingName); + Map> svcProviderMap = new HashMap>(); + Set defaultProviders = new HashSet(); + defaultProviders.add(Provider.VPCVirtualRouter); + for (Service svc : getSupportedServices()) { + if (svc == Service.Lb) { + Set lbProviders = new HashSet(); + lbProviders.add(Provider.Netscaler); + lbProviders.add(Provider.InternalLbVm); + svcProviderMap.put(svc, lbProviders); + } else { + svcProviderMap.put(svc, defaultProviders); + } + } + createVpcOffering(VpcOffering.defaultVPCNSOfferingName, VpcOffering.defaultVPCNSOfferingName, + svcProviderMap, false, State.Enabled, null, false, false); + } } - createVpcOffering(VpcOffering.defaultVPCNSOfferingName, VpcOffering.defaultVPCNSOfferingName, svcProviderMap, false, State.Enabled, null, false); - } - } + }); Map configs = _configDao.getConfiguration(params); @@ -380,10 +386,12 @@ public VpcOffering createVpcOffering(String name, String displayText, List> svcProviderMap, final boolean isDefault, final State state, final Long serviceOfferingId, - final boolean supportsDistributedRouter) { + final boolean supportsDistributedRouter, final boolean offersRegionLevelVPC) { + return Transaction.execute(new TransactionCallback() { @Override public VpcOffering doInTransaction(TransactionStatus status) { // create vpc offering object - VpcOfferingVO offering = new VpcOfferingVO(name, displayText, isDefault, serviceOfferingId, supportsDistributedRouter); + VpcOfferingVO offering = new VpcOfferingVO(name, displayText, isDefault, serviceOfferingId, + supportsDistributedRouter, offersRegionLevelVPC); - if (state != null) { - offering.setState(state); - } - s_logger.debug("Adding vpc offering " + offering); - offering = _vpcOffDao.persist(offering); - // populate services and providers - if (svcProviderMap != null) { - for (Network.Service service : svcProviderMap.keySet()) { - Set providers = svcProviderMap.get(service); - if (providers != null && !providers.isEmpty()) { - for (Network.Provider provider : providers) { - VpcOfferingServiceMapVO offService = new VpcOfferingServiceMapVO(offering.getId(), service, provider); - _vpcOffSvcMapDao.persist(offService); - s_logger.trace("Added service for the vpc offering: " + offService + " with provider " + provider.getName()); + if (state != null) { + offering.setState(state); + } + s_logger.debug("Adding vpc offering " + offering); + offering = _vpcOffDao.persist(offering); + // populate services and providers + if (svcProviderMap != null) { + for (Network.Service service : svcProviderMap.keySet()) { + Set providers = svcProviderMap.get(service); + if (providers != null && !providers.isEmpty()) { + for (Network.Provider provider : providers) { + VpcOfferingServiceMapVO offService = new VpcOfferingServiceMapVO(offering.getId(), service, provider); + _vpcOffSvcMapDao.persist(offService); + s_logger.trace("Added service for the vpc offering: " + offService + " with provider " + provider.getName()); + } + } else { + throw new InvalidParameterValueException("Provider is missing for the VPC offering service " + service.getName()); + } } - } else { - throw new InvalidParameterValueException("Provider is missing for the VPC offering service " + service.getName()); } - } - } - return offering; - } + return offering; + } }); } - private boolean isVpcOfferingSupportsDistributedRouter(Map serviceCapabilitystList) { - boolean supportsDistributedRouter = false; + private void validateConnectivtyServiceCapablitlies(Set providers, Map serviceCapabilitystList) { + if (serviceCapabilitystList != null && !serviceCapabilitystList.isEmpty()) { Collection serviceCapabilityCollection = serviceCapabilitystList.values(); Iterator iter = serviceCapabilityCollection.iterator(); Map capabilityMap = null; + boolean distributedRouterCapabilitySpecified = false; + boolean regionLevelVpcCapabilitySpecified = false; while (iter.hasNext()) { HashMap svcCapabilityMap = (HashMap)iter.next(); @@ -448,24 +460,56 @@ private boolean isVpcOfferingSupportsDistributedRouter(Map serviceCapabilitystLi } if (!svc.equalsIgnoreCase(Service.Connectivity.getName())) { - throw new InvalidParameterValueException("Invalid Service:" + svc + " specified. Only for 'Connectivity' service capabilities can be specified"); + throw new InvalidParameterValueException("Invalid Service:" + svc + " specified. Only 'Connectivity'" + + " service capabilities can be specified"); } - if (!capabilityName.equalsIgnoreCase("DistributedRouter")) { - throw new InvalidParameterValueException("Invalid Capability:" + capabilityName + " specified. Only 'DistributedRouter' capability can be specified."); + if (!capabilityName.equalsIgnoreCase("DistributedRouter") && !capabilityName.equalsIgnoreCase("RegionLevelVpc")) { + throw new InvalidParameterValueException("Invalid Capability:" + capabilityName + " specified." + + " Only 'DistributedRouter'/'RegionLevelVpc' capability can be specified."); + } + + if (capabilityName.equalsIgnoreCase("DistributedRouter")) { + distributedRouterCapabilitySpecified = true; + } + + if (capabilityName.equalsIgnoreCase("RegionLevelVpc")) { + regionLevelVpcCapabilitySpecified = true; } if (!capabilityValue.equalsIgnoreCase("true") && capabilityValue.equalsIgnoreCase("false")) { throw new InvalidParameterValueException("Invalid Capability value:" + capabilityValue + " specified."); } - supportsDistributedRouter = capabilityValue.equalsIgnoreCase("true"); + } + + if (providers != null && !providers.isEmpty()) { + for (Provider provider: providers) { + NetworkElement element = _ntwkModel.getElementImplementingProvider(provider.getName()); + Map> capabilities = element.getCapabilities(); + if (capabilities != null && !capabilities.isEmpty()) { + Map connectivityCapabilities = capabilities.get(Service.Connectivity); + if (regionLevelVpcCapabilitySpecified) { + if (connectivityCapabilities == null || (connectivityCapabilities != null && + !connectivityCapabilities.keySet().contains(Network.Capability.RegionLevelVpc))) { + throw new InvalidParameterValueException("Provider: " + provider.getName() + " does not support " + + Network.Capability.RegionLevelVpc.getName() + " capability."); + } + } + if (distributedRouterCapabilitySpecified) { + if (connectivityCapabilities == null || (connectivityCapabilities != null && + !connectivityCapabilities.keySet().contains(Network.Capability.DistributedRouter))) { + throw new InvalidParameterValueException("Provider: " + provider.getName() + " does not support " + + Network.Capability.DistributedRouter.getName() + " capability."); + } + } + } + } } } - return supportsDistributedRouter; } - private void validateConnectivtyServiceCapablitlies(Set providers, Map serviceCapabilitystList) { - + private boolean isVpcOfferingForRegionLevelVpc(Map serviceCapabilitystList) { + boolean offersRegionLevelVPC = false; if (serviceCapabilitystList != null && !serviceCapabilitystList.isEmpty()) { Collection serviceCapabilityCollection = serviceCapabilitystList.values(); Iterator iter = serviceCapabilityCollection.iterator(); @@ -489,29 +533,55 @@ private void validateConnectivtyServiceCapablitlies(Set providers, Map throw new InvalidParameterValueException("Invalid Service:" + svc + " specified. Only for 'Connectivity' service capabilities can be specified"); } - if (!capabilityName.equalsIgnoreCase("DistributedRouter")) { - throw new InvalidParameterValueException("Invalid Capability:" + capabilityName + " specified. Only 'DistributedRouter' capability can be specified."); + if (!capabilityName.equalsIgnoreCase("RegionLevelVpc")) { + continue; } if (!capabilityValue.equalsIgnoreCase("true") && capabilityValue.equalsIgnoreCase("false")) { throw new InvalidParameterValueException("Invalid Capability value:" + capabilityValue + " specified."); } + offersRegionLevelVPC = capabilityValue.equalsIgnoreCase("true"); } + } + return offersRegionLevelVPC; + } - if (providers != null && !providers.isEmpty()) { - for (Provider provider: providers) { - NetworkElement element = _ntwkModel.getElementImplementingProvider(provider.getName()); - Map> capabilities = element.getCapabilities(); - if (capabilities != null && !capabilities.isEmpty()) { - Map connectivityCapabilities = capabilities.get(Service.Connectivity); - if (connectivityCapabilities == null || (connectivityCapabilities != null && !connectivityCapabilities.keySet().contains(Network.Capability.DistributedRouter))) { - throw new InvalidParameterValueException("Provider: " + provider.getName() + " does not support " - + Network.Capability.DistributedRouter.getName() + " capability."); - } - } + private boolean isVpcOfferingSupportsDistributedRouter(Map serviceCapabilitystList) { + boolean supportsDistributedRouter = false; + if (serviceCapabilitystList != null && !serviceCapabilitystList.isEmpty()) { + Collection serviceCapabilityCollection = serviceCapabilitystList.values(); + Iterator iter = serviceCapabilityCollection.iterator(); + Map capabilityMap = null; + + while (iter.hasNext()) { + HashMap svcCapabilityMap = (HashMap)iter.next(); + Network.Capability capability = null; + String svc = svcCapabilityMap.get("service"); + String capabilityName = svcCapabilityMap.get("capabilitytype"); + String capabilityValue = svcCapabilityMap.get("capabilityvalue"); + if (capabilityName != null) { + capability = Network.Capability.getCapability(capabilityName); } + + if ((capability == null) || (capabilityName == null) || (capabilityValue == null)) { + throw new InvalidParameterValueException("Invalid capability:" + capabilityName + " capability value:" + capabilityValue); + } + + if (!svc.equalsIgnoreCase(Service.Connectivity.getName())) { + throw new InvalidParameterValueException("Invalid Service:" + svc + " specified. Only for 'Connectivity' service capabilities can be specified"); + } + + if (!capabilityName.equalsIgnoreCase("DistributedRouter")) { + continue; + } + + if (!capabilityValue.equalsIgnoreCase("true") && capabilityValue.equalsIgnoreCase("false")) { + throw new InvalidParameterValueException("Invalid Capability value:" + capabilityValue + " specified."); + } + supportsDistributedRouter = capabilityValue.equalsIgnoreCase("true"); } } + return supportsDistributedRouter; } @Override @@ -708,6 +778,11 @@ public Vpc createVpc(long zoneId, long vpcOffId, long vpcOwnerId, String vpcName throw ex; } + boolean isRegionLevelVpcOff = vpcOff.offersRegionLevelVPC(); + if (isRegionLevelVpcOff && networkDomain == null) { + throw new InvalidParameterValueException("Network domain must be specified for region level VPC"); + } + //Validate zone DataCenter zone = _entityMgr.findById(DataCenter.class, zoneId); if (zone == null) { @@ -730,13 +805,15 @@ public Vpc createVpc(long zoneId, long vpcOffId, long vpcOwnerId, String vpcName networkDomain = "cs" + Long.toHexString(owner.getId()) + NetworkOrchestrationService.GuestDomainSuffix.valueIn(zoneId); } } + boolean useDistributedRouter = vpcOff.supportsDistributedRouter(); - return createVpc(zoneId, vpcOffId, owner, vpcName, displayText, cidr, networkDomain, displayVpc, useDistributedRouter); + return createVpc(zoneId, vpcOffId, owner, vpcName, displayText, cidr, networkDomain, displayVpc, + useDistributedRouter, isRegionLevelVpcOff); } @DB protected Vpc createVpc(final long zoneId, final long vpcOffId, final Account vpcOwner, final String vpcName, final String displayText, final String cidr, - final String networkDomain, final Boolean displayVpc, final boolean useDistributedRouter) { + final String networkDomain, final Boolean displayVpc, final boolean useDistributedRouter, final boolean regionLevelVpc) { //Validate CIDR if (!NetUtils.isValidCIDR(cidr)) { @@ -759,7 +836,8 @@ protected Vpc createVpc(final long zoneId, final long vpcOffId, final Account vp @Override public VpcVO doInTransaction(TransactionStatus status) { VpcVO vpc = new VpcVO(zoneId, vpcName, displayText, vpcOwner.getId(), vpcOwner.getDomainId(), vpcOffId, - cidr, networkDomain, useDistributedRouter); + cidr, networkDomain, useDistributedRouter, regionLevelVpc); + if (displayVpc != null) { vpc.setDisplay(displayVpc); } @@ -917,20 +995,18 @@ public List listVpcs(Long id, String vpcName, String displayText, String accountName, Long domainId, String keyword, Long startIndex, Long pageSizeVal, Long zoneId, Boolean isRecursive, Boolean listAll, Boolean restartRequired, Map tags, Long projectId, Boolean display) { Account caller = CallContext.current().getCallingAccount(); - List permittedDomains = new ArrayList(); List permittedAccounts = new ArrayList(); - List permittedResources = new ArrayList(); - Ternary domainIdRecursiveListProject = new Ternary(domainId, isRecursive, null); - _accountMgr.buildACLSearchParameters(caller, id, accountName, projectId, permittedDomains, permittedAccounts, permittedResources, domainIdRecursiveListProject, listAll, - false, "listVPCs"); + _accountMgr.buildACLSearchParameters(caller, id, accountName, projectId, permittedAccounts, domainIdRecursiveListProject, + listAll, false); + domainId = domainIdRecursiveListProject.first(); isRecursive = domainIdRecursiveListProject.second(); ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third(); Filter searchFilter = new Filter(VpcVO.class, "created", false, startIndex, pageSizeVal); SearchBuilder sb = _vpcDao.createSearchBuilder(); - _accountMgr.buildACLSearchBuilder(sb, isRecursive, permittedDomains, permittedAccounts, permittedResources, listProjectResourcesCriteria); + _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); sb.and("name", sb.entity().getName(), SearchCriteria.Op.LIKE); sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); @@ -956,7 +1032,7 @@ public List listVpcs(Long id, String vpcName, String displayText, // now set the SC criteria... SearchCriteria sc = sb.create(); - _accountMgr.buildACLSearchCriteria(sc, isRecursive, permittedDomains, permittedAccounts, permittedResources, listProjectResourcesCriteria); + _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); if (keyword != null) { SearchCriteria ssc = _vpcDao.createSearchCriteria(); @@ -1199,7 +1275,9 @@ public void validateNtwkOffForNtwkInVpc(Long networkId, long newNtwkOffId, Strin continue; } else { NetworkOffering otherOff = _entityMgr.findById(NetworkOffering.class, network.getNetworkOfferingId()); - if (_ntwkModel.areServicesSupportedInNetwork(network.getId(), Service.Lb) && otherOff.getPublicLb()) { + //throw only if networks have different offerings with public lb support + if (_ntwkModel.areServicesSupportedInNetwork(network.getId(), Service.Lb) && otherOff.getPublicLb() && + guestNtwkOff.getId() != otherOff.getId()) { throw new InvalidParameterValueException("Public LB service is already supported " + "by network " + network + " in VPC " + vpc); } } @@ -1573,10 +1651,14 @@ public PrivateGateway applyVpcPrivateGateway(long gatewayId, boolean destroyOnFa boolean success = true; try { + List providersToImplement = getVpcProviders(vo.getVpcId()); + PrivateGateway gateway = getVpcPrivateGateway(gatewayId); for (VpcProvider provider : getVpcElements()) { - if (!provider.createPrivateGateway(gateway)) { - success = false; + if (providersToImplement.contains(provider.getProvider())) { + if (!provider.createPrivateGateway(gateway)) { + success = false; + } } } if (success) { @@ -1635,17 +1717,20 @@ public void doInTransactionWithoutResult(TransactionStatus status) { }); //1) delete the gateway on the backend + List providersToImplement = getVpcProviders(gatewayVO.getVpcId()); PrivateGateway gateway = getVpcPrivateGateway(gatewayId); for (VpcProvider provider : getVpcElements()) { - if (provider.deletePrivateGateway(gateway)) { - s_logger.debug("Private gateway " + gateway + " was applied succesfully on the backend"); - } else { - s_logger.warn("Private gateway " + gateway + " failed to apply on the backend"); - gatewayVO.setState(VpcGateway.State.Ready); - _vpcGatewayDao.update(gatewayVO.getId(), gatewayVO); - s_logger.debug("Marked gateway " + gatewayVO + " with state " + VpcGateway.State.Ready); + if (providersToImplement.contains(provider.getProvider())) { + if (provider.deletePrivateGateway(gateway)) { + s_logger.debug("Private gateway " + gateway + " was applied succesfully on the backend"); + } else { + s_logger.warn("Private gateway " + gateway + " failed to apply on the backend"); + gatewayVO.setState(VpcGateway.State.Ready); + _vpcGatewayDao.update(gatewayVO.getId(), gatewayVO); + s_logger.debug("Marked gateway " + gatewayVO + " with state " + VpcGateway.State.Ready); - return false; + return false; + } } } @@ -1710,23 +1795,21 @@ public Pair, Integer> listPrivateGateway(ListPrivateGateway Long domainId = cmd.getDomainId(); String accountName = cmd.getAccountName(); Account caller = CallContext.current().getCallingAccount(); - List permittedDomains = new ArrayList(); List permittedAccounts = new ArrayList(); - List permittedResources = new ArrayList(); String state = cmd.getState(); Long projectId = cmd.getProjectId(); Filter searchFilter = new Filter(VpcGatewayVO.class, "id", false, cmd.getStartIndex(), cmd.getPageSizeVal()); Ternary domainIdRecursiveListProject = new Ternary(domainId, isRecursive, null); - _accountMgr.buildACLSearchParameters(caller, id, accountName, projectId, permittedDomains, permittedAccounts, permittedResources, domainIdRecursiveListProject, listAll, - false, "listPrivateGateways"); + _accountMgr.buildACLSearchParameters(caller, id, accountName, projectId, permittedAccounts, domainIdRecursiveListProject, + listAll, false); + domainId = domainIdRecursiveListProject.first(); isRecursive = domainIdRecursiveListProject.second(); ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third(); SearchBuilder sb = _vpcGatewayDao.createSearchBuilder(); - _accountMgr.buildACLSearchBuilder(sb, isRecursive, permittedDomains, permittedAccounts, permittedResources, listProjectResourcesCriteria); - + _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); if (vlan != null) { SearchBuilder ntwkSearch = _ntwkDao.createSearchBuilder(); ntwkSearch.and("vlan", ntwkSearch.entity().getBroadcastUri(), SearchCriteria.Op.EQ); @@ -1734,8 +1817,7 @@ public Pair, Integer> listPrivateGateway(ListPrivateGateway } SearchCriteria sc = sb.create(); - _accountMgr.buildACLSearchBuilder(sb, isRecursive, permittedDomains, permittedAccounts, permittedResources, listProjectResourcesCriteria); - + _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); if (id != null) { sc.addAnd("id", Op.EQ, id); } @@ -1963,23 +2045,21 @@ public Pair, Integer> listStaticRoutes(ListStaticRou Boolean listAll = cmd.listAll(); String accountName = cmd.getAccountName(); Account caller = CallContext.current().getCallingAccount(); - List permittedDomains = new ArrayList(); List permittedAccounts = new ArrayList(); - List permittedResources = new ArrayList(); - Map tags = cmd.getTags(); Long projectId = cmd.getProjectId(); Ternary domainIdRecursiveListProject = new Ternary(domainId, isRecursive, null); - _accountMgr.buildACLSearchParameters(caller, id, accountName, projectId, permittedDomains, permittedAccounts, permittedResources, domainIdRecursiveListProject, listAll, - false, "listStaticRoutes"); + _accountMgr.buildACLSearchParameters(caller, id, accountName, projectId, permittedAccounts, domainIdRecursiveListProject, + listAll, false); + domainId = domainIdRecursiveListProject.first(); isRecursive = domainIdRecursiveListProject.second(); ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third(); Filter searchFilter = new Filter(StaticRouteVO.class, "created", false, cmd.getStartIndex(), cmd.getPageSizeVal()); SearchBuilder sb = _staticRouteDao.createSearchBuilder(); - _accountMgr.buildACLSearchBuilder(sb, isRecursive, permittedDomains, permittedAccounts, permittedResources, listProjectResourcesCriteria); + _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); sb.and("vpcId", sb.entity().getVpcId(), SearchCriteria.Op.EQ); @@ -1998,8 +2078,7 @@ public Pair, Integer> listStaticRoutes(ListStaticRou } SearchCriteria sc = sb.create(); - _accountMgr.buildACLSearchCriteria(sc, isRecursive, permittedDomains, permittedAccounts, permittedResources, listProjectResourcesCriteria); - + _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); if (id != null) { sc.addAnd("id", Op.EQ, id); } @@ -2078,9 +2157,6 @@ protected void runInContext() { } try { - Transaction.execute(new TransactionCallbackWithExceptionNoReturn() { - @Override - public void doInTransactionWithoutResult(TransactionStatus status) throws Exception { // Cleanup inactive VPCs List inactiveVpcs = _vpcDao.listInactiveVpcs(); s_logger.info("Found " + inactiveVpcs.size() + " removed VPCs to cleanup"); @@ -2088,8 +2164,6 @@ public void doInTransactionWithoutResult(TransactionStatus status) throws Except s_logger.debug("Cleaning up " + vpc); destroyVpc(vpc, _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM), User.UID_SYSTEM); } - } - }); } catch (Exception e) { s_logger.error("Exception ", e); } finally { @@ -2210,7 +2284,7 @@ public Network createVpcGuestNetwork(long ntwkOffId, String name, String display networkDomain = vpc.getNetworkDomain(); } - if (vpc.getZoneId() != zoneId) { + if (!vpc.isRegionLevelVpc() && vpc.getZoneId() != zoneId) { throw new InvalidParameterValueException("New network doesn't belong to vpc zone"); } diff --git a/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java b/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java index 531adad352..f4d8947824 100755 --- a/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java +++ b/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java @@ -285,15 +285,17 @@ private void validateRemoteAccessVpnConfiguration() throws ConfigurationExceptio @Override @DB - public void destroyRemoteAccessVpnForIp(long ipId, Account caller) throws ResourceUnavailableException { + @ActionEvent(eventType = EventTypes.EVENT_REMOTE_ACCESS_VPN_DESTROY, eventDescription = "removing remote access vpn", async = true) + public boolean destroyRemoteAccessVpnForIp(long ipId, Account caller) throws ResourceUnavailableException { final RemoteAccessVpnVO vpn = _remoteAccessVpnDao.findByPublicIpAddress(ipId); if (vpn == null) { s_logger.debug("there are no Remote access vpns for public ip address id=" + ipId); - return; + return true; } _accountMgr.checkAccess(caller, AccessType.OperateEntry, true, vpn); + RemoteAccessVpn.State prevState = vpn.getState(); vpn.setState(RemoteAccessVpn.State.Removed); _remoteAccessVpnDao.update(vpn.getId(), vpn); @@ -305,6 +307,12 @@ public void destroyRemoteAccessVpnForIp(long ipId, Account caller) throws Resour break; } } + }catch (ResourceUnavailableException ex) { + vpn.setState(prevState); + _remoteAccessVpnDao.update(vpn.getId(), vpn); + s_logger.debug("Failed to stop the vpn " + vpn.getId() + " , so reverted state to "+ + RemoteAccessVpn.State.Running); + success = false; } finally { if (success) { //Cleanup corresponding ports @@ -366,6 +374,7 @@ public void doInTransactionWithoutResult(TransactionStatus status) { } } } + return success; } @Override @@ -441,6 +450,7 @@ public List listVpnUsers(long vpnOwnerId, String userName) { @Override @DB + @ActionEvent(eventType = EventTypes.EVENT_REMOTE_ACCESS_VPN_CREATE, eventDescription = "creating remote access vpn", async = true) public RemoteAccessVpnVO startRemoteAccessVpn(long ipAddressId, boolean openFirewall) throws ResourceUnavailableException { Account caller = CallContext.current().getCallingAccount(); @@ -578,26 +588,24 @@ public Pair, Integer> searchForVpnUsers(ListVpnUsersCmd String username = cmd.getUsername(); Long id = cmd.getId(); Account caller = CallContext.current().getCallingAccount(); - List permittedDomains = new ArrayList(); List permittedAccounts = new ArrayList(); - List permittedResources = new ArrayList(); Ternary domainIdRecursiveListProject = new Ternary(cmd.getDomainId(), cmd.isRecursive(), null); - _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedDomains, permittedAccounts, permittedResources, - domainIdRecursiveListProject, cmd.listAll(), false, "listVpnUsers"); - //Long domainId = domainIdRecursiveListProject.first(); + _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, cmd.listAll(), false); + Long domainId = domainIdRecursiveListProject.first(); Boolean isRecursive = domainIdRecursiveListProject.second(); ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third(); Filter searchFilter = new Filter(VpnUserVO.class, "username", true, cmd.getStartIndex(), cmd.getPageSizeVal()); SearchBuilder sb = _vpnUsersDao.createSearchBuilder(); - _accountMgr.buildACLSearchBuilder(sb, isRecursive, permittedDomains, permittedAccounts, permittedResources, listProjectResourcesCriteria); + _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); + sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); sb.and("username", sb.entity().getUsername(), SearchCriteria.Op.EQ); sb.and("state", sb.entity().getState(), Op.IN); SearchCriteria sc = sb.create(); - _accountMgr.buildACLSearchCriteria(sc, isRecursive, permittedDomains, permittedAccounts, permittedResources, listProjectResourcesCriteria); + _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); //list only active users sc.setParameters("state", State.Active, State.Add); @@ -619,9 +627,7 @@ public Pair, Integer> searchForRemoteAccessVpns( // do some parameter validation Account caller = CallContext.current().getCallingAccount(); Long ipAddressId = cmd.getPublicIpId(); - List permittedDomains = new ArrayList(); List permittedAccounts = new ArrayList(); - List permittedResources = new ArrayList(); Long vpnId = cmd.getId(); Long networkId = cmd.getNetworkId(); @@ -640,15 +646,14 @@ public Pair, Integer> searchForRemoteAccessVpns( } Ternary domainIdRecursiveListProject = new Ternary(cmd.getDomainId(), cmd.isRecursive(), null); - _accountMgr.buildACLSearchParameters(caller, null, cmd.getAccountName(), cmd.getProjectId(), permittedDomains, permittedAccounts, permittedResources, - domainIdRecursiveListProject, cmd.listAll(), false, "listRemoteAccessVpns"); - //Long domainId = domainIdRecursiveListProject.first(); + _accountMgr.buildACLSearchParameters(caller, null, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, cmd.listAll(), false); + Long domainId = domainIdRecursiveListProject.first(); Boolean isRecursive = domainIdRecursiveListProject.second(); ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third(); Filter filter = new Filter(RemoteAccessVpnVO.class, "serverAddressId", false, cmd.getStartIndex(), cmd.getPageSizeVal()); SearchBuilder sb = _remoteAccessVpnDao.createSearchBuilder(); - _accountMgr.buildACLSearchBuilder(sb, isRecursive, permittedDomains, permittedAccounts, permittedResources, listProjectResourcesCriteria); + _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); sb.and("serverAddressId", sb.entity().getServerAddressId(), Op.EQ); sb.and("id", sb.entity().getId(), Op.EQ); @@ -657,7 +662,8 @@ public Pair, Integer> searchForRemoteAccessVpns( sb.and("display", sb.entity().isDisplay(), Op.EQ); SearchCriteria sc = sb.create(); - _accountMgr.buildACLSearchCriteria(sc, isRecursive, permittedDomains, permittedAccounts, permittedResources, listProjectResourcesCriteria); + _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); + sc.setParameters("state", RemoteAccessVpn.State.Running); diff --git a/server/src/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java b/server/src/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java index fdb5bbf124..8edab62554 100644 --- a/server/src/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java +++ b/server/src/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java @@ -24,6 +24,9 @@ import javax.inject.Inject; import javax.naming.ConfigurationException; +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; + import org.apache.cloudstack.api.command.user.vpn.CreateVpnConnectionCmd; import org.apache.cloudstack.api.command.user.vpn.CreateVpnCustomerGatewayCmd; import org.apache.cloudstack.api.command.user.vpn.CreateVpnGatewayCmd; @@ -37,8 +40,6 @@ import org.apache.cloudstack.api.command.user.vpn.UpdateVpnCustomerGatewayCmd; import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; -import org.apache.log4j.Logger; -import org.springframework.stereotype.Component; import com.cloud.configuration.Config; import com.cloud.event.ActionEvent; @@ -118,7 +119,7 @@ public boolean configure(String name, Map params) throws Configu } @Override - @ActionEvent(eventType = EventTypes.EVENT_S2S_VPN_GATEWAY_CREATE, eventDescription = "creating s2s vpn gateway", create = true) + @ActionEvent(eventType = EventTypes.EVENT_S2S_VPN_GATEWAY_CREATE, eventDescription = "creating s2s vpn gateway", async = true) public Site2SiteVpnGateway createVpnGateway(CreateVpnGatewayCmd cmd) { Account caller = CallContext.current().getCallingAccount(); Account owner = _accountMgr.getAccount(cmd.getEntityOwnerId()); @@ -263,13 +264,9 @@ public Site2SiteVpnConnection createVpnConnection(CreateVpnConnectionCmd cmd) th } if (_vpnConnectionDao.findByVpnGatewayIdAndCustomerGatewayId(vpnGatewayId, customerGatewayId) != null) { - throw new InvalidParameterValueException("The vpn connection with customer gateway id " + customerGatewayId + " or vpn gateway id " + vpnGatewayId + + throw new InvalidParameterValueException("The vpn connection with customer gateway id " + customerGatewayId + " and vpn gateway id " + vpnGatewayId + " already existed!"); } - if (_vpnConnectionDao.findByCustomerGatewayId(customerGatewayId) != null) { - throw new InvalidParameterValueException("The vpn connection with specified customer gateway id " + customerGatewayId + " already exists!"); - } - String[] cidrList = customerGateway.getGuestCidrList().split(","); // Remote sub nets cannot overlap VPC's sub net @@ -314,6 +311,7 @@ public Site2SiteVpnConnection createVpnConnection(CreateVpnConnectionCmd cmd) th @Override @DB + @ActionEvent(eventType = EventTypes.EVENT_S2S_VPN_CONNECTION_CREATE, eventDescription = "starting s2s vpn connection", async = true) public Site2SiteVpnConnection startVpnConnection(long id) throws ResourceUnavailableException { Site2SiteVpnConnectionVO conn = _vpnConnectionDao.acquireInLockTable(id); if (conn == null) { @@ -390,7 +388,7 @@ protected void doDeleteVpnGateway(Site2SiteVpnGateway gw) { } @Override - @ActionEvent(eventType = EventTypes.EVENT_S2S_VPN_GATEWAY_DELETE, eventDescription = "deleting s2s vpn gateway", create = true) + @ActionEvent(eventType = EventTypes.EVENT_S2S_VPN_GATEWAY_DELETE, eventDescription = "deleting s2s vpn gateway", async = true) public boolean deleteVpnGateway(DeleteVpnGatewayCmd cmd) { CallContext.current().setEventDetails(" Id: " + cmd.getId()); Account caller = CallContext.current().getCallingAccount(); @@ -581,26 +579,23 @@ public Pair, Integer> searchForCustomer long pageSizeVal = cmd.getPageSizeVal(); Account caller = CallContext.current().getCallingAccount(); - List permittedDomains = new ArrayList(); List permittedAccounts = new ArrayList(); - List permittedResources = new ArrayList(); Ternary domainIdRecursiveListProject = new Ternary(domainId, isRecursive, null); - _accountMgr.buildACLSearchParameters(caller, id, accountName, null, permittedDomains, permittedAccounts, permittedResources, domainIdRecursiveListProject, listAll, false, - "listVpnCustomerGateways"); - //domainId = domainIdRecursiveListProject.first(); + _accountMgr.buildACLSearchParameters(caller, id, accountName, null, permittedAccounts, domainIdRecursiveListProject, listAll, false); + domainId = domainIdRecursiveListProject.first(); isRecursive = domainIdRecursiveListProject.second(); ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third(); Filter searchFilter = new Filter(Site2SiteCustomerGatewayVO.class, "id", false, startIndex, pageSizeVal); SearchBuilder sb = _customerGatewayDao.createSearchBuilder(); - _accountMgr.buildACLSearchBuilder(sb, isRecursive, permittedDomains, permittedAccounts, permittedResources, listProjectResourcesCriteria); + _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); SearchCriteria sc = sb.create(); - _accountMgr.buildACLSearchCriteria(sc, isRecursive, permittedDomains, permittedAccounts, permittedResources, listProjectResourcesCriteria); + _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); if (id != null) { sc.addAnd("id", SearchCriteria.Op.EQ, id); @@ -624,28 +619,25 @@ public Pair, Integer> searchForVpnGateways(L long pageSizeVal = cmd.getPageSizeVal(); Account caller = CallContext.current().getCallingAccount(); - List permittedDomains = new ArrayList(); List permittedAccounts = new ArrayList(); - List permittedResources = new ArrayList(); Ternary domainIdRecursiveListProject = new Ternary(domainId, isRecursive, null); - _accountMgr.buildACLSearchParameters(caller, id, accountName, null, permittedDomains, permittedAccounts, permittedResources, domainIdRecursiveListProject, listAll, false, - "listVpnGateways"); - //domainId = domainIdRecursiveListProject.first(); + _accountMgr.buildACLSearchParameters(caller, id, accountName, null, permittedAccounts, domainIdRecursiveListProject, listAll, false); + domainId = domainIdRecursiveListProject.first(); isRecursive = domainIdRecursiveListProject.second(); ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third(); Filter searchFilter = new Filter(Site2SiteVpnGatewayVO.class, "id", false, startIndex, pageSizeVal); SearchBuilder sb = _vpnGatewayDao.createSearchBuilder(); - _accountMgr.buildACLSearchBuilder(sb, isRecursive, permittedDomains, permittedAccounts, permittedResources, listProjectResourcesCriteria); + _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); sb.and("vpcId", sb.entity().getVpcId(), SearchCriteria.Op.EQ); sb.and("display", sb.entity().isDisplay(), SearchCriteria.Op.EQ); SearchCriteria sc = sb.create(); - _accountMgr.buildACLSearchCriteria(sc, isRecursive, permittedDomains, permittedAccounts, permittedResources, listProjectResourcesCriteria); + _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); if (id != null) { sc.addAnd("id", SearchCriteria.Op.EQ, id); @@ -677,21 +669,18 @@ public Pair, Integer> searchForVpnConnect long pageSizeVal = cmd.getPageSizeVal(); Account caller = CallContext.current().getCallingAccount(); - List permittedDomains = new ArrayList(); List permittedAccounts = new ArrayList(); - List permittedResources = new ArrayList(); Ternary domainIdRecursiveListProject = new Ternary(domainId, isRecursive, null); - _accountMgr.buildACLSearchParameters(caller, id, accountName, null, permittedDomains, permittedAccounts, permittedResources, domainIdRecursiveListProject, listAll, false, - "listVpnConnections"); - //domainId = domainIdRecursiveListProject.first(); + _accountMgr.buildACLSearchParameters(caller, id, accountName, null, permittedAccounts, domainIdRecursiveListProject, listAll, false); + domainId = domainIdRecursiveListProject.first(); isRecursive = domainIdRecursiveListProject.second(); ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third(); Filter searchFilter = new Filter(Site2SiteVpnConnectionVO.class, "id", false, startIndex, pageSizeVal); SearchBuilder sb = _vpnConnectionDao.createSearchBuilder(); - _accountMgr.buildACLSearchBuilder(sb, isRecursive, permittedDomains, permittedAccounts, permittedResources, listProjectResourcesCriteria); + _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); sb.and("display", sb.entity().isDisplay(), SearchCriteria.Op.EQ); @@ -703,7 +692,7 @@ public Pair, Integer> searchForVpnConnect } SearchCriteria sc = sb.create(); - _accountMgr.buildACLSearchCriteria(sc, isRecursive, permittedDomains, permittedAccounts, permittedResources, listProjectResourcesCriteria); + _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); if (display != null) { sc.setParameters("display", display); diff --git a/server/src/com/cloud/resource/DiscovererBase.java b/server/src/com/cloud/resource/DiscovererBase.java index ae2a9c9f1e..871dc15cf6 100644 --- a/server/src/com/cloud/resource/DiscovererBase.java +++ b/server/src/com/cloud/resource/DiscovererBase.java @@ -16,18 +16,6 @@ // under the License. package com.cloud.resource; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.net.URL; -import java.util.HashMap; -import java.util.Map; - -import javax.inject.Inject; -import javax.naming.ConfigurationException; - -import org.apache.cloudstack.framework.config.dao.ConfigurationDao; -import org.apache.log4j.Logger; - import com.cloud.configuration.Config; import com.cloud.dc.ClusterVO; import com.cloud.dc.dao.ClusterDao; @@ -37,6 +25,16 @@ import com.cloud.network.NetworkModel; import com.cloud.utils.component.AdapterBase; import com.cloud.utils.net.UrlUtil; +import org.apache.cloudstack.framework.config.dao.ConfigurationDao; +import org.apache.log4j.Logger; + +import javax.inject.Inject; +import javax.naming.ConfigurationException; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.net.URL; +import java.util.HashMap; +import java.util.Map; public abstract class DiscovererBase extends AdapterBase implements Discoverer { protected Map _params; @@ -139,6 +137,8 @@ protected HashMap buildConfigParams(HostVO host) { params.put("migratewait", _configDao.getValue(Config.MigrateWait.toString())); params.put(Config.XenMaxNics.toString().toLowerCase(), _configDao.getValue(Config.XenMaxNics.toString())); params.put(Config.XenHeartBeatInterval.toString().toLowerCase(), _configDao.getValue(Config.XenHeartBeatInterval.toString())); + params.put("router.aggregation.command.each.timeout", _configDao.getValue(Config.RouterAggregationCommandEachTimeout.toString())); + return params; } diff --git a/server/src/com/cloud/resource/ResourceManagerImpl.java b/server/src/com/cloud/resource/ResourceManagerImpl.java index f9a59ba4eb..0f2ffc39b5 100755 --- a/server/src/com/cloud/resource/ResourceManagerImpl.java +++ b/server/src/com/cloud/resource/ResourceManagerImpl.java @@ -63,6 +63,7 @@ import com.cloud.agent.api.StartupRoutingCommand; import com.cloud.agent.api.UnsupportedAnswer; import com.cloud.agent.api.UpdateHostPasswordCommand; +import com.cloud.agent.api.VgpuTypesInfo; import com.cloud.agent.api.to.GPUDeviceTO; import com.cloud.agent.transport.Request; import com.cloud.api.ApiDBUtils; @@ -97,7 +98,6 @@ import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.PermissionDeniedException; import com.cloud.exception.ResourceInUseException; -import com.cloud.gpu.GPU.vGPUType; import com.cloud.gpu.HostGpuGroupsVO; import com.cloud.gpu.VGPUTypesVO; import com.cloud.gpu.dao.HostGpuGroupsDao; @@ -583,7 +583,7 @@ public List discoverHosts(AddHostCmd cmd) throws IllegalArgument } } - return discoverHostsFull(dcId, podId, clusterId, clusterName, url, username, password, cmd.getHypervisor(), hostTags, cmd.getFullUrlParams(), true); + return discoverHostsFull(dcId, podId, clusterId, clusterName, url, username, password, cmd.getHypervisor(), hostTags, cmd.getFullUrlParams(), false); } @Override @@ -1349,6 +1349,7 @@ public boolean configure(String name, Map params) throws Configu _gpuAvailability = _hostGpuGroupsDao.createSearchBuilder(); _gpuAvailability.and("hostId", _gpuAvailability.entity().getHostId(), Op.EQ); + _gpuAvailability.and("groupName", _gpuAvailability.entity().getGroupName(), Op.EQ); SearchBuilder join1 = _vgpuTypesDao.createSearchBuilder(); join1.and("vgpuType", join1.entity().getVgpuType(), Op.EQ); join1.and("remainingCapacity", join1.entity().getRemainingCapacity(), Op.GT); @@ -2501,21 +2502,26 @@ public List listAllUpAndEnabledHostsInOneZoneByHypervisor(HypervisorType } @Override - public List listAvailableGPUDevice(long hostId, String vgpuType) { - if (vgpuType == null) { - vgpuType = vGPUType.passthrough.getType(); - } + public boolean isHostGpuEnabled(long hostId) { + SearchCriteria sc = _gpuAvailability.create(); + sc.setParameters("hostId", hostId); + return _hostGpuGroupsDao.customSearch(sc, null).size() > 0 ? true : false; + } + + @Override + public List listAvailableGPUDevice(long hostId, String groupName, String vgpuType) { Filter searchFilter = new Filter(VGPUTypesVO.class, "remainingCapacity", false, null, null); SearchCriteria sc = _gpuAvailability.create(); sc.setParameters("hostId", hostId); + sc.setParameters("groupName", groupName); sc.setJoinParameters("groupId", "vgpuType", vgpuType); sc.setJoinParameters("groupId", "remainingCapacity", 0); return _hostGpuGroupsDao.customSearch(sc, searchFilter); } @Override - public boolean isGPUDeviceAvailable(long hostId, String vgpuType) { - if(!listAvailableGPUDevice(hostId, vgpuType).isEmpty()) { + public boolean isGPUDeviceAvailable(long hostId, String groupName, String vgpuType) { + if(!listAvailableGPUDevice(hostId, groupName, vgpuType).isEmpty()) { return true; } else { if (s_logger.isDebugEnabled()) { @@ -2526,13 +2532,13 @@ public boolean isGPUDeviceAvailable(long hostId, String vgpuType) { } @Override - public GPUDeviceTO getGPUDevice(long hostId, String vgpuType) { - HostGpuGroupsVO gpuDevice = listAvailableGPUDevice(hostId, vgpuType).get(0); + public GPUDeviceTO getGPUDevice(long hostId, String groupName, String vgpuType) { + HostGpuGroupsVO gpuDevice = listAvailableGPUDevice(hostId, groupName, vgpuType).get(0); return new GPUDeviceTO(gpuDevice.getGroupName(), vgpuType, null); } @Override - public void updateGPUDetails(long hostId, HashMap> groupDetails) { + public void updateGPUDetails(long hostId, HashMap> groupDetails) { // Update GPU group capacity TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); @@ -2542,7 +2548,7 @@ public void updateGPUDetails(long hostId, HashMap> } @Override - public HashMap> getGPUStatistics(HostVO host) { + public HashMap> getGPUStatistics(HostVO host) { Answer answer = _agentMgr.easySend(host.getId(), new GetGPUStatsCommand(host.getGuid(), host.getName())); if (answer != null && (answer instanceof UnsupportedAnswer)) { return null; diff --git a/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java b/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java index 74cfc31e74..b6977c2808 100755 --- a/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java +++ b/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java @@ -325,6 +325,9 @@ public long findCorrectResourceLimitForAccount(long accountId, Long limit, Resou } Account account = _accountDao.findById(accountId); + if (account == null) { + return max; + } // Check if limit is configured for account if (limit != null) { @@ -458,7 +461,7 @@ public List searchForLimits(Long id, Long accountId, Long domai List limits = new ArrayList(); boolean isAccount = true; - if (!_accountMgr.isAdmin(caller.getType())) { + if (!_accountMgr.isAdmin(caller.getId())) { accountId = caller.getId(); domainId = null; } else { @@ -633,6 +636,9 @@ public ResourceLimitVO updateResourceLimit(Long accountId, Long domainId, Intege if (accountId != null) { Account account = _entityMgr.findById(Account.class, accountId); + if (account == null) { + throw new InvalidParameterValueException("Unable to find account " + accountId); + } if (account.getId() == Account.ACCOUNT_ID_SYSTEM) { throw new InvalidParameterValueException("Can't update system account"); } diff --git a/server/src/com/cloud/server/ConfigurationServerImpl.java b/server/src/com/cloud/server/ConfigurationServerImpl.java index b8da4c8831..ac0fe5e12c 100755 --- a/server/src/com/cloud/server/ConfigurationServerImpl.java +++ b/server/src/com/cloud/server/ConfigurationServerImpl.java @@ -211,8 +211,8 @@ public void persistDefaultValues() throws InternalErrorException { _configDao.update(Config.UseSecondaryStorageVm.key(), Config.UseSecondaryStorageVm.getCategory(), "true"); s_logger.debug("ConfigurationServer made secondary storage vm required."); - _configDao.update(Config.SecStorageEncryptCopy.key(), Config.SecStorageEncryptCopy.getCategory(), "true"); - s_logger.debug("ConfigurationServer made secondary storage copy encrypted."); + _configDao.update(Config.SecStorageEncryptCopy.key(), Config.SecStorageEncryptCopy.getCategory(), "false"); + s_logger.debug("ConfigurationServer made secondary storage copy encrypt set to false."); _configDao.update("secstorage.secure.copy.cert", "realhostip"); s_logger.debug("ConfigurationServer made secondary storage copy use realhostip."); @@ -1153,9 +1153,9 @@ public void doInTransactionWithoutResult(TransactionStatus status) { // Offering #5 NetworkOfferingVO defaultNetscalerNetworkOffering = - new NetworkOfferingVO(NetworkOffering.DefaultSharedEIPandELBNetworkOffering, - "Offering for Shared networks with Elastic IP and Elastic LB capabilities", TrafficType.Guest, false, true, null, null, true, - Availability.Optional, null, Network.GuestType.Shared, true, false, false, false, true, true, true, false, false, true, true, false, false); + new NetworkOfferingVO(NetworkOffering.DefaultSharedEIPandELBNetworkOffering, + "Offering for Shared networks with Elastic IP and Elastic LB capabilities", TrafficType.Guest, false, true, null, null, true, + Availability.Optional, null, Network.GuestType.Shared, true, false, false, false, true, true, true, false, false, true, true, false, false, false); defaultNetscalerNetworkOffering.setState(NetworkOffering.State.Enabled); defaultNetscalerNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(defaultNetscalerNetworkOffering); diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index 073cf47a90..da72711b34 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -16,13 +16,10 @@ // under the License. package com.cloud.server; -import java.io.UnsupportedEncodingException; import java.lang.reflect.Field; -import java.net.URLDecoder; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; -import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.Date; @@ -40,6 +37,7 @@ import javax.inject.Inject; import javax.naming.ConfigurationException; +import org.apache.cloudstack.api.command.user.snapshot.UpdateSnapshotPolicyCmd; import org.apache.commons.codec.binary.Base64; import org.apache.log4j.Logger; @@ -51,8 +49,12 @@ import org.apache.cloudstack.api.command.admin.account.DeleteAccountCmd; import org.apache.cloudstack.api.command.admin.account.DisableAccountCmd; 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.AssociateIPAddrCmdByAdmin; +import org.apache.cloudstack.api.command.admin.address.ListPublicIpAddressesCmdByAdmin; +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; import org.apache.cloudstack.api.command.admin.autoscale.DeleteCounterCmd; @@ -94,8 +96,16 @@ import org.apache.cloudstack.api.command.admin.internallb.ListInternalLoadBalancerElementsCmd; import org.apache.cloudstack.api.command.admin.internallb.StartInternalLBVMCmd; import org.apache.cloudstack.api.command.admin.internallb.StopInternalLBVMCmd; +import org.apache.cloudstack.api.command.admin.iso.AttachIsoCmdByAdmin; +import org.apache.cloudstack.api.command.admin.iso.CopyIsoCmdByAdmin; +import org.apache.cloudstack.api.command.admin.iso.DetachIsoCmdByAdmin; +import org.apache.cloudstack.api.command.admin.iso.ListIsoPermissionsCmdByAdmin; +import org.apache.cloudstack.api.command.admin.iso.ListIsosCmdByAdmin; +import org.apache.cloudstack.api.command.admin.iso.RegisterIsoCmdByAdmin; +import org.apache.cloudstack.api.command.admin.loadbalancer.ListLoadBalancerRuleInstancesCmdByAdmin; import org.apache.cloudstack.api.command.admin.network.AddNetworkDeviceCmd; import org.apache.cloudstack.api.command.admin.network.AddNetworkServiceProviderCmd; +import org.apache.cloudstack.api.command.admin.network.CreateNetworkCmdByAdmin; import org.apache.cloudstack.api.command.admin.network.CreateNetworkOfferingCmd; import org.apache.cloudstack.api.command.admin.network.CreatePhysicalNetworkCmd; import org.apache.cloudstack.api.command.admin.network.CreateStorageNetworkIpRangeCmd; @@ -109,10 +119,12 @@ import org.apache.cloudstack.api.command.admin.network.ListNetworkDeviceCmd; import org.apache.cloudstack.api.command.admin.network.ListNetworkIsolationMethodsCmd; import org.apache.cloudstack.api.command.admin.network.ListNetworkServiceProvidersCmd; +import org.apache.cloudstack.api.command.admin.network.ListNetworksCmdByAdmin; import org.apache.cloudstack.api.command.admin.network.ListPhysicalNetworksCmd; import org.apache.cloudstack.api.command.admin.network.ListStorageNetworkIpRangeCmd; import org.apache.cloudstack.api.command.admin.network.ListSupportedNetworkServicesCmd; import org.apache.cloudstack.api.command.admin.network.ReleaseDedicatedGuestVlanRangeCmd; +import org.apache.cloudstack.api.command.admin.network.UpdateNetworkCmdByAdmin; import org.apache.cloudstack.api.command.admin.network.UpdateNetworkOfferingCmd; import org.apache.cloudstack.api.command.admin.network.UpdateNetworkServiceProviderCmd; import org.apache.cloudstack.api.command.admin.network.UpdatePhysicalNetworkCmd; @@ -178,7 +190,12 @@ import org.apache.cloudstack.api.command.admin.systemvm.StartSystemVMCmd; import org.apache.cloudstack.api.command.admin.systemvm.StopSystemVmCmd; import org.apache.cloudstack.api.command.admin.systemvm.UpgradeSystemVMCmd; +import org.apache.cloudstack.api.command.admin.template.CopyTemplateCmdByAdmin; +import org.apache.cloudstack.api.command.admin.template.CreateTemplateCmdByAdmin; +import org.apache.cloudstack.api.command.admin.template.ListTemplatePermissionsCmdByAdmin; +import org.apache.cloudstack.api.command.admin.template.ListTemplatesCmdByAdmin; import org.apache.cloudstack.api.command.admin.template.PrepareTemplateCmd; +import org.apache.cloudstack.api.command.admin.template.RegisterTemplateCmdByAdmin; import org.apache.cloudstack.api.command.admin.usage.AddTrafficMonitorCmd; import org.apache.cloudstack.api.command.admin.usage.AddTrafficTypeCmd; import org.apache.cloudstack.api.command.admin.usage.DeleteTrafficMonitorCmd; @@ -204,20 +221,47 @@ import org.apache.cloudstack.api.command.admin.vlan.DeleteVlanIpRangeCmd; import org.apache.cloudstack.api.command.admin.vlan.ListVlanIpRangesCmd; import org.apache.cloudstack.api.command.admin.vlan.ReleasePublicIpRangeCmd; +import org.apache.cloudstack.api.command.admin.vm.AddNicToVMCmdByAdmin; import org.apache.cloudstack.api.command.admin.vm.AssignVMCmd; +import org.apache.cloudstack.api.command.admin.vm.DeployVMCmdByAdmin; +import org.apache.cloudstack.api.command.admin.vm.DestroyVMCmdByAdmin; import org.apache.cloudstack.api.command.admin.vm.ExpungeVMCmd; import org.apache.cloudstack.api.command.admin.vm.GetVMUserDataCmd; import org.apache.cloudstack.api.command.admin.vm.ListVMsCmdByAdmin; import org.apache.cloudstack.api.command.admin.vm.MigrateVMCmd; import org.apache.cloudstack.api.command.admin.vm.MigrateVirtualMachineWithVolumeCmd; +import org.apache.cloudstack.api.command.admin.vm.RebootVMCmdByAdmin; import org.apache.cloudstack.api.command.admin.vm.RecoverVMCmd; +import org.apache.cloudstack.api.command.admin.vm.RemoveNicFromVMCmdByAdmin; +import org.apache.cloudstack.api.command.admin.vm.ResetVMPasswordCmdByAdmin; +import org.apache.cloudstack.api.command.admin.vm.ResetVMSSHKeyCmdByAdmin; +import org.apache.cloudstack.api.command.admin.vm.RestoreVMCmdByAdmin; +import org.apache.cloudstack.api.command.admin.vm.ScaleVMCmdByAdmin; +import org.apache.cloudstack.api.command.admin.vm.StartVMCmdByAdmin; +import org.apache.cloudstack.api.command.admin.vm.StopVMCmdByAdmin; +import org.apache.cloudstack.api.command.admin.vm.UpdateDefaultNicForVMCmdByAdmin; +import org.apache.cloudstack.api.command.admin.vm.UpdateVMCmdByAdmin; +import org.apache.cloudstack.api.command.admin.vm.UpgradeVMCmdByAdmin; +import org.apache.cloudstack.api.command.admin.vmsnapshot.RevertToVMSnapshotCmdByAdmin; +import org.apache.cloudstack.api.command.admin.volume.AttachVolumeCmdByAdmin; +import org.apache.cloudstack.api.command.admin.volume.CreateVolumeCmdByAdmin; +import org.apache.cloudstack.api.command.admin.volume.DetachVolumeCmdByAdmin; +import org.apache.cloudstack.api.command.admin.volume.ListVolumesCmdByAdmin; +import org.apache.cloudstack.api.command.admin.volume.MigrateVolumeCmdByAdmin; +import org.apache.cloudstack.api.command.admin.volume.ResizeVolumeCmdByAdmin; +import org.apache.cloudstack.api.command.admin.volume.UpdateVolumeCmdByAdmin; +import org.apache.cloudstack.api.command.admin.volume.UploadVolumeCmdByAdmin; import org.apache.cloudstack.api.command.admin.vpc.CreatePrivateGatewayCmd; +import org.apache.cloudstack.api.command.admin.vpc.CreateVPCCmdByAdmin; import org.apache.cloudstack.api.command.admin.vpc.CreateVPCOfferingCmd; import org.apache.cloudstack.api.command.admin.vpc.DeletePrivateGatewayCmd; import org.apache.cloudstack.api.command.admin.vpc.DeleteVPCOfferingCmd; +import org.apache.cloudstack.api.command.admin.vpc.ListVPCsCmdByAdmin; +import org.apache.cloudstack.api.command.admin.vpc.UpdateVPCCmdByAdmin; import org.apache.cloudstack.api.command.admin.vpc.UpdateVPCOfferingCmd; import org.apache.cloudstack.api.command.admin.zone.CreateZoneCmd; import org.apache.cloudstack.api.command.admin.zone.DeleteZoneCmd; +import org.apache.cloudstack.api.command.admin.zone.ListZonesCmdByAdmin; import org.apache.cloudstack.api.command.admin.zone.MarkDefaultZoneForAccountCmd; import org.apache.cloudstack.api.command.admin.zone.UpdateZoneCmd; import org.apache.cloudstack.api.command.user.account.AddAccountToProjectCmd; @@ -302,6 +346,8 @@ import org.apache.cloudstack.api.command.user.loadbalancer.RemoveCertFromLoadBalancerCmd; import org.apache.cloudstack.api.command.user.loadbalancer.RemoveFromLoadBalancerRuleCmd; import org.apache.cloudstack.api.command.user.loadbalancer.UpdateApplicationLoadBalancerCmd; +import org.apache.cloudstack.api.command.user.loadbalancer.UpdateLBHealthCheckPolicyCmd; +import org.apache.cloudstack.api.command.user.loadbalancer.UpdateLBStickinessPolicyCmd; import org.apache.cloudstack.api.command.user.loadbalancer.UpdateLoadBalancerRuleCmd; import org.apache.cloudstack.api.command.user.loadbalancer.UploadSslCertCmd; import org.apache.cloudstack.api.command.user.nat.CreateIpForwardingRuleCmd; @@ -849,7 +895,8 @@ protected Map getConfigs() { @Override public String generateRandomPassword() { - return PasswordGenerator.generateRandomPassword(6); + Integer passwordLength = Integer.parseInt(_configDao.getValue("vm.password.length")); + return PasswordGenerator.generateRandomPassword(passwordLength); } @Override @@ -1126,29 +1173,28 @@ public Ternary, Integer>, List, Map allHosts = null; Map requiresStorageMotion = new HashMap(); DataCenterDeployment plan = null; - boolean zoneWideStoragePool = false; + if (canMigrateWithStorage) { - allHostsPair = searchForServers(startIndex, pageSize, null, hostType, null, srcHost.getDataCenterId(), null, null, null, null, null, null, srcHost.getHypervisorType(), - srcHost.getHypervisorVersion()); + allHostsPair = searchForServers(startIndex, pageSize, null, hostType, null, srcHost.getDataCenterId(), null, null, null, null, null, null, + srcHost.getHypervisorType(), srcHost.getHypervisorVersion()); allHosts = allHostsPair.first(); allHosts.remove(srcHost); - - // Check if the host has storage pools for all the volumes of the vm to be migrated. - for (Iterator iterator = allHosts.iterator(); iterator.hasNext();) { - Host host = iterator.next(); - Map> volumePools = findSuitablePoolsForVolumes(vmProfile, host); - if (volumePools.isEmpty()) { - iterator.remove(); - } else { - if (srcHost.getHypervisorType() == HypervisorType.VMware || srcHost.getHypervisorType() == HypervisorType.KVM) { - zoneWideStoragePool = checkForZoneWideStoragePool(volumePools); - } - if ((!host.getClusterId().equals(srcHost.getClusterId()) || usesLocal) && !zoneWideStoragePool) { - requiresStorageMotion.put(host, true); + for (VolumeVO volume : volumes) { + Long volClusterId = _poolDao.findById(volume.getPoolId()).getClusterId(); + // only check for volume which are not in zone wide primary store, as only those may require storage motion + if (volClusterId != null) { + for (Iterator iterator = allHosts.iterator(); iterator.hasNext();) { + Host host = iterator.next(); + if (!host.getClusterId().equals(volClusterId) || usesLocal) { + if (hasSuitablePoolsForVolume(volume, host, vmProfile)) { + requiresStorageMotion.put(host, true); + } else { + iterator.remove(); + } + } } } } - plan = new DataCenterDeployment(srcHost.getDataCenterId(), null, null, null, null, null); } else { Long cluster = srcHost.getClusterId(); @@ -1199,50 +1245,20 @@ public Ternary, Integer>, List, Map, Integer>, List, Map>(otherHosts, suitableHosts, requiresStorageMotion); } - private boolean checkForZoneWideStoragePool(Map> volumePools) { - boolean zoneWideStoragePool = false; - Collection> pools = volumePools.values(); - List aggregatePoolList = new ArrayList(); - for (Iterator> volumePoolsIter = pools.iterator(); volumePoolsIter.hasNext();) { - aggregatePoolList.addAll(volumePoolsIter.next()); - } - for (StoragePool pool : aggregatePoolList) { - if (null == pool.getClusterId()) { - zoneWideStoragePool = true; - break; - } - } - return zoneWideStoragePool; - } - - private Map> findSuitablePoolsForVolumes(VirtualMachineProfile vmProfile, Host host) { - List volumes = _volumeDao.findCreatedByInstance(vmProfile.getId()); - Map> suitableVolumeStoragePools = new HashMap>(); - - // For each volume find list of suitable storage pools by calling the allocators - for (VolumeVO volume : volumes) { - DiskOfferingVO diskOffering = _diskOfferingDao.findById(volume.getDiskOfferingId()); - DiskProfile diskProfile = new DiskProfile(volume, diskOffering, vmProfile.getHypervisorType()); - DataCenterDeployment plan = new DataCenterDeployment(host.getDataCenterId(), host.getPodId(), host.getClusterId(), host.getId(), null, null); - ExcludeList avoid = new ExcludeList(); - - boolean foundPools = false; - for (StoragePoolAllocator allocator : _storagePoolAllocators) { - List poolList = allocator.allocateToPool(diskProfile, vmProfile, plan, avoid, StoragePoolAllocator.RETURN_UPTO_ALL); - if (poolList != null && !poolList.isEmpty()) { - suitableVolumeStoragePools.put(volume, poolList); - foundPools = true; - break; - } - } + private boolean hasSuitablePoolsForVolume(VolumeVO volume, Host host, VirtualMachineProfile vmProfile) { + DiskOfferingVO diskOffering = _diskOfferingDao.findById(volume.getDiskOfferingId()); + DiskProfile diskProfile = new DiskProfile(volume, diskOffering, vmProfile.getHypervisorType()); + DataCenterDeployment plan = new DataCenterDeployment(host.getDataCenterId(), host.getPodId(), host.getClusterId(), host.getId(), null, null); + ExcludeList avoid = new ExcludeList(); - if (!foundPools) { - suitableVolumeStoragePools.clear(); - break; + for (StoragePoolAllocator allocator : _storagePoolAllocators) { + List poolList = allocator.allocateToPool(diskProfile, vmProfile, plan, avoid, 1); + if (poolList != null && !poolList.isEmpty()) { + return true; } } - return suitableVolumeStoragePools; + return false; } @Override @@ -1723,22 +1739,19 @@ public Pair, Integer> searchForIPAddresses(ListPublicI SearchBuilder sb = _publicIpAddressDao.createSearchBuilder(); Long domainId = null; Boolean isRecursive = null; - List permittedDomains = new ArrayList(); List permittedAccounts = new ArrayList(); - List permittedResources = new ArrayList(); - ListProjectResourcesCriteria listProjectResourcesCriteria = null; if (isAllocated) { Account caller = CallContext.current().getCallingAccount(); Ternary domainIdRecursiveListProject = new Ternary( cmd.getDomainId(), cmd.isRecursive(), null); - _accountMgr.buildACLSearchParameters(caller, cmd.getId(), cmd.getAccountName(), cmd.getProjectId(), permittedDomains, permittedAccounts, permittedResources, - domainIdRecursiveListProject, cmd.listAll(), false, "listPublicIpAddresses"); - //domainId = domainIdRecursiveListProject.first(); + _accountMgr.buildACLSearchParameters(caller, cmd.getId(), cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, + domainIdRecursiveListProject, cmd.listAll(), false); + domainId = domainIdRecursiveListProject.first(); isRecursive = domainIdRecursiveListProject.second(); listProjectResourcesCriteria = domainIdRecursiveListProject.third(); - _accountMgr.buildACLSearchBuilder(sb, isRecursive, permittedDomains, permittedAccounts, permittedResources, listProjectResourcesCriteria); + _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); } sb.and("dataCenterId", sb.entity().getDataCenterId(), SearchCriteria.Op.EQ); @@ -1793,7 +1806,7 @@ public Pair, Integer> searchForIPAddresses(ListPublicI SearchCriteria sc = sb.create(); if (isAllocated) { - _accountMgr.buildACLSearchCriteria(sc, isRecursive, permittedDomains, permittedAccounts, permittedResources, listProjectResourcesCriteria); + _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); } sc.setJoinParameters("vlanSearch", "vlanType", vlanType); @@ -1984,7 +1997,7 @@ else if (osStdName != null) { throw new InvalidParameterValueException("Unable to find the guest OS by name or UUID"); } //check for duplicates - GuestOSHypervisorVO duplicate = _guestOSHypervisorDao.findByOsIdAndHypervisor(osTypeId.longValue(), hypervisorType.toString(), hypervisorVersion); + GuestOSHypervisorVO duplicate = _guestOSHypervisorDao.findByOsIdAndHypervisorAndUserDefined(guestOs.getId(), hypervisorType.toString(), hypervisorVersion, true); if (duplicate != null) { throw new InvalidParameterValueException("Mapping from hypervisor : " + hypervisorType.toString() + ", version : " + hypervisorVersion + " and guest OS : " @@ -1995,6 +2008,7 @@ else if (osStdName != null) { guestOsMapping.setGuestOsName(osNameForHypervisor); guestOsMapping.setHypervisorType(hypervisorType.toString()); guestOsMapping.setHypervisorVersion(hypervisorVersion); + guestOsMapping.setIsUserDefined(true); return _guestOSHypervisorDao.persist(guestOsMapping); } @@ -2027,6 +2041,7 @@ public GuestOS addGuestOs(AddGuestOsCmd cmd) { guestOsVo.setCategoryId(categoryId.longValue()); guestOsVo.setDisplayName(displayName); guestOsVo.setName(name); + guestOsVo.setIsUserDefined(true); return _guestOSDao.persist(guestOsVo); } @@ -2049,6 +2064,10 @@ public GuestOS updateGuestOs(UpdateGuestOsCmd cmd) { throw new InvalidParameterValueException("Guest OS not found. Please specify a valid ID for the Guest OS"); } + if (!guestOsHandle.getIsUserDefined()) { + throw new InvalidParameterValueException("Unable to modify system defined guest OS"); + } + //Check if update is needed if (displayName.equals(guestOsHandle.getDisplayName())) { return guestOsHandle; @@ -2080,6 +2099,10 @@ public boolean removeGuestOs(RemoveGuestOsCmd cmd) { throw new InvalidParameterValueException("Guest OS not found. Please specify a valid ID for the Guest OS"); } + if (!guestOs.getIsUserDefined()) { + throw new InvalidParameterValueException("Unable to remove system defined guest OS"); + } + return _guestOSDao.remove(id); } @@ -2096,6 +2119,10 @@ public GuestOSHypervisor updateGuestOsMapping(UpdateGuestOsMappingCmd cmd) { throw new InvalidParameterValueException("Guest OS Mapping not found. Please specify a valid ID for the Guest OS Mapping"); } + if (!guestOsHypervisorHandle.getIsUserDefined()) { + throw new InvalidParameterValueException("Unable to modify system defined Guest OS mapping"); + } + GuestOSHypervisorVO guestOsHypervisor = _guestOSHypervisorDao.createForUpdate(id); guestOsHypervisor.setGuestOsName(osNameForHypervisor); if (_guestOSHypervisorDao.update(id, guestOsHypervisor)) { @@ -2117,6 +2144,10 @@ public boolean removeGuestOsMapping(RemoveGuestOsMappingCmd cmd) { throw new InvalidParameterValueException("Guest OS Mapping not found. Please specify a valid ID for the Guest OS Mapping"); } + if (!guestOsHypervisorHandle.getIsUserDefined()) { + throw new InvalidParameterValueException("Unable to remove system defined Guest OS mapping"); + } + return _guestOSHypervisorDao.removeGuestOsMapping(id); } @@ -2710,6 +2741,7 @@ public List> getCommands() { cmdList.add(ListIpForwardingRulesCmd.class); cmdList.add(CreateNetworkACLCmd.class); cmdList.add(CreateNetworkCmd.class); + cmdList.add(CreateNetworkCmdByAdmin.class); cmdList.add(DeleteNetworkACLCmd.class); cmdList.add(DeleteNetworkCmd.class); cmdList.add(ListNetworkACLsCmd.class); @@ -2742,8 +2774,9 @@ public List> getCommands() { cmdList.add(RevokeSecurityGroupEgressCmd.class); cmdList.add(RevokeSecurityGroupIngressCmd.class); cmdList.add(CreateSnapshotCmd.class); - cmdList.add(CreateSnapshotPolicyCmd.class); cmdList.add(DeleteSnapshotCmd.class); + cmdList.add(CreateSnapshotPolicyCmd.class); + cmdList.add(UpdateSnapshotPolicyCmd.class); cmdList.add(DeleteSnapshotPoliciesCmd.class); cmdList.add(ListSnapshotPoliciesCmd.class); cmdList.add(ListSnapshotsCmd.class); @@ -2770,7 +2803,6 @@ public List> getCommands() { cmdList.add(ExpungeVMCmd.class); cmdList.add(GetVMPasswordCmd.class); cmdList.add(ListVMsCmd.class); - cmdList.add(ListVMsCmdByAdmin.class); cmdList.add(ScaleVMCmd.class); cmdList.add(RebootVMCmd.class); cmdList.add(RemoveNicFromVMCmd.class); @@ -2898,6 +2930,57 @@ public List> getCommands() { cmdList.add(UpdateRemoteAccessVpnCmd.class); cmdList.add(UpdateVpnConnectionCmd.class); cmdList.add(UpdateVpnGatewayCmd.class); + // separated admin commands + cmdList.add(ListAccountsCmdByAdmin.class); + cmdList.add(ListZonesCmdByAdmin.class); + cmdList.add(ListTemplatesCmdByAdmin.class); + cmdList.add(CreateTemplateCmdByAdmin.class); + cmdList.add(CopyTemplateCmdByAdmin.class); + cmdList.add(RegisterTemplateCmdByAdmin.class); + cmdList.add(ListTemplatePermissionsCmdByAdmin.class); + cmdList.add(RegisterIsoCmdByAdmin.class); + cmdList.add(CopyIsoCmdByAdmin.class); + cmdList.add(ListIsosCmdByAdmin.class); + cmdList.add(AttachIsoCmdByAdmin.class); + cmdList.add(DetachIsoCmdByAdmin.class); + cmdList.add(ListIsoPermissionsCmdByAdmin.class); + cmdList.add(UpdateVMAffinityGroupCmdByAdmin.class); + cmdList.add(AddNicToVMCmdByAdmin.class); + cmdList.add(RemoveNicFromVMCmdByAdmin.class); + cmdList.add(UpdateDefaultNicForVMCmdByAdmin.class); + cmdList.add(ListLoadBalancerRuleInstancesCmdByAdmin.class); + cmdList.add(DeployVMCmdByAdmin.class); + cmdList.add(DestroyVMCmdByAdmin.class); + cmdList.add(RebootVMCmdByAdmin.class); + cmdList.add(ResetVMPasswordCmdByAdmin.class); + cmdList.add(ResetVMSSHKeyCmdByAdmin.class); + cmdList.add(RestoreVMCmdByAdmin.class); + cmdList.add(ScaleVMCmdByAdmin.class); + cmdList.add(StartVMCmdByAdmin.class); + cmdList.add(StopVMCmdByAdmin.class); + cmdList.add(UpdateVMCmdByAdmin.class); + cmdList.add(UpgradeVMCmdByAdmin.class); + cmdList.add(RevertToVMSnapshotCmdByAdmin.class); + cmdList.add(ListVMsCmdByAdmin.class); + cmdList.add(AttachVolumeCmdByAdmin.class); + cmdList.add(CreateVolumeCmdByAdmin.class); + cmdList.add(DetachVolumeCmdByAdmin.class); + cmdList.add(MigrateVolumeCmdByAdmin.class); + cmdList.add(ResizeVolumeCmdByAdmin.class); + cmdList.add(UpdateVolumeCmdByAdmin.class); + cmdList.add(UploadVolumeCmdByAdmin.class); + cmdList.add(ListVolumesCmdByAdmin.class); + cmdList.add(AssociateIPAddrCmdByAdmin.class); + cmdList.add(ListPublicIpAddressesCmdByAdmin.class); + cmdList.add(CreateNetworkCmdByAdmin.class); + cmdList.add(UpdateNetworkCmdByAdmin.class); + cmdList.add(ListNetworksCmdByAdmin.class); + cmdList.add(CreateVPCCmdByAdmin.class); + cmdList.add(ListVPCsCmdByAdmin.class); + cmdList.add(UpdateVPCCmdByAdmin.class); + cmdList.add(UpdateLBStickinessPolicyCmd.class); + cmdList.add(UpdateLBHealthCheckPolicyCmd.class); + return cmdList; } @@ -3248,6 +3331,7 @@ public Map listCapabilities(ListCapabilitiesCmd cmd) { } } + long diskOffMinSize = VolumeOrchestrationService.CustomDiskOfferingMinSize.value(); long diskOffMaxSize = VolumeOrchestrationService.CustomDiskOfferingMaxSize.value(); KVMSnapshotEnabled = Boolean.parseBoolean(_configDao.getValue("KVM.snapshot.enabled")); @@ -3271,6 +3355,7 @@ public Map listCapabilities(ListCapabilitiesCmd cmd) { capabilities.put("supportELB", supportELB); capabilities.put("projectInviteRequired", _projectMgr.projectInviteRequired()); capabilities.put("allowusercreateprojects", _projectMgr.allowUserToCreateProject()); + capabilities.put("customDiskOffMinSize", diskOffMinSize); capabilities.put("customDiskOffMaxSize", diskOffMaxSize); capabilities.put("regionSecondaryEnabled", regionSecondaryEnabled); capabilities.put("KVMSnapshotEnabled", KVMSnapshotEnabled); @@ -3352,16 +3437,6 @@ public String uploadCertificate(UploadCustomCertificateCmd cmd) { String certificate = cmd.getCertificate(); String key = cmd.getPrivateKey(); - try { - if (certificate != null) { - certificate = URLDecoder.decode(certificate, "UTF-8"); - } - if (key != null) { - key = URLDecoder.decode(key, "UTF-8"); - } - } catch (UnsupportedEncodingException e) { - } finally { - } if (cmd.getPrivateKey() != null && !_ksMgr.validateCertificate(certificate, key, cmd.getDomainSuffix())) { throw new InvalidParameterValueException("Failed to pass certificate validation check"); @@ -3369,16 +3444,20 @@ public String uploadCertificate(UploadCustomCertificateCmd cmd) { if (cmd.getPrivateKey() != null) { _ksMgr.saveCertificate(ConsoleProxyManager.CERTIFICATE_NAME, certificate, key, cmd.getDomainSuffix()); + + // Reboot ssvm here since private key is present - meaning server cert being passed + List alreadyRunning = _secStorageVmDao.getSecStorageVmListInStates(null, State.Running, State.Migrating, State.Starting); + for (SecondaryStorageVmVO ssVmVm : alreadyRunning) { + _secStorageVmMgr.rebootSecStorageVm(ssVmVm.getId()); + } } else { _ksMgr.saveCertificate(cmd.getAlias(), certificate, cmd.getCertIndex(), cmd.getDomainSuffix()); } _consoleProxyMgr.setManagementState(ConsoleProxyManagementState.ResetSuspending); - List alreadyRunning = _secStorageVmDao.getSecStorageVmListInStates(null, State.Running, State.Migrating, State.Starting); - for (SecondaryStorageVmVO ssVmVm : alreadyRunning) { - _secStorageVmMgr.rebootSecStorageVm(ssVmVm.getId()); - } - return "Certificate has been updated, we will stop all running console proxy VMs and secondary storage VMs to propagate the new certificate, please give a few minutes for console access service to be up again"; + return "Certificate has been successfully updated, if its the server certificate we would reboot all " + + "running console proxy VMs and secondary storage VMs to propagate the new certificate, " + + "please give a few minutes for console access and storage services service to be up and working again"; } @Override @@ -3471,22 +3550,21 @@ public Pair, Integer> listSSHKeyPairs(ListSSHKeyPairs String fingerPrint = cmd.getFingerprint(); Account caller = CallContext.current().getCallingAccount(); - List permittedDomains = new ArrayList(); List permittedAccounts = new ArrayList(); - List permittedResources = new ArrayList(); Ternary domainIdRecursiveListProject = new Ternary( cmd.getDomainId(), cmd.isRecursive(), null); - _accountMgr.buildACLSearchParameters(caller, null, cmd.getAccountName(), cmd.getProjectId(), permittedDomains, permittedAccounts, permittedResources, - domainIdRecursiveListProject, cmd.listAll(), false, "listSSHKeyPairs"); + _accountMgr.buildACLSearchParameters(caller, null, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, + cmd.listAll(), false); + Long domainId = domainIdRecursiveListProject.first(); Boolean isRecursive = domainIdRecursiveListProject.second(); ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third(); SearchBuilder sb = _sshKeyPairDao.createSearchBuilder(); - _accountMgr.buildACLSearchBuilder(sb, isRecursive, permittedDomains, permittedAccounts, permittedResources, listProjectResourcesCriteria); + _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); Filter searchFilter = new Filter(SSHKeyPairVO.class, "id", false, cmd.getStartIndex(), cmd.getPageSizeVal()); SearchCriteria sc = sb.create(); - _accountMgr.buildACLSearchCriteria(sc, isRecursive, permittedDomains, permittedAccounts, permittedResources, listProjectResourcesCriteria); + _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); if (name != null) { sc.addAnd("name", SearchCriteria.Op.EQ, name); diff --git a/server/src/com/cloud/server/StatsCollector.java b/server/src/com/cloud/server/StatsCollector.java index 50aa93cd5e..29ace93202 100755 --- a/server/src/com/cloud/server/StatsCollector.java +++ b/server/src/com/cloud/server/StatsCollector.java @@ -49,6 +49,7 @@ import com.cloud.agent.api.GetStorageStatsCommand; 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.VmStatsEntry; import com.cloud.cluster.ManagementServerHostVO; @@ -342,7 +343,7 @@ protected void runInContext() { gpuEnabledHosts = hosts; } for (HostVO host : gpuEnabledHosts) { - HashMap> groupDetails = _resourceMgr.getGPUStatistics(host); + HashMap> groupDetails = _resourceMgr.getGPUStatistics(host); if (groupDetails != null) { _resourceMgr.updateGPUDetails(host.getId(), groupDetails); } diff --git a/server/src/com/cloud/storage/StorageManager.java b/server/src/com/cloud/storage/StorageManager.java index c8a7051e34..eebbf7fa12 100755 --- a/server/src/com/cloud/storage/StorageManager.java +++ b/server/src/com/cloud/storage/StorageManager.java @@ -114,4 +114,6 @@ public interface StorageManager extends StorageService { Long getDiskIopsReadRate(ServiceOfferingVO offering, DiskOfferingVO diskOffering); Long getDiskIopsWriteRate(ServiceOfferingVO offering, DiskOfferingVO diskOffering); + + void cleanupDownloadUrls(); } diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index 3b29b33624..a1f4cd68c3 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -41,6 +41,8 @@ import javax.inject.Inject; import javax.naming.ConfigurationException; +import com.cloud.utils.DateUtil; +import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -284,6 +286,8 @@ public void setDiscoverers(List discoverers) { boolean _templateCleanupEnabled = true; int _storageCleanupInterval; int _storagePoolAcquisitionWaitSeconds = 1800; // 30 minutes + int _downloadUrlCleanupInterval; + int _downloadUrlExpirationInterval; // protected BigDecimal _overProvisioningFactor = new BigDecimal(1); private long _serverId; @@ -455,6 +459,12 @@ public boolean configure(String name, Map params) throws Configu s_logger.info("Storage cleanup enabled: " + _storageCleanupEnabled + ", interval: " + _storageCleanupInterval + ", template cleanup enabled: " + _templateCleanupEnabled); + String cleanupInterval = configs.get("extract.url.cleanup.interval"); + _downloadUrlCleanupInterval = NumbersUtil.parseInt(cleanupInterval, 7200); + + String urlExpirationInterval = configs.get("extract.url.expiration.interval"); + _downloadUrlExpirationInterval = NumbersUtil.parseInt(urlExpirationInterval, 14400); + String workers = configs.get("expunge.workers"); int wrks = NumbersUtil.parseInt(workers, 10); _executor = Executors.newScheduledThreadPool(wrks, new NamedThreadFactory("StorageManager-Scavenger")); @@ -507,6 +517,9 @@ public boolean start() { } else { s_logger.debug("Storage cleanup is not enabled, so the storage cleanup thread is not being scheduled."); } + + _executor.scheduleWithFixedDelay(new DownloadURLGarbageCollector(), _downloadUrlCleanupInterval, _downloadUrlCleanupInterval, TimeUnit.SECONDS); + return true; } @@ -618,7 +631,7 @@ public PrimaryDataStoreInfo createPool(CreateStoragePoolCmd cmd) throws Resource } else { throw new InvalidParameterValueException("Missing parameter hypervisor. Hypervisor type is required to create zone wide primary storage."); } - if (hypervisorType != HypervisorType.KVM && hypervisorType != HypervisorType.VMware && hypervisorType != HypervisorType.Any) { + if (hypervisorType != HypervisorType.KVM && hypervisorType != HypervisorType.VMware && hypervisorType != HypervisorType.Hyperv && hypervisorType != HypervisorType.Any) { throw new InvalidParameterValueException("zone wide storage pool is not supported for hypervisor type " + hypervisor); } } @@ -1962,6 +1975,80 @@ public void doInTransactionWithoutResult(TransactionStatus status) { return true; } + protected class DownloadURLGarbageCollector implements Runnable { + + public DownloadURLGarbageCollector() { + } + + @Override + public void run() { + try { + s_logger.trace("Download URL Garbage Collection Thread is running."); + + cleanupDownloadUrls(); + + } catch (Exception e) { + s_logger.error("Caught the following Exception", e); + } + } + } + + @Override + public void cleanupDownloadUrls(){ + + // Cleanup expired volume URLs + List volumesOnImageStoreList = _volumeStoreDao.listVolumeDownloadUrls(); + for(VolumeDataStoreVO volumeOnImageStore : volumesOnImageStoreList){ + + try { + long downloadUrlCurrentAgeInSecs = DateUtil.getTimeDifference(DateUtil.now(), volumeOnImageStore.getExtractUrlCreated()); + if(downloadUrlCurrentAgeInSecs < _downloadUrlExpirationInterval){ // URL hasnt expired yet + continue; + } + + s_logger.debug("Removing download url " + volumeOnImageStore.getExtractUrl() + " for volume id " + volumeOnImageStore.getVolumeId()); + + // Remove it from image store + ImageStoreEntity secStore = (ImageStoreEntity) _dataStoreMgr.getDataStore(volumeOnImageStore.getDataStoreId(), DataStoreRole.Image); + secStore.deleteExtractUrl(volumeOnImageStore.getInstallPath(), volumeOnImageStore.getExtractUrl(), Upload.Type.VOLUME); + + // Now expunge it from DB since this entry was created only for download purpose + _volumeStoreDao.expunge(volumeOnImageStore.getId()); + }catch(Throwable th){ + s_logger.warn("Caught exception while deleting download url " +volumeOnImageStore.getExtractUrl() + + " for volume id " + volumeOnImageStore.getVolumeId(), th); + } + } + + // Cleanup expired template URLs + List templatesOnImageStoreList = _templateStoreDao.listTemplateDownloadUrls(); + for(TemplateDataStoreVO templateOnImageStore : templatesOnImageStoreList){ + + try { + long downloadUrlCurrentAgeInSecs = DateUtil.getTimeDifference(DateUtil.now(), templateOnImageStore.getExtractUrlCreated()); + if(downloadUrlCurrentAgeInSecs < _downloadUrlExpirationInterval){ // URL hasnt expired yet + continue; + } + + s_logger.debug("Removing download url " + templateOnImageStore.getExtractUrl() + " for template id " + templateOnImageStore.getTemplateId()); + + // Remove it from image store + ImageStoreEntity secStore = (ImageStoreEntity) _dataStoreMgr.getDataStore(templateOnImageStore.getDataStoreId(), DataStoreRole.Image); + secStore.deleteExtractUrl(templateOnImageStore.getInstallPath(), templateOnImageStore.getExtractUrl(), Upload.Type.TEMPLATE); + + // Now remove download details from DB. + templateOnImageStore.setExtractUrl(null); + templateOnImageStore.setExtractUrlCreated(null); + _templateStoreDao.update(templateOnImageStore.getId(), templateOnImageStore); + }catch(Throwable th){ + s_logger.warn("caught exception while deleting download url " +templateOnImageStore.getExtractUrl() + + " for template id " +templateOnImageStore.getTemplateId(), th); + } + } + + + } + // get bytesReadRate from service_offering, disk_offering and vm.disk.throttling.bytes_read_rate @Override public Long getDiskBytesReadRate(ServiceOfferingVO offering, DiskOfferingVO diskOffering) { diff --git a/server/src/com/cloud/storage/StoragePoolAutomationImpl.java b/server/src/com/cloud/storage/StoragePoolAutomationImpl.java index 8becd75ef2..8ff759df10 100644 --- a/server/src/com/cloud/storage/StoragePoolAutomationImpl.java +++ b/server/src/com/cloud/storage/StoragePoolAutomationImpl.java @@ -23,15 +23,14 @@ import javax.inject.Inject; -import org.apache.log4j.Logger; -import org.springframework.stereotype.Component; - import org.apache.cloudstack.context.CallContext; 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.DataStoreProviderManager; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; @@ -362,10 +361,16 @@ public boolean cancelMaintain(DataStore store) { // if the instance is of type user vm, call the user vm manager if (vmInstance.getType().equals(VirtualMachine.Type.User)) { UserVmVO userVm = userVmDao.findById(vmInstance.getId()); - - vmMgr.advanceStart(userVm.getUuid(), null, null); // update work queue - work.setStartedAfterMaintenance(true); - _storagePoolWorkDao.update(work.getId(), work); + // check if the vm has a root volume. If not, remove the item from the queue, the vm should be + // started only when it has at least one root volume attached to it + // don't allow to start vm that doesn't have a root volume + if (volumeDao.findByInstanceAndType(work.getId(), Volume.Type.ROOT).isEmpty()) { + _storagePoolWorkDao.remove(work.getId()); + } else { + vmMgr.advanceStart(userVm.getUuid(), null, null); + work.setStartedAfterMaintenance(true); + _storagePoolWorkDao.update(work.getId(), work); + } } return true; } catch (Exception e) { diff --git a/server/src/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/com/cloud/storage/VolumeApiServiceImpl.java index 30b5479b63..5c517f4fd3 100644 --- a/server/src/com/cloud/storage/VolumeApiServiceImpl.java +++ b/server/src/com/cloud/storage/VolumeApiServiceImpl.java @@ -26,6 +26,7 @@ import javax.inject.Inject; +import com.cloud.utils.DateUtil; import org.apache.log4j.Logger; import org.apache.cloudstack.api.command.user.volume.AttachVolumeCmd; @@ -253,12 +254,13 @@ public VolumeVO uploadVolume(UploadVolumeCmd cmd) throws ResourceAllocationExcep String volumeName = cmd.getVolumeName(); String url = cmd.getUrl(); String format = cmd.getFormat(); + Long diskOfferingId = cmd.getDiskOfferingId(); String imageStoreUuid = cmd.getImageStoreUuid(); DataStore store = _tmpltMgr.getImageStore(imageStoreUuid, zoneId); - validateVolume(caller, ownerId, zoneId, volumeName, url, format); + validateVolume(caller, ownerId, zoneId, volumeName, url, format, diskOfferingId); - VolumeVO volume = persistVolume(owner, zoneId, volumeName, url, cmd.getFormat()); + VolumeVO volume = persistVolume(owner, zoneId, volumeName, url, cmd.getFormat(), diskOfferingId); VolumeInfo vol = volFactory.getVolume(volume.getId()); @@ -269,13 +271,15 @@ public VolumeVO uploadVolume(UploadVolumeCmd cmd) throws ResourceAllocationExcep return volume; } - private boolean validateVolume(Account caller, long ownerId, Long zoneId, String volumeName, String url, String format) throws ResourceAllocationException { + private boolean validateVolume(Account caller, long ownerId, Long zoneId, String volumeName, String url, + String format, Long diskOfferingId) throws ResourceAllocationException { // permission check - _accountMgr.checkAccess(caller, null, true, _accountMgr.getActiveAccountById(ownerId)); + Account volumeOwner = _accountMgr.getActiveAccountById(ownerId); + _accountMgr.checkAccess(caller, null, true, volumeOwner); // Check that the resource limit for volumes won't be exceeded - _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(ownerId), ResourceType.volume); + _resourceLimitMgr.checkResourceLimit(volumeOwner, ResourceType.volume); // Verify that zone exists DataCenterVO zone = _dcDao.findById(zoneId); @@ -322,9 +326,28 @@ private boolean validateVolume(Account caller, long ownerId, Long zoneId, String } UriUtils.validateUrl(url); + // Check that the resource limit for secondary storage won't be exceeded _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(ownerId), ResourceType.secondary_storage, UriUtils.getRemoteSize(url)); + // Check that the the disk offering specified is valid + if (diskOfferingId != null) { + DiskOfferingVO diskOffering = _diskOfferingDao.findById(diskOfferingId); + if ((diskOffering == null) || diskOffering.getRemoved() != null + || !DiskOfferingVO.Type.Disk.equals(diskOffering.getType())) { + throw new InvalidParameterValueException("Please specify a valid disk offering."); + } + if (!diskOffering.isCustomized()) { + throw new InvalidParameterValueException("Please specify a custom sized disk offering."); + } + + if (diskOffering.getDomainId() == null) { + // do nothing as offering is public + } else { + _configMgr.checkDiskOfferingAccess(volumeOwner, diskOffering); + } + } + return false; } @@ -333,7 +356,8 @@ public String getRandomVolumeName() { } @DB - protected VolumeVO persistVolume(final Account owner, final Long zoneId, final String volumeName, final String url, final String format) { + protected VolumeVO persistVolume(final Account owner, final Long zoneId, final String volumeName, final String url, + final String format, final Long diskOfferingId) { return Transaction.execute(new TransactionCallback() { @Override public VolumeVO doInTransaction(TransactionStatus status) { @@ -345,8 +369,13 @@ public VolumeVO doInTransaction(TransactionStatus status) { // TODO Decide if this is valid or whether throwing a CloudRuntimeException is more appropriate volume.setAccountId((owner == null) ? Account.ACCOUNT_ID_SYSTEM : owner.getAccountId()); volume.setDomainId((owner == null) ? Domain.ROOT_DOMAIN : owner.getDomainId()); - long diskOfferingId = _diskOfferingDao.findByUniqueName("Cloud.com-Custom").getId(); - volume.setDiskOfferingId(diskOfferingId); + + if (diskOfferingId == null) { + long defaultDiskOfferingId = _diskOfferingDao.findByUniqueName("Cloud.com-Custom").getId(); + volume.setDiskOfferingId(defaultDiskOfferingId); + } else { + volume.setDiskOfferingId(diskOfferingId); + } // volume.setSize(size); volume.setInstanceId(null); volume.setUpdated(new Date()); @@ -378,6 +407,7 @@ public VolumeVO allocVolume(CreateVolumeCmd cmd) throws ResourceAllocationExcept Account caller = CallContext.current().getCallingAccount(); long ownerId = cmd.getEntityOwnerId(); + Account owner = _accountMgr.getActiveAccountById(ownerId); Boolean displayVolume = cmd.getDisplayVolume(); // permission check @@ -392,7 +422,7 @@ public VolumeVO allocVolume(CreateVolumeCmd cmd) throws ResourceAllocationExcept } // Check that the resource limit for volumes won't be exceeded - _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(ownerId), ResourceType.volume, displayVolume); + _resourceLimitMgr.checkResourceLimit(owner, ResourceType.volume, displayVolume); Long zoneId = cmd.getZoneId(); Long diskOfferingId = null; @@ -533,7 +563,7 @@ public VolumeVO allocVolume(CreateVolumeCmd cmd) throws ResourceAllocationExcept } // Check that the resource limit for primary storage won't be exceeded - _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(ownerId), ResourceType.primary_storage, displayVolume, new Long(size)); + _resourceLimitMgr.checkResourceLimit(owner, ResourceType.primary_storage, displayVolume, new Long(size)); // Verify that zone exists DataCenterVO zone = _dcDao.findById(zoneId); @@ -557,13 +587,13 @@ public VolumeVO allocVolume(CreateVolumeCmd cmd) throws ResourceAllocationExcept userSpecifiedName = getRandomVolumeName(); } - VolumeVO volume = commitVolume(cmd, caller, ownerId, displayVolume, zoneId, diskOfferingId, size, minIops, maxIops, parentVolume, userSpecifiedName, + VolumeVO volume = commitVolume(cmd, caller, owner, displayVolume, zoneId, diskOfferingId, size, minIops, maxIops, parentVolume, userSpecifiedName, _uuidMgr.generateUuid(Volume.class, cmd.getCustomId())); return volume; } - private VolumeVO commitVolume(final CreateVolumeCmd cmd, final Account caller, final long ownerId, final Boolean displayVolume, final Long zoneId, + private VolumeVO commitVolume(final CreateVolumeCmd cmd, final Account caller, final Account owner, final Boolean displayVolume, final Long zoneId, final Long diskOfferingId, final Long size, final Long minIops, final Long maxIops, final VolumeVO parentVolume, final String userSpecifiedName, final String uuid) { return Transaction.execute(new TransactionCallback() { @Override @@ -573,15 +603,14 @@ public VolumeVO doInTransaction(TransactionStatus status) { volume.setUuid(uuid); volume.setDataCenterId(zoneId); volume.setPodId(null); - volume.setAccountId(ownerId); - volume.setDomainId(((caller == null) ? Domain.ROOT_DOMAIN : caller.getDomainId())); + volume.setAccountId(owner.getId()); + volume.setDomainId(owner.getDomainId()); volume.setDiskOfferingId(diskOfferingId); volume.setSize(size); volume.setMinIops(minIops); volume.setMaxIops(maxIops); volume.setInstanceId(null); volume.setUpdated(new Date()); - volume.setDomainId((caller == null) ? Domain.ROOT_DOMAIN : caller.getDomainId()); volume.setDisplayVolume(displayVolume); if (parentVolume != null) { volume.setTemplateId(parentVolume.getTemplateId()); @@ -591,10 +620,10 @@ public VolumeVO doInTransaction(TransactionStatus status) { } volume = _volsDao.persist(volume); - if (cmd.getSnapshotId() == null) { + if (cmd.getSnapshotId() == null && displayVolume) { // for volume created from snapshot, create usage event after volume creation - UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(), - diskOfferingId, null, size, Volume.class.getName(), volume.getUuid()); + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(), + diskOfferingId, null, size, Volume.class.getName(), volume.getUuid(), displayVolume); } CallContext.current().setEventDetails("Volume Id: " + volume.getId()); @@ -677,11 +706,11 @@ protected VolumeVO createVolumeFromSnapshot(VolumeVO volume, long snapshotId, Lo // sync old snapshots to region store if necessary createdVolume = _volumeMgr.createVolumeFromSnapshot(volume, snapshot, vm); - + VolumeVO volumeVo = _volsDao.findById(createdVolume.getId()); UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, createdVolume.getAccountId(), createdVolume.getDataCenterId(), createdVolume.getId(), - createdVolume.getName(), createdVolume.getDiskOfferingId(), null, createdVolume.getSize(), Volume.class.getName(), createdVolume.getUuid()); + createdVolume.getName(), createdVolume.getDiskOfferingId(), null, createdVolume.getSize(), Volume.class.getName(), createdVolume.getUuid(), volumeVo.isDisplayVolume()); - return _volsDao.findById(createdVolume.getId()); + return volumeVo; } @Override @@ -701,27 +730,17 @@ public VolumeVO resizeVolume(ResizeVolumeCmd cmd) throws ResourceAllocationExcep newDiskOffering = _diskOfferingDao.findById(cmd.getNewDiskOfferingId()); - /* - * Volumes with no hypervisor have never been assigned, and can be - * resized by recreating. perhaps in the future we can just update the - * db entry for the volume - */ - if (_volsDao.getHypervisorType(volume.getId()) == HypervisorType.None) { - throw new InvalidParameterValueException("Can't resize a volume that has never been attached, not sure which hypervisor type. Recreate volume to resize."); - } - - /* Only works for KVM/Xen for now */ - if (_volsDao.getHypervisorType(volume.getId()) != HypervisorType.KVM && _volsDao.getHypervisorType(volume.getId()) != HypervisorType.XenServer - && _volsDao.getHypervisorType(volume.getId()) != HypervisorType.VMware) { - throw new InvalidParameterValueException("Cloudstack currently only supports volumes marked as KVM or XenServer hypervisor for resize"); + /* Only works for KVM/Xen/VMware for now, and volumes with 'None' since they're just allocated in db */ + if (_volsDao.getHypervisorType(volume.getId()) != HypervisorType.KVM + && _volsDao.getHypervisorType(volume.getId()) != HypervisorType.XenServer + && _volsDao.getHypervisorType(volume.getId()) != HypervisorType.VMware + && _volsDao.getHypervisorType(volume.getId()) != HypervisorType.None) { + throw new InvalidParameterValueException("Cloudstack currently only supports volumes marked as KVM, VMware, XenServer hypervisor for resize"); } - if (volume.getState() != Volume.State.Ready) { - throw new InvalidParameterValueException("Volume should be in ready state before attempting a resize"); - } - - if (!volume.getVolumeType().equals(Volume.Type.DATADISK)) { - throw new InvalidParameterValueException("Can only resize DATA volumes"); + if (volume.getState() != Volume.State.Ready && volume.getState() != Volume.State.Allocated) { + throw new InvalidParameterValueException("Volume should be in ready or allocated state before attempting a resize. " + + "Volume " + volume.getUuid() + " state is:" + volume.getState()); } /* @@ -729,7 +748,7 @@ public VolumeVO resizeVolume(ResizeVolumeCmd cmd) throws ResourceAllocationExcep * required, get the correct size value */ if (newDiskOffering == null) { - if (diskOffering.isCustomized()) { + if (diskOffering.isCustomized() || volume.getVolumeType().equals(Volume.Type.ROOT)) { newSize = cmd.getSize(); if (newSize == null) { @@ -741,6 +760,9 @@ public VolumeVO resizeVolume(ResizeVolumeCmd cmd) throws ResourceAllocationExcep throw new InvalidParameterValueException("current offering" + volume.getDiskOfferingId() + " cannot be resized, need to specify a disk offering"); } } else { + if (!volume.getVolumeType().equals(Volume.Type.DATADISK)) { + throw new InvalidParameterValueException("Can only resize Data volumes via new disk offering"); + } if (newDiskOffering.getRemoved() != null || !DiskOfferingVO.Type.Disk.equals(newDiskOffering.getType())) { throw new InvalidParameterValueException("Disk offering ID is missing or invalid"); @@ -784,8 +806,6 @@ public VolumeVO resizeVolume(ResizeVolumeCmd cmd) throws ResourceAllocationExcep /* does the caller have the authority to act on this volume? */ _accountMgr.checkAccess(CallContext.current().getCallingAccount(), null, true, volume); - UserVmVO userVm = _userVmDao.findById(volume.getInstanceId()); - long currentSize = volume.getSize(); /* @@ -805,6 +825,20 @@ public VolumeVO resizeVolume(ResizeVolumeCmd cmd) throws ResourceAllocationExcep - currentSize)); } + /* If this volume has never been beyond allocated state, short circuit everything and simply update the database */ + if (volume.getState() == Volume.State.Allocated) { + s_logger.debug("Volume is allocated, but never created, simply updating database with new size"); + volume.setSize(newSize); + if (newDiskOffering != null) { + volume.setDiskOfferingId(cmd.getNewDiskOfferingId()); + } + _volsDao.update(volume.getId(), volume); + return volume; + } + + UserVmVO userVm = _userVmDao.findById(volume.getInstanceId()); + + if (userVm != null) { // serialize VM operation AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext(); @@ -967,7 +1001,7 @@ storage count (in case of upload volume). */ // Log usage event for volumes belonging user VM's only UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_DELETE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(), - Volume.class.getName(), volume.getUuid()); + Volume.class.getName(), volume.getUuid(), volume.isDisplayVolume()); } } // Mark volume as removed if volume has not been created on primary or secondary @@ -1206,7 +1240,7 @@ public Volume attachVolumeToVM(Long vmId, Long volumeId, Long deviceId) { s_logger.info("Trying to attaching volume " + volumeId + " to vm instance:" + vm.getId() + ", update async job-" + job.getId() + " progress status"); } - _asyncMgr.updateAsyncJobAttachment(job.getId(), "volume", volumeId); + _asyncMgr.updateAsyncJobAttachment(job.getId(), "Volume", volumeId); } VolumeVO newVol = _volumeDao.findById(volumeOnPrimaryStorage.getId()); @@ -1220,14 +1254,13 @@ public Volume updateVolume(long volumeId, String path, String state, Long storag VolumeVO volume = _volumeDao.findById(volumeId); + if(volume == null) + throw new InvalidParameterValueException("The volume id doesn't exist"); + if (path != null) { volume.setPath(path); } - if (displayVolume != null) { - volume.setDisplayVolume(displayVolume); - } - if(chainInfo != null){ volume.setChainInfo(chainInfo); } @@ -1253,17 +1286,61 @@ public Volume updateVolume(long volumeId, String path, String state, Long storag volume.setUuid(customId); } - if (displayVolume != null && displayVolume != volume.isDisplayVolume()) { // No need to check permissions since only Admin allowed to call this API. - volume.setDisplayVolume(displayVolume); - _resourceLimitMgr.changeResourceCount(entityOwnerId, ResourceType.volume, displayVolume); - _resourceLimitMgr.changeResourceCount(entityOwnerId, ResourceType.primary_storage, displayVolume, new Long(volume.getSize())); - } + updateDisplay(volume, displayVolume); _volumeDao.update(volumeId, volume); return volume; } + + @Override + public void updateDisplay(Volume volume, Boolean displayVolume){ + // 1. Resource limit changes + updateResourceCount(volume, displayVolume); + + // 2. generate usage event if not in destroyed state + saveUsageEvent(volume, displayVolume); + + // 3. Set the flag + if (displayVolume != null && displayVolume != volume.isDisplayVolume()){ + // FIXME - Confused - typecast for now. + ((VolumeVO)volume).setDisplayVolume(displayVolume); + _volumeDao.update(volume.getId(), (VolumeVO)volume); + } + + } + + private void updateResourceCount(Volume volume, Boolean displayVolume){ + // Update only when the flag has changed. + if (displayVolume != null && displayVolume != volume.isDisplayVolume()){ + _resourceLimitMgr.changeResourceCount(volume.getAccountId(), ResourceType.volume, displayVolume); + _resourceLimitMgr.changeResourceCount(volume.getAccountId(), ResourceType.primary_storage, displayVolume, new Long(volume.getSize())); + } + } + + private void saveUsageEvent(Volume volume, Boolean displayVolume){ + + // Update only when the flag has changed && only when volume in a non-destroyed state. + if ((displayVolume != null && displayVolume != volume.isDisplayVolume()) && !isVolumeDestroyed(volume)){ + if (displayVolume){ + // flag turned 1 equivalent to freshly created volume + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(), + volume.getDiskOfferingId(), volume.getTemplateId(), volume.getSize(), Volume.class.getName(), volume.getUuid()); + }else { + // flag turned 0 equivalent to deleting a volume + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_DELETE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(), + Volume.class.getName(), volume.getUuid()); + } + } + } + + private boolean isVolumeDestroyed(Volume volume){ + if(volume.getState() == Volume.State.Destroy || volume.getState() == Volume.State.Expunging && volume.getState() == Volume.State.Expunged) + return true; + return false; + } + @Override @ActionEvent(eventType = EventTypes.EVENT_VOLUME_DETACH, eventDescription = "detaching volume", async = true) public Volume detachVolumeFromVM(DetachVolumeCmd cmmd) { @@ -1329,7 +1406,7 @@ public Volume detachVolumeFromVM(DetachVolumeCmd cmmd) { s_logger.info("Trying to attaching volume " + volumeId + "to vm instance:" + vm.getId() + ", update async job-" + job.getId() + " progress status"); } - _asyncMgr.updateAsyncJobAttachment(job.getId(), "volume", volumeId); + _asyncMgr.updateAsyncJobAttachment(job.getId(), "Volume", volumeId); } AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext(); @@ -1428,7 +1505,7 @@ private Volume orchestrateDetachVolumeFromVM(long vmId, long volumeId) { // Mark the volume as detached _volsDao.detachVolume(volume.getId()); - // volume.getPoolId() should be null if the VM we are attaching the disk to has never been started before + // volume.getPoolId() should be null if the VM we are detaching the disk from has never been started before DataStore dataStore = volume.getPoolId() != null ? dataStoreMgr.getDataStore(volume.getPoolId(), DataStoreRole.Primary) : null; volService.disconnectVolumeFromHost(volFactory.getVolume(volume.getId()), host, dataStore); @@ -1487,12 +1564,11 @@ public Volume migrateVolume(MigrateVolumeCmd cmd) { liveMigrateVolume = capabilities.isStorageMotionSupported(); } } - } - // If the disk is not attached to any VM then it can be moved. Otherwise, it needs to be attached to a vm - // running on a hypervisor that supports storage motion so that it be be migrated. - if (instanceId != null && !liveMigrateVolume) { - throw new InvalidParameterValueException("Volume needs to be detached from VM"); + // If vm is running, and hypervisor doesn't support live migration, then return error + if (!liveMigrateVolume) { + throw new InvalidParameterValueException("Volume needs to be detached from VM"); + } } if (liveMigrateVolume && !cmd.isLiveMigrate()) { @@ -1614,6 +1690,9 @@ public Snapshot takeSnapshot(Long volumeId, Long policyId, Long snapshotId, Acco if (volume.getInstanceId() != null) vm = _vmInstanceDao.findById(volume.getInstanceId()); + if (volume.getHypervisorType() == HypervisorType.Hyperv) { + throw new InvalidParameterValueException("Volume Snapshots are not supported on Hypervisor Type : Hyper-V"); + } if (vm != null) { // serialize VM operation AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext(); @@ -1823,6 +1902,7 @@ public String extractVolume(ExtractVolumeCmd cmd) { String extractUrl = secStore.createEntityExtractUrl(vol.getPath(), vol.getFormat(), vol); volumeStoreRef = _volumeStoreDao.findByVolume(volumeId); volumeStoreRef.setExtractUrl(extractUrl); + volumeStoreRef.setExtractUrlCreated(DateUtil.now()); _volumeStoreDao.update(volumeStoreRef.getId(), volumeStoreRef); return extractUrl; @@ -1892,7 +1972,9 @@ private boolean needMoveVolume(VolumeVO rootVolumeOfVm, VolumeInfo volume) { } if (storeForDataStoreScope.getScopeId().equals(vmClusterId)) { return false; - } + } else { + return true; + } } else if (storeForDataStoreScope.getScopeType() == ScopeType.HOST && (storeForRootStoreScope.getScopeType() == ScopeType.CLUSTER || storeForRootStoreScope.getScopeType() == ScopeType.ZONE)) { Long hostId = _vmInstanceDao.findById(rootVolumeOfVm.getInstanceId()).getHostId(); diff --git a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java index 6bf4817571..446699f028 100755 --- a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java +++ b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java @@ -26,6 +26,7 @@ import javax.inject.Inject; import javax.naming.ConfigurationException; +import org.apache.cloudstack.api.command.user.snapshot.UpdateSnapshotPolicyCmd; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -271,6 +272,30 @@ public boolean revertSnapshot(Long snapshotId) { return snapshotStrategy.revertSnapshot(snapshotId); } + @Override + @ActionEvent(eventType = EventTypes.EVENT_SNAPSHOT_POLICY_UPDATE, eventDescription = "updating snapshot policy", async = true) + public SnapshotPolicy updateSnapshotPolicy(UpdateSnapshotPolicyCmd cmd) { + + Long id = cmd.getId(); + String customUUID = cmd.getCustomId(); + Boolean display = cmd.getDisplay(); + + SnapshotPolicyVO policyVO = _snapshotPolicyDao.findById(id); + if(display != null){ + boolean previousDisplay = policyVO.isDisplay(); + policyVO.setDisplay(display); + _snapSchedMgr.scheduleOrCancelNextSnapshotJobOnDisplayChange(policyVO, previousDisplay); + } + + if(customUUID != null) + policyVO.setUuid(customUUID); + + _snapshotPolicyDao.update(id, policyVO); + + return policyVO; + + } + @Override @DB @ActionEvent(eventType = EventTypes.EVENT_SNAPSHOT_CREATE, eventDescription = "creating snapshot", async = true) @@ -441,10 +466,7 @@ public Pair, Integer> listSnapshots(ListSnapshotsCmd cm Map tags = cmd.getTags(); Long zoneId = cmd.getZoneId(); Account caller = CallContext.current().getCallingAccount(); - List permittedDomains = new ArrayList(); List permittedAccounts = new ArrayList(); - List permittedResources = new ArrayList(); - // Verify parameters if (volumeId != null) { @@ -455,14 +477,14 @@ public Pair, Integer> listSnapshots(ListSnapshotsCmd cm } Ternary domainIdRecursiveListProject = new Ternary(cmd.getDomainId(), cmd.isRecursive(), null); - _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedDomains, permittedAccounts, permittedResources, - domainIdRecursiveListProject, cmd.listAll(), false, "listSnapshots"); + _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, cmd.listAll(), false); + Long domainId = domainIdRecursiveListProject.first(); Boolean isRecursive = domainIdRecursiveListProject.second(); ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third(); Filter searchFilter = new Filter(SnapshotVO.class, "created", false, cmd.getStartIndex(), cmd.getPageSizeVal()); SearchBuilder sb = _snapshotDao.createSearchBuilder(); - _accountMgr.buildACLSearchBuilder(sb, isRecursive, permittedDomains, permittedAccounts, permittedResources, listProjectResourcesCriteria); + _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); sb.and("statusNEQ", sb.entity().getState(), SearchCriteria.Op.NEQ); //exclude those Destroyed snapshot, not showing on UI sb.and("volumeId", sb.entity().getVolumeId(), SearchCriteria.Op.EQ); @@ -485,7 +507,7 @@ public Pair, Integer> listSnapshots(ListSnapshotsCmd cm } SearchCriteria sc = sb.create(); - _accountMgr.buildACLSearchCriteria(sc, isRecursive, permittedDomains, permittedAccounts, permittedResources, listProjectResourcesCriteria); + _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); sc.setParameters("statusNEQ", Snapshot.State.Destroyed); @@ -599,7 +621,7 @@ public boolean deleteSnapshotDirsForAccount(long accountId) { SnapshotDataStoreVO snapshotStoreRef = _snapshotStoreDao.findBySnapshot(snapshot.getId(), DataStoreRole.Image); if (snapshotStrategy.deleteSnapshot(snapshot.getId())) { - if (snapshot.getRecurringType() == Type.MANUAL) { + if (Type.MANUAL == snapshot.getRecurringType()) { _resourceLimitMgr.decrementResourceCount(accountId, ResourceType.snapshot); _resourceLimitMgr.decrementResourceCount(accountId, ResourceType.secondary_storage, new Long(snapshotStoreRef.getSize())); } @@ -619,6 +641,7 @@ public boolean deleteSnapshotDirsForAccount(long accountId) { @DB public SnapshotPolicyVO createPolicy(CreateSnapshotPolicyCmd cmd, Account policyOwner) { Long volumeId = cmd.getVolumeId(); + boolean display = cmd.isDisplay(); VolumeVO volume = _volsDao.findById(cmd.getVolumeId()); if (volume == null) { throw new InvalidParameterValueException("Failed to create snapshot policy, unable to find a volume with id " + volumeId); @@ -626,7 +649,8 @@ public SnapshotPolicyVO createPolicy(CreateSnapshotPolicyCmd cmd, Account policy _accountMgr.checkAccess(CallContext.current().getCallingAccount(), null, true, volume); - if (volume.getState() != Volume.State.Ready) { + // If display is false we don't actually schedule snapshots. + if (volume.getState() != Volume.State.Ready && display) { throw new InvalidParameterValueException("VolumeId: " + volumeId + " is not in " + Volume.State.Ready + " state but " + volume.getState() + ". Cannot take snapshot."); } @@ -673,33 +697,37 @@ public SnapshotPolicyVO createPolicy(CreateSnapshotPolicyCmd cmd, Account policy throw new InvalidParameterValueException("maxSnaps exceeds limit: " + intervalMaxSnaps + " for interval type: " + cmd.getIntervalType()); } - // Verify that max doesn't exceed domain and account snapshot limits - long accountLimit = _resourceLimitMgr.findCorrectResourceLimitForAccount(owner, ResourceType.snapshot); - long domainLimit = _resourceLimitMgr.findCorrectResourceLimitForDomain(_domainMgr.getDomain(owner.getDomainId()), ResourceType.snapshot); - int max = cmd.getMaxSnaps().intValue(); - if (!_accountMgr.isRootAdmin(owner.getId())&& ((accountLimit != -1 && max > accountLimit) || (domainLimit != -1 && max > domainLimit))) { - String message = "domain/account"; - if (owner.getType() == Account.ACCOUNT_TYPE_PROJECT) { - message = "domain/project"; - } + // Verify that max doesn't exceed domain and account snapshot limits in case display is on + if(display){ + long accountLimit = _resourceLimitMgr.findCorrectResourceLimitForAccount(owner, ResourceType.snapshot); + long domainLimit = _resourceLimitMgr.findCorrectResourceLimitForDomain(_domainMgr.getDomain(owner.getDomainId()), ResourceType.snapshot); + int max = cmd.getMaxSnaps().intValue(); + if (!_accountMgr.isRootAdmin(owner.getId())&& ((accountLimit != -1 && max > accountLimit) || (domainLimit != -1 && max > domainLimit))) { + String message = "domain/account"; + if (owner.getType() == Account.ACCOUNT_TYPE_PROJECT) { + message = "domain/project"; + } - throw new InvalidParameterValueException("Max number of snapshots shouldn't exceed the " + message + " level snapshot limit"); + throw new InvalidParameterValueException("Max number of snapshots shouldn't exceed the " + message + " level snapshot limit"); + } } - SnapshotPolicyVO policy = _snapshotPolicyDao.findOneByVolumeInterval(volumeId, intvType); if (policy == null) { - policy = new SnapshotPolicyVO(volumeId, cmd.getSchedule(), timezoneId, intvType, cmd.getMaxSnaps()); + policy = new SnapshotPolicyVO(volumeId, cmd.getSchedule(), timezoneId, intvType, cmd.getMaxSnaps(), display); policy = _snapshotPolicyDao.persist(policy); _snapSchedMgr.scheduleNextSnapshotJob(policy); } else { try { + boolean previousDisplay = policy.isDisplay(); policy = _snapshotPolicyDao.acquireInLockTable(policy.getId()); policy.setSchedule(cmd.getSchedule()); policy.setTimezone(timezoneId); policy.setInterval((short)intvType.ordinal()); policy.setMaxSnaps(cmd.getMaxSnaps()); policy.setActive(true); + policy.setDisplay(display); _snapshotPolicyDao.update(policy.getId(), policy); + _snapSchedMgr.scheduleOrCancelNextSnapshotJobOnDisplayChange(policy, previousDisplay); } finally { if (policy != null) { _snapshotPolicyDao.releaseFromLockTable(policy.getId()); @@ -719,12 +747,25 @@ protected boolean deletePolicy(long userId, Long policyId) { @Override public Pair, Integer> listPoliciesforVolume(ListSnapshotPoliciesCmd cmd) { Long volumeId = cmd.getVolumeId(); + boolean display = cmd.isDisplay(); + Long id = cmd.getId(); + Pair, Integer> result = null; + // TODO - Have a better way of doing this. + if(id != null){ + result = _snapshotPolicyDao.listAndCountById(id, display, null); + if(result != null && result.first() != null && !result.first().isEmpty()){ + SnapshotPolicyVO snapshotPolicy = result.first().get(0); + volumeId = snapshotPolicy.getVolumeId(); + } + } VolumeVO volume = _volsDao.findById(volumeId); if (volume == null) { throw new InvalidParameterValueException("Unable to find a volume with id " + volumeId); } _accountMgr.checkAccess(CallContext.current().getCallingAccount(), null, true, volume); - Pair, Integer> result = _snapshotPolicyDao.listAndCountByVolumeId(volumeId); + if(result != null) + return new Pair, Integer>(result.first(), result.second()); + result = _snapshotPolicyDao.listAndCountByVolumeId(volumeId, display); return new Pair, Integer>(result.first(), result.second()); } @@ -769,7 +810,7 @@ public List findRecurringSnapshotSchedule(ListRecurringSnaps if (account != null) { long volAcctId = volume.getAccountId(); - if (_accountMgr.isAdmin(account.getType())) { + if (_accountMgr.isAdmin(account.getId())) { Account userAccount = _accountDao.findById(Long.valueOf(volAcctId)); if (!_domainDao.isChildDomain(account.getDomainId(), userAccount.getDomainId())) { throw new PermissionDeniedException("Unable to list snapshot schedule for volume " + volumeId + ", permission denied."); diff --git a/server/src/com/cloud/storage/snapshot/SnapshotScheduler.java b/server/src/com/cloud/storage/snapshot/SnapshotScheduler.java index c744f69b4d..ae4f7ce9af 100644 --- a/server/src/com/cloud/storage/snapshot/SnapshotScheduler.java +++ b/server/src/com/cloud/storage/snapshot/SnapshotScheduler.java @@ -40,4 +40,6 @@ public interface SnapshotScheduler extends Manager, Scheduler { * @return */ boolean removeSchedule(Long volumeId, Long policyId); + + void scheduleOrCancelNextSnapshotJobOnDisplayChange(SnapshotPolicyVO policy, boolean previousDisplay); } diff --git a/server/src/com/cloud/storage/snapshot/SnapshotSchedulerImpl.java b/server/src/com/cloud/storage/snapshot/SnapshotSchedulerImpl.java index 447697f100..1090dcbb44 100644 --- a/server/src/com/cloud/storage/snapshot/SnapshotSchedulerImpl.java +++ b/server/src/com/cloud/storage/snapshot/SnapshotSchedulerImpl.java @@ -304,6 +304,13 @@ public Date scheduleNextSnapshotJob(final SnapshotPolicyVO policy) { if (policy == null) { return null; } + + // If display attribute is false then remove schedules if any and return. + if(!policy.isDisplay()){ + removeSchedule(policy.getVolumeId(), policy.getId()); + return null; + } + final long policyId = policy.getId(); if (policyId == Snapshot.MANUAL_POLICY_ID) { return null; @@ -330,6 +337,20 @@ public Date scheduleNextSnapshotJob(final SnapshotPolicyVO policy) { return nextSnapshotTimestamp; } + @Override + public void scheduleOrCancelNextSnapshotJobOnDisplayChange(final SnapshotPolicyVO policy, boolean previousDisplay) { + + // Take action only if display changed + if(policy.isDisplay() != previousDisplay ){ + if(policy.isDisplay()){ + scheduleNextSnapshotJob(policy); + }else{ + removeSchedule(policy.getVolumeId(), policy.getId()); + } + } + } + + @Override @DB public boolean removeSchedule(final Long volumeId, final Long policyId) { diff --git a/server/src/com/cloud/tags/TaggedResourceManagerImpl.java b/server/src/com/cloud/tags/TaggedResourceManagerImpl.java index 900c822da8..b77c55e090 100644 --- a/server/src/com/cloud/tags/TaggedResourceManagerImpl.java +++ b/server/src/com/cloud/tags/TaggedResourceManagerImpl.java @@ -25,6 +25,9 @@ import javax.inject.Inject; import javax.naming.ConfigurationException; +import com.cloud.storage.SnapshotPolicyVO; +import com.cloud.user.dao.AccountDao; +import com.cloud.utils.exception.CloudRuntimeException; import org.apache.cloudstack.api.Identity; import org.apache.cloudstack.api.InternalIdentity; import org.apache.cloudstack.context.CallContext; @@ -33,15 +36,16 @@ import com.cloud.api.query.dao.ResourceTagJoinDao; import com.cloud.dc.DataCenterVO; -import com.cloud.domain.Domain; import com.cloud.domain.PartOf; import com.cloud.event.ActionEvent; import com.cloud.event.EventTypes; import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.PermissionDeniedException; +import com.cloud.network.LBHealthCheckPolicyVO; import com.cloud.network.as.AutoScaleVmGroupVO; import com.cloud.network.as.AutoScaleVmProfileVO; import com.cloud.network.dao.IPAddressVO; +import com.cloud.network.dao.LBStickinessPolicyVO; import com.cloud.network.dao.LoadBalancerVO; import com.cloud.network.dao.NetworkVO; import com.cloud.network.dao.RemoteAccessVpnVO; @@ -103,7 +107,7 @@ public class TaggedResourceManagerImpl extends ManagerBase implements TaggedReso s_typeMap.put(ResourceObjectType.Project, ProjectVO.class); s_typeMap.put(ResourceObjectType.Vpc, VpcVO.class); s_typeMap.put(ResourceObjectType.Nic, NicVO.class); - s_typeMap.put(ResourceObjectType.NetworkACL, NetworkACLVO.class); + s_typeMap.put(ResourceObjectType.NetworkACL, NetworkACLItemVO.class); s_typeMap.put(ResourceObjectType.StaticRoute, StaticRouteVO.class); s_typeMap.put(ResourceObjectType.VMSnapshot, VMSnapshotVO.class); s_typeMap.put(ResourceObjectType.RemoteAccessVpn, RemoteAccessVpnVO.class); @@ -111,7 +115,7 @@ public class TaggedResourceManagerImpl extends ManagerBase implements TaggedReso s_typeMap.put(ResourceObjectType.ServiceOffering, ServiceOfferingVO.class); s_typeMap.put(ResourceObjectType.Storage, StoragePoolVO.class); s_typeMap.put(ResourceObjectType.PrivateGateway, RemoteAccessVpnVO.class); - s_typeMap.put(ResourceObjectType.NetworkACLList, NetworkACLItemVO.class); + s_typeMap.put(ResourceObjectType.NetworkACLList, NetworkACLVO.class); s_typeMap.put(ResourceObjectType.VpnGateway, Site2SiteVpnGatewayVO.class); s_typeMap.put(ResourceObjectType.CustomerGateway, Site2SiteCustomerGatewayVO.class); s_typeMap.put(ResourceObjectType.VpnConnection, Site2SiteVpnConnectionVO.class); @@ -119,6 +123,10 @@ public class TaggedResourceManagerImpl extends ManagerBase implements TaggedReso s_typeMap.put(ResourceObjectType.DiskOffering, DiskOfferingVO.class); s_typeMap.put(ResourceObjectType.AutoScaleVmProfile, AutoScaleVmProfileVO.class); s_typeMap.put(ResourceObjectType.AutoScaleVmGroup, AutoScaleVmGroupVO.class); + s_typeMap.put(ResourceObjectType.LBStickinessPolicy, LBStickinessPolicyVO.class); + s_typeMap.put(ResourceObjectType.LBHealthCheckPolicy, LBHealthCheckPolicyVO.class); + s_typeMap.put(ResourceObjectType.SnapshotPolicy, SnapshotPolicyVO.class); + } @Inject @@ -131,6 +139,8 @@ public class TaggedResourceManagerImpl extends ManagerBase implements TaggedReso ResourceTagJoinDao _resourceTagJoinDao; @Inject DomainManager _domainMgr; + @Inject + AccountDao _accountDao; @Override @@ -158,9 +168,9 @@ public long getResourceId(String resourceId, ResourceObjectType resourceType) { entity = _entityMgr.findById(clazz, resourceId); if (entity != null) { return ((InternalIdentity)entity).getId(); - } - throw new InvalidParameterValueException("Unable to find resource by id " + resourceId + " and type " + resourceType); } + throw new InvalidParameterValueException("Unable to find resource by id " + resourceId + " and type " + resourceType); + } private Pair getAccountDomain(long resourceId, ResourceObjectType resourceType) { Class clazz = s_typeMap.get(resourceType); @@ -180,10 +190,10 @@ private Pair getAccountDomain(long resourceId, ResourceObjectType re accountId = Account.ACCOUNT_ID_SYSTEM; } - if (domainId == null) { - domainId = Domain.ROOT_DOMAIN; + if ( ((accountId != null) && (domainId == -1)) || (domainId == null) ) + { + domainId = _accountDao.getDomainIdForGivenAccountId(accountId); } - return new Pair(accountId, domainId); } @@ -221,6 +231,11 @@ public void doInTransactionWithoutResult(TransactionStatus status) { Pair accountDomainPair = getAccountDomain(id, resourceType); Long domainId = accountDomainPair.second(); Long accountId = accountDomainPair.first(); + + if ((domainId != null) && (domainId == -1)) + { + throw new CloudRuntimeException("Invalid DomainId : -1"); + } if (accountId != null) { _accountMgr.checkAccess(caller, null, false, _accountMgr.getAccount(accountId)); } else if (domainId != null && !_accountMgr.isNormalUser(caller.getId())) { diff --git a/server/src/com/cloud/template/HypervisorTemplateAdapter.java b/server/src/com/cloud/template/HypervisorTemplateAdapter.java index 2b6f1ebf3a..20309d6ddc 100755 --- a/server/src/com/cloud/template/HypervisorTemplateAdapter.java +++ b/server/src/com/cloud/template/HypervisorTemplateAdapter.java @@ -16,8 +16,6 @@ // under the License. package com.cloud.template; -import java.net.MalformedURLException; -import java.net.URL; import java.util.Collections; import java.util.HashSet; import java.util.List; @@ -29,7 +27,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.api.command.user.iso.DeleteIsoCmd; import org.apache.cloudstack.api.command.user.iso.RegisterIsoCmd; import org.apache.cloudstack.api.command.user.template.DeleteTemplateCmd; @@ -131,20 +128,6 @@ public TemplateProfile prepare(RegisterIsoCmd cmd) throws ResourceAllocationExce public TemplateProfile prepare(RegisterTemplateCmd cmd) throws ResourceAllocationException { TemplateProfile profile = super.prepare(cmd); String url = profile.getUrl(); - String path = null; - try { - URL str = new URL(url); - path = str.getPath(); - } catch (MalformedURLException ex) { - throw new InvalidParameterValueException("Please specify a valid URL. URL:" + url + " is invalid"); - } - - try { - checkFormat(cmd.getFormat(), url); - } catch (InvalidParameterValueException ex) { - checkFormat(cmd.getFormat(), path); - } - UriUtils.validateUrl(url); profile.setUrl(url); // Check that the resource limit for secondary storage won't be exceeded @@ -400,6 +383,11 @@ public boolean delete(TemplateProfile profile) { } } if (success) { + if ((imageStores.size() > 1) && (profile.getZoneId() != null)) { + //if template is stored in more than one image stores, and the zone id is not null, then don't delete other templates. + return success; + } + // delete all cache entries for this template List cacheTmpls = imageFactory.listTemplateOnCache(template.getId()); for (TemplateInfo tmplOnCache : cacheTmpls) { @@ -423,7 +411,7 @@ public boolean delete(TemplateProfile profile) { } // remove its related ACL permission - Pair tmplt = new Pair(IAMEntityType.VirtualMachineTemplate, template.getId()); + Pair, Long> tmplt = new Pair, Long>(VirtualMachineTemplate.class, template.getId()); _messageBus.publish(_name, EntityManager.MESSAGE_REMOVE_ENTITY_EVENT, PublishScope.LOCAL, tmplt); } diff --git a/server/src/com/cloud/template/TemplateAdapterBase.java b/server/src/com/cloud/template/TemplateAdapterBase.java index f3c16cad03..fcf15df675 100755 --- a/server/src/com/cloud/template/TemplateAdapterBase.java +++ b/server/src/com/cloud/template/TemplateAdapterBase.java @@ -179,7 +179,7 @@ public TemplateProfile prepare(boolean isIso, long userId, String name, String d if (!isAdmin && zoneId == null && !isRegionStore ) { // domain admin and user should also be able to register template on a region store - throw new InvalidParameterValueException("Please specify a valid zone Id."); + throw new InvalidParameterValueException("Please specify a valid zone Id. Only admins can create templates in all zones."); } if (url.toLowerCase().contains("file://")) { @@ -209,10 +209,6 @@ public TemplateProfile prepare(boolean isIso, long userId, String name, String d _resourceLimitMgr.checkResourceLimit(templateOwner, ResourceType.template); - if (!_accountMgr.isRootAdmin(templateOwner.getId()) && zoneId == null) { - throw new IllegalArgumentException("Only admins can create templates in all zones"); - } - // If a zoneId is specified, make sure it is valid if (zoneId != null) { DataCenterVO zone = _dcDao.findById(zoneId); @@ -324,7 +320,7 @@ protected VMTemplateVO persistTemplate(TemplateProfile profile) { private Long accountAndUserValidation(Account account, long userId, UserVmVO vmInstanceCheck, VMTemplateVO template, String msg) throws PermissionDeniedException { if (account != null) { - if (!_accountMgr.isAdmin(account.getType())) { + if (!_accountMgr.isAdmin(account.getId())) { if ((vmInstanceCheck != null) && (account.getId() != vmInstanceCheck.getAccountId())) { throw new PermissionDeniedException(msg + ". Permission denied."); } diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index 34123cdb98..dc076a8f1c 100755 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -31,9 +31,9 @@ import javax.inject.Inject; import javax.naming.ConfigurationException; +import com.cloud.utils.DateUtil; import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseListTemplateOrIsoPermissionsCmd; @@ -438,12 +438,20 @@ private String extract(Account caller, Long templateId, String url, Long zoneId, throw new InvalidParameterValueException("The " + desc + " has not been downloaded "); } + // Check if the url already exists + if(tmpltStoreRef.getExtractUrl() != null){ + return tmpltStoreRef.getExtractUrl(); + } + // Handle NFS to S3 object store migration case, we trigger template sync from NFS to S3 during extract template or copy template _tmpltSvr.syncTemplateToRegionStore(templateId, tmpltStore); TemplateInfo templateObject = _tmplFactory.getTemplate(templateId, tmpltStore); - - return tmpltStore.createEntityExtractUrl(templateObject.getInstallPath(), template.getFormat(), templateObject); + String extractUrl = tmpltStore.createEntityExtractUrl(tmpltStoreRef.getInstallPath(), template.getFormat(), templateObject); + tmpltStoreRef.setExtractUrl(extractUrl); + tmpltStoreRef.setExtractUrlCreated(DateUtil.now()); + _tmplStoreDao.update(tmpltStoreRef.getId(), tmpltStoreRef); + return extractUrl; } @Override @@ -1221,7 +1229,7 @@ public boolean updateTemplateOrIsoPermissions(BaseUpdateTemplateOrIsoPermissions throw new InvalidParameterValueException("unable to update permissions for " + mediaType + " with id " + id); } - boolean isAdmin = _accountMgr.isAdmin(caller.getType()); + boolean isAdmin = _accountMgr.isAdmin(caller.getId()); // check configuration parameter(allow.public.user.templates) value for // the template owner boolean allowPublicUserTemplates = AllowPublicUserTemplates.valueIn(template.getAccountId()); @@ -1257,8 +1265,8 @@ public boolean updateTemplateOrIsoPermissions(BaseUpdateTemplateOrIsoPermissions if (isExtractable != null) { // Only Root admins allowed to change it for templates - if (!template.getFormat().equals(ImageFormat.ISO) && _accountMgr.isRootAdmin(caller.getId())) { - throw new InvalidParameterValueException("Only ROOT admins are allowed to modify this attribute."); + if (!template.getFormat().equals(ImageFormat.ISO) && !_accountMgr.isRootAdmin(caller.getId())) { + throw new InvalidParameterValueException("Only ROOT admins are allowed to modify isExtractable attribute."); } else { // For Isos normal user can change it, as their are no derivatives. updatedTemplate.setExtractable(isExtractable.booleanValue()); @@ -1304,7 +1312,7 @@ public void doInTransactionWithoutResult(TransactionStatus status) { // add ACL permission in IAM Map permit = new HashMap(); - permit.put(ApiConstants.ENTITY_TYPE, IAMEntityType.VirtualMachineTemplate.toString()); + permit.put(ApiConstants.ENTITY_TYPE, VirtualMachineTemplate.class); permit.put(ApiConstants.ENTITY_ID, id); permit.put(ApiConstants.ACCESS_TYPE, AccessType.UseEntry); permit.put(ApiConstants.IAM_ACTION, "listTemplates"); @@ -1321,7 +1329,7 @@ public void doInTransactionWithoutResult(TransactionStatus status) { _launchPermissionDao.removePermissions(id, accountIds); // remove ACL permission in IAM Map permit = new HashMap(); - permit.put(ApiConstants.ENTITY_TYPE, IAMEntityType.VirtualMachineTemplate.toString()); + permit.put(ApiConstants.ENTITY_TYPE, VirtualMachineTemplate.class); permit.put(ApiConstants.ENTITY_ID, id); permit.put(ApiConstants.ACCESS_TYPE, AccessType.UseEntry); permit.put(ApiConstants.IAM_ACTION, "listTemplates"); @@ -1488,7 +1496,7 @@ public VMTemplateVO createPrivateTemplateRecord(CreateTemplateCmd cmd, Account t Long userId = CallContext.current().getCallingUserId(); Account caller = CallContext.current().getCallingAccount(); - boolean isAdmin = (_accountMgr.isAdmin(caller.getType())); + boolean isAdmin = (_accountMgr.isAdmin(caller.getId())); _accountMgr.checkAccess(caller, null, true, templateOwner); @@ -1648,6 +1656,7 @@ public VMTemplateVO createPrivateTemplateRecord(CreateTemplateCmd cmd, Account t } } if (cmd.getDetails() != null) { + details.remove("Encrypted.Password"); // new password will be generated during vm deployment from password enabled template details.putAll(cmd.getDetails()); } if (!details.isEmpty()) { diff --git a/server/src/com/cloud/test/IPRangeConfig.java b/server/src/com/cloud/test/IPRangeConfig.java index 1d56471408..29feba6119 100755 --- a/server/src/com/cloud/test/IPRangeConfig.java +++ b/server/src/com/cloud/test/IPRangeConfig.java @@ -318,31 +318,31 @@ private Vector deletePublicIPRange(TransactionLegacy txn, long startIP, String isPublicIPAllocatedSelectSql = "SELECT * FROM `cloud`.`user_ip_address` WHERE public_ip_address = ? AND vlan_id = ?"; Vector problemIPs = new Vector(); - PreparedStatement stmt = null; - PreparedStatement isAllocatedStmt = null; - Connection conn = null; try { conn = txn.getConnection(); - stmt = conn.prepareStatement(deleteSql); - isAllocatedStmt = conn.prepareStatement(isPublicIPAllocatedSelectSql); - } catch (SQLException e) { + } + catch (SQLException e) { + System.out.println("deletePublicIPRange. Exception: " +e.getMessage()); return null; } - - while (startIP <= endIP) { - if (!isPublicIPAllocated(startIP, vlanDbId, isAllocatedStmt)) { - try { - stmt.clearParameters(); - stmt.setLong(1, startIP); - stmt.setLong(2, vlanDbId); - stmt.executeUpdate(); - } catch (Exception ex) { + try(PreparedStatement stmt = conn.prepareStatement(deleteSql); + PreparedStatement isAllocatedStmt = conn.prepareStatement(isPublicIPAllocatedSelectSql);) { + while (startIP <= endIP) { + if (!isPublicIPAllocated(startIP, vlanDbId, isAllocatedStmt)) { + stmt.clearParameters(); + stmt.setLong(1, startIP); + stmt.setLong(2, vlanDbId); + stmt.executeUpdate(); + } + else { + problemIPs.add(NetUtils.long2Ip(startIP)); } - } else { - problemIPs.add(NetUtils.long2Ip(startIP)); + startIP += 1; } - startIP += 1; + }catch (Exception ex) { + System.out.println("deletePublicIPRange. Exception: " +ex.getMessage()); + return null; } return problemIPs; @@ -351,52 +351,46 @@ private Vector deletePublicIPRange(TransactionLegacy txn, long startIP, private Vector deletePrivateIPRange(TransactionLegacy txn, long startIP, long endIP, long podId, long zoneId) { String deleteSql = "DELETE FROM `cloud`.`op_dc_ip_address_alloc` WHERE ip_address = ? AND pod_id = ? AND data_center_id = ?"; String isPrivateIPAllocatedSelectSql = "SELECT * FROM `cloud`.`op_dc_ip_address_alloc` WHERE ip_address = ? AND data_center_id = ? AND pod_id = ?"; - Vector problemIPs = new Vector(); - PreparedStatement stmt = null; - PreparedStatement isAllocatedStmt = null; - - Connection conn = null; try { - conn = txn.getConnection(); - stmt = conn.prepareStatement(deleteSql); - isAllocatedStmt = conn.prepareStatement(isPrivateIPAllocatedSelectSql); - } catch (SQLException e) { - System.out.println("Exception: " + e.getMessage()); - printError("Unable to start DB connection to delete private IPs. Please contact Cloud Support."); - } - - while (startIP <= endIP) { - if (!isPrivateIPAllocated(NetUtils.long2Ip(startIP), podId, zoneId, isAllocatedStmt)) { - try { - stmt.clearParameters(); - stmt.setString(1, NetUtils.long2Ip(startIP)); - stmt.setLong(2, podId); - stmt.setLong(3, zoneId); - stmt.executeUpdate(); - } catch (Exception ex) { + Connection conn = txn.getConnection(); + try (PreparedStatement stmt = conn.prepareStatement(deleteSql); + PreparedStatement isAllocatedStmt = conn.prepareStatement(isPrivateIPAllocatedSelectSql);) { + while (startIP <= endIP) { + if (!isPrivateIPAllocated(NetUtils.long2Ip(startIP), podId, zoneId, isAllocatedStmt)) { + stmt.clearParameters(); + stmt.setString(1, NetUtils.long2Ip(startIP)); + stmt.setLong(2, podId); + stmt.setLong(3, zoneId); + stmt.executeUpdate(); + } else { + problemIPs.add(NetUtils.long2Ip(startIP)); + } + startIP += 1; } - } else { - problemIPs.add(NetUtils.long2Ip(startIP)); + } catch (SQLException e) { + System.out.println("deletePrivateIPRange. Exception: " + e.getMessage()); + printError("deletePrivateIPRange. Exception: " + e.getMessage()); } - startIP += 1; + }catch (SQLException e) { + System.out.println("deletePrivateIPRange. Exception: " + e.getMessage()); + printError("deletePrivateIPRange. Exception: " + e.getMessage()); } - return problemIPs; } private boolean isPublicIPAllocated(long ip, long vlanDbId, PreparedStatement stmt) { - try { + try(ResultSet rs = stmt.executeQuery();) { stmt.clearParameters(); stmt.setLong(1, ip); stmt.setLong(2, vlanDbId); - ResultSet rs = stmt.executeQuery(); if (rs.next()) { return (rs.getString("allocated") != null); } else { return false; } - } catch (SQLException ex) { + } + catch (SQLException ex) { System.out.println(ex.getMessage()); return true; } @@ -408,11 +402,16 @@ private boolean isPrivateIPAllocated(String ip, long podId, long zoneId, Prepare stmt.setString(1, ip); stmt.setLong(2, zoneId); stmt.setLong(3, podId); - ResultSet rs = stmt.executeQuery(); - if (rs.next()) { - return (rs.getString("taken") != null); - } else { - return false; + try(ResultSet rs = stmt.executeQuery();) { + if (rs.next()) { + return (rs.getString("taken") != null); + } else { + return false; + } + } + catch (Exception ex) { + System.out.println(ex.getMessage()); + return true; } } catch (SQLException ex) { System.out.println(ex.getMessage()); @@ -451,7 +450,6 @@ public Vector savePublicIPRange(TransactionLegacy txn, long startIP, lon "INSERT INTO `cloud`.`user_ip_address` (public_ip_address, data_center_id, vlan_db_id, mac_address, source_network_id, physical_network_id, uuid) VALUES (?, ?, ?, (select mac_address from `cloud`.`data_center` where id=?), ?, ?, ?)"; String updateSql = "UPDATE `cloud`.`data_center` set mac_address = mac_address+1 where id=?"; Vector problemIPs = new Vector(); - PreparedStatement stmt = null; Connection conn = null; try { @@ -459,23 +457,20 @@ public Vector savePublicIPRange(TransactionLegacy txn, long startIP, lon } catch (SQLException e) { return null; } - while (startIP <= endIP) { - try { - stmt = conn.prepareStatement(insertSql); - stmt.setString(1, NetUtils.long2Ip(startIP)); - stmt.setLong(2, zoneId); - stmt.setLong(3, vlanDbId); - stmt.setLong(4, zoneId); - stmt.setLong(5, sourceNetworkId); - stmt.setLong(6, physicalNetworkId); - stmt.setString(7, UUID.randomUUID().toString()); - stmt.executeUpdate(); - stmt.close(); - stmt = conn.prepareStatement(updateSql); - stmt.setLong(1, zoneId); - stmt.executeUpdate(); - stmt.close(); + try (PreparedStatement insert_stmt = conn.prepareStatement(insertSql); + PreparedStatement update_stmt = conn.prepareStatement(updateSql); + ){ + insert_stmt.setString(1, NetUtils.long2Ip(startIP)); + insert_stmt.setLong(2, zoneId); + insert_stmt.setLong(3, vlanDbId); + insert_stmt.setLong(4, zoneId); + insert_stmt.setLong(5, sourceNetworkId); + insert_stmt.setLong(6, physicalNetworkId); + insert_stmt.setString(7, UUID.randomUUID().toString()); + insert_stmt.executeUpdate(); + update_stmt.setLong(1, zoneId); + update_stmt.executeUpdate(); } catch (Exception ex) { problemIPs.add(NetUtils.long2Ip(startIP)); } @@ -492,21 +487,19 @@ public List savePrivateIPRange(TransactionLegacy txn, long startIP, long Vector problemIPs = new Vector(); try { - Connection conn = null; - conn = txn.getConnection(); + Connection conn = txn.getConnection(); while (startIP <= endIP) { - try { - PreparedStatement stmt = conn.prepareStatement(insertSql); - stmt.setString(1, NetUtils.long2Ip(startIP)); - stmt.setLong(2, zoneId); - stmt.setLong(3, podId); - stmt.setLong(4, zoneId); - stmt.executeUpdate(); - stmt.close(); - stmt = conn.prepareStatement(updateSql); - stmt.setLong(1, zoneId); - stmt.executeUpdate(); - stmt.close(); + try (PreparedStatement insert_stmt = conn.prepareStatement(insertSql); + PreparedStatement update_stmt = conn.prepareStatement(updateSql); + ) + { + insert_stmt.setString(1, NetUtils.long2Ip(startIP)); + insert_stmt.setLong(2, zoneId); + insert_stmt.setLong(3, podId); + insert_stmt.setLong(4, zoneId); + insert_stmt.executeUpdate(); + update_stmt.setLong(1, zoneId); + update_stmt.executeUpdate(); } catch (Exception e) { problemIPs.add(NetUtils.long2Ip(startIP)); } @@ -531,10 +524,10 @@ private Vector saveLinkLocalPrivateIPRange(TransactionLegacy txn, long s System.out.println("Exception: " + e.getMessage()); printError("Unable to start DB connection to save private IPs. Please contact Cloud Support."); } + long start = startIP; - try { - long start = startIP; - PreparedStatement stmt = conn.prepareStatement(insertSql); + try(PreparedStatement stmt = conn.prepareStatement(insertSql);) + { while (startIP <= endIP) { stmt.setString(1, NetUtils.long2Ip(startIP++)); stmt.setLong(2, zoneId); @@ -547,10 +540,9 @@ private Vector saveLinkLocalPrivateIPRange(TransactionLegacy txn, long s problemIPs.add(NetUtils.long2Ip(start + (i / 2))); } } - stmt.close(); } catch (Exception ex) { + System.out.println("saveLinkLocalPrivateIPRange. Exception: " + ex.getMessage()); } - return problemIPs; } diff --git a/server/src/com/cloud/user/AccountManager.java b/server/src/com/cloud/user/AccountManager.java index 03bf8421a3..194c5d212f 100755 --- a/server/src/com/cloud/user/AccountManager.java +++ b/server/src/com/cloud/user/AccountManager.java @@ -24,6 +24,7 @@ import org.apache.cloudstack.api.command.admin.user.DeleteUserCmd; import org.apache.cloudstack.api.command.admin.user.UpdateUserCmd; +import com.cloud.api.query.vo.ControlledViewEntity; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.projects.Project.ListProjectResourcesCriteria; @@ -84,22 +85,21 @@ public interface AccountManager extends AccountService { boolean enableAccount(long accountId); - // new ACL model routine for query api based on db views - void buildACLSearchParameters(Account caller, Long id, - String accountName, Long projectId, List permittedDomains, List permittedAccounts, List permittedResources, - Ternary domainIdRecursiveListProject, boolean listAll, boolean forProjectInvitation, String action); + void buildACLSearchBuilder(SearchBuilder sb, Long domainId, + boolean isRecursive, List permittedAccounts, ListProjectResourcesCriteria listProjectResourcesCriteria); + + void buildACLViewSearchBuilder(SearchBuilder sb, Long domainId, + boolean isRecursive, List permittedAccounts, ListProjectResourcesCriteria listProjectResourcesCriteria); - void buildACLSearchBuilder(SearchBuilder sb, boolean isRecursive, - List permittedDomains, - List permittedAccounts, List permittedResources, ListProjectResourcesCriteria listProjectResourcesCriteria); + void buildACLSearchCriteria(SearchCriteria sc, + Long domainId, boolean isRecursive, List permittedAccounts, ListProjectResourcesCriteria listProjectResourcesCriteria); - void buildACLSearchCriteria(SearchCriteria sc, boolean isRecursive, - List permittedDomains, - List permittedAccounts, List permittedResources, ListProjectResourcesCriteria listProjectResourcesCriteria); + void buildACLSearchParameters(Account caller, Long id, + String accountName, Long projectId, List permittedAccounts, Ternary domainIdRecursiveListProject, boolean listAll, + boolean forProjectInvitation); - void buildACLViewSearchCriteria(SearchCriteria sc, SearchCriteria aclSc, boolean isRecursive, - List permittedDomains, List permittedAccounts, - List permittedResources, ListProjectResourcesCriteria listProjectResourcesCriteria); + void buildACLViewSearchCriteria(SearchCriteria sc, + Long domainId, boolean isRecursive, List permittedAccounts, ListProjectResourcesCriteria listProjectResourcesCriteria); /** diff --git a/server/src/com/cloud/user/AccountManagerImpl.java b/server/src/com/cloud/user/AccountManagerImpl.java index f0d129a3ce..decbedfeea 100755 --- a/server/src/com/cloud/user/AccountManagerImpl.java +++ b/server/src/com/cloud/user/AccountManagerImpl.java @@ -48,7 +48,6 @@ import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.affinity.AffinityGroup; import org.apache.cloudstack.affinity.dao.AffinityGroupDao; -import org.apache.cloudstack.api.InternalIdentity; import org.apache.cloudstack.api.command.admin.account.UpdateAccountCmd; import org.apache.cloudstack.api.command.admin.user.DeleteUserCmd; import org.apache.cloudstack.api.command.admin.user.RegisterCmd; @@ -62,6 +61,7 @@ import org.apache.cloudstack.region.gslb.GlobalLoadBalancerRuleDao; import com.cloud.api.ApiDBUtils; +import com.cloud.api.query.vo.ControlledViewEntity; import com.cloud.configuration.Config; import com.cloud.configuration.ConfigurationManager; import com.cloud.configuration.Resource.ResourceOwnerType; @@ -76,7 +76,6 @@ import com.cloud.dc.dao.DedicatedResourceDao; import com.cloud.domain.Domain; import com.cloud.domain.DomainVO; -import com.cloud.domain.PartOf; import com.cloud.domain.dao.DomainDao; import com.cloud.event.ActionEvent; import com.cloud.event.ActionEventUtils; @@ -111,6 +110,7 @@ import com.cloud.network.vpn.Site2SiteVpnManager; import com.cloud.projects.Project; import com.cloud.projects.Project.ListProjectResourcesCriteria; +import com.cloud.projects.ProjectInvitationVO; import com.cloud.projects.ProjectManager; import com.cloud.projects.ProjectVO; import com.cloud.projects.dao.ProjectAccountDao; @@ -361,20 +361,34 @@ public AccountVO getSystemAccount() { } @Override - public boolean isAdmin(short accountType) { - return ((accountType == Account.ACCOUNT_TYPE_ADMIN) || (accountType == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) || - (accountType == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) || (accountType == Account.ACCOUNT_TYPE_READ_ONLY_ADMIN)); + public boolean isAdmin(Long accountId) { + if (accountId != null) { + AccountVO acct = _accountDao.findById(accountId); + if (acct == null) { + return false; //account is deleted or does not exist + } + if ((isRootAdmin(accountId)) || (isDomainAdmin(accountId)) || (isResourceDomainAdmin(accountId))) { + return true; + } else if (acct.getType() == Account.ACCOUNT_TYPE_READ_ONLY_ADMIN) { + return true; + } + + } + return false; } @Override public boolean isRootAdmin(Long accountId) { if (accountId != null) { AccountVO acct = _accountDao.findById(accountId); + if (acct == null) { + return false; //account is deleted or does not exist + } for (SecurityChecker checker : _securityCheckers) { try { if (checker.checkAccess(acct, null, null, "SystemCapability")) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Root Access granted to " + acct + " by " + checker.getName()); + if (s_logger.isTraceEnabled()) { + s_logger.trace("Root Access granted to " + acct + " by " + checker.getName()); } return true; } @@ -390,11 +404,14 @@ public boolean isRootAdmin(Long accountId) { public boolean isDomainAdmin(Long accountId) { if (accountId != null) { AccountVO acct = _accountDao.findById(accountId); + if (acct == null) { + return false; //account is deleted or does not exist + } for (SecurityChecker checker : _securityCheckers) { try { if (checker.checkAccess(acct, null, null, "DomainCapability")) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Root Access granted to " + acct + " by " + checker.getName()); + if (s_logger.isTraceEnabled()) { + s_logger.trace("DomainAdmin Access granted to " + acct + " by " + checker.getName()); } return true; } @@ -415,12 +432,33 @@ public boolean isNormalUser(long accountId) { return false; } - public boolean isResourceDomainAdmin(short accountType) { - return (accountType == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN); + public boolean isResourceDomainAdmin(Long accountId) { + if (accountId != null) { + AccountVO acct = _accountDao.findById(accountId); + if (acct == null) { + return false; //account is deleted or does not exist + } + for (SecurityChecker checker : _securityCheckers) { + try { + if (checker.checkAccess(acct, null, null, "DomainResourceCapability")) { + if (s_logger.isTraceEnabled()) { + s_logger.trace("ResourceDomainAdmin Access granted to " + acct + " by " + checker.getName()); + } + return true; + } + } catch (PermissionDeniedException ex) { + return false; + } + } + } + return false; } public boolean isInternalAccount(long accountId) { Account account = _accountDao.findById(accountId); + if (account == null) { + return false; //account is deleted or does not exist + } if (isRootAdmin(accountId) || (account.getType() == Account.ACCOUNT_ID_SYSTEM)) { return true; } @@ -442,13 +480,6 @@ public void checkAccess(Account caller, Domain domain) throws PermissionDeniedEx throw new PermissionDeniedException("There's no way to confirm " + caller + " has access to " + domain); } - @Override - public void checkAccess(Account account, AccessType accessType, boolean sameOwner, PartOf... entities) throws PermissionDeniedException { - // TODO Auto-generated method stub - - //TO BE IMPLEMENTED - - } @Override public void checkAccess(Account caller, AccessType accessType, boolean sameOwner, ControlledEntity... entities) { @@ -536,10 +567,31 @@ public void checkAccess(Account caller, AccessType accessType, boolean sameOwner } + private Domain getEntityDomain(ControlledEntity entity) { + Domain entityDomain = null; + long domainId = entity.getDomainId(); + + if (domainId != -1) { + entityDomain = _domainMgr.getDomain(domainId); + } else { + if (entity.getAccountId() != -1) { + // If account exists domainId should too so + // calculate + // it. This condition might be hit for templates or + // entities which miss domainId in their tables + Account account = getAccount(entity.getAccountId()); + domainId = account != null ? account.getDomainId() : -1; + entityDomain = _domainMgr.getDomain(domainId); + } + } + + return entityDomain; + } + @Override public Long checkAccessAndSpecifyAuthority(Account caller, Long zoneId) { // We just care for resource domain admin for now. He should be permitted to see only his zone. - if (isResourceDomainAdmin(caller.getType())) { + if (isResourceDomainAdmin(caller.getAccountId())) { if (zoneId == null) return getZoneIdForAccount(caller); else if (zoneId.compareTo(getZoneIdForAccount(caller)) != 0) @@ -660,8 +712,10 @@ protected boolean cleanupAccount(AccountVO account, long callerUserId, Account c // delete the account from project accounts _projectAccountDao.removeAccountFromProjects(accountId); - //delete the account from group - _messageBus.publish(_name, MESSAGE_REMOVE_ACCOUNT_EVENT, PublishScope.LOCAL, accountId); + if (account.getType() != Account.ACCOUNT_TYPE_PROJECT) { + // delete the account from group + _messageBus.publish(_name, MESSAGE_REMOVE_ACCOUNT_EVENT, PublishScope.LOCAL, accountId); + } // delete all vm groups belonging to accont List groups = _vmGroupDao.listByAccountId(accountId); @@ -1099,6 +1153,9 @@ public UserAccount updateUser(UpdateUserCmd cmd) { // If the account is an admin type, return an error. We do not allow this Account account = _accountDao.findById(user.getAccountId()); + if (account == null) { + throw new InvalidParameterValueException("unable to find user account " + user.getAccountId()); + } // don't allow updating project account if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) { @@ -1106,7 +1163,7 @@ public UserAccount updateUser(UpdateUserCmd cmd) { } // don't allow updating system account - if (account != null && (account.getId() == Account.ACCOUNT_ID_SYSTEM)) { + if (account.getId() == Account.ACCOUNT_ID_SYSTEM) { throw new PermissionDeniedException("user id : " + id + " is system account, update is not allowed"); } @@ -1213,6 +1270,9 @@ public UserAccount disableUser(long userId) { } Account account = _accountDao.findById(user.getAccountId()); + if (account == null) { + throw new InvalidParameterValueException("unable to find user account " + user.getAccountId()); + } // don't allow disabling user belonging to project's account if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) { @@ -1252,6 +1312,9 @@ public UserAccount enableUser(final long userId) { } Account account = _accountDao.findById(user.getAccountId()); + if (account == null) { + throw new InvalidParameterValueException("unable to find user account " + user.getAccountId()); + } if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) { throw new InvalidParameterValueException("Unable to find active user by id " + userId); @@ -1300,6 +1363,9 @@ public UserAccount lockUser(long userId) { } Account account = _accountDao.findById(user.getAccountId()); + if (account == null) { + throw new InvalidParameterValueException("unable to find user account " + user.getAccountId()); + } // don't allow to lock user of the account of type Project if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) { @@ -1365,7 +1431,7 @@ boolean deleteUserAccount(long accountId) { // If the user is a System user, return an error. We do not allow this AccountVO account = _accountDao.findById(accountId); - if (account.getRemoved() != null) { + if (account == null || account.getRemoved() != null) { s_logger.info("The account:" + account.getAccountName() + " is already removed"); return true; } @@ -1725,7 +1791,7 @@ public Account finalizeOwner(Account caller, String accountName, Long domainId, return getAccount(project.getProjectAccountId()); } - if (isAdmin(caller.getType()) && accountName != null && domainId != null) { + if (isAdmin(caller.getId()) && accountName != null && domainId != null) { Domain domain = _domainMgr.getDomain(domainId); if (domain == null) { throw new InvalidParameterValueException("Unable to find the domain by id=" + domainId); @@ -1738,7 +1804,7 @@ public Account finalizeOwner(Account caller, String accountName, Long domainId, checkAccess(caller, domain); return owner; - } else if (!isAdmin(caller.getType()) && accountName != null && domainId != null) { + } else if (!isAdmin(caller.getId()) && accountName != null && domainId != null) { if (!accountName.equals(caller.getAccountName()) || domainId.longValue() != caller.getDomainId()) { throw new PermissionDeniedException("Can't create/list resources for account " + accountName + " in domain " + domainId + ", permission denied"); } else { @@ -2099,7 +2165,7 @@ private UserAccount getUserAccount(String username, String password, Long domain UserAccount userAccount = _userAccountDao.getUserAccount(username, domainId); if (userAccount != null) { if (userAccount.getState().equalsIgnoreCase(Account.State.enabled.toString())) { - if (!isInternalAccount(userAccount.getType())) { + if (!isInternalAccount(userAccount.getId())) { // Internal accounts are not disabled int attemptsMade = userAccount.getLoginAttempts() + 1; if (updateIncorrectLoginCount) { @@ -2212,19 +2278,168 @@ private String createUserSecretKey(long userId) { } + @Override - public UserAccount getUserByApiKey(String apiKey) { - return _userAccountDao.getUserByApiKey(apiKey); + public void buildACLSearchBuilder(SearchBuilder sb, + Long domainId, boolean isRecursive, List permittedAccounts, ListProjectResourcesCriteria listProjectResourcesCriteria) { + + if (sb.entity() instanceof IPAddressVO) { + sb.and("accountIdIN", ((IPAddressVO) sb.entity()).getAllocatedToAccountId(), SearchCriteria.Op.IN); + sb.and("domainId", ((IPAddressVO) sb.entity()).getAllocatedInDomainId(), SearchCriteria.Op.EQ); + } else if (sb.entity() instanceof ProjectInvitationVO) { + sb.and("accountIdIN", ((ProjectInvitationVO) sb.entity()).getForAccountId(), SearchCriteria.Op.IN); + sb.and("domainId", ((ProjectInvitationVO) sb.entity()).getInDomainId(), SearchCriteria.Op.EQ); + } else { + sb.and("accountIdIN", sb.entity().getAccountId(), SearchCriteria.Op.IN); + sb.and("domainId", sb.entity().getDomainId(), SearchCriteria.Op.EQ); + } + + if (((permittedAccounts.isEmpty()) && (domainId != null) && isRecursive)) { + // if accountId isn't specified, we can do a domain match for the admin case if isRecursive is true + SearchBuilder domainSearch = _domainDao.createSearchBuilder(); + domainSearch.and("path", domainSearch.entity().getPath(), SearchCriteria.Op.LIKE); + + if (sb.entity() instanceof IPAddressVO) { + sb.join("domainSearch", domainSearch, ((IPAddressVO) sb.entity()).getAllocatedInDomainId(), domainSearch.entity().getId(), JoinBuilder.JoinType.INNER); + } else if (sb.entity() instanceof ProjectInvitationVO) { + sb.join("domainSearch", domainSearch, ((ProjectInvitationVO) sb.entity()).getInDomainId(), domainSearch.entity().getId(), JoinBuilder.JoinType.INNER); + } else { + sb.join("domainSearch", domainSearch, sb.entity().getDomainId(), domainSearch.entity().getId(), JoinBuilder.JoinType.INNER); + } + + } + if (listProjectResourcesCriteria != null) { + SearchBuilder accountSearch = _accountDao.createSearchBuilder(); + if (listProjectResourcesCriteria == Project.ListProjectResourcesCriteria.ListProjectResourcesOnly) { + accountSearch.and("type", accountSearch.entity().getType(), SearchCriteria.Op.EQ); + } else if (listProjectResourcesCriteria == Project.ListProjectResourcesCriteria.SkipProjectResources) { + accountSearch.and("type", accountSearch.entity().getType(), SearchCriteria.Op.NEQ); + } + + if (sb.entity() instanceof IPAddressVO) { + sb.join("accountSearch", accountSearch, ((IPAddressVO) sb.entity()).getAllocatedToAccountId(), accountSearch.entity().getId(), JoinBuilder.JoinType.INNER); + } else if (sb.entity() instanceof ProjectInvitationVO) { + sb.join("accountSearch", accountSearch, ((ProjectInvitationVO) sb.entity()).getForAccountId(), accountSearch.entity().getId(), JoinBuilder.JoinType.INNER); + } else { + sb.join("accountSearch", accountSearch, sb.entity().getAccountId(), accountSearch.entity().getId(), JoinBuilder.JoinType.INNER); + } + } } @Override - public void buildACLSearchParameters(Account caller, Long id, String accountName, Long projectId, List permittedDomains, List permittedAccounts, - List permittedResources, Ternary domainIdRecursiveListProject, boolean listAll, boolean forProjectInvitation, - String action) { - //TODO: need to handle listAll flag + public void buildACLSearchCriteria(SearchCriteria sc, + Long domainId, boolean isRecursive, List permittedAccounts, ListProjectResourcesCriteria listProjectResourcesCriteria) { + + if (listProjectResourcesCriteria != null) { + sc.setJoinParameters("accountSearch", "type", Account.ACCOUNT_TYPE_PROJECT); + } + + if (!permittedAccounts.isEmpty()) { + sc.setParameters("accountIdIN", permittedAccounts.toArray()); + } else if (domainId != null) { + DomainVO domain = _domainDao.findById(domainId); + if (isRecursive) { + sc.setJoinParameters("domainSearch", "path", domain.getPath() + "%"); + } else { + sc.setParameters("domainId", domainId); + } + } + } + +// @Override +// public void buildACLSearchParameters(Account caller, Long id, String accountName, Long projectId, List +// permittedAccounts, Ternary domainIdRecursiveListProject, +// boolean listAll, boolean forProjectInvitation) { +// Long domainId = domainIdRecursiveListProject.first(); +// if (domainId != null) { +// Domain domain = _domainDao.findById(domainId); +// if (domain == null) { +// throw new InvalidParameterValueException("Unable to find domain by id " + domainId); +// } +// // check permissions +// checkAccess(caller, domain); +// } +// +// if (accountName != null) { +// if (projectId != null) { +// throw new InvalidParameterValueException("Account and projectId can't be specified together"); +// } +// +// Account userAccount = null; +// Domain domain = null; +// if (domainId != null) { +// userAccount = _accountDao.findActiveAccount(accountName, domainId); +// domain = _domainDao.findById(domainId); +// } else { +// userAccount = _accountDao.findActiveAccount(accountName, caller.getDomainId()); +// domain = _domainDao.findById(caller.getDomainId()); +// } +// +// if (userAccount != null) { +// checkAccess(caller, null, false, userAccount); +// //check permissions +// permittedAccounts.add(userAccount.getId()); +// } else { +// throw new InvalidParameterValueException("could not find account " + accountName + " in domain " + domain.getUuid()); +// } +// } +// +// // set project information +// if (projectId != null) { +// if (!forProjectInvitation) { +// if (projectId.longValue() == -1) { +// if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL) { +// permittedAccounts.addAll(_projectMgr.listPermittedProjectAccounts(caller.getId())); +// } else { +// domainIdRecursiveListProject.third(Project.ListProjectResourcesCriteria.ListProjectResourcesOnly); +// } +// } else { +// Project project = _projectMgr.getProject(projectId); +// if (project == null) { +// throw new InvalidParameterValueException("Unable to find project by id " + projectId); +// } +// if (!_projectMgr.canAccessProjectAccount(caller, project.getProjectAccountId())) { +// throw new PermissionDeniedException("Account " + caller + " can't access project id=" + projectId); +// } +// permittedAccounts.add(project.getProjectAccountId()); +// } +// } +// } else { +// if (id == null) { +// domainIdRecursiveListProject.third(Project.ListProjectResourcesCriteria.SkipProjectResources); +// } +// if (permittedAccounts.isEmpty() && domainId == null) { +// if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL) { +// permittedAccounts.add(caller.getId()); +// } else if (!listAll) { +// if (id == null) { +// permittedAccounts.add(caller.getId()); +// } else if (!isRootAdmin(caller.getId())) { +// domainIdRecursiveListProject.first(caller.getDomainId()); +// domainIdRecursiveListProject.second(true); +// } +// } else if (domainId == null) { +// if (caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) { +// domainIdRecursiveListProject.first(caller.getDomainId()); +// domainIdRecursiveListProject.second(true); +// } +// } +// } else if (domainId != null) { +// if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL) { +// permittedAccounts.add(caller.getId()); +// } +// } +// +// } +// } + + //TODO: deprecate this to use the new buildACLSearchParameters with permittedDomains, permittedAccounts, and permittedResources as return + @Override + public void buildACLSearchParameters(Account caller, Long id, String accountName, Long projectId, List + permittedAccounts, Ternary domainIdRecursiveListProject, + boolean listAll, boolean forProjectInvitation) { Long domainId = domainIdRecursiveListProject.first(); if (domainId != null) { - // look for entity in the given domain Domain domain = _domainDao.findById(domainId); if (domain == null) { throw new InvalidParameterValueException("Unable to find domain by id " + domainId); @@ -2249,8 +2464,8 @@ public void buildACLSearchParameters(Account caller, Long id, String accountName } if (userAccount != null) { - //check permissions checkAccess(caller, null, false, userAccount); + // check permissions permittedAccounts.add(userAccount.getId()); } else { throw new InvalidParameterValueException("could not find account " + accountName + " in domain " + domain.getUuid()); @@ -2261,7 +2476,7 @@ public void buildACLSearchParameters(Account caller, Long id, String accountName if (projectId != null) { if (!forProjectInvitation) { if (projectId.longValue() == -1) { - if (isNormalUser(caller.getId())) { + if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL) { permittedAccounts.addAll(_projectMgr.listPermittedProjectAccounts(caller.getId())); } else { domainIdRecursiveListProject.third(Project.ListProjectResourcesCriteria.ListProjectResourcesOnly); @@ -2278,203 +2493,87 @@ public void buildACLSearchParameters(Account caller, Long id, String accountName } } } else { - domainIdRecursiveListProject.third(Project.ListProjectResourcesCriteria.SkipProjectResources); - - // search for policy permissions associated with caller to get all his authorized domains, accounts, and resources - // Assumption: if a domain is in grantedDomains, then all the accounts under this domain will not be returned in "grantedAccounts". Similarly, if an account - // is in grantedAccounts, then all the resources owned by this account will not be returned in "grantedResources". - // assume that there is only one query selector adapter - if (_querySelectors == null || _querySelectors.size() == 0) - return; // no futher filtering - - QuerySelector qs = _querySelectors.get(0); - boolean grantedAll = qs.isGrantedAll(caller, action); - if ( grantedAll ){ - if ( domainId != null ){ - permittedDomains.add(domainId); - } - } - else { - List grantedDomains = qs.getAuthorizedDomains(caller, action); - List grantedAccounts = qs.getAuthorizedAccounts(caller, action); - List grantedResources = qs.getAuthorizedResources(caller, action); - - if (permittedAccounts.isEmpty() && domainId != null) { - // specific domain and no account is specified - if (grantedDomains.contains(domainId)) { - permittedDomains.add(domainId); - } else { - for (Long acctId : grantedAccounts) { - Account acct = _accountDao.findById(acctId); - if (acct != null && acct.getDomainId() == domainId) { - permittedAccounts.add(acctId); - } - } - permittedResources.addAll(grantedResources); + if (id == null) { + domainIdRecursiveListProject.third(Project.ListProjectResourcesCriteria.SkipProjectResources); + } + if (permittedAccounts.isEmpty() && domainId == null) { + if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL) { + permittedAccounts.add(caller.getId()); + } else if (!listAll) { + if (id == null) { + permittedAccounts.add(caller.getId()); + } else if (caller.getType() != Account.ACCOUNT_TYPE_ADMIN) { + domainIdRecursiveListProject.first(caller.getDomainId()); + domainIdRecursiveListProject.second(true); + } + } else if (domainId == null) { + if (caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) { + domainIdRecursiveListProject.first(caller.getDomainId()); + domainIdRecursiveListProject.second(true); } - } else if (permittedAccounts.isEmpty()) { - // neither domain nor account is not specified - permittedDomains.addAll(grantedDomains); - permittedAccounts.addAll(grantedAccounts); - permittedResources.addAll(grantedResources); + } + } else if (domainId != null) { + if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL) { + permittedAccounts.add(caller.getId()); } } + } + } + @Override - public void buildACLSearchBuilder(SearchBuilder sb, boolean isRecursive, - List permittedDomains, - List permittedAccounts, List permittedResources, ListProjectResourcesCriteria listProjectResourcesCriteria) { + public void buildACLViewSearchBuilder(SearchBuilder sb, Long domainId, + boolean isRecursive, List permittedAccounts, ListProjectResourcesCriteria listProjectResourcesCriteria) { + + sb.and("accountIdIN", sb.entity().getAccountId(), SearchCriteria.Op.IN); + sb.and("domainId", sb.entity().getDomainId(), SearchCriteria.Op.EQ); + + if (((permittedAccounts.isEmpty()) && (domainId != null) && isRecursive)) { + // if accountId isn't specified, we can do a domain match for the + // admin case if isRecursive is true + sb.and("domainPath", sb.entity().getDomainPath(), SearchCriteria.Op.LIKE); + } if (listProjectResourcesCriteria != null) { - // add criteria for project or not - SearchBuilder accountSearch = _accountDao.createSearchBuilder(); if (listProjectResourcesCriteria == Project.ListProjectResourcesCriteria.ListProjectResourcesOnly) { - accountSearch.and("type", accountSearch.entity().getType(), SearchCriteria.Op.EQ); + sb.and("accountType", sb.entity().getAccountType(), SearchCriteria.Op.EQ); } else if (listProjectResourcesCriteria == Project.ListProjectResourcesCriteria.SkipProjectResources) { - accountSearch.and("type", accountSearch.entity().getType(), SearchCriteria.Op.NEQ); - } - - if (sb.entity() instanceof IPAddressVO) { - sb.join("accountSearch", accountSearch, ((IPAddressVO)sb.entity()).getAllocatedToAccountId(), accountSearch.entity().getId(), JoinBuilder.JoinType.INNER); - } else { - sb.join("accountSearch", accountSearch, sb.entity().getAccountId(), accountSearch.entity().getId(), JoinBuilder.JoinType.INNER); + sb.and("accountType", sb.entity().getAccountType(), SearchCriteria.Op.NEQ); } } - if (permittedDomains.isEmpty() && permittedAccounts.isEmpty() && permittedResources.isEmpty()) - // can access everything - return; - if (!permittedAccounts.isEmpty() || !permittedResources.isEmpty()) { - if (!permittedAccounts.isEmpty()) { - if (sb.entity() instanceof IPAddressVO) { - sb.and().op("accountIdIn", ((IPAddressVO)sb.entity()).getAllocatedToAccountId(), SearchCriteria.Op.IN); - } else { - sb.and().op("accountIdIn", sb.entity().getAccountId(), SearchCriteria.Op.IN); - } - if (!permittedResources.isEmpty()) { - sb.or("idIn", ((InternalIdentity)sb.entity()).getId(), SearchCriteria.Op.IN); - } - } else { - // permittedResources is not empty - sb.and().op("idIn", ((InternalIdentity)sb.entity()).getId(), SearchCriteria.Op.IN); - } - if (!permittedDomains.isEmpty()) { - if (isRecursive) { - SearchBuilder domainSearch = _domainDao.createSearchBuilder(); - for (int i = 0; i < permittedDomains.size(); i++) { - domainSearch.or("path" + i, domainSearch.entity().getPath(), SearchCriteria.Op.LIKE); - } - if (sb.entity() instanceof IPAddressVO) { - sb.join("domainSearch", domainSearch, ((IPAddressVO)sb.entity()).getAllocatedInDomainId(), domainSearch.entity().getId(), JoinBuilder.JoinType.INNER); - } else { - sb.join("domainSearch", domainSearch, sb.entity().getDomainId(), domainSearch.entity().getId(), JoinBuilder.JoinType.INNER); - } - } else { - if (sb.entity() instanceof IPAddressVO) { - sb.or("domainIdIn", ((IPAddressVO)sb.entity()).getAllocatedInDomainId(), SearchCriteria.Op.IN); - } else { - sb.or("domainIdIn", sb.entity().getDomainId(), SearchCriteria.Op.IN); - } - } - } - sb.cp(); - } else { - // permittedDomains is not empty - if (isRecursive) { - SearchBuilder domainSearch = _domainDao.createSearchBuilder(); - domainSearch.and().op("path0", domainSearch.entity().getPath(), SearchCriteria.Op.LIKE); - for (int i = 1; i < permittedDomains.size(); i++) { - domainSearch.or("path" + i, domainSearch.entity().getPath(), SearchCriteria.Op.LIKE); - } - domainSearch.cp(); - if (sb.entity() instanceof IPAddressVO) { - sb.join("domainSearch", domainSearch, ((IPAddressVO)sb.entity()).getAllocatedInDomainId(), domainSearch.entity().getId(), JoinBuilder.JoinType.INNER); - } else { - sb.join("domainSearch", domainSearch, sb.entity().getDomainId(), domainSearch.entity().getId(), JoinBuilder.JoinType.INNER); - } - } else { - if (sb.entity() instanceof IPAddressVO) { - sb.and().op("domainIdIn", ((IPAddressVO)sb.entity()).getAllocatedInDomainId(), SearchCriteria.Op.IN); - } else { - sb.and().op("domainIdIn", sb.entity().getDomainId(), SearchCriteria.Op.IN); - } - sb.cp(); - } - } } - @Override - public void buildACLSearchCriteria(SearchCriteria sc, boolean isRecursive, - List permittedDomains, - List permittedAccounts, List permittedResources, ListProjectResourcesCriteria listProjectResourcesCriteria) { + @Override + public void buildACLViewSearchCriteria(SearchCriteria sc, + Long domainId, boolean isRecursive, List permittedAccounts, ListProjectResourcesCriteria listProjectResourcesCriteria) { if (listProjectResourcesCriteria != null) { - sc.setJoinParameters("accountSearch", "type", Account.ACCOUNT_TYPE_PROJECT); + sc.setParameters("accountType", Account.ACCOUNT_TYPE_PROJECT); } - if (permittedDomains.isEmpty() && permittedAccounts.isEmpty() && permittedResources.isEmpty()) - // can access everything - return; - if (!permittedAccounts.isEmpty()) { - sc.setParameters("accountIdIn", permittedAccounts.toArray()); - } - if (!permittedResources.isEmpty()) { - sc.setParameters("idIn", permittedResources.toArray()); - } - if (!permittedDomains.isEmpty()) { + sc.setParameters("accountIdIN", permittedAccounts.toArray()); + } else if (domainId != null) { + DomainVO domain = _domainDao.findById(domainId); if (isRecursive) { - for (int i = 0; i < permittedDomains.size(); i++) { - DomainVO domain = _domainDao.findById(permittedDomains.get(i)); - sc.setJoinParameters("domainSearch", "path" + i, domain.getPath() + "%"); - } + sc.setParameters("domainPath", domain.getPath() + "%"); } else { - sc.setParameters("domainIdIn", permittedDomains.toArray()); - } - } - } - - @Override - public void buildACLViewSearchCriteria(SearchCriteria sc, SearchCriteria aclSc, boolean isRecursive, - List permittedDomains, - List permittedAccounts, List permittedResources, ListProjectResourcesCriteria listProjectResourcesCriteria) { - - if (listProjectResourcesCriteria != null) { - // add criteria for project or not - if (listProjectResourcesCriteria == ListProjectResourcesCriteria.SkipProjectResources) { - sc.addAnd("accountType", SearchCriteria.Op.NEQ, Account.ACCOUNT_TYPE_PROJECT); - } else if (listProjectResourcesCriteria == ListProjectResourcesCriteria.ListProjectResourcesOnly) { - sc.addAnd("accountType", SearchCriteria.Op.EQ, Account.ACCOUNT_TYPE_PROJECT); + sc.setParameters("domainId", domainId); } } - if (permittedDomains.isEmpty() && permittedAccounts.isEmpty() && permittedResources.isEmpty()) - // can access everything - return; + } - // Note that this may have limitations on number of permitted domains, accounts, or resource ids are allowed due to sql package size limitation - if (!permittedDomains.isEmpty()) { - if (isRecursive) { - for (int i = 0; i < permittedDomains.size(); i++) { - Domain domain = _domainDao.findById(permittedDomains.get(i)); - aclSc.addOr("domainPath", SearchCriteria.Op.LIKE, domain.getPath() + "%"); - } - } else { - aclSc.addOr("domainId", SearchCriteria.Op.IN, permittedDomains.toArray()); - } - } - if (!permittedAccounts.isEmpty()) { - aclSc.addOr("accountId", SearchCriteria.Op.IN, permittedAccounts.toArray()); - } - if (!permittedResources.isEmpty()) { - aclSc.addOr("id", SearchCriteria.Op.IN, permittedResources.toArray()); - } - sc.addAnd("accountId", SearchCriteria.Op.SC, aclSc); + @Override + public UserAccount getUserByApiKey(String apiKey) { + return _userAccountDao.getUserByApiKey(apiKey); } + @Override public List listAclGroupsByAccount(Long accountId) { if (_querySelectors == null || _querySelectors.size() == 0) @@ -2530,4 +2629,9 @@ public Long finalyzeAccountId(final String accountName, final Long domainId, fin } return null; } + + @Override + public UserAccount getUserAccountById(Long userId) { + return _userAccountDao.findById(userId); + } } diff --git a/server/src/com/cloud/user/DomainManagerImpl.java b/server/src/com/cloud/user/DomainManagerImpl.java index fbbe0c2870..fe6e530ccb 100644 --- a/server/src/com/cloud/user/DomainManagerImpl.java +++ b/server/src/com/cloud/user/DomainManagerImpl.java @@ -227,7 +227,11 @@ public Set getDomainParentIds(long domainId) { @Override public boolean removeDomain(long domainId) { - return _domainDao.remove(domainId); + boolean removed = _domainDao.remove(domainId); + if (removed) { + _messageBus.publish(_name, MESSAGE_REMOVE_DOMAIN_EVENT, PublishScope.LOCAL, domainId); + } + return removed; } @Override @@ -324,6 +328,9 @@ public boolean deleteDomain(DomainVO domain, Boolean cleanup) { " because it can't be removed due to resources referencing to it"); domain.setState(Domain.State.Active); _domainDao.update(domain.getId(), domain); + } else { + // succeeded in removing the domain + _messageBus.publish(_name, MESSAGE_REMOVE_DOMAIN_EVENT, PublishScope.LOCAL, domain.getId()); } } } diff --git a/server/src/com/cloud/vm/UserVmManager.java b/server/src/com/cloud/vm/UserVmManager.java index afe1002788..61e28d81bd 100755 --- a/server/src/com/cloud/vm/UserVmManager.java +++ b/server/src/com/cloud/vm/UserVmManager.java @@ -109,4 +109,6 @@ UserVm updateVirtualMachine(long id, String displayName, String group, Boolean h public void saveCustomOfferingDetails(long vmId, ServiceOffering serviceOffering); public void removeCustomOfferingDetails(long vmId); + + void generateUsageEvent(VirtualMachine vm, boolean isDisplay, String eventType); } diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index 393613a140..425598cedf 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -35,6 +35,7 @@ import javax.inject.Inject; import javax.naming.ConfigurationException; +import com.cloud.server.ManagementService; import org.apache.commons.codec.binary.Base64; import org.apache.log4j.Logger; @@ -47,7 +48,6 @@ import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseCmd.HTTPMethod; import org.apache.cloudstack.api.command.admin.vm.AssignVMCmd; -import org.apache.cloudstack.api.command.admin.vm.ExpungeVMCmd; import org.apache.cloudstack.api.command.admin.vm.RecoverVMCmd; import org.apache.cloudstack.api.command.user.vm.AddNicToVMCmd; import org.apache.cloudstack.api.command.user.vm.DeployVMCmd; @@ -69,6 +69,9 @@ import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService; import org.apache.cloudstack.engine.service.api.OrchestrationService; +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.PrimaryDataStore; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; @@ -80,11 +83,14 @@ import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.cloudstack.framework.jobs.AsyncJobManager; import org.apache.cloudstack.managed.context.ManagedContextRunnable; +import org.apache.cloudstack.storage.command.DeleteCommand; +import org.apache.cloudstack.storage.command.DettachCommand; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; +import com.cloud.agent.api.Command; import com.cloud.agent.api.GetVmDiskStatsAnswer; import com.cloud.agent.api.GetVmDiskStatsCommand; import com.cloud.agent.api.GetVmStatsAnswer; @@ -93,6 +99,7 @@ import com.cloud.agent.api.StartAnswer; import com.cloud.agent.api.VmDiskStatsEntry; import com.cloud.agent.api.VmStatsEntry; +import com.cloud.agent.api.to.DiskTO; import com.cloud.agent.api.to.NicTO; import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.agent.manager.Commands; @@ -191,6 +198,7 @@ import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.service.dao.ServiceOfferingDetailsDao; +import com.cloud.storage.DataStoreRole; import com.cloud.storage.DiskOfferingVO; import com.cloud.storage.GuestOSCategoryVO; import com.cloud.storage.GuestOSVO; @@ -204,6 +212,7 @@ import com.cloud.storage.VMTemplateVO; import com.cloud.storage.VMTemplateZoneVO; import com.cloud.storage.Volume; +import com.cloud.storage.VolumeApiService; import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.DiskOfferingDao; import com.cloud.storage.dao.GuestOSCategoryDao; @@ -235,7 +244,6 @@ import com.cloud.utils.Journal; import com.cloud.utils.NumbersUtil; import com.cloud.utils.Pair; -import com.cloud.utils.PasswordGenerator; import com.cloud.utils.component.ManagerBase; import com.cloud.utils.concurrency.NamedThreadFactory; import com.cloud.utils.crypt.RSAHelper; @@ -445,6 +453,12 @@ public enum UserVmCloneType { UUIDManager _uuidMgr; @Inject DeploymentPlanningManager _planningMgr; + @Inject + VolumeApiService _volumeService; + @Inject + DataStoreManager _dataStoreMgr; + @Inject + ManagementService _mgr; protected ScheduledExecutorService _executor = null; protected int _expungeInterval; @@ -630,7 +644,7 @@ public UserVm resetVMSSHKey(ResetVMSSHKeyCmd cmd) throws ResourceUnavailableExce String password = null; String sshPublicKey = s.getPublicKey(); if (template != null && template.getEnablePassword()) { - password = generateRandomPassword(); + password = _mgr.generateRandomPassword(); } boolean result = resetVMSSHKeyInternal(vmId, sshPublicKey, password); @@ -828,9 +842,10 @@ public UserVm upgradeVirtualMachine(UpgradeVMCmd cmd) throws ResourceAllocationE } // Generate usage event for VM upgrade - generateUsageEvent(newServiceOffering, cmd.getDetails(), _vmDao.findById(vmId), EventTypes.EVENT_VM_UPGRADE); + UserVmVO userVm = _vmDao.findById(vmId); + generateUsageEvent( userVm, userVm.isDisplayVm(), EventTypes.EVENT_VM_UPGRADE); - return _vmDao.findById(vmInstance.getId()); + return userVm; } @Override @@ -944,6 +959,7 @@ private UserVm upgradeStoppedVirtualMachine(Long vmId, Long svcOffId, Map params) throws Configu _itMgr.registerGuru(VirtualMachine.Type.User, this); - VirtualMachine.State.getStateMachine().registerListener(new UserVmStateListener(_usageEventDao, _networkDao, _nicDao, _offeringDao)); + VirtualMachine.State.getStateMachine().registerListener(new UserVmStateListener(_usageEventDao, _networkDao, _nicDao, _offeringDao, _vmDao, this)); String value = _configDao.getValue(Config.SetVmInternalNameUsingDisplayName.key()); _instanceNameFlag = (value == null) ? false : Boolean.parseBoolean(value); @@ -1799,7 +1817,7 @@ protected void runInContext() { } for (UserVmVO vm : vms) { try { - expunge(vm, _accountMgr.getSystemUser().getId(), _accountMgr.getSystemAccount()); + expungeVm(vm.getId()); } catch (Exception e) { s_logger.warn("Unable to expunge " + vm, e); } @@ -1829,6 +1847,7 @@ public UserVm updateVirtualMachine(UpdateVMCmd cmd) throws ResourceUnavailableEx String userData = cmd.getUserData(); Boolean isDynamicallyScalable = cmd.isDynamicallyScalable(); String hostName = cmd.getHostName(); + Account caller = CallContext.current().getCallingAccount(); // Input validation and permission checks UserVmVO vmInstance = _vmDao.findById(id.longValue()); @@ -1840,15 +1859,81 @@ public UserVm updateVirtualMachine(UpdateVMCmd cmd) throws ResourceUnavailableEx //If the flag is specified and is changed if (isDisplayVm != null && isDisplayVm != vmInstance.isDisplayVm()) { + + //update vm + vmInstance.setDisplayVm(isDisplayVm); + + // Resource limit changes ServiceOffering offering = _serviceOfferingDao.findByIdIncludingRemoved(vmInstance.getServiceOfferingId()); _resourceLimitMgr.changeResourceCount(vmInstance.getAccountId(), ResourceType.user_vm, isDisplayVm); _resourceLimitMgr.changeResourceCount(vmInstance.getAccountId(), ResourceType.cpu, isDisplayVm, new Long(offering.getCpu())); _resourceLimitMgr.changeResourceCount(vmInstance.getAccountId(), ResourceType.memory, isDisplayVm, new Long(offering.getRamSize())); + + // Usage + saveUsageEvent(vmInstance); + + // take care of the root volume as well. + List rootVols = _volsDao.findByInstanceAndType(id, Volume.Type.ROOT); + if(!rootVols.isEmpty()){ + _volumeService.updateDisplay(rootVols.get(0), isDisplayVm); + } + + // take care of the data volumes as well. + List dataVols = _volsDao.findByInstanceAndType(id, Volume.Type.DATADISK); + for(Volume dataVol : dataVols){ + _volumeService.updateDisplay(dataVol, isDisplayVm); + } + } return updateVirtualMachine(id, displayName, group, ha, isDisplayVm, osTypeId, userData, isDynamicallyScalable, cmd.getHttpMethod(), cmd.getCustomId(), hostName); } + private void saveUsageEvent(UserVmVO vm) { + + // If vm not destroyed + if( vm.getState() != State.Destroyed && vm.getState() != State.Expunging && vm.getState() != State.Error){ + + if(vm.isDisplayVm()){ + //1. Allocated VM Usage Event + generateUsageEvent(vm, true, EventTypes.EVENT_VM_CREATE); + + if(vm.getState() == State.Running || vm.getState() == State.Stopping){ + //2. Running VM Usage Event + generateUsageEvent(vm, true, EventTypes.EVENT_VM_START); + + // 3. Network offering usage + generateNetworkUsageForVm(vm, true, EventTypes.EVENT_NETWORK_OFFERING_ASSIGN); + } + + }else { + //1. Allocated VM Usage Event + generateUsageEvent(vm, true, EventTypes.EVENT_VM_DESTROY); + + if(vm.getState() == State.Running || vm.getState() == State.Stopping){ + //2. Running VM Usage Event + generateUsageEvent(vm, true, EventTypes.EVENT_VM_STOP); + + // 3. Network offering usage + generateNetworkUsageForVm(vm, true, EventTypes.EVENT_NETWORK_OFFERING_REMOVE); + } + } + } + + } + + private void generateNetworkUsageForVm(VirtualMachine vm, boolean isDisplay, String eventType){ + + List nics = _nicDao.listByVmId(vm.getId()); + for (NicVO nic : nics) { + NetworkVO network = _networkDao.findById(nic.getNetworkId()); + long isDefault = (nic.isDefaultNic()) ? 1 : 0; + UsageEventUtils.publishUsageEvent(eventType, vm.getAccountId(), vm.getDataCenterId(), vm.getId(), + Long.toString(nic.getId()), network.getNetworkOfferingId(), null, isDefault, vm.getClass().getName(), vm.getUuid(), isDisplay); + } + + } + @Override public UserVm updateVirtualMachine(long id, String displayName, String group, Boolean ha, Boolean isDisplayVmEnabled, Long osTypeId, String userData, Boolean isDynamicallyScalable, HTTPMethod httpMethod, String customId, String hostName) throws ResourceUnavailableException, InsufficientCapacityException { @@ -2008,7 +2093,7 @@ public UserVm destroyVm(DestroyVMCmd cmd) throws ResourceUnavailableException, C long vmId = cmd.getId(); boolean expunge = cmd.getExpunge(); - if (!_accountMgr.isAdmin(ctx.getCallingAccount().getType()) && expunge) { + if (!_accountMgr.isAdmin(ctx.getCallingAccount().getId()) && expunge) { throw new PermissionDeniedException("Parameter " + ApiConstants.EXPUNGE + " can be passed by Admin only"); } @@ -2023,12 +2108,6 @@ public UserVm destroyVm(DestroyVMCmd cmd) throws ResourceUnavailableException, C return destroyedVm; } - @Override - @ActionEvent(eventType = EventTypes.EVENT_VM_EXPUNGE, eventDescription = "expunging Vm", async = true) - public UserVm expungeVm(ExpungeVMCmd cmd) throws ResourceUnavailableException, ConcurrentOperationException { - return expungeVm(cmd.getId()); - } - @Override @DB public InstanceGroupVO createVmGroup(CreateVMGroupCmd cmd) { @@ -2282,7 +2361,7 @@ public UserVm createAdvancedSecurityGroupVirtualMachine(DataCenter zone, Service // If no network is specified, find system security group enabled network if (networkIdList == null || networkIdList.isEmpty()) { - Network networkWithSecurityGroup = _networkModel.getNetworkWithSecurityGroupEnabled(zone.getId()); + Network networkWithSecurityGroup = _networkModel.getNetworkWithSGWithFreeIPs(zone.getId()); if (networkWithSecurityGroup == null) { throw new InvalidParameterValueException("No network with security enabled is found in zone id=" + zone.getId()); } @@ -2642,8 +2721,29 @@ protected UserVm createVirtualMachine(DataCenter zone, ServiceOffering serviceOf boolean securityGroupEnabled = false; boolean vpcNetwork = false; for (NetworkVO network : networkList) { - if (network.getDataCenterId() != zone.getId()) { - throw new InvalidParameterValueException("Network id=" + network.getId() + " doesn't belong to zone " + zone.getId()); + if ((network.getDataCenterId() != zone.getId())) { + if (!network.isStrechedL2Network()) { + throw new InvalidParameterValueException("Network id=" + network.getId() + + " doesn't belong to zone " + zone.getId()); + } + + NetworkOffering ntwkOffering = _networkOfferingDao.findById(network.getNetworkOfferingId()); + Long physicalNetworkId = _networkModel.findPhysicalNetworkId(zone.getId(), ntwkOffering.getTags(), + ntwkOffering.getTrafficType()); + if (physicalNetworkId == null) { + s_logger.warn("Network id " + network.getId() + " could not be streched to the zone " + zone.getId() + + " as valid phyical network could not be found"); + throw new InvalidParameterValueException("Network in which is VM getting deployed could not be" + + " streched to the zone."); + } + + String provider = _ntwkSrvcDao.getProviderForServiceInNetwork(network.getId(), Service.Connectivity); + if (!_networkModel.isProviderEnabledInPhysicalNetwork(physicalNetworkId, provider)) { + s_logger.warn("Network id " + network.getId() + " could not be streched to the zone " +zone.getId() + + " as Connectivity service provider is not enabled in the zone " + zone.getId()); + throw new InvalidParameterValueException("Network in which is VM getting deployed could not be" + + " streched to the zone."); + } } //relax the check if the caller is admin account @@ -2824,6 +2924,12 @@ public UserVmVO doInTransaction(TransactionStatus status) throws InsufficientCap .getLimitCpuUse(), owner.getDomainId(), owner.getId(), offering.getId(), userData, hostName, diskOfferingId); vm.setUuid(uuidName); vm.setDynamicallyScalable(template.isDynamicallyScalable()); + + Map details = template.getDetails(); + if (details != null && !details.isEmpty()) { + vm.details.putAll(details); + } + if (sshPublicKey != null) { vm.setDetail("SSH.PublicKey", sshPublicKey); } @@ -2835,11 +2941,31 @@ public UserVmVO doInTransaction(TransactionStatus status) throws InsufficientCap vm.setIsoId(template.getId()); } Long rootDiskSize = null; + // custom root disk size, resizes base template to larger size if (customParameters.containsKey("rootdisksize")) { if (NumbersUtil.parseLong(customParameters.get("rootdisksize"), -1) <= 0) { throw new InvalidParameterValueException("rootdisk size should be a non zero number."); } - rootDiskSize = Long.parseLong(customParameters.get("rootDisksize")); + rootDiskSize = Long.parseLong(customParameters.get("rootdisksize")); + + // only KVM supports rootdisksize override + if (hypervisor != HypervisorType.KVM) { + throw new InvalidParameterValueException("Hypervisor " + hypervisor + " does not support rootdisksize override"); + } + + // rotdisksize must be larger than template + VMTemplateVO templateVO = _templateDao.findById(template.getId()); + if (templateVO == null) { + throw new InvalidParameterValueException("Unable to look up template by id " + template.getId()); + } + + if ((rootDiskSize << 30) < templateVO.getSize()) { + throw new InvalidParameterValueException("unsupported: rootdisksize override is smaller than template size " + templateVO.getSize()); + } else { + s_logger.debug("rootdisksize of " + (rootDiskSize << 30) + " was larger than template size of " + templateVO.getSize()); + } + + s_logger.debug("found root disk size of " + rootDiskSize); customParameters.remove("rootdisksize"); } @@ -2877,11 +3003,6 @@ public UserVmVO doInTransaction(TransactionStatus status) throws InsufficientCap } } - Map details = template.getDetails(); - if (details != null && !details.isEmpty()) { - vm.details.putAll(details); - } - _vmDao.persist(vm); if (customParameters != null && customParameters.size() > 0) { for (String key : customParameters.keySet()) { @@ -2915,10 +3036,10 @@ public UserVmVO doInTransaction(TransactionStatus status) throws InsufficientCap if (!offering.isDynamic()) { UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_CREATE, accountId, zone.getId(), vm.getId(), vm.getHostName(), offering.getId(), template.getId(), - hypervisorType.toString(), VirtualMachine.class.getName(), vm.getUuid()); + hypervisorType.toString(), VirtualMachine.class.getName(), vm.getUuid(), vm.isDisplayVm()); } else { UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_CREATE, accountId, zone.getId(), vm.getId(), vm.getHostName(), offering.getId(), template.getId(), - hypervisorType.toString(), VirtualMachine.class.getName(), vm.getUuid(), customParameters); + hypervisorType.toString(), VirtualMachine.class.getName(), vm.getUuid(), customParameters, vm.isDisplayVm()); } //Update Resource Count for the given account @@ -2928,13 +3049,22 @@ public UserVmVO doInTransaction(TransactionStatus status) throws InsufficientCap }); } - private void generateUsageEvent(ServiceOfferingVO serviceOffering, Map customParameters, UserVmVO vm, String eventType) { + @Override + public void generateUsageEvent(VirtualMachine vm, boolean isDisplay, String eventType){ + ServiceOfferingVO serviceOffering = _offeringDao.findById(vm.getId(), vm.getServiceOfferingId()); if (!serviceOffering.isDynamic()) { - UsageEventUtils.publishUsageEvent(eventType, vm.getAccountId(), vm.getDataCenterId(), vm.getId(), vm.getHostName(), serviceOffering.getId(), vm.getTemplateId(), vm - .getHypervisorType().toString(), VirtualMachine.class.getName(), vm.getUuid()); - } else { - UsageEventUtils.publishUsageEvent(eventType, vm.getAccountId(), vm.getDataCenterId(), vm.getId(), vm.getHostName(), serviceOffering.getId(), vm.getTemplateId(), vm - .getHypervisorType().toString(), VirtualMachine.class.getName(), vm.getUuid(), customParameters); + UsageEventUtils.publishUsageEvent(eventType, vm.getAccountId(), vm.getDataCenterId(), vm.getId(), + vm.getHostName(), serviceOffering.getId(), vm.getTemplateId(), vm.getHypervisorType().toString(), + VirtualMachine.class.getName(), vm.getUuid(), isDisplay); + } + else { + Map customParameters = new HashMap(); + customParameters.put(UsageEventVO.DynamicParameters.cpuNumber.name(), serviceOffering.getCpu().toString()); + customParameters.put(UsageEventVO.DynamicParameters.cpuSpeed.name(), serviceOffering.getSpeed().toString()); + customParameters.put(UsageEventVO.DynamicParameters.memory.name(), serviceOffering.getRamSize().toString()); + UsageEventUtils.publishUsageEvent(eventType, vm.getAccountId(), vm.getDataCenterId(), vm.getId(), + vm.getHostName(), serviceOffering.getId(), vm.getTemplateId(), vm.getHypervisorType().toString(), + VirtualMachine.class.getName(), vm.getUuid(), customParameters, isDisplay); } } @@ -3104,7 +3234,7 @@ public boolean finalizeStart(VirtualMachineProfile profile, long hostId, Command NetworkVO network = _networkDao.findById(nic.getNetworkId()); long isDefault = (nic.isDefaultNic()) ? 1 : 0; UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NETWORK_OFFERING_ASSIGN, vm.getAccountId(), vm.getDataCenterId(), vm.getId(), Long.toString(nic.getId()), - network.getNetworkOfferingId(), null, isDefault, VirtualMachine.class.getName(), vm.getUuid()); + network.getNetworkOfferingId(), null, isDefault, VirtualMachine.class.getName(), vm.getUuid(), vm.isDisplay()); if (network.getTrafficType() == TrafficType.Guest) { originalIp = nic.getIp4Address(); guestNic = nic; @@ -3225,10 +3355,6 @@ public void finalizeStop(VirtualMachineProfile profile, Answer answer) { } } - public String generateRandomPassword() { - return PasswordGenerator.generateRandomPassword(6); - } - @Override public Pair> startVirtualMachine(long vmId, Long hostId, Map additionalParams, String deploymentPlannerToUse) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException { @@ -3303,7 +3429,7 @@ public Pair> startVirtualMach String password = "saved_password"; if (template.getEnablePassword()) { - password = generateRandomPassword(); + password = _mgr.generateRandomPassword(); } if (!validPassword(password)) { @@ -3389,7 +3515,7 @@ public UserVm destroyVm(long vmId) throws ResourceUnavailableException, Concurre for (VolumeVO volume : volumes) { if (volume.getVolumeType().equals(Volume.Type.ROOT)) { UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_DELETE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(), - Volume.class.getName(), volume.getUuid()); + Volume.class.getName(), volume.getUuid(), volume.isDisplayVolume()); } } @@ -3424,12 +3550,12 @@ public void collectVmDiskStatistics(final UserVmVO userVm) { try { diskStatsAnswer = (GetVmDiskStatsAnswer)_agentMgr.easySend(hostId, new GetVmDiskStatsCommand(vmNames, host.getGuid(), host.getName())); } catch (Exception e) { - s_logger.warn("Error while collecting disk stats for vm: " + userVm.getHostName() + " from host: " + host.getName(), e); + s_logger.warn("Error while collecting disk stats for vm: " + userVm.getInstanceName() + " from host: " + host.getName(), e); return; } if (diskStatsAnswer != null) { if (!diskStatsAnswer.getResult()) { - s_logger.warn("Error while collecting disk stats vm: " + userVm.getHostName() + " from host: " + host.getName() + "; details: " + diskStatsAnswer.getDetails()); + s_logger.warn("Error while collecting disk stats vm: " + userVm.getInstanceName() + " from host: " + host.getName() + "; details: " + diskStatsAnswer.getDetails()); return; } try { @@ -3529,6 +3655,7 @@ public void doInTransactionWithoutResult(TransactionStatus status) { } @Override + @ActionEvent(eventType = EventTypes.EVENT_VM_EXPUNGE, eventDescription = "expunging Vm", async = true) public UserVm expungeVm(long vmId) throws ResourceUnavailableException, ConcurrentOperationException { Account caller = CallContext.current().getCallingAccount(); Long userId = caller.getId(); @@ -3622,7 +3749,12 @@ public VirtualMachine vmStorageMigration(Long vmId, StoragePool destPool) { throw new InvalidParameterValueException("Data disks attached to the vm, can not migrate. Need to dettach data disks at first"); } - HypervisorType destHypervisorType = _clusterDao.findById(destPool.getClusterId()).getHypervisorType(); + HypervisorType destHypervisorType = destPool.getHypervisor(); + if (destHypervisorType == null) { + destHypervisorType = _clusterDao.findById( + destPool.getClusterId()).getHypervisorType(); + } + if (vm.getHypervisorType() != destHypervisorType) { throw new InvalidParameterValueException("hypervisor is not compatible: dest: " + destHypervisorType.toString() + ", vm: " + vm.getHypervisorType().toString()); } @@ -4027,7 +4159,7 @@ public VirtualMachine migrateVirtualMachineWithVolume(Long vmId, Host destinatio } List vmVolumes = _volsDao.findUsableVolumesForInstance(vm.getId()); - Map volToPoolObjectMap = new HashMap(); + Map volToPoolObjectMap = new HashMap(); if (!isVMUsingLocalStorage(vm) && destinationHost.getClusterId().equals(srcHost.getClusterId())) { if (volumeToPool.isEmpty()) { // If the destination host is in the same cluster and volumes do not have to be migrated across pools @@ -4051,7 +4183,7 @@ public VirtualMachine migrateVirtualMachineWithVolume(Long vmId, Host destinatio if (!vmVolumes.contains(volume)) { throw new InvalidParameterValueException("There volume " + volume + " doesn't belong to " + "the virtual machine " + vm + " that has to be migrated"); } - volToPoolObjectMap.put(volume, pool); + volToPoolObjectMap.put(Long.valueOf(volume.getId()), Long.valueOf(pool.getId())); } } } @@ -4194,7 +4326,7 @@ public UserVm moveVMToUser(final AssignVMCmd cmd) throws ResourceAllocationExcep public void doInTransactionWithoutResult(TransactionStatus status) { //generate destroy vm event for usage UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_DESTROY, vm.getAccountId(), vm.getDataCenterId(), vm.getId(), vm.getHostName(), vm.getServiceOfferingId(), - vm.getTemplateId(), vm.getHypervisorType().toString(), VirtualMachine.class.getName(), vm.getUuid()); + vm.getTemplateId(), vm.getHypervisorType().toString(), VirtualMachine.class.getName(), vm.getUuid(), vm.isDisplayVm()); // update resource counts for old account resourceCountDecrement(oldAccount.getAccountId(), vm.isDisplayVm(), new Long(offering.getCpu()), new Long(offering.getRamSize())); @@ -4206,20 +4338,20 @@ public void doInTransactionWithoutResult(TransactionStatus status) { // OS 2: update volume for (VolumeVO volume : volumes) { - UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_DELETE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(), - Volume.class.getName(), volume.getUuid()); + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_DELETE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(), + Volume.class.getName(), volume.getUuid(), volume.isDisplayVolume()); _resourceLimitMgr.decrementResourceCount(oldAccount.getAccountId(), ResourceType.volume); - _resourceLimitMgr.decrementResourceCount(oldAccount.getAccountId(), ResourceType.primary_storage, new Long(volume.getSize())); + _resourceLimitMgr.decrementResourceCount(oldAccount.getAccountId(), ResourceType.primary_storage, new Long(volume.getSize())); volume.setAccountId(newAccount.getAccountId()); volume.setDomainId(newAccount.getDomainId()); _volsDao.persist(volume); _resourceLimitMgr.incrementResourceCount(newAccount.getAccountId(), ResourceType.volume); - _resourceLimitMgr.incrementResourceCount(newAccount.getAccountId(), ResourceType.primary_storage, new Long(volume.getSize())); - UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(), - volume.getDiskOfferingId(), volume.getTemplateId(), volume.getSize(), Volume.class.getName(), volume.getUuid()); + _resourceLimitMgr.incrementResourceCount(newAccount.getAccountId(), ResourceType.primary_storage, new Long(volume.getSize())); + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(), + volume.getDiskOfferingId(), volume.getTemplateId(), volume.getSize(), Volume.class.getName(), volume.getUuid(), volume.isDisplayVolume()); //snapshots: mark these removed in db List snapshots = _snapshotDao.listByVolumeIdIncludingRemoved(volume.getId()); - for (SnapshotVO snapshot : snapshots) { + for (SnapshotVO snapshot : snapshots) { _snapshotDao.remove(snapshot.getId()); } } @@ -4229,7 +4361,7 @@ public void doInTransactionWithoutResult(TransactionStatus status) { //generate usage events to account for this change UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_CREATE, vm.getAccountId(), vm.getDataCenterId(), vm.getId(), vm.getHostName(), vm.getServiceOfferingId(), - vm.getTemplateId(), vm.getHypervisorType().toString(), VirtualMachine.class.getName(), vm.getUuid()); + vm.getTemplateId(), vm.getHypervisorType().toString(), VirtualMachine.class.getName(), vm.getUuid(), vm.isDisplayVm()); } }); @@ -4541,16 +4673,22 @@ public UserVm restoreVMInternal(Account caller, UserVmVO vm, Long newTemplateId) } else { newVol = volumeMgr.allocateDuplicateVolume(root, null); } - // Save usage event and update resource count for user vm volumes + // 1. Save usage event and update resource count for user vm volumes if (vm instanceof UserVm) { _resourceLimitMgr.incrementResourceCount(vm.getAccountId(), ResourceType.volume); } + //2. Create Usage event for the newly created volume + UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VOLUME_CREATE, newVol.getAccountId(), newVol.getDataCenterId(), newVol.getId(), newVol.getName(), newVol.getDiskOfferingId(), templateId, newVol.getSize()); + _usageEventDao.persist(usageEvent); + + handleManagedStorage(vm, root); _volsDao.attachVolume(newVol.getId(), vmId, newVol.getDeviceId()); /* Detach and destory the old root volume */ _volsDao.detachVolume(root.getId()); + volumeMgr.destroyVolume(root); // For VMware hypervisor since the old root volume is replaced by the new root volume, force expunge old root volume if it has been created in storage @@ -4568,7 +4706,7 @@ public UserVm restoreVMInternal(Account caller, UserVmVO vm, Long newTemplateId) } if (template.getEnablePassword()) { - String password = generateRandomPassword(); + String password = _mgr.generateRandomPassword(); boolean result = resetVMPasswordInternal(vmId, password); if (result) { vm.setPassword(password); @@ -4598,6 +4736,80 @@ public UserVm restoreVMInternal(Account caller, UserVmVO vm, Long newTemplateId) } + private void handleManagedStorage(UserVmVO vm, VolumeVO root) { + StoragePoolVO storagePool = _storagePoolDao.findById(root.getPoolId()); + + if (storagePool.isManaged()) { + Long hostId = vm.getHostId() != null ? vm.getHostId() : vm.getLastHostId(); + + if (hostId != null) { + VolumeInfo volumeInfo = volFactory.getVolume(root.getId()); + Host host = _hostDao.findById(hostId); + + final Command cmd; + + if (host.getHypervisorType() == HypervisorType.XenServer) { + DiskTO disk = new DiskTO(volumeInfo.getTO(), root.getDeviceId(), root.getPath(), root.getVolumeType()); + + // it's OK in this case to send a detach command to the host for a root volume as this + // will simply lead to the SR that supports the root volume being removed + cmd = new DettachCommand(disk, vm.getInstanceName()); + + DettachCommand detachCommand = (DettachCommand)cmd; + + detachCommand.setManaged(true); + + detachCommand.setStorageHost(storagePool.getHostAddress()); + detachCommand.setStoragePort(storagePool.getPort()); + + detachCommand.set_iScsiName(root.get_iScsiName()); + } + else if (host.getHypervisorType() == HypervisorType.VMware) { + PrimaryDataStore primaryDataStore = (PrimaryDataStore)volumeInfo.getDataStore(); + Map details = primaryDataStore.getDetails(); + + if (details == null) { + details = new HashMap(); + + primaryDataStore.setDetails(details); + } + + details.put(DiskTO.MANAGED, Boolean.TRUE.toString()); + + cmd = new DeleteCommand(volumeInfo.getTO()); + } + else { + throw new CloudRuntimeException("This hypervisor type is not supported on managed storage for this command."); + } + + Commands cmds = new Commands(Command.OnError.Stop); + + cmds.addCommand(cmd); + + try { + _agentMgr.send(hostId, cmds); + } + catch (Exception ex) { + throw new CloudRuntimeException(ex.getMessage()); + } + + if (!cmds.isSuccessful()) { + for (Answer answer : cmds.getAnswers()) { + if (!answer.getResult()) { + s_logger.warn("Failed to reset vm due to: " + answer.getDetails()); + + throw new CloudRuntimeException("Unable to reset " + vm + " due to " + answer.getDetails()); + } + } + } + + // root.getPoolId() should be null if the VM we are detaching the disk from has never been started before + DataStore dataStore = root.getPoolId() != null ? _dataStoreMgr.getDataStore(root.getPoolId(), DataStoreRole.Primary) : null; + volumeMgr.disconnectVolumeFromHost(volFactory.getVolume(root.getId()), host, dataStore); + } + } + } + @Override public void prepareStop(VirtualMachineProfile profile) { UserVmVO vm = _vmDao.findById(profile.getId()); diff --git a/server/src/com/cloud/vm/UserVmStateListener.java b/server/src/com/cloud/vm/UserVmStateListener.java index 2f6be6cbbc..202391f4e4 100644 --- a/server/src/com/cloud/vm/UserVmStateListener.java +++ b/server/src/com/cloud/vm/UserVmStateListener.java @@ -25,6 +25,7 @@ import javax.inject.Inject; import com.cloud.server.ManagementService; +import com.cloud.vm.dao.UserVmDao; import org.apache.log4j.Logger; import org.springframework.beans.factory.NoSuchBeanDefinitionException; @@ -33,11 +34,9 @@ import com.cloud.event.EventCategory; import com.cloud.event.EventTypes; import com.cloud.event.UsageEventUtils; -import com.cloud.event.UsageEventVO; import com.cloud.event.dao.UsageEventDao; import com.cloud.network.dao.NetworkDao; import com.cloud.network.dao.NetworkVO; -import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.utils.component.ComponentContext; import com.cloud.utils.fsm.StateListener; @@ -51,15 +50,19 @@ public class UserVmStateListener implements StateListener customParameters = new HashMap(); - customParameters.put(UsageEventVO.DynamicParameters.cpuNumber.name(), serviceOffering.getCpu().toString()); - customParameters.put(UsageEventVO.DynamicParameters.cpuSpeed.name(), serviceOffering.getSpeed().toString()); - customParameters.put(UsageEventVO.DynamicParameters.memory.name(), serviceOffering.getRamSize().toString()); - UsageEventUtils.publishUsageEvent(eventType, vm.getAccountId(), vm.getDataCenterId(), vm.getId(), - vm.getHostName(), serviceOffering.getId(), vm.getTemplateId(), vm.getHypervisorType().toString(), - VirtualMachine.class.getName(), vm.getUuid(), customParameters); + private void generateUsageEvent(Long serviceOfferingId, VirtualMachine vm, String eventType){ + boolean displayVm = true; + if(vm.getType() == VirtualMachine.Type.User){ + UserVmVO uservm = _userVmDao.findById(vm.getId()); + displayVm = uservm.isDisplayVm(); } + + _userVmMgr.generateUsageEvent(vm, displayVm, eventType); } private void pubishOnEventBus(String event, String status, VirtualMachine vo, VirtualMachine.State oldState, VirtualMachine.State newState) { diff --git a/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java b/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java index 37cdf86fd4..f5957ff085 100644 --- a/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java +++ b/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java @@ -169,9 +169,7 @@ public boolean stop() { @Override public List listVMSnapshots(ListVMSnapshotCmd cmd) { Account caller = getCaller(); - List permittedDomains = new ArrayList(); List permittedAccounts = new ArrayList(); - List permittedResources = new ArrayList(); boolean listAll = cmd.listAll(); Long id = cmd.getId(); @@ -184,14 +182,15 @@ public List listVMSnapshots(ListVMSnapshotCmd cmd) { Ternary domainIdRecursiveListProject = new Ternary( cmd.getDomainId(), cmd.isRecursive(), null); - _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedDomains, permittedAccounts, permittedResources, - domainIdRecursiveListProject, listAll, false, "listVMSnapshot"); + _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, listAll, + false); + Long domainId = domainIdRecursiveListProject.first(); Boolean isRecursive = domainIdRecursiveListProject.second(); ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third(); Filter searchFilter = new Filter(VMSnapshotVO.class, "created", false, cmd.getStartIndex(), cmd.getPageSizeVal()); SearchBuilder sb = _vmSnapshotDao.createSearchBuilder(); - _accountMgr.buildACLSearchBuilder(sb, isRecursive, permittedDomains, permittedAccounts, permittedResources, listProjectResourcesCriteria); + _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); sb.and("vm_id", sb.entity().getVmId(), SearchCriteria.Op.EQ); sb.and("domain_id", sb.entity().getDomainId(), SearchCriteria.Op.EQ); @@ -203,7 +202,7 @@ public List listVMSnapshots(ListVMSnapshotCmd cmd) { sb.done(); SearchCriteria sc = sb.create(); - _accountMgr.buildACLSearchCriteria(sc, isRecursive, permittedDomains, permittedAccounts, permittedResources, listProjectResourcesCriteria); + _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); if (accountName != null && cmd.getDomainId() != null) { Account account = _accountMgr.getActiveAccountByName(accountName, cmd.getDomainId()); @@ -214,8 +213,8 @@ public List listVMSnapshots(ListVMSnapshotCmd cmd) { sc.setParameters("vm_id", vmId); } - if (cmd.getDomainId() != null) { - sc.setParameters("domain_id", cmd.getDomainId()); + if (domainId != null) { + sc.setParameters("domain_id", domainId); } if (state == null) { diff --git a/server/src/org/apache/cloudstack/affinity/AffinityGroupServiceImpl.java b/server/src/org/apache/cloudstack/affinity/AffinityGroupServiceImpl.java index f375fde565..8e606ca058 100644 --- a/server/src/org/apache/cloudstack/affinity/AffinityGroupServiceImpl.java +++ b/server/src/org/apache/cloudstack/affinity/AffinityGroupServiceImpl.java @@ -28,7 +28,6 @@ import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.ControlledEntity; import org.apache.cloudstack.acl.ControlledEntity.ACLType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; @@ -218,7 +217,7 @@ public AffinityGroupVO doInTransaction(TransactionStatus status) { _affinityGroupDomainMapDao.persist(domainMap); //send event for storing the domain wide resource access Map params = new HashMap(); - params.put(ApiConstants.ENTITY_TYPE, IAMEntityType.AffinityGroup); + params.put(ApiConstants.ENTITY_TYPE, AffinityGroup.class); params.put(ApiConstants.ENTITY_ID, group.getId()); params.put(ApiConstants.DOMAIN_ID, domainId); params.put(ApiConstants.SUBDOMAIN_ACCESS, subDomainAccess); @@ -300,7 +299,7 @@ public void doInTransactionWithoutResult(TransactionStatus status) { _affinityGroupDomainMapDao.remove(groupDomain.getId()); } // remove its related ACL permission - Pair params = new Pair(IAMEntityType.AffinityGroup, affinityGroupIdFinal); + Pair, Long> params = new Pair, Long>(AffinityGroup.class, affinityGroupIdFinal); _messageBus.publish(_name, EntityManager.MESSAGE_REMOVE_ENTITY_EVENT, PublishScope.LOCAL, params); } } diff --git a/server/src/org/apache/cloudstack/network/lb/ApplicationLoadBalancerManagerImpl.java b/server/src/org/apache/cloudstack/network/lb/ApplicationLoadBalancerManagerImpl.java index 73bf0d2a38..6854347ba6 100644 --- a/server/src/org/apache/cloudstack/network/lb/ApplicationLoadBalancerManagerImpl.java +++ b/server/src/org/apache/cloudstack/network/lb/ApplicationLoadBalancerManagerImpl.java @@ -24,14 +24,15 @@ import javax.ejb.Local; import javax.inject.Inject; +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; + import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.command.user.loadbalancer.ListApplicationLoadBalancersCmd; import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; import org.apache.cloudstack.lb.ApplicationLoadBalancerRuleVO; import org.apache.cloudstack.lb.dao.ApplicationLoadBalancerRuleDao; -import org.apache.log4j.Logger; -import org.springframework.stereotype.Component; import com.cloud.event.ActionEvent; import com.cloud.event.EventTypes; @@ -388,20 +389,19 @@ public Pair, Integer> listApplicatio Map tags = cmd.getTags(); Account caller = CallContext.current().getCallingAccount(); - List permittedDomains = new ArrayList(); List permittedAccounts = new ArrayList(); - List permittedResources = new ArrayList(); Ternary domainIdRecursiveListProject = new Ternary( cmd.getDomainId(), cmd.isRecursive(), null); - _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedDomains, permittedAccounts, permittedResources, - domainIdRecursiveListProject, cmd.listAll(), false, "listLoadBalancers"); + _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, + domainIdRecursiveListProject, cmd.listAll(), false); + Long domainId = domainIdRecursiveListProject.first(); Boolean isRecursive = domainIdRecursiveListProject.second(); ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third(); Filter searchFilter = new Filter(ApplicationLoadBalancerRuleVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal()); SearchBuilder sb = _lbDao.createSearchBuilder(); - _accountMgr.buildACLSearchBuilder(sb, isRecursive, permittedDomains, permittedAccounts, permittedResources, listProjectResourcesCriteria); + _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ); @@ -428,7 +428,7 @@ public Pair, Integer> listApplicatio } SearchCriteria sc = sb.create(); - _accountMgr.buildACLSearchCriteria(sc, isRecursive, permittedDomains, permittedAccounts, permittedResources, listProjectResourcesCriteria); + _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); if (keyword != null) { SearchCriteria ssc = _lbDao.createSearchCriteria(); diff --git a/server/src/org/apache/cloudstack/network/lb/CertServiceImpl.java b/server/src/org/apache/cloudstack/network/lb/CertServiceImpl.java index ba71d631a9..c2c155d0b8 100644 --- a/server/src/org/apache/cloudstack/network/lb/CertServiceImpl.java +++ b/server/src/org/apache/cloudstack/network/lb/CertServiceImpl.java @@ -18,8 +18,6 @@ import java.io.IOException; import java.io.StringReader; -import java.io.UnsupportedEncodingException; -import java.net.URLDecoder; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.KeyPair; @@ -53,18 +51,17 @@ import javax.ejb.Local; import javax.inject.Inject; -import org.apache.commons.io.IOUtils; -import org.apache.log4j.Logger; -import org.bouncycastle.jce.provider.BouncyCastleProvider; -import org.bouncycastle.openssl.PEMReader; -import org.bouncycastle.openssl.PasswordFinder; - import org.apache.cloudstack.acl.SecurityChecker; import org.apache.cloudstack.api.command.user.loadbalancer.DeleteSslCertCmd; import org.apache.cloudstack.api.command.user.loadbalancer.ListSslCertsCmd; import org.apache.cloudstack.api.command.user.loadbalancer.UploadSslCertCmd; import org.apache.cloudstack.api.response.SslCertResponse; import org.apache.cloudstack.context.CallContext; +import org.apache.commons.io.IOUtils; +import org.apache.log4j.Logger; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.openssl.PEMReader; +import org.bouncycastle.openssl.PasswordFinder; import com.cloud.event.ActionEvent; import com.cloud.event.EventTypes; @@ -109,10 +106,10 @@ public CertServiceImpl() { public SslCertResponse uploadSslCert(UploadSslCertCmd certCmd) { try { - String cert = URLDecoder.decode(certCmd.getCert(), "UTF-8"); - String key = URLDecoder.decode(certCmd.getKey(), "UTF-8"); + String cert = certCmd.getCert(); + String key = certCmd.getKey(); String password = certCmd.getPassword(); - String chain = certCmd.getChain() == null ? null : URLDecoder.decode(certCmd.getChain(), "UTF-8"); + String chain = certCmd.getChain(); validate(cert, key, password, chain); s_logger.debug("Certificate Validation succeeded"); @@ -127,8 +124,8 @@ public SslCertResponse uploadSslCert(UploadSslCertCmd certCmd) { return createCertResponse(certVO, null); - } catch (UnsupportedEncodingException e) { - throw new CloudRuntimeException("Error decoding certificate data"); + } catch (Exception e) { + throw new CloudRuntimeException("Error parsing certificate data " + e.getMessage()); } } @@ -429,7 +426,7 @@ public Certificate parseCertificate(String cert) { try { return (Certificate)certPem.readObject(); } catch (Exception e) { - throw new InvalidParameterValueException("Invalid Certificate format. Expected X509 certificate"); + throw new InvalidParameterValueException("Invalid Certificate format. Expected X509 certificate. Failed due to " + e.getMessage()); } finally { IOUtils.closeQuietly(certPem); } diff --git a/server/test/com/cloud/api/dispatch/CommandCreationWorkerTest.java b/server/test/com/cloud/api/dispatch/CommandCreationWorkerTest.java index 34d64fc3c1..72dd770d5a 100644 --- a/server/test/com/cloud/api/dispatch/CommandCreationWorkerTest.java +++ b/server/test/com/cloud/api/dispatch/CommandCreationWorkerTest.java @@ -18,7 +18,12 @@ import java.util.HashMap; import java.util.Map; +import java.util.UUID; +import com.cloud.user.Account; +import com.cloud.user.AccountVO; +import com.cloud.user.UserVO; +import org.apache.cloudstack.context.CallContext; import org.junit.Test; import static org.mockito.Mockito.mock; @@ -36,6 +41,9 @@ public void testHandle() throws ResourceAllocationException { // Prepare final BaseAsyncCreateCmd asyncCreateCmd = mock(BaseAsyncCreateCmd.class); final Map params = new HashMap(); + Account account = new AccountVO("testaccount", 1L, "networkdomain", (short) 0, "uuid"); + UserVO user = new UserVO(1, "testuser", "password", "firstname", "lastName", "email", "timezone", UUID.randomUUID().toString()); + CallContext.register(user, account); // Execute final CommandCreationWorker creationWorker = new CommandCreationWorker(); diff --git a/server/test/com/cloud/api/dispatch/ParamGenericValidationWorkerTest.java b/server/test/com/cloud/api/dispatch/ParamGenericValidationWorkerTest.java index 8f9709ca9d..3073c7ffd8 100644 --- a/server/test/com/cloud/api/dispatch/ParamGenericValidationWorkerTest.java +++ b/server/test/com/cloud/api/dispatch/ParamGenericValidationWorkerTest.java @@ -95,6 +95,10 @@ public void testHandle() throws ResourceAllocationException { params.put(ApiConstants.SIGNATURE, ""); params.put(ApiConstants.CTX_ACCOUNT_ID, ""); params.put(ApiConstants.CTX_START_EVENT_ID, ""); + // Make sure it's case insensitive + params.put(ApiConstants.CTX_START_EVENT_ID, ""); + params.put(ApiConstants.CTX_START_EVENT_ID.toLowerCase(), ""); + params.put(ApiConstants.CTX_USER_ID.toUpperCase(), ""); params.put(ApiConstants.CTX_USER_ID, ""); params.put(ApiConstants.UUID, ""); params.put(ApiConstants.ID, ""); diff --git a/server/test/com/cloud/network/CreatePrivateNetworkTest.java b/server/test/com/cloud/network/CreatePrivateNetworkTest.java index dc979d05c9..b124b20dad 100644 --- a/server/test/com/cloud/network/CreatePrivateNetworkTest.java +++ b/server/test/com/cloud/network/CreatePrivateNetworkTest.java @@ -103,7 +103,7 @@ public void setup() throws Exception { NetworkOfferingVO ntwkOff = new NetworkOfferingVO("offer", "fakeOffer", TrafficType.Guest, true, true, null, null, false, null, null, GuestType.Isolated, false, false, false, false, - false, false, false, false, false, false, false, false, false); + false, false, false, false, false, false, false, false, false, false); when(networkService._networkOfferingDao.findById(anyLong())).thenReturn(ntwkOff); List netofferlist = new ArrayList(); netofferlist.add(ntwkOff); diff --git a/server/test/com/cloud/network/MockFirewallManagerImpl.java b/server/test/com/cloud/network/MockFirewallManagerImpl.java index 3c026135da..e484e61b9b 100644 --- a/server/test/com/cloud/network/MockFirewallManagerImpl.java +++ b/server/test/com/cloud/network/MockFirewallManagerImpl.java @@ -70,9 +70,13 @@ public Pair, Integer> listFirewallRules(ListFirewal } @Override - public boolean revokeFirewallRule(long ruleId, boolean apply) { - // TODO Auto-generated method stub - return false; + public boolean revokeIngressFirewallRule(long ruleId, boolean apply) { + return false; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public boolean revokeEgressFirewallRule(long ruleId, boolean apply) { + return false; //To change body of implemented methods use File | Settings | File Templates. } @Override @@ -87,6 +91,26 @@ public boolean revokeRelatedFirewallRule(long ruleId, boolean apply) { return false; } + @Override + public FirewallRule updateIngressFirewallRule(long ruleId, String customId, Boolean forDisplay) { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public FirewallRule updateEgressFirewallRule(long ruleId, String customId, Boolean forDisplay) { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public boolean applyIngressFwRules(long ipId, Account caller) throws ResourceUnavailableException { + return false; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public boolean revokeIngressFwRule(long ruleId, boolean apply) { + return false; //To change body of implemented methods use File | Settings | File Templates. + } + @Override public void detectRulesConflict(FirewallRule newRule) throws NetworkRuleConflictException { // TODO Auto-generated method stub @@ -184,10 +208,5 @@ public FirewallRule createIngressFirewallRule(FirewallRule rule) throws NetworkR return null; } - @Override - public FirewallRule updateFirewallRule(long ruleId, String customId, Boolean forDisplay) { - // TODO Auto-generated method stub - return null; - } } diff --git a/server/test/com/cloud/network/MockNetworkModelImpl.java b/server/test/com/cloud/network/MockNetworkModelImpl.java index 6c9e597b9f..14c42f302e 100644 --- a/server/test/com/cloud/network/MockNetworkModelImpl.java +++ b/server/test/com/cloud/network/MockNetworkModelImpl.java @@ -227,6 +227,15 @@ public boolean areServicesSupportedByNetworkOffering(long networkOfferingId, Ser return false; } + /* (non-Javadoc) + * @see com.cloud.network.NetworkModel#getNetworkWithSGWithFreeIPs(java.lang.Long) + */ + @Override + public NetworkVO getNetworkWithSGWithFreeIPs(Long zoneId) { + // TODO Auto-generated method stub + return null; + } + /* (non-Javadoc) * @see com.cloud.network.NetworkModel#getNetworkWithSecurityGroupEnabled(java.lang.Long) */ diff --git a/server/test/com/cloud/network/lb/AssignLoadBalancerTest.java b/server/test/com/cloud/network/lb/AssignLoadBalancerTest.java new file mode 100644 index 0000000000..257a21fd67 --- /dev/null +++ b/server/test/com/cloud/network/lb/AssignLoadBalancerTest.java @@ -0,0 +1,271 @@ +// 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.lb; + +import com.cloud.domain.DomainVO; +import com.cloud.domain.dao.DomainDao; +import com.cloud.exception.ResourceAllocationException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.network.NetworkModelImpl; +import com.cloud.network.dao.LoadBalancerDao; +import com.cloud.network.dao.LoadBalancerVMMapDao; +import com.cloud.network.dao.LoadBalancerVMMapVO; +import com.cloud.network.dao.LoadBalancerVO; +import com.cloud.network.rules.FirewallRule; +import com.cloud.network.rules.RulesManagerImpl; +import com.cloud.user.Account; +import com.cloud.user.AccountManager; +import com.cloud.user.AccountVO; +import com.cloud.user.UserVO; +import com.cloud.user.dao.AccountDao; +import com.cloud.uservm.UserVm; +import com.cloud.vm.Nic; +import com.cloud.vm.NicVO; +import com.cloud.vm.UserVmVO; +import com.cloud.vm.dao.NicSecondaryIpDao; +import com.cloud.vm.dao.UserVmDao; +import org.apache.cloudstack.api.ResponseGenerator; +import org.apache.cloudstack.api.command.user.loadbalancer.AssignToLoadBalancerRuleCmd; +import org.apache.cloudstack.api.response.SuccessResponse; +import org.apache.cloudstack.context.CallContext; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.Spy; + +import javax.inject.Inject; + +import java.util.UUID; +import java.util.HashMap; +import java.util.Map; +import java.util.List; +import java.util.ArrayList; + +import static org.mockito.Matchers.anyBoolean; +import static org.mockito.Matchers.anyLong; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.when; + +public class AssignLoadBalancerTest { + + @Inject + AccountManager _accountMgr; + + @Inject + AccountManager _acctMgr; + + @Inject + AccountDao _accountDao; + + @Inject + DomainDao _domainDao; + + @Mock + List _lbvmMapList; + + @Mock + List nic; + + @Mock + UserVmDao userDao; + + @Spy + RulesManagerImpl _rulesMgr = new RulesManagerImpl() { + @Override + public void checkRuleAndUserVm (FirewallRule rule, UserVm userVm, Account caller) { + + } + }; + + + @Spy + NicVO nicvo = new NicVO() { + + }; + + @Spy + NetworkModelImpl _networkModel = new NetworkModelImpl() { + @Override + public List getNics(long vmId) { + nic = new ArrayList(); + nicvo.setNetworkId(204L); + nic.add(nicvo); + return nic; + } + }; + + + LoadBalancingRulesManagerImpl _lbMgr = new LoadBalancingRulesManagerImpl(); + + private AssignToLoadBalancerRuleCmd assignToLbRuleCmd; + private ResponseGenerator responseGenerator; + private SuccessResponse successResponseGenerator; + + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + private static long domainId = 5L; + private static long accountId = 5L; + private static String accountName = "admin"; + + @Before + public void setUp() { + assignToLbRuleCmd = new AssignToLoadBalancerRuleCmd() { + }; + + // ComponentContext.initComponentsLifeCycle(); + AccountVO account = new AccountVO(accountName, domainId, "networkDomain", Account.ACCOUNT_TYPE_NORMAL, "uuid"); + DomainVO domain = new DomainVO("rootDomain", 5L, 5L, "networkDomain"); + + UserVO user = new UserVO(1, "testuser", "password", "firstname", "lastName", "email", "timezone", UUID.randomUUID().toString()); + + CallContext.register(user, account); + + } + + @Test(expected = InvalidParameterValueException.class) + public void testBothArgsEmpty() throws ResourceAllocationException, ResourceUnavailableException, InsufficientCapacityException { + + Map> emptyMap = new HashMap>(); + + LoadBalancerDao lbdao = Mockito.mock(LoadBalancerDao.class); + _lbMgr._lbDao = lbdao; + + when(lbdao.findById(anyLong())).thenReturn(Mockito.mock(LoadBalancerVO.class)); + + _lbMgr.assignToLoadBalancer(1L, null, emptyMap); + + } + + @Test(expected = InvalidParameterValueException.class) + public void testNicIsNotInNw() throws ResourceAllocationException, ResourceUnavailableException, InsufficientCapacityException { + + Map> vmIdIpMap = new HashMap>(); + List secIp = new ArrayList(); + secIp.add("10.1.1.175"); + vmIdIpMap.put(1L,secIp); + + List vmIds = new ArrayList(); + vmIds.add(2L); + + LoadBalancerDao lbDao = Mockito.mock(LoadBalancerDao.class); + LoadBalancerVMMapDao lb2VmMapDao = Mockito.mock(LoadBalancerVMMapDao.class); + UserVmDao userVmDao = Mockito.mock(UserVmDao.class); + + _lbMgr._lbDao = lbDao; + _lbMgr._lb2VmMapDao = lb2VmMapDao; + _lbMgr._vmDao = userVmDao; + _lbvmMapList = new ArrayList<>(); + _lbMgr._rulesMgr = _rulesMgr; + _lbMgr._networkModel = _networkModel; + + when(lbDao.findById(anyLong())).thenReturn(Mockito.mock(LoadBalancerVO.class)); + when(userVmDao.findById(anyLong())).thenReturn(Mockito.mock(UserVmVO.class)); + when(lb2VmMapDao.listByLoadBalancerId(anyLong(), anyBoolean())).thenReturn(_lbvmMapList); + + _lbMgr.assignToLoadBalancer(1L, null, vmIdIpMap); + } + + + @Test(expected = InvalidParameterValueException.class) + public void tesSecIpNotSetToVm() throws ResourceAllocationException, ResourceUnavailableException, InsufficientCapacityException { + + AssignToLoadBalancerRuleCmd assignLbRuleCmd = Mockito.mock(AssignToLoadBalancerRuleCmd.class); + + Map> vmIdIpMap = new HashMap>(); + List secIp = new ArrayList(); + secIp.add("10.1.1.175"); + vmIdIpMap.put(1L,secIp); + + List vmIds = new ArrayList(); + vmIds.add(2L); + + LoadBalancerVO lbVO = new LoadBalancerVO("1", "L1", "Lbrule", 1, 22, 22, "rb", 204, 0, 0, "tcp"); + + LoadBalancerDao lbDao = Mockito.mock(LoadBalancerDao.class); + LoadBalancerVMMapDao lb2VmMapDao = Mockito.mock(LoadBalancerVMMapDao.class); + UserVmDao userVmDao = Mockito.mock(UserVmDao.class); + NicSecondaryIpDao nicSecIpDao = Mockito.mock(NicSecondaryIpDao.class); + + _lbMgr._lbDao = lbDao; + _lbMgr._lb2VmMapDao = lb2VmMapDao; + _lbMgr._vmDao = userVmDao; + _lbMgr._nicSecondaryIpDao = nicSecIpDao; + _lbvmMapList = new ArrayList<>(); + _lbMgr._rulesMgr = _rulesMgr; + _lbMgr._networkModel = _networkModel; + + when(lbDao.findById(anyLong())).thenReturn(lbVO); + when(userVmDao.findById(anyLong())).thenReturn(Mockito.mock(UserVmVO.class)); + when(lb2VmMapDao.listByLoadBalancerId(anyLong(), anyBoolean())).thenReturn(_lbvmMapList); + when (nicSecIpDao.findByIp4AddressAndNicId(anyString(), anyLong())).thenReturn(null); + + _lbMgr.assignToLoadBalancer(1L, null, vmIdIpMap); + } + + + + @Test(expected = InvalidParameterValueException.class) + public void testVmIdAlreadyExist() throws ResourceAllocationException, ResourceUnavailableException, InsufficientCapacityException { + + AssignToLoadBalancerRuleCmd assignLbRuleCmd = Mockito.mock(AssignToLoadBalancerRuleCmd.class); + + Map> vmIdIpMap = new HashMap>(); + List secIp = new ArrayList(); + secIp.add("10.1.1.175"); + vmIdIpMap.put(1L,secIp); + + List vmIds = new ArrayList(); + vmIds.add(2L); + + LoadBalancerVO lbVO = new LoadBalancerVO("1", "L1", "Lbrule", 1, 22, 22, "rb", 204, 0, 0, "tcp"); + + LoadBalancerDao lbDao = Mockito.mock(LoadBalancerDao.class); + LoadBalancerVMMapDao lb2VmMapDao = Mockito.mock(LoadBalancerVMMapDao.class); + UserVmDao userVmDao = Mockito.mock(UserVmDao.class); + NicSecondaryIpDao nicSecIpDao = Mockito.mock(NicSecondaryIpDao.class); + LoadBalancerVMMapVO lbVmMapVO = new LoadBalancerVMMapVO(1L, 1L, "10.1.1.175", false); + + _lbMgr._lbDao = lbDao; + _lbMgr._lb2VmMapDao = lb2VmMapDao; + _lbMgr._vmDao = userVmDao; + _lbMgr._nicSecondaryIpDao = nicSecIpDao; + _lbvmMapList = new ArrayList<>(); + _lbvmMapList.add(lbVmMapVO); + _lbMgr._rulesMgr = _rulesMgr; + _lbMgr._networkModel = _networkModel; + + when(lbDao.findById(anyLong())).thenReturn(lbVO); + when(userVmDao.findById(anyLong())).thenReturn(Mockito.mock(UserVmVO.class)); + when(lb2VmMapDao.listByLoadBalancerId(anyLong(), anyBoolean())).thenReturn(_lbvmMapList); + when (nicSecIpDao.findByIp4AddressAndNicId(anyString(), anyLong())).thenReturn(null); + + _lbMgr.assignToLoadBalancer(1L, null, vmIdIpMap); + } + + @After + public void tearDown() { + CallContext.unregister(); + } + +} \ No newline at end of file diff --git a/server/test/com/cloud/resource/MockResourceManagerImpl.java b/server/test/com/cloud/resource/MockResourceManagerImpl.java index e6bf9a26b2..2646af079a 100644 --- a/server/test/com/cloud/resource/MockResourceManagerImpl.java +++ b/server/test/com/cloud/resource/MockResourceManagerImpl.java @@ -36,6 +36,7 @@ import com.cloud.agent.api.StartupCommand; import com.cloud.agent.api.StartupRoutingCommand; +import com.cloud.agent.api.VgpuTypesInfo; import com.cloud.agent.api.to.GPUDeviceTO; import com.cloud.dc.DataCenterVO; import com.cloud.dc.HostPodVO; @@ -558,31 +559,37 @@ public boolean releaseHostReservation(Long hostId) { } @Override - public boolean isGPUDeviceAvailable(long hostId, String vgpuType) { + public boolean isGPUDeviceAvailable(long hostId, String groupName, String vgpuType) { // TODO Auto-generated method stub return false; } @Override - public GPUDeviceTO getGPUDevice(long hostId, String vgpuType) { + public GPUDeviceTO getGPUDevice(long hostId, String groupName, String vgpuType) { // TODO Auto-generated method stub return null; } @Override - public List listAvailableGPUDevice(long hostId, String vgpuType) { + public List listAvailableGPUDevice(long hostId, String groupName, String vgpuType) { // TODO Auto-generated method stub return null; } @Override - public void updateGPUDetails(long hostId, HashMap> deviceDetails) { + public void updateGPUDetails(long hostId, HashMap> deviceDetails) { // TODO Auto-generated method stub } @Override - public HashMap> getGPUStatistics(HostVO host) { + public HashMap> getGPUStatistics(HostVO host) { // TODO Auto-generated method stub return null; } + + @Override + public boolean isHostGpuEnabled(long hostId) { + // TODO Auto-generated method stub + return false; + } } diff --git a/server/test/com/cloud/user/MockAccountManagerImpl.java b/server/test/com/cloud/user/MockAccountManagerImpl.java index f373cba922..746fa1b062 100644 --- a/server/test/com/cloud/user/MockAccountManagerImpl.java +++ b/server/test/com/cloud/user/MockAccountManagerImpl.java @@ -32,8 +32,8 @@ import org.apache.cloudstack.api.command.admin.user.RegisterCmd; import org.apache.cloudstack.api.command.admin.user.UpdateUserCmd; +import com.cloud.api.query.vo.ControlledViewEntity; import com.cloud.domain.Domain; -import com.cloud.domain.PartOf; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.PermissionDeniedException; import com.cloud.exception.ResourceUnavailableException; @@ -120,7 +120,7 @@ public boolean deleteUser(DeleteUserCmd deleteUserCmd) { } @Override - public boolean isAdmin(short accountType) { + public boolean isAdmin(Long accountId) { // TODO Auto-generated method stub return false; } @@ -224,10 +224,11 @@ public void checkAccess(Account account, AccessType accessType, boolean sameOwne // TODO Auto-generated method stub } + @Override - public void checkAccess(Account account, AccessType accessType, boolean sameOwner, PartOf... entities) throws PermissionDeniedException { + public UserAccount getUserAccountById(Long userId) { // TODO Auto-generated method stub - + return null; } @Override @@ -256,6 +257,36 @@ public boolean enableAccount(long accountId) { return false; } + @Override + public void buildACLSearchBuilder(SearchBuilder sb, Long domainId, boolean isRecursive, List permittedAccounts, + ListProjectResourcesCriteria listProjectResourcesCriteria) { + // TODO Auto-generated method stub + + } + + @Override + public void buildACLSearchCriteria(SearchCriteria sc, Long domainId, boolean isRecursive, List permittedAccounts, + ListProjectResourcesCriteria listProjectResourcesCriteria) { + // TODO Auto-generated method stub + + } + + @Override + public void buildACLSearchParameters(Account caller, Long id, String accountName, Long projectId, List permittedAccounts, Ternary domainIdRecursiveListProject, boolean listAll, boolean forProjectInvitation) { + // TODO Auto-generated method stub + } + + @Override + public void buildACLViewSearchBuilder(SearchBuilder sb, Long domainId, + boolean isRecursive, List permittedAccounts, ListProjectResourcesCriteria listProjectResourcesCriteria) { + // TODO Auto-generated method stub + } + + @Override + public void buildACLViewSearchCriteria(SearchCriteria sc, Long domainId, + boolean isRecursive, List permittedAccounts, ListProjectResourcesCriteria listProjectResourcesCriteria) { + // TODO Auto-generated method stub + } /* (non-Javadoc) * @see com.cloud.user.AccountService#getUserByApiKey(java.lang.String) @@ -309,35 +340,6 @@ public boolean isNormalUser(long accountId) { return false; } - @Override - public void buildACLSearchParameters(Account caller, Long id, String accountName, Long projectId, List permittedDomains, List permittedAccounts, - List permittedResources, Ternary domainIdRecursiveListProject, boolean listAll, boolean forProjectInvitation, - String action) { - // TODO Auto-generated method stub - - } - - @Override - public void buildACLViewSearchCriteria(SearchCriteria sc, SearchCriteria aclSc, boolean isRecursive, - List permittedDomains, List permittedAccounts, List permittedResources, ListProjectResourcesCriteria listProjectResourcesCriteria) { - // TODO Auto-generated method stub - - } - - @Override - public void buildACLSearchBuilder(SearchBuilder sb, boolean isRecursive, List permittedDomains, List permittedAccounts, - List permittedResources, ListProjectResourcesCriteria listProjectResourcesCriteria) { - // TODO Auto-generated method stub - - } - - @Override - public void buildACLSearchCriteria(SearchCriteria sc, boolean isRecursive, List permittedDomains, List permittedAccounts, - List permittedResources, ListProjectResourcesCriteria listProjectResourcesCriteria) { - // TODO Auto-generated method stub - - } - @Override public List listAclGroupsByAccount(Long accountId) { // TODO Auto-generated method stub diff --git a/server/test/com/cloud/vm/UserVmManagerTest.java b/server/test/com/cloud/vm/UserVmManagerTest.java index 43010a3f64..21cebb5ed8 100755 --- a/server/test/com/cloud/vm/UserVmManagerTest.java +++ b/server/test/com/cloud/vm/UserVmManagerTest.java @@ -35,6 +35,7 @@ import java.util.List; import java.util.UUID; +import com.cloud.event.dao.UsageEventDao; import org.junit.Before; import org.junit.Test; import org.mockito.Mock; @@ -50,6 +51,8 @@ import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; +import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import com.cloud.capacity.CapacityManager; import com.cloud.configuration.ConfigurationManager; @@ -141,6 +144,10 @@ public class UserVmManagerTest { EntityManager _entityMgr; @Mock ResourceLimitService _resourceLimitMgr; + @Mock + PrimaryDataStoreDao _storagePoolDao; + @Mock + UsageEventDao _usageEventDao; @Before public void setup() { @@ -150,6 +157,7 @@ public void setup() { _userVmMgr._vmInstanceDao = _vmInstanceDao; _userVmMgr._templateDao = _templateDao; _userVmMgr._volsDao = _volsDao; + _userVmMgr._usageEventDao = _usageEventDao; _userVmMgr._itMgr = _itMgr; _userVmMgr.volumeMgr = _storageMgr; _userVmMgr._accountDao = _accountDao; @@ -162,6 +170,7 @@ public void setup() { _userVmMgr._resourceLimitMgr = _resourceLimitMgr; _userVmMgr._scaleRetry = 2; _userVmMgr._entityMgr = _entityMgr; + _userVmMgr._storagePoolDao = _storagePoolDao; doReturn(3L).when(_account).getId(); doReturn(8L).when(_vmMock).getAccountId(); @@ -214,6 +223,12 @@ public void testRestoreVMF2() throws ResourceUnavailableException, InsufficientC Account account = new AccountVO("testaccount", 1L, "networkdomain", (short)0, "uuid"); UserVO user = new UserVO(1, "testuser", "password", "firstname", "lastName", "email", "timezone", UUID.randomUUID().toString()); + StoragePoolVO storagePool = new StoragePoolVO(); + + storagePool.setManaged(false); + + when(_storagePoolDao.findById(anyLong())).thenReturn(storagePool); + CallContext.register(user, account); try { _userVmMgr.restoreVMInternal(_account, _vmMock, null); @@ -245,6 +260,12 @@ public void testRestoreVMF3() throws ResourceUnavailableException, InsufficientC Account account = new AccountVO("testaccount", 1L, "networkdomain", (short)0, "uuid"); UserVO user = new UserVO(1, "testuser", "password", "firstname", "lastName", "email", "timezone", UUID.randomUUID().toString()); + StoragePoolVO storagePool = new StoragePoolVO(); + + storagePool.setManaged(false); + + when(_storagePoolDao.findById(anyLong())).thenReturn(storagePool); + CallContext.register(user, account); try { _userVmMgr.restoreVMInternal(_account, _vmMock, null); @@ -282,6 +303,12 @@ public void testRestoreVMF4() throws ResourceUnavailableException, InsufficientC Account account = new AccountVO("testaccount", 1L, "networkdomain", (short)0, "uuid"); UserVO user = new UserVO(1, "testuser", "password", "firstname", "lastName", "email", "timezone", UUID.randomUUID().toString()); + StoragePoolVO storagePool = new StoragePoolVO(); + + storagePool.setManaged(false); + + when(_storagePoolDao.findById(anyLong())).thenReturn(storagePool); + CallContext.register(user, account); try { _userVmMgr.restoreVMInternal(_account, _vmMock, 14L); @@ -321,6 +348,12 @@ public void testRestoreVMF5() throws ResourceUnavailableException, InsufficientC Account account = new AccountVO("testaccount", 1L, "networkdomain", (short)0, "uuid"); UserVO user = new UserVO(1, "testuser", "password", "firstname", "lastName", "email", "timezone", UUID.randomUUID().toString()); + StoragePoolVO storagePool = new StoragePoolVO(); + + storagePool.setManaged(false); + + when(_storagePoolDao.findById(anyLong())).thenReturn(storagePool); + CallContext.register(user, account); try { _userVmMgr.restoreVMInternal(_account, _vmMock, 14L); diff --git a/server/test/com/cloud/vpc/MockNetworkManagerImpl.java b/server/test/com/cloud/vpc/MockNetworkManagerImpl.java index ac303dddfc..387a710d9d 100644 --- a/server/test/com/cloud/vpc/MockNetworkManagerImpl.java +++ b/server/test/com/cloud/vpc/MockNetworkManagerImpl.java @@ -606,7 +606,7 @@ public boolean destroyNetwork(long networkId, ReservationContext context, boolea @Override public Network createGuestNetwork(long networkOfferingId, String name, String displayText, String gateway, String cidr, String vlanId, String networkDomain, Account owner, Long domainId, PhysicalNetwork physicalNetwork, long zoneId, ACLType aclType, Boolean subdomainAccess, Long vpcId, String gatewayv6, - String cidrv6, Boolean displayNetworkEnabled, String isolatedPvlan) throws ConcurrentOperationException, InsufficientCapacityException, + String cidrv6, Boolean displayNetworkEnabled, String isolatedPvlan ) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException { // TODO Auto-generated method stub return null; diff --git a/server/test/com/cloud/vpc/MockNetworkModelImpl.java b/server/test/com/cloud/vpc/MockNetworkModelImpl.java index 67ab8e875c..1364644628 100644 --- a/server/test/com/cloud/vpc/MockNetworkModelImpl.java +++ b/server/test/com/cloud/vpc/MockNetworkModelImpl.java @@ -238,6 +238,15 @@ public boolean areServicesSupportedByNetworkOffering(long networkOfferingId, Ser return (_ntwkOfferingSrvcDao.areServicesSupportedByNetworkOffering(networkOfferingId, services)); } + /* (non-Javadoc) + * @see com.cloud.network.NetworkModel#getNetworkWithSGWithFreeIPs(java.lang.Long) + */ + @Override + public NetworkVO getNetworkWithSGWithFreeIPs(Long zoneId) { + // TODO Auto-generated method stub + return null; + } + /* (non-Javadoc) * @see com.cloud.network.NetworkModel#getNetworkWithSecurityGroupEnabled(java.lang.Long) */ diff --git a/server/test/com/cloud/vpc/VpcApiUnitTest.java b/server/test/com/cloud/vpc/VpcApiUnitTest.java index 5e283743b7..dee9afe3b5 100644 --- a/server/test/com/cloud/vpc/VpcApiUnitTest.java +++ b/server/test/com/cloud/vpc/VpcApiUnitTest.java @@ -85,7 +85,7 @@ public void getActiveVpc() { public void validateNtwkOffForVpc() { //validate network offering //1) correct network offering - VpcVO vo = new VpcVO(1, "new vpc", "new vpc", 1, 1, 1, "0.0.0.0/0", "vpc domain", false); + VpcVO vo = new VpcVO(1, "new vpc", "new vpc", 1, 1, 1, "0.0.0.0/0", "vpc domain", false, false); boolean result = false; try { _vpcService.validateNtwkOffForNtwkInVpc(2L, 1, "0.0.0.0", "111-", vo, "10.1.1.1", new AccountVO(), null); diff --git a/server/test/com/cloud/vpc/dao/MockVpcDaoImpl.java b/server/test/com/cloud/vpc/dao/MockVpcDaoImpl.java index e1a6ac2ae4..7492598e90 100644 --- a/server/test/com/cloud/vpc/dao/MockVpcDaoImpl.java +++ b/server/test/com/cloud/vpc/dao/MockVpcDaoImpl.java @@ -98,9 +98,9 @@ public void persistVpcServiceProviders(long vpcId, Map> ser public VpcVO findById(Long id) { VpcVO vo = null; if (id.longValue() == 1) { - vo = new VpcVO(1, "new vpc", "new vpc", 1, 1, 1, "0.0.0.0/0", "vpc domain", false); + vo = new VpcVO(1, "new vpc", "new vpc", 1, 1, 1, "0.0.0.0/0", "vpc domain", false, false); } else if (id.longValue() == 2) { - vo = new VpcVO(1, "new vpc", "new vpc", 1, 1, 1, "0.0.0.0/0", "vpc domain", false); + vo = new VpcVO(1, "new vpc", "new vpc", 1, 1, 1, "0.0.0.0/0", "vpc domain", false, false); vo.setState(State.Inactive); } diff --git a/server/test/org/apache/cloudstack/affinity/AffinityApiUnitTest.java b/server/test/org/apache/cloudstack/affinity/AffinityApiUnitTest.java index f0ee8abd02..e7581d6777 100644 --- a/server/test/org/apache/cloudstack/affinity/AffinityApiUnitTest.java +++ b/server/test/org/apache/cloudstack/affinity/AffinityApiUnitTest.java @@ -32,6 +32,7 @@ import javax.inject.Inject; import javax.naming.ConfigurationException; +import com.cloud.utils.db.EntityManager; import org.junit.After; import org.junit.Before; import org.junit.BeforeClass; @@ -282,6 +283,11 @@ public AffinityGroupDomainMapDao affinityGroupDomainMapDao() { return Mockito.mock(AffinityGroupDomainMapDao.class); } + @Bean + public EntityManager entityManager() { + return Mockito.mock(EntityManager.class); + } + @Bean public DomainDao domainDao() { return Mockito.mock(DomainDao.class); diff --git a/server/test/org/apache/cloudstack/network/lb/CertServiceTest.java b/server/test/org/apache/cloudstack/network/lb/CertServiceTest.java index a67a9abf12..038845d928 100644 --- a/server/test/org/apache/cloudstack/network/lb/CertServiceTest.java +++ b/server/test/org/apache/cloudstack/network/lb/CertServiceTest.java @@ -27,21 +27,19 @@ import java.io.File; import java.io.IOException; import java.lang.reflect.Field; -import java.net.URLEncoder; import java.util.ArrayList; import java.util.List; import java.util.UUID; +import org.apache.cloudstack.api.command.user.loadbalancer.DeleteSslCertCmd; +import org.apache.cloudstack.api.command.user.loadbalancer.UploadSslCertCmd; +import org.apache.cloudstack.context.CallContext; import org.junit.After; import org.junit.Assume; import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; -import org.apache.cloudstack.api.command.user.loadbalancer.DeleteSslCertCmd; -import org.apache.cloudstack.api.command.user.loadbalancer.UploadSslCertCmd; -import org.apache.cloudstack.context.CallContext; - import com.cloud.network.dao.LoadBalancerCertMapDao; import com.cloud.network.dao.LoadBalancerCertMapVO; import com.cloud.network.dao.LoadBalancerVO; @@ -101,9 +99,9 @@ public void runUploadSslCertWithCAChain() throws Exception { String chainFile = getClass().getResource("/certs/root_chain.crt").getFile(); String password = "user"; - String cert = URLEncoder.encode(readFileToString(new File(certFile)), "UTF-8"); - String key = URLEncoder.encode(readFileToString(new File(keyFile)), "UTF-8"); - String chain = URLEncoder.encode(readFileToString(new File(chainFile)), "UTF-8"); + String cert = readFileToString(new File(certFile)); + String key = readFileToString(new File(keyFile)); + String chain = readFileToString(new File(chainFile)); CertServiceImpl certService = new CertServiceImpl(); @@ -153,8 +151,8 @@ public void runUploadSslCertSelfSignedWithPassword() throws Exception { String keyFile = getClass().getResource("/certs/rsa_self_signed_with_pwd.key").getFile(); String password = "test"; - String cert = URLEncoder.encode(readFileToString(new File(certFile)), "UTF-8"); - String key = URLEncoder.encode(readFileToString(new File(keyFile)), "UTF-8"); + String cert = readFileToString(new File(certFile)); + String key = readFileToString(new File(keyFile)); CertServiceImpl certService = new CertServiceImpl(); @@ -199,8 +197,8 @@ public void runUploadSslCertSelfSignedNoPassword() throws Exception { String certFile = getClass().getResource("/certs/rsa_self_signed.crt").getFile(); String keyFile = getClass().getResource("/certs/rsa_self_signed.key").getFile(); - String cert = URLEncoder.encode(readFileToString(new File(certFile)), "UTF-8"); - String key = URLEncoder.encode(readFileToString(new File(keyFile)), "UTF-8"); + String cert = readFileToString(new File(certFile)); + String key = readFileToString(new File(keyFile)); CertServiceImpl certService = new CertServiceImpl(); @@ -239,9 +237,9 @@ public void runUploadSslCertBadChain() throws IOException, IllegalAccessExceptio String chainFile = getClass().getResource("/certs/rsa_self_signed.crt").getFile(); String password = "user"; - String cert = URLEncoder.encode(readFileToString(new File(certFile)), "UTF-8"); - String key = URLEncoder.encode(readFileToString(new File(keyFile)), "UTF-8"); - String chain = URLEncoder.encode(readFileToString(new File(chainFile)), "UTF-8"); + String cert = readFileToString(new File(certFile)); + String key = readFileToString(new File(keyFile)); + String chain = readFileToString(new File(chainFile)); CertServiceImpl certService = new CertServiceImpl(); @@ -291,9 +289,9 @@ public void runUploadSslCertNoRootCert() throws IOException, IllegalAccessExcept String chainFile = getClass().getResource("/certs/rsa_ca_signed2.crt").getFile(); String password = "user"; - String cert = URLEncoder.encode(readFileToString(new File(certFile)), "UTF-8"); - String key = URLEncoder.encode(readFileToString(new File(keyFile)), "UTF-8"); - String chain = URLEncoder.encode(readFileToString(new File(chainFile)), "UTF-8"); + String cert = readFileToString(new File(certFile)); + String key = readFileToString(new File(keyFile)); + String chain = readFileToString(new File(chainFile)); CertServiceImpl certService = new CertServiceImpl(); @@ -343,8 +341,8 @@ public void runUploadSslCertNoChain() throws IOException, IllegalAccessException String keyFile = getClass().getResource("/certs/rsa_ca_signed.key").getFile(); String password = "user"; - String cert = URLEncoder.encode(readFileToString(new File(certFile)), "UTF-8"); - String key = URLEncoder.encode(readFileToString(new File(keyFile)), "UTF-8"); + String cert = readFileToString(new File(certFile)); + String key = readFileToString(new File(keyFile)); CertServiceImpl certService = new CertServiceImpl(); @@ -388,8 +386,8 @@ public void runUploadSslCertBadPassword() throws IOException, IllegalAccessExcep String keyFile = getClass().getResource("/certs/rsa_self_signed_with_pwd.key").getFile(); String password = "bad_password"; - String cert = URLEncoder.encode(readFileToString(new File(certFile)), "UTF-8"); - String key = URLEncoder.encode(readFileToString(new File(keyFile)), "UTF-8"); + String cert = readFileToString(new File(certFile)); + String key = readFileToString(new File(keyFile)); CertServiceImpl certService = new CertServiceImpl(); @@ -432,8 +430,8 @@ public void runUploadSslCertBadkeyPair() throws IOException, IllegalAccessExcept String certFile = getClass().getResource("/certs/rsa_self_signed.crt").getFile(); String keyFile = getClass().getResource("/certs/rsa_random_pkey.key").getFile(); - String cert = URLEncoder.encode(readFileToString(new File(certFile)), "UTF-8"); - String key = URLEncoder.encode(readFileToString(new File(keyFile)), "UTF-8"); + String cert = readFileToString(new File(certFile)); + String key = readFileToString(new File(keyFile)); CertServiceImpl certService = new CertServiceImpl(); @@ -471,8 +469,8 @@ public void runUploadSslCertBadkeyAlgo() throws IOException, IllegalAccessExcept String certFile = getClass().getResource("/certs/rsa_self_signed.crt").getFile(); String keyFile = getClass().getResource("/certs/dsa_self_signed.key").getFile(); - String cert = URLEncoder.encode(readFileToString(new File(certFile)), "UTF-8"); - String key = URLEncoder.encode(readFileToString(new File(keyFile)), "UTF-8"); + String cert = readFileToString(new File(certFile)); + String key = readFileToString(new File(keyFile)); CertServiceImpl certService = new CertServiceImpl(); @@ -511,8 +509,8 @@ public void runUploadSslCertExpiredCert() throws IOException, IllegalAccessExcep String certFile = getClass().getResource("/certs/expired_cert.crt").getFile(); String keyFile = getClass().getResource("/certs/rsa_self_signed.key").getFile(); - String cert = URLEncoder.encode(readFileToString(new File(certFile)), "UTF-8"); - String key = URLEncoder.encode(readFileToString(new File(keyFile)), "UTF-8"); + String cert = readFileToString(new File(certFile)); + String key = readFileToString(new File(keyFile)); CertServiceImpl certService = new CertServiceImpl(); @@ -550,8 +548,8 @@ public void runUploadSslCertNotX509() throws IOException, IllegalAccessException String certFile = getClass().getResource("/certs/non_x509_pem.crt").getFile(); String keyFile = getClass().getResource("/certs/rsa_self_signed.key").getFile(); - String cert = URLEncoder.encode(readFileToString(new File(certFile)), "UTF-8"); - String key = URLEncoder.encode(readFileToString(new File(keyFile)), "UTF-8"); + String cert = readFileToString(new File(certFile)); + String key = readFileToString(new File(keyFile)); CertServiceImpl certService = new CertServiceImpl(); @@ -590,8 +588,8 @@ public void runUploadSslCertBadFormat() throws IOException, IllegalAccessExcepti String certFile = getClass().getResource("/certs/bad_format_cert.crt").getFile(); String keyFile = getClass().getResource("/certs/rsa_self_signed.key").getFile(); - String cert = URLEncoder.encode(readFileToString(new File(certFile)), "UTF-8"); - String key = URLEncoder.encode(readFileToString(new File(keyFile)), "UTF-8"); + String cert = readFileToString(new File(certFile)); + String key = readFileToString(new File(keyFile)); CertServiceImpl certService = new CertServiceImpl(); diff --git a/server/test/org/apache/cloudstack/networkoffering/ChildTestConfiguration.java b/server/test/org/apache/cloudstack/networkoffering/ChildTestConfiguration.java index 22516c03a4..4760144043 100644 --- a/server/test/org/apache/cloudstack/networkoffering/ChildTestConfiguration.java +++ b/server/test/org/apache/cloudstack/networkoffering/ChildTestConfiguration.java @@ -19,6 +19,7 @@ import java.io.IOException; +import com.cloud.storage.StorageManager; import org.mockito.Mockito; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; @@ -132,7 +133,8 @@ PortableIpRangeDaoImpl.class, RegionDaoImpl.class, PortableIpDaoImpl.class, AccountGuestVlanMapDaoImpl.class}, includeFilters = {@Filter(value = ChildTestConfiguration.Library.class, type = FilterType.CUSTOM)}, useDefaultFilters = false) -public class ChildTestConfiguration { +public class + ChildTestConfiguration { @Bean public ManagementService managementService() { @@ -329,6 +331,11 @@ public AffinityGroupService affinityGroupService() { return Mockito.mock(AffinityGroupService.class); } + @Bean + public StorageManager storageManager() { + return Mockito.mock(StorageManager.class); + } + public static class Library implements TypeFilter { @Override diff --git a/server/test/org/apache/cloudstack/networkoffering/CreateNetworkOfferingTest.java b/server/test/org/apache/cloudstack/networkoffering/CreateNetworkOfferingTest.java index ccebb95e2c..466adb52e0 100644 --- a/server/test/org/apache/cloudstack/networkoffering/CreateNetworkOfferingTest.java +++ b/server/test/org/apache/cloudstack/networkoffering/CreateNetworkOfferingTest.java @@ -26,6 +26,10 @@ import junit.framework.TestCase; +import org.apache.cloudstack.context.CallContext; +import org.apache.cloudstack.framework.config.dao.ConfigurationDao; +import org.apache.cloudstack.framework.config.impl.ConfigurationVO; +import org.apache.cloudstack.resourcedetail.dao.UserIpAddressDetailsDao; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -35,10 +39,6 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.apache.cloudstack.context.CallContext; -import org.apache.cloudstack.framework.config.dao.ConfigurationDao; -import org.apache.cloudstack.framework.config.impl.ConfigurationVO; - import com.cloud.configuration.ConfigurationManager; import com.cloud.event.dao.UsageEventDao; import com.cloud.event.dao.UsageEventDetailsDao; @@ -90,6 +90,9 @@ public class CreateNetworkOfferingTest extends TestCase { @Inject UsageEventDetailsDao usageEventDetailsDao; + @Inject + UserIpAddressDetailsDao userIpAddressDetailsDao; + @Override @Before public void setUp() { diff --git a/server/test/resources/createNetworkOffering.xml b/server/test/resources/createNetworkOffering.xml index 6ae1978f40..1336367582 100644 --- a/server/test/resources/createNetworkOffering.xml +++ b/server/test/resources/createNetworkOffering.xml @@ -48,4 +48,8 @@ + + + + diff --git a/services/iam/plugin/src/org/apache/cloudstack/api/command/iam/AddIAMPermissionToIAMPolicyCmd.java b/services/iam/plugin/src/org/apache/cloudstack/api/command/iam/AddIAMPermissionToIAMPolicyCmd.java index d37cc3cb7b..d69f3d0a0b 100644 --- a/services/iam/plugin/src/org/apache/cloudstack/api/command/iam/AddIAMPermissionToIAMPolicyCmd.java +++ b/services/iam/plugin/src/org/apache/cloudstack/api/command/iam/AddIAMPermissionToIAMPolicyCmd.java @@ -72,6 +72,9 @@ public class AddIAMPermissionToIAMPolicyCmd extends BaseAsyncCmd { @Parameter(name = ApiConstants.IAM_SCOPE_ID, type = CommandType.STRING, required = false, description = "The UUID of the permission scope id") private String scopeId; + @Parameter(name = ApiConstants.READ_ONLY, type = CommandType.BOOLEAN, required = false, description = "Read Only access is added; Only applicable when action = List/Read api name") + private Boolean readOnly; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// @@ -100,6 +103,10 @@ public Long getScopeId() { return _iamApiSrv.getPermissionScopeId(scope, entityType, scopeId); } + public Boolean isReadOnly() { + return (readOnly != null) ? readOnly : false; + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// @@ -123,7 +130,7 @@ public void execute() throws ResourceUnavailableException, CallContext.current().setEventDetails("IAM policy Id: " + getId()); // Only explicit ALLOW is supported for this release, no explicit deny IAMPolicy result = _iamApiSrv.addIAMPermissionToIAMPolicy(id, entityType, PermissionScope.valueOf(scope), - getScopeId(), action, Permission.Allow, false); + getScopeId(), action, Permission.Allow, false, isReadOnly()); if (result != null) { IAMPolicyResponse response = _iamApiSrv.createIAMPolicyResponse(result); response.setResponseName(getCommandName()); diff --git a/services/iam/plugin/src/org/apache/cloudstack/api/command/iam/CreateIAMGroupCmd.java b/services/iam/plugin/src/org/apache/cloudstack/api/command/iam/CreateIAMGroupCmd.java index d0b9bc6b1c..93940e810c 100644 --- a/services/iam/plugin/src/org/apache/cloudstack/api/command/iam/CreateIAMGroupCmd.java +++ b/services/iam/plugin/src/org/apache/cloudstack/api/command/iam/CreateIAMGroupCmd.java @@ -97,7 +97,7 @@ public String getCommandName() { @Override public long getEntityOwnerId() { Account account = CallContext.current().getCallingAccount(); - if ((account == null) || _accountService.isAdmin(account.getType())) { + if ((account == null) || _accountService.isAdmin(account.getId())) { if ((domainId != null) && (accountName != null)) { Account userAccount = _responseGenerator.findAccountByNameDomain(accountName, domainId); if (userAccount != null) { diff --git a/services/iam/plugin/src/org/apache/cloudstack/api/command/iam/CreateIAMPolicyCmd.java b/services/iam/plugin/src/org/apache/cloudstack/api/command/iam/CreateIAMPolicyCmd.java index be863de308..7ebab6735a 100644 --- a/services/iam/plugin/src/org/apache/cloudstack/api/command/iam/CreateIAMPolicyCmd.java +++ b/services/iam/plugin/src/org/apache/cloudstack/api/command/iam/CreateIAMPolicyCmd.java @@ -104,7 +104,7 @@ public String getCommandName() { @Override public long getEntityOwnerId() { Account account = CallContext.current().getCallingAccount(); - if ((account == null) || _accountService.isAdmin(account.getType())) { + if ((account == null) || _accountService.isAdmin(account.getId())) { if ((domainId != null) && (accountName != null)) { Account userAccount = _responseGenerator.findAccountByNameDomain(accountName, domainId); if (userAccount != null) { diff --git a/services/iam/plugin/src/org/apache/cloudstack/api/response/iam/IAMPermissionResponse.java b/services/iam/plugin/src/org/apache/cloudstack/api/response/iam/IAMPermissionResponse.java index 5def248d7a..046e1f4d34 100644 --- a/services/iam/plugin/src/org/apache/cloudstack/api/response/iam/IAMPermissionResponse.java +++ b/services/iam/plugin/src/org/apache/cloudstack/api/response/iam/IAMPermissionResponse.java @@ -18,7 +18,6 @@ import com.google.gson.annotations.SerializedName; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.PermissionScope; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseResponse; @@ -34,7 +33,7 @@ public class IAMPermissionResponse extends BaseResponse { @SerializedName(ApiConstants.ENTITY_TYPE) @Param(description = "the entity type of this permission") - private IAMEntityType entityType; + private String entityType; @SerializedName(ApiConstants.IAM_SCOPE) @Param(description = "scope of this permission") @@ -48,11 +47,11 @@ public class IAMPermissionResponse extends BaseResponse { @Param(description = "allow or deny of this permission") private IAMPolicyPermission.Permission permission; - public IAMEntityType getEntityType() { + public String getEntityType() { return entityType; } - public void setEntityType(IAMEntityType entityType) { + public void setEntityType(String entityType) { this.entityType = entityType; } diff --git a/services/iam/plugin/src/org/apache/cloudstack/iam/IAMApiService.java b/services/iam/plugin/src/org/apache/cloudstack/iam/IAMApiService.java index bb8f03b77f..6735d4804d 100644 --- a/services/iam/plugin/src/org/apache/cloudstack/iam/IAMApiService.java +++ b/services/iam/plugin/src/org/apache/cloudstack/iam/IAMApiService.java @@ -60,7 +60,7 @@ public interface IAMApiService extends PluggableService { void removeIAMPolicyFromAccounts(Long policyId, List accountIds); IAMPolicy addIAMPermissionToIAMPolicy(long iamPolicyId, String entityType, PermissionScope scope, Long scopeId, - String action, Permission perm, Boolean recursive); + String action, Permission perm, Boolean recursive, Boolean readOnly); IAMPolicy removeIAMPermissionFromIAMPolicy(long iamPolicyId, String entityType, PermissionScope scope, Long scopeId, String action); diff --git a/services/iam/plugin/src/org/apache/cloudstack/iam/IAMApiServiceImpl.java b/services/iam/plugin/src/org/apache/cloudstack/iam/IAMApiServiceImpl.java index 69f669c7e1..b4c2d4d0d2 100644 --- a/services/iam/plugin/src/org/apache/cloudstack/iam/IAMApiServiceImpl.java +++ b/services/iam/plugin/src/org/apache/cloudstack/iam/IAMApiServiceImpl.java @@ -27,11 +27,18 @@ import javax.naming.ConfigurationException; import org.apache.log4j.Logger; +import org.bouncycastle.util.IPAddress; + +import com.amazonaws.auth.policy.Condition; +import com.amazonaws.services.ec2.model.SecurityGroup; +import com.amazonaws.services.ec2.model.Snapshot; +import com.amazonaws.services.ec2.model.Volume; +import com.amazonaws.services.ec2.model.Vpc; +import com.amazonaws.services.elasticache.model.Event; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.PermissionScope; import org.apache.cloudstack.acl.SecurityChecker.AccessType; -import org.apache.cloudstack.affinity.AffinityGroupVO; +import org.apache.cloudstack.affinity.AffinityGroup; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseListCmd; import org.apache.cloudstack.api.InternalIdentity; @@ -54,7 +61,7 @@ import org.apache.cloudstack.api.response.iam.IAMPermissionResponse; import org.apache.cloudstack.api.response.iam.IAMPolicyResponse; import org.apache.cloudstack.context.CallContext; -import org.apache.cloudstack.framework.jobs.impl.AsyncJobVO; +import org.apache.cloudstack.framework.jobs.AsyncJob; import org.apache.cloudstack.framework.messagebus.MessageBus; import org.apache.cloudstack.framework.messagebus.MessageSubscriber; import org.apache.cloudstack.iam.api.IAMGroup; @@ -62,9 +69,6 @@ import org.apache.cloudstack.iam.api.IAMPolicyPermission; import org.apache.cloudstack.iam.api.IAMPolicyPermission.Permission; import org.apache.cloudstack.iam.api.IAMService; -import org.apache.cloudstack.iam.server.IAMGroupVO; -import org.apache.cloudstack.iam.server.IAMPolicyVO; -import org.apache.cloudstack.region.gslb.GlobalLoadBalancerRuleVO; import com.cloud.api.ApiServerService; import com.cloud.domain.Domain; @@ -72,50 +76,45 @@ import com.cloud.domain.dao.DomainDao; import com.cloud.event.ActionEvent; import com.cloud.event.EventTypes; -import com.cloud.event.EventVO; import com.cloud.exception.InvalidParameterValueException; -import com.cloud.network.UserIpv6AddressVO; -import com.cloud.network.VpnUserVO; -import com.cloud.network.as.AutoScalePolicyVO; -import com.cloud.network.as.AutoScaleVmGroupVO; -import com.cloud.network.as.AutoScaleVmProfileVO; -import com.cloud.network.as.ConditionVO; -import com.cloud.network.dao.IPAddressVO; -import com.cloud.network.dao.MonitoringServiceVO; -import com.cloud.network.dao.NetworkVO; -import com.cloud.network.dao.RemoteAccessVpnVO; -import com.cloud.network.dao.Site2SiteCustomerGatewayVO; -import com.cloud.network.dao.Site2SiteVpnConnectionVO; -import com.cloud.network.dao.Site2SiteVpnGatewayVO; -import com.cloud.network.dao.SslCertVO; -import com.cloud.network.rules.FirewallRuleVO; -import com.cloud.network.rules.PortForwardingRuleVO; -import com.cloud.network.security.SecurityGroupVO; -import com.cloud.network.vpc.StaticRouteVO; -import com.cloud.network.vpc.VpcGatewayVO; -import com.cloud.network.vpc.VpcVO; -import com.cloud.projects.ProjectInvitationVO; -import com.cloud.storage.SnapshotVO; -import com.cloud.storage.VMTemplateVO; -import com.cloud.storage.VolumeVO; -import com.cloud.tags.ResourceTagVO; +import com.cloud.network.IpAddress; +import com.cloud.network.MonitoringService; +import com.cloud.network.Network; +import com.cloud.network.RemoteAccessVpn; +import com.cloud.network.Site2SiteCustomerGateway; +import com.cloud.network.Site2SiteVpnConnection; +import com.cloud.network.Site2SiteVpnGateway; +import com.cloud.network.UserIpv6Address; +import com.cloud.network.VpnUser; +import com.cloud.network.as.AutoScalePolicy; +import com.cloud.network.as.AutoScaleVmGroup; +import com.cloud.network.as.AutoScaleVmProfile; +import com.cloud.network.lb.SslCert; +import com.cloud.network.rules.FirewallRule; +import com.cloud.network.rules.PortForwardingRule; +import com.cloud.network.vpc.StaticRoute; +import com.cloud.network.vpc.VpcGateway; +import com.cloud.projects.ProjectInvitation; +import com.cloud.region.ha.GlobalLoadBalancerRule; +import com.cloud.server.ResourceTag; import com.cloud.template.TemplateManager; +import com.cloud.template.VirtualMachineTemplate; import com.cloud.user.Account; import com.cloud.user.AccountManager; import com.cloud.user.AccountVO; import com.cloud.user.DomainManager; -import com.cloud.user.SSHKeyPairVO; +import com.cloud.user.SSHKeyPair; import com.cloud.user.dao.AccountDao; import com.cloud.utils.Pair; import com.cloud.utils.component.Manager; import com.cloud.utils.component.ManagerBase; import com.cloud.utils.db.DB; import com.cloud.utils.db.EntityManager; -import com.cloud.vm.InstanceGroupVO; -import com.cloud.vm.VMInstanceVO; -import com.cloud.vm.dao.NicIpAliasVO; -import com.cloud.vm.dao.NicSecondaryIpVO; -import com.cloud.vm.snapshot.VMSnapshotVO; +import com.cloud.vm.InstanceGroup; +import com.cloud.vm.NicIpAlias; +import com.cloud.vm.NicSecondaryIp; +import com.cloud.vm.VirtualMachine; +import com.cloud.vm.snapshot.VMSnapshot; @Local(value = {IAMApiService.class}) public class IAMApiServiceImpl extends ManagerBase implements IAMApiService, Manager { @@ -144,48 +143,46 @@ public class IAMApiServiceImpl extends ManagerBase implements IAMApiService, Man @Inject EntityManager _entityMgr; - private static final Map> s_typeMap = new HashMap>(); + private static final Map> s_typeMap = new HashMap>(); static { - s_typeMap.put(IAMEntityType.VirtualMachine, VMInstanceVO.class); - s_typeMap.put(IAMEntityType.Volume, VolumeVO.class); - s_typeMap.put(IAMEntityType.ResourceTag, ResourceTagVO.class); - s_typeMap.put(IAMEntityType.Account, AccountVO.class); - s_typeMap.put(IAMEntityType.AffinityGroup, AffinityGroupVO.class); - s_typeMap.put(IAMEntityType.AutoScalePolicy, AutoScalePolicyVO.class); - s_typeMap.put(IAMEntityType.AutoScaleVmProfile, AutoScaleVmProfileVO.class); - s_typeMap.put(IAMEntityType.AutoScaleVmGroup, AutoScaleVmGroupVO.class); - s_typeMap.put(IAMEntityType.Condition, ConditionVO.class); - s_typeMap.put(IAMEntityType.Vpc, VpcVO.class); - s_typeMap.put(IAMEntityType.VpcGateway, VpcGatewayVO.class); - s_typeMap.put(IAMEntityType.PrivateGateway, RemoteAccessVpnVO.class); - s_typeMap.put(IAMEntityType.VpnUser, VpnUserVO.class); - s_typeMap.put(IAMEntityType.VMSnapshot, VMSnapshotVO.class); - s_typeMap.put(IAMEntityType.VirtualMachineTemplate, VMTemplateVO.class); - s_typeMap.put(IAMEntityType.UserIpv6Address, UserIpv6AddressVO.class); - s_typeMap.put(IAMEntityType.StaticRoute, StaticRouteVO.class); - s_typeMap.put(IAMEntityType.SSHKeyPair, SSHKeyPairVO.class); - s_typeMap.put(IAMEntityType.Snapshot, SnapshotVO.class); - s_typeMap.put(IAMEntityType.Site2SiteVpnGateway, Site2SiteVpnGatewayVO.class); - s_typeMap.put(IAMEntityType.Site2SiteCustomerGateway, Site2SiteCustomerGatewayVO.class); - s_typeMap.put(IAMEntityType.Site2SiteVpnConnection, Site2SiteVpnConnectionVO.class); - s_typeMap.put(IAMEntityType.SecurityGroup, SecurityGroupVO.class); - s_typeMap.put(IAMEntityType.RemoteAccessVpn, RemoteAccessVpnVO.class); - s_typeMap.put(IAMEntityType.PublicIpAddress, IPAddressVO.class); - s_typeMap.put(IAMEntityType.ProjectInvitation, ProjectInvitationVO.class); - s_typeMap.put(IAMEntityType.NicSecondaryIp, NicSecondaryIpVO.class); - s_typeMap.put(IAMEntityType.NicIpAlias, NicIpAliasVO.class); - s_typeMap.put(IAMEntityType.Network, NetworkVO.class); - s_typeMap.put(IAMEntityType.IpAddress, IPAddressVO.class); - s_typeMap.put(IAMEntityType.InstanceGroup, InstanceGroupVO.class); - s_typeMap.put(IAMEntityType.GlobalLoadBalancerRule, GlobalLoadBalancerRuleVO.class); - s_typeMap.put(IAMEntityType.FirewallRule, FirewallRuleVO.class); - s_typeMap.put(IAMEntityType.PortForwardingRule, PortForwardingRuleVO.class); - s_typeMap.put(IAMEntityType.Event, EventVO.class); - s_typeMap.put(IAMEntityType.AsyncJob, AsyncJobVO.class); - s_typeMap.put(IAMEntityType.IAMGroup, IAMGroupVO.class); - s_typeMap.put(IAMEntityType.IAMPolicy, IAMPolicyVO.class); - s_typeMap.put(IAMEntityType.MonitorService, MonitoringServiceVO.class); - s_typeMap.put(IAMEntityType.SSLCert, SslCertVO.class); + s_typeMap.put(VirtualMachine.class.getSimpleName(), VirtualMachine.class); + s_typeMap.put(Volume.class.getSimpleName(), Volume.class); + s_typeMap.put(ResourceTag.class.getSimpleName(), ResourceTag.class); + s_typeMap.put(Account.class.getSimpleName(), Account.class); + s_typeMap.put(AffinityGroup.class.getSimpleName(), AffinityGroup.class); + s_typeMap.put(AutoScalePolicy.class.getSimpleName(), AutoScalePolicy.class); + s_typeMap.put(AutoScaleVmProfile.class.getSimpleName(), AutoScaleVmProfile.class); + s_typeMap.put(AutoScaleVmGroup.class.getSimpleName(), AutoScaleVmGroup.class); + s_typeMap.put(Condition.class.getSimpleName(), Condition.class); + s_typeMap.put(Vpc.class.getSimpleName(), Vpc.class); + s_typeMap.put(VpcGateway.class.getSimpleName(), VpcGateway.class); + s_typeMap.put(VpnUser.class.getSimpleName(), VpnUser.class); + s_typeMap.put(VMSnapshot.class.getSimpleName(), VMSnapshot.class); + s_typeMap.put(VirtualMachineTemplate.class.getSimpleName(), VirtualMachineTemplate.class); + s_typeMap.put(UserIpv6Address.class.getSimpleName(), UserIpv6Address.class); + s_typeMap.put(StaticRoute.class.getSimpleName(), StaticRoute.class); + s_typeMap.put(SSHKeyPair.class.getSimpleName(), SSHKeyPair.class); + s_typeMap.put(Snapshot.class.getSimpleName(), Snapshot.class); + s_typeMap.put(Site2SiteVpnGateway.class.getSimpleName(), Site2SiteVpnGateway.class); + s_typeMap.put(Site2SiteCustomerGateway.class.getSimpleName(), Site2SiteCustomerGateway.class); + s_typeMap.put(Site2SiteVpnConnection.class.getSimpleName(), Site2SiteVpnConnection.class); + s_typeMap.put(SecurityGroup.class.getSimpleName(), SecurityGroup.class); + s_typeMap.put(RemoteAccessVpn.class.getSimpleName(), RemoteAccessVpn.class); + s_typeMap.put(ProjectInvitation.class.getSimpleName(), ProjectInvitation.class); + s_typeMap.put(NicSecondaryIp.class.getSimpleName(), NicSecondaryIp.class); + s_typeMap.put(NicIpAlias.class.getSimpleName(), NicIpAlias.class); + s_typeMap.put(Network.class.getSimpleName(), Network.class); + s_typeMap.put(IpAddress.class.getSimpleName(), IPAddress.class); + s_typeMap.put(InstanceGroup.class.getSimpleName(), InstanceGroup.class); + s_typeMap.put(GlobalLoadBalancerRule.class.getSimpleName(), GlobalLoadBalancerRule.class); + s_typeMap.put(FirewallRule.class.getSimpleName(), FirewallRule.class); + s_typeMap.put(PortForwardingRule.class.getSimpleName(), PortForwardingRule.class); + s_typeMap.put(Event.class.getSimpleName(), Event.class); + s_typeMap.put(AsyncJob.class.getSimpleName(), AsyncJob.class); + s_typeMap.put(IAMGroup.class.getSimpleName(), IAMGroup.class); + s_typeMap.put(IAMPolicy.class.getSimpleName(), IAMPolicy.class); + s_typeMap.put(MonitoringService.class.getSimpleName(), MonitoringService.class); + s_typeMap.put(SslCert.class.getSimpleName(), SslCert.class); } @Override @@ -246,7 +243,7 @@ public void onPublishMessage(String senderAddress, String subject, Object obj) { Long domainId = ((Long) obj); if (domainId != null) { s_logger.debug("MessageBus message: Domain removed: " + domainId + ", removing the domain group"); - Domain domain = _domainDao.findById(domainId); + Domain domain = _domainDao.findByIdIncludingRemoved(domainId); List groups = listDomainGroup(domain); for (IAMGroup group : groups) { _iamSrv.deleteIAMGroup(group.getId()); @@ -260,10 +257,13 @@ public void onPublishMessage(String senderAddress, String subject, Object obj) { public void onPublishMessage(String senderAddress, String subject, Object obj) { Long templateId = (Long)obj; if (templateId != null) { - s_logger.debug("MessageBus message: new public template registered: " + templateId + ", grant permission to domain admin and normal user policies"); - _iamSrv.addIAMPermissionToIAMPolicy(new Long(Account.ACCOUNT_TYPE_DOMAIN_ADMIN + 1), IAMEntityType.VirtualMachineTemplate.toString(), + s_logger.debug("MessageBus message: new public template registered: " + templateId + + ", grant permission to default root admin, domain admin and normal user policies"); + _iamSrv.addIAMPermissionToIAMPolicy(new Long(Account.ACCOUNT_TYPE_ADMIN + 1), VirtualMachineTemplate.class.getSimpleName(), + PermissionScope.RESOURCE.toString(), templateId, "listTemplates", AccessType.UseEntry.toString(), Permission.Allow, false); + _iamSrv.addIAMPermissionToIAMPolicy(new Long(Account.ACCOUNT_TYPE_DOMAIN_ADMIN + 1), VirtualMachineTemplate.class.getSimpleName(), PermissionScope.RESOURCE.toString(), templateId, "listTemplates", AccessType.UseEntry.toString(), Permission.Allow, false); - _iamSrv.addIAMPermissionToIAMPolicy(new Long(Account.ACCOUNT_TYPE_NORMAL + 1), IAMEntityType.VirtualMachineTemplate.toString(), + _iamSrv.addIAMPermissionToIAMPolicy(new Long(Account.ACCOUNT_TYPE_NORMAL + 1), VirtualMachineTemplate.class.getSimpleName(), PermissionScope.RESOURCE.toString(), templateId, "listTemplates", AccessType.UseEntry.toString(), Permission.Allow, false); } } @@ -283,9 +283,9 @@ public void onPublishMessage(String senderAddress, String subject, Object obj) { _messageBus.subscribe(EntityManager.MESSAGE_REMOVE_ENTITY_EVENT, new MessageSubscriber() { @Override public void onPublishMessage(String senderAddress, String subject, Object obj) { - Pair entity = (Pair)obj; + Pair, Long> entity = (Pair, Long>)obj; if (entity != null) { - String entityType = entity.first().toString(); + String entityType = entity.first().getSimpleName(); Long entityId = entity.second(); s_logger.debug("MessageBus message: delete an entity: (" + entityType + "," + entityId + "), remove its related permission"); _iamSrv.removeIAMPermissionForEntity(entityType, entityId); @@ -299,13 +299,13 @@ public void onPublishMessage(String senderAddress, String subject, Object obj) { public void onPublishMessage(String senderAddress, String subject, Object obj) { Map permit = (Map)obj; if (permit != null) { - String entityType = (String)permit.get(ApiConstants.ENTITY_TYPE); + Class entityType = (Class)permit.get(ApiConstants.ENTITY_TYPE); Long entityId = (Long)permit.get(ApiConstants.ENTITY_ID); AccessType accessType = (AccessType)permit.get(ApiConstants.ACCESS_TYPE); String action = (String)permit.get(ApiConstants.IAM_ACTION); List acctIds = (List)permit.get(ApiConstants.ACCOUNTS); s_logger.debug("MessageBus message: grant accounts permission to an entity: (" + entityType + "," + entityId + ")"); - grantEntityPermissioinToAccounts(entityType, entityId, accessType, action, acctIds); + grantEntityPermissioinToAccounts(entityType.getSimpleName(), entityId, accessType, action, acctIds); } } }); @@ -315,13 +315,13 @@ public void onPublishMessage(String senderAddress, String subject, Object obj) { public void onPublishMessage(String senderAddress, String subject, Object obj) { Map permit = (Map)obj; if (permit != null) { - String entityType = (String)permit.get(ApiConstants.ENTITY_TYPE); + Class entityType = (Class)permit.get(ApiConstants.ENTITY_TYPE); Long entityId = (Long)permit.get(ApiConstants.ENTITY_ID); AccessType accessType = (AccessType)permit.get(ApiConstants.ACCESS_TYPE); String action = (String)permit.get(ApiConstants.IAM_ACTION); List acctIds = (List)permit.get(ApiConstants.ACCOUNTS); s_logger.debug("MessageBus message: revoke from accounts permission to an entity: (" + entityType + "," + entityId + ")"); - revokeEntityPermissioinFromAccounts(entityType, entityId, accessType, action, acctIds); + revokeEntityPermissioinFromAccounts(entityType.getSimpleName(), entityId, accessType, action, acctIds); } } }); @@ -355,20 +355,35 @@ private void populateIAMGroupAdminAccountMap() { sysAccts.add(Account.ACCOUNT_ID_SYSTEM); sysAccts.add(Account.ACCOUNT_ID_SYSTEM + 1); _iamSrv.addAccountsToGroup(sysAccts, new Long(Account.ACCOUNT_TYPE_ADMIN + 1)); + + // add the root domain group + Domain domain = _domainDao.findById(Domain.ROOT_DOMAIN); + if (domain != null) { + List domainGroups = listDomainGroup(domain); + if (domainGroups != null && !domainGroups.isEmpty()) { + return; + } + IAMGroup rootDomainGrp = _iamSrv.createIAMGroup("DomainGrp-" + domain.getUuid(), "Root Domain group", + domain.getPath()); + // add the system accounts to the root domain group + _iamSrv.addAccountsToGroup(sysAccts, rootDomainGrp.getId()); + + } + } private void addDomainWideResourceAccess(Map params) { - IAMEntityType entityType = (IAMEntityType)params.get(ApiConstants.ENTITY_TYPE); + Class entityType = (Class)params.get(ApiConstants.ENTITY_TYPE); Long entityId = (Long) params.get(ApiConstants.ENTITY_ID); Long domainId = (Long) params.get(ApiConstants.DOMAIN_ID); Boolean isRecursive = (Boolean) params.get(ApiConstants.SUBDOMAIN_ACCESS); - if (entityType == IAMEntityType.Network) { - createPolicyAndAddToDomainGroup("DomainWideNetwork-" + entityId, "domain wide network", entityType.toString(), + if (entityType == Network.class) { + createPolicyAndAddToDomainGroup("DomainWideNetwork-" + entityId, "domain wide network", entityType.getSimpleName(), entityId, "listNetworks", AccessType.UseEntry, domainId, isRecursive); - } else if (entityType == IAMEntityType.AffinityGroup) { - createPolicyAndAddToDomainGroup("DomainWideNetwork-" + entityId, "domain wide affinityGroup", entityType.toString(), + } else if (entityType == AffinityGroup.class) { + createPolicyAndAddToDomainGroup("DomainWideNetwork-" + entityId, "domain wide affinityGroup", entityType.getSimpleName(), entityId, "listAffinityGroups", AccessType.UseEntry, domainId, isRecursive); } @@ -509,11 +524,17 @@ public void removeIAMPolicyFromAccounts(final Long policyId, final List ac @Override @ActionEvent(eventType = EventTypes.EVENT_IAM_POLICY_GRANT, eventDescription = "Granting acl permission to IAM Policy") public IAMPolicy addIAMPermissionToIAMPolicy(long iamPolicyId, String entityType, PermissionScope scope, - Long scopeId, String action, Permission perm, Boolean recursive) { + Long scopeId, String action, Permission perm, Boolean recursive, Boolean readOnly) { Class cmdClass = _apiServer.getCmdClass(action); AccessType accessType = null; if (BaseListCmd.class.isAssignableFrom(cmdClass)) { - accessType = AccessType.UseEntry; + if (readOnly) { + accessType = AccessType.ListEntry; + } else { + accessType = AccessType.UseEntry; + } + } else { + accessType = AccessType.OperateEntry; } String accessTypeStr = (accessType != null) ? accessType.toString() : null; return _iamSrv.addIAMPermissionToIAMPolicy(iamPolicyId, entityType, scope.toString(), scopeId, action, @@ -575,7 +596,7 @@ public IAMPolicyResponse createIAMPolicyResponse(IAMPolicy policy) { IAMPermissionResponse perm = new IAMPermissionResponse(); perm.setAction(permission.getAction()); if (permission.getEntityType() != null) { - perm.setEntityType(IAMEntityType.valueOf(permission.getEntityType())); + perm.setEntityType(permission.getEntityType()); } if (permission.getScope() != null) { perm.setScope(PermissionScope.valueOf(permission.getScope())); @@ -717,7 +738,8 @@ public void grantEntityPermissioinToAccounts(String entityType, Long entityId, A String description = "Policy to grant permission to " + entityType + entityId; policy = createIAMPolicy(caller, aclPolicyName, description, null); // add permission to this policy - addIAMPermissionToIAMPolicy(policy.getId(), entityType, PermissionScope.RESOURCE, entityId, action, Permission.Allow, false); + addIAMPermissionToIAMPolicy(policy.getId(), entityType, PermissionScope.RESOURCE, entityId, action, + Permission.Allow, false, false); } // attach this policy to list of accounts if not attached already Long policyId = policy.getId(); @@ -758,12 +780,12 @@ private boolean isPolicyAttachedToAccount(Long policyId, Long accountId) { private void resetTemplatePermission(Long templateId){ // reset template will change template to private, so we need to remove its permission for domain admin and normal user group - _iamSrv.removeIAMPermissionFromIAMPolicy(new Long(Account.ACCOUNT_TYPE_DOMAIN_ADMIN + 1), IAMEntityType.VirtualMachineTemplate.toString(), + _iamSrv.removeIAMPermissionFromIAMPolicy(new Long(Account.ACCOUNT_TYPE_DOMAIN_ADMIN + 1), VirtualMachineTemplate.class.getSimpleName(), PermissionScope.RESOURCE.toString(), templateId, "listTemplates"); - _iamSrv.removeIAMPermissionFromIAMPolicy(new Long(Account.ACCOUNT_TYPE_NORMAL + 1), IAMEntityType.VirtualMachineTemplate.toString(), + _iamSrv.removeIAMPermissionFromIAMPolicy(new Long(Account.ACCOUNT_TYPE_NORMAL + 1), VirtualMachineTemplate.class.getSimpleName(), PermissionScope.RESOURCE.toString(), templateId, "listTemplates"); // check if there is a policy with only UseEntry permission for this template added - IAMPolicy policy = _iamSrv.getResourceGrantPolicy(IAMEntityType.VirtualMachineTemplate.toString(), templateId, AccessType.UseEntry.toString(), "listTemplates"); + IAMPolicy policy = _iamSrv.getResourceGrantPolicy(VirtualMachineTemplate.class.getSimpleName(), templateId, AccessType.UseEntry.toString(), "listTemplates"); if ( policy == null ){ s_logger.info("No policy found for this template grant: " + templateId + ", no detach to be done"); return; @@ -788,7 +810,7 @@ public Long getPermissionScopeId(String scope, String entityType, String scopeId entity = _accountDao.findByUuid(scopeId); break; case RESOURCE: - Class clazz = s_typeMap.get(IAMEntityType.valueOf(entityType)); + Class clazz = s_typeMap.get(entityType); entity = (InternalIdentity)_entityMgr.findByUuid(clazz, scopeId); } diff --git a/services/iam/plugin/src/org/apache/cloudstack/iam/RoleBasedAPIAccessChecker.java b/services/iam/plugin/src/org/apache/cloudstack/iam/RoleBasedAPIAccessChecker.java index fb75db310f..91593f6f23 100644 --- a/services/iam/plugin/src/org/apache/cloudstack/iam/RoleBasedAPIAccessChecker.java +++ b/services/iam/plugin/src/org/apache/cloudstack/iam/RoleBasedAPIAccessChecker.java @@ -29,12 +29,10 @@ import org.apache.log4j.Logger; import org.apache.cloudstack.acl.APIChecker; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.PermissionScope; import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.APICommand; -import org.apache.cloudstack.api.BaseAsyncCreateCmd; import org.apache.cloudstack.api.BaseCmd; import org.apache.cloudstack.api.BaseListCmd; import org.apache.cloudstack.iam.api.IAMPolicy; @@ -46,6 +44,7 @@ import com.cloud.exception.PermissionDeniedException; import com.cloud.storage.VMTemplateVO; import com.cloud.storage.dao.VMTemplateDao; +import com.cloud.template.VirtualMachineTemplate; import com.cloud.user.Account; import com.cloud.user.AccountService; import com.cloud.user.User; @@ -133,9 +132,11 @@ public boolean start() { // add permissions for public templates List pTmplts = _templateDao.listByPublic(); for (VMTemplateVO tmpl : pTmplts){ - _iamSrv.addIAMPermissionToIAMPolicy(new Long(Account.ACCOUNT_TYPE_DOMAIN_ADMIN + 1), IAMEntityType.VirtualMachineTemplate.toString(), + _iamSrv.addIAMPermissionToIAMPolicy(new Long(Account.ACCOUNT_TYPE_ADMIN + 1), VirtualMachineTemplate.class.getSimpleName(), PermissionScope.RESOURCE.toString(), tmpl.getId(), "listTemplates", AccessType.UseEntry.toString(), Permission.Allow, false); - _iamSrv.addIAMPermissionToIAMPolicy(new Long(Account.ACCOUNT_TYPE_NORMAL + 1), IAMEntityType.VirtualMachineTemplate.toString(), + _iamSrv.addIAMPermissionToIAMPolicy(new Long(Account.ACCOUNT_TYPE_DOMAIN_ADMIN + 1), VirtualMachineTemplate.class.getSimpleName(), + PermissionScope.RESOURCE.toString(), tmpl.getId(), "listTemplates", AccessType.UseEntry.toString(), Permission.Allow, false); + _iamSrv.addIAMPermissionToIAMPolicy(new Long(Account.ACCOUNT_TYPE_NORMAL + 1), VirtualMachineTemplate.class.getSimpleName(), PermissionScope.RESOURCE.toString(), tmpl.getId(), "listTemplates", AccessType.UseEntry.toString(), Permission.Allow, false); } @@ -216,26 +217,8 @@ public void setServices(List services) { } private void addDefaultAclPolicyPermission(String apiName, Class cmdClass, RoleType role) { - AccessType accessType = null; - IAMEntityType[] entityTypes = null; - if (cmdClass != null) { - BaseCmd cmdObj; - try { - cmdObj = (BaseCmd) cmdClass.newInstance(); - if (cmdObj instanceof BaseListCmd) { - accessType = AccessType.UseEntry; - } else if (!(cmdObj instanceof BaseAsyncCreateCmd)) { - accessType = AccessType.OperateEntry; - } - } catch (Exception e) { - throw new CloudRuntimeException(String.format( - "%s is claimed as an API command, but it cannot be instantiated", cmdClass.getName())); - } - - APICommand at = cmdClass.getAnnotation(APICommand.class); - entityTypes = at.entityType(); - } + Class[] entityTypes = null; PermissionScope permissionScope = PermissionScope.ACCOUNT; Long policyId = getDefaultPolicyId(role); @@ -257,14 +240,43 @@ private void addDefaultAclPolicyPermission(String apiName, Class cmdClass, Ro break; } + boolean addAccountScopedUseEntry = false; + + if (cmdClass != null) { + BaseCmd cmdObj; + try { + cmdObj = (BaseCmd) cmdClass.newInstance(); + if (cmdObj instanceof BaseListCmd) { + accessType = AccessType.ListEntry; + addAccountScopedUseEntry = true; + } else { + accessType = AccessType.OperateEntry; + } + } catch (Exception e) { + throw new CloudRuntimeException(String.format( + "%s is claimed as an API command, but it cannot be instantiated", cmdClass.getName())); + } + + APICommand at = cmdClass.getAnnotation(APICommand.class); + entityTypes = at.entityType(); + } if (entityTypes == null || entityTypes.length == 0) { _iamSrv.addIAMPermissionToIAMPolicy(policyId, null, permissionScope.toString(), new Long(IAMPolicyPermission.PERMISSION_SCOPE_ID_CURRENT_CALLER), apiName, (accessType == null) ? null : accessType.toString(), Permission.Allow, false); + if (addAccountScopedUseEntry) { + _iamSrv.addIAMPermissionToIAMPolicy(policyId, null, PermissionScope.ACCOUNT.toString(), new Long( + IAMPolicyPermission.PERMISSION_SCOPE_ID_CURRENT_CALLER), apiName, AccessType.UseEntry.toString(), Permission.Allow, false); + } } else { - for (IAMEntityType entityType : entityTypes) { - _iamSrv.addIAMPermissionToIAMPolicy(policyId, entityType.toString(), permissionScope.toString(), new Long(IAMPolicyPermission.PERMISSION_SCOPE_ID_CURRENT_CALLER), + for (Class entityType : entityTypes) { + _iamSrv.addIAMPermissionToIAMPolicy(policyId, entityType.getSimpleName(), permissionScope.toString(), new Long( + IAMPolicyPermission.PERMISSION_SCOPE_ID_CURRENT_CALLER), apiName, (accessType == null) ? null : accessType.toString(), Permission.Allow, false); + if (addAccountScopedUseEntry) { + _iamSrv.addIAMPermissionToIAMPolicy(policyId, entityType.getSimpleName(), PermissionScope.ACCOUNT.toString(), new Long( + IAMPolicyPermission.PERMISSION_SCOPE_ID_CURRENT_CALLER), apiName, AccessType.UseEntry.toString(), Permission.Allow, false); + } } } diff --git a/services/iam/plugin/src/org/apache/cloudstack/iam/RoleBasedEntityAccessChecker.java b/services/iam/plugin/src/org/apache/cloudstack/iam/RoleBasedEntityAccessChecker.java index 3fe854a2a0..bb471c037e 100644 --- a/services/iam/plugin/src/org/apache/cloudstack/iam/RoleBasedEntityAccessChecker.java +++ b/services/iam/plugin/src/org/apache/cloudstack/iam/RoleBasedEntityAccessChecker.java @@ -27,6 +27,7 @@ import org.apache.cloudstack.acl.ControlledEntity; import org.apache.cloudstack.acl.PermissionScope; import org.apache.cloudstack.acl.SecurityChecker; +import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.InternalIdentity; import org.apache.cloudstack.iam.api.IAMGroup; import org.apache.cloudstack.iam.api.IAMPolicy; @@ -59,6 +60,25 @@ public boolean checkAccess(Account caller, ControlledEntity entity, AccessType a return checkAccess(caller, entity, accessType, null); } + private String buildAccessCacheKey(Account caller, ControlledEntity entity, AccessType accessType, String action) { + StringBuffer key = new StringBuffer(); + key.append(caller.getAccountId()); + key.append("-"); + String entityType = null; + if (entity != null && entity.getEntityType() != null) { + entityType = entity.getEntityType().getSimpleName(); + if (entity instanceof InternalIdentity) { + entityType += ((InternalIdentity)entity).getId(); + } + } + key.append(entityType != null ? entityType : "null"); + key.append("-"); + key.append(accessType != null ? accessType.toString() : "null"); + key.append("-"); + key.append(action != null ? action : "null"); + return key.toString(); + } + @Override public boolean checkAccess(Account caller, ControlledEntity entity, AccessType accessType, String action) throws PermissionDeniedException { @@ -66,32 +86,60 @@ public boolean checkAccess(Account caller, ControlledEntity entity, AccessType a if (caller == null) { throw new InvalidParameterValueException("Caller cannot be passed as NULL to IAM!"); } + + if (entity == null && action == null) { + throw new InvalidParameterValueException("Entity and action cannot be both NULL in checkAccess!"); + } + + // check IAM cache first + String accessKey = buildAccessCacheKey(caller, entity, accessType, action); + CheckAccessResult allowDeny = (CheckAccessResult)_iamSrv.getFromIAMCache(accessKey); + if (allowDeny != null) { + s_logger.debug("IAM access check for " + accessKey + " from cache: " + allowDeny.isAllow()); + if (allowDeny.isAllow()) { + return true; + } else { + if (allowDeny.getDenyMsg() != null) { + throw new PermissionDeniedException(allowDeny.getDenyMsg()); + } else { + return false; + } + } + } + if (entity == null && action != null) { // check if caller can do this action List policies = _iamSrv.listIAMPolicies(caller.getAccountId()); boolean isAllowed = _iamSrv.isActionAllowedForPolicies(action, policies); if (!isAllowed) { - throw new PermissionDeniedException("The action '" + action + "' not allowed for account " + caller); + String msg = "The action '" + action + "' not allowed for account " + caller; + _iamSrv.addToIAMCache(accessKey, new CheckAccessResult(msg)); + throw new PermissionDeniedException(msg); } + _iamSrv.addToIAMCache(accessKey, new CheckAccessResult(true)); return true; } - if (entity == null) { - throw new InvalidParameterValueException("Entity and action cannot be both NULL in checkAccess!"); + + // if a Project entity, skip + Account entityAccount = _accountService.getAccount(entity.getAccountId()); + if (entityAccount != null && entityAccount.getType() == Account.ACCOUNT_TYPE_PROJECT) { + _iamSrv.addToIAMCache(accessKey, new CheckAccessResult(false)); + return false; } String entityType = null; if (entity.getEntityType() != null) { - entityType = entity.getEntityType().toString(); + entityType = entity.getEntityType().getSimpleName(); } if (accessType == null) { accessType = AccessType.UseEntry; } - // get all Policies of this caller w.r.t the entity - List policies = getEffectivePolicies(caller, entity); + // get all Policies of this caller by considering recursive domain group policy + List policies = getEffectivePolicies(caller); HashMap policyPermissionMap = new HashMap(); for (IAMPolicy policy : policies) { @@ -122,22 +170,69 @@ public boolean checkAccess(Account caller, ControlledEntity entity, AccessType a } } if (policyPermissionMap.containsKey(policy) && policyPermissionMap.get(policy)) { + _iamSrv.addToIAMCache(accessKey, new CheckAccessResult(true)); return true; } } if (!policies.isEmpty()) { // Since we reach this point, none of the // roles granted access + + String msg = "Account " + caller + " does not have permission to access resource " + entity + + " for access type: " + accessType; if (s_logger.isDebugEnabled()) { - s_logger.debug("Account " + caller + " does not have permission to access resource " + entity - + " for access type: " + accessType); + s_logger.debug(msg); } - throw new PermissionDeniedException(caller + " does not have permission to access resource " + entity); + _iamSrv.addToIAMCache(accessKey, new CheckAccessResult(msg)); + throw new PermissionDeniedException(msg); } + _iamSrv.addToIAMCache(accessKey, new CheckAccessResult(false)); return false; } + @Override + public boolean checkAccess(Account caller, AccessType accessType, String action, ControlledEntity... entities) + throws PermissionDeniedException { + + // operate access on multiple entities? + if (accessType != null && accessType == AccessType.OperateEntry) { + // In this case caller MUST own n-1 entities. + + for (ControlledEntity entity : entities) { + checkAccess(caller, entity, accessType, action); + + boolean otherEntitiesAccess = true; + + for (ControlledEntity otherEntity : entities) { + if (otherEntity.getAccountId() == caller.getAccountId() + || (checkAccess(caller, otherEntity, accessType, action) && otherEntity.getAccountId() == entity + .getAccountId())) { + continue; + } else { + otherEntitiesAccess = false; + break; + } + } + + if (otherEntitiesAccess) { + return true; + } + } + + throw new PermissionDeniedException(caller + + " does not have permission to perform this operation on these resources"); + + } else { + for (ControlledEntity entity : entities) { + if (!checkAccess(caller, entity, accessType, action)) { + return false; + } + } + return true; + } + } + private boolean checkPermissionScope(Account caller, String scope, Long scopeId, ControlledEntity entity) { if(scopeId != null && !scopeId.equals(new Long(IAMPolicyPermission.PERMISSION_SCOPE_ID_CURRENT_CALLER))){ @@ -172,17 +267,10 @@ private boolean checkPermissionScope(Account caller, String scope, Long scopeId, return false; } - private List getEffectivePolicies(Account caller, ControlledEntity entity) { + private List getEffectivePolicies(Account caller) { - // Get the static Policies of the Caller List policies = _iamSrv.listIAMPolicies(caller.getId()); - // add any dynamic policies w.r.t the entity - if (caller.getId() == entity.getAccountId()) { - // The caller owns the entity - policies.add(_iamSrv.getResourceOwnerPolicy()); - } - List groups = _iamSrv.listIAMGroups(caller.getId()); for (IAMGroup group : groups) { // for each group find the grand parent groups. @@ -194,4 +282,40 @@ private List getEffectivePolicies(Account caller, ControlledEntity en return policies; } + + private class CheckAccessResult { + boolean allow; + String denyMsg; + + public CheckAccessResult(boolean aw) { + this(aw, null); + } + + public CheckAccessResult(String msg) { + this(false, msg); + } + + public CheckAccessResult(boolean aw, String msg) { + allow = aw; + denyMsg = msg; + } + + public boolean isAllow() { + return allow; + } + + public void setAllow(boolean aw) { + allow = aw; + } + + + public String getDenyMsg() { + return denyMsg; + } + + public void setDenyMsg(String denyMsg) { + this.denyMsg = denyMsg; + } + + } } diff --git a/services/iam/plugin/src/org/apache/cloudstack/iam/RoleBasedEntityQuerySelector.java b/services/iam/plugin/src/org/apache/cloudstack/iam/RoleBasedEntityQuerySelector.java index 23c57a1688..5d31433803 100644 --- a/services/iam/plugin/src/org/apache/cloudstack/iam/RoleBasedEntityQuerySelector.java +++ b/services/iam/plugin/src/org/apache/cloudstack/iam/RoleBasedEntityQuerySelector.java @@ -25,11 +25,14 @@ import org.apache.cloudstack.acl.PermissionScope; import org.apache.cloudstack.acl.QuerySelector; +import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.iam.api.IAMGroup; import org.apache.cloudstack.iam.api.IAMPolicy; import org.apache.cloudstack.iam.api.IAMPolicyPermission; import org.apache.cloudstack.iam.api.IAMService; +import com.cloud.domain.DomainVO; +import com.cloud.domain.dao.DomainDao; import com.cloud.user.Account; import com.cloud.utils.component.AdapterBase; @@ -39,24 +42,44 @@ public class RoleBasedEntityQuerySelector extends AdapterBase implements QuerySe @Inject IAMService _iamService; + @Inject + DomainDao _domainDao; @Override - public List getAuthorizedDomains(Account caller, String action) { + public List getAuthorizedDomains(Account caller, String action, AccessType accessType) { long accountId = caller.getAccountId(); + if (accessType == null) { + accessType = AccessType.UseEntry; // default always show resources authorized to use + } // Get the static Policies of the Caller List policies = _iamService.listIAMPolicies(accountId); // for each policy, find granted permission with Domain scope List domainIds = new ArrayList(); for (IAMPolicy policy : policies) { - List pp = _iamService.listPolicyPermissionsByScope(policy.getId(), action, PermissionScope.DOMAIN.toString()); + List pp = new ArrayList(); + pp.addAll(_iamService.listPolicyPermissionsByScope(policy.getId(), action, + PermissionScope.DOMAIN.toString(), accessType.toString())); + if (pp != null) { for (IAMPolicyPermission p : pp) { if (p.getScopeId() != null) { + Long domainId = null; if (p.getScopeId().longValue() == -1) { - domainIds.add(caller.getDomainId()); + domainId = caller.getDomainId(); + //domainIds.add(caller.getDomainId()); } else { - domainIds.add(p.getScopeId()); + domainId = p.getScopeId(); + //domainIds.add(p.getScopeId()); } + //domainIds.add(domainId); + // add all the domain children from this domain (including this domain itself). Like RoleBasedEntityAccessChecker, we made an assumption, if DOMAIN scope is granted, it means that + // the whole domain tree is granted access. + DomainVO domain = _domainDao.findById(domainId); + List childDomains = _domainDao.getDomainChildrenIds(domain.getPath()); + if (childDomains != null && childDomains.size() > 0) { + domainIds.addAll(childDomains); + } + } } } @@ -65,14 +88,20 @@ public List getAuthorizedDomains(Account caller, String action) { } @Override - public List getAuthorizedAccounts(Account caller, String action) { + public List getAuthorizedAccounts(Account caller, String action, AccessType accessType) { long accountId = caller.getAccountId(); + if (accessType == null) { + accessType = AccessType.UseEntry; // default always show resources authorized to use + } // Get the static Policies of the Caller List policies = _iamService.listIAMPolicies(accountId); // for each policy, find granted permission with Account scope List accountIds = new ArrayList(); for (IAMPolicy policy : policies) { - List pp = _iamService.listPolicyPermissionsByScope(policy.getId(), action, PermissionScope.ACCOUNT.toString()); + List pp = new ArrayList(); + pp.addAll(_iamService.listPolicyPermissionsByScope(policy.getId(), action, + PermissionScope.ACCOUNT.toString(), accessType.toString())); + if (pp != null) { for (IAMPolicyPermission p : pp) { if (p.getScopeId() != null) { @@ -89,8 +118,11 @@ public List getAuthorizedAccounts(Account caller, String action) { } @Override - public List getAuthorizedResources(Account caller, String action) { + public List getAuthorizedResources(Account caller, String action, AccessType accessType) { long accountId = caller.getAccountId(); + if (accessType == null) { + accessType = AccessType.UseEntry; // default always show resources authorized to use + } // Get the static Policies of the Caller List policies = _iamService.listIAMPolicies(accountId); @@ -107,7 +139,10 @@ public List getAuthorizedResources(Account caller, String action) { // for each policy, find granted permission with Resource scope List entityIds = new ArrayList(); for (IAMPolicy policy : policies) { - List pp = _iamService.listPolicyPermissionsByScope(policy.getId(), action, PermissionScope.RESOURCE.toString()); + List pp = new ArrayList(); + pp.addAll(_iamService.listPolicyPermissionsByScope(policy.getId(), action, + PermissionScope.RESOURCE.toString(), accessType.toString())); + if (pp != null) { for (IAMPolicyPermission p : pp) { if (p.getScopeId() != null) { @@ -120,13 +155,18 @@ public List getAuthorizedResources(Account caller, String action) { } @Override - public boolean isGrantedAll(Account caller, String action) { + public boolean isGrantedAll(Account caller, String action, AccessType accessType) { long accountId = caller.getAccountId(); + if (accessType == null) { + accessType = AccessType.UseEntry; // default always show resources authorized to use + } // Get the static Policies of the Caller List policies = _iamService.listIAMPolicies(accountId); // for each policy, find granted permission with ALL scope for (IAMPolicy policy : policies) { - List pp = _iamService.listPolicyPermissionsByScope(policy.getId(), action, PermissionScope.ALL.toString()); + List pp = new ArrayList(); + pp.addAll(_iamService.listPolicyPermissionsByScope(policy.getId(), action, PermissionScope.ALL.toString(), + accessType.toString())); if (pp != null && pp.size() > 0) { return true; } diff --git a/services/iam/plugin/test/org/apache/cloudstack/iam/test/IAMApiServiceTest.java b/services/iam/plugin/test/org/apache/cloudstack/iam/test/IAMApiServiceTest.java index b825ab224f..84e1e56255 100644 --- a/services/iam/plugin/test/org/apache/cloudstack/iam/test/IAMApiServiceTest.java +++ b/services/iam/plugin/test/org/apache/cloudstack/iam/test/IAMApiServiceTest.java @@ -50,7 +50,6 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.support.AnnotationConfigContextLoader; -import org.apache.cloudstack.acl.IAMEntityType; import org.apache.cloudstack.acl.PermissionScope; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.command.user.vm.ListVMsCmd; @@ -84,6 +83,7 @@ import com.cloud.utils.Pair; import com.cloud.utils.component.ComponentContext; import com.cloud.utils.db.EntityManager; +import com.cloud.vm.VirtualMachine; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(loader = AnnotationConfigContextLoader.class) @@ -292,15 +292,15 @@ public void addRemovePermissionToPolicyTest() { Class clz = ListVMsCmd.class; when(_apiServer.getCmdClass("listVirtualMachines")).thenReturn(clz); when( - _iamSrv.addIAMPermissionToIAMPolicy(policyId, IAMEntityType.VirtualMachine.toString(), + _iamSrv.addIAMPermissionToIAMPolicy(policyId, VirtualMachine.class.getSimpleName(), PermissionScope.RESOURCE.toString(), resId, "listVirtualMachines", AccessType.UseEntry.toString(), Permission.Allow, false)).thenReturn(policy); - _aclSrv.addIAMPermissionToIAMPolicy(policyId, IAMEntityType.VirtualMachine.toString(), - PermissionScope.RESOURCE, resId, "listVirtualMachines", Permission.Allow, false); + _aclSrv.addIAMPermissionToIAMPolicy(policyId, VirtualMachine.class.getSimpleName(), + PermissionScope.RESOURCE, resId, "listVirtualMachines", Permission.Allow, false, false); Pair, Integer> policyList = new Pair, Integer>(policies, 1); List policyPerms = new ArrayList(); IAMPolicyPermission perm = new IAMPolicyPermissionVO(policyId, "listVirtualMachines", - IAMEntityType.VirtualMachine.toString(), AccessType.UseEntry.toString(), + VirtualMachine.class.getSimpleName(), AccessType.UseEntry.toString(), PermissionScope.RESOURCE.toString(), resId, Permission.Allow, false); policyPerms.add(perm); @@ -316,7 +316,7 @@ public void addRemovePermissionToPolicyTest() { //remove permission from policy policyPerms.remove(perm); - _aclSrv.removeIAMPermissionFromIAMPolicy(policyId, IAMEntityType.VirtualMachine.toString(), + _aclSrv.removeIAMPermissionFromIAMPolicy(policyId, VirtualMachine.class.getSimpleName(), PermissionScope.RESOURCE, resId, "listVirtualMachines"); policyResp = _aclSrv.listIAMPolicies(null, "policy1", callerDomainId, 0L, 20L); assertTrue("No. of response items should be one", policyResp.getCount() == 1); diff --git a/services/iam/server/pom.xml b/services/iam/server/pom.xml index bed8811d16..77b2522843 100644 --- a/services/iam/server/pom.xml +++ b/services/iam/server/pom.xml @@ -31,6 +31,10 @@ commons-io commons-io + + net.sf.ehcache + ehcache-core + org.apache.cloudstack cloud-utils diff --git a/services/iam/server/resources/META-INF/cloudstack/core/spring-iam-server-context.xml b/services/iam/server/resources/META-INF/cloudstack/core/spring-iam-server-context.xml index c9f383f4f5..4994a3400b 100644 --- a/services/iam/server/resources/META-INF/cloudstack/core/spring-iam-server-context.xml +++ b/services/iam/server/resources/META-INF/cloudstack/core/spring-iam-server-context.xml @@ -35,6 +35,13 @@ - + + + + + + + + diff --git a/services/iam/server/src/org/apache/cloudstack/iam/api/IAMService.java b/services/iam/server/src/org/apache/cloudstack/iam/api/IAMService.java index 74a0885150..29e7c972b7 100644 --- a/services/iam/server/src/org/apache/cloudstack/iam/api/IAMService.java +++ b/services/iam/server/src/org/apache/cloudstack/iam/api/IAMService.java @@ -1,92 +1,99 @@ -// 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.iam.api; - -import java.util.List; - -import org.apache.cloudstack.iam.api.IAMPolicyPermission.Permission; - -import com.cloud.utils.Pair; - -public interface IAMService { - - /* IAM group related interfaces */ - IAMGroup createIAMGroup(String iamGroupName, String description, String path); - - boolean deleteIAMGroup(Long iamGroupId); - - List listIAMGroups(long accountId); - - IAMGroup addAccountsToGroup(List acctIds, Long groupId); - - IAMGroup removeAccountsFromGroup(List acctIds, Long groupId); - - List listAccountsByGroup(long groupId); - - Pair, Integer> listIAMGroups(Long iamGroupId, String iamGroupName, String path, Long startIndex, Long pageSize); - - /* IAM Policy related interfaces */ - IAMPolicy createIAMPolicy(String iamPolicyName, String description, Long parentPolicyId, String path); - - boolean deleteIAMPolicy(long iamPolicyId); - - List listIAMPolicies(long accountId); - - List listIAMPoliciesByGroup(long groupId); - - Pair, Integer> listIAMPolicies(Long iamPolicyId, String iamPolicyName, String path, Long startIndex, Long pageSize); - - IAMGroup attachIAMPoliciesToGroup(List policyIds, Long groupId); - - IAMGroup removeIAMPoliciesFromGroup(List policyIds, Long groupId); - - void attachIAMPolicyToAccounts(Long policyId, List acctIds); - - void removeIAMPolicyFromAccounts(Long policyId, List acctIds); - - IAMPolicy addIAMPermissionToIAMPolicy(long iamPolicyId, String entityType, String scope, Long scopeId, - String action, String accessType, Permission perm, Boolean recursive); - - IAMPolicy removeIAMPermissionFromIAMPolicy(long iamPolicyId, String entityType, String scope, Long scopeId, - String action); - - void removeIAMPermissionForEntity(final String entityType, final Long entityId); - - IAMPolicy getResourceGrantPolicy(String entityType, Long entityId, String accessType, String action); - - IAMPolicy getResourceOwnerPolicy(); - - List listPolicyPermissions(long policyId); - - List listPolicyPermissionsByScope(long policyId, String action, String scope); - - List listPolicyPermissionByActionAndEntity(long policyId, String action, String entityType); - - boolean isActionAllowedForPolicies(String action, List policies); - - List getGrantedEntities(long accountId, String action, String scope); - - IAMPolicy resetIAMPolicy(long iamPolicyId); - - List listPolicyPermissionByAccessAndEntity(long policyId, String accessType, - String entityType); - - List listParentIAMGroups(long groupId); - - List listRecursiveIAMPoliciesByGroup(long groupId); - -} +// 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.iam.api; + +import java.util.List; + +import org.apache.cloudstack.iam.api.IAMPolicyPermission.Permission; + +import com.cloud.utils.Pair; + +public interface IAMService { + + /* IAM group related interfaces */ + IAMGroup createIAMGroup(String iamGroupName, String description, String path); + + boolean deleteIAMGroup(Long iamGroupId); + + List listIAMGroups(long accountId); + + IAMGroup addAccountsToGroup(List acctIds, Long groupId); + + IAMGroup removeAccountsFromGroup(List acctIds, Long groupId); + + List listAccountsByGroup(long groupId); + + Pair, Integer> listIAMGroups(Long iamGroupId, String iamGroupName, String path, Long startIndex, Long pageSize); + + /* IAM Policy related interfaces */ + IAMPolicy createIAMPolicy(String iamPolicyName, String description, Long parentPolicyId, String path); + + boolean deleteIAMPolicy(long iamPolicyId); + + List listIAMPolicies(long accountId); + + List listIAMPoliciesByGroup(long groupId); + + Pair, Integer> listIAMPolicies(Long iamPolicyId, String iamPolicyName, String path, Long startIndex, Long pageSize); + + IAMGroup attachIAMPoliciesToGroup(List policyIds, Long groupId); + + IAMGroup removeIAMPoliciesFromGroup(List policyIds, Long groupId); + + void attachIAMPolicyToAccounts(Long policyId, List acctIds); + + void removeIAMPolicyFromAccounts(Long policyId, List acctIds); + + IAMPolicy addIAMPermissionToIAMPolicy(long iamPolicyId, String entityType, String scope, Long scopeId, + String action, String accessType, Permission perm, Boolean recursive); + + IAMPolicy removeIAMPermissionFromIAMPolicy(long iamPolicyId, String entityType, String scope, Long scopeId, + String action); + + void removeIAMPermissionForEntity(final String entityType, final Long entityId); + + IAMPolicy getResourceGrantPolicy(String entityType, Long entityId, String accessType, String action); + + IAMPolicy getResourceOwnerPolicy(); + + List listPolicyPermissions(long policyId); + + List listPolicyPermissionsByScope(long policyId, String action, String scope, String accessType); + + List listPolicyPermissionByActionAndEntity(long policyId, String action, String entityType); + + boolean isActionAllowedForPolicies(String action, List policies); + + List getGrantedEntities(long accountId, String action, String scope); + + IAMPolicy resetIAMPolicy(long iamPolicyId); + + List listPolicyPermissionByAccessAndEntity(long policyId, String accessType, + String entityType); + + List listParentIAMGroups(long groupId); + + List listRecursiveIAMPoliciesByGroup(long groupId); + + /* Interface used for cache IAM checkAccess result */ + void addToIAMCache(Object accessKey, Object allowDeny); + + Object getFromIAMCache(Object accessKey); + + void invalidateIAMCache(); + +} diff --git a/services/iam/server/src/org/apache/cloudstack/iam/server/IAMServiceImpl.java b/services/iam/server/src/org/apache/cloudstack/iam/server/IAMServiceImpl.java index 097d84f958..fa37cf621e 100644 --- a/services/iam/server/src/org/apache/cloudstack/iam/server/IAMServiceImpl.java +++ b/services/iam/server/src/org/apache/cloudstack/iam/server/IAMServiceImpl.java @@ -1,815 +1,906 @@ -// 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.iam.server; - -import java.util.ArrayList; -import java.util.List; - -import javax.ejb.Local; -import javax.inject.Inject; - -import org.apache.log4j.Logger; - -import org.apache.cloudstack.acl.PermissionScope; -import org.apache.cloudstack.iam.api.IAMGroup; -import org.apache.cloudstack.iam.api.IAMPolicy; -import org.apache.cloudstack.iam.api.IAMPolicyPermission; -import org.apache.cloudstack.iam.api.IAMPolicyPermission.Permission; -import org.apache.cloudstack.iam.api.IAMService; -import org.apache.cloudstack.iam.server.dao.IAMAccountPolicyMapDao; -import org.apache.cloudstack.iam.server.dao.IAMGroupAccountMapDao; -import org.apache.cloudstack.iam.server.dao.IAMGroupDao; -import org.apache.cloudstack.iam.server.dao.IAMGroupPolicyMapDao; -import org.apache.cloudstack.iam.server.dao.IAMPolicyDao; -import org.apache.cloudstack.iam.server.dao.IAMPolicyPermissionDao; - -import com.cloud.exception.InvalidParameterValueException; -import com.cloud.utils.Pair; -import com.cloud.utils.component.Manager; -import com.cloud.utils.component.ManagerBase; -import com.cloud.utils.db.DB; -import com.cloud.utils.db.EntityManager; -import com.cloud.utils.db.Filter; -import com.cloud.utils.db.GenericSearchBuilder; -import com.cloud.utils.db.JoinBuilder; -import com.cloud.utils.db.JoinBuilder.JoinType; -import com.cloud.utils.db.SearchBuilder; -import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.SearchCriteria.Op; -import com.cloud.utils.db.Transaction; -import com.cloud.utils.db.TransactionCallback; -import com.cloud.utils.db.TransactionCallbackNoReturn; -import com.cloud.utils.db.TransactionStatus; - -@Local(value = {IAMService.class}) -public class IAMServiceImpl extends ManagerBase implements IAMService, Manager { - - public static final Logger s_logger = Logger.getLogger(IAMServiceImpl.class); - private String _name; - - @Inject - IAMPolicyDao _aclPolicyDao; - - @Inject - IAMGroupDao _aclGroupDao; - - @Inject - EntityManager _entityMgr; - - @Inject - IAMGroupPolicyMapDao _aclGroupPolicyMapDao; - - @Inject - IAMAccountPolicyMapDao _aclAccountPolicyMapDao; - - @Inject - IAMGroupAccountMapDao _aclGroupAccountMapDao; - - @Inject - IAMPolicyPermissionDao _policyPermissionDao; - - @DB - @Override - public IAMGroup createIAMGroup(String iamGroupName, String description, String path) { - // check if the group is already existing - IAMGroup grp = _aclGroupDao.findByName(path, iamGroupName); - if (grp != null) { - throw new InvalidParameterValueException( - "Unable to create acl group with name " + iamGroupName - + " already exisits for path " + path); - } - IAMGroupVO rvo = new IAMGroupVO(iamGroupName, description); - rvo.setPath(path); - - return _aclGroupDao.persist(rvo); - } - - @DB - @Override - public boolean deleteIAMGroup(final Long iamGroupId) { - // get the Acl Group entity - final IAMGroup grp = _aclGroupDao.findById(iamGroupId); - if (grp == null) { - throw new InvalidParameterValueException("Unable to find acl group: " + iamGroupId - + "; failed to delete acl group."); - } - - Transaction.execute(new TransactionCallbackNoReturn() { - @Override - public void doInTransactionWithoutResult(TransactionStatus status) { - // remove this group related entry in acl_group_role_map - List groupPolicyMap = _aclGroupPolicyMapDao.listByGroupId(grp.getId()); - if (groupPolicyMap != null) { - for (IAMGroupPolicyMapVO gr : groupPolicyMap) { - _aclGroupPolicyMapDao.remove(gr.getId()); - } - } - - // remove this group related entry in acl_group_account table - List groupAcctMap = _aclGroupAccountMapDao.listByGroupId(grp.getId()); - if (groupAcctMap != null) { - for (IAMGroupAccountMapVO grpAcct : groupAcctMap) { - _aclGroupAccountMapDao.remove(grpAcct.getId()); - } - } - - // remove this group from acl_group table - _aclGroupDao.remove(iamGroupId); - } - }); - - return true; - } - - @SuppressWarnings("unchecked") - @Override - public List listIAMGroups(long accountId) { - - GenericSearchBuilder groupSB = _aclGroupAccountMapDao.createSearchBuilder(Long.class); - groupSB.selectFields(groupSB.entity().getAclGroupId()); - groupSB.and("account", groupSB.entity().getAccountId(), Op.EQ); - SearchCriteria groupSc = groupSB.create(); - groupSc.setParameters("account", accountId); - - List groupIds = _aclGroupAccountMapDao.customSearch(groupSc, null); - - SearchBuilder sb = _aclGroupDao.createSearchBuilder(); - sb.and("ids", sb.entity().getId(), Op.IN); - SearchCriteria sc = sb.create(); - sc.setParameters("ids", groupIds.toArray(new Object[groupIds.size()])); - @SuppressWarnings("rawtypes") - List groups = _aclGroupDao.search(sc, null); - return groups; - } - - @DB - @Override - public IAMGroup addAccountsToGroup(final List acctIds, final Long groupId) { - // get the Acl Group entity - IAMGroup group = _aclGroupDao.findById(groupId); - if (group == null) { - throw new InvalidParameterValueException("Unable to find acl group: " + groupId - + "; failed to add accounts to acl group."); - } - - Transaction.execute(new TransactionCallbackNoReturn() { - @Override - public void doInTransactionWithoutResult(TransactionStatus status) { - // add entries in acl_group_account_map table - for (Long acctId : acctIds) { - // check account permissions - IAMGroupAccountMapVO grMap = _aclGroupAccountMapDao.findByGroupAndAccount(groupId, acctId); - if (grMap == null) { - // not there already - grMap = new IAMGroupAccountMapVO(groupId, acctId); - _aclGroupAccountMapDao.persist(grMap); - } - } - } - }); - return group; - } - - @DB - @Override - public IAMGroup removeAccountsFromGroup(final List acctIds, final Long groupId) { - // get the Acl Group entity - IAMGroup group = _aclGroupDao.findById(groupId); - if (group == null) { - throw new InvalidParameterValueException("Unable to find acl group: " + groupId - + "; failed to remove accounts from acl group."); - } - - Transaction.execute(new TransactionCallbackNoReturn() { - @Override - public void doInTransactionWithoutResult(TransactionStatus status) { - // remove entries from acl_group_account_map table - for (Long acctId : acctIds) { - IAMGroupAccountMapVO grMap = _aclGroupAccountMapDao.findByGroupAndAccount(groupId, acctId); - if (grMap != null) { - // not removed yet - _aclGroupAccountMapDao.remove(grMap.getId()); - } - } - } - }); - return group; - } - - @Override - public List listAccountsByGroup(long groupId) { - List grpAcctMap = _aclGroupAccountMapDao.listByGroupId(groupId); - if (grpAcctMap == null || grpAcctMap.size() == 0) { - return new ArrayList(); - } - - List accts = new ArrayList(); - for (IAMGroupAccountMapVO grpAcct : grpAcctMap) { - accts.add(grpAcct.getAccountId()); - } - return accts; - } - - @Override - public Pair, Integer> listIAMGroups(Long iamGroupId, String iamGroupName, String path, Long startIndex, Long pageSize) { - if (iamGroupId != null) { - IAMGroup group = _aclGroupDao.findById(iamGroupId); - if (group == null) { - throw new InvalidParameterValueException("Unable to find acl group by id " + iamGroupId); - } - } - - Filter searchFilter = new Filter(IAMGroupVO.class, "id", true, startIndex, pageSize); - - SearchBuilder sb = _aclGroupDao.createSearchBuilder(); - sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ); - sb.and("path", sb.entity().getPath(), SearchCriteria.Op.LIKE); - sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); - - SearchCriteria sc = sb.create(); - - if (iamGroupName != null) { - sc.setParameters("name", iamGroupName); - } - - if (iamGroupId != null) { - sc.setParameters("id", iamGroupId); - } - - sc.setParameters("path", path + "%"); - - Pair, Integer> groups = _aclGroupDao.searchAndCount(sc, searchFilter); - return new Pair, Integer>(new ArrayList(groups.first()), groups.second()); - } - - @Override - public List listParentIAMGroups(long groupId) { - IAMGroup group = _aclGroupDao.findById(groupId); - if (group == null) { - throw new InvalidParameterValueException("Unable to find acl group by id " + groupId); - } - - String path = group.getPath(); - List pathList = new ArrayList(); - - String[] parts = path.split("/"); - - for (String part : parts) { - int start = path.indexOf(part); - if (start > 0) { - String subPath = path.substring(0, start); - pathList.add(subPath); - } - } - - if (pathList.isEmpty()) { - return new ArrayList(); - } - - SearchBuilder sb = _aclGroupDao.createSearchBuilder(); - sb.and("paths", sb.entity().getPath(), SearchCriteria.Op.IN); - - SearchCriteria sc = sb.create(); - sc.setParameters("paths", pathList.toArray()); - - List groups = _aclGroupDao.search(sc, null); - - return new ArrayList(groups); - - } - - @DB - @Override - public IAMPolicy createIAMPolicy(final String iamPolicyName, final String description, final Long parentPolicyId, final String path) { - - // check if the policy is already existing - IAMPolicy ro = _aclPolicyDao.findByName(iamPolicyName); - if (ro != null) { - throw new InvalidParameterValueException( - "Unable to create acl policy with name " + iamPolicyName - + " already exisits"); - } - - IAMPolicy role = Transaction.execute(new TransactionCallback() { - @Override - public IAMPolicy doInTransaction(TransactionStatus status) { - IAMPolicyVO rvo = new IAMPolicyVO(iamPolicyName, description); - rvo.setPath(path); - - IAMPolicy role = _aclPolicyDao.persist(rvo); - if (parentPolicyId != null) { - // copy parent role permissions - List perms = _policyPermissionDao.listByPolicy(parentPolicyId); - if (perms != null) { - for (IAMPolicyPermissionVO perm : perms) { - perm.setAclPolicyId(role.getId()); - _policyPermissionDao.persist(perm); - } - } - } - return role; - } - }); - - - return role; - } - - @DB - @Override - public boolean deleteIAMPolicy(final long iamPolicyId) { - // get the Acl Policy entity - final IAMPolicy policy = _aclPolicyDao.findById(iamPolicyId); - if (policy == null) { - throw new InvalidParameterValueException("Unable to find acl policy: " + iamPolicyId - + "; failed to delete acl policy."); - } - - Transaction.execute(new TransactionCallbackNoReturn() { - @Override - public void doInTransactionWithoutResult(TransactionStatus status) { - // remove this role related entry in acl_group_role_map - List groupPolicyMap = _aclGroupPolicyMapDao.listByPolicyId(policy.getId()); - if (groupPolicyMap != null) { - for (IAMGroupPolicyMapVO gr : groupPolicyMap) { - _aclGroupPolicyMapDao.remove(gr.getId()); - } - } - - // remove this policy related entry in acl_account_policy_map table - List policyAcctMap = _aclAccountPolicyMapDao.listByPolicyId(policy.getId()); - if (policyAcctMap != null) { - for (IAMAccountPolicyMapVO policyAcct : policyAcctMap) { - _aclAccountPolicyMapDao.remove(policyAcct.getId()); - } - } - - // remove this policy related entry in acl_policy_permission table - List policyPermMap = _policyPermissionDao.listByPolicy(policy.getId()); - if (policyPermMap != null) { - for (IAMPolicyPermissionVO policyPerm : policyPermMap) { - _policyPermissionDao.remove(policyPerm.getId()); - } - } - - // remove this role from acl_role table - _aclPolicyDao.remove(iamPolicyId); - } - }); - - return true; - } - - - @SuppressWarnings("unchecked") - @Override - public List listIAMPolicies(long accountId) { - - // static policies of the account - SearchBuilder groupSB = _aclGroupAccountMapDao.createSearchBuilder(); - groupSB.and("account", groupSB.entity().getAccountId(), Op.EQ); - - GenericSearchBuilder policySB = _aclGroupPolicyMapDao.createSearchBuilder(Long.class); - policySB.selectFields(policySB.entity().getAclPolicyId()); - policySB.join("accountgroupjoin", groupSB, groupSB.entity().getAclGroupId(), policySB.entity().getAclGroupId(), - JoinType.INNER); - policySB.done(); - SearchCriteria policySc = policySB.create(); - policySc.setJoinParameters("accountgroupjoin", "account", accountId); - - List policyIds = _aclGroupPolicyMapDao.customSearch(policySc, null); - // add policies directly attached to the account - List acctPolicies = _aclAccountPolicyMapDao.listByAccountId(accountId); - for (IAMAccountPolicyMapVO p : acctPolicies) { - policyIds.add(p.getIamPolicyId()); - } - if (policyIds.size() == 0) { - return new ArrayList(); - } - SearchBuilder sb = _aclPolicyDao.createSearchBuilder(); - sb.and("ids", sb.entity().getId(), Op.IN); - SearchCriteria sc = sb.create(); - sc.setParameters("ids", policyIds.toArray(new Object[policyIds.size()])); - @SuppressWarnings("rawtypes") - List policies = _aclPolicyDao.customSearch(sc, null); - - return policies; - - } - - @SuppressWarnings("unchecked") - @Override - public List listIAMPoliciesByGroup(long groupId) { - List policyGrpMap = _aclGroupPolicyMapDao.listByGroupId(groupId); - if (policyGrpMap == null || policyGrpMap.size() == 0) { - return new ArrayList(); - } - - List policyIds = new ArrayList(); - for (IAMGroupPolicyMapVO pg : policyGrpMap) { - policyIds.add(pg.getAclPolicyId()); - } - - SearchBuilder sb = _aclPolicyDao.createSearchBuilder(); - sb.and("ids", sb.entity().getId(), Op.IN); - SearchCriteria sc = sb.create(); - sc.setParameters("ids", policyIds.toArray(new Object[policyIds.size()])); - @SuppressWarnings("rawtypes") - List policies = _aclPolicyDao.customSearch(sc, null); - - return policies; - } - - @SuppressWarnings("unchecked") - @Override - public List listRecursiveIAMPoliciesByGroup(long groupId) { - List policyGrpMap = _aclGroupPolicyMapDao.listByGroupId(groupId); - if (policyGrpMap == null || policyGrpMap.size() == 0) { - return new ArrayList(); - } - - List policyIds = new ArrayList(); - for (IAMGroupPolicyMapVO pg : policyGrpMap) { - policyIds.add(pg.getAclPolicyId()); - } - - SearchBuilder permSb = _policyPermissionDao.createSearchBuilder(); - permSb.and("isRecursive", permSb.entity().isRecursive(), Op.EQ); - - SearchBuilder sb = _aclPolicyDao.createSearchBuilder(); - sb.and("ids", sb.entity().getId(), Op.IN); - sb.join("recursivePerm", permSb, sb.entity().getId(), permSb.entity().getAclPolicyId(), - JoinBuilder.JoinType.INNER); - - SearchCriteria sc = sb.create(); - sc.setParameters("ids", policyIds.toArray(new Object[policyIds.size()])); - sc.setJoinParameters("recursivePerm", "isRecursive", true); - - @SuppressWarnings("rawtypes") - List policies = _aclPolicyDao.customSearch(sc, null); - - return policies; - } - - - @SuppressWarnings("unchecked") - @Override - public Pair, Integer> listIAMPolicies(Long iamPolicyId, String iamPolicyName, String path, Long startIndex, Long pageSize) { - - if (iamPolicyId != null) { - IAMPolicy policy = _aclPolicyDao.findById(iamPolicyId); - if (policy == null) { - throw new InvalidParameterValueException("Unable to find acl policy by id " + iamPolicyId); - } - } - - Filter searchFilter = new Filter(IAMPolicyVO.class, "id", true, startIndex, pageSize); - - SearchBuilder sb = _aclPolicyDao.createSearchBuilder(); - sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ); - sb.and("path", sb.entity().getPath(), SearchCriteria.Op.LIKE); - sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); - - SearchCriteria sc = sb.create(); - - if (iamPolicyName != null) { - sc.setParameters("name", iamPolicyName); - } - - if (iamPolicyId != null) { - sc.setParameters("id", iamPolicyId); - } - - sc.setParameters("path", path + "%"); - - Pair, Integer> policies = _aclPolicyDao.searchAndCount(sc, searchFilter); - @SuppressWarnings("rawtypes") - List policyList = policies.first(); - return new Pair, Integer>(policyList, policies.second()); - } - - @DB - @Override - public IAMGroup attachIAMPoliciesToGroup(final List policyIds, final Long groupId) { - // get the Acl Group entity - IAMGroup group = _aclGroupDao.findById(groupId); - if (group == null) { - throw new InvalidParameterValueException("Unable to find acl group: " + groupId - + "; failed to add roles to acl group."); - } - - Transaction.execute(new TransactionCallbackNoReturn() { - @Override - public void doInTransactionWithoutResult(TransactionStatus status) { - // add entries in acl_group_policy_map table - for (Long policyId : policyIds) { - IAMPolicy policy = _aclPolicyDao.findById(policyId); - if (policy == null) { - throw new InvalidParameterValueException("Unable to find acl policy: " + policyId - + "; failed to add policies to acl group."); - } - - IAMGroupPolicyMapVO grMap = _aclGroupPolicyMapDao.findByGroupAndPolicy(groupId, policyId); - if (grMap == null) { - // not there already - grMap = new IAMGroupPolicyMapVO(groupId, policyId); - _aclGroupPolicyMapDao.persist(grMap); - } - } - } - }); - - return group; - } - - @DB - @Override - public IAMGroup removeIAMPoliciesFromGroup(final List policyIds, final Long groupId) { - // get the Acl Group entity - IAMGroup group = _aclGroupDao.findById(groupId); - if (group == null) { - throw new InvalidParameterValueException("Unable to find acl group: " + groupId - + "; failed to remove roles from acl group."); - } - - Transaction.execute(new TransactionCallbackNoReturn() { - @Override - public void doInTransactionWithoutResult(TransactionStatus status) { - // add entries in acl_group_role_map table - for (Long policyId : policyIds) { - IAMPolicy policy = _aclPolicyDao.findById(policyId); - if (policy == null) { - throw new InvalidParameterValueException("Unable to find acl policy: " + policyId - + "; failed to add policies to acl group."); - } - - IAMGroupPolicyMapVO grMap = _aclGroupPolicyMapDao.findByGroupAndPolicy(groupId, policyId); - if (grMap != null) { - // not removed yet - _aclGroupPolicyMapDao.remove(grMap.getId()); - } - } - } - }); - return group; - } - - - @Override - public void attachIAMPolicyToAccounts(final Long policyId, final List acctIds) { - IAMPolicy policy = _aclPolicyDao.findById(policyId); - if (policy == null) { - throw new InvalidParameterValueException("Unable to find acl policy: " + policyId - + "; failed to add policy to account."); - } - - Transaction.execute(new TransactionCallbackNoReturn() { - @Override - public void doInTransactionWithoutResult(TransactionStatus status) { - // add entries in acl_group_policy_map table - for (Long acctId : acctIds) { - IAMAccountPolicyMapVO acctMap = _aclAccountPolicyMapDao.findByAccountAndPolicy(acctId, policyId); - if (acctMap == null) { - // not there already - acctMap = new IAMAccountPolicyMapVO(acctId, policyId); - _aclAccountPolicyMapDao.persist(acctMap); - } - } - } - }); - } - - @Override - public void removeIAMPolicyFromAccounts(final Long policyId, final List acctIds) { - IAMPolicy policy = _aclPolicyDao.findById(policyId); - if (policy == null) { - throw new InvalidParameterValueException("Unable to find acl policy: " + policyId - + "; failed to add policy to account."); - } - - Transaction.execute(new TransactionCallbackNoReturn() { - @Override - public void doInTransactionWithoutResult(TransactionStatus status) { - // add entries in acl_group_policy_map table - for (Long acctId : acctIds) { - IAMAccountPolicyMapVO acctMap = _aclAccountPolicyMapDao.findByAccountAndPolicy(acctId, policyId); - if (acctMap != null) { - // exists - _aclAccountPolicyMapDao.remove(acctMap.getId()); - } - } - } - }); - } - - @DB - @Override - public IAMPolicy addIAMPermissionToIAMPolicy(long iamPolicyId, String entityType, String scope, Long scopeId, - String action, String accessType, Permission perm, Boolean recursive) { - // get the Acl Policy entity - IAMPolicy policy = _aclPolicyDao.findById(iamPolicyId); - if (policy == null) { - throw new InvalidParameterValueException("Unable to find acl policy: " + iamPolicyId - + "; failed to add permission to policy."); - } - - // add entry in acl_policy_permission table - IAMPolicyPermissionVO permit = _policyPermissionDao.findByPolicyAndEntity(iamPolicyId, entityType, scope, scopeId, action, perm); - if (permit == null) { - // not there already - permit = new IAMPolicyPermissionVO(iamPolicyId, action, entityType, accessType, scope, scopeId, perm, - recursive); - _policyPermissionDao.persist(permit); - } - return policy; - - } - - @DB - @Override - public IAMPolicy removeIAMPermissionFromIAMPolicy(long iamPolicyId, String entityType, String scope, Long scopeId, - String action) { - // get the Acl Policy entity - IAMPolicy policy = _aclPolicyDao.findById(iamPolicyId); - if (policy == null) { - throw new InvalidParameterValueException("Unable to find acl policy: " + iamPolicyId - + "; failed to revoke permission from policy."); - } - // remove entry from acl_entity_permission table - IAMPolicyPermissionVO permit = _policyPermissionDao.findByPolicyAndEntity(iamPolicyId, entityType, scope, scopeId, action, Permission.Allow); - if (permit != null) { - // not removed yet - _policyPermissionDao.remove(permit.getId()); - } - return policy; - } - - @DB - @Override - public void removeIAMPermissionForEntity(final String entityType, final Long entityId) { - Transaction.execute(new TransactionCallbackNoReturn() { - @Override - public void doInTransactionWithoutResult(TransactionStatus status) { - // remove entry from acl_entity_permission table - List permitList = _policyPermissionDao.listByEntity(entityType, entityId); - for (IAMPolicyPermissionVO permit : permitList) { - long policyId = permit.getAclPolicyId(); - _policyPermissionDao.remove(permit.getId()); - - // remove the policy if there are no other permissions - if ((_policyPermissionDao.listByPolicy(policyId)).isEmpty()) { - deleteIAMPolicy(policyId); - } - } - } - }); - } - - @DB - @Override - public IAMPolicy resetIAMPolicy(long iamPolicyId) { - // get the Acl Policy entity - IAMPolicy policy = _aclPolicyDao.findById(iamPolicyId); - if (policy == null) { - throw new InvalidParameterValueException("Unable to find acl policy: " + iamPolicyId - + "; failed to reset the policy."); - } - - SearchBuilder sb = _policyPermissionDao.createSearchBuilder(); - sb.and("policyId", sb.entity().getAclPolicyId(), SearchCriteria.Op.EQ); - sb.and("scope", sb.entity().getScope(), SearchCriteria.Op.EQ); - sb.done(); - SearchCriteria permissionSC = sb.create(); - permissionSC.setParameters("policyId", iamPolicyId); - _policyPermissionDao.expunge(permissionSC); - - return policy; - } - - @Override - public boolean isActionAllowedForPolicies(String action, List policies) { - - boolean allowed = false; - - if (policies == null || policies.size() == 0) { - return allowed; - } - - List policyIds = new ArrayList(); - for (IAMPolicy policy : policies) { - policyIds.add(policy.getId()); - } - - SearchBuilder sb = _policyPermissionDao.createSearchBuilder(); - sb.and("action", sb.entity().getAction(), Op.EQ); - sb.and("policyId", sb.entity().getAclPolicyId(), Op.IN); - - SearchCriteria sc = sb.create(); - sc.setParameters("policyId", policyIds.toArray(new Object[policyIds.size()])); - sc.setParameters("action", action); - - List permissions = _policyPermissionDao.customSearch(sc, null); - - if (permissions != null && !permissions.isEmpty()) { - allowed = true; - } - - return allowed; - } - - - @Override - public List getGrantedEntities(long accountId, String action, String scope) { - // Get the static Policies of the Caller - List policies = listIAMPolicies(accountId); - // for each policy, find granted permission within the given scope - List entityIds = new ArrayList(); - for (IAMPolicy policy : policies) { - List pp = _policyPermissionDao.listGrantedByActionAndScope(policy.getId(), action, - scope); - if (pp != null) { - for (IAMPolicyPermissionVO p : pp) { - if (p.getScopeId() != null) { - entityIds.add(p.getScopeId()); - } - } - } - } - return entityIds; - } - - @Override - @SuppressWarnings("unchecked") - public List listPolicyPermissions(long policyId) { - @SuppressWarnings("rawtypes") - List pp = _policyPermissionDao.listByPolicy(policyId); - return pp; - } - - @SuppressWarnings("unchecked") - @Override - public List listPolicyPermissionsByScope(long policyId, String action, String scope) { - @SuppressWarnings("rawtypes") - List pp = _policyPermissionDao.listGrantedByActionAndScope(policyId, action, scope); - return pp; - } - - @SuppressWarnings("unchecked") - @Override - public List listPolicyPermissionByActionAndEntity(long policyId, String action, - String entityType) { - @SuppressWarnings("rawtypes") - List pp = _policyPermissionDao.listByPolicyActionAndEntity(policyId, action, entityType); - return pp; - } - - @SuppressWarnings("unchecked") - @Override - public List listPolicyPermissionByAccessAndEntity(long policyId, String accessType, - String entityType) { - @SuppressWarnings("rawtypes") - List pp = _policyPermissionDao.listByPolicyAccessAndEntity(policyId, accessType, entityType); - return pp; - } - - @Override - public IAMPolicy getResourceOwnerPolicy() { - return _aclPolicyDao.findByName("RESOURCE_OWNER"); - } - - // search for policy with only one resource grant permission - @Override - public IAMPolicy getResourceGrantPolicy(String entityType, Long entityId, String accessType, String action) { - List policyList = _aclPolicyDao.listAll(); - for (IAMPolicyVO policy : policyList){ - List pp = listPolicyPermissions(policy.getId()); - if ( pp != null && pp.size() == 1){ - // resource grant policy should only have one ACL permission assigned - IAMPolicyPermission permit = pp.get(0); - if ( permit.getEntityType().equals(entityType) && permit.getScope().equals(PermissionScope.RESOURCE.toString()) && permit.getScopeId().longValue() == entityId.longValue()){ - if (accessType != null && permit.getAccessType().equals(accessType)){ - return policy; - } else if (action != null && permit.getAction().equals(action)) { - return policy; - } - } - } - } - return null; - } - -} +// 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.iam.server; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import javax.ejb.Local; +import javax.inject.Inject; +import javax.naming.ConfigurationException; + +import net.sf.ehcache.Cache; +import net.sf.ehcache.CacheManager; +import net.sf.ehcache.Element; + +import org.apache.log4j.Logger; + +import org.apache.cloudstack.acl.PermissionScope; +import org.apache.cloudstack.iam.api.IAMGroup; +import org.apache.cloudstack.iam.api.IAMPolicy; +import org.apache.cloudstack.iam.api.IAMPolicyPermission; +import org.apache.cloudstack.iam.api.IAMPolicyPermission.Permission; +import org.apache.cloudstack.iam.api.IAMService; +import org.apache.cloudstack.iam.server.dao.IAMAccountPolicyMapDao; +import org.apache.cloudstack.iam.server.dao.IAMGroupAccountMapDao; +import org.apache.cloudstack.iam.server.dao.IAMGroupDao; +import org.apache.cloudstack.iam.server.dao.IAMGroupPolicyMapDao; +import org.apache.cloudstack.iam.server.dao.IAMPolicyDao; +import org.apache.cloudstack.iam.server.dao.IAMPolicyPermissionDao; + +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.utils.NumbersUtil; +import com.cloud.utils.Pair; +import com.cloud.utils.component.Manager; +import com.cloud.utils.component.ManagerBase; +import com.cloud.utils.db.DB; +import com.cloud.utils.db.EntityManager; +import com.cloud.utils.db.Filter; +import com.cloud.utils.db.GenericSearchBuilder; +import com.cloud.utils.db.JoinBuilder; +import com.cloud.utils.db.JoinBuilder.JoinType; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.SearchCriteria.Op; +import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionCallback; +import com.cloud.utils.db.TransactionCallbackNoReturn; +import com.cloud.utils.db.TransactionStatus; + +@Local(value = {IAMService.class}) +public class IAMServiceImpl extends ManagerBase implements IAMService, Manager { + + public static final Logger s_logger = Logger.getLogger(IAMServiceImpl.class); + private String _name; + + @Inject + IAMPolicyDao _aclPolicyDao; + + @Inject + IAMGroupDao _aclGroupDao; + + @Inject + EntityManager _entityMgr; + + @Inject + IAMGroupPolicyMapDao _aclGroupPolicyMapDao; + + @Inject + IAMAccountPolicyMapDao _aclAccountPolicyMapDao; + + @Inject + IAMGroupAccountMapDao _aclGroupAccountMapDao; + + @Inject + IAMPolicyPermissionDao _policyPermissionDao; + + private Cache _iamCache; + + private void createIAMCache(final Map params) { + final String value = (String)params.get("cache.size"); + + if (value != null) { + final CacheManager cm = CacheManager.create(); + final int maxElements = NumbersUtil.parseInt(value, 0); + final int live = NumbersUtil.parseInt((String)params.get("cache.time.to.live"), 300); + final int idle = NumbersUtil.parseInt((String)params.get("cache.time.to.idle"), 300); + _iamCache = new Cache(getName(), maxElements, false, live == -1, live == -1 ? Integer.MAX_VALUE : live, idle); + cm.addCache(_iamCache); + s_logger.info("IAM Cache created: " + _iamCache.toString()); + } else { + _iamCache = null; + } + } + + @Override + public void addToIAMCache(Object accessKey, Object allowDeny) { + if (_iamCache != null) { + try { + s_logger.debug("Put IAM access check for " + accessKey + " in cache"); + _iamCache.put(new Element(accessKey, allowDeny)); + } catch (final Exception e) { + s_logger.debug("Can't put " + accessKey + " to IAM cache", e); + } + } + } + + @Override + public void invalidateIAMCache() { + //This may need to use event bus to publish to other MS, but event bus now is missing this functionality to handle PublishScope.GLOBAL + if (_iamCache != null) { + s_logger.debug("Invalidate IAM cache"); + _iamCache.removeAll(); + } + } + + @Override + public Object getFromIAMCache(Object accessKey) { + if (_iamCache != null) { + final Element element = _iamCache.get(accessKey); + return element == null ? null : element.getObjectValue(); + } + return null; + } + + @Override + public boolean configure(final String name, final Map params) throws ConfigurationException { + boolean result = super.configure(name, params); + // create IAM cache + createIAMCache(params); + return result; + } + + @DB + @Override + public IAMGroup createIAMGroup(String iamGroupName, String description, String path) { + // check if the group is already existing + IAMGroup grp = _aclGroupDao.findByName(path, iamGroupName); + if (grp != null) { + throw new InvalidParameterValueException( + "Unable to create acl group with name " + iamGroupName + + " already exisits for path " + path); + } + IAMGroupVO rvo = new IAMGroupVO(iamGroupName, description); + rvo.setPath(path); + + return _aclGroupDao.persist(rvo); + } + + @DB + @Override + public boolean deleteIAMGroup(final Long iamGroupId) { + // get the Acl Group entity + final IAMGroup grp = _aclGroupDao.findById(iamGroupId); + if (grp == null) { + throw new InvalidParameterValueException("Unable to find acl group: " + iamGroupId + + "; failed to delete acl group."); + } + + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + // remove this group related entry in acl_group_policy_map + List groupPolicyMap = _aclGroupPolicyMapDao.listByGroupId(grp.getId()); + if (groupPolicyMap != null) { + for (IAMGroupPolicyMapVO gr : groupPolicyMap) { + _aclGroupPolicyMapDao.remove(gr.getId()); + } + } + + // remove this group related entry in acl_group_account table + List groupAcctMap = _aclGroupAccountMapDao.listByGroupId(grp.getId()); + if (groupAcctMap != null) { + for (IAMGroupAccountMapVO grpAcct : groupAcctMap) { + _aclGroupAccountMapDao.remove(grpAcct.getId()); + } + } + + // remove this group from acl_group table + _aclGroupDao.remove(iamGroupId); + } + }); + + invalidateIAMCache(); + return true; + } + + @SuppressWarnings("unchecked") + @Override + public List listIAMGroups(long accountId) { + + GenericSearchBuilder groupSB = _aclGroupAccountMapDao.createSearchBuilder(Long.class); + groupSB.selectFields(groupSB.entity().getAclGroupId()); + groupSB.and("account", groupSB.entity().getAccountId(), Op.EQ); + SearchCriteria groupSc = groupSB.create(); + groupSc.setParameters("account", accountId); + + List groupIds = _aclGroupAccountMapDao.customSearch(groupSc, null); + + if (groupIds == null || groupIds.isEmpty()) { + return new ArrayList(); + } + SearchBuilder sb = _aclGroupDao.createSearchBuilder(); + sb.and("ids", sb.entity().getId(), Op.IN); + SearchCriteria sc = sb.create(); + sc.setParameters("ids", groupIds.toArray(new Object[groupIds.size()])); + @SuppressWarnings("rawtypes") + List groups = _aclGroupDao.search(sc, null); + return groups; + } + + @DB + @Override + public IAMGroup addAccountsToGroup(final List acctIds, final Long groupId) { + // get the Acl Group entity + IAMGroup group = _aclGroupDao.findById(groupId); + if (group == null) { + throw new InvalidParameterValueException("Unable to find acl group: " + groupId + + "; failed to add accounts to acl group."); + } + + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + // add entries in acl_group_account_map table + for (Long acctId : acctIds) { + // check account permissions + IAMGroupAccountMapVO grMap = _aclGroupAccountMapDao.findByGroupAndAccount(groupId, acctId); + if (grMap == null) { + // not there already + grMap = new IAMGroupAccountMapVO(groupId, acctId); + _aclGroupAccountMapDao.persist(grMap); + } + } + } + }); + + invalidateIAMCache(); + return group; + } + + @DB + @Override + public IAMGroup removeAccountsFromGroup(final List acctIds, final Long groupId) { + // get the Acl Group entity + IAMGroup group = _aclGroupDao.findById(groupId); + if (group == null) { + throw new InvalidParameterValueException("Unable to find acl group: " + groupId + + "; failed to remove accounts from acl group."); + } + + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + // remove entries from acl_group_account_map table + for (Long acctId : acctIds) { + IAMGroupAccountMapVO grMap = _aclGroupAccountMapDao.findByGroupAndAccount(groupId, acctId); + if (grMap != null) { + // not removed yet + _aclGroupAccountMapDao.remove(grMap.getId()); + } + } + } + }); + + invalidateIAMCache(); + return group; + } + + @Override + public List listAccountsByGroup(long groupId) { + List grpAcctMap = _aclGroupAccountMapDao.listByGroupId(groupId); + if (grpAcctMap == null || grpAcctMap.size() == 0) { + return new ArrayList(); + } + + List accts = new ArrayList(); + for (IAMGroupAccountMapVO grpAcct : grpAcctMap) { + accts.add(grpAcct.getAccountId()); + } + return accts; + } + + @Override + public Pair, Integer> listIAMGroups(Long iamGroupId, String iamGroupName, String path, Long startIndex, Long pageSize) { + if (iamGroupId != null) { + IAMGroup group = _aclGroupDao.findById(iamGroupId); + if (group == null) { + throw new InvalidParameterValueException("Unable to find acl group by id " + iamGroupId); + } + } + + Filter searchFilter = new Filter(IAMGroupVO.class, "id", true, startIndex, pageSize); + + SearchBuilder sb = _aclGroupDao.createSearchBuilder(); + sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ); + sb.and("path", sb.entity().getPath(), SearchCriteria.Op.LIKE); + sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); + + SearchCriteria sc = sb.create(); + + if (iamGroupName != null) { + sc.setParameters("name", iamGroupName); + } + + if (iamGroupId != null) { + sc.setParameters("id", iamGroupId); + } + + sc.setParameters("path", path + "%"); + + Pair, Integer> groups = _aclGroupDao.searchAndCount(sc, searchFilter); + return new Pair, Integer>(new ArrayList(groups.first()), groups.second()); + } + + @Override + public List listParentIAMGroups(long groupId) { + IAMGroup group = _aclGroupDao.findById(groupId); + if (group == null) { + throw new InvalidParameterValueException("Unable to find acl group by id " + groupId); + } + + String path = group.getPath(); + List pathList = new ArrayList(); + + String[] parts = path.split("/"); + + for (String part : parts) { + int start = path.indexOf(part); + if (start > 0) { + String subPath = path.substring(0, start); + pathList.add(subPath); + } + } + + if (pathList.isEmpty()) { + return new ArrayList(); + } + + SearchBuilder sb = _aclGroupDao.createSearchBuilder(); + sb.and("paths", sb.entity().getPath(), SearchCriteria.Op.IN); + + SearchCriteria sc = sb.create(); + sc.setParameters("paths", pathList.toArray()); + + List groups = _aclGroupDao.search(sc, null); + + return new ArrayList(groups); + + } + + @DB + @Override + public IAMPolicy createIAMPolicy(final String iamPolicyName, final String description, final Long parentPolicyId, final String path) { + + // check if the policy is already existing + IAMPolicy ro = _aclPolicyDao.findByName(iamPolicyName); + if (ro != null) { + throw new InvalidParameterValueException( + "Unable to create acl policy with name " + iamPolicyName + + " already exisits"); + } + + IAMPolicy role = Transaction.execute(new TransactionCallback() { + @Override + public IAMPolicy doInTransaction(TransactionStatus status) { + IAMPolicyVO rvo = new IAMPolicyVO(iamPolicyName, description); + rvo.setPath(path); + + IAMPolicy role = _aclPolicyDao.persist(rvo); + if (parentPolicyId != null) { + // copy parent role permissions + List perms = _policyPermissionDao.listByPolicy(parentPolicyId); + if (perms != null) { + for (IAMPolicyPermissionVO perm : perms) { + perm.setAclPolicyId(role.getId()); + _policyPermissionDao.persist(perm); + } + } + } + return role; + } + }); + + + return role; + } + + @DB + @Override + public boolean deleteIAMPolicy(final long iamPolicyId) { + // get the Acl Policy entity + final IAMPolicy policy = _aclPolicyDao.findById(iamPolicyId); + if (policy == null) { + throw new InvalidParameterValueException("Unable to find acl policy: " + iamPolicyId + + "; failed to delete acl policy."); + } + + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + // remove this policy related entry in acl_group_policy_map + List groupPolicyMap = _aclGroupPolicyMapDao.listByPolicyId(policy.getId()); + if (groupPolicyMap != null) { + for (IAMGroupPolicyMapVO gr : groupPolicyMap) { + _aclGroupPolicyMapDao.remove(gr.getId()); + } + } + + // remove this policy related entry in acl_account_policy_map table + List policyAcctMap = _aclAccountPolicyMapDao.listByPolicyId(policy.getId()); + if (policyAcctMap != null) { + for (IAMAccountPolicyMapVO policyAcct : policyAcctMap) { + _aclAccountPolicyMapDao.remove(policyAcct.getId()); + } + } + + // remove this policy related entry in acl_policy_permission table + List policyPermMap = _policyPermissionDao.listByPolicy(policy.getId()); + if (policyPermMap != null) { + for (IAMPolicyPermissionVO policyPerm : policyPermMap) { + _policyPermissionDao.remove(policyPerm.getId()); + } + } + + // remove this role from acl_role table + _aclPolicyDao.remove(iamPolicyId); + } + }); + + invalidateIAMCache(); + + return true; + } + + + @SuppressWarnings("unchecked") + @Override + public List listIAMPolicies(long accountId) { + + // static policies of the account + SearchBuilder groupSB = _aclGroupAccountMapDao.createSearchBuilder(); + groupSB.and("account", groupSB.entity().getAccountId(), Op.EQ); + + GenericSearchBuilder policySB = _aclGroupPolicyMapDao.createSearchBuilder(Long.class); + policySB.selectFields(policySB.entity().getAclPolicyId()); + policySB.join("accountgroupjoin", groupSB, groupSB.entity().getAclGroupId(), policySB.entity().getAclGroupId(), + JoinType.INNER); + policySB.done(); + SearchCriteria policySc = policySB.create(); + policySc.setJoinParameters("accountgroupjoin", "account", accountId); + + List policyIds = _aclGroupPolicyMapDao.customSearch(policySc, null); + // add policies directly attached to the account + List acctPolicies = _aclAccountPolicyMapDao.listByAccountId(accountId); + for (IAMAccountPolicyMapVO p : acctPolicies) { + policyIds.add(p.getIamPolicyId()); + } + if (policyIds.size() == 0) { + return new ArrayList(); + } + SearchBuilder sb = _aclPolicyDao.createSearchBuilder(); + sb.and("ids", sb.entity().getId(), Op.IN); + SearchCriteria sc = sb.create(); + sc.setParameters("ids", policyIds.toArray(new Object[policyIds.size()])); + @SuppressWarnings("rawtypes") + List policies = _aclPolicyDao.customSearch(sc, null); + + return policies; + + } + + @SuppressWarnings("unchecked") + @Override + public List listIAMPoliciesByGroup(long groupId) { + List policyGrpMap = _aclGroupPolicyMapDao.listByGroupId(groupId); + if (policyGrpMap == null || policyGrpMap.size() == 0) { + return new ArrayList(); + } + + List policyIds = new ArrayList(); + for (IAMGroupPolicyMapVO pg : policyGrpMap) { + policyIds.add(pg.getAclPolicyId()); + } + + SearchBuilder sb = _aclPolicyDao.createSearchBuilder(); + sb.and("ids", sb.entity().getId(), Op.IN); + SearchCriteria sc = sb.create(); + sc.setParameters("ids", policyIds.toArray(new Object[policyIds.size()])); + @SuppressWarnings("rawtypes") + List policies = _aclPolicyDao.customSearch(sc, null); + + return policies; + } + + @SuppressWarnings("unchecked") + @Override + public List listRecursiveIAMPoliciesByGroup(long groupId) { + List policyGrpMap = _aclGroupPolicyMapDao.listByGroupId(groupId); + if (policyGrpMap == null || policyGrpMap.size() == 0) { + return new ArrayList(); + } + + List policyIds = new ArrayList(); + for (IAMGroupPolicyMapVO pg : policyGrpMap) { + policyIds.add(pg.getAclPolicyId()); + } + + SearchBuilder permSb = _policyPermissionDao.createSearchBuilder(); + permSb.and("isRecursive", permSb.entity().isRecursive(), Op.EQ); + + SearchBuilder sb = _aclPolicyDao.createSearchBuilder(); + sb.and("ids", sb.entity().getId(), Op.IN); + sb.join("recursivePerm", permSb, sb.entity().getId(), permSb.entity().getAclPolicyId(), + JoinBuilder.JoinType.INNER); + + SearchCriteria sc = sb.create(); + sc.setParameters("ids", policyIds.toArray(new Object[policyIds.size()])); + sc.setJoinParameters("recursivePerm", "isRecursive", true); + + @SuppressWarnings("rawtypes") + List policies = _aclPolicyDao.customSearch(sc, null); + + return policies; + } + + + @SuppressWarnings("unchecked") + @Override + public Pair, Integer> listIAMPolicies(Long iamPolicyId, String iamPolicyName, String path, Long startIndex, Long pageSize) { + + if (iamPolicyId != null) { + IAMPolicy policy = _aclPolicyDao.findById(iamPolicyId); + if (policy == null) { + throw new InvalidParameterValueException("Unable to find acl policy by id " + iamPolicyId); + } + } + + Filter searchFilter = new Filter(IAMPolicyVO.class, "id", true, startIndex, pageSize); + + SearchBuilder sb = _aclPolicyDao.createSearchBuilder(); + sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ); + sb.and("path", sb.entity().getPath(), SearchCriteria.Op.LIKE); + sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); + + SearchCriteria sc = sb.create(); + + if (iamPolicyName != null) { + sc.setParameters("name", iamPolicyName); + } + + if (iamPolicyId != null) { + sc.setParameters("id", iamPolicyId); + } + + sc.setParameters("path", path + "%"); + + Pair, Integer> policies = _aclPolicyDao.searchAndCount(sc, searchFilter); + @SuppressWarnings("rawtypes") + List policyList = policies.first(); + return new Pair, Integer>(policyList, policies.second()); + } + + @DB + @Override + public IAMGroup attachIAMPoliciesToGroup(final List policyIds, final Long groupId) { + // get the Acl Group entity + IAMGroup group = _aclGroupDao.findById(groupId); + if (group == null) { + throw new InvalidParameterValueException("Unable to find acl group: " + groupId + + "; failed to add roles to acl group."); + } + + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + // add entries in acl_group_policy_map table + for (Long policyId : policyIds) { + IAMPolicy policy = _aclPolicyDao.findById(policyId); + if (policy == null) { + throw new InvalidParameterValueException("Unable to find acl policy: " + policyId + + "; failed to add policies to acl group."); + } + + IAMGroupPolicyMapVO grMap = _aclGroupPolicyMapDao.findByGroupAndPolicy(groupId, policyId); + if (grMap == null) { + // not there already + grMap = new IAMGroupPolicyMapVO(groupId, policyId); + _aclGroupPolicyMapDao.persist(grMap); + } + } + } + }); + + invalidateIAMCache(); + return group; + } + + @DB + @Override + public IAMGroup removeIAMPoliciesFromGroup(final List policyIds, final Long groupId) { + // get the Acl Group entity + IAMGroup group = _aclGroupDao.findById(groupId); + if (group == null) { + throw new InvalidParameterValueException("Unable to find acl group: " + groupId + + "; failed to remove roles from acl group."); + } + + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + // add entries in acl_group_role_map table + for (Long policyId : policyIds) { + IAMPolicy policy = _aclPolicyDao.findById(policyId); + if (policy == null) { + throw new InvalidParameterValueException("Unable to find acl policy: " + policyId + + "; failed to add policies to acl group."); + } + + IAMGroupPolicyMapVO grMap = _aclGroupPolicyMapDao.findByGroupAndPolicy(groupId, policyId); + if (grMap != null) { + // not removed yet + _aclGroupPolicyMapDao.remove(grMap.getId()); + } + } + } + }); + + invalidateIAMCache(); + return group; + } + + + @Override + public void attachIAMPolicyToAccounts(final Long policyId, final List acctIds) { + IAMPolicy policy = _aclPolicyDao.findById(policyId); + if (policy == null) { + throw new InvalidParameterValueException("Unable to find acl policy: " + policyId + + "; failed to add policy to account."); + } + + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + // add entries in acl_group_policy_map table + for (Long acctId : acctIds) { + IAMAccountPolicyMapVO acctMap = _aclAccountPolicyMapDao.findByAccountAndPolicy(acctId, policyId); + if (acctMap == null) { + // not there already + acctMap = new IAMAccountPolicyMapVO(acctId, policyId); + _aclAccountPolicyMapDao.persist(acctMap); + } + } + } + }); + + invalidateIAMCache(); + } + + @Override + public void removeIAMPolicyFromAccounts(final Long policyId, final List acctIds) { + IAMPolicy policy = _aclPolicyDao.findById(policyId); + if (policy == null) { + throw new InvalidParameterValueException("Unable to find acl policy: " + policyId + + "; failed to add policy to account."); + } + + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + // add entries in acl_group_policy_map table + for (Long acctId : acctIds) { + IAMAccountPolicyMapVO acctMap = _aclAccountPolicyMapDao.findByAccountAndPolicy(acctId, policyId); + if (acctMap != null) { + // exists + _aclAccountPolicyMapDao.remove(acctMap.getId()); + } + } + } + }); + + invalidateIAMCache(); + } + + @DB + @Override + public IAMPolicy addIAMPermissionToIAMPolicy(long iamPolicyId, String entityType, String scope, Long scopeId, + String action, String accessType, Permission perm, Boolean recursive) { + // get the Acl Policy entity + IAMPolicy policy = _aclPolicyDao.findById(iamPolicyId); + if (policy == null) { + throw new InvalidParameterValueException("Unable to find acl policy: " + iamPolicyId + + "; failed to add permission to policy."); + } + + // add entry in acl_policy_permission table + IAMPolicyPermissionVO permit = _policyPermissionDao.findByPolicyAndEntity(iamPolicyId, entityType, scope, + scopeId, action, perm, accessType); + if (permit == null) { + // not there already + permit = new IAMPolicyPermissionVO(iamPolicyId, action, entityType, accessType, scope, scopeId, perm, + recursive); + _policyPermissionDao.persist(permit); + } + + invalidateIAMCache(); + return policy; + + } + + @DB + @Override + public IAMPolicy removeIAMPermissionFromIAMPolicy(long iamPolicyId, String entityType, String scope, Long scopeId, + String action) { + // get the Acl Policy entity + IAMPolicy policy = _aclPolicyDao.findById(iamPolicyId); + if (policy == null) { + throw new InvalidParameterValueException("Unable to find acl policy: " + iamPolicyId + + "; failed to revoke permission from policy."); + } + // remove entry from acl_entity_permission table + IAMPolicyPermissionVO permit = _policyPermissionDao.findByPolicyAndEntity(iamPolicyId, entityType, scope, + scopeId, action, Permission.Allow, null); + if (permit != null) { + // not removed yet + _policyPermissionDao.remove(permit.getId()); + } + + invalidateIAMCache(); + return policy; + } + + @DB + @Override + public void removeIAMPermissionForEntity(final String entityType, final Long entityId) { + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + // remove entry from acl_entity_permission table + List permitList = _policyPermissionDao.listByEntity(entityType, entityId); + for (IAMPolicyPermissionVO permit : permitList) { + long policyId = permit.getAclPolicyId(); + _policyPermissionDao.remove(permit.getId()); + + // remove the policy if there are no other permissions + if ((_policyPermissionDao.listByPolicy(policyId)).isEmpty()) { + deleteIAMPolicy(policyId); + } + } + } + }); + + invalidateIAMCache(); + } + + @DB + @Override + public IAMPolicy resetIAMPolicy(long iamPolicyId) { + // get the Acl Policy entity + IAMPolicy policy = _aclPolicyDao.findById(iamPolicyId); + if (policy == null) { + throw new InvalidParameterValueException("Unable to find acl policy: " + iamPolicyId + + "; failed to reset the policy."); + } + + SearchBuilder sb = _policyPermissionDao.createSearchBuilder(); + sb.and("policyId", sb.entity().getAclPolicyId(), SearchCriteria.Op.EQ); + sb.and("scope", sb.entity().getScope(), SearchCriteria.Op.EQ); + sb.done(); + SearchCriteria permissionSC = sb.create(); + permissionSC.setParameters("policyId", iamPolicyId); + _policyPermissionDao.expunge(permissionSC); + + invalidateIAMCache(); + return policy; + } + + @Override + public boolean isActionAllowedForPolicies(String action, List policies) { + + boolean allowed = false; + + if (policies == null || policies.size() == 0) { + return allowed; + } + + List policyIds = new ArrayList(); + for (IAMPolicy policy : policies) { + policyIds.add(policy.getId()); + } + + SearchBuilder sb = _policyPermissionDao.createSearchBuilder(); + sb.and("action", sb.entity().getAction(), Op.EQ); + sb.and("policyId", sb.entity().getAclPolicyId(), Op.IN); + + SearchCriteria sc = sb.create(); + sc.setParameters("policyId", policyIds.toArray(new Object[policyIds.size()])); + sc.setParameters("action", action); + + List permissions = _policyPermissionDao.customSearch(sc, null); + + if (permissions != null && !permissions.isEmpty()) { + allowed = true; + } + + return allowed; + } + + + @Override + public List getGrantedEntities(long accountId, String action, String scope) { + // Get the static Policies of the Caller + List policies = listIAMPolicies(accountId); + // for each policy, find granted permission within the given scope + List entityIds = new ArrayList(); + for (IAMPolicy policy : policies) { + List pp = _policyPermissionDao.listByPolicyActionAndScope(policy.getId(), action, + scope, null); + if (pp != null) { + for (IAMPolicyPermissionVO p : pp) { + if (p.getScopeId() != null) { + entityIds.add(p.getScopeId()); + } + } + } + } + return entityIds; + } + + @Override + @SuppressWarnings("unchecked") + public List listPolicyPermissions(long policyId) { + @SuppressWarnings("rawtypes") + List pp = _policyPermissionDao.listByPolicy(policyId); + return pp; + } + + @SuppressWarnings("unchecked") + @Override + public List listPolicyPermissionsByScope(long policyId, String action, String scope, + String accessType) { + @SuppressWarnings("rawtypes") + List pp = _policyPermissionDao.listByPolicyActionAndScope(policyId, action, scope, accessType); + return pp; + } + + @SuppressWarnings("unchecked") + @Override + public List listPolicyPermissionByActionAndEntity(long policyId, String action, + String entityType) { + @SuppressWarnings("rawtypes") + List pp = _policyPermissionDao.listByPolicyActionAndEntity(policyId, action, entityType); + return pp; + } + + @SuppressWarnings("unchecked") + @Override + public List listPolicyPermissionByAccessAndEntity(long policyId, String accessType, + String entityType) { + @SuppressWarnings("rawtypes") + List pp = _policyPermissionDao.listByPolicyAccessAndEntity(policyId, accessType, entityType); + return pp; + } + + @Override + public IAMPolicy getResourceOwnerPolicy() { + return _aclPolicyDao.findByName("RESOURCE_OWNER"); + } + + // search for policy with only one resource grant permission + @Override + public IAMPolicy getResourceGrantPolicy(String entityType, Long entityId, String accessType, String action) { + List policyList = _aclPolicyDao.listAll(); + for (IAMPolicyVO policy : policyList) { + List pp = listPolicyPermissions(policy.getId()); + if (pp != null && pp.size() == 1) { + // resource grant policy should only have one ACL permission assigned + IAMPolicyPermission permit = pp.get(0); + if (permit.getEntityType().equals(entityType) && permit.getScope().equals(PermissionScope.RESOURCE.toString()) + && permit.getScopeId().longValue() == entityId.longValue()) { + if (accessType != null && permit.getAccessType().equals(accessType)) { + return policy; + } else if (action != null && permit.getAction().equals(action)) { + return policy; + } + } + } + } + return null; + } + +} diff --git a/services/iam/server/src/org/apache/cloudstack/iam/server/dao/IAMPolicyPermissionDao.java b/services/iam/server/src/org/apache/cloudstack/iam/server/dao/IAMPolicyPermissionDao.java index cdcb02b1de..ebb4916470 100644 --- a/services/iam/server/src/org/apache/cloudstack/iam/server/dao/IAMPolicyPermissionDao.java +++ b/services/iam/server/src/org/apache/cloudstack/iam/server/dao/IAMPolicyPermissionDao.java @@ -27,9 +27,9 @@ public interface IAMPolicyPermissionDao extends GenericDao listByPolicy(long policyId); IAMPolicyPermissionVO findByPolicyAndEntity(long policyId, String entityType, String scope, Long scopeId, - String action, Permission perm); + String action, Permission perm, String accessType); - List listGrantedByActionAndScope(long policyId, String action, String scope); + List listByPolicyActionAndScope(long policyId, String action, String scope, String accessType); List listByPolicyActionAndEntity(long policyId, String action, String entityType); diff --git a/services/iam/server/src/org/apache/cloudstack/iam/server/dao/IAMPolicyPermissionDaoImpl.java b/services/iam/server/src/org/apache/cloudstack/iam/server/dao/IAMPolicyPermissionDaoImpl.java index 3f976cfefc..44b77d1163 100644 --- a/services/iam/server/src/org/apache/cloudstack/iam/server/dao/IAMPolicyPermissionDaoImpl.java +++ b/services/iam/server/src/org/apache/cloudstack/iam/server/dao/IAMPolicyPermissionDaoImpl.java @@ -33,7 +33,6 @@ public class IAMPolicyPermissionDaoImpl extends GenericDaoBase policyIdSearch; private SearchBuilder fullSearch; - private SearchBuilder actionScopeSearch; private SearchBuilder entitySearch; @Override @@ -54,13 +53,6 @@ public boolean configure(String name, Map params) throws Configu fullSearch.and("accessType", fullSearch.entity().getAccessType(), SearchCriteria.Op.EQ); fullSearch.done(); - actionScopeSearch = createSearchBuilder(); - actionScopeSearch.and("policyId", actionScopeSearch.entity().getAclPolicyId(), SearchCriteria.Op.EQ); - actionScopeSearch.and("scope", actionScopeSearch.entity().getScope(), SearchCriteria.Op.EQ); - actionScopeSearch.and("action", actionScopeSearch.entity().getAction(), SearchCriteria.Op.EQ); - actionScopeSearch.and("permission", actionScopeSearch.entity().getPermission(), SearchCriteria.Op.EQ); - actionScopeSearch.done(); - entitySearch = createSearchBuilder(); entitySearch.and("entityType", entitySearch.entity().getEntityType(), SearchCriteria.Op.EQ); entitySearch.and("scopeId", entitySearch.entity().getScopeId(), SearchCriteria.Op.EQ); @@ -78,7 +70,7 @@ public List listByPolicy(long policyId) { @Override public IAMPolicyPermissionVO findByPolicyAndEntity(long policyId, String entityType, String scope, Long scopeId, - String action, Permission perm) { + String action, Permission perm, String accessType) { SearchCriteria sc = fullSearch.create(); sc.setParameters("policyId", policyId); sc.setParameters("entityType", entityType); @@ -86,16 +78,25 @@ public IAMPolicyPermissionVO findByPolicyAndEntity(long policyId, String entityT sc.setParameters("scopeId", scopeId); sc.setParameters("action", action); sc.setParameters("permission", perm); + if (accessType != null) { + // accessType can be optional, used mainly in list apis with + // ListEntry and UseEntry distinction + sc.setParameters("accessType", accessType); + } return findOneBy(sc); } @Override - public List listGrantedByActionAndScope(long policyId, String action, String scope) { - SearchCriteria sc = actionScopeSearch.create(); + public List listByPolicyActionAndScope(long policyId, String action, String scope, String accessType) { + SearchCriteria sc = fullSearch.create(); sc.setParameters("policyId", policyId); sc.setParameters("action", action); sc.setParameters("scope", scope); sc.setParameters("permission", Permission.Allow); + if ( accessType != null ){ + // accessType can be optional, used mainly in list apis with ListEntry and UseEntry distinction + sc.setParameters("accessType", accessType); + } return listBy(sc); } @@ -120,7 +121,7 @@ public List listByPolicyAccessAndEntity(long policyId, St @Override public List listByEntity(String entityType, Long entityId) { - SearchCriteria sc = fullSearch.create(); + SearchCriteria sc = entitySearch.create(); sc.setParameters("entityType", entityType); sc.setParameters("scopeId", entityId); return listBy(sc); diff --git a/services/pom.xml b/services/pom.xml index a12a7b5fe4..def30271f9 100644 --- a/services/pom.xml +++ b/services/pom.xml @@ -47,6 +47,5 @@ console-proxy console-proxy-rdp/rdpconsole secondary-storage - iam diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java index 9782c2ec7c..6927f028cf 100755 --- a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java +++ b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java @@ -1188,6 +1188,8 @@ private void configCerts(KeystoreManager.Certificates certs) { } else { String prvKey = certs.getPrivKey(); String pubCert = certs.getPrivCert(); + String certChain = certs.getCertChain(); + String rootCACert = certs.getRootCACert(); try { File prvKeyFile = File.createTempFile("prvkey", null); @@ -1203,10 +1205,34 @@ private void configCerts(KeystoreManager.Certificates certs) { out.write(pubCert); out.close(); - configureSSL(prvkeyPath, pubCertFilePath, null); + String certChainFilePath = null, rootCACertFilePath = null; + File certChainFile = null, rootCACertFile = null; + if(certChain != null){ + certChainFile = File.createTempFile("certchain", null); + certChainFilePath = certChainFile.getAbsolutePath(); + out = new BufferedWriter(new FileWriter(certChainFile)); + out.write(certChain); + out.close(); + } + + if(rootCACert != null){ + rootCACertFile = File.createTempFile("rootcert", null); + rootCACertFilePath = rootCACertFile.getAbsolutePath(); + out = new BufferedWriter(new FileWriter(rootCACertFile)); + out.write(rootCACert); + out.close(); + } + + configureSSL(prvkeyPath, pubCertFilePath, certChainFilePath, rootCACertFilePath); prvKeyFile.delete(); pubCertFile.delete(); + if(certChainFile != null){ + certChainFile.delete(); + } + if(rootCACertFile != null){ + rootCACertFile.delete(); + } } catch (IOException e) { s_logger.debug("Failed to config ssl: " + e.toString()); @@ -1278,7 +1304,7 @@ protected Answer deleteSnapshot(final DeleteCommand cmd) { if (!snapshotDir.exists()) { details = "snapshot directory " + snapshotDir.getName() + " doesn't exist"; s_logger.debug(details); - return new Answer(cmd, false, details); + return new Answer(cmd, true, details); } // delete snapshot in the directory if exists String lPath = absoluteSnapshotPath + "/*" + snapshotName + "*"; @@ -2064,7 +2090,7 @@ private void configureSSL() { } } - private void configureSSL(String prvkeyPath, String prvCertPath, String certChainPath) { + private void configureSSL(String prvkeyPath, String prvCertPath, String certChainPath, String rootCACert) { if (!_inSystemVM) { return; } @@ -2076,6 +2102,9 @@ private void configureSSL(String prvkeyPath, String prvCertPath, String certChai if (certChainPath != null) { command.add("-t", certChainPath); } + if (rootCACert != null) { + command.add("-u", rootCACert); + } String result = command.execute(); if (result != null) { s_logger.warn("Unable to configure httpd to use ssl"); diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/UploadManager.java b/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/UploadManager.java index be99fea79f..81168b8388 100755 --- a/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/UploadManager.java +++ b/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/UploadManager.java @@ -16,11 +16,11 @@ // under the License. package org.apache.cloudstack.storage.template; +import com.cloud.agent.api.Answer; import org.apache.cloudstack.storage.resource.SecondaryStorageResource; import com.cloud.agent.api.storage.CreateEntityDownloadURLAnswer; import com.cloud.agent.api.storage.CreateEntityDownloadURLCommand; -import com.cloud.agent.api.storage.DeleteEntityDownloadURLAnswer; import com.cloud.agent.api.storage.DeleteEntityDownloadURLCommand; import com.cloud.agent.api.storage.UploadAnswer; import com.cloud.agent.api.storage.UploadCommand; @@ -77,6 +77,6 @@ String uploadPublicTemplate(long id, String url, String name, ImageFormat format CreateEntityDownloadURLAnswer handleCreateEntityURLCommand(CreateEntityDownloadURLCommand cmd); - DeleteEntityDownloadURLAnswer handleDeleteEntityDownloadURLCommand(DeleteEntityDownloadURLCommand cmd); + Answer handleDeleteEntityDownloadURLCommand(DeleteEntityDownloadURLCommand cmd); } diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/UploadManagerImpl.java b/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/UploadManagerImpl.java index cdbc52dec5..a8ed9a84d9 100755 --- a/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/UploadManagerImpl.java +++ b/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/UploadManagerImpl.java @@ -29,13 +29,13 @@ import javax.naming.ConfigurationException; +import com.cloud.agent.api.Answer; import org.apache.log4j.Logger; import org.apache.cloudstack.storage.resource.SecondaryStorageResource; import com.cloud.agent.api.storage.CreateEntityDownloadURLAnswer; import com.cloud.agent.api.storage.CreateEntityDownloadURLCommand; -import com.cloud.agent.api.storage.DeleteEntityDownloadURLAnswer; import com.cloud.agent.api.storage.DeleteEntityDownloadURLCommand; import com.cloud.agent.api.storage.UploadAnswer; import com.cloud.agent.api.storage.UploadCommand; @@ -303,7 +303,7 @@ public CreateEntityDownloadURLAnswer handleCreateEntityURLCommand(CreateEntityDo } @Override - public DeleteEntityDownloadURLAnswer handleDeleteEntityDownloadURLCommand(DeleteEntityDownloadURLCommand cmd) { + public Answer handleDeleteEntityDownloadURLCommand(DeleteEntityDownloadURLCommand cmd) { //Delete the soft link. Example path = volumes/8/74eeb2c6-8ab1-4357-841f-2e9d06d1f360.vhd s_logger.warn("handleDeleteEntityDownloadURLCommand Path:" + cmd.getPath() + " Type:" + cmd.getType().toString()); @@ -316,26 +316,26 @@ public DeleteEntityDownloadURLAnswer handleDeleteEntityDownloadURLCommand(Delete command.add("unlink /var/www/html/userdata/" + extractUrl.substring(extractUrl.lastIndexOf(File.separator) + 1)); String result = command.execute(); if (result != null) { - String errorString = "Error in deleting =" + result; - s_logger.warn(errorString); - return new DeleteEntityDownloadURLAnswer(errorString, CreateEntityDownloadURLAnswer.RESULT_FAILURE); + // FIXME - Ideally should bail out if you cant delete symlink. Not doing it right now. + // This is because the ssvm might already be destroyed and the symlinks do not exist. + s_logger.warn("Error in deleting symlink :" + result); } // If its a volume also delete the Hard link since it was created only for the purpose of download. if (cmd.getType() == Upload.Type.VOLUME) { command = new Script("/bin/bash", s_logger); command.add("-c"); - command.add("rm -f /mnt/SecStorage/" + cmd.getParentPath() + File.separator + path); + command.add("rm -rf /mnt/SecStorage/" + cmd.getParentPath() + File.separator + path); s_logger.warn(" " + parentDir + File.separator + path); result = command.execute(); if (result != null) { - String errorString = "Error in linking err=" + result; + String errorString = "Error in deleting volume " + path + " : " + result; s_logger.warn(errorString); - return new DeleteEntityDownloadURLAnswer(errorString, CreateEntityDownloadURLAnswer.RESULT_FAILURE); + return new Answer(cmd, false, errorString); } } - return new DeleteEntityDownloadURLAnswer("", CreateEntityDownloadURLAnswer.RESULT_SUCCESS); + return new Answer(cmd, true, ""); } private String getInstallPath(String jobId) { diff --git a/setup/bindir/cloud-setup-baremetal.in b/setup/bindir/cloud-setup-baremetal.in new file mode 100644 index 0000000000..367e38943e --- /dev/null +++ b/setup/bindir/cloud-setup-baremetal.in @@ -0,0 +1,232 @@ +#!/usr/bin/python +# 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 sys, os +from subprocess import PIPE, Popen +import logging +import traceback +from os.path import exists, join +from signal import alarm, signal, SIGALRM, SIGKILL + +class CloudRuntimeException(Exception): + def __init__(self, errMsg): + self.errMsg = errMsg + def __str__(self): + return self.errMsg +def formatExceptionInfo(maxTBlevel=5): + cla, exc, trbk = sys.exc_info() + excTb = traceback.format_tb(trbk, maxTBlevel) + msg = str(exc) + "\n" + for tb in excTb: + msg += tb + return msg + +class bash: + def __init__(self, args, timeout=600): + self.args = args + logging.debug("execute:%s"%args) + self.timeout = timeout + self.process = None + self.success = False + self.run() + + def run(self): + class Alarm(Exception): + pass + def alarm_handler(signum, frame): + raise Alarm + + try: + self.process = Popen(self.args, shell=True, stdout=PIPE, stderr=PIPE) + if self.timeout != -1: + signal(SIGALRM, alarm_handler) + alarm(self.timeout) + + try: + self.stdout, self.stderr = self.process.communicate() + if self.timeout != -1: + alarm(0) + except Alarm: + os.kill(self.process.pid, SIGKILL) + raise CloudRuntimeException("Timeout during command execution") + + self.success = self.process.returncode == 0 + except: + raise CloudRuntimeException(formatExceptionInfo()) + +# if not self.success: +# raise CloudRuntimeException(self.getStderr()) + + def isSuccess(self): + return self.success + + def getStdout(self): + return self.stdout.strip("\n") + + def getLines(self): + return self.stdout.split("\n") + + def getStderr(self): + return self.stderr.strip("\n") + + +def initLoging(logFile=None): + try: + if logFile is None: + logging.basicConfig(level=logging.DEBUG) + else: + logging.basicConfig(filename=logFile, level=logging.DEBUG) + except: + logging.basicConfig(level=logging.DEBUG) + +def writeProgressBar(msg, result=None): + if msg is not None: + output = "%-80s"%msg + elif result is True: + output = "[ \033[92m%-2s\033[0m ]\n"%"OK" + elif result is False: + output = "[ \033[91m%-6s\033[0m ]\n"%"FAILED" + sys.stdout.write(output) + sys.stdout.flush() + +def printError(msg): + sys.stderr.write(msg) + sys.stderr.write("\n") + sys.stderr.flush() + +def printMsg(msg): + sys.stdout.write(msg+"\n") + sys.stdout.flush() + +def checkRpm(pkgName): + chkPkg = bash("rpm -q %s"%pkgName) + writeProgressBar("Checking %s"%pkgName, None) + if not chkPkg.isSuccess(): + writeProgressBar(None, False) + printError("%s is not found, please make sure it is installed. You may try 'yum install %s'\n"%(pkgName, pkgName)) + return False + else: + writeProgressBar(None, True) + return True + +def checkEnv(): + writeProgressBar("Checking is root") + ret = bash("whoami") + if ret.getStdout() != "root": + writeProgressBar(None, False) + printError("This script must run as root") + return False + else: + writeProgressBar(None, True) + + pkgList = ['tftp-server', 'syslinux', 'xinetd', 'chkconfig', 'dhcp'] + for pkg in pkgList: + if not checkRpm(pkg): + return False + return True + +def exitIfFail(ret): + if not ret: sys.exit(1) + +def bashWithResult(cmd): + writeProgressBar("Executing '%s'"%cmd) + ret = bash(cmd) + if not ret.isSuccess(): + writeProgressBar(None, False) + writeProgressBar(ret.getStderr() + '\n') + return False + else: + writeProgressBar(None, True) + return True + +def configurePxeStuff(): + stuff = ['tftp', 'xinetd', 'dhcpd'] + cmds = ['chkconfig --level 345 %s on' % i for i in stuff] + cmds.append('/etc/init.d/xinetd restart') + + for cmd in cmds: + if not bashWithResult(cmd): return False + + chkIptable = bash('chkconfig --list iptables') + if 'on' in chkIptable.getStdout(): + printMsg("Detected iptables is running, need to open tftp port 69") + if not bashWithResult('iptables -I INPUT 1 -p udp --dport 69 -j ACCEPT'): return False + if not bashWithResult('/etc/init.d/iptables save'): return False + + return True + +def getTftpRootDir(tftpRootDirList): + tftpRoot = bash("cat /etc/xinetd.d/tftp | grep server_args") + if not tftpRoot.isSuccess(): + printError("Cannot get tftp root directory from /etc/xinetd.d/tftp, here may be something wrong with your tftp-server, try reinstall it\n") + return False + tftpRootDir = tftpRoot.getStdout() + index = tftpRootDir.find("/") + if index == -1: + printError("Wrong server_arg in /etc/xinetd.d/tftp (%s)"%tftpRootDir) + return False + tftpRootDir = tftpRootDir[index:] + tftpRootDirList.append(tftpRootDir) + return True + +def preparePING(tftpRootDir): + pingFiles = ['boot.msg', 'initrd.gz', 'kernel', 'pxelinux.0'] + pingDir = "/usr/share/PING" + + for f in pingFiles: + path = join(pingDir, f) + if not exists(path): + printError("Cannot find %s, please make sure PING-3.01 is installed"%path) + return False + if not bashWithResult("cp -f %s %s"%(path, tftpRootDir)): return False + + if not bashWithResult("mkdir -p %s/pxelinux.cfg"%tftpRootDir): return False + + return True + +def prepareSyslinux(tftpRootDir): + pkg = bash('rpm -ql syslinux | grep "/pxelinux.0$"') + if not pkg.isSuccess(): + printError('cannot find pxelinux.0 on system. is syslinux installed?') + return False + + pkg = pkg.getStdout() + cp = "cp -f %s %s" % (pkg, tftpRootDir) + if not bashWithResult(cp): + return False + + return True + + + +if __name__ == "__main__": + initLoging("/tmp/cloud-setup-baremetal.log") + tftpRootDirList = [] + + exitIfFail(checkEnv()) + exitIfFail(configurePxeStuff()) + exitIfFail(getTftpRootDir(tftpRootDirList)) + + tftpRootDir = tftpRootDirList[0].strip() + #exitIfFail(preparePING(tftpRootDir)) + exitIfFail(prepareSyslinux(tftpRootDir)) + printMsg("") + printMsg("Setup BareMetal PXE server successfully") + printMsg("TFTP root directory is: %s\n"%tftpRootDir) + sys.exit(0) + diff --git a/setup/bindir/cloud-sysvmadm.in b/setup/bindir/cloud-sysvmadm.in index e2a626ef92..4c67c31085 100755 --- a/setup/bindir/cloud-sysvmadm.in +++ b/setup/bindir/cloud-sysvmadm.in @@ -7,9 +7,9 @@ # 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 @@ -75,7 +75,7 @@ do esac done - + stop_start_system() { @@ -86,46 +86,46 @@ length_console=(${#console[@]}) echo -e "\nStopping and starting $length_secondary secondary storage vm(s)$inzone..." -echo -e "Stopping and starting $length_secondary secondary storage vm(s)$inzone..." >>$LOGFILE +echo -e "[$(date "+%Y.%m.%d-%H.%M.%S")] Stopping and starting $length_secondary secondary storage vm(s)$inzone..." >>$LOGFILE for d in "${secondary[@]}"; do - echo "INFO: Stopping secondary storage vm with id $d" >>$LOGFILE + echo "[$(date "+%Y.%m.%d-%H.%M.%S")] INFO: Stopping secondary storage vm with id $d" >>$LOGFILE jobresult=$(send_request stopSystemVm $d) if [ "$jobresult" != "1" ]; then echo -e "ERROR: Failed to stop secondary storage vm with id $d \n" - echo "ERROR: Failed to stop secondary storage vm with id $d" >>$LOGFILE - else - echo "INFO: Starting secondary storage vm with id $d" >>$LOGFILE + echo "[$(date "+%Y.%m.%d-%H.%M.%S")] ERROR: Failed to stop secondary storage vm with id $d" >>$LOGFILE + else + echo "[$(date "+%Y.%m.%d-%H.%M.%S")] INFO: Starting secondary storage vm with id $d" >>$LOGFILE jobresult=$(send_request startSystemVm $d SSVM) if [ "$jobresult" != "1" ]; then - echo "ERROR: Failed to start secondary storage vm with id $d" >>$LOGFILE - echo "ERROR: Failed to start secondary storage vm with id $d" >>$LOGFILE + echo "[$(date "+%Y.%m.%d-%H.%M.%S")] ERROR: Failed to start secondary storage vm with id $d" >>$LOGFILE + echo "[$(date "+%Y.%m.%d-%H.%M.%S")] ERROR: Failed to start secondary storage vm with id $d" >>$LOGFILE fi fi done if [ "$length_secondary" == "0" ];then echo -e "No running secondary storage vms found \n" -else +else echo -e "Done stopping and starting secondary storage vm(s)$inzone" - echo -e "Done stopping and starting secondary storage vm(s)$inzone." >>$LOGFILE + echo -e "[$(date "+%Y.%m.%d-%H.%M.%S")] Done stopping and starting secondary storage vm(s)$inzone." >>$LOGFILE fi echo -e "\nStopping and starting $length_console console proxy vm(s)$inzone..." -echo -e "Stopping and starting $length_console console proxy vm(s)$inzone..." >>$LOGFILE +echo -e "[$(date "+%Y.%m.%d-%H.%M.%S")] Stopping and starting $length_console console proxy vm(s)$inzone..." >>$LOGFILE for d in "${console[@]}"; do - echo "INFO: Stopping console proxy with id $d" >>$LOGFILE + echo "[$(date "+%Y.%m.%d-%H.%M.%S")] INFO: Stopping console proxy with id $d" >>$LOGFILE jobresult=$(send_request stopSystemVm $d) if [ "$jobresult" != "1" ]; then echo -e "ERROR: Failed to stop console proxy vm with id $d \n" - echo "ERROR: Failed to stop console proxy vm with id $d" >>$LOGFILE - else - echo "INFO: Starting console proxy vm with id $d" >>$LOGFILE + echo "[$(date "+%Y.%m.%d-%H.%M.%S")] ERROR: Failed to stop console proxy vm with id $d" >>$LOGFILE + else + echo "[$(date "+%Y.%m.%d-%H.%M.%S")] INFO: Starting console proxy vm with id $d" >>$LOGFILE jobresult=$(send_request startSystemVm $d consoleProxy) if [ "$jobresult" != "1" ]; then echo -e "ERROR: Failed to start console proxy vm with id $d \n" - echo "ERROR: Failed to start console proxy vm with id $d" >>$LOGFILE + echo "[$(date "+%Y.%m.%d-%H.%M.%S")] ERROR: Failed to start console proxy vm with id $d" >>$LOGFILE fi fi done @@ -134,33 +134,33 @@ if [ "$length_console" == "0" ];then echo -e "No running console proxy vms found \n" else echo "Done stopping and starting console proxy vm(s) $inzone." - echo "Done stopping and starting console proxy vm(s) $inzone." >>$LOGFILE + echo "[$(date "+%Y.%m.%d-%H.%M.%S")] Done stopping and starting console proxy vm(s) $inzone." >>$LOGFILE fi } stop_start_router() { router=(`mysql -h $db --user=$user --password=$password --skip-column-names -U cloud -e "select id from vm_instance where state=\"Running\" and type=\"DomainRouter\"$zone"`) length_router=(${#router[@]}) - + echo -e "\nStopping and starting $length_router running routing vm(s)$inzone... " - echo -e "Stopping and starting $length_router running routing vm(s)$inzone... " >>$LOGFILE - + echo -e "[$(date "+%Y.%m.%d-%H.%M.%S")] Stopping and starting $length_router running routing vm(s)$inzone... " >>$LOGFILE + #Spawn reboot router in parallel - run commands in chunks - number of threads is configurable pids=() for d in "${router[@]}"; do - + reboot_router $d & pids=( "${pids[@]}" $! ) - + length_pids=(${#pids[@]}) unfinishedPids=(${#pids[@]}) - + if [ $maxthreads -gt $length_router ]; then maxthreads=$length_router fi - + if [ $length_pids -ge $maxthreads ]; then while [ $unfinishedPids -gt 0 ]; do sleep 10 @@ -170,33 +170,33 @@ stop_start_router() { count=`expr $count + 1` fi done - + if [ $count -eq $unfinishedPids ]; then unfinishedPids=0 fi - + done - + #remove all elements from pids if [ $unfinishedPids -eq 0 ]; then pids=() length_pids=(${#pids[@]}) fi - + fi - + done - + if [ "$length_router" == "0" ];then - echo -e "No running router vms found \n" >>$LOGFILE - else + echo -e "[$(date "+%Y.%m.%d-%H.%M.%S")] No running router vms found \n" >>$LOGFILE + else while [ $unfinishedPids -gt 0 ]; do sleep 10 done - + echo -e "Done restarting router(s)$inzone. \n" - echo -e "Done restarting router(s)$inzone. \n" >>$LOGFILE - + echo -e "[$(date "+%Y.%m.%d-%H.%M.%S")] Done restarting router(s)$inzone. \n" >>$LOGFILE + fi } @@ -212,56 +212,60 @@ send_request(){ return fi jobresult=$(query_async_job_result $jobid) + if [ "$jobresult" != "1" ]; then + echo -e "ERROR: Failed to $1 id=$2; jobId is $jobid \n" + echo "[$(date "+%Y.%m.%d-%H.%M.%S")] ERROR: Failed to $1 id=$2; jobId is $jobid" >>$LOGFILE + fi echo $jobresult } reboot_router(){ - echo "INFO: Restarting router with id $1" >>$LOGFILE + echo "[$(date "+%Y.%m.%d-%H.%M.%S")] INFO: Restarting router with id $1" >>$LOGFILE jobid=`curl -sS "http://$ms:8096/?command=rebootRouter&id=$1&response=json" | sed 's/\"//g' | sed 's/ //g' | sed 's/{//g' | sed 's/}//g' | awk -F: {'print $3'}` if [ "$jobid" == "" ]; then - echo "ERROR: Failed to restart domainRouter with id $1" >>$LOGFILE + echo "[$(date "+%Y.%m.%d-%H.%M.%S")] ERROR: Failed to restart domainRouter with id $1; unable to submit the job" >>$LOGFILE echo 2 return fi - + jobresult=$(query_async_job_result $jobid) - + if [ "$jobresult" != "1" ]; then echo -e "ERROR: Failed to restart domainRouter with id $1 \n" - echo "ERROR: Failed to restart domainRouter with id $1" >>$LOGFILE + echo "[$(date "+%Y.%m.%d-%H.%M.%S")] ERROR: Failed to restart domainRouter with id $1; jobId $jobid" >>$LOGFILE exit 0 else - echo "INFO: Successfully restarted domainRouter with id $1" >>$LOGFILE + echo "[$(date "+%Y.%m.%d-%H.%M.%S")] INFO: Successfully restarted domainRouter with id $1; jobId $jobid" >>$LOGFILE exit 0 fi - + } restart_networks(){ - networks=(`mysql -h $db --user=$user --password=$password --skip-column-names -U cloud -e "select n.id + networks=(`mysql -h $db --user=$user --password=$password --skip-column-names -U cloud -e "select n.id from networks n, network_offerings no where n.network_offering_id = no.id and no.system_only = 0 and n.removed is null$zone"`) length_networks=(${#networks[@]}) - + echo -e "\nRestarting $length_networks networks$inzone... " - echo -e "Restarting $length_networks networks$inzone... " >>$LOGFILE - + echo -e "[$(date "+%Y.%m.%d-%H.%M.%S")] Restarting $length_networks networks$inzone... " >>$LOGFILE + #Spawn restart network in parallel - run commands in chunks - number of threads is configurable pids=() for d in "${networks[@]}"; do - + restart_network $d & pids=( "${pids[@]}" $! ) - + length_pids=(${#pids[@]}) unfinishedPids=(${#pids[@]}) - + if [ $maxthreads -gt $length_networks ]; then maxthreads=$length_networks fi - + if [ $length_pids -ge $maxthreads ]; then while [ $unfinishedPids -gt 0 ]; do sleep 10 @@ -271,74 +275,74 @@ restart_networks(){ count=`expr $count + 1` fi done - + if [ $count -eq $unfinishedPids ]; then unfinishedPids=0 fi - + done - + #remove all elements from pids if [ $unfinishedPids -eq 0 ]; then pids=() length_pids=(${#pids[@]}) fi - + fi - + done - + if [ "$length_networks" == "0" ];then - echo -e "No networks found \n" >>$LOGFILE - else + echo -e "[$(date "+%Y.%m.%d-%H.%M.%S")] No networks found \n" >>$LOGFILE + else while [ $unfinishedPids -gt 0 ]; do sleep 10 done - + echo -e "Done restarting networks$inzone. \n" - echo -e "Done restarting networks$inzone. \n" >>$LOGFILE - + echo -e "[$(date "+%Y.%m.%d-%H.%M.%S")] Done restarting networks$inzone. \n" >>$LOGFILE + fi } restart_network(){ jobid=`curl -sS "http://$ms:8096/?command=restartNetwork&id=$1&response=json" | sed 's/\"//g' | sed 's/ //g' | sed 's/{//g' | sed 's/}//g' | awk -F: {'print $3'}` if [ "$jobid" == "" ]; then - echo "ERROR: Failed to restart network with id $1" >>$LOGFILE + echo "[$(date "+%Y.%m.%d-%H.%M.%S")] ERROR: Failed to restart network with id $1; unable to submit the job" >>$LOGFILE echo 2 return fi - + jobresult=$(query_async_job_result $jobid) - + if [ "$jobresult" != "1" ]; then - echo "ERROR: Failed to restart network with id $1" >>$LOGFILE + echo "[$(date "+%Y.%m.%d-%H.%M.%S")] ERROR: Failed to restart network with id $1; jobId $jobid" >>$LOGFILE else - echo "INFO: Successfully restarted network with id $1" >>$LOGFILE + echo "[$(date "+%Y.%m.%d-%H.%M.%S")] INFO: Successfully restarted network with id $1; jobId $jobid" >>$LOGFILE fi - + } restart_vpc(){ echo -e "INFO: Restarting vpc with id $1" - echo "INFO: Restarting vpc with id $1" >>$LOGFILE + echo "[$(date "+%Y.%m.%d-%H.%M.%S")] INFO: Restarting vpc with id $1" >>$LOGFILE jobid=`curl -sS "http://$ms:8096/?command=restartVPC&id=$1&response=json" | sed 's/\"//g' | sed 's/ //g' | sed 's/{//g' | sed 's/}//g' | awk -F: {'print $3'}` if [ "$jobid" == "" ]; then - echo "ERROR: Failed to restart vpc with id $1" >>$LOGFILE + echo "[$(date "+%Y.%m.%d-%H.%M.%S")] ERROR: Failed to restart vpc with id $1; unable to submit the job" >>$LOGFILE echo 2 return fi - + jobresult=$(query_async_job_result $jobid) - + if [ "$jobresult" != "1" ]; then echo -e "ERROR: Failed to restart vpc with id $1 \n" - echo "ERROR: Failed to restart vpc with id $1" >>$LOGFILE + echo "[$(date "+%Y.%m.%d-%H.%M.%S")] ERROR: Failed to restart vpc with id $1; jobId $jobid" >>$LOGFILE else echo -e "INFO: Successfully restarted vpc with id $1 \n" - echo "INFO: Successfully restarted vpc with id $1" >>$LOGFILE + echo "[$(date "+%Y.%m.%d-%H.%M.%S")] INFO: Successfully restarted vpc with id $1; jobId $jobid" >>$LOGFILE fi } @@ -346,26 +350,26 @@ restart_vpc(){ restart_vpcs(){ vpcs=(`mysql -h $db --user=$user --password=$password --skip-column-names -U cloud -e "select id from vpc WHERE removed is null$zone"`) length_vpcs=(${#vpcs[@]}) - + echo -e "\nRestarting $length_vpcs vpcs... " - echo -e "Restarting $length_vpcs vpcs... " >>$LOGFILE - + echo -e "[$(date "+%Y.%m.%d-%H.%M.%S")] Restarting $length_vpcs vpcs... " >>$LOGFILE + #Spawn restart vpcs in parallel - run commands in chunks - number of threads is configurable pids=() for d in "${vpcs[@]}"; do - + restart_vpc $d & pids=( "${pids[@]}" $! ) - + length_pids=(${#pids[@]}) unfinishedPids=(${#pids[@]}) - + if [ $maxthreads -gt $length_vpcs ]; then maxthreads=$length_vpcs fi - + if [ $length_pids -ge $maxthreads ]; then while [ $unfinishedPids -gt 0 ]; do sleep 10 @@ -375,34 +379,34 @@ restart_vpcs(){ count=`expr $count + 1` fi done - + if [ $count -eq $unfinishedPids ]; then unfinishedPids=0 fi - + done - + #remove all elements from pids if [ $unfinishedPids -eq 0 ]; then pids=() length_pids=(${#pids[@]}) fi - + fi - + done - + if [ "$length_vpcs" == "0" ];then - echo -e "No vpcs found \n" >>$LOGFILE - else + echo -e "[$(date "+%Y.%m.%d-%H.%M.%S")] No vpcs found \n" >>$LOGFILE + else while [ $unfinishedPids -gt 0 ]; do sleep 10 done - + echo -e "Done restarting vpcs$inzone. \n" - echo -e "Done restarting vpcs$inzone. \n" >>$LOGFILE - + echo -e "[$(date "+%Y.%m.%d-%H.%M.%S")] Done restarting vpcs$inzone. \n" >>$LOGFILE + fi } diff --git a/setup/db/create-schema-simulator.sql b/setup/db/create-schema-simulator.sql index facfefc5e7..d33596ebdb 100644 --- a/setup/db/create-schema-simulator.sql +++ b/setup/db/create-schema-simulator.sql @@ -106,7 +106,10 @@ CREATE TABLE `simulator`.`mockconfiguration` ( `cluster_id` bigint unsigned, `host_id` bigint unsigned, `name` varchar(255), - `values` varchar(4095), + `values` varchar(4096), + `count` int, + `json_response` varchar(4096), + `removed` datetime, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; diff --git a/setup/db/db/schema-40to410.sql b/setup/db/db/schema-40to410.sql index 65fb350bf1..53b4a1a5b8 100644 --- a/setup/db/db/schema-40to410.sql +++ b/setup/db/db/schema-40to410.sql @@ -367,7 +367,6 @@ CREATE TABLE `cloud`.`autoscale_vmgroups` ( `max_members` int unsigned NOT NULL, `member_port` int unsigned NOT NULL, `interval` int unsigned NOT NULL, - `last_interval` datetime DEFAULT NULL, `profile_id` bigint unsigned NOT NULL, `state` varchar(255) NOT NULL COMMENT 'enabled or disabled, a vmgroup is disabled to stop autoscaling activity', `created` datetime NOT NULL COMMENT 'date created', diff --git a/setup/db/db/schema-420to421.sql b/setup/db/db/schema-420to421.sql index 42e9c1e1ec..78687f22fe 100644 --- a/setup/db/db/schema-420to421.sql +++ b/setup/db/db/schema-420to421.sql @@ -24,7 +24,8 @@ INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'manag 'The maximum size limit for S3 single part upload API(in GB). If it is set to 0, then it means always use multi-part upload to upload object to S3. If it is set to -1, then it means always use single-part upload to upload object to S3.'); INSERT IGNORE INTO `cloud`.`configuration` VALUES ("Storage", 'DEFAULT', 'management-server', "enable.ha.storage.migration", "true", "Enable/disable storage migration across primary storage during HA"); - +UPDATE `cloud`.`configuration` SET description="Specify whether or not to reserve CPU based on CPU overprovisioning factor" where name="vmware.reserve.cpu"; +UPDATE `cloud`.`configuration` SET description="Specify whether or not to reserve memory based on memory overprovisioning factor" where name="vmware.reserve.mem"; -- Remove Windows Server 8 from guest_os_type dropdown to use Windows Server 2012 DELETE FROM `cloud`.`guest_os_hypervisor` where guest_os_id=168; DELETE FROM `cloud`.`guest_os` where id=168; diff --git a/setup/db/db/schema-430to440-cleanup.sql b/setup/db/db/schema-430to440-cleanup.sql index 30df9782f6..8b1eec406c 100644 --- a/setup/db/db/schema-430to440-cleanup.sql +++ b/setup/db/db/schema-430to440-cleanup.sql @@ -19,4 +19,4 @@ -- Schema cleanup from 4.3.0 to 4.4.0; --; - +ALTER TABLE `cloud`.`network_acl_item` DROP COLUMN `cidr`; diff --git a/setup/db/db/schema-430to440.sql b/setup/db/db/schema-430to440.sql index 5c5511ac5f..8ab2ffba0a 100644 --- a/setup/db/db/schema-430to440.sql +++ b/setup/db/db/schema-430to440.sql @@ -128,9 +128,9 @@ CREATE VIEW `cloud`.`volume_view` AS volumes.attached, volumes.removed, volumes.pod_id, - volumes.display_volume, + volumes.display_volume, volumes.format, - volumes.path, + volumes.path, volumes.chain_info, account.id account_id, account.uuid account_uuid, @@ -146,7 +146,7 @@ CREATE VIEW `cloud`.`volume_view` AS data_center.id data_center_id, data_center.uuid data_center_uuid, data_center.name data_center_name, - data_center.networktype data_center_type, + data_center.networktype data_center_type, vm_instance.id vm_id, vm_instance.uuid vm_uuid, vm_instance.name vm_name, @@ -177,6 +177,12 @@ CREATE VIEW `cloud`.`volume_view` AS vm_template.uuid template_uuid, vm_template.extractable, vm_template.type template_type, + vm_template.name template_name, + vm_template.display_text template_display_text, + iso.id iso_id, + iso.uuid iso_uuid, + iso.name iso_name, + iso.display_text iso_display_text, resource_tags.id tag_id, resource_tags.uuid tag_uuid, resource_tags.key tag_key, @@ -214,7 +220,9 @@ CREATE VIEW `cloud`.`volume_view` AS left join `cloud`.`cluster` ON storage_pool.cluster_id = cluster.id left join - `cloud`.`vm_template` ON volumes.template_id = vm_template.id OR volumes.iso_id = vm_template.id + `cloud`.`vm_template` ON volumes.template_id = vm_template.id + left join + `cloud`.`vm_template` iso ON iso.id = volumes.iso_id left join `cloud`.`resource_tags` ON resource_tags.resource_id = volumes.id and resource_tags.resource_type = 'Volume' @@ -453,20 +461,25 @@ CREATE VIEW `cloud`.`user_vm_view` AS left join `cloud`.`user_vm_details` `custom_ram_size` ON (((`custom_ram_size`.`vm_id` = `cloud`.`vm_instance`.`id`) and (`custom_ram_size`.`name` = 'memory'))); --- ACL DB schema +ALTER TABLE `cloud_usage`.`cloud_usage` ADD COLUMN `cpu_speed` INT(10) UNSIGNED NULL COMMENT 'speed per core in Mhz', + ADD COLUMN `cpu_cores` INT(10) UNSIGNED NULL COMMENT 'number of cpu cores', + ADD COLUMN `memory` INT(10) UNSIGNED NULL COMMENT 'memory in MB'; + + +-- ACL DB schema CREATE TABLE `cloud`.`iam_group` ( `id` bigint unsigned NOT NULL UNIQUE auto_increment, `name` varchar(255) NOT NULL, `description` varchar(255) default NULL, `uuid` varchar(40), - `path` varchar(255) NOT NULL, + `path` varchar(255) NOT NULL, `account_id` bigint unsigned NOT NULL, `view` varchar(40) default 'User' COMMENT 'response review this group account should see for result', `removed` datetime COMMENT 'date the group was removed', `created` datetime COMMENT 'date the group was created', PRIMARY KEY (`id`), INDEX `i_iam_group__removed`(`removed`), - CONSTRAINT `uc_iam_group__uuid` UNIQUE (`uuid`) + CONSTRAINT `uc_iam_group__uuid` UNIQUE (`uuid`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; CREATE TABLE `cloud`.`iam_group_account_map` ( @@ -474,11 +487,11 @@ CREATE TABLE `cloud`.`iam_group_account_map` ( `group_id` bigint unsigned NOT NULL, `account_id` bigint unsigned NOT NULL, `removed` datetime COMMENT 'date the account was removed from the group', - `created` datetime COMMENT 'date the account was assigned to the group', + `created` datetime COMMENT 'date the account was assigned to the group', PRIMARY KEY (`id`), CONSTRAINT `fk_iam_group_vm_map__group_id` FOREIGN KEY(`group_id`) REFERENCES `iam_group` (`id`) ON DELETE CASCADE, CONSTRAINT `fk_iam_group_vm_map__account_id` FOREIGN KEY(`account_id`) REFERENCES `account` (`id`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8; +) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE `cloud`.`iam_policy` ( @@ -487,7 +500,7 @@ CREATE TABLE `cloud`.`iam_policy` ( `description` varchar(255) DEFAULT NULL, `uuid` varchar(40) DEFAULT NULL, `path` varchar(255) NOT NULL, - `account_id` bigint unsigned NOT NULL, + `account_id` bigint unsigned NOT NULL, `removed` datetime DEFAULT NULL COMMENT 'date the role was removed', `created` datetime DEFAULT NULL COMMENT 'date the role was created', `policy_type` varchar(64) DEFAULT 'Static' COMMENT 'Static or Dynamic', @@ -649,6 +662,7 @@ ALTER TABLE `cloud`.`vpc` ADD COLUMN `display` tinyint(1) NOT NULL DEFAULT '1' C ALTER TABLE `cloud`.`firewall_rules` ADD COLUMN `display` tinyint(1) NOT NULL DEFAULT '1' COMMENT 'True if the rule can be displayed to the end user'; ALTER TABLE `cloud`.`autoscale_vmgroups` ADD COLUMN `display` tinyint(1) NOT NULL DEFAULT '1' COMMENT 'True if the entry can be displayed to the end user'; ALTER TABLE `cloud`.`autoscale_vmprofiles` ADD COLUMN `display` tinyint(1) NOT NULL DEFAULT '1' COMMENT 'True if the entry can be displayed to the end user'; +ALTER TABLE `cloud`.`autoscale_vmgroups` ADD COLUMN `last_interval` datetime NULL DEFAULT NULL COMMENT 'last updated time'; ALTER TABLE `cloud`.`network_acl_item` ADD COLUMN `display` tinyint(1) NOT NULL DEFAULT '1' COMMENT 'True if the entry can be displayed to the end user'; ALTER TABLE `cloud`.`network_acl` ADD COLUMN `display` tinyint(1) NOT NULL DEFAULT '1' COMMENT 'True if the entry can be displayed to the end user'; ALTER TABLE `cloud`.`remote_access_vpn` ADD COLUMN `display` tinyint(1) NOT NULL DEFAULT '1' COMMENT 'True if the entry can be displayed to the end user'; @@ -658,13 +672,27 @@ ALTER TABLE `cloud`.`s2s_vpn_gateway` ADD COLUMN `display` tinyint(1) NOT NULL D INSERT IGNORE INTO `cloud`.`guest_os` (id, uuid, category_id, display_name) VALUES (225, UUID(), 9, 'FreeBSD 10 (32-bit)'); INSERT IGNORE INTO `cloud`.`guest_os` (id, uuid, category_id, display_name) VALUES (226, UUID(), 9, 'FreeBSD 10 (64-bit)'); +INSERT IGNORE INTO `cloud`.`guest_os` (id, uuid, category_id, display_name) VALUES (227, UUID(), 1, 'CentOS 6.5 (32-bit)'); +INSERT IGNORE INTO `cloud`.`guest_os` (id, uuid, category_id, display_name) VALUES (228, UUID(), 1, 'CentOS 6.5 (64-bit)'); +INSERT IGNORE INTO `cloud`.`guest_os` (id, uuid, category_id, display_name) VALUES (229, UUID(), 6, 'Windows 8.1 (64-bit)'); +INSERT IGNORE INTO `cloud`.`guest_os` (id, uuid, category_id, display_name) VALUES (230, UUID(), 6, 'Windows 8.1 (32-bit)'); + +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'Windows 8.1 (64-bit)', 229); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Windows 8.1 (64-bit)', 229); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'Windows 8.1 (32-bit)', 230); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Windows 8.1 (32-bit)', 230); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'CentOS 6.5 (32-bit)', 227); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'CentOS 6.5 (32-bit)', 227); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'CentOS 6.5 (64-bit)', 228); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'CentOS 6.5 (64-bit)', 228); + CREATE TABLE `cloud`.`op_router_monitoring_services` ( `vm_id` bigint unsigned UNIQUE NOT NULL COMMENT 'Primary Key', `router_name` varchar(255) NOT NULL COMMENT 'Name of the Virtual Router', `last_alert_timestamp` varchar(255) NOT NULL COMMENT 'Timestamp of the last alert received from Virtual Router', PRIMARY KEY (`vm_id`), CONSTRAINT `fk_virtual_router__id` FOREIGN KEY `fk_virtual_router__id` (`vm_id`) REFERENCES `vm_instance`(`id`) ON DELETE CASCADE -) ENGINE = InnoDB DEFAULT CHARSET=utf8 +) ENGINE = InnoDB DEFAULT CHARSET=utf8; ALTER TABLE `cloud`.`event` ADD COLUMN `display` tinyint(1) NOT NULL DEFAULT '1' COMMENT 'True if the detail can be displayed to the end user'; @@ -724,7 +752,13 @@ CREATE TABLE `cloud`.`vgpu_types` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `gpu_group_id` bigint(20) unsigned NOT NULL, `vgpu_type` varchar(40) NOT NULL COMMENT 'vgpu type supported by this gpu group', - `remaining_vm_capacity` bigint(20) unsigned DEFAULT NULL COMMENT 'remaining vgpu can be created with this vgpu_type on the given gpu group', + `video_ram` bigint(20) unsigned DEFAULT NULL COMMENT 'video RAM for this vgpu type', + `max_heads` bigint(20) unsigned DEFAULT NULL COMMENT 'maximum displays per user', + `max_resolution_x` bigint(20) unsigned DEFAULT NULL COMMENT 'maximum X resolution per display', + `max_resolution_y` bigint(20) unsigned DEFAULT NULL COMMENT 'maximum Y resolution per display', + `max_vgpu_per_pgpu` bigint(20) unsigned DEFAULT NULL COMMENT 'max number of vgpus per physical gpu (pgpu)', + `remaining_capacity` bigint(20) unsigned DEFAULT NULL COMMENT 'remaining vgpu can be created with this vgpu_type on the given gpu group', + `max_capacity` bigint(20) unsigned DEFAULT NULL COMMENT 'maximum vgpu can be created with this vgpu_type on the given gpu group', PRIMARY KEY (`id`), CONSTRAINT `fk_vgpu_types__gpu_group_id` FOREIGN KEY (`gpu_group_id`) REFERENCES `host_gpu_groups` (`id`) ON DELETE CASCADE ) ENGINE=InnoDB CHARSET=utf8; @@ -734,14 +768,1687 @@ ALTER TABLE `cloud`.`guest_os_hypervisor` ADD COLUMN `uuid` varchar(40) COMMENT ALTER TABLE `cloud`.`guest_os_hypervisor` ADD CONSTRAINT `uc_guest_os_hypervisor__uuid` UNIQUE (`uuid`); ALTER TABLE `cloud`.`guest_os_hypervisor` ADD COLUMN `created` datetime COMMENT 'Time when mapping was created'; ALTER TABLE `cloud`.`guest_os_hypervisor` ADD COLUMN `removed` datetime COMMENT 'Time when mapping was removed if deleted, else NULL'; +ALTER TABLE `cloud`.`guest_os_hypervisor` ADD COLUMN `is_user_defined` INT(1) UNSIGNED DEFAULT 0 COMMENT 'True if this guest OS mapping was added by admin'; UPDATE `cloud`.`guest_os_hypervisor` SET `uuid` = UUID(); UPDATE `cloud`.`guest_os_hypervisor` SET `created` = now(); ALTER TABLE `cloud`.`guest_os` ADD COLUMN `created` datetime COMMENT 'Time when Guest OS was created in system'; ALTER TABLE `cloud`.`guest_os` ADD COLUMN `removed` datetime COMMENT 'Time when Guest OS was removed if deleted, else NULL'; UPDATE `cloud`.`guest_os` SET `created` = now(); +ALTER TABLE `cloud`.`guest_os` ADD COLUMN `is_user_defined` INT(1) UNSIGNED DEFAULT 0 COMMENT 'True if this guest OS type was added by admin'; ALTER TABLE `cloud`.`vm_reservation` ADD COLUMN `deployment_planner` varchar(40) DEFAULT NULL COMMENT 'Preferred deployment planner for the vm'; ALTER TABLE `cloud`.`vpc_offerings` ADD COLUMN supports_distributed_router boolean default false; ALTER TABLE `cloud`.`vpc` ADD COLUMN uses_distributed_router boolean default false; - INSERT INTO `cloud`.`storage_pool_details` (pool_id,name,value,display) SELECT storage_pool.id,data_center_details.name,data_center_details.value,data_center_details.display FROM `cloud`.`storage_pool` JOIN `cloud`.`data_center_details` ON data_center_details.dc_id=storage_pool.data_center_id WHERE data_center_details.name = "storage.overprovisioning.factor"; DELETE FROM `cloud`.`data_center_details` WHERE name="storage.overprovisioning.factor"; +ALTER TABLE `cloud`.`vpc_offerings` ADD COLUMN supports_region_level_vpc boolean default false; +ALTER TABLE `cloud`.`network_offerings` ADD COLUMN supports_streched_l2 boolean default false; +ALTER TABLE `cloud`.`networks` ADD COLUMN streched_l2 boolean default false; +ALTER TABLE `cloud`.`vpc` ADD COLUMN region_level_vpc boolean default false; +ALTER TABLE `cloud`.`load_balancer_vm_map` ADD COLUMN instance_ip VARCHAR(40); +ALTER TABLE `cloud`.`load_balancer_vm_map` DROP KEY `load_balancer_id`, ADD UNIQUE KEY load_balancer_id (`load_balancer_id`, `instance_id`, `instance_ip`); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'CentOS 4.5 (32-bit)', 1, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'CentOS 4.6 (32-bit)', 2, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'CentOS 4.7 (32-bit)', 3, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'CentOS 4.8 (32-bit)', 4, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'CentOS 5 (32-bit)', 5, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'CentOS 5 (64-bit)', 6, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'CentOS 5 (32-bit)', 7, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'CentOS 5 (64-bit)', 8, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'CentOS 5 (32-bit)', 9, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'CentOS 5 (64-bit)', 10, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'CentOS 5 (32-bit)', 11, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'CentOS 5 (64-bit)', 12, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'CentOS 5 (32-bit)', 13, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'CentOS 5 (64-bit)', 14, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'CentOS 5 (32-bit)', 111, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'CentOS 5 (64-bit)', 112, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'Debian Lenny 5.0 (32-bit)', 15, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'Debian Squeeze 6.0 (32-bit)', 132, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'Debian Squeeze 6.0 (64-bit) (experimental)', 133, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'Debian Squeeze 6.0 (32-bit)', 183, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'Debian Squeeze 6.0 (64-bit) (experimental)', 184, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'Oracle Enterprise Linux 5 (32-bit)', 16, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'Oracle Enterprise Linux 5 (64-bit)', 17, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'Oracle Enterprise Linux 5 (32-bit)', 18, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'Oracle Enterprise Linux 5 (64-bit)', 19, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'Oracle Enterprise Linux 5 (32-bit)', 20, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'Oracle Enterprise Linux 5 (64-bit)', 21, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'Oracle Enterprise Linux 5 (32-bit)', 22, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'Oracle Enterprise Linux 5 (64-bit)', 23, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'Oracle Enterprise Linux 5 (32-bit)', 24, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'Oracle Enterprise Linux 5 (64-bit)', 25, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'Oracle Enterprise Linux 5 (32-bit)', 134, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'Oracle Enterprise Linux 5 (64-bit)', 135, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'Red Hat Enterprise Linux 4.5 (32-bit)', 26, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'Red Hat Enterprise Linux 4.6 (32-bit)', 27, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'Red Hat Enterprise Linux 4.7 (32-bit)', 28, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'Red Hat Enterprise Linux 4.8 (32-bit)', 29, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'Red Hat Enterprise Linux 5 (32-bit)', 30, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'Red Hat Enterprise Linux 5 (64-bit)', 31, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'Red Hat Enterprise Linux 5 (32-bit)', 32, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'Red Hat Enterprise Linux 5 (64-bit)', 33, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'Red Hat Enterprise Linux 5 (32-bit)', 34, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'Red Hat Enterprise Linux 5 (64-bit)', 35, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'Red Hat Enterprise Linux 5 (32-bit)', 36, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'Red Hat Enterprise Linux 5 (64-bit)', 37, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'Red Hat Enterprise Linux 5 (32-bit)', 38, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'Red Hat Enterprise Linux 5 (64-bit)', 39, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'Red Hat Enterprise Linux 5 (32-bit)', 113, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'Red Hat Enterprise Linux 5 (64-bit)', 114, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'Red Hat Enterprise Linux 6 (32-bit)', 136, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'Red Hat Enterprise Linux 6 (64-bit)', 137, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'SUSE Linux Enterprise Server 9 SP4', 40, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'SUSE Linux Enterprise Server 10 SP1', 41, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'SUSE Linux Enterprise Server 10 SP1 x64', 42, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'SUSE Linux Enterprise Server 10 SP2', 43, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'SUSE Linux Enterprise Server 10 SP2 x64', 44, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'Other install media', 45, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'SUSE Linux Enterprise Server 11', 46, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'SUSE Linux Enterprise Server 11 x64', 47, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'SUSE Linux Enterprise Server 11 SP1 (32-bit)', 155, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'SUSE Linux Enterprise Server 11 SP1 (64-bit)', 154, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'Windows 7 (32-bit)', 48, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'Windows 7 (64-bit)', 49, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'Windows Server 2003 (32-bit)', 50, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'Windows Server 2003 (64-bit)', 51, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'Windows Server 2003 (32-bit)', 87, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'Windows Server 2003 (64-bit)', 88, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'Windows Server 2003 (32-bit)', 89, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'Windows Server 2003 (64-bit)', 90, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'Windows Server 2008 (32-bit)', 52, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'Windows Server 2008 (64-bit)', 53, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'Windows Server 2008 R2 (64-bit)', 54, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'Windows XP SP3 (32-bit)', 58, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'Windows Vista (32-bit)', 56, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'Ubuntu Lucid Lynx 10.04 (32-bit) (experimental)', 121, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'Ubuntu Lucid Lynx 10.04 (64-bit) (experimental)', 126, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'Other install media', 98, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'Other install media', 99, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'CentOS 5 (32-bit)', 139, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', 'XCP 1.0', 'CentOS 5 (64-bit)', 140, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'CentOS 4.5 (32-bit)', 1, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'CentOS 4.6 (32-bit)', 2, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'CentOS 4.7 (32-bit)', 3, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'CentOS 4.8 (32-bit)', 4, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'CentOS 5 (32-bit)', 5, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'CentOS 5 (64-bit)', 6, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'CentOS 5 (32-bit)', 7, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'CentOS 5 (64-bit)', 8, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'CentOS 5 (32-bit)', 9, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'CentOS 5 (64-bit)', 10, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'CentOS 5 (32-bit)', 11, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'CentOS 5 (64-bit)', 12, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'CentOS 5 (32-bit)', 13, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'CentOS 5 (64-bit)', 14, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'CentOS 5 (32-bit)', 111, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'CentOS 5 (64-bit)', 112, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'Debian Lenny 5.0 (32-bit)', 15, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'Debian Squeeze 6.0 (32-bit)', 132, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'Debian Squeeze 6.0 (64-bit) (experimental)', 133, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'Debian Squeeze 6.0 (32-bit)', 183, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'Debian Squeeze 6.0 (64-bit) (experimental)', 184, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'Oracle Enterprise Linux 5 (32-bit)', 16, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'Oracle Enterprise Linux 5 (64-bit)', 17, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'Oracle Enterprise Linux 5 (32-bit)', 18, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'Oracle Enterprise Linux 5 (64-bit)', 19, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'Oracle Enterprise Linux 5 (32-bit)', 20, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'Oracle Enterprise Linux 5 (64-bit)', 21, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'Oracle Enterprise Linux 5 (32-bit)', 22, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'Oracle Enterprise Linux 5 (64-bit)', 23, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'Oracle Enterprise Linux 5 (32-bit)', 24, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'Oracle Enterprise Linux 5 (64-bit)', 25, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'Oracle Enterprise Linux 5 (32-bit)', 134, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'Oracle Enterprise Linux 5 (64-bit)', 135, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'Red Hat Enterprise Linux 4.5 (32-bit)', 26, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'Red Hat Enterprise Linux 4.6 (32-bit)', 27, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'Red Hat Enterprise Linux 4.7 (32-bit)', 28, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'Red Hat Enterprise Linux 4.8 (32-bit)', 29, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'Red Hat Enterprise Linux 5 (32-bit)', 30, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'Red Hat Enterprise Linux 5 (64-bit)', 31, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'Red Hat Enterprise Linux 5 (32-bit)', 32, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'Red Hat Enterprise Linux 5 (64-bit)', 33, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'Red Hat Enterprise Linux 5 (32-bit)', 34, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'Red Hat Enterprise Linux 5 (64-bit)', 35, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'Red Hat Enterprise Linux 5 (32-bit)', 36, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'Red Hat Enterprise Linux 5 (64-bit)', 37, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'Red Hat Enterprise Linux 5 (32-bit)', 38, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'Red Hat Enterprise Linux 5 (64-bit)', 39, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'Red Hat Enterprise Linux 5 (32-bit)', 113, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'Red Hat Enterprise Linux 5 (64-bit)', 114, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'Red Hat Enterprise Linux 6 (32-bit) (experimental)', 136, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'Red Hat Enterprise Linux 6 (64-bit) (experimental)', 137, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'SUSE Linux Enterprise Server 9 SP4 (32-bit)', 40, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'SUSE Linux Enterprise Server 10 SP1 (32-bit)', 41, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'SUSE Linux Enterprise Server 10 SP1 (64-bit)', 42, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'SUSE Linux Enterprise Server 10 SP2 (32-bit)', 43, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'SUSE Linux Enterprise Server 10 SP2 (64-bit)', 44, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'SUSE Linux Enterprise Server 10 SP3 (64-bit)', 45, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'SUSE Linux Enterprise Server 11 (32-bit)', 46, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'SUSE Linux Enterprise Server 11 (64-bit)', 47, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'Windows 7 (32-bit)', 48, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'Windows 7 (64-bit)', 49, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'Windows Server 2003 (32-bit)', 50, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'Windows Server 2003 (64-bit)', 51, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'Windows Server 2003 (32-bit)', 87, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'Windows Server 2003 (64-bit)', 88, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'Windows Server 2008 (32-bit)', 52, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'Windows Server 2008 (64-bit)', 53, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'Windows Server 2008 R2 (64-bit)', 54, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'Windows 2000 SP4 (32-bit)', 55, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'Windows Vista (32-bit)', 56, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'Windows XP SP3 (32-bit)', 58, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'Ubuntu Lucid Lynx 10.04 (32-bit) (experimental)', 121, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'Ubuntu Lucid Lynx 10.04 (64-bit) (experimental)', 126, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'Other install media', 98, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'Other install media', 99, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'CentOS 5 (32-bit)', 139, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 FP1', 'CentOS 5 (64-bit)', 140, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'CentOS 4.5 (32-bit)', 1, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'CentOS 4.6 (32-bit)', 2, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'CentOS 4.7 (32-bit)', 3, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'CentOS 4.8 (32-bit)', 4, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'CentOS 5 (32-bit)', 5, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'CentOS 5 (64-bit)', 6, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'CentOS 5 (32-bit)', 7, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'CentOS 5 (64-bit)', 8, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'CentOS 5 (32-bit)', 9, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'CentOS 5 (64-bit)', 10, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'CentOS 5 (32-bit)', 11, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'CentOS 5 (64-bit)', 12, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'CentOS 5 (32-bit)', 13, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'CentOS 5 (64-bit)', 14, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'CentOS 5 (32-bit)', 111, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'CentOS 5 (64-bit)', 112, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'Debian Lenny 5.0 (32-bit)', 15, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'Debian Squeeze 6.0 (32-bit)', 132, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'Debian Squeeze 6.0 (64-bit) (experimental)', 133, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'Debian Squeeze 6.0 (32-bit)', 183, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'Debian Squeeze 6.0 (64-bit) (experimental)', 184, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'Oracle Enterprise Linux 5 (32-bit)', 16, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'Oracle Enterprise Linux 5 (64-bit)', 17, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'Oracle Enterprise Linux 5 (32-bit)', 18, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'Oracle Enterprise Linux 5 (64-bit)', 19, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'Oracle Enterprise Linux 5 (32-bit)', 20, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'Oracle Enterprise Linux 5 (64-bit)', 21, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'Oracle Enterprise Linux 5 (32-bit)', 22, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'Oracle Enterprise Linux 5 (64-bit)', 23, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'Oracle Enterprise Linux 5 (32-bit)', 24, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'Oracle Enterprise Linux 5 (64-bit)', 25, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'Oracle Enterprise Linux 5 (32-bit)', 134, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'Oracle Enterprise Linux 5 (64-bit)', 135, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'Red Hat Enterprise Linux 4.5 (32-bit)', 26, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'Red Hat Enterprise Linux 4.6 (32-bit)', 27, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'Red Hat Enterprise Linux 4.7 (32-bit)', 28, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'Red Hat Enterprise Linux 4.8 (32-bit)', 29, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'Red Hat Enterprise Linux 5 (32-bit)', 30, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'Red Hat Enterprise Linux 5 (64-bit)', 31, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'Red Hat Enterprise Linux 5 (32-bit)', 32, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'Red Hat Enterprise Linux 5 (64-bit)', 33, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'Red Hat Enterprise Linux 5 (32-bit)', 34, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'Red Hat Enterprise Linux 5 (64-bit)', 35, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'Red Hat Enterprise Linux 5 (32-bit)', 36, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'Red Hat Enterprise Linux 5 (64-bit)', 37, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'Red Hat Enterprise Linux 5 (32-bit)', 38, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'Red Hat Enterprise Linux 5 (64-bit)', 39, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'Red Hat Enterprise Linux 5 (32-bit)', 113, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'Red Hat Enterprise Linux 5 (64-bit)', 114, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'Red Hat Enterprise Linux 6 (32-bit)', 136, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'Red Hat Enterprise Linux 6 (64-bit)', 137, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'SUSE Linux Enterprise Server 9 SP4 (32-bit)', 40, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'SUSE Linux Enterprise Server 10 SP1 (32-bit)', 41, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'SUSE Linux Enterprise Server 10 SP1 (64-bit)', 42, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'SUSE Linux Enterprise Server 10 SP2 (32-bit)', 43, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'SUSE Linux Enterprise Server 10 SP2 (64-bit)', 44, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'SUSE Linux Enterprise Server 10 SP3 (64-bit)', 45, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'SUSE Linux Enterprise Server 11 (32-bit)', 46, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'SUSE Linux Enterprise Server 11 (64-bit)', 47, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'Windows 7 (32-bit)', 48, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'Windows 7 (64-bit)', 49, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'Windows Server 2008 (32-bit)', 52, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'Windows Server 2008 (64-bit)', 53, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'Windows Server 2008 R2 (64-bit)', 54, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'Windows Vista (32-bit)', 56, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'Windows XP SP3 (32-bit)', 58, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'Ubuntu Lucid Lynx 10.04 (32-bit) (experimental)', 121, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'Ubuntu Lucid Lynx 10.04 (64-bit) (experimental)', 126, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'Other install media', 98, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'Other install media', 99, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'CentOS 5 (32-bit)', 139, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '5.6 SP2', 'CentOS 5 (64-bit)', 140, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'CentOS 4.5 (32-bit)', 1, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'CentOS 4.6 (32-bit)', 2, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'CentOS 4.7 (32-bit)', 3, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'CentOS 4.8 (32-bit)', 4, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'CentOS 5 (32-bit)', 5, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'CentOS 5 (64-bit)', 6, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'CentOS 5 (32-bit)', 7, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'CentOS 5 (64-bit)', 8, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'CentOS 5 (32-bit)', 9, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'CentOS 5 (64-bit)', 10, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'CentOS 5 (32-bit)', 11, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'CentOS 5 (64-bit)', 12, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'CentOS 5 (32-bit)', 13, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'CentOS 5 (64-bit)', 14, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'CentOS 5 (32-bit)', 111, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'CentOS 5 (64-bit)', 112, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'CentOS 5 (32-bit)', 141, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'CentOS 5 (64-bit)', 142, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'CentOS 6.0 (32-bit) (experimental)', 143, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'CentOS 6.0 (64-bit) (experimental)', 144, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Debian Lenny 5.0 (32-bit)', 15, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Debian Squeeze 6.0 (32-bit)', 132, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Debian Squeeze 6.0 (64-bit)', 133, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Debian Squeeze 6.0 (32-bit)', 183, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Debian Squeeze 6.0 (64-bit)', 184, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Oracle Enterprise Linux 5 (32-bit)', 16, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Oracle Enterprise Linux 5 (64-bit)', 17, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Oracle Enterprise Linux 5 (32-bit)', 18, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Oracle Enterprise Linux 5 (64-bit)', 19, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Oracle Enterprise Linux 5 (32-bit)', 20, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Oracle Enterprise Linux 5 (64-bit)', 21, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Oracle Enterprise Linux 5 (32-bit)', 22, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Oracle Enterprise Linux 5 (64-bit)', 23, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Oracle Enterprise Linux 5 (32-bit)', 24, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Oracle Enterprise Linux 5 (64-bit)', 25, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Oracle Enterprise Linux 5 (32-bit)', 134, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Oracle Enterprise Linux 5 (64-bit)', 135, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Oracle Enterprise Linux 5 (32-bit)', 145, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Oracle Enterprise Linux 5 (64-bit)', 146, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Oracle Enterprise Linux 6.0 (32-bit)', 147, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Oracle Enterprise Linux 6.0 (64-bit)', 148, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Red Hat Enterprise Linux 4.5 (32-bit)', 26, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Red Hat Enterprise Linux 4.6 (32-bit)', 27, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Red Hat Enterprise Linux 4.7 (32-bit)', 28, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Red Hat Enterprise Linux 4.8 (32-bit)', 29, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Red Hat Enterprise Linux 5 (32-bit)', 30, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Red Hat Enterprise Linux 5 (64-bit)', 31, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Red Hat Enterprise Linux 5 (32-bit)', 32, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Red Hat Enterprise Linux 5 (64-bit)', 33, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Red Hat Enterprise Linux 5 (32-bit)', 34, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Red Hat Enterprise Linux 5 (64-bit)', 35, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Red Hat Enterprise Linux 5 (32-bit)', 36, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Red Hat Enterprise Linux 5 (64-bit)', 37, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Red Hat Enterprise Linux 5 (32-bit)', 38, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Red Hat Enterprise Linux 5 (64-bit)', 39, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Red Hat Enterprise Linux 5 (32-bit)', 113, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Red Hat Enterprise Linux 5 (64-bit)', 114, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Red Hat Enterprise Linux 5 (32-bit)', 149, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Red Hat Enterprise Linux 5 (64-bit)', 150, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Red Hat Enterprise Linux 6.0 (32-bit)', 136, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Red Hat Enterprise Linux 6.0 (64-bit)', 137, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'SUSE Linux Enterprise Server 9 SP4 (32-bit)', 40, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'SUSE Linux Enterprise Server 10 SP1 (32-bit)', 41, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'SUSE Linux Enterprise Server 10 SP1 (64-bit)', 42, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'SUSE Linux Enterprise Server 10 SP2 (32-bit)', 43, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'SUSE Linux Enterprise Server 10 SP2 (64-bit)', 44, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'SUSE Linux Enterprise Server 10 SP3 (32-bit)', 151, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'SUSE Linux Enterprise Server 10 SP3 (64-bit)', 45, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'SUSE Linux Enterprise Server 10 SP4 (32-bit)', 153, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'SUSE Linux Enterprise Server 10 SP4 (64-bit)', 152, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'SUSE Linux Enterprise Server 11 (32-bit)', 46, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'SUSE Linux Enterprise Server 11 (64-bit)', 47, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'SUSE Linux Enterprise Server 11 SP1 (32-bit)', 155, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'SUSE Linux Enterprise Server 11 SP1 (64-bit)', 154, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Windows 7 (32-bit)', 48, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Windows 7 (64-bit)', 49, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Windows Server 2003 (32-bit)', 50, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Windows Server 2003 (64-bit)', 51, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Windows Server 2003 (32-bit)', 87, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Windows Server 2003 (64-bit)', 88, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Windows Server 2003 (32-bit)', 89, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Windows Server 2003 (64-bit)', 90, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Windows Server 2008 (32-bit)', 52, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Windows Server 2008 (64-bit)', 53, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Windows Server 2008 R2 (64-bit)', 54, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Windows Vista (32-bit)', 56, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Windows XP SP3 (32-bit)', 58, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Ubuntu Lucid Lynx 10.04 (32-bit)', 121, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Ubuntu Lucid Lynx 10.04 (64-bit)', 126, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Ubuntu Maverick Meerkat 10.10 (32-bit) (experimental)', 156, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Ubuntu Maverick Meerkat 10.10 (64-bit) (experimental)', 157, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Other install media', 98, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Other install media', 99, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Other install media', 60, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Other install media', 103, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Other install media', 200, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Other install media', 201, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Other install media', 59, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Other install media', 100, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Other install media', 202, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'Other install media', 203, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'CentOS 5 (32-bit)', 139, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0', 'CentOS 5 (64-bit)', 140, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'CentOS 4.5 (32-bit)', 1, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'CentOS 4.6 (32-bit)', 2, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'CentOS 4.7 (32-bit)', 3, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'CentOS 4.8 (32-bit)', 4, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'CentOS 5 (32-bit)', 5, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'CentOS 5 (64-bit)', 6, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'CentOS 5 (32-bit)', 7, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'CentOS 5 (64-bit)', 8, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'CentOS 5 (32-bit)', 9, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'CentOS 5 (64-bit)', 10, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'CentOS 5 (32-bit)', 11, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'CentOS 5 (64-bit)', 12, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'CentOS 5 (32-bit)', 13, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'CentOS 5 (64-bit)', 14, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'CentOS 5 (32-bit)', 111, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'CentOS 5 (64-bit)', 112, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'CentOS 5 (32-bit)', 141, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'CentOS 5 (64-bit)', 142, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'CentOS 5 (32-bit)', 161, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'CentOS 5 (64-bit)', 162, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'CentOS 6.0 (32-bit)', 143, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'CentOS 6.0 (64-bit)', 144, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Debian Lenny 5.0 (32-bit)', 15, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Debian Squeeze 6.0 (32-bit)', 132, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Debian Squeeze 6.0 (64-bit)', 133, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Debian Squeeze 6.0 (32-bit)', 183, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Debian Squeeze 6.0 (64-bit)', 184, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Oracle Enterprise Linux 5 (32-bit)', 16, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Oracle Enterprise Linux 5 (64-bit)', 17, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Oracle Enterprise Linux 5 (32-bit)', 18, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Oracle Enterprise Linux 5 (64-bit)', 19, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Oracle Enterprise Linux 5 (32-bit)', 20, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Oracle Enterprise Linux 5 (64-bit)', 21, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Oracle Enterprise Linux 5 (32-bit)', 22, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Oracle Enterprise Linux 5 (64-bit)', 23, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Oracle Enterprise Linux 5 (32-bit)', 24, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Oracle Enterprise Linux 5 (64-bit)', 25, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Oracle Enterprise Linux 5 (32-bit)', 134, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Oracle Enterprise Linux 5 (64-bit)', 135, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Oracle Enterprise Linux 5 (32-bit)', 145, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Oracle Enterprise Linux 5 (64-bit)', 146, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Oracle Enterprise Linux 5 (32-bit)', 207, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Oracle Enterprise Linux 5 (64-bit)', 208, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Oracle Enterprise Linux 6.0 (32-bit)', 147, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Oracle Enterprise Linux 6.0 (64-bit)', 148, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Red Hat Enterprise Linux 4.5 (32-bit)', 26, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Red Hat Enterprise Linux 4.6 (32-bit)', 27, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Red Hat Enterprise Linux 4.7 (32-bit)', 28, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Red Hat Enterprise Linux 4.8 (32-bit)', 29, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Red Hat Enterprise Linux 5 (32-bit)', 30, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Red Hat Enterprise Linux 5 (64-bit)', 31, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Red Hat Enterprise Linux 5 (32-bit)', 32, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Red Hat Enterprise Linux 5 (64-bit)', 33, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Red Hat Enterprise Linux 5 (32-bit)', 34, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Red Hat Enterprise Linux 5 (64-bit)', 35, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Red Hat Enterprise Linux 5 (32-bit)', 36, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Red Hat Enterprise Linux 5 (64-bit)', 37, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Red Hat Enterprise Linux 5 (32-bit)', 38, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Red Hat Enterprise Linux 5 (64-bit)', 39, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Red Hat Enterprise Linux 5 (32-bit)', 113, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Red Hat Enterprise Linux 5 (64-bit)', 114, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Red Hat Enterprise Linux 5 (32-bit)', 149, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Red Hat Enterprise Linux 5 (64-bit)', 150, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Red Hat Enterprise Linux 5 (32-bit)', 189, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Red Hat Enterprise Linux 5 (64-bit)', 190, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Red Hat Enterprise Linux 6.0 (32-bit)', 136, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Red Hat Enterprise Linux 6.0 (64-bit)', 137, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'SUSE Linux Enterprise Server 10 SP1 (32-bit)', 40, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'SUSE Linux Enterprise Server 10 SP1 (32-bit)', 41, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'SUSE Linux Enterprise Server 10 SP1 (64-bit)', 42, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'SUSE Linux Enterprise Server 10 SP2 (32-bit)', 43, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'SUSE Linux Enterprise Server 10 SP2 (64-bit)', 44, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'SUSE Linux Enterprise Server 10 SP3 (32-bit)', 151, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'SUSE Linux Enterprise Server 10 SP3 (64-bit)', 45, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'SUSE Linux Enterprise Server 10 SP4 (32-bit)', 153, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'SUSE Linux Enterprise Server 10 SP4 (64-bit)', 152, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'SUSE Linux Enterprise Server 11 (32-bit)', 46, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'SUSE Linux Enterprise Server 11 (64-bit)', 47, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'SUSE Linux Enterprise Server 11 SP1 (32-bit)', 155, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'SUSE Linux Enterprise Server 11 SP1 (64-bit)', 154, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Windows 7 (32-bit)', 48, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Windows 7 (64-bit)', 49, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Windows 8 (32-bit) (experimental)', 165, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Windows 8 (64-bit) (experimental)', 166, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Windows Server 2003 (32-bit)', 50, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Windows Server 2003 (64-bit)', 51, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Windows Server 2003 (32-bit)', 87, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Windows Server 2003 (64-bit)', 88, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Windows Server 2003 (32-bit)', 89, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Windows Server 2003 (64-bit)', 90, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Windows Server 2008 (32-bit)', 52, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Windows Server 2008 (64-bit)', 53, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Windows Server 2008 R2 (64-bit)', 54, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Windows Vista (32-bit)', 56, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Windows XP SP3 (32-bit)', 58, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Ubuntu Lucid Lynx 10.04 (32-bit)', 121, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Ubuntu Lucid Lynx 10.04 (64-bit)', 126, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Ubuntu Maverick Meerkat 10.10 (32-bit) (experimental)', 156, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Ubuntu Maverick Meerkat 10.10 (64-bit) (experimental)', 157, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Other install media', 98, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Other install media', 99, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Other install media', 60, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Other install media', 103, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Other install media', 200, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Other install media', 201, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Other install media', 59, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Other install media', 100, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Other install media', 202, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'Other install media', 203, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'CentOS 5 (32-bit)', 139, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.0.2', 'CentOS 5 (64-bit)', 140, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'CentOS 4.5 (32-bit)', 1, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'CentOS 4.6 (32-bit)', 2, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'CentOS 4.7 (32-bit)', 3, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'CentOS 4.8 (32-bit)', 4, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'CentOS 5 (32-bit)', 5, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'CentOS 5 (64-bit)', 6, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'CentOS 5 (32-bit)', 7, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'CentOS 5 (64-bit)', 8, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'CentOS 5 (32-bit)', 9, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'CentOS 5 (64-bit)', 10, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'CentOS 5 (32-bit)', 11, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'CentOS 5 (64-bit)', 12, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'CentOS 5 (32-bit)', 13, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'CentOS 5 (64-bit)', 14, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'CentOS 5 (32-bit)', 111, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'CentOS 5 (64-bit)', 112, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'CentOS 5 (32-bit)', 141, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'CentOS 5 (64-bit)', 142, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'CentOS 5 (32-bit)', 161, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'CentOS 5 (64-bit)', 162, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'CentOS 6 (32-bit)', 143, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'CentOS 6 (64-bit)', 144, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'CentOS 6 (32-bit)', 177, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'CentOS 6 (64-bit)', 178, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'CentOS 6 (32-bit)', 179, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'CentOS 6 (64-bit)', 180, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'CentOS 6 (32-bit)', 171, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'CentOS 6 (64-bit)', 172, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Debian Squeeze 6.0 (32-bit)', 132, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Debian Squeeze 6.0 (64-bit)', 133, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Debian Squeeze 6.0 (32-bit)', 183, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Debian Squeeze 6.0 (64-bit)', 184, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Oracle Enterprise Linux 5 (32-bit)', 16, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Oracle Enterprise Linux 5 (64-bit)', 17, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Oracle Enterprise Linux 5 (32-bit)', 18, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Oracle Enterprise Linux 5 (64-bit)', 19, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Oracle Enterprise Linux 5 (32-bit)', 20, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Oracle Enterprise Linux 5 (64-bit)', 21, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Oracle Enterprise Linux 5 (32-bit)', 22, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Oracle Enterprise Linux 5 (64-bit)', 23, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Oracle Enterprise Linux 5 (32-bit)', 24, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Oracle Enterprise Linux 5 (64-bit)', 25, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Oracle Enterprise Linux 5 (32-bit)', 134, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Oracle Enterprise Linux 5 (64-bit)', 135, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Oracle Enterprise Linux 5 (32-bit)', 145, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Oracle Enterprise Linux 5 (64-bit)', 146, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Oracle Enterprise Linux 5 (32-bit)', 207, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Oracle Enterprise Linux 5 (64-bit)', 208, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Oracle Enterprise Linux 6 (32-bit)', 147, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Oracle Enterprise Linux 6 (64-bit)', 148, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Oracle Enterprise Linux 6 (32-bit)', 213, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Oracle Enterprise Linux 6 (64-bit)', 214, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Oracle Enterprise Linux 6 (32-bit)', 215, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Oracle Enterprise Linux 6 (64-bit)', 216, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Red Hat Enterprise Linux 4.5 (32-bit)', 26, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Red Hat Enterprise Linux 4.6 (32-bit)', 27, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Red Hat Enterprise Linux 4.7 (32-bit)', 28, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Red Hat Enterprise Linux 4.8 (32-bit)', 29, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Red Hat Enterprise Linux 5 (32-bit)', 30, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Red Hat Enterprise Linux 5 (64-bit)', 31, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Red Hat Enterprise Linux 5 (32-bit)', 32, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Red Hat Enterprise Linux 5 (64-bit)', 33, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Red Hat Enterprise Linux 5 (32-bit)', 34, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Red Hat Enterprise Linux 5 (64-bit)', 35, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Red Hat Enterprise Linux 5 (32-bit)', 36, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Red Hat Enterprise Linux 5 (64-bit)', 37, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Red Hat Enterprise Linux 5 (32-bit)', 38, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Red Hat Enterprise Linux 5 (64-bit)', 39, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Red Hat Enterprise Linux 5 (32-bit)', 113, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Red Hat Enterprise Linux 5 (64-bit)', 114, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Red Hat Enterprise Linux 5 (32-bit)', 149, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Red Hat Enterprise Linux 5 (64-bit)', 150, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Red Hat Enterprise Linux 5 (32-bit)', 189, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Red Hat Enterprise Linux 5 (64-bit)', 190, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Red Hat Enterprise Linux 6 (32-bit)', 136, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Red Hat Enterprise Linux 6 (64-bit)', 137, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Red Hat Enterprise Linux 6 (32-bit)', 195, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Red Hat Enterprise Linux 6 (64-bit)', 196, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Red Hat Enterprise Linux 6 (32-bit)', 197, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Red Hat Enterprise Linux 6 (64-bit)', 198, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'SUSE Linux Enterprise Server 10 SP1 (32-bit)', 40, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'SUSE Linux Enterprise Server 10 SP1 (32-bit)', 41, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'SUSE Linux Enterprise Server 10 SP1 (64-bit)', 42, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'SUSE Linux Enterprise Server 10 SP2 (32-bit)', 43, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'SUSE Linux Enterprise Server 10 SP2 (64-bit)', 44, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'SUSE Linux Enterprise Server 10 SP3 (32-bit)', 151, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'SUSE Linux Enterprise Server 10 SP3 (64-bit)', 45, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'SUSE Linux Enterprise Server 10 SP4 (32-bit)', 153, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'SUSE Linux Enterprise Server 10 SP4 (64-bit)', 152, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'SUSE Linux Enterprise Server 11 (32-bit)', 46, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'SUSE Linux Enterprise Server 11 (64-bit)', 47, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'SUSE Linux Enterprise Server 11 SP1 (32-bit)', 155, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'SUSE Linux Enterprise Server 11 SP1 (64-bit)', 154, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Windows 7 (32-bit)', 48, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Windows 7 (64-bit)', 49, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Windows 8 (32-bit) (experimental)', 165, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Windows 8 (64-bit) (experimental)', 166, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Windows Server 2003 (32-bit)', 50, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Windows Server 2003 (64-bit)', 51, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Windows Server 2003 (32-bit)', 87, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Windows Server 2003 (64-bit)', 88, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Windows Server 2003 (32-bit)', 89, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Windows Server 2003 (64-bit)', 90, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Windows Server 2008 (32-bit)', 52, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Windows Server 2008 (64-bit)', 53, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Windows Server 2008 R2 (64-bit)', 54, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Windows Server 2012 (64-bit) (experimental)', 167, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Windows Vista (32-bit)', 56, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Windows XP SP3 (32-bit)', 58, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Ubuntu Lucid Lynx 10.04 (32-bit)', 121, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Ubuntu Lucid Lynx 10.04 (64-bit)', 126, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Ubuntu Maverick Meerkat 10.10 (32-bit) (experimental)', 156, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Ubuntu Maverick Meerkat 10.10 (64-bit) (experimental)', 157, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Ubuntu Precise Pangolin 12.04 (32-bit)', 163, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Ubuntu Precise Pangolin 12.04 (64-bit)', 164, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Other install media', 169, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Other install media', 170, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Other install media', 98, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Other install media', 99, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Other install media', 60, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Other install media', 103, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Other install media', 200, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Other install media', 201, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Other install media', 59, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Other install media', 100, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Other install media', 202, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'Other install media', 203, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'CentOS 5 (32-bit)', 139, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.1.0', 'CentOS 5 (64-bit)', 140, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'CentOS 4.5 (32-bit)', 1, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'CentOS 4.6 (32-bit)', 2, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'CentOS 4.7 (32-bit)', 3, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'CentOS 4.8 (32-bit)', 4, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'CentOS 5 (32-bit)', 5, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'CentOS 5 (64-bit)', 6, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'CentOS 5 (32-bit)', 7, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'CentOS 5 (64-bit)', 8, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'CentOS 5 (32-bit)', 9, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'CentOS 5 (64-bit)', 10, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'CentOS 5 (32-bit)', 11, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'CentOS 5 (64-bit)', 12, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'CentOS 5 (32-bit)', 13, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'CentOS 5 (64-bit)', 14, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'CentOS 5 (32-bit)', 111, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'CentOS 5 (64-bit)', 112, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'CentOS 5 (32-bit)', 141, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'CentOS 5 (64-bit)', 142, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'CentOS 5 (32-bit)', 161, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'CentOS 5 (64-bit)', 162, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'CentOS 5 (32-bit)', 173, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'CentOS 5 (64-bit)', 174, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'CentOS 5 (32-bit)', 175, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'CentOS 5 (64-bit)', 176, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'CentOS 6 (32-bit)', 143, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'CentOS 6 (64-bit)', 144, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'CentOS 6 (32-bit)', 177, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'CentOS 6 (64-bit)', 178, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'CentOS 6 (32-bit)', 179, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'CentOS 6 (64-bit)', 180, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'CentOS 6 (32-bit)', 171, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'CentOS 6 (64-bit)', 172, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'CentOS 6 (32-bit)', 181, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'CentOS 6 (64-bit)', 182, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Debian Squeeze 6.0 (32-bit)', 132, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Debian Squeeze 6.0 (64-bit)', 133, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Debian Wheezy 7.0 (32-bit)', 183, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Debian Wheezy 7.0 (64-bit)', 184, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Oracle Enterprise Linux 5 (32-bit)', 16, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Oracle Enterprise Linux 5 (64-bit)', 17, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Oracle Enterprise Linux 5 (32-bit)', 18, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Oracle Enterprise Linux 5 (64-bit)', 19, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Oracle Enterprise Linux 5 (32-bit)', 20, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Oracle Enterprise Linux 5 (64-bit)', 21, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Oracle Enterprise Linux 5 (32-bit)', 22, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Oracle Enterprise Linux 5 (64-bit)', 23, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Oracle Enterprise Linux 5 (32-bit)', 24, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Oracle Enterprise Linux 5 (64-bit)', 25, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Oracle Enterprise Linux 5 (32-bit)', 134, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Oracle Enterprise Linux 5 (64-bit)', 135, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Oracle Enterprise Linux 5 (32-bit)', 145, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Oracle Enterprise Linux 5 (64-bit)', 146, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Oracle Enterprise Linux 5 (32-bit)', 207, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Oracle Enterprise Linux 5 (64-bit)', 208, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Oracle Enterprise Linux 5 (32-bit)', 209, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Oracle Enterprise Linux 5 (64-bit)', 210, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Oracle Enterprise Linux 5 (32-bit)', 211, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Oracle Enterprise Linux 5 (64-bit)', 212, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Oracle Enterprise Linux 6 (32-bit)', 147, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Oracle Enterprise Linux 6 (64-bit)', 148, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Oracle Enterprise Linux 6 (32-bit)', 213, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Oracle Enterprise Linux 6 (64-bit)', 214, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Oracle Enterprise Linux 6 (32-bit)', 215, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Oracle Enterprise Linux 6 (64-bit)', 216, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Oracle Enterprise Linux 6 (32-bit)', 217, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Oracle Enterprise Linux 6 (64-bit)', 218, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Oracle Enterprise Linux 6 (32-bit)', 219, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Oracle Enterprise Linux 6 (64-bit)', 220, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Red Hat Enterprise Linux 4.5 (32-bit)', 26, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Red Hat Enterprise Linux 4.6 (32-bit)', 27, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Red Hat Enterprise Linux 4.7 (32-bit)', 28, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Red Hat Enterprise Linux 4.8 (32-bit)', 29, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Red Hat Enterprise Linux 5 (32-bit)', 30, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Red Hat Enterprise Linux 5 (64-bit)', 31, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Red Hat Enterprise Linux 5 (32-bit)', 32, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Red Hat Enterprise Linux 5 (64-bit)', 33, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Red Hat Enterprise Linux 5 (32-bit)', 34, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Red Hat Enterprise Linux 5 (64-bit)', 35, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Red Hat Enterprise Linux 5 (32-bit)', 36, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Red Hat Enterprise Linux 5 (64-bit)', 37, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Red Hat Enterprise Linux 5 (32-bit)', 38, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Red Hat Enterprise Linux 5 (64-bit)', 39, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Red Hat Enterprise Linux 5 (32-bit)', 113, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Red Hat Enterprise Linux 5 (64-bit)', 114, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Red Hat Enterprise Linux 5 (32-bit)', 149, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Red Hat Enterprise Linux 5 (64-bit)', 150, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Red Hat Enterprise Linux 5 (32-bit)', 189, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Red Hat Enterprise Linux 5 (64-bit)', 190, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Red Hat Enterprise Linux 5 (32-bit)', 191, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Red Hat Enterprise Linux 5 (64-bit)', 192, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Red Hat Enterprise Linux 5 (32-bit)', 193, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Red Hat Enterprise Linux 5 (64-bit)', 194, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Red Hat Enterprise Linux 6 (32-bit)', 136, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Red Hat Enterprise Linux 6 (64-bit)', 137, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Red Hat Enterprise Linux 6 (32-bit)', 195, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Red Hat Enterprise Linux 6 (64-bit)', 196, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Red Hat Enterprise Linux 6 (32-bit)', 197, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Red Hat Enterprise Linux 6 (64-bit)', 198, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Red Hat Enterprise Linux 6 (32-bit)', 199, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Red Hat Enterprise Linux 6 (64-bit)', 204, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Red Hat Enterprise Linux 6 (32-bit)', 205, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Red Hat Enterprise Linux 6 (64-bit)', 206, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'SUSE Linux Enterprise Server 10 SP1 (32-bit)', 41, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'SUSE Linux Enterprise Server 10 SP1 (64-bit)', 42, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'SUSE Linux Enterprise Server 10 SP2 (32-bit)', 43, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'SUSE Linux Enterprise Server 10 SP2 (64-bit)', 44, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'SUSE Linux Enterprise Server 10 SP3 (32-bit)', 151, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'SUSE Linux Enterprise Server 10 SP3 (64-bit)', 45, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'SUSE Linux Enterprise Server 10 SP4 (32-bit)', 153, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'SUSE Linux Enterprise Server 10 SP4 (64-bit)', 152, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'SUSE Linux Enterprise Server 11 (32-bit)', 46, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'SUSE Linux Enterprise Server 11 (64-bit)', 47, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'SUSE Linux Enterprise Server 11 SP1 (32-bit)', 155, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'SUSE Linux Enterprise Server 11 SP1 (64-bit)', 154, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'SUSE Linux Enterprise Server 11 SP2 (32-bit)', 186, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'SUSE Linux Enterprise Server 11 SP2 (64-bit)', 185, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Windows 7 (32-bit)', 48, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Windows 7 (64-bit)', 49, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Windows 8 (32-bit)', 165, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Windows 8 (64-bit)', 166, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Windows Server 2003 (32-bit)', 50, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Windows Server 2003 (64-bit)', 51, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Windows Server 2003 (32-bit)', 87, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Windows Server 2003 (64-bit)', 88, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Windows Server 2003 (32-bit)', 89, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Windows Server 2003 (64-bit)', 90, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Windows Server 2008 R2 (64-bit)', 54, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Windows Server 2012 (64-bit)', 167, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Windows XP SP3 (32-bit)', 58, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Ubuntu Lucid Lynx 10.04 (32-bit)', 121, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Ubuntu Lucid Lynx 10.04 (64-bit)', 126, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Ubuntu Maverick Meerkat 10.10 (32-bit) (experimental)', 156, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Ubuntu Maverick Meerkat 10.10 (64-bit) (experimental)', 157, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Ubuntu Precise Pangolin 12.04 (32-bit)', 163, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Ubuntu Precise Pangolin 12.04 (64-bit)', 164, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Other install media', 169, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Other install media', 170, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Other install media', 98, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Other install media', 99, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Other install media', 60, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Other install media', 103, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Other install media', 200, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Other install media', 201, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Other install media', 59, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Other install media', 100, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Other install media', 202, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'Other install media', 203, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'CentOS 5 (32-bit)', 139, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.0', 'CentOS 5 (64-bit)', 140, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'CentOS 4.5 (32-bit)', 1, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'CentOS 4.6 (32-bit)', 2, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'CentOS 4.7 (32-bit)', 3, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'CentOS 4.8 (32-bit)', 4, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'CentOS 5 (32-bit)', 5, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'CentOS 5 (64-bit)', 6, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'CentOS 5 (32-bit)', 7, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'CentOS 5 (64-bit)', 8, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'CentOS 5 (32-bit)', 9, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'CentOS 5 (64-bit)', 10, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'CentOS 5 (32-bit)', 11, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'CentOS 5 (64-bit)', 12, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'CentOS 5 (32-bit)', 13, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'CentOS 5 (64-bit)', 14, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'CentOS 5 (32-bit)', 111, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'CentOS 5 (64-bit)', 112, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'CentOS 5 (32-bit)', 141, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'CentOS 5 (64-bit)', 142, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'CentOS 5 (32-bit)', 161, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'CentOS 5 (64-bit)', 162, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'CentOS 5 (32-bit)', 173, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'CentOS 5 (64-bit)', 174, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'CentOS 5 (32-bit)', 175, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'CentOS 5 (64-bit)', 176, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'CentOS 6 (32-bit)', 143, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'CentOS 6 (64-bit)', 144, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'CentOS 6 (32-bit)', 177, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'CentOS 6 (64-bit)', 178, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'CentOS 6 (32-bit)', 179, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'CentOS 6 (64-bit)', 180, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'CentOS 6 (32-bit)', 171, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'CentOS 6 (64-bit)', 172, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'CentOS 6 (32-bit)', 181, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'CentOS 6 (64-bit)', 182, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Debian Squeeze 6.0 (32-bit)', 132, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Debian Squeeze 6.0 (64-bit)', 133, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Debian Wheezy 7.0 (32-bit)', 183, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Debian Wheezy 7.0 (64-bit)', 184, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Oracle Enterprise Linux 5 (32-bit)', 16, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Oracle Enterprise Linux 5 (64-bit)', 17, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Oracle Enterprise Linux 5 (32-bit)', 18, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Oracle Enterprise Linux 5 (64-bit)', 19, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Oracle Enterprise Linux 5 (32-bit)', 20, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Oracle Enterprise Linux 5 (64-bit)', 21, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Oracle Enterprise Linux 5 (32-bit)', 22, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Oracle Enterprise Linux 5 (64-bit)', 23, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Oracle Enterprise Linux 5 (32-bit)', 24, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Oracle Enterprise Linux 5 (64-bit)', 25, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Oracle Enterprise Linux 5 (32-bit)', 134, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Oracle Enterprise Linux 5 (64-bit)', 135, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Oracle Enterprise Linux 5 (32-bit)', 145, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Oracle Enterprise Linux 5 (64-bit)', 146, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Oracle Enterprise Linux 5 (32-bit)', 207, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Oracle Enterprise Linux 5 (64-bit)', 208, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Oracle Enterprise Linux 5 (32-bit)', 209, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Oracle Enterprise Linux 5 (64-bit)', 210, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Oracle Enterprise Linux 5 (32-bit)', 211, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Oracle Enterprise Linux 5 (64-bit)', 212, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Oracle Enterprise Linux 6 (32-bit)', 147, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Oracle Enterprise Linux 6 (64-bit)', 148, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Oracle Enterprise Linux 6 (32-bit)', 213, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Oracle Enterprise Linux 6 (64-bit)', 214, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Oracle Enterprise Linux 6 (32-bit)', 215, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Oracle Enterprise Linux 6 (64-bit)', 216, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Oracle Enterprise Linux 6 (32-bit)', 217, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Oracle Enterprise Linux 6 (64-bit)', 218, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Oracle Enterprise Linux 6 (32-bit)', 219, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Oracle Enterprise Linux 6 (64-bit)', 220, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Red Hat Enterprise Linux 4.5 (32-bit)', 26, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Red Hat Enterprise Linux 4.6 (32-bit)', 27, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Red Hat Enterprise Linux 4.7 (32-bit)', 28, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Red Hat Enterprise Linux 4.8 (32-bit)', 29, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Red Hat Enterprise Linux 5 (32-bit)', 30, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Red Hat Enterprise Linux 5 (64-bit)', 31, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Red Hat Enterprise Linux 5 (32-bit)', 32, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Red Hat Enterprise Linux 5 (64-bit)', 33, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Red Hat Enterprise Linux 5 (32-bit)', 34, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Red Hat Enterprise Linux 5 (64-bit)', 35, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Red Hat Enterprise Linux 5 (32-bit)', 36, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Red Hat Enterprise Linux 5 (64-bit)', 37, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Red Hat Enterprise Linux 5 (32-bit)', 38, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Red Hat Enterprise Linux 5 (64-bit)', 39, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Red Hat Enterprise Linux 5 (32-bit)', 113, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Red Hat Enterprise Linux 5 (64-bit)', 114, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Red Hat Enterprise Linux 5 (32-bit)', 149, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Red Hat Enterprise Linux 5 (64-bit)', 150, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Red Hat Enterprise Linux 5 (32-bit)', 189, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Red Hat Enterprise Linux 5 (64-bit)', 190, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Red Hat Enterprise Linux 5 (32-bit)', 191, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Red Hat Enterprise Linux 5 (64-bit)', 192, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Red Hat Enterprise Linux 5 (32-bit)', 193, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Red Hat Enterprise Linux 5 (64-bit)', 194, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Red Hat Enterprise Linux 6 (32-bit)', 136, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Red Hat Enterprise Linux 6 (64-bit)', 137, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Red Hat Enterprise Linux 6 (32-bit)', 195, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Red Hat Enterprise Linux 6 (64-bit)', 196, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Red Hat Enterprise Linux 6 (32-bit)', 197, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Red Hat Enterprise Linux 6 (64-bit)', 198, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Red Hat Enterprise Linux 6 (32-bit)', 199, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Red Hat Enterprise Linux 6 (64-bit)', 204, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Red Hat Enterprise Linux 6 (32-bit)', 205, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Red Hat Enterprise Linux 6 (64-bit)', 206, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'SUSE Linux Enterprise Server 10 SP1 (32-bit)', 41, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'SUSE Linux Enterprise Server 10 SP1 (64-bit)', 42, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'SUSE Linux Enterprise Server 10 SP2 (32-bit)', 43, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'SUSE Linux Enterprise Server 10 SP2 (64-bit)', 44, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'SUSE Linux Enterprise Server 10 SP3 (32-bit)', 151, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'SUSE Linux Enterprise Server 10 SP3 (64-bit)', 45, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'SUSE Linux Enterprise Server 10 SP4 (32-bit)', 153, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'SUSE Linux Enterprise Server 10 SP4 (64-bit)', 152, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'SUSE Linux Enterprise Server 11 (32-bit)', 46, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'SUSE Linux Enterprise Server 11 (64-bit)', 47, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'SUSE Linux Enterprise Server 11 SP1 (32-bit)', 155, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'SUSE Linux Enterprise Server 11 SP1 (64-bit)', 154, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'SUSE Linux Enterprise Server 11 SP2 (32-bit)', 186, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'SUSE Linux Enterprise Server 11 SP2 (64-bit)', 185, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Windows 7 (32-bit)', 48, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Windows 7 (64-bit)', 49, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Windows 8 (32-bit)', 165, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Windows 8 (64-bit)', 166, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Windows Server 2003 (32-bit)', 50, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Windows Server 2003 (64-bit)', 51, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Windows Server 2003 (32-bit)', 87, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Windows Server 2003 (64-bit)', 88, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Windows Server 2003 (32-bit)', 89, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Windows Server 2003 (64-bit)', 90, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Windows Server 2008 R2 (64-bit)', 54, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Windows Server 2012 (64-bit)', 167, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Windows Server 2012 (64-bit)', 168, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Windows XP SP3 (32-bit)', 58, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Ubuntu Lucid Lynx 10.04 (32-bit)', 121, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Ubuntu Lucid Lynx 10.04 (64-bit)', 126, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Ubuntu Maverick Meerkat 10.10 (32-bit) (experimental)', 156, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Ubuntu Maverick Meerkat 10.10 (64-bit) (experimental)', 157, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Ubuntu Precise Pangolin 12.04 (32-bit)', 163, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Ubuntu Precise Pangolin 12.04 (64-bit)', 164, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Other install media', 169, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Other install media', 170, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Other install media', 98, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Other install media', 99, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Other install media', 60, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Other install media', 103, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Other install media', 200, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Other install media', 201, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Other install media', 59, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Other install media', 100, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Other install media', 202, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'Other install media', 203, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'CentOS 5 (32-bit)', 139, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '6.2.5', 'CentOS 5 (64-bit)', 140, now(), 0); +INSERT INTO `cloud`.`configuration`(category, instance, component, name, value, description, default_value) VALUES ('Advanced', 'DEFAULT', 'NetworkOrchestrationService', 'router.redundant.vrrp.interval', '1', 'seconds between VRRP broadcast. It would 3 times broadcast fail to trigger fail-over mechanism of redundant router', '1') ON DUPLICATE KEY UPDATE category='Advanced'; +CREATE TABLE `cloud`.`op_vpc_distributed_router_sequence_no` ( + `id` bigint unsigned UNIQUE NOT NULL AUTO_INCREMENT COMMENT 'id', + `vpc_id` bigint unsigned NOT NULL COMMENT 'vpc id.', + `topology_update_sequence_no` bigint unsigned COMMENT 'sequence number to be sent to hypervisor, uniquely identifies a VPC topology update', + `routing_policy__update_sequence_no` bigint unsigned COMMENT 'sequence number to be sent to hypervisor, uniquely identifies a routing policy update', + PRIMARY KEY (`id`), + UNIQUE `u_op_vpc_distributed_router_sequence_no_vpc_id`(`vpc_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +INSERT INTO `cloud`.`configuration`(category, instance, component, name, value, description, default_value) VALUES ('Advanced', 'DEFAULT', 'NetworkOrchestrationService', 'router.aggregation.command.each.timeout', '3', 'timeout in seconds for each Virtual Router command being aggregated. The final aggregation command timeout would be determined by this timeout * commands counts ', '3') ON DUPLICATE KEY UPDATE category='Advanced'; + +CREATE TABLE `cloud`.`network_acl_item_cidrs` ( + `id` bigint unsigned UNIQUE NOT NULL auto_increment, + `network_acl_item_id` bigint unsigned NOT NULL COMMENT 'Network ACL Item id', + `cidr` varchar(255) NOT NULL, + PRIMARY KEY (`id`), + CONSTRAINT `fk_network_acl_item_id` FOREIGN KEY `fk_network_acl_item_id`(`network_acl_item_id`) REFERENCES `network_acl_item`(`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + + +ALTER TABLE `cloud`.`load_balancer_healthcheck_policies` ADD COLUMN `display` tinyint(1) NOT NULL DEFAULT '1' COMMENT 'True if the policy can be displayed to the end user'; +ALTER TABLE `cloud`.`load_balancer_stickiness_policies` ADD COLUMN `display` tinyint(1) NOT NULL DEFAULT '1' COMMENT 'True if the policy can be displayed to the end user'; +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'CentOS 5 (64-bit)', 140, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Red Hat Enterprise Linux 6.0', 136, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Red Hat Enterprise Linux 6.0', 137, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Ubuntu 12.04', 164, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Ubuntu 10.10', 156, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Ubuntu 10.10', 157, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Debian GNU/Linux 5', 72, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Debian GNU/Linux 5', 15, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Debian GNU/Linux 6', 133, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Debian GNU/Linux 6', 132, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Other Linux', 69, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Other Linux', 70, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Windows Server 2008', 54, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Windows 2000', 105, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Windows NT', 64, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Windows 3.1', 65, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Other PV', 160, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'FreeBSD 10', 225, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'FreeBSD 10', 226, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Other PV', 139, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Other PV', 140, now(), 0); + +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel5Guest', 149, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'windows8Server64Guest', 168, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel5_64Guest', 114, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel6Guest', 205, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel5Guest', 34, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel5_64Guest', 33, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'winVistaGuest', 56, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel6Guest', 197, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'suse64Guest', 203, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'centosGuest', 143, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel6_64Guest', 204, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'ubuntu64Guest', 130, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel5Guest', 38, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'win2000ServGuest', 55, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'darwin11_64Guest', 224, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel4Guest', 28, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'debian4Guest', 73, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'winNetEnterprise64Guest', 51, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'darwin10_64Guest', 222, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel5Guest', 32, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'suseGuest', 96, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'other26xLinuxGuest', 75, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'winXPProGuest', 93, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'suseGuest', 202, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'winNetDatacenterGuest', 87, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'ubuntu64Guest', 100, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'darwin11Guest', 223, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'windows8_64Guest', 166, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'debian4_64Guest', 74, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel5_64Guest', 37, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'windows7Guest', 48, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'asianux3Guest', 69, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'otherGuest64', 103, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'winVista64Guest', 101, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'centosGuest', 111, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'ubuntu64Guest', 128, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel5Guest', 191, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel6Guest', 195, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'winLonghorn64Guest', 54, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'darwin10Guest', 221, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'centosGuest', 11, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'winNetWebGuest', 91, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'asianux3_64Guest', 70, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'solaris10Guest', 79, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'ubuntuGuest', 124, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'otherLinux64Guest', 99, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel6Guest', 199, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'freebsdGuest', 83, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'winNetStandardGuest', 89, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'solaris10_64Guest', 80, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'win98Guest', 62, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'ubuntu64Guest', 129, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel5_64Guest', 35, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'winNetStandard64Guest', 90, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'winNetEnterpriseGuest', 50, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel6Guest', 136, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'win95Guest', 63, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'win31Guest', 65, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'centosGuest', 5, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'suse64Guest', 110, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'debian5Guest', 15, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel6_64Guest', 198, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'debian5_64Guest', 72, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'ubuntuGuest', 123, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel6_64Guest', 196, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel5_64Guest', 192, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'centos64Guest', 8, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'winXPProGuest', 58, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'windows8Guest', 165, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel4Guest', 26, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel6_64Guest', 206, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'winNetDatacenter64Guest', 88, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel5Guest', 30, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel6_64Guest', 137, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'ubuntuGuest', 163, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'ubuntuGuest', 156, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel5Guest', 36, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'centosGuest', 13, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'windows8Server64Guest', 167, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'winXPProGuest', 57, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'centosGuest', 141, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'centos64Guest', 12, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'ubuntuGuest', 59, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'netware6Guest', 77, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'suse64Guest', 97, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'suseGuest', 109, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'centosGuest', 1, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel4Guest', 27, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel5_64Guest', 31, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel5Guest', 193, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'solaris8Guest', 82, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel5_64Guest', 150, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel5_64Guest', 39, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel5_64Guest', 190, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'ubuntuGuest', 125, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'os2Guest', 104, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel2Guest', 131, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'centos64Guest', 112, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'centos64Guest', 201, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel5Guest', 189, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'winXPPro64Guest', 94, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'otherLinuxGuest', 98, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'suse64Guest', 108, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'ubuntu64Guest', 157, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'centos64Guest', 6, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'ubuntu64Guest', 126, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel5_64Guest', 194, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'unixWare7Guest', 86, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'win2000AdvServGuest', 95, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'centos64Guest', 144, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'ubuntu64Guest', 127, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'winNetBusinessGuest', 92, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'dosGuest', 102, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'win2000ServGuest', 61, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'windows7_64Guest', 49, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'win2000ProGuest', 105, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'netware5Guest', 78, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'centosGuest', 7, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'otherGuest', 85, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'centosGuest', 200, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'ubuntuGuest', 122, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'ubuntuGuest', 121, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'oesGuest', 68, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'winLonghornGuest', 52, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'centosGuest', 3, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel4Guest', 29, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'other26xLinux64Guest', 76, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'freebsd64Guest', 84, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'centosGuest', 9, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'solaris9Guest', 81, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'otherGuest', 60, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'winLonghorn64Guest', 53, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel5Guest', 113, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'suseGuest', 107, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'centosGuest', 4, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'centos64Guest', 14, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'centos64Guest', 10, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'winNTGuest', 64, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'centos64Guest', 142, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'centosGuest', 2, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'ubuntu64Guest', 164, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel5Guest', 149, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'windows8Server64Guest', 168, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel5_64Guest', 114, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel6Guest', 205, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel5Guest', 34, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel5_64Guest', 33, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'winVistaGuest', 56, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel6Guest', 197, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'suse64Guest', 203, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'centosGuest', 143, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel6_64Guest', 204, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'ubuntu64Guest', 130, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel5Guest', 38, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'win2000ServGuest', 55, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'darwin11_64Guest', 224, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel4Guest', 28, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'debian4Guest', 73, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'winNetEnterprise64Guest', 51, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'darwin10_64Guest', 222, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel5Guest', 32, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'suseGuest', 96, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'other26xLinuxGuest', 75, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'winXPProGuest', 93, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'suseGuest', 202, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'winNetDatacenterGuest', 87, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'ubuntu64Guest', 100, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'darwin11Guest', 223, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'windows8_64Guest', 166, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'debian4_64Guest', 74, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel5_64Guest', 37, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'windows7Guest', 48, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'asianux3Guest', 69, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'otherGuest64', 103, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'winVista64Guest', 101, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'centosGuest', 111, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'ubuntu64Guest', 128, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel5Guest', 191, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel6Guest', 195, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'winLonghorn64Guest', 54, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'darwin10Guest', 221, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'centosGuest', 11, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'winNetWebGuest', 91, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'asianux3_64Guest', 70, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'solaris10Guest', 79, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'ubuntuGuest', 124, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'otherLinux64Guest', 99, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel6Guest', 199, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'freebsdGuest', 83, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'winNetStandardGuest', 89, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'solaris10_64Guest', 80, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'win98Guest', 62, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'ubuntu64Guest', 129, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel5_64Guest', 35, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'winNetStandard64Guest', 90, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'winNetEnterpriseGuest', 50, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel6Guest', 136, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'win95Guest', 63, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'win31Guest', 65, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'centosGuest', 5, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'suse64Guest', 110, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'debian5Guest', 15, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel6_64Guest', 198, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'debian5_64Guest', 72, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'ubuntuGuest', 123, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel6_64Guest', 196, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel5_64Guest', 192, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'centos64Guest', 8, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'winXPProGuest', 58, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'windows8Guest', 165, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel4Guest', 26, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel6_64Guest', 206, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'winNetDatacenter64Guest', 88, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel5Guest', 30, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel6_64Guest', 137, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'ubuntuGuest', 163, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'ubuntuGuest', 156, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel5Guest', 36, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'centosGuest', 13, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'windows8Server64Guest', 167, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'winXPProGuest', 57, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'centosGuest', 141, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'centos64Guest', 12, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'ubuntuGuest', 59, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'netware6Guest', 77, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'suse64Guest', 97, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'suseGuest', 109, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'centosGuest', 1, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel4Guest', 27, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel5_64Guest', 31, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel5Guest', 193, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'solaris8Guest', 82, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel5_64Guest', 150, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel5_64Guest', 39, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel5_64Guest', 190, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'ubuntuGuest', 125, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'os2Guest', 104, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel2Guest', 131, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'centos64Guest', 112, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'centos64Guest', 201, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel5Guest', 189, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'winXPPro64Guest', 94, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'otherLinuxGuest', 98, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'suse64Guest', 108, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'ubuntu64Guest', 157, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'centos64Guest', 6, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'ubuntu64Guest', 126, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel5_64Guest', 194, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'unixWare7Guest', 86, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'win2000AdvServGuest', 95, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'centos64Guest', 144, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'ubuntu64Guest', 127, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'winNetBusinessGuest', 92, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'dosGuest', 102, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'win2000ServGuest', 61, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'windows7_64Guest', 49, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'win2000ProGuest', 105, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'netware5Guest', 78, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'centosGuest', 7, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'otherGuest', 85, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'centosGuest', 200, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'ubuntuGuest', 122, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'ubuntuGuest', 121, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'oesGuest', 68, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'winLonghornGuest', 52, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'centosGuest', 3, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel4Guest', 29, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'other26xLinux64Guest', 76, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'freebsd64Guest', 84, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'centosGuest', 9, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'solaris9Guest', 81, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'otherGuest', 60, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'winLonghorn64Guest', 53, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel5Guest', 113, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'suseGuest', 107, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'centosGuest', 4, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'centos64Guest', 14, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'centos64Guest', 10, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'winNTGuest', 64, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'centos64Guest', 142, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'centosGuest', 2, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'ubuntu64Guest', 164, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel5Guest', 149, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'windows8Server64Guest', 168, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel5_64Guest', 114, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel6Guest', 205, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel5Guest', 34, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel5_64Guest', 33, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'winVistaGuest', 56, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel6Guest', 197, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'suse64Guest', 203, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'centosGuest', 143, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel6_64Guest', 204, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'ubuntu64Guest', 130, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel5Guest', 38, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'win2000ServGuest', 55, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'darwin11_64Guest', 224, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel4Guest', 28, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'debian4Guest', 73, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'winNetEnterprise64Guest', 51, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'darwin10_64Guest', 222, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel5Guest', 32, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'suseGuest', 96, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'other26xLinuxGuest', 75, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'winXPProGuest', 93, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'suseGuest', 202, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'winNetDatacenterGuest', 87, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'ubuntu64Guest', 100, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'darwin11Guest', 223, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'windows8_64Guest', 166, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'debian4_64Guest', 74, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel5_64Guest', 37, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'windows7Guest', 48, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'asianux3Guest', 69, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'otherGuest64', 103, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'winVista64Guest', 101, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'centosGuest', 111, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'ubuntu64Guest', 128, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel5Guest', 191, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel6Guest', 195, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'winLonghorn64Guest', 54, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'darwin10Guest', 221, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'centosGuest', 11, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'winNetWebGuest', 91, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'asianux3_64Guest', 70, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'solaris10Guest', 79, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'ubuntuGuest', 124, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'otherLinux64Guest', 99, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel6Guest', 199, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'freebsdGuest', 83, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'winNetStandardGuest', 89, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'solaris10_64Guest', 80, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'win98Guest', 62, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'ubuntu64Guest', 129, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel5_64Guest', 35, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'winNetStandard64Guest', 90, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'winNetEnterpriseGuest', 50, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel6Guest', 136, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'win95Guest', 63, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'win31Guest', 65, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'centosGuest', 5, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'suse64Guest', 110, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'debian5Guest', 15, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel6_64Guest', 198, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'debian5_64Guest', 72, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'ubuntuGuest', 123, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel6_64Guest', 196, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel5_64Guest', 192, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'centos64Guest', 8, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'winXPProGuest', 58, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'windows8Guest', 165, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel4Guest', 26, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel6_64Guest', 206, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'winNetDatacenter64Guest', 88, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel5Guest', 30, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel6_64Guest', 137, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'ubuntuGuest', 163, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'ubuntuGuest', 156, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel5Guest', 36, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'centosGuest', 13, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'windows8Server64Guest', 167, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'winXPProGuest', 57, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'centosGuest', 141, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'centos64Guest', 12, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'ubuntuGuest', 59, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'netware6Guest', 77, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'suse64Guest', 97, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'suseGuest', 109, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'centosGuest', 1, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel4Guest', 27, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel5_64Guest', 31, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel5Guest', 193, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'solaris8Guest', 82, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel5_64Guest', 150, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel5_64Guest', 39, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel5_64Guest', 190, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'ubuntuGuest', 125, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'os2Guest', 104, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel2Guest', 131, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'centos64Guest', 112, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'centos64Guest', 201, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel5Guest', 189, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'winXPPro64Guest', 94, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'otherLinuxGuest', 98, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'suse64Guest', 108, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'ubuntu64Guest', 157, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'centos64Guest', 6, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'ubuntu64Guest', 126, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel5_64Guest', 194, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'unixWare7Guest', 86, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'win2000AdvServGuest', 95, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'centos64Guest', 144, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'ubuntu64Guest', 127, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'winNetBusinessGuest', 92, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'dosGuest', 102, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'win2000ServGuest', 61, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'windows7_64Guest', 49, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'win2000ProGuest', 105, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'netware5Guest', 78, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'centosGuest', 7, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'otherGuest', 85, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'centosGuest', 200, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'ubuntuGuest', 122, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'ubuntuGuest', 121, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'oesGuest', 68, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'winLonghornGuest', 52, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'centosGuest', 3, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel4Guest', 29, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'other26xLinux64Guest', 76, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'freebsd64Guest', 84, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'centosGuest', 9, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'solaris9Guest', 81, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'otherGuest', 60, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'winLonghorn64Guest', 53, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel5Guest', 113, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'suseGuest', 107, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'centosGuest', 4, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'centos64Guest', 14, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'centos64Guest', 10, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'winNTGuest', 64, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'centos64Guest', 142, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'centosGuest', 2, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'ubuntu64Guest', 164, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel5Guest', 149, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'windows8Server64Guest', 168, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel5_64Guest', 114, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel6Guest', 205, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel5Guest', 34, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel5_64Guest', 33, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'winVistaGuest', 56, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel6Guest', 197, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'suse64Guest', 203, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'centosGuest', 143, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel6_64Guest', 204, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'ubuntu64Guest', 130, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel5Guest', 38, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'win2000ServGuest', 55, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'darwin11_64Guest', 224, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel4Guest', 28, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'debian4Guest', 73, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'winNetEnterprise64Guest', 51, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'darwin10_64Guest', 222, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel5Guest', 32, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'suseGuest', 96, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'other26xLinuxGuest', 75, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'winXPProGuest', 93, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'suseGuest', 202, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'winNetDatacenterGuest', 87, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'ubuntu64Guest', 100, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'darwin11Guest', 223, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'windows8_64Guest', 166, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'debian4_64Guest', 74, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel5_64Guest', 37, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'windows7Guest', 48, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'asianux3Guest', 69, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'otherGuest64', 103, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'winVista64Guest', 101, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'centosGuest', 111, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'ubuntu64Guest', 128, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel5Guest', 191, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel6Guest', 195, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'winLonghorn64Guest', 54, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'darwin10Guest', 221, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'centosGuest', 11, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'winNetWebGuest', 91, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'asianux3_64Guest', 70, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'solaris10Guest', 79, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'ubuntuGuest', 124, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'otherLinux64Guest', 99, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel6Guest', 199, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'freebsdGuest', 83, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'winNetStandardGuest', 89, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'solaris10_64Guest', 80, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'win98Guest', 62, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'ubuntu64Guest', 129, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel5_64Guest', 35, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'winNetStandard64Guest', 90, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'winNetEnterpriseGuest', 50, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel6Guest', 136, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'win95Guest', 63, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'win31Guest', 65, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'centosGuest', 5, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'suse64Guest', 110, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'debian5Guest', 15, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel6_64Guest', 198, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'debian5_64Guest', 72, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'ubuntuGuest', 123, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel6_64Guest', 196, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel5_64Guest', 192, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'centos64Guest', 8, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'winXPProGuest', 58, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'windows8Guest', 165, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel4Guest', 26, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel6_64Guest', 206, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'winNetDatacenter64Guest', 88, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel5Guest', 30, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel6_64Guest', 137, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'ubuntuGuest', 163, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'ubuntuGuest', 156, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel5Guest', 36, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'centosGuest', 13, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'windows8Server64Guest', 167, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'winXPProGuest', 57, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'centosGuest', 141, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'centos64Guest', 12, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'ubuntuGuest', 59, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'netware6Guest', 77, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'suse64Guest', 97, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'suseGuest', 109, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'centosGuest', 1, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel4Guest', 27, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel5_64Guest', 31, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel5Guest', 193, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'solaris8Guest', 82, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel5_64Guest', 150, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel5_64Guest', 39, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel5_64Guest', 190, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'ubuntuGuest', 125, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'os2Guest', 104, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel2Guest', 131, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'centos64Guest', 112, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'centos64Guest', 201, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel5Guest', 189, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'winXPPro64Guest', 94, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'otherLinuxGuest', 98, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'suse64Guest', 108, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'ubuntu64Guest', 157, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'centos64Guest', 6, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'ubuntu64Guest', 126, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel5_64Guest', 194, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'unixWare7Guest', 86, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'win2000AdvServGuest', 95, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'centos64Guest', 144, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'ubuntu64Guest', 127, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'winNetBusinessGuest', 92, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'dosGuest', 102, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'win2000ServGuest', 61, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'windows7_64Guest', 49, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'win2000ProGuest', 105, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'netware5Guest', 78, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'centosGuest', 7, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'otherGuest', 85, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'centosGuest', 200, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'ubuntuGuest', 122, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'ubuntuGuest', 121, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'oesGuest', 68, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'winLonghornGuest', 52, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'centosGuest', 3, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel4Guest', 29, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'other26xLinux64Guest', 76, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'freebsd64Guest', 84, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'centosGuest', 9, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'solaris9Guest', 81, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'otherGuest', 60, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'winLonghorn64Guest', 53, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel5Guest', 113, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'suseGuest', 107, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'centosGuest', 4, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'centos64Guest', 14, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'centos64Guest', 10, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'winNTGuest', 64, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'centos64Guest', 142, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'centosGuest', 2, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'ubuntu64Guest', 164, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel5Guest', 149, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'windows8Server64Guest', 168, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel5_64Guest', 114, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel6Guest', 205, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel5Guest', 34, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel5_64Guest', 33, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'winVistaGuest', 56, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel6Guest', 197, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'suse64Guest', 203, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'centosGuest', 143, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel6_64Guest', 204, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'ubuntu64Guest', 130, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel5Guest', 38, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'win2000ServGuest', 55, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'darwin11_64Guest', 224, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel4Guest', 28, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'debian4Guest', 73, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'winNetEnterprise64Guest', 51, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'darwin10_64Guest', 222, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel5Guest', 32, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'suseGuest', 96, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'other26xLinuxGuest', 75, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'winXPProGuest', 93, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'suseGuest', 202, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'winNetDatacenterGuest', 87, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'ubuntu64Guest', 100, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'darwin11Guest', 223, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'windows8_64Guest', 166, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'debian4_64Guest', 74, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel5_64Guest', 37, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'windows7Guest', 48, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'asianux3Guest', 69, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'otherGuest64', 103, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'winVista64Guest', 101, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'centosGuest', 111, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'ubuntu64Guest', 128, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel5Guest', 191, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel6Guest', 195, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'winLonghorn64Guest', 54, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'darwin10Guest', 221, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'centosGuest', 11, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'winNetWebGuest', 91, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'asianux3_64Guest', 70, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'solaris10Guest', 79, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'ubuntuGuest', 124, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'otherLinux64Guest', 99, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel6Guest', 199, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'freebsdGuest', 83, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'winNetStandardGuest', 89, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'solaris10_64Guest', 80, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'win98Guest', 62, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'ubuntu64Guest', 129, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel5_64Guest', 35, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'winNetStandard64Guest', 90, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'winNetEnterpriseGuest', 50, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel6Guest', 136, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'win95Guest', 63, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'win31Guest', 65, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'centosGuest', 5, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'suse64Guest', 110, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'debian5Guest', 15, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel6_64Guest', 198, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'debian5_64Guest', 72, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'ubuntuGuest', 123, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel6_64Guest', 196, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel5_64Guest', 192, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'centos64Guest', 8, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'winXPProGuest', 58, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'windows8Guest', 165, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel4Guest', 26, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel6_64Guest', 206, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'winNetDatacenter64Guest', 88, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel5Guest', 30, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel6_64Guest', 137, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'ubuntuGuest', 163, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'ubuntuGuest', 156, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel5Guest', 36, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'centosGuest', 13, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'windows8Server64Guest', 167, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'winXPProGuest', 57, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'centosGuest', 141, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'centos64Guest', 12, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'ubuntuGuest', 59, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'netware6Guest', 77, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'suse64Guest', 97, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'suseGuest', 109, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'centosGuest', 1, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel4Guest', 27, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel5_64Guest', 31, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel5Guest', 193, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'solaris8Guest', 82, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel5_64Guest', 150, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel5_64Guest', 39, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel5_64Guest', 190, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'ubuntuGuest', 125, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'os2Guest', 104, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel2Guest', 131, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'centos64Guest', 112, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'centos64Guest', 201, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel5Guest', 189, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'winXPPro64Guest', 94, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'otherLinuxGuest', 98, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'suse64Guest', 108, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'ubuntu64Guest', 157, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'centos64Guest', 6, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'ubuntu64Guest', 126, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel5_64Guest', 194, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'unixWare7Guest', 86, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'win2000AdvServGuest', 95, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'centos64Guest', 144, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'ubuntu64Guest', 127, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'winNetBusinessGuest', 92, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'dosGuest', 102, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'win2000ServGuest', 61, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'windows7_64Guest', 49, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'win2000ProGuest', 105, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'netware5Guest', 78, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'centosGuest', 7, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'otherGuest', 85, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'centosGuest', 200, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'ubuntuGuest', 122, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'ubuntuGuest', 121, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'oesGuest', 68, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'winLonghornGuest', 52, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'centosGuest', 3, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel4Guest', 29, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'other26xLinux64Guest', 76, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'freebsd64Guest', 84, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'centosGuest', 9, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'solaris9Guest', 81, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'otherGuest', 60, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'winLonghorn64Guest', 53, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel5Guest', 113, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'suseGuest', 107, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'centosGuest', 4, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'centos64Guest', 14, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'centos64Guest', 10, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'winNTGuest', 64, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'centos64Guest', 142, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'centosGuest', 2, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'ubuntu64Guest', 164, now(), 0); + +alter table `cloud`.`user_ip_address` add column removed datetime DEFAULT NULL COMMENT 'date removed'; +alter table `cloud`.`user_ip_address` add column created datetime NULL COMMENT 'date created'; + +alter table `cloud`.`vlan` add column removed datetime DEFAULT NULL COMMENT 'date removed'; +alter table `cloud`.`vlan` add column created datetime NULL COMMENT 'date created'; + +alter table `cloud`.`user_ip_address` drop key public_ip_address; +alter table `cloud`.`user_ip_address` add UNIQUE KEY public_ip_address (public_ip_address,source_network_id, removed); + + +CREATE TABLE `cloud`.`load_balancer_stickiness_policy_details` ( + `id` bigint unsigned NOT NULL auto_increment, + `lb_policy_id` bigint unsigned NOT NULL COMMENT 'resource id', + `name` varchar(255) NOT NULL, + `value` varchar(1024) NOT NULL, + `display` tinyint(1) NOT NULL DEFAULT '1' COMMENT 'True if the detail can be displayed to the end user', + PRIMARY KEY (`id`), + CONSTRAINT `fk_lb_stickiness_policy_details__lb_stickiness_policy_id` FOREIGN KEY `fk_lb_stickiness_policy_details__lb_stickiness_policy_id`(`lb_policy_id`) REFERENCES `load_balancer_stickiness_policies`(`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + + +CREATE TABLE `cloud`.`load_balancer_healthcheck_policy_details` ( + `id` bigint unsigned NOT NULL auto_increment, + `lb_policy_id` bigint NOT NULL COMMENT 'resource id', + `name` varchar(255) NOT NULL, + `value` varchar(1024) NOT NULL, + `display` tinyint(1) NOT NULL DEFAULT '1' COMMENT 'True if the detail can be displayed to the end user', + PRIMARY KEY (`id`), + CONSTRAINT `fk_lb_healthcheck_policy_details__lb_healthcheck_policy_id` FOREIGN KEY `fk_lb_healthcheck_policy_details__lb_healthcheck_policy_id`(`lb_policy_id`) REFERENCES `load_balancer_healthcheck_policies`(`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +ALTER TABLE `cloud`.`snapshot_policy` ADD COLUMN `display` tinyint(1) NOT NULL DEFAULT '1' COMMENT 'True if the policy can be displayed to the end user'; + +CREATE TABLE `cloud`.`snapshot_policy_details` ( + `id` bigint unsigned NOT NULL auto_increment, + `policy_id` bigint unsigned NOT NULL COMMENT 'snapshot policy id', + `name` varchar(255) NOT NULL, + `value` varchar(1024) NOT NULL, + `display` tinyint(1) NOT NULL DEFAULT '1' COMMENT 'True if the detail can be displayed to the end user', + PRIMARY KEY (`id`), + CONSTRAINT `fk_snapshot_policy_details__snapshot_policy_id` FOREIGN KEY `fk_snapshot_policy_details__snapshot_policy_id`(`policy_id`) REFERENCES `snapshot_policy`(`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +INSERT INTO `cloud`.`configuration`(category, instance, component, name, value, description, default_value) VALUES ('Advanced', 'DEFAULT', 'management-server', 'vm.password.length', '6', 'Specifies the length of a randomly generated password', '6') ON DUPLICATE KEY UPDATE category='Advanced'; \ No newline at end of file diff --git a/setup/db/templates.sql b/setup/db/templates.sql index 329932060e..6a74633efc 100755 --- a/setup/db/templates.sql +++ b/setup/db/templates.sql @@ -16,13 +16,13 @@ -- under the License. INSERT INTO `cloud`.`vm_template` (id, uuid, unique_name, name, public, created, type, hvm, bits, account_id, url, checksum, enable_password, display_text, format, guest_os_id, featured, cross_zones, hypervisor_type) - VALUES (1, UUID(), 'routing-1', 'SystemVM Template (XenServer)', 0, now(), 'SYSTEM', 0, 32, 1, 'http://download.cloud.com/templates/4.2/systemvmtemplate-2013-07-12-master-xen.vhd.bz2', '74b92f031cc5c2089ee89efb81344dcf', 0, 'SystemVM Template (XenServer)', 'VHD', 183, 0, 1, 'XenServer' ); + VALUES (1, UUID(), 'routing-1', 'SystemVM Template (XenServer)', 0, now(), 'SYSTEM', 0, 64, 1, 'http://download.cloud.com/templates/4.3/systemvm64template-2014-01-14-master-xen.vhd.bz2', '74b92f031cc5c2089ee89efb81344dcf', 0, 'SystemVM Template (XenServer)', 'VHD', 183, 0, 1, 'XenServer' ); INSERT INTO `cloud`.`vm_template` (id, uuid, unique_name, name, public, created, removed, type, hvm, bits, account_id, url, checksum, enable_password, display_text, format, guest_os_id, featured, cross_zones, hypervisor_type, extractable) VALUES (2, UUID(), 'centos53-x86_64', 'CentOS 5.3(64-bit) no GUI (XenServer)', 1, now(), now(), 'BUILTIN', 0, 64, 1, 'http://download.cloud.com/templates/builtin/f59f18fb-ae94-4f97-afd2-f84755767aca.vhd.bz2', 'b63d854a9560c013142567bbae8d98cf', 0, 'CentOS 5.3(64-bit) no GUI (XenServer)', 'VHD', 12, 1, 1, 'XenServer', 1); INSERT INTO `cloud`.`vm_template` (id, uuid, unique_name, name, public, created, type, hvm, bits, account_id, url, checksum, enable_password, display_text, format, guest_os_id, featured, cross_zones, hypervisor_type) - VALUES (3, UUID(), 'routing-3', 'SystemVM Template (KVM)', 0, now(), 'SYSTEM', 0, 64, 1, 'http://download.cloud.com/templates/4.2/systemvmtemplate-2013-06-12-master-kvm.qcow2.bz2', '6cea42b2633841648040becb588bd8f0', 0, 'SystemVM Template (KVM)', 'QCOW2', 15, 0, 1, 'KVM' ); + VALUES (3, UUID(), 'routing-3', 'SystemVM Template (KVM)', 0, now(), 'SYSTEM', 0, 64, 1, 'http://download.cloud.com/templates/4.3/systemvm64template-2014-01-14-master-kvm.qcow2.bz2', '85a1bed07bf43cbf022451cb2ecae4ff', 0, 'SystemVM Template (KVM)', 'QCOW2', 15, 0, 1, 'KVM' ); INSERT INTO `cloud`.`vm_template` (id, uuid, unique_name, name, public, created, type, hvm, bits, account_id, url, checksum, display_text, enable_password, format, guest_os_id, featured, cross_zones, hypervisor_type, extractable) VALUES (4, UUID(), 'centos55-x86_64', 'CentOS 5.5(64-bit) no GUI (KVM)', 1, now(), 'BUILTIN', 0, 64, 1, 'http://download.cloud.com/releases/2.2.0/eec2209b-9875-3c8d-92be-c001bd8a0faf.qcow2.bz2', 'ed0e788280ff2912ea40f7f91ca7a249', 'CentOS 5.5(64-bit) no GUI (KVM)', 0, 'QCOW2', 112, 1, 1, 'KVM', 1); @@ -68,7 +68,7 @@ INSERT INTO `cloud`.`guest_os` (id, uuid, category_id, display_name) VALUES (11, INSERT INTO `cloud`.`guest_os` (id, uuid, category_id, display_name) VALUES (12, UUID(), 1, 'CentOS 5.3 (64-bit)'); INSERT INTO `cloud`.`guest_os` (id, uuid, category_id, display_name) VALUES (13, UUID(), 1, 'CentOS 5.4 (32-bit)'); INSERT INTO `cloud`.`guest_os` (id, uuid, category_id, display_name) VALUES (14, UUID(), 1, 'CentOS 5.4 (64-bit)'); -INSERT INTO `cloud`.`guest_os` (id, uuid, category_id, display_name) VALUES (15, UUID(), 2, 'Debian GNU/Linux 5.0 (32-bit)'); +INSERT INTO `cloud`.`guest_os` (id, uuid, category_id, display_name) VALUES (15, UUID(), 2, 'Debian GNU/Linux 5.0 (64-bit)'); INSERT INTO `cloud`.`guest_os` (id, uuid, category_id, display_name) VALUES (16, UUID(), 3, 'Oracle Enterprise Linux 5.0 (32-bit)'); INSERT INTO `cloud`.`guest_os` (id, uuid, category_id, display_name) VALUES (17, UUID(), 3, 'Oracle Enterprise Linux 5.0 (64-bit)'); INSERT INTO `cloud`.`guest_os` (id, uuid, category_id, display_name) VALUES (18, UUID(), 3, 'Oracle Enterprise Linux 5.1 (32-bit)'); diff --git a/systemvm/js/ajaxkeys.js b/systemvm/js/ajaxkeys.js index 60c9798fca..8f78cc8a45 100644 --- a/systemvm/js/ajaxkeys.js +++ b/systemvm/js/ajaxkeys.js @@ -169,8 +169,7 @@ KEYBOARD_TYPE_UK = "uk"; var keyboardTables = [ {tindex: 0, keyboardType: KEYBOARD_TYPE_COOKED, mappingTable: - {X11: [ {keycode: 220, entry: X11_KEY_YEN_MARK}, - {keycode: 226, entry: X11_KEY_REVERSE_SOLIUS}, + {X11: [ {keycode: 226, entry: X11_KEY_REVERSE_SOLIUS}, {keycode: 240, entry: [ {type: KEY_DOWN, code: X11_KEY_CAPSLOCK, modifiers: 0 }, diff --git a/systemvm/patches/debian/config/etc/init.d/cloud b/systemvm/patches/debian/config/etc/init.d/cloud index 83853bcd4e..b18b8b1c8a 100755 --- a/systemvm/patches/debian/config/etc/init.d/cloud +++ b/systemvm/patches/debian/config/etc/init.d/cloud @@ -75,17 +75,15 @@ _failure() { } RETVAL=$? CLOUDSTACK_HOME="/usr/local/cloud" +if [ -f $CLOUDSTACK_HOME/systemvm/utils.sh ]; +then + . $CLOUDSTACK_HOME/systemvm/utils.sh +else + _failure +fi # mkdir -p /var/log/vmops -get_pids() { - local i - for i in $(ps -ef| grep java | grep -v grep | awk '{print $2}'); - do - echo $(pwdx $i) | grep "$CLOUDSTACK_HOME" | awk -F: '{print $1}'; - done -} - start() { local pid=$(get_pids) if [ "$pid" != "" ]; then diff --git a/systemvm/patches/debian/config/etc/init.d/cloud-early-config b/systemvm/patches/debian/config/etc/init.d/cloud-early-config index 5751f09ac3..bbf1998a21 100755 --- a/systemvm/patches/debian/config/etc/init.d/cloud-early-config +++ b/systemvm/patches/debian/config/etc/init.d/cloud-early-config @@ -30,13 +30,13 @@ PATH="/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin" #set -x #exec 3>&0 4>&1 > /var/log/test.log 2>&1 #start hv_kvp daemon -/usr/sbin/hv_kvp_daemon +[ -f /usr/sbin/hv_kvp_daemon ] && /usr/sbin/hv_kvp_daemon # Fix haproxy directory issue mkdir -p /var/lib/haproxy # Clear boot up flag, it would be created by rc.local after boot up done -rm /var/cache/cloud/boot_up_done +rm -f /var/cache/cloud/boot_up_done [ -x /sbin/ifup ] || exit 0 @@ -44,7 +44,7 @@ rm /var/cache/cloud/boot_up_done log_it() { echo "$(date) $@" >> /var/log/cloud.log - log_action_begin_msg "$@" + log_action_msg "$@" } init_interfaces_orderby_macs() { @@ -387,6 +387,7 @@ setup_interface() { setup_interface_ipv6() { sysctl net.ipv6.conf.all.disable_ipv6=0 + sysctl net.ipv6.conf.all.forwarding=1 sysctl net.ipv6.conf.all.accept_ra=1 local intfnum=$1 @@ -865,6 +866,12 @@ setup_redundant_router() { sed -i "s/\[RROUTER_LOG\]/$rrouter_log_str/g" $rrouter_bin_path/check_heartbeat.sh sed -i "s/\[RROUTER_LOG\]/$rrouter_log_str/g" $rrouter_bin_path/arping_gateways.sh sed -i "s/\[RROUTER_LOG\]/$rrouter_log_str/g" /opt/cloud/bin/checkrouter.sh + + if [ $ADVERT_INT ] + then + sed -i "s/advert_int 1/advert_int $ADVERT_INT/g" /etc/keepalived/keepalived.conf + fi + chmod a+x $rrouter_bin_path/*.sh sed -i "s/--exec\ \$DAEMON;/--exec\ \$DAEMON\ --\ --vrrp;/g" /etc/init.d/keepalived @@ -885,6 +892,9 @@ setup_aesni() { setup_router() { log_it "Setting up virtual router system vm" + #To save router public interface and gw ip information + touch /var/cache/cloud/ifaceGwIp + oldmd5= [ -f "/etc/udev/rules.d/70-persistent-net.rules" ] && oldmd5=$(md5sum "/etc/udev/rules.d/70-persistent-net.rules" | awk '{print $1}') @@ -1073,8 +1083,16 @@ setup_dhcpsrvr() { enable_svc cloud 0 enable_fwding 0 chkconfig nfs-common off + cp /etc/iptables/iptables-router /etc/iptables/rules.v4 cp /etc/iptables/iptables-router /etc/iptables/rules + + #Only allow DNS service for current network + sed -i "s/-A INPUT -i eth0 -p udp -m udp --dport 53 -j ACCEPT/-A INPUT -i eth0 -p udp -m udp --dport 53 -s $DHCP_RANGE\/$CIDR_SIZE -j ACCEPT/g" /etc/iptables/rules.v4 + sed -i "s/-A INPUT -i eth0 -p udp -m udp --dport 53 -j ACCEPT/-A INPUT -i eth0 -p udp -m udp --dport 53 -s $DHCP_RANGE\/$CIDR_SIZE -j ACCEPT/g" /etc/iptables/rules + sed -i "s/-A INPUT -i eth0 -p tcp -m tcp --dport 53 -j ACCEPT/-A INPUT -i eth0 -p tcp -m tcp --dport 53 -s $DHCP_RANGE\/$CIDR_SIZE -j ACCEPT/g" /etc/iptables/rules.v4 + sed -i "s/-A INPUT -i eth0 -p tcp -m tcp --dport 53 -j ACCEPT/-A INPUT -i eth0 -p tcp -m tcp --dport 53 -s $DHCP_RANGE\/$CIDR_SIZE -j ACCEPT/g" /etc/iptables/rules + if [ "$SSHONGUEST" == "true" ] then setup_sshd $ETH0_IP "eth0" @@ -1100,6 +1118,7 @@ setup_storage_network() { setup_secstorage() { log_it "Setting up secondary storage system vm" + sysctl vm.min_free_kbytes=8192 local hyp=$1 setup_common eth0 eth1 eth2 setup_storage_network @@ -1419,6 +1438,12 @@ for i in $CMDLINE vpccidr) VPCCIDR=$VALUE ;; + cidrsize) + CIDR_SIZE=$VALUE + ;; + advert_int) + ADVERT_INT=$VALUE + ;; esac done diff --git a/systemvm/patches/debian/config/etc/logrotate.d/conntrackd b/systemvm/patches/debian/config/etc/logrotate.d/conntrackd new file mode 100644 index 0000000000..d09d752e11 --- /dev/null +++ b/systemvm/patches/debian/config/etc/logrotate.d/conntrackd @@ -0,0 +1,13 @@ +/var/log/conntrackd-stats.log { + daily + rotate 2 + missingok + compress + delaycompress + + postrotate + if [ -e /var/run/conntrackd.sock ]; then + invoke-rc.d conntrackd restart > /dev/null + fi + endscript +} diff --git a/systemvm/patches/debian/config/etc/logrotate.d/dnsmasq b/systemvm/patches/debian/config/etc/logrotate.d/dnsmasq index 838415d304..265459077f 100644 --- a/systemvm/patches/debian/config/etc/logrotate.d/dnsmasq +++ b/systemvm/patches/debian/config/etc/logrotate.d/dnsmasq @@ -8,6 +8,6 @@ postrotate [ ! -f /var/run/dnsmasq/dnsmasq.pid ] || kill -USR2 `cat /var/run/dnsmasq/dnsmasq.pid` endscript - create 0640 nobody root + create 0640 dnsmasq root } diff --git a/systemvm/patches/debian/config/etc/modprobe.d/aesni_intel b/systemvm/patches/debian/config/etc/modprobe.d/aesni_intel deleted file mode 100644 index 1c140f0a9b..0000000000 --- a/systemvm/patches/debian/config/etc/modprobe.d/aesni_intel +++ /dev/null @@ -1 +0,0 @@ -blacklist aesni_intel diff --git a/systemvm/patches/debian/config/etc/modprobe.d/aesni_intel.conf b/systemvm/patches/debian/config/etc/modprobe.d/aesni_intel.conf new file mode 100644 index 0000000000..2bc7cb15fc --- /dev/null +++ b/systemvm/patches/debian/config/etc/modprobe.d/aesni_intel.conf @@ -0,0 +1,17 @@ +# 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. +blacklist aesni_intel diff --git a/systemvm/patches/debian/config/etc/modprobe.d/pcspkr.conf b/systemvm/patches/debian/config/etc/modprobe.d/pcspkr.conf new file mode 100644 index 0000000000..892b51fef5 --- /dev/null +++ b/systemvm/patches/debian/config/etc/modprobe.d/pcspkr.conf @@ -0,0 +1,17 @@ +# 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. +blacklist pcspkr \ No newline at end of file diff --git a/systemvm/patches/debian/config/etc/rc.local b/systemvm/patches/debian/config/etc/rc.local index 6119497596..fd3488e6f5 100755 --- a/systemvm/patches/debian/config/etc/rc.local +++ b/systemvm/patches/debian/config/etc/rc.local @@ -14,5 +14,16 @@ do service $svc stop done +CMDLINE=$(cat /var/cache/cloud/cmdline) +router=$(echo "$CMDLINE" | grep -o type=router) +vpcrouter=$(echo "$CMDLINE" | grep -o type=vpcrouter) + +if [ "$router" != "" ] || [ "$vpcrouter" != "" ] +then + echo 1000000 > /proc/sys/net/ipv4/netfilter/ip_conntrack_max + echo 1000000 > /proc/sys/net/netfilter/nf_conntrack_max + echo 1000000 > /proc/sys/net/nf_conntrack_max +fi + date > /var/cache/cloud/boot_up_done logger -t cloud "Boot up process done" diff --git a/systemvm/patches/debian/config/etc/sysctl.conf b/systemvm/patches/debian/config/etc/sysctl.conf index 586d5bdb7c..961d471dfa 100644 --- a/systemvm/patches/debian/config/etc/sysctl.conf +++ b/systemvm/patches/debian/config/etc/sysctl.conf @@ -42,8 +42,8 @@ net.ipv4.tcp_max_tw_buckets=1000000 net.core.somaxconn=1000000 # Disable IPv6 -net.ipv6.conf.all.disable_ipv6 = 0 -net.ipv6.conf.all.forwarding = 1 -net.ipv6.conf.all.accept_ra = 1 +net.ipv6.conf.all.disable_ipv6 = 1 +net.ipv6.conf.all.forwarding = 0 +net.ipv6.conf.all.accept_ra = 0 net.ipv6.conf.all.accept_redirects = 0 net.ipv6.conf.all.autoconf = 0 diff --git a/systemvm/patches/debian/config/opt/cloud/bin/edithosts.sh b/systemvm/patches/debian/config/opt/cloud/bin/edithosts.sh index 8e7ddac8fd..4912bcecc7 100755 --- a/systemvm/patches/debian/config/opt/cloud/bin/edithosts.sh +++ b/systemvm/patches/debian/config/opt/cloud/bin/edithosts.sh @@ -99,7 +99,7 @@ if [ $dnsmasq_managed_lease ] then #release previous dhcp lease if present logger -t cloud "edithosts: releasing $ipv4" - dhcp_release eth0 $ipv4 $(grep "$ipv4 " $DHCP_LEASES | awk '{print $2}') > /dev/null 2>&1 + dhcp_release $(ip route get "$ipv4/32" | grep " dev " | sed -e "s/^.* dev \([^ ]*\) .*$/\1/g") $ipv4 $(grep "$ipv4 " $DHCP_LEASES | awk '{print $2}') > /dev/null 2>&1 logger -t cloud "edithosts: released $ipv4" fi @@ -184,14 +184,14 @@ then echo "$ipv6 $host" >> $HOSTS fi -if [ "$dflt" != "" ] +if [ "$dflt" != "" -a "$ipv4" != "" ] then #make sure dnsmasq looks into options file sed -i /dhcp-optsfile/d /etc/dnsmasq.conf echo "dhcp-optsfile=$DHCP_OPTS" >> /etc/dnsmasq.conf tag=$(echo $ipv4 | tr '.' '_') - sed -i /$tag/d $DHCP_OPTS + sed -i /$tag,/d $DHCP_OPTS if [ "$dflt" == "0.0.0.0" ] then logger -t cloud "$0: unset default router for $ipv4" diff --git a/systemvm/patches/debian/config/opt/cloud/bin/getRouterAlerts.sh b/systemvm/patches/debian/config/opt/cloud/bin/getRouterAlerts.sh index e5e8abeffd..3f5f4a3b05 100644 --- a/systemvm/patches/debian/config/opt/cloud/bin/getRouterAlerts.sh +++ b/systemvm/patches/debian/config/opt/cloud/bin/getRouterAlerts.sh @@ -18,53 +18,38 @@ # getRouterAlerts.sh --- Send the alerts from routerServiceMonitor.log to Management Server -source /root/func.sh - -lock="biglock" -locked=$(getLockFile $lock) -if [ "$locked" != "1" ] -then - exit 1 -fi - #set -x filename=/var/log/routerServiceMonitor.log #Monitor service log file if [ -n "$1" -a -n "$2" ] then - reqdateval=$(date -d $1 +"%Y%m%d"); - reqtimeval=$(date -d $2 +"%H%M%S"); + reqDateVal=$(date -d "$1 $2" "+%s"); else - reqdateval=0 - reqtimeval=0 + reqDateVal=0 fi if [ -f $filename ] then while read line do - if [ -n "$line" ]; then - dateval=`echo $line |awk '{print $1}'` - timeval=`echo $line |awk '{print $2}'` - - todate=$(date -d "$dateval" +"%Y%m%d") > /dev/null - totime=$(date -d "$timeval" +"%H%M%S") > /dev/null - if [ "$todate" -gt "$reqdateval" ] > /dev/null + if [ -n "$line" ] then - if [ -n "$alerts" ]; then alerts="$alerts\n$line"; else alerts="$line"; fi #>> $outputfile - elif [ "$todate" -eq "$reqdateval" ] > /dev/null + dateval=`echo $line |awk '{print $1, $2}'` + IFS=',' read -a array <<< "$dateval" + dateval=${array[0]} + + toDateVal=$(date -d "$dateval" "+%s") + + if [ "$toDateVal" -gt "$reqDateVal" ] then - if [ "$totime" -gt "$reqtimeval" ] > /dev/null - then - if [ -n "$alerts" ]; then alerts="$alerts\n$line"; else alerts="$line"; fi #>> $outputfile - fi + alerts="$line\n$alerts" + else + break fi fi - done < $filename + done < <(tac $filename) fi if [ -n "$alerts" ]; then echo $alerts else echo "No Alerts" -fi - -unlock_exit 0 $lock $locked \ No newline at end of file +fi \ No newline at end of file diff --git a/systemvm/patches/debian/config/opt/cloud/bin/ipassoc.sh b/systemvm/patches/debian/config/opt/cloud/bin/ipassoc.sh index 2a9d780774..50f6b4df46 100755 --- a/systemvm/patches/debian/config/opt/cloud/bin/ipassoc.sh +++ b/systemvm/patches/debian/config/opt/cloud/bin/ipassoc.sh @@ -230,6 +230,11 @@ add_first_ip() { sudo arping -c 1 -I $ethDev -A -U -s $ipNoMask $ipNoMask; sudo arping -c 1 -I $ethDev -A -U -s $ipNoMask $ipNoMask; fi + + # add interface gateway ip info into file, used on redundant router fail over for adding routes + sed -i /"$ethDev "/d $IFACEGWIPFILE + echo "$ethDev $defaultGwIP" >> $IFACEGWIPFILE + add_routing $1 return 0 @@ -257,6 +262,7 @@ remove_first_ip() { sudo ip link set $ethDev down return 1 fi + sed -i /"$ethDev "/d $IFACEGWIPFILE remove_routing $1 sudo ip link set $ethDev down return $? @@ -344,6 +350,7 @@ op="" is_master=0 is_redundant=0 if_keep_state=0 +IFACEGWIPFILE='/var/cache/cloud/ifaceGwIp' grep "redundant_router=1" /var/cache/cloud/cmdline > /dev/null if [ $? -eq 0 ] then diff --git a/systemvm/patches/debian/config/opt/cloud/bin/monitor_service.sh b/systemvm/patches/debian/config/opt/cloud/bin/monitor_service.sh index a5e704d4db..dfc6463bab 100755 --- a/systemvm/patches/debian/config/opt/cloud/bin/monitor_service.sh +++ b/systemvm/patches/debian/config/opt/cloud/bin/monitor_service.sh @@ -45,7 +45,7 @@ processname=$(echo $s | cut -d: -f2); service_name=$(echo $s | cut -d: -f3); pidfile=$(echo $s | cut -d: -f4); -echo $service >> $configFile; +echo "$service" >> $configFile; echo $processname >> $configFile echo $service_name >> $configFile echo $pidfile >> $configFile diff --git a/systemvm/patches/debian/config/opt/cloud/bin/savepassword.sh b/systemvm/patches/debian/config/opt/cloud/bin/savepassword.sh index 1ea27e5b70..21fa09d5b7 100755 --- a/systemvm/patches/debian/config/opt/cloud/bin/savepassword.sh +++ b/systemvm/patches/debian/config/opt/cloud/bin/savepassword.sh @@ -52,7 +52,7 @@ done [ -f $PASSWD_FILE ] || touch $PASSWD_FILE -sed -i /$VM_IP/d $PASSWD_FILE +sed -i /$VM_IP=/d $PASSWD_FILE ps aux | grep serve_password.sh |grep -v grep 2>&1 > /dev/null if [ $? -eq 0 ] diff --git a/systemvm/patches/debian/config/opt/cloud/bin/vpc_privategw_acl.sh b/systemvm/patches/debian/config/opt/cloud/bin/vpc_privategw_acl.sh index d4e3eba14a..b585a364bd 100755 --- a/systemvm/patches/debian/config/opt/cloud/bin/vpc_privategw_acl.sh +++ b/systemvm/patches/debian/config/opt/cloud/bin/vpc_privategw_acl.sh @@ -155,10 +155,12 @@ acl_entry_for_guest_network() { dflag=0 gflag=0 aflag=0 +mflag=0 rules="" rules_list="" dev="" -while getopts 'd:a:' OPTION +mac="" +while getopts 'd:a:M:' OPTION do case $OPTION in d) dflag=1 @@ -167,6 +169,9 @@ do a) aflag=1 rules="$OPTARG" ;; + M) mflag=1 + mac="$OPTARG" + ;; ?) usage unlock_exit 2 $lock $locked ;; diff --git a/systemvm/patches/debian/config/root/redundant_router/check_heartbeat.sh.templ b/systemvm/patches/debian/config/root/redundant_router/check_heartbeat.sh.templ index 95cabd6b06..d6bdc5d63e 100755 --- a/systemvm/patches/debian/config/root/redundant_router/check_heartbeat.sh.templ +++ b/systemvm/patches/debian/config/root/redundant_router/check_heartbeat.sh.templ @@ -17,12 +17,27 @@ # under the License. +STRIKE_FILE="[RROUTER_BIN_PATH]/keepalived.strikes" + if [ -e [RROUTER_BIN_PATH]/keepalived.ts2 ] then lasttime=$(cat [RROUTER_BIN_PATH]/keepalived.ts2) thistime=$(cat [RROUTER_BIN_PATH]/keepalived.ts) diff=$(($thistime - $lasttime)) + s=0 if [ $diff -lt 30 ] + then + if [ -e $STRIKE_FILE ] + then + s=`cat $STRIKE_FILE 2>/dev/null` + fi + s=$(($s+1)) + echo $s > $STRIKE_FILE + else + rm $STRIKE_FILE + fi + #3 strikes rule + if [ $s -gt 2 ] then echo Keepalived process is dead! >> [RROUTER_LOG] [RROUTER_BIN_PATH]/services.sh stop >> [RROUTER_LOG] 2>&1 diff --git a/systemvm/patches/debian/config/root/redundant_router/enable_pubip.sh.templ b/systemvm/patches/debian/config/root/redundant_router/enable_pubip.sh.templ index 0e2d03a904..a59cd66220 100644 --- a/systemvm/patches/debian/config/root/redundant_router/enable_pubip.sh.templ +++ b/systemvm/patches/debian/config/root/redundant_router/enable_pubip.sh.templ @@ -35,3 +35,16 @@ do fi done < /tmp/iflist ip route add default via [GATEWAY] dev eth2 + +while read line +do +dev=$(echo $line | awk '{print $1'}) +gw=$(echo $line | awk '{print $2'}) + +if [ "$dev" == "eth2" ] +then + continue; +fi +ip route add default via $gw table Table_$dev proto static + +done < /var/cache/cloud/ifaceGwIp diff --git a/systemvm/patches/debian/xe/xe-update-guest-attrs b/systemvm/patches/debian/xe/xe-update-guest-attrs index 30a44980b9..6c605be420 100644 --- a/systemvm/patches/debian/xe/xe-update-guest-attrs +++ b/systemvm/patches/debian/xe/xe-update-guest-attrs @@ -74,7 +74,7 @@ xenstore_write_cached() { fi # try to write and update cache if successfull - if $XENSTORE write "$key" "$newval" ; then + if $XENSTORE-write "$key" "$newval" ; then mkdir -p $(dirname "$cache") echo -n "$newval" > "$cache" XENSTORE_UPDATED=1 @@ -104,7 +104,7 @@ xenstore_rm_cached() { return 1 fi # try to write and update cache if successfull - if $XENSTORE rm "$key" ; then + if $XENSTORE-rm "$key" ; then rm -rf "$cache" XENSTORE_UPDATED=1 return 0 diff --git a/systemvm/scripts/_run.sh b/systemvm/scripts/_run.sh index 1a37c7d372..3792261c14 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 -Dlog.home=$LOGHOME -mx${maxmem}m -cp $CP com.cloud.agent.AgentShell $keyvalues $@ +java -Djavax.net.ssl.trustStore=./certs/realhostip.keystore -Djsse.enableSNIExtension=false -Dlog.home=$LOGHOME -mx${maxmem}m -cp $CP com.cloud.agent.AgentShell $keyvalues $@ diff --git a/systemvm/scripts/config_ssl.sh b/systemvm/scripts/config_ssl.sh index e474787269..69710554f1 100755 --- a/systemvm/scripts/config_ssl.sh +++ b/systemvm/scripts/config_ssl.sh @@ -24,6 +24,7 @@ help() { printf " -k path of private key\n" printf " -p path of certificate of public key\n" printf " -t path of certificate chain\n" + printf " -u path of root ca certificate \n" } @@ -53,6 +54,10 @@ config_apache2_conf() { sed -i -e "s/NameVirtualHost .*:80/NameVirtualHost $ip:80/g" /etc/apache2/ports.conf sed -i 's/ssl-cert-snakeoil.key/cert_apache.key/' /etc/apache2/sites-available/default-ssl sed -i 's/ssl-cert-snakeoil.pem/cert_apache.crt/' /etc/apache2/sites-available/default-ssl + if [ -f /etc/ssl/certs/cert_apache_chain.crt ] + then + sed -i -e "s/#SSLCertificateChainFile.*/SSLCertificateChainFile \/etc\/ssl\/certs\/cert_apache_chain.crt/" /etc/apache2/sites-available/default-ssl + fi } copy_certs() { @@ -88,12 +93,13 @@ cccflag= customPrivKey=$(dirname $0)/certs/realhostip.key customPrivCert=$(dirname $0)/certs/realhostip.crt customCertChain= +customCACert= publicIp= hostName= keyStore=$(dirname $0)/certs/realhostip.keystore aliasName="CPVMCertificate" storepass="vmops.com" -while getopts 'i:h:k:p:t:c' OPTION +while getopts 'i:h:k:p:t:u:c' OPTION do case $OPTION in c) cflag=1 @@ -107,6 +113,9 @@ do t) cccflag=1 customCertChain="$OPTARG" ;; + u) ccacflag=1 + customCACert="$OPTARG" + ;; i) publicIp="$OPTARG" ;; h) hostName="$OPTARG" @@ -165,10 +174,10 @@ then exit 2 fi -if [ -f "$customPrivCert" ] +if [ -f "$customCACert" ] then keytool -delete -alias $aliasName -keystore $keyStore -storepass $storepass -noprompt - keytool -import -alias $aliasName -keystore $keyStore -storepass $storepass -noprompt -file $customPrivCert + keytool -import -alias $aliasName -keystore $keyStore -storepass $storepass -noprompt -file $customCACert fi if [ -d /etc/apache2 ] diff --git a/systemvm/scripts/run.sh b/systemvm/scripts/run.sh index 146d96f028..76e89a8cae 100755 --- a/systemvm/scripts/run.sh +++ b/systemvm/scripts/run.sh @@ -23,15 +23,31 @@ #_run.sh runs the agent client. # set -x - +readonly PROGNAME=$(basename "$0") +readonly LOCKDIR=/tmp +readonly LOCKFD=500 + +CLOUDSTACK_HOME="/usr/local/cloud" +. $CLOUDSTACK_HOME/systemvm/utils.sh + +LOCKFILE=$LOCKDIR/$PROGNAME.xlock +lock $LOCKFILE $LOCKFD +if [ $? -eq 1 ];then + exit 1 +fi + while true do - ./_run.sh "$@" & - wait - ex=$? - if [ $ex -eq 0 ] || [ $ex -eq 1 ] || [ $ex -eq 66 ] || [ $ex -gt 128 ]; then - # permanent errors - sleep 5 + pid=$(get_pids) + action=`cat /usr/local/cloud/systemvm/user_request` + if [ "$pid" == "" ] && [ "$action" == "start" ] ; then + ./_run.sh "$@" & + wait + ex=$? + if [ $ex -eq 0 ] || [ $ex -eq 1 ] || [ $ex -eq 66 ] || [ $ex -gt 128 ]; then + # permanent errors + sleep 5 + fi fi # user stop agent by service cloud stop diff --git a/systemvm/scripts/utils.sh b/systemvm/scripts/utils.sh new file mode 100644 index 0000000000..bdd85f0b87 --- /dev/null +++ b/systemvm/scripts/utils.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash +# 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. + + +CLOUDSTACK_HOME="/usr/local/cloud" + +get_pids() { + local i + for i in $(ps -ef| grep java | grep -v grep | awk '{print $2}'); + do + echo $(pwdx $i) | grep "$CLOUDSTACK_HOME" | awk -F: '{print $1}'; + done +} + +lock() +{ + lockfile=$1 + lockfd=$2 + eval "exec $lockfd>$lockfile" + flock -n $lockfd\ + && return 0 \ + || return 1 +} diff --git a/test/integration/component/maint/test_egress_rules_host_maintenance.py b/test/integration/component/maint/test_egress_rules_host_maintenance.py index 2b817879c4..a27ada3dca 100644 --- a/test/integration/component/maint/test_egress_rules_host_maintenance.py +++ b/test/integration/component/maint/test_egress_rules_host_maintenance.py @@ -23,9 +23,9 @@ from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * from marvin.sshClient import SshClient -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * +from marvin.lib.utils import * +from marvin.lib.base import * +from marvin.lib.common import * #Import System modules import time @@ -100,19 +100,17 @@ def tearDown(self): @classmethod def setUpClass(cls): - cls.services = Services().services - cls.api_client = super( - TestEgressAfterHostMaintenance, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestEgressAfterHostMaintenance, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype cls.pod = get_pod( cls.api_client, - zoneid=cls.zone.id + zone_id=cls.zone.id ) template = get_template( diff --git a/test/integration/component/maint/test_high_availability.py b/test/integration/component/maint/test_high_availability.py index 6ada659cd4..cc687f83ea 100644 --- a/test/integration/component/maint/test_high_availability.py +++ b/test/integration/component/maint/test_high_availability.py @@ -23,9 +23,9 @@ from nose.plugins.attrib import attr from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * +from marvin.lib.utils import * +from marvin.lib.base import * +from marvin.lib.common import * from marvin.sshClient import SshClient import datetime @@ -107,24 +107,16 @@ class TestHighAvailability(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestHighAvailability, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestHighAvailability, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain( - cls.api_client, - cls.services - ) - cls.zone = get_zone( - cls.api_client, - cls.services - ) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.pod = get_pod( cls.api_client, - zoneid=cls.zone.id, - services=cls.services + zone_id=cls.zone.id ) cls.template = get_template( cls.api_client, diff --git a/test/integration/component/maint/test_host_high_availability.py b/test/integration/component/maint/test_host_high_availability.py index b4c50c7114..4cd7fd8fe8 100644 --- a/test/integration/component/maint/test_host_high_availability.py +++ b/test/integration/component/maint/test_host_high_availability.py @@ -21,9 +21,10 @@ from nose.plugins.attrib import attr from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * +from marvin.lib.utils import * +from marvin.lib.base import * +from marvin.lib.common import * +import time class Services: @@ -76,20 +77,13 @@ class TestHostHighAvailability(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestHostHighAvailability, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestHostHighAvailability, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain( - cls.api_client, - cls.services - ) - cls.zone = get_zone( - cls.api_client, - cls.services - ) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, @@ -626,11 +620,7 @@ def test_05_no_vm_with_ha_gets_migrated_to_ha_host_in_live_migration(self): #verify the VM live migration happened to another running host self.debug("Waiting for VM to come up") - wait_for_vm( - self.apiclient, - virtualmachineid=vm_with_ha_enabled.id, - interval=timeout - ) + time.sleep(timeout) vms = VirtualMachine.list( self.apiclient, @@ -758,11 +748,7 @@ def test_06_no_vm_without_ha_gets_migrated_to_ha_host_in_live_migration(self): #verify the VM live migration happened to another running host self.debug("Waiting for VM to come up") - wait_for_vm( - self.apiclient, - virtualmachineid=vm_with_ha_disabled.id, - interval=timeout - ) + time.sleep(timeout) vms = VirtualMachine.list( self.apiclient, diff --git a/test/integration/component/maint/test_multiple_ip_ranges.py b/test/integration/component/maint/test_multiple_ip_ranges.py index dc8021bc91..982dd7c85b 100644 --- a/test/integration/component/maint/test_multiple_ip_ranges.py +++ b/test/integration/component/maint/test_multiple_ip_ranges.py @@ -18,10 +18,10 @@ """ from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * -from marvin.cloudstackException import cloudstackAPIException -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * +from marvin.cloudstackException import CloudstackAPIException +from marvin.lib.utils import * +from marvin.lib.base import * +from marvin.lib.common import * # from netaddr import * import netaddr from nose.plugins.attrib import attr @@ -87,13 +87,15 @@ class TestMultipleIpRanges(cloudstackTestCase): """ @classmethod def setUpClass(cls): - cls.api_client = super(TestMultipleIpRanges, cls).getClsTestClient().getApiClient() - cls.dbclient = super(TestMultipleIpRanges, cls).getClsTestClient().getDbConnection() + cls.testClient = super(TestEgressAfterHostMaintenance, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.dbclient = cls.testClient.getDbConnection() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - cls.pod = get_pod(cls.api_client, cls.zone.id, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) + cls.pod = get_pod(cls.api_client, cls.zone.id) cls.services['mode'] = cls.zone.networktype cls.services["domainid"] = cls.domain.id cls.services["zoneid"] = cls.zone.id diff --git a/test/integration/component/maint/test_redundant_router.py b/test/integration/component/maint/test_redundant_router.py index 617a54673b..66bb477e04 100644 --- a/test/integration/component/maint/test_redundant_router.py +++ b/test/integration/component/maint/test_redundant_router.py @@ -16,9 +16,9 @@ # under the License. from nose.plugins.attrib import attr -from marvin.integration.lib.base import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.common import * +from marvin.lib.base import * +from marvin.lib.utils import * +from marvin.lib.common import * #Import Local Modules from marvin.cloudstackTestCase import cloudstackTestCase @@ -137,14 +137,13 @@ class TestCreateRvRNetworkOffering(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestCreateRvRNetworkOffering, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestCreateRvRNetworkOffering, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls._cleanup = [] return @@ -231,14 +230,13 @@ class TestCreateRvRNetwork(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestCreateRvRNetwork, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestCreateRvRNetwork, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, @@ -433,14 +431,13 @@ class TestCreateRvRNetworkNonDefaultGuestCidr(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestCreateRvRNetworkNonDefaultGuestCidr, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestCreateRvRNetworkNonDefaultGuestCidr, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, @@ -642,14 +639,13 @@ class TestRVRInternals(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestRVRInternals, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestRVRInternals, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, @@ -685,6 +681,7 @@ def tearDownClass(cls): def setUp(self): self.apiclient = self.testClient.getApiClient() + self.hypervisor = self.testClient.getHypervisorInfo() self.dbclient = self.testClient.getDbConnection() self.account = Account.create( self.apiclient, @@ -846,7 +843,7 @@ def test_redundantVR_internals(self): self.debug(master_router.linklocalip) # Check eth2 port for master router - if self.apiclient.hypervisor.lower() == 'vmware': + if self.hypervisor.lower() == 'vmware': result = get_process_status( self.apiclient.connection.mgtSvr, 22, @@ -854,7 +851,7 @@ def test_redundantVR_internals(self): self.apiclient.connection.passwd, master_router.linklocalip, 'ip addr show eth2', - hypervisor=self.apiclient.hypervisor + hypervisor=self.hypervisor ) else: result = get_process_status( @@ -882,7 +879,7 @@ def test_redundantVR_internals(self): ) # Check eth2 port for backup router - if self.apiclient.hypervisor.lower() == 'vmware': + if self.hypervisor.lower() == 'vmware': result = get_process_status( self.apiclient.connection.mgtSvr, 22, @@ -890,7 +887,7 @@ def test_redundantVR_internals(self): self.apiclient.connction.passwd, backup_router.linklocalip, 'ip addr show eth2', - hypervisor=self.apiclient.hypervisor + hypervisor=self.hypervisor ) else: result = get_process_status( @@ -945,14 +942,13 @@ class TestRvRRedundancy(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestRvRRedundancy, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestRvRRedundancy, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, diff --git a/test/integration/component/maint/test_redundant_router_deployment_planning.py b/test/integration/component/maint/test_redundant_router_deployment_planning.py index 879a4da774..b63cda94e5 100644 --- a/test/integration/component/maint/test_redundant_router_deployment_planning.py +++ b/test/integration/component/maint/test_redundant_router_deployment_planning.py @@ -16,9 +16,9 @@ # under the License. from nose.plugins.attrib import attr -from marvin.integration.lib.base import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.common import * +from marvin.lib.base import * +from marvin.lib.utils import * +from marvin.lib.common import * #Import Local Modules from marvin.cloudstackTestCase import cloudstackTestCase @@ -136,14 +136,13 @@ class TestRvRDeploymentPlanning(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestRvRDeploymentPlanning, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestRvRDeploymentPlanning, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, diff --git a/test/integration/component/maint/test_redundant_router_network_rules.py b/test/integration/component/maint/test_redundant_router_network_rules.py index 010aaaa7b7..12c4d2c116 100644 --- a/test/integration/component/maint/test_redundant_router_network_rules.py +++ b/test/integration/component/maint/test_redundant_router_network_rules.py @@ -16,9 +16,9 @@ # under the License. from nose.plugins.attrib import attr -from marvin.integration.lib.base import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.common import * +from marvin.lib.base import * +from marvin.lib.utils import * +from marvin.lib.common import * #Import Local Modules from marvin.cloudstackTestCase import cloudstackTestCase @@ -137,14 +137,13 @@ class TestRedundantRouterRulesLifeCycle(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestRedundantRouterRulesLifeCycle, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestRedundantRouterRulesLifeCycle, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, diff --git a/test/integration/component/maint/test_vpc_host_maintenance.py b/test/integration/component/maint/test_vpc_host_maintenance.py index 57dfb4be8d..83ba2717d9 100644 --- a/test/integration/component/maint/test_vpc_host_maintenance.py +++ b/test/integration/component/maint/test_vpc_host_maintenance.py @@ -22,11 +22,9 @@ from nose.plugins.attrib import attr from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * -from marvin.sshClient import SshClient -import datetime +from marvin.lib.utils import * +from marvin.lib.base import * +from marvin.lib.common import * class Services: @@ -190,14 +188,13 @@ class TestVMLifeCycleHostmaintenance(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestVMLifeCycleHostmaintenance, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestVMLifeCycleHostmaintenance, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, @@ -554,4 +551,4 @@ def test_03_reconnect_host(self): "Router state should be running" ) # TODO: Check for the network connectivity - return \ No newline at end of file + return diff --git a/test/integration/component/maint/test_vpc_on_host_maintenance.py b/test/integration/component/maint/test_vpc_on_host_maintenance.py index 6630ee61e0..eb3360a458 100644 --- a/test/integration/component/maint/test_vpc_on_host_maintenance.py +++ b/test/integration/component/maint/test_vpc_on_host_maintenance.py @@ -18,9 +18,9 @@ from nose.plugins.attrib import attr from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * +from marvin.lib.utils import * +from marvin.lib.base import * +from marvin.lib.common import * class Services: @@ -77,14 +77,13 @@ class TestVPCHostMaintenance(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestVPCHostMaintenance, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestVPCHostMaintenance, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, diff --git a/test/integration/smoke/test_VirtualRouter_alerts.py b/test/integration/component/test_VirtualRouter_alerts.py similarity index 90% rename from test/integration/smoke/test_VirtualRouter_alerts.py rename to test/integration/component/test_VirtualRouter_alerts.py index 2333d846f1..e6f0a823fd 100644 --- a/test/integration/smoke/test_VirtualRouter_alerts.py +++ b/test/integration/component/test_VirtualRouter_alerts.py @@ -20,10 +20,11 @@ import marvin from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * +from marvin.lib.utils import * +from marvin.lib.base import * +from marvin.lib.common import * from nose.plugins.attrib import attr +from marvin.codes import FAILED import time @@ -96,12 +97,13 @@ def __init__(self): class TestVRServiceFailureAlerting(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestVRServiceFailureAlerting, cls).getClsTestClient().getApiClient() + cls.testClient = super(TestVRServiceFailureAlerting, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() cls.services = Services().services # Get Zone, Domain and templates - domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) + domain = get_domain(cls.api_client) cls.services['mode'] = cls.zone.networktype template = get_template( @@ -109,6 +111,9 @@ def setUpClass(cls): cls.zone.id, cls.services["ostype"] ) + + if template == FAILED: + assert False, "get_template() failed to return template with description %s" % cls.services["ostype"] # Set Zones and disk offerings ?? cls.services["small"]["zoneid"] = cls.zone.id cls.services["small"]["template"] = template.id @@ -148,6 +153,7 @@ def tearDownClass(cls): def setUp(self): self.apiclient = self.testClient.getApiClient() self.dbclient = self.testClient.getDbConnection() + self.hypervisor = self.testClient.getHypervisorInfo() self.cleanup = [] def tearDown(self): @@ -202,7 +208,7 @@ def test_01_VRServiceFailureAlerting(self): alertSubject = "Monitoring Service on VR " + router.name - if self.apiclient.hypervisor.lower() == 'vmware': + if self.hypervisor.lower() == 'vmware': result = get_process_status( self.apiclient.connection.mgtSvr, 22, @@ -210,7 +216,7 @@ def test_01_VRServiceFailureAlerting(self): self.apiclient.connection.passwd, router.linklocalip, "service dnsmasq status", - hypervisor=self.apiclient.hypervisor + hypervisor=self.hypervisor ) else: try: @@ -229,7 +235,7 @@ def test_01_VRServiceFailureAlerting(self): res = str(result) self.debug("apache process status: %s" % res) - time.sleep(300) #wait for 5 minutes meanwhile monitor service on VR starts the apache service + time.sleep(2400) #wait for 40 minutes meanwhile monitor service on VR starts the apache service (router.alerts.check.interval default value is 30minutes) qresultset = self.dbclient.execute( "select id from alert where subject = '%s' ORDER BY id DESC LIMIT 1;" \ diff --git a/test/integration/component/test_accounts.py b/test/integration/component/test_accounts.py index 650a595936..a60a5beba8 100644 --- a/test/integration/component/test_accounts.py +++ b/test/integration/component/test_accounts.py @@ -17,14 +17,32 @@ """ P1 tests for Account """ #Import Local Modules -from marvin.cloudstackTestCase import * -from marvin.cloudstackAPI import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * -from marvin.sshClient import SshClient +from marvin.cloudstackTestCase import cloudstackTestCase +#from marvin.cloudstackAPI import * +from marvin.lib.utils import (random_gen, + cleanup_resources) +from marvin.lib.base import (Domain, + Account, + ServiceOffering, + VirtualMachine, + Network, + User, + NATRule, + Template, + PublicIPAddress) +from marvin.lib.common import (get_domain, + get_zone, + get_template, + list_accounts, + list_virtual_machines, + list_service_offering, + list_templates, + list_users, + get_builtin_template_info, + wait_for_cleanup) from nose.plugins.attrib import attr -from marvin.cloudstackException import cloudstackAPIException +from marvin.cloudstackException import CloudstackAPIException +import time class Services: """Test Account Services @@ -102,13 +120,11 @@ class TestAccounts(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestAccounts, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestAccounts, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services - # Get Zone, Domain and templates - cls.zone = get_zone(cls.api_client, cls.services) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype cls.template = get_template( cls.api_client, @@ -148,7 +164,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags=["advanced", "basic", "eip", "advancedns", "sg"]) + @attr(tags=["advanced", "basic", "eip", "advancedns", "sg", "selfservice"]) def test_01_create_account(self): """Test Create Account and user for that account """ @@ -232,13 +248,11 @@ class TestRemoveUserFromAccount(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestRemoveUserFromAccount, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestRemoveUserFromAccount, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services - # Get Zone, Domain and templates - cls.zone = get_zone(cls.api_client, cls.services) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype cls.template = get_template( cls.api_client, @@ -258,8 +272,8 @@ def setUpClass(cls): cls.services["account"] ) - cls._cleanup = [ - cls.service_offering, + cls._cleanup = [cls.account, + cls.service_offering, ] return @@ -286,7 +300,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags=["advanced", "basic", "eip", "advancedns", "sg"]) + @attr(tags=["advanced", "basic", "eip", "advancedns", "sg", "selfservice"]) def test_01_user_remove_VM_running(self): """Test Remove one user from the account """ @@ -392,13 +406,11 @@ class TestNonRootAdminsPrivileges(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestNonRootAdminsPrivileges, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestNonRootAdminsPrivileges, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services - # Get Zone settings - cls.zone = get_zone(cls.api_client, cls.services) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype # Create an account, domain etc cls.domain = Domain.create( @@ -440,7 +452,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags=["advanced", "basic", "eip", "advancedns", "sg"]) + @attr(tags=["advanced", "basic", "eip", "advancedns", "sg", "selfservice"]) def test_01_non_root_admin_Privileges(self): """Test to verify Non Root admin previleges""" @@ -465,7 +477,8 @@ def test_01_non_root_admin_Privileges(self): accounts_response = list_accounts( self.apiclient, - domainid=self.domain.id + domainid=self.domain.id, + listall=True ) self.assertEqual( @@ -561,7 +574,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags=["advanced", "basic", "eip", "advancedns", "sg"]) + @attr(tags=["advanced", "basic", "eip", "advancedns", "sg", "selfservice"]) def test_01_service_offering_siblings(self): """Test to verify service offerings at same level in hierarchy""" @@ -679,7 +692,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags=["advanced", "basic", "eip", "advancedns", "sg"]) + @attr(tags=["advanced", "basic", "eip", "advancedns", "sg", "selfservice"]) def test_01_service_offering_hierarchy(self): """Test to verify service offerings at same level in hierarchy""" @@ -726,12 +739,12 @@ class TestTemplateHierarchy(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestTemplateHierarchy, - cls).getClsTestClient().getApiClient() + cls.testClient = super(TestTemplateHierarchy, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.hypervisor = cls.testClient.getHypervisorInfo() + cls.services = Services().services - # Get Zone settings - cls.zone = get_zone(cls.api_client, cls.services) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype # Create domains, accounts and template @@ -761,6 +774,13 @@ def setUpClass(cls): domainid=cls.domain_2.id ) + cls._cleanup = [ + cls.account_2, + cls.domain_2, + cls.account_1, + cls.domain_1, + ] + builtin_info = get_builtin_template_info(cls.api_client, cls.zone.id) cls.services["template"]["url"] = builtin_info[0] cls.services["template"]["hypervisor"] = builtin_info[1] @@ -772,7 +792,8 @@ def setUpClass(cls): cls.services["template"], zoneid=cls.zone.id, account=cls.account_1.name, - domainid=cls.domain_1.id + domainid=cls.domain_1.id, + hypervisor=cls.hypervisor ) # Wait for template to download @@ -780,14 +801,6 @@ def setUpClass(cls): # Wait for template status to be changed across time.sleep(60) - - cls._cleanup = [ - cls.account_2, - cls.domain_2, - cls.template, - cls.account_1, - cls.domain_1, - ] return @classmethod @@ -879,21 +892,12 @@ class TestAddVmToSubDomain(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestAddVmToSubDomain, - cls - ).getClsTestClient().getApiClient() - cls.services = Services().services + cls.testClient = super(TestAddVmToSubDomain, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() - # Setup working Environment- Create domain, zone, pod cluster etc. - cls.domain = get_domain( - cls.api_client, - cls.services - ) - cls.zone = get_zone( - cls.api_client, - cls.services, - ) + cls.services = Services().services + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype cls.sub_domain = Domain.create( cls.api_client, @@ -922,6 +926,13 @@ def setUpClass(cls): cls.services["service_offering"], domainid=cls.domain.id ) + + cls._cleanup = [ + cls.account_2, + cls.account_1, + cls.sub_domain, + cls.service_offering + ] cls.template = get_template( cls.api_client, cls.zone.id, @@ -945,12 +956,6 @@ def setUpClass(cls): domainid=cls.account_2.domainid, serviceofferingid=cls.service_offering.id ) - cls._cleanup = [ - cls.account_2, - cls.account_1, - cls.sub_domain, - cls.service_offering - ] return @classmethod @@ -976,7 +981,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags=["advanced", "basic", "eip", "advancedns", "sg"]) + @attr(tags=["advanced", "basic", "eip", "advancedns", "sg", "selfservice"]) def test_01_add_vm_to_subdomain(self): """ Test Sub domain allowed to launch VM when a Domain level zone is created""" @@ -1031,14 +1036,12 @@ class TestUserDetails(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestUserDetails, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestUserDetails, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services - # Get Zone, Domain etc - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype cls._cleanup = [] return @@ -1331,14 +1334,12 @@ class TestUserLogin(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestUserLogin, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestUserLogin, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services - # Get Zone, Domain etc - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype cls._cleanup = [] return @@ -1482,21 +1483,12 @@ class TestDomainForceRemove(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestDomainForceRemove, - cls - ).getClsTestClient().getApiClient() - cls.services = Services().services + cls.testClient = super(TestDomainForceRemove, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() - # Setup working Environment- Create domain, zone, pod cluster etc. - cls.domain = get_domain( - cls.api_client, - cls.services - ) - cls.zone = get_zone( - cls.api_client, - cls.services, - ) + cls.services = Services().services + 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( @@ -1533,7 +1525,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags=["domains", "advanced", "advancedns", "simulator"]) + @attr(tags=["domains", "advanced", "advancedns", "simulator", "selfservice"]) def test_forceDeleteDomain(self): """ Test delete domain with force option""" @@ -1582,16 +1574,17 @@ def test_forceDeleteDomain(self): domainid=domain.id ) - self.debug("Creating a tiny service offering for VM deployment") - self.service_offering = ServiceOffering.create( + try: + self.debug("Creating a tiny service offering for VM deployment") + self.service_offering = ServiceOffering.create( self.apiclient, self.services["service_offering"], domainid=self.domain.id ) - self.debug("Deploying virtual machine in account 1: %s" % + self.debug("Deploying virtual machine in account 1: %s" % self.account_1.name) - vm_1 = VirtualMachine.create( + vm_1 = VirtualMachine.create( self.apiclient, self.services["virtual_machine"], templateid=self.template.id, @@ -1600,9 +1593,9 @@ def test_forceDeleteDomain(self): serviceofferingid=self.service_offering.id ) - self.debug("Deploying virtual machine in account 2: %s" % + self.debug("Deploying virtual machine in account 2: %s" % self.account_2.name) - vm_2 = VirtualMachine.create( + VirtualMachine.create( self.apiclient, self.services["virtual_machine"], templateid=self.template.id, @@ -1611,22 +1604,22 @@ def test_forceDeleteDomain(self): serviceofferingid=self.service_offering.id ) - networks = Network.list( + networks = Network.list( self.apiclient, account=self.account_1.name, domainid=self.account_1.domainid, listall=True ) - self.assertEqual( + self.assertEqual( isinstance(networks, list), True, "List networks should return a valid response" ) - network_1 = networks[0] - self.debug("Default network in account 1: %s is %s" % ( + network_1 = networks[0] + self.debug("Default network in account 1: %s is %s" % ( self.account_1.name, network_1.name)) - src_nat_list = PublicIPAddress.list( + src_nat_list = PublicIPAddress.list( self.apiclient, associatednetworkid=network_1.id, account=self.account_1.name, @@ -1634,44 +1627,48 @@ def test_forceDeleteDomain(self): listall=True, issourcenat=True, ) - self.assertEqual( + self.assertEqual( isinstance(src_nat_list, list), True, "List Public IP should return a valid source NAT" ) - self.assertNotEqual( + self.assertNotEqual( len(src_nat_list), 0, "Length of response from listPublicIp should not be 0" ) - src_nat = src_nat_list[0] + src_nat = src_nat_list[0] - self.debug( - "Trying to create a port forwarding rule in source NAT: %s" % + self.debug( + "Trying to create a port forwarding rule in source NAT: %s" % src_nat.ipaddress) - #Create NAT rule - nat_rule = NATRule.create( + #Create NAT rule + nat_rule = NATRule.create( self.apiclient, vm_1, self.services["natrule"], ipaddressid=src_nat.id ) - self.debug("Created PF rule on source NAT: %s" % src_nat.ipaddress) + self.debug("Created PF rule on source NAT: %s" % src_nat.ipaddress) - nat_rules = NATRule.list(self.apiclient, id=nat_rule.id) + nat_rules = NATRule.list(self.apiclient, id=nat_rule.id) - self.assertEqual( + self.assertEqual( isinstance(nat_rules, list), True, "List NAT should return a valid port forwarding rules" ) - self.assertNotEqual( + self.assertNotEqual( len(nat_rules), 0, "Length of response from listLbRules should not be 0" ) + except Exception as e: + self.clenaup.append(self.account_1) + self.cleanup.append(self.account_2) + self.fail(e) self.debug("Deleting domain with force option") try: @@ -1681,7 +1678,7 @@ def test_forceDeleteDomain(self): " to cleanup any remaining resouces") # Sleep 3*account.gc to ensure that all resources are deleted wait_for_cleanup(self.apiclient, ["account.cleanup.interval"]*3) - with self.assertRaises(cloudstackAPIException): + with self.assertRaises(CloudstackAPIException): Domain.list( self.apiclient, id=domain.id, @@ -1689,7 +1686,7 @@ def test_forceDeleteDomain(self): ) self.debug("Checking if the resources in domain are deleted") - with self.assertRaises(cloudstackAPIException): + with self.assertRaises(CloudstackAPIException): Account.list( self.apiclient, name=self.account_1.name, @@ -1698,7 +1695,7 @@ def test_forceDeleteDomain(self): ) return - @attr(tags=["domains", "advanced", "advancedns", "simulator"]) + @attr(tags=["domains", "advanced", "advancedns", "simulator", "selfservice"]) def test_DeleteDomain(self): """ Test delete domain without force option""" @@ -1768,7 +1765,7 @@ def test_DeleteDomain(self): self.debug("Deploying virtual machine in account 2: %s" % self.account_2.name) - vm_2 = VirtualMachine.create( + VirtualMachine.create( self.apiclient, self.services["virtual_machine"], templateid=self.template.id, diff --git a/test/integration/component/test_acl_isolatednetwork.py b/test/integration/component/test_acl_isolatednetwork.py new file mode 100644 index 0000000000..59119f15c6 --- /dev/null +++ b/test/integration/component/test_acl_isolatednetwork.py @@ -0,0 +1,1151 @@ +# 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. +""" +Test cases relating to access checks for createNetwork(), deploying VM in an isolated network and restartNetwork() for Admin, domain admin and regular users +""" + +#Import Local Modules +import marvin +from marvin.cloudstackTestCase import * +from marvin.cloudstackAPI import * +from marvin.lib.utils import * +from marvin.lib.base import * +from marvin.lib.common import * +from marvin.cloudstackException import CloudstackAclException +from marvin.lib.common import * +from marvin.codes import (RUNNING, + ALLOCATED) +from nose.plugins.attrib import attr +#Import System modules +import time + +_multiprocess_shared_ = True + +class TestIsolatedNetwork(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + + """ + Create the following domain tree and accounts that are reqiured for executing Test cases relating to access checks for createNetwork(), deploying VM in an isolated network and restartNetwork(): + Under ROOT - create 2 domaind D1 and D2 + Under D1 - Create 2 subdomain D11 and D12 + Under D11 - Create subdimain D111 + + Under each of the domain create 1 admin user and couple of regular users. + + As each of these users , create an isolated network. + + """ + + cls.testclient = super(TestIsolatedNetwork, cls).getClsTestClient() + cls.apiclient = cls.testclient.getApiClient() + #cls.acldata = Services().services + cls.testdata = cls.testClient.getParsedTestDataConfig() + cls.acldata = cls.testdata["acl"] + cls.domain_1 = None + cls.domain_2 = None + cls.cleanup = [] + + + try: + + # backup default apikey and secretkey + cls.default_apikey = cls.apiclient.connection.apiKey + cls.default_secretkey = cls.apiclient.connection.securityKey + + # Create domains + cls.domain_1 = Domain.create( + cls.apiclient, + cls.acldata["domain1"] + ) + cls.domain_11 = Domain.create( + cls.apiclient, + cls.acldata["domain11"], + parentdomainid=cls.domain_1.id + ) + cls.domain_111 = Domain.create( + cls.apiclient, + cls.acldata["domain111"], + parentdomainid=cls.domain_11.id, + ) + cls.domain_12 = Domain.create( + cls.apiclient, + cls.acldata["domain12"], + parentdomainid=cls.domain_1.id + ) + cls.domain_2 = Domain.create( + cls.apiclient, + cls.acldata["domain2"] + ) + # Create 1 admin account and 2 user accounts for doamin_1 + cls.account_d1 = Account.create( + cls.apiclient, + cls.acldata["accountD1"], + admin=True, + domainid=cls.domain_1.id + ) + + user = cls.generateKeysForUser(cls.apiclient,cls.account_d1) + cls.user_d1_apikey = user.apikey + cls.user_d1_secretkey = user.secretkey + + cls.account_d1a = Account.create( + cls.apiclient, + cls.acldata["accountD1A"], + admin=False, + domainid=cls.domain_1.id + ) + user = cls.generateKeysForUser(cls.apiclient,cls.account_d1a) + cls.user_d1a_apikey = user.apikey + cls.user_d1a_secretkey = user.secretkey + + + cls.account_d1b = Account.create( + cls.apiclient, + cls.acldata["accountD1B"], + admin=False, + domainid=cls.domain_1.id + ) + + user = cls.generateKeysForUser(cls.apiclient,cls.account_d1b) + cls.user_d1b_apikey = user.apikey + cls.user_d1b_secretkey = user.secretkey + + # Create 1 admin and 2 user accounts for doamin_11 + cls.account_d11 = Account.create( + cls.apiclient, + cls.acldata["accountD11"], + admin=True, + domainid=cls.domain_11.id + ) + user = cls.generateKeysForUser(cls.apiclient,cls.account_d11) + cls.user_d11_apikey = user.apikey + cls.user_d11_secretkey = user.secretkey + + cls.account_d11a = Account.create( + cls.apiclient, + cls.acldata["accountD11A"], + admin=False, + domainid=cls.domain_11.id + ) + user = cls.generateKeysForUser(cls.apiclient,cls.account_d11a) + cls.user_d11a_apikey = user.apikey + cls.user_d11a_secretkey = user.secretkey + + cls.account_d11b = Account.create( + cls.apiclient, + cls.acldata["accountD11B"], + admin=False, + domainid=cls.domain_11.id + ) + user = cls.generateKeysForUser(cls.apiclient,cls.account_d11b) + cls.user_d11b_apikey = user.apikey + cls.user_d11b_secretkey = user.secretkey + + # Create 2 user accounts and 1 admin account for doamin_111 + + cls.account_d111 = Account.create( + cls.apiclient, + cls.acldata["accountD111"], + admin=True, + domainid=cls.domain_111.id + ) + user = cls.generateKeysForUser(cls.apiclient,cls.account_d111) + cls.user_d111_apikey = user.apikey + cls.user_d111_secretkey = user.secretkey + + cls.account_d111a = Account.create( + cls.apiclient, + cls.acldata["accountD111A"], + admin=False, + domainid=cls.domain_111.id + ) + user = cls.generateKeysForUser(cls.apiclient,cls.account_d111a) + cls.user_d111a_apikey = user.apikey + cls.user_d111a_secretkey = user.secretkey + + cls.account_d111b = Account.create( + cls.apiclient, + cls.acldata["accountD111B"], + admin=False, + domainid=cls.domain_111.id + ) + user = cls.generateKeysForUser(cls.apiclient,cls.account_d111b) + cls.user_d111b_apikey = user.apikey + cls.user_d111b_secretkey = user.secretkey + + # Create 2 user accounts for doamin_12 + cls.account_d12a = Account.create( + cls.apiclient, + cls.acldata["accountD12A"], + admin=False, + domainid=cls.domain_12.id + ) + user = cls.generateKeysForUser(cls.apiclient,cls.account_d12a) + cls.user_d12a_apikey = user.apikey + cls.user_d12a_secretkey = user.secretkey + + cls.account_d12b = Account.create( + cls.apiclient, + cls.acldata["accountD12B"], + admin=False, + domainid=cls.domain_12.id + ) + + user = cls.generateKeysForUser(cls.apiclient,cls.account_d12b) + cls.user_d12b_apikey = user.apikey + cls.user_d12b_secretkey = user.secretkey + + # Create 1 user account for domain_2 + + cls.account_d2a = Account.create( + cls.apiclient, + cls.acldata["accountD2"], + admin=False, + domainid=cls.domain_2.id + ) + + user = cls.generateKeysForUser(cls.apiclient,cls.account_d2a) + cls.user_d2a_apikey = user.apikey + cls.user_d2a_secretkey = user.secretkey + + + # Create 1 user account and admin account in "ROOT" domain + + cls.account_roota = Account.create( + cls.apiclient, + cls.acldata["accountROOTA"], + admin=False, + ) + + user = cls.generateKeysForUser(cls.apiclient,cls.account_roota) + cls.user_roota_apikey = user.apikey + cls.user_roota_secretkey = user.secretkey + + cls.account_root = Account.create( + cls.apiclient, + cls.acldata["accountROOT"], + admin=True, + ) + + user = cls.generateKeysForUser(cls.apiclient,cls.account_root) + cls.user_root_apikey = user.apikey + cls.user_root_secretkey = user.secretkey + + # create service offering + cls.service_offering = ServiceOffering.create( + cls.apiclient, + cls.acldata["service_offering"]["small"] + ) + + cls.zone = get_zone(cls.apiclient,cls.testclient.getZoneForTests()) + cls.acldata['mode'] = cls.zone.networktype + cls.template = get_template(cls.apiclient, cls.zone.id, cls.acldata["ostype"]) + + cls.apiclient.connection.apiKey = cls.default_apikey + cls.apiclient.connection.securityKey = cls.default_secretkey + + list_isolated_network_offerings_response = NetworkOffering.list( + cls.apiclient, + name="DefaultIsolatedNetworkOfferingWithSourceNatService" + ) + cls.isolated_network_offering_id = list_isolated_network_offerings_response[0].id + + ## Create Network objects for deployVirtualMachine and restartNetwork API related test cases + + cls.apiclient.connection.apiKey = cls.user_root_apikey + cls.apiclient.connection.securityKey = cls.user_root_secretkey + cls.network_root = cls.createNetwork(cls.apiclient,cls.account_root,cls.isolated_network_offering_id,cls.zone) + cls.createVM(cls.apiclient,cls.zone.id,cls.service_offering.id,cls.template.id,cls.network_root.id) + + cls.apiclient.connection.apiKey = cls.user_d1_apikey + cls.apiclient.connection.securityKey = cls.user_d1_secretkey + cls.network_d1 = cls.createNetwork(cls.apiclient,cls.account_d1,cls.isolated_network_offering_id,cls.zone) + cls.createVM(cls.apiclient,cls.zone.id,cls.service_offering.id,cls.template.id,cls.network_d1.id) + + cls.apiclient.connection.apiKey = cls.user_d1a_apikey + cls.apiclient.connection.securityKey = cls.user_d1a_secretkey + cls.network_d1a = cls.createNetwork(cls.apiclient,cls.account_d1a,cls.isolated_network_offering_id,cls.zone) + cls.createVM(cls.apiclient,cls.zone.id,cls.service_offering.id,cls.template.id,cls.network_d1a.id) + + cls.apiclient.connection.apiKey = cls.user_d1b_apikey + cls.apiclient.connection.securityKey = cls.user_d1b_secretkey + cls.network_d1b = cls.createNetwork(cls.apiclient,cls.account_d1b,cls.isolated_network_offering_id,cls.zone) + cls.createVM(cls.apiclient,cls.zone.id,cls.service_offering.id,cls.template.id,cls.network_d1b.id) + + cls.apiclient.connection.apiKey = cls.user_d11a_apikey + cls.apiclient.connection.securityKey = cls.user_d11a_secretkey + cls.network_d11a = cls.createNetwork(cls.apiclient,cls.account_d11a,cls.isolated_network_offering_id,cls.zone) + cls.createVM(cls.apiclient,cls.zone.id,cls.service_offering.id,cls.template.id,cls.network_d11a.id) + + cls.apiclient.connection.apiKey = cls.user_d11b_apikey + cls.apiclient.connection.securityKey = cls.user_d11b_secretkey + cls.network_d11b = cls.createNetwork(cls.apiclient,cls.account_d11b,cls.isolated_network_offering_id,cls.zone) + cls.createVM(cls.apiclient,cls.zone.id,cls.service_offering.id,cls.template.id,cls.network_d11b.id) + + cls.apiclient.connection.apiKey = cls.user_d12a_apikey + cls.apiclient.connection.securityKey = cls.user_d12a_secretkey + cls.network_d12a = cls.createNetwork(cls.apiclient,cls.account_d12a,cls.isolated_network_offering_id,cls.zone) + cls.createVM(cls.apiclient,cls.zone.id,cls.service_offering.id,cls.template.id,cls.network_d12a.id) + + cls.apiclient.connection.apiKey = cls.user_roota_apikey + cls.apiclient.connection.securityKey = cls.user_roota_secretkey + cls.network_roota = cls.createNetwork(cls.apiclient,cls.account_roota,cls.isolated_network_offering_id,cls.zone) + cls.createVM(cls.apiclient,cls.zone.id,cls.service_offering.id,cls.template.id,cls.network_roota.id) + + cls.apiclient.connection.apiKey = cls.user_d111a_apikey + cls.apiclient.connection.securityKey = cls.user_d111a_secretkey + cls.network_d111a = cls.createNetwork(cls.apiclient,cls.account_d111a,cls.isolated_network_offering_id,cls.zone) + cls.createVM(cls.apiclient,cls.zone.id,cls.service_offering.id,cls.template.id,cls.network_d111a.id) + + cls.apiclient.connection.apiKey = cls.user_d111b_apikey + cls.apiclient.connection.securityKey = cls.user_d111b_secretkey + cls.network_d111b = cls.createNetwork(cls.apiclient,cls.account_d111b,cls.isolated_network_offering_id,cls.zone) + cls.createVM(cls.apiclient,cls.zone.id,cls.service_offering.id,cls.template.id,cls.network_d111b.id) + + + cls.apiclient.connection.apiKey = cls.user_d2a_apikey + cls.apiclient.connection.securityKey = cls.user_d2a_secretkey + cls.network_d2a = cls.createNetwork(cls.apiclient,cls.account_d2a,cls.isolated_network_offering_id,cls.zone) + cls.createVM(cls.apiclient,cls.zone.id,cls.service_offering.id,cls.template.id,cls.network_d2a.id) + + cls.cleanup = [ + cls.account_root, + cls.account_roota, + cls.service_offering, + ] + except Exception as e: + cls.domain_1.delete(cls.apiclient,cleanup="true") + cls.domain_2.delete(cls.apiclient,cleanup="true") + cleanup_resources(cls.apiclient, cls.cleanup) + raise Exception("Failed to create the setup required to execute the test cases: %s" % e) + + @classmethod + def tearDownClass(cls): + cls.apiclient = super(TestIsolatedNetwork, cls).getClsTestClient().getApiClient() + cls.apiclient.connection.apiKey = cls.default_apikey + cls.apiclient.connection.securityKey = cls.default_secretkey + cls.domain_1.delete(cls.apiclient,cleanup="true") + cls.domain_2.delete(cls.apiclient,cleanup="true") + cleanup_resources(cls.apiclient, cls.cleanup) + return + + def setUp(cls): + cls.apiclient = cls.testClient.getApiClient() + cls.dbclient = cls.testClient.getDbConnection() + + def tearDown(cls): + # restore back default apikey and secretkey + cls.apiclient.connection.apiKey = cls.default_apikey + cls.apiclient.connection.securityKey = cls.default_secretkey + return + +## Test cases relating to createNetwork as admin user + + @attr(tags=[ "advanced"],required_hardware="false") + def test_01_createNetwork_admin(self): + + """ + # Validate that Admin should be able to create network for himslef + """ + self.apiclient.connection.apiKey = self.user_root_apikey + self.apiclient.connection.securityKey = self.user_root_secretkey + self.acldata["network"]["name"] = "root" + self.acldata["network"]["displayname"] = "root" + + network = Network.create( + self.apiclient, + self.acldata["network"], + networkofferingid=self.isolated_network_offering_id, + zoneid=self.zone.id + ) + + self.assertEqual(network.state.lower() == ALLOCATED.lower(), + True, + "Admin User is not able to create a network for himself") + + + @attr(tags=[ "advanced"],required_hardware="false") + def test_02_createNetwork_admin_foruserinsamedomain(self): + + """ + # Validate that Admin should be able to create network for users in his domain + """ + self.apiclient.connection.apiKey = self.user_root_apikey + self.apiclient.connection.securityKey = self.user_root_secretkey + self.acldata["network"]["name"] = "root_roota" + self.acldata["network"]["displayname"] = "root_roota" + + network = Network.create( + self.apiclient, + self.acldata["network"], + networkofferingid=self.isolated_network_offering_id, + zoneid=self.zone.id, + accountid=self.account_roota.name, + domainid=self.account_roota.domainid + ) + + self.assertEqual(network.state.lower() == ALLOCATED.lower(), + True, + "Admin User is not able to create a network for other users in his domain") + + @attr(tags=[ "advanced"],required_hardware="false") + def test_03_createNetwork_admin_foruserinotherdomain(self): + + """ + # Validate that Admin should be able to create network for users in his sub domain + """ + self.apiclient.connection.apiKey = self.user_root_apikey + self.apiclient.connection.securityKey = self.user_root_secretkey + self.acldata["network"]["name"] = "root_d11a" + self.acldata["network"]["displayname"] = "root_d11a" + + network = Network.create( + self.apiclient, + self.acldata["network"], + networkofferingid=self.isolated_network_offering_id, + zoneid=self.zone.id, + accountid=self.account_d11a.name, + domainid=self.account_d11a.domainid + ) + + self.assertEqual(network.state.lower() == ALLOCATED.lower(), + True, + "Admin User is not able to create a network for for other users in other domain") + +## Test cases relating to createNetwork as domain admin user + + @attr(tags=[ "advanced"],required_hardware="false") + def test_04_createNetwork_domaindmin(self): + + """ + # Validate that Domain admin should be able to create network for himslef + """ + self.apiclient.connection.apiKey = self.user_d1_apikey + self.apiclient.connection.securityKey = self.user_d1_secretkey + self.acldata["network"]["name"] = "d1" + self.acldata["network"]["displayname"] = "d1" + + network = Network.create( + self.apiclient, + self.acldata["network"], + networkofferingid=self.isolated_network_offering_id, + zoneid=self.zone.id + ) + + self.assertEqual(network.state.lower() == ALLOCATED.lower(), + True, + "Domain admin User is not able to create a network for himself") + + + @attr(tags=[ "advanced"],required_hardware="false") + def test_05_createNetwork_domaindmin_foruserinsamedomain(self): + + """ + # Validate that Domain admin should be able to create network for users in his domain + """ + self.apiclient.connection.apiKey = self.user_d1_apikey + self.apiclient.connection.securityKey = self.user_d1_secretkey + self.acldata["network"]["name"] = "d1-d1a" + self.acldata["network"]["displayname"] = "d1-d1a" + + network = Network.create( + self.apiclient, + self.acldata["network"], + networkofferingid=self.isolated_network_offering_id, + zoneid=self.zone.id, + accountid=self.account_d1a.name, + domainid=self.account_d1a.domainid + ) + + self.assertEqual(network.state.lower() == ALLOCATED.lower(), + True, + "Domain admin User is not able to create a network for other users in his domain") + + @attr(tags=[ "advanced"],required_hardware="false") + def test_06_createNetwork_domaindmin_foruserinsubdomain(self): + + """ + # Validate that Domain admin should be able to create network for users in his sub domain + """ + self.apiclient.connection.apiKey = self.user_d1_apikey + self.apiclient.connection.securityKey = self.user_d1_secretkey + self.acldata["network"]["name"] = "d1_d11a" + self.acldata["network"]["displayname"] = "d1_d11a" + + network = Network.create( + self.apiclient, + self.acldata["network"], + networkofferingid=self.isolated_network_offering_id, + zoneid=self.zone.id, + accountid=self.account_d11a.name, + domainid=self.account_d11a.domainid + ) + + self.assertEqual(network.state.lower() == ALLOCATED.lower(), + True, + "Domain admin User is not able to create a network for other users in his sub domain") + + @attr(tags=[ "advanced"],required_hardware="false") + def test_07_createNetwork_domaindmin_forcrossdomainuser(self): + + """ + # Validate that Domain admin should not be able to create network for users in his sub domain + """ + self.apiclient.connection.apiKey = self.user_d1_apikey + self.apiclient.connection.securityKey = self.user_d1_secretkey + self.acldata["network"]["name"] = "d1_d2a" + self.acldata["network"]["displayname"] = "d1_d2a" + try: + network = Network.create( + self.apiclient, + self.acldata["network"], + networkofferingid=self.isolated_network_offering_id, + zoneid=self.zone.id, + accountid=self.account_d2a.name, + domainid=self.account_d2a.domainid + ) + self.fail("Domain admin is allowed to create network for users not in his domain ") + except Exception as e: + self.debug ("When Domain admin tries to create network for users in his sub domain %s" %e) + if not CloudstackAclException.verifyMsginException(e,CloudstackAclException.NO_PERMISSION_TO_OPERATE_DOMAIN): + self.fail("Error message validation failed when Domain admin tries to create network for users not in his domain ") + +## Test cases relating to createNetwork as regular user + + @attr(tags=[ "advanced"],required_hardware="false") + def test_08_createNetwork_user(self): + + """ + # Validate that Regular should be able to create network for himslef + """ + self.apiclient.connection.apiKey = self.user_d1a_apikey + self.apiclient.connection.securityKey = self.user_d1a_secretkey + self.acldata["network"]["name"] = "d1a" + self.acldata["network"]["displayname"] = "d1a" + + network = Network.create( + self.apiclient, + self.acldata["network"], + networkofferingid=self.isolated_network_offering_id, + zoneid=self.zone.id + ) + + self.assertEqual(network.state.lower() == ALLOCATED.lower(), + True, + "User is not able to create a network for himself") + + + @attr(tags=[ "advanced"],required_hardware="false") + def test_09_createNetwork_user_foruserinsamedomain(self): + + """ + # Validate that Regular user should NOT be able to create network for users in his domain + """ + self.apiclient.connection.apiKey = self.user_d1a_apikey + self.apiclient.connection.securityKey = self.user_d1a_secretkey + self.acldata["network"]["name"] = "d1a_d1b" + self.acldata["network"]["displayname"] = "d1a_d1b" + + try: + network = Network.create( + self.apiclient, + self.acldata["network"], + networkofferingid=self.isolated_network_offering_id, + zoneid=self.zone.id, + accountid=self.account_d1b.name, + domainid=self.account_d1b.domainid + ) + self.fail("User is allowed to create network for other users in his domain ") + except Exception as e: + self.debug ("When user tries to create network for users in his domain %s" %e) + if not CloudstackAclException.verifyMsginException(e,CloudstackAclException.UNABLE_TO_LIST_NETWORK_ACCOUNT): + self.fail("Error message validation failed when when User tries to create network for other users in his domain ") + + @attr(tags=[ "advanced"],required_hardware="false") + def test_10_createNetwork_user_foruserinotherdomain(self): + + """ + # Validate that Domain admin should be NOT be able to create network for users in other domains + """ + self.apiclient.connection.apiKey = self.user_d1a_apikey + self.apiclient.connection.securityKey = self.user_d1a_secretkey + self.acldata["network"]["name"] = "d1a_d11a" + self.acldata["network"]["displayname"] = "d1a_d11a" + + try: + network = Network.create( + self.apiclient, + self.acldata["network"], + networkofferingid=self.isolated_network_offering_id, + zoneid=self.zone.id, + accountid=self.account_d11a.name, + domainid=self.account_d11a.domainid + ) + self.fail("User is allowed to create network for users not in his domain ") + except Exception as e: + self.debug ("When user tries to create network for users in other domain %s" %e) + if not CloudstackAclException.verifyMsginException(e,CloudstackAclException.UNABLE_TO_LIST_NETWORK_ACCOUNT): + self.fail("Error message validation failed when User tries to create network for users not in his domain ") + + +## Test cases relating to Deploying VM in a network as admin user + + @attr(tags=[ "advanced"],required_hardware="false") + def test_11_deployvm_admin(self): + + """ + # Validate that Admin should be able to deploy VM in the networks he owns + """ + self.apiclient.connection.apiKey = self.user_root_apikey + self.apiclient.connection.securityKey = self.user_root_secretkey + vmData = {"name":"root-root","dispayname":"root-root"} + + vm = VirtualMachine.create( + self.apiclient, + vmData, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.network_root.id + ) + + self.assertEqual(vm.state.lower() == RUNNING.lower(), + True, + "Admin User is not able to deploy VM in his own network") + + + @attr(tags=[ "advanced"],required_hardware="false") + def test_12_deployvm_admin_foruserinsamedomain(self): + + """ + # Validate that Admin should be able to deploy Vm for users in his domain + """ + self.apiclient.connection.apiKey = self.user_root_apikey + self.apiclient.connection.securityKey = self.user_root_secretkey + vmData={"name":"roota-root","displayname":"roota-root"} + + vm = VirtualMachine.create( + self.apiclient, + vmData, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.network_roota.id, + accountid=self.account_roota.name, + domainid=self.account_roota.domainid + ) + + self.assertEqual(vm.state.lower() == RUNNING.lower() and vm.account== self.account_roota.name and vm.domainid == self.account_roota.domainid, + True, + "Admin User is not able to deploy VM for users in his domain") + + @attr(tags=[ "advanced"],required_hardware="false") + def test_13_deployvm_admin_foruserinotherdomain(self): + + """ + # Validate that Admin should be able to deploy VM for users in his sub domain + """ + self.apiclient.connection.apiKey = self.user_root_apikey + self.apiclient.connection.securityKey = self.user_root_secretkey + vmData={"name":"d2a-root","displayname":"d2a-root"} + + vm = VirtualMachine.create( + self.apiclient, + vmData, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.network_d2a.id, + accountid=self.account_d2a.name, + domainid=self.account_d2a.domainid + ) + + self.assertEqual(vm.state.lower() == RUNNING.lower() and vm.account== self.account_d2a.name and vm.domainid == self.account_d2a.domainid, + True, + "Admin User is not able to deploy VM for users users in other domain") + + @attr(tags=[ "advanced"],required_hardware="false") + def test_13_1_deployvm_admin_foruserinotherdomain_crossnetwork(self): + + """ + # Validate that Admin should not be able deploy VM for a user in a network that does not belong to the user + """ + self.apiclient.connection.apiKey = self.user_root_apikey + self.apiclient.connection.securityKey = self.user_root_secretkey + vmData={"name":"d11a-root-invalidnetwork","displayname":"d11a-root-invalidnetwork"} + try: + vm = VirtualMachine.create( + self.apiclient, + vmData, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.network_d11b.id, + accountid=self.account_d11a.name, + domainid=self.account_d11a.domainid + ) + self.fail("Admin is allowed to deploy VM for a user in a network that does not belong to the user ") + except Exception as e: + self.debug ("When admin tries to deploy vm for users in network that does not belong to the user %s" %e) + if not CloudstackAclException.verifyMsginException(e,CloudstackAclException.UNABLE_TO_USE_NETWORK): + self.fail("Admin tries to deploy VM for a user in a network that does not belong to the user ") + +## Test cases relating to deploying VM as domain admin user + + @attr(tags=[ "advanced"],required_hardware="false") + def test_14_deployvm_domaindmin(self): + + """ + # Validate that Domain admin should be able to deploy vm for himslef + """ + self.apiclient.connection.apiKey = self.user_d1_apikey + self.apiclient.connection.securityKey = self.user_d1_secretkey + vmData={"name":"d1-d1","displayname":"d1-d1"} + + vm = VirtualMachine.create( + self.apiclient, + vmData, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.network_d1.id, + ) + + self.assertEqual(vm.state.lower() == RUNNING.lower(), + True, + "Domain admin User is not able to deploy VM for himself") + + + @attr(tags=[ "advanced"],required_hardware="false") + def test_15_deployvm_domaindmin_foruserinsamedomain(self): + + """ + # Validate that Domain admin should be able to deploy vm for users in his domain + """ + self.apiclient.connection.apiKey = self.user_d1_apikey + self.apiclient.connection.securityKey = self.user_d1_secretkey + vmData={"name":"d1a-d1","displayname":"d1a-d1"} + + vm = VirtualMachine.create( + self.apiclient, + vmData, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.network_d1a.id, + accountid=self.account_d1a.name, + domainid=self.account_d1a.domainid + ) + self.assertEqual(vm.state.lower() == RUNNING.lower() and vm.account== self.account_d1a.name and vm.domainid == self.account_d1a.domainid, + True, + "Domain admin User is not able to deploy VM for other users in his domain") + + @attr(tags=[ "advanced"],required_hardware="false") + def test_16_deployvm_domaindmin_foruserinsubdomain(self): + + """ + # Validate that Domain admin should be able to deploy vm for users in his sub domain + """ + self.apiclient.connection.apiKey = self.user_d1_apikey + self.apiclient.connection.securityKey = self.user_d1_secretkey + vmData={"name":"d11a-d1","displayname":"d111a-d1"} + + vm = VirtualMachine.create( + self.apiclient, + vmData, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.network_d11a.id, + accountid=self.account_d11a.name, + domainid=self.account_d11a.domainid + ) + self.assertEqual(vm.state.lower() == RUNNING.lower() and vm.account== self.account_d11a.name and vm.domainid == self.account_d11a.domainid, + True, + "Domain admin User is not able to deploy vm for himself") + + @attr(tags=[ "advanced"],required_hardware="false") + def test_17_deployvm_domaindmin_forcrossdomainuser(self): + + """ + # Validate that Domain admin should not be able allowed to deploy vm for users not in his sub domain + """ + self.apiclient.connection.apiKey = self.user_d1_apikey + self.apiclient.connection.securityKey = self.user_d1_secretkey + vmData={"name":"d2a-d1","displayname":"d2a-d1"} + + try: + vm = VirtualMachine.create( + self.apiclient, + vmData, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.network_d2a.id, + accountid=self.account_d2a.name, + domainid=self.account_d2a.domainid + ) + self.fail("Domain admin is allowed to deploy vm for users not in hos domain ") + except Exception as e: + self.debug ("When Domain admin tries to deploy vm for users in his sub domain %s" %e) + if not CloudstackAclException.verifyMsginException(e,CloudstackAclException.NO_PERMISSION_TO_OPERATE_DOMAIN): + self.fail("Error message validation failed when Domain admin tries to deploy vm for users not in hos domain ") + + @attr(tags=[ "advanced"],required_hardware="false") + def test_17_1_deployvm_domainadmin_foruserinotherdomain_crossnetwork(self): + + """ + # Validate that Domain admin should not be able deploy VM for a user in a network that does not belong to the user + """ + self.apiclient.connection.apiKey = self.user_d1_apikey + self.apiclient.connection.securityKey = self.user_d1_secretkey + vmData={"name":"d1-d11a-invalidnetwork","displayname":"d1-d11a-invalidnetwork"} + try: + vm = VirtualMachine.create( + self.apiclient, + vmData, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.network_d11b.id, + accountid=self.account_d11a.name, + domainid=self.account_d11a.domainid + ) + self.fail("Domain admin is allowed to deploy vm for users in a network that does not belong to him ") + except Exception as e: + self.debug ("When domain admin tries to deploy vm for users in network that does not belong to the user %s" %e) + if not CloudstackAclException.verifyMsginException(e,CloudstackAclException.UNABLE_TO_USE_NETWORK): + self.fail("Error message validation failed when Domain admin tries to deploy vm for users in a network that does not belong to him ") + +## Test cases relating to deploying VM as regular user + + @attr(tags=[ "advanced"],required_hardware="false") + def test_18_deployvm_user(self): + + """ + # Validate that Regular should be able to deploy vm for himslef + """ + self.apiclient.connection.apiKey = self.user_d1a_apikey + self.apiclient.connection.securityKey = self.user_d1a_secretkey + vmData={"name":"d1a-d1a","displayname":"d1a-d1a"} + + vm = VirtualMachine.create( + self.apiclient, + vmData, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.network_d1a.id, + ) + self.assertEqual(vm.state.lower() == RUNNING.lower(), + True, + "User is not able to deploy vm for himself") + + + @attr(tags=[ "advanced"],required_hardware="false") + def test_19_deployvm_user_foruserinsamedomain(self): + + """ + # Validate that Regular user should NOT be able to deploy vm for users in his domain + """ + self.apiclient.connection.apiKey = self.user_d1a_apikey + self.apiclient.connection.securityKey = self.user_d1a_secretkey + vmData={"name":"d1b-d1a","displayname":"d1b-d1a"} + + try: + vm = VirtualMachine.create( + self.apiclient, + vmData, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.network_d1b.id, + accountid=self.account_d1b.name, + domainid=self.account_d1b.domainid + ) + self.fail("Regular user is allowed to deploy vm for other users in his domain ") + except Exception as e: + self.debug ("When user tries to deploy vm for users in his domain %s" %e) + if not CloudstackAclException.verifyMsginException(e,CloudstackAclException.NO_PERMISSION_TO_OPERATE_ACCOUNT): + self.fail("Error message validation failed when Regular user tries to deploy vm for other users in his domain ") + + @attr(tags=[ "advanced"],required_hardware="false") + def test_20_deployvm_user_foruserincrossdomain(self): + + """ + # Validate that Regular user should NOT be able to deploy vm for users in his domain + """ + self.apiclient.connection.apiKey = self.user_d1a_apikey + self.apiclient.connection.securityKey = self.user_d1a_secretkey + vmData={"name":"d2a-d1a","displayname":"d2a-d1a"} + + try: + vm = VirtualMachine.create( + self.apiclient, + vmData, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.network_d2a.id, + accountid=self.account_d2a.name, + domainid=self.account_d2a.domainid + ) + self.fail("Regular user is allowed to deploy vm for users not in his domain ") + except Exception as e: + self.debug ("When user tries to deploy vm for users n different domain %s" %e) + if not CloudstackAclException.verifyMsginException(e,CloudstackAclException.NO_PERMISSION_TO_OPERATE_ACCOUNT): + self.fail("Error message validation failed when Regular user tries to deploy vm for users not in his domain ") + + @attr(tags=[ "advanced"],required_hardware="false") + def test_20_1_deployvm_user_incrossnetwork(self): + + """ + #Validate that User should not be able deploy VM in a network that does not belong to him + """ + self.apiclient.connection.apiKey = self.user_d11a_apikey + self.apiclient.connection.securityKey = self.user_d11a_secretkey + vmData={"name":"d11a-invalidnetwork","displayname":"d11a-invalidnetwork"} + try: + vm = VirtualMachine.create( + self.apiclient, + vmData, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.network_d11b.id, + ) + self.fail("User is allowed to deploy VM in a network that does not belong to him ") + except Exception as e: + self.debug ("When user tries to deploy vm in a network that does not belong to him %s" %e) + if not CloudstackAclException.verifyMsginException(e,CloudstackAclException.UNABLE_TO_USE_NETWORK): + self.fail("Error message validation failed when User is allowed to deploy VM in a network that does not belong to him ") + +## Test cases relating to restart Network as admin user + + @attr(tags=[ "advanced"],required_hardware="false") + def test_21_restartNetwork_admin(self): + + """ + #Validate that Admin should be able to restart network for networks he owns + """ + self.apiclient.connection.apiKey = self.user_root_apikey + self.apiclient.connection.securityKey = self.user_root_secretkey + + restartResponse = self.network_root.restart(self.apiclient) + + self.assertEqual(restartResponse.success, + True, + "Admin User is not able to restart network he owns") + + + @attr(tags=[ "advanced"],required_hardware="false") + def test_22_restartNetwork_admin_foruserinsamedomain(self): + + """ + # Validate that Admin should be able to restart network for users in his domain + """ + self.apiclient.connection.apiKey = self.user_root_apikey + self.apiclient.connection.securityKey = self.user_root_secretkey + + restartResponse = self.network_roota.restart(self.apiclient) + + self.assertEqual(restartResponse.success, + True, + "Admin User is not able to restart network owned by users his domain") + + @attr(tags=[ "advanced"],required_hardware="false") + def test_23_restartNetwork_admin_foruserinotherdomain(self): + + """ + # Validate that Admin should be able to restart network for users in his sub domain + """ + self.apiclient.connection.apiKey = self.user_root_apikey + self.apiclient.connection.securityKey = self.user_root_secretkey + + restartResponse = self.network_d11a.restart(self.apiclient) + + self.assertEqual(restartResponse.success, + True, + "Admin User is not able to restart network owned other users in other domain") + +## Test cases relating to restart Network as domain admin user + + @attr(tags=[ "advanced"],required_hardware="false") + def test_24_restartNetwork_domaindmin(self): + + """ + # Validate that Domain admin should be able to restart network for himslef + """ + self.apiclient.connection.apiKey = self.user_d1_apikey + self.apiclient.connection.securityKey = self.user_d1_secretkey + + restartResponse = self.network_d1.restart(self.apiclient) + + self.assertEqual(restartResponse.success, + True, + "Domain admin User is not able to restart network for himself") + + + @attr(tags=[ "advanced"],required_hardware="false") + def test_25_restartNetwork_domaindmin_foruserinsamedomain(self): + + """ + # Validate that Domain admin should be able to restart network for users in his domain + """ + self.apiclient.connection.apiKey = self.user_d1_apikey + self.apiclient.connection.securityKey = self.user_d1_secretkey + + restartResponse = self.network_d1a.restart(self.apiclient) + self.assertEqual(restartResponse.success, + True, + "Domain admin User is not able to restart network for other users in his domain") + + @attr(tags=[ "advanced"],required_hardware="false") + def test_26_restartNetwork_domaindmin_foruserinsubdomain(self): + + """ + # Validate that Domain admin should be able to restart network for users in his sub domain + """ + self.apiclient.connection.apiKey = self.user_d1_apikey + self.apiclient.connection.securityKey = self.user_d1_secretkey + + restartResponse = self.network_d11a.restart(self.apiclient) + self.assertEqual(restartResponse.success, + True, + "Domain admin User is not able to restart network he owns") + + @attr(tags=[ "advanced"],required_hardware="false") + def test_27_restartNetwork_domaindmin_forcrossdomainuser(self): + + """ + # Validate that Domain admin should be able to restart network for users in his sub domain + """ + self.apiclient.connection.apiKey = self.user_d1_apikey + self.apiclient.connection.securityKey = self.user_d1_secretkey + + try: + restartResponse = self.network_d2a.restart(self.apiclient) + self.fail("Domain admin is allowed to restart network for users not in his domain ") + except Exception as e: + self.debug ("When Domain admin tries to restart network for users in his sub domain %s" %e) + if not CloudstackAclException.verifyMsginException(e,CloudstackAclException.NO_PERMISSION_TO_OPERATE_DOMAIN): + self.fail("Error message validation failed when Domain admin tries to restart network for users not in his domain ") + +## Test cases relating restart network as regular user + + @attr(tags=[ "advanced"],required_hardware="false") + def test_28_restartNetwork_user(self): + + """ + #Validate that Regular should be able to restart network for himslef + """ + self.apiclient.connection.apiKey = self.user_d1a_apikey + self.apiclient.connection.securityKey = self.user_d1a_secretkey + + restartResponse = self.network_d1a.restart(self.apiclient) + self.assertEqual(restartResponse.success, + True, + "User is not able to restart network he owns") + + + @attr(tags=[ "advanced"],required_hardware="false") + def test_29_restartNetwork_user_foruserinsamedomain(self): + + """ + #Validate that Regular user should NOT be able to restart network for users in his domain + """ + self.apiclient.connection.apiKey = self.user_d1a_apikey + self.apiclient.connection.securityKey = self.user_d1a_secretkey + + try: + restartResponse = self.network_d1b.restart(self.apiclient) + self.fail("Regular user is allowed to restart network for users in his domain ") + except Exception as e: + self.debug ("When user tries to restart network for users in his domain %s" %e) + if not CloudstackAclException.verifyMsginException(e,CloudstackAclException.NO_PERMISSION_TO_OPERATE_ACCOUNT): + self.fail("Error message validation failed when Regular user tries to restart network for users in his domain ") + + @attr(tags=[ "advanced"],required_hardware="false") + def test_30_restartNetwork_user_foruserinotherdomain(self): + + """ + #Validate that Domain admin should be NOT be able to restart network for users in other domains + """ + self.apiclient.connection.apiKey = self.user_d1a_apikey + self.apiclient.connection.securityKey = self.user_d1a_secretkey + + try: + + restartResponse = self.network_d11a.restart(self.apiclient) + self.fail("Regular user is allowed to restart network for users not in his domain ") + except Exception as e: + self.debug ("When user tries to restart network for users in other domain %s" %e) + if not CloudstackAclException.verifyMsginException(e,CloudstackAclException.NO_PERMISSION_TO_OPERATE_ACCOUNT): + self.fail("Error message validation failed when Regular user is allowed to restart network for users not in his domain ") + + @staticmethod + def generateKeysForUser(apiclient,account): + user = User.list( + apiclient, + account=account.name, + domainid=account.domainid + )[0] + + return (User.registerUserKeys( + apiclient, + user.id + )) + + @staticmethod + def createNetwork(apiclient,account,isolated_network_offering_id,zone): + network= { + "name": "Network-", + "displaytext": "Network-", + "gateway" :"10.223.1.1", + "netmask" :"255.255.255.0", + "startip" :"10.223.1.2", + "endip" :"10.223.1.100", + } + + network["name"] = account.name +" -forupdate" + network["displayname"] = account.name + "-forupdate" + + network = Network.create( + apiclient, + network, + networkofferingid=isolated_network_offering_id, + zoneid=zone.id + ) + return network + + + @staticmethod + def createVM(apiclient,zoneId,serviceOfferingId,templateId,networkId): + vmData = {"name":"prereq","dispayname":"prereq"} + + vm = VirtualMachine.create( + apiclient, + vmData, + zoneid=zoneId, + serviceofferingid=serviceOfferingId, + templateid=templateId, + networkids=networkId + ) + + return vm diff --git a/test/integration/component/test_add_remove_network.py b/test/integration/component/test_add_remove_network.py index 4529ec7dfa..4222f7afec 100644 --- a/test/integration/component/test_add_remove_network.py +++ b/test/integration/component/test_add_remove_network.py @@ -29,7 +29,7 @@ from nose.plugins.attrib import attr from marvin.cloudstackTestCase import cloudstackTestCase, unittest from ddt import ddt, data -from marvin.integration.lib.base import ( +from marvin.lib.base import ( Account, Domain, ServiceOffering, @@ -39,7 +39,7 @@ VpcOffering, VPC ) -from marvin.integration.lib.common import (get_domain, +from marvin.lib.common import (get_domain, get_zone, get_template, list_virtual_machines, @@ -49,7 +49,7 @@ update_resource_limit ) -from marvin.integration.lib.utils import (validateList, +from marvin.lib.utils import (validateList, random_gen, get_hypervisor_type, cleanup_resources) @@ -60,6 +60,7 @@ from marvin.codes import PASS import random +import time class Services: """Test Add Remove Network Services @@ -67,7 +68,7 @@ class Services: def __init__(self): self.services = { - + "sleep": 60, "ostype": "CentOS 5.3 (64-bit)", # Cent OS 5.3 (64 bit) @@ -173,7 +174,10 @@ class TestAddNetworkToVirtualMachine(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestAddNetworkToVirtualMachine, cls).getClsTestClient().getApiClient() + cls.testClient = super(TestAddNetworkToVirtualMachine, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + + cls.services = Services().services hypervisor = get_hypervisor_type(cls.api_client) if hypervisor.lower() not in ["xenserver","kvm"]: @@ -181,8 +185,8 @@ def setUpClass(cls): cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) template = get_template(cls.api_client, cls.zone.id, cls.services["ostype"]) # Set Zones and disk offerings @@ -192,10 +196,13 @@ def setUpClass(cls): # Create Accounts & networks cls.services["isolated_network"]["zoneid"] = cls.zone.id cls.services["shared_network"]["zoneid"] = cls.zone.id + cls._cleanup = [] cls.account = Account.create(cls.api_client, cls.services["account"], domainid = cls.domain.id) + cls._cleanup.append(cls.account) cls.service_offering = ServiceOffering.create(cls.api_client,cls.services["service_offering"]) + cls._cleanup.append(cls.service_offering) cls.virtual_machine = VirtualMachine.create(cls.api_client, cls.services["virtual_machine"],accountid=cls.account.name, domainid=cls.account.domainid, serviceofferingid=cls.service_offering.id, @@ -203,6 +210,7 @@ def setUpClass(cls): # Create Shared Network Offering cls.isolated_network_offering = NetworkOffering.create(cls.api_client, cls.services["isolated_network_offering"]) + cls._cleanup.append(cls.isolated_network_offering) # Enable Isolated Network offering cls.isolated_network_offering.update(cls.api_client, state='Enabled') @@ -226,9 +234,8 @@ def setUpClass(cls): cls.shared_network = Network.create(cls.api_client,cls.services["shared_network"],cls.account.name, cls.account.domainid,networkofferingid=cls.shared_network_offering.id) - - cls._cleanup = [cls.account,cls.service_offering,cls.shared_network,cls.isolated_network_offering, - cls.shared_network_offering] + cls._cleanup.append(cls.shared_network) + cls._cleanup.append(cls.shared_network_offering) return def setUp(self): @@ -286,7 +293,14 @@ def addNetworkToVm(self, network, vm, ipaddress=None): self.debug("virtual machine nics: %s" % vm_list[0].nic) nics = [x for x in vm_list[0].nic if x.networkid == network.id] self.debug("Filtered nics list: %s:" % nics) - self.addednics.append(nics[-1]) + + # Only the nics added to self.virtual_machine should be added to this list + # Nics added to his list are removed before execution of next test case because we are using + # same virtual machine in all test cases, so it is important that the common + # virtual machine should contain only the default nic whenever new test case + # execution starts + if vm.id == self.virtual_machine.id: + self.addednics.append(nics[-1]) self.assertTrue(len(nics) == 1, "nics list should contain the nic of added isolated network,\ the number of nics for the network should be 1, instead they are %s" % @@ -343,14 +357,10 @@ def test_02_add_nw_stopped_vm(self, value): # Validate the following: # 1. New nic is generated for the added network - self.debug("Stopping Virtual Machine: %s" % self.virtual_machine.id) - self.virtual_machine.stop(self.apiclient) - - vm_list = list_virtual_machines(self.apiclient,id=self.virtual_machine.id) - vm_list_validation_result = validateList(vm_list) - self.assertEqual(vm_list_validation_result[0], PASS, "vm list validation failed due to %s" % - vm_list_validation_result[2]) - self.assertTrue(vm_list[0].state == 'Stopped', "Failed to stop VM, the state is %s" % vm_list[0].state) + try: + self.virtual_machine.stop(self.apiclient) + except Exception as e: + self.fail("Failed to stop VM: %s" % e) network = None #The network which we are adding to the vm if value == "isolated": @@ -386,14 +396,24 @@ def test_03_add_nw_multiple_times(self, value): if network is None: self.skipTest("Network should not be none. Case not handled for Network of type %s" % value) + try: + virtual_machine = VirtualMachine.create( + self.api_client, self.services["virtual_machine"], + accountid=self.account.name, domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + mode=self.zone.networktype, + networkids=[self.defaultNetworkId]) + self.cleanup.append(virtual_machine) + except Exception as e: + self.fail("Failed to deply virtual machine: %s" % e) + # Adding network to vm for the first time - self.addNetworkToVm(network, self.virtual_machine) + self.addNetworkToVm(network, virtual_machine) # Trying to add same network to vm for the second time with self.assertRaises(Exception) as e: - self.addNetworkToVm(network, self.virtual_machine) - - self.debug("Adding same network again failed with exception: %s" % e.exception) + self.addNetworkToVm(network, virtual_machine) + self.debug("Adding same network again failed with exception: %s" % e.exception) return @@ -410,8 +430,19 @@ def test_04_vpc_nw_running_vm(self, value): # Validate the following: # 1. Adding VPC to vm should fail + try: + virtual_machine = VirtualMachine.create( + self.api_client, self.services["virtual_machine"], + accountid=self.account.name, domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + mode=self.zone.networktype, + networkids=[self.defaultNetworkId]) + self.cleanup.append(virtual_machine) + except Exception as e: + self.fail("Failed to deply virtual machine: %s" % e) + network = self.isolated_network - self.addNetworkToVm(network, self.virtual_machine) + self.addNetworkToVm(network, virtual_machine) self.debug("Creating VPC offering") vpc_off = VpcOffering.create(self.api_client,self.services["vpc_offering"]) @@ -427,11 +458,10 @@ def test_04_vpc_nw_running_vm(self, value): self.debug("Trying to add VPC to vm belonging to isolated network, this should fail") with self.assertRaises(Exception): - self.virtual_machine.add_nic(self.apiclient, vpc.id) + virtual_machine.add_nic(self.apiclient, vpc.id) self.debug("Disabling vpc offering: %s" % vpc_off.id) vpc_off.update(self.apiclient, state='Disabled') - return @attr(tags = ["advanced"]) @@ -448,16 +478,10 @@ def test_05_add_vpc_nw_stopped_vm(self, value): # Validate the following: # 1. Adding VPC to vm should fail - self.debug("Stopping Virtual Machine: %s" % self.virtual_machine.id) - self.virtual_machine.stop(self.apiclient) - - vm_list = list_virtual_machines(self.apiclient,id=self.virtual_machine.id) - #validation vm list - vm_list_validation_result = validateList(vm_list) - self.assertEqual(vm_list_validation_result[0], PASS, "vm list validation failed due to %s" % - vm_list_validation_result[2]) - - self.assertTrue(vm_list[0].state == 'Stopped', "Failed to stop VM, the state is %s" % vm_list[0].state) + try: + self.virtual_machine.stop(self.apiclient) + except Exception as e: + self.fail("Failed to stop virtual machine: %s" % e) self.addNetworkToVm(self.isolated_network, self.virtual_machine) @@ -494,10 +518,20 @@ def test_06_add_nw_ipaddress_running_vm(self): # 2. The newly added nic has the ip address same as # that passed while adding the network + try: + virtual_machine = VirtualMachine.create( + self.api_client, self.services["virtual_machine"], + accountid=self.account.name, domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + mode=self.zone.networktype, + networkids=[self.defaultNetworkId]) + self.cleanup.append(virtual_machine) + except Exception as e: + self.fail("Failed to deply virtual machine: %s" % e) + ipaddress = self.shared_nw_endip self.debug("Adding network to vm with ip address %s: " % ipaddress) - self.addNetworkToVm(self.shared_network, self.virtual_machine,ipaddress = ipaddress) - + self.addNetworkToVm(self.shared_network, virtual_machine,ipaddress = ipaddress) return @attr(tags = ["advanced"]) @@ -515,7 +549,7 @@ def test_10_add_nw_invalid_ipaddress_running_vm(self): with self.assertRaises(Exception) as e: self.addNetworkToVm(self.shared_network, self.virtual_machine, ipaddress = ipaddress) - self.debug("API failed with exception: %s" % e.exception) + self.debug("API failed with exception: %s" % e.exception) return @@ -552,9 +586,7 @@ def test_14_add_nw_different_account(self, value): with self.assertRaises(Exception) as e: self.virtual_machine.add_nic(self.apiclient, network.id) - network.delete(self.apiclient) - - self.debug("Operation failed with exception %s" % e.exception) + self.debug("Operation failed with exception %s" % e.exception) return @@ -571,50 +603,51 @@ def test_24_add_nw_different_domain(self): network = None #The network which we are adding to the vm - self.child_domain_1 = Domain.create(self.apiclient, + try: + tempCleanupList = [] + self.child_domain_1 = Domain.create(self.apiclient, services=self.services["domain"], parentdomainid=self.domain.id) + tempCleanupList.append(self.child_domain_1) - self.child_do_admin_1 = Account.create( + self.child_do_admin_1 = Account.create( self.apiclient, self.services["account"], admin=True, domainid=self.child_domain_1.id ) + tempCleanupList.append(self.child_do_admin_1) - self.debug("Creating a domain under: %s" % self.domain.name) - - self.child_domain_2 = Domain.create(self.apiclient, + self.child_domain_2 = Domain.create(self.apiclient, services=self.services["domain"], parentdomainid=self.domain.id) + tempCleanupList.append(self.child_domain_2) - self.child_do_admin_2 = Account.create( + self.child_do_admin_2 = Account.create( self.apiclient, self.services["account"], admin=True, domainid=self.child_domain_2.id) + tempCleanupList.append(self.child_do_admin_2) + except Exception as e: + tempCleanupList.reverse() + self.cleanup += tempCleanupList + self.fail(e) network = Network.create(self.api_client,self.services["isolated_network"],self.child_do_admin_1.name, self.child_do_admin_1.domainid,networkofferingid=self.isolated_network_offering.id) - self.cleanup.append(self.child_do_admin_1) - self.cleanup.append(self.child_domain_1) - self.cleanup.append(self.child_do_admin_2) - self.cleanup.append(self.child_domain_2) - virtual_machine = VirtualMachine.create(self.apiclient, self.services["virtual_machine"],accountid=self.child_do_admin_2.name, domainid=self.child_do_admin_2.domainid, serviceofferingid=self.service_offering.id, mode=self.zone.networktype) + time.sleep(self.services["sleep"]) self.debug("Trying to %s network in domain %s to a vm in domain %s, This should fail" % (network.type, self.child_domain_1.name, self.child_domain_2.name)) with self.assertRaises(Exception) as e: virtual_machine.add_nic(self.apiclient, network.id) - self.debug("Operation failed with exception %s" % e.exception) - - network.delete(self.apiclient) - + self.debug("Operation failed with exception %s" % e.exception) return @attr(tags = ["advanced"]) @@ -634,12 +667,9 @@ def test_25_add_nw_above_account_limit(self): self.services["account"], domainid=self.domain.id ) - self.debug("create account %s" % account_1.name) - self.cleanup.append(account_1) self.debug("setting network limit of account: %s as 1" % account_1.name) - update_resource_limit( self.apiclient, 6, # Network @@ -686,7 +716,7 @@ def test_25_add_nw_above_account_limit(self): with self.assertRaises(Exception) as e: virtual_machine.add_nic(self.apiclient, network_2.id) - self.debug("Operation failed with exception %s" % e.exception) + self.debug("Operation failed with exception %s" % e.exception) return @@ -694,16 +724,18 @@ class TestRemoveNetworkFromVirtualMachine(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestRemoveNetworkFromVirtualMachine, cls).getClsTestClient().getApiClient() + cls.testClient = super(TestRemoveNetworkFromVirtualMachine, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + + cls.services = Services().services hypervisor = get_hypervisor_type(cls.api_client) if hypervisor.lower() not in ["xenserver","kvm"]: raise unittest.SkipTest("This feature is supported only on XenServer and KVM") - cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) template = get_template(cls.api_client,cls.zone.id,cls.services["ostype"]) # Set Zones and disk offerings @@ -713,22 +745,25 @@ def setUpClass(cls): # Create Accounts & networks cls.services["isolated_network"]["zoneid"] = cls.zone.id cls.services["shared_network"]["zoneid"] = cls.zone.id + cls._cleanup = [] cls.account = Account.create(cls.api_client,cls.services["account"],domainid = cls.domain.id) + cls._cleanup.append(cls.account) cls.service_offering = ServiceOffering.create(cls.api_client,cls.services["service_offering"]) + cls._cleanup.append(cls.service_offering) cls.virtual_machine = VirtualMachine.create(cls.api_client,cls.services["virtual_machine"],accountid=cls.account.name, domainid=cls.account.domainid,serviceofferingid=cls.service_offering.id, mode=cls.zone.networktype) # Create Shared Network Offering cls.isolated_network_offering = NetworkOffering.create(cls.api_client,cls.services["isolated_network_offering"]) + cls._cleanup.append(cls.isolated_network_offering) + # Enable Isolated Network offering cls.isolated_network_offering.update(cls.api_client, state='Enabled') cls.isolated_network = Network.create(cls.api_client,cls.services["isolated_network"],cls.account.name, cls.account.domainid,networkofferingid=cls.isolated_network_offering.id) - - cls._cleanup = [cls.account,cls.service_offering,cls.isolated_network_offering,] return def setUp(self): @@ -836,7 +871,7 @@ def test_08_remove_default_nic(self): self.virtual_machine.id) with self.assertRaises(Exception): self.virtual_machine.remove_nic(self.apiclient, vm_list[0].nic[0].id) - self.debug("Removing default nic of vm failed") + self.debug("Removing default nic of vm failed") return @attr(tags = ["advanced"]) @@ -867,23 +902,25 @@ def test_09_remove_foreign_nic(self): operation should fail") with self.assertRaises(Exception) as e: self.virtual_machine.remove_nic(self.apiclient, virtual_machine.nic[0].id) - self.debug("Operation failed with exception: %s" % e.exception) + self.debug("Operation failed with exception: %s" % e.exception) return class TestUpdateVirtualMachineNIC(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestUpdateVirtualMachineNIC, cls).getClsTestClient().getApiClient() + cls.testClient = super(TestUpdateVirtualMachineNIC, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + + cls.services = Services().services hypervisor = get_hypervisor_type(cls.api_client) if hypervisor.lower() not in ["xenserver","kvm"]: raise unittest.SkipTest("This feature is supported only on XenServer and KVM") - cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) template = get_template(cls.api_client,cls.zone.id,cls.services["ostype"]) # Set Zones and disk offerings @@ -893,22 +930,25 @@ def setUpClass(cls): # Create Accounts & networks cls.services["isolated_network"]["zoneid"] = cls.zone.id cls.services["shared_network"]["zoneid"] = cls.zone.id + cls._cleanup = [] cls.account = Account.create(cls.api_client,cls.services["account"],domainid = cls.domain.id) + cls._cleanup.append(cls.account) cls.service_offering = ServiceOffering.create(cls.api_client,cls.services["service_offering"]) + cls._cleanup.append(cls.service_offering) cls.virtual_machine = VirtualMachine.create(cls.api_client,cls.services["virtual_machine"], accountid=cls.account.name,domainid=cls.account.domainid, serviceofferingid=cls.service_offering.id, mode=cls.zone.networktype) # Create Shared Network Offering - cls.isolated_network_offering = NetworkOffering.create(cls.api_client,cls.services["isolated_network_offering"],) + cls.isolated_network_offering = NetworkOffering.create(cls.api_client,cls.services["isolated_network_offering"]) + cls._cleanup.append(cls.isolated_network_offering) # Enable Isolated Network offering cls.isolated_network_offering.update(cls.api_client, state='Enabled') cls.isolated_network = Network.create(cls.api_client,cls.services["isolated_network"],cls.account.name, cls.account.domainid,networkofferingid=cls.isolated_network_offering.id) - cls._cleanup = [cls.account,cls.service_offering,cls.isolated_network_offering,] return def setUp(self): @@ -1045,7 +1085,7 @@ def test_12_make_default_nic_as_default(self): self.debug("Trying to set default nic again as default nic, This should fail") with self.assertRaises(Exception) as e: self.virtual_machine.update_default_nic(self.apiclient, nicId = defaultNicId) - self.debug("updateDefaultNic operation failed as expected with exception: %s" % + self.debug("updateDefaultNic operation failed as expected with exception: %s" % e.exception) return @@ -1070,15 +1110,15 @@ def test_13_set_foreign_nic_as_default(self): virtual_machine = VirtualMachine.create(self.apiclient,self.services["virtual_machine"], accountid=account.name,domainid=account.domainid, serviceofferingid=self.service_offering.id,mode=self.zone.networktype) + time.sleep(self.services["sleep"]) self.debug("Deployed virtual machine: %s" % virtual_machine.id) - foreignNicId = virtual_machine.nic[0].id self.debug("Trying to set nic of new virtual machine as default nic of existing virtual machine, This \ operation should fail") with self.assertRaises(Exception) as e: self.virtual_machine.update_default_nic(self.apiclient, nicId = foreignNicId) - self.debug("updateDefaultNic operation failed as expected with exception: %s" % + self.debug("updateDefaultNic operation failed as expected with exception: %s" % e.exception) return @@ -1087,37 +1127,43 @@ class TestFailureScenariosAddNetworkToVM(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestFailureScenariosAddNetworkToVM, cls).getClsTestClient().getApiClient() + cls.testClient = super(TestFailureScenariosAddNetworkToVM, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + + cls.services = Services().services hypervisor = get_hypervisor_type(cls.api_client) if hypervisor.lower() not in ["xenserver","kvm"]: raise unittest.SkipTest("This feature is supported only on XenServer and KVM") - cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) template = get_template(cls.api_client,cls.zone.id,cls.services["ostype"]) # Set Zones and disk offerings cls.services["virtual_machine"]["zoneid"] = cls.zone.id cls.services["virtual_machine"]["template"] = template.id # Create Accounts & networks cls.services["isolated_network"]["zoneid"] = cls.zone.id + cls._cleanup = [] cls.account = Account.create(cls.api_client,cls.services["account"],domainid = cls.domain.id) + cls._cleanup.append(cls.account) + cls.service_offering = ServiceOffering.create(cls.api_client,cls.services["service_offering"]) + cls._cleanup.append(cls.service_offering) cls.virtual_machine = VirtualMachine.create(cls.api_client,cls.services["virtual_machine"], accountid=cls.account.name,domainid=cls.account.domainid, serviceofferingid=cls.service_offering.id,mode=cls.zone.networktype) # Create Shared Network Offering cls.isolated_network_offering = NetworkOffering.create(cls.api_client,cls.services["isolated_network_offering"],) + cls._cleanup.append(cls.isolated_network_offering) + # Enable Isolated Network offering cls.isolated_network_offering.update(cls.api_client, state='Enabled') cls.isolated_network = Network.create(cls.api_client,cls.services["isolated_network"],cls.account.name, cls.account.domainid,networkofferingid=cls.isolated_network_offering.id) - - cls._cleanup = [cls.account,cls.service_offering,cls.isolated_network_offering,] return def setUp(self): @@ -1224,6 +1270,7 @@ def test_17_add_nic_different_zone(self): cmd.networkid = isolated_network.id with self.assertRaises(Exception) as e: + time.sleep(5) self.apiclient.addNicToVirtualMachine(cmd) self.debug("addNicToVirtualMachine API failed with exception: %s" % e.exception) @@ -1265,6 +1312,7 @@ def test_18_add_nic_basic_zone(self): virtual_machine = VirtualMachine.create(self.apiclient,self.services["virtual_machine"], serviceofferingid=self.service_offering.id, mode=basicZone.networktype) + time.sleep(self.services["sleep"]) self.debug("Deployed virtual machine %s: " % virtual_machine.id) cmd = addNicToVirtualMachine.addNicToVirtualMachineCmd() @@ -1274,6 +1322,7 @@ def test_18_add_nic_basic_zone(self): self.dedbug("Trying to add isolated network to VM (both in basic zone,\ this operation should fail") with self.assertRaises(Exception) as e: + time.sleep(5) self.apiclient.addNicToVirtualMachine(cmd) self.debug("addNicToVirtualMachine API failed with exception: %s" % e.exception) @@ -1300,12 +1349,13 @@ def test_26_add_nic_insufficient_permission(self): self.debug("Created account %s" % account.name) self.debug("creating user api client for account: %s" % account.name) - api_client = self.testClient.createUserApiClient(UserName=account.name, DomainName=self.account.domain) + api_client = self.testClient.getUserApiClient(UserName=account.name, DomainName=self.account.domain) self.debug("Trying to add network to vm with this api client, this should fail due to \ insufficient permission") with self.assertRaises(Exception) as e: + time.sleep(5) api_client.addNicToVirtualMachine(cmd) self.debug("addNicToVirtualMachine API failed with exception: %s" % e.exception) @@ -1315,16 +1365,18 @@ class TestFailureScenariosRemoveNicFromVM(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestFailureScenariosRemoveNicFromVM, cls).getClsTestClient().getApiClient() + cls.testClient = super(TestFailureScenariosRemoveNicFromVM, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + + cls.services = Services().services hypervisor = get_hypervisor_type(cls.api_client) if hypervisor.lower() not in ["xenserver","kvm"]: raise unittest.SkipTest("This feature is supported only on XenServer and KVM") - cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) template = get_template(cls.api_client,cls.zone.id,cls.services["ostype"]) # Set Zones and disk offerings @@ -1334,9 +1386,14 @@ def setUpClass(cls): # Create Accounts & networks cls.services["isolated_network"]["zoneid"] = cls.zone.id cls.services["shared_network"]["zoneid"] = cls.zone.id + cls._cleanup = [] cls.account = Account.create(cls.api_client,cls.services["account"],domainid = cls.domain.id) + cls.append(cls.account) + cls.service_offering = ServiceOffering.create(cls.api_client,cls.services["service_offering"]) + cls._cleanup.append(cls.service_offering) + cls.virtual_machine = VirtualMachine.create(cls.api_client,cls.services["virtual_machine"], accountid=cls.account.name,domainid=cls.account.domainid, serviceofferingid=cls.service_offering.id, @@ -1344,6 +1401,7 @@ def setUpClass(cls): # Create Shared Network Offering cls.isolated_network_offering = NetworkOffering.create(cls.api_client, cls.services["isolated_network_offering"],) + cls._cleanup.append(cls.isolated_network_offering) # Enable Isolated Network offering cls.isolated_network_offering.update(cls.api_client, state='Enabled') cls.isolated_network = Network.create(cls.api_client,cls.services["isolated_network"],cls.account.name, @@ -1351,8 +1409,6 @@ def setUpClass(cls): # Add network to VM cls.virtual_machine.add_nic(cls.api_client, cls.isolated_network.id) - - cls._cleanup = [cls.account,cls.service_offering,cls.isolated_network_offering,] return def setUp(self): @@ -1372,7 +1428,7 @@ def tearDown(self): def tearDownClass(cls): try: # Disable Network Offerings - #cls.isolated_network_offering.update(cls.api_client, state='Disabled') + cls.isolated_network_offering.update(cls.api_client, state='Disabled') # Cleanup resources used cleanup_resources(cls.api_client, cls._cleanup) @@ -1478,7 +1534,7 @@ def test_27_remove_nic_insufficient_permission(self): self.debug("Created account %s" % account.name) self.debug("creating user api client for account: %s" % account.name) - api_client = self.testClient.createUserApiClient(UserName=account.name, DomainName=self.account.domain) + api_client = self.testClient.getUserApiClient(UserName=account.name, DomainName=self.account.domain) self.debug("Trying to add network to vm with this api client, this should fail due to \ insufficient permission") @@ -1493,16 +1549,18 @@ class TestFailureScenariosUpdateVirtualMachineNIC(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestFailureScenariosUpdateVirtualMachineNIC, cls).getClsTestClient().getApiClient() + cls.testClient = super(TestFailureScenariosUpdateVirtualMachineNIC, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + + cls.services = Services().services hypervisor = get_hypervisor_type(cls.api_client) if hypervisor.lower() not in ["xenserver","kvm"]: raise unittest.SkipTest("This feature is supported only on XenServer and KVM") - cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) template = get_template(cls.api_client, cls.zone.id, cls.services["ostype"]) # Set Zones and disk offerings @@ -1512,10 +1570,13 @@ def setUpClass(cls): # Create Accounts & networks cls.services["isolated_network"]["zoneid"] = cls.zone.id cls.services["shared_network"]["zoneid"] = cls.zone.id + cls._cleanup = [] cls.account = Account.create(cls.api_client, cls.services["account"], domainid = cls.domain.id) + cls._cleanup.append(cls.account) cls.service_offering = ServiceOffering.create(cls.api_client, cls.services["service_offering"]) + cls._cleanup.append(cls.service_offering) cls.virtual_machine = VirtualMachine.create(cls.api_client,cls.services["virtual_machine"], accountid=cls.account.name,domainid=cls.account.domainid, @@ -1525,6 +1586,7 @@ def setUpClass(cls): # Create Shared Network Offering cls.isolated_network_offering = NetworkOffering.create(cls.api_client, cls.services["isolated_network_offering"],) + cls._cleanup.append(cls.isolated_network_offering) # Enable Isolated Network offering cls.isolated_network_offering.update(cls.api_client, state='Enabled') @@ -1532,8 +1594,6 @@ def setUpClass(cls): cls.account.name,cls.account.domainid, networkofferingid=cls.isolated_network_offering.id) cls.virtual_machine.add_nic(cls.api_client, cls.isolated_network.id) - cls._cleanup = [cls.account,cls.service_offering, - cls.isolated_network_offering,] return def setUp(self): @@ -1601,7 +1661,7 @@ def test_21_update_nic_wrong_vm_id(self): with self.assertRaises(Exception) as e: self.apiclient.updateDefaultNicForVirtualMachine(cmd) - self.debug("updateDefaultNicForVirtualMachine API failed with exception: %s" % + self.debug("updateDefaultNicForVirtualMachine API failed with exception: %s" % e.exception) return @@ -1647,7 +1707,7 @@ def test_22_update_nic_wrong_nic_id(self): with self.assertRaises(Exception) as e: self.apiclient.updateDefaultNicForVirtualMachine(cmd) - self.debug("updateDefaultNicForVirtualMachine API failed with exception: %s" % + self.debug("updateDefaultNicForVirtualMachine API failed with exception: %s" % e.exception) return @@ -1667,8 +1727,6 @@ def test_23_update_nic_incorrect_vm_state(self): self.debug("Creating new account") account = Account.create(self.apiclient,self.services["account"],domainid = self.domain.id) - self.debug("Created account %s" % account.name) - self.cleanup.append(account) self.debug("Creating virtual machine in the account %s" % account.name) @@ -1676,7 +1734,7 @@ def test_23_update_nic_incorrect_vm_state(self): accountid=account.name,domainid=account.domainid, serviceofferingid=self.service_offering.id, mode=self.zone.networktype) - + time.sleep(self.services["sleep"]) self.debug("Created virtual machine %s" % virtual_machine.id) self.debug("Creating isolated network in account %s" % account.name) @@ -1729,7 +1787,7 @@ def test_23_update_nic_incorrect_vm_state(self): with self.assertRaises(Exception) as e: self.apiclient.updateDefaultNicForVirtualMachine(cmd) - self.debug("updateDefaultNicForVirtualMachine API failed with exception: %s" % + self.debug("updateDefaultNicForVirtualMachine API failed with exception: %s" % e.exception) return @@ -1749,7 +1807,7 @@ def test_28_update_nic_insufficient_permission(self): self.debug("Created account %s" % account.name) self.debug("creating user api client for account: %s" % account.name) - api_client = self.testClient.createUserApiClient(UserName=account.name, DomainName=self.account.domain) + api_client = self.testClient.getUserApiClient(UserName=account.name, DomainName=self.account.domain) self.debug("Listing virtual machine so that to retrive the list of non-default and default nic") vm_list = list_virtual_machines(self.apiclient, id=self.virtual_machine.id) @@ -1779,7 +1837,7 @@ def test_28_update_nic_insufficient_permission(self): with self.assertRaises(Exception) as e: api_client.updateDefaultNicForVirtualMachine(cmd) - self.debug("updateDefaultNicForVirtualMachine API failed with exception: %s" % + self.debug("updateDefaultNicForVirtualMachine API failed with exception: %s" % e.exception) return diff --git a/test/integration/component/test_advancedsg_networks.py b/test/integration/component/test_advancedsg_networks.py index 207659f1ef..2794f96951 100644 --- a/test/integration/component/test_advancedsg_networks.py +++ b/test/integration/component/test_advancedsg_networks.py @@ -19,7 +19,7 @@ """ from marvin.cloudstackTestCase import cloudstackTestCase, unittest from ddt import ddt, data -from marvin.integration.lib.base import (Zone, +from marvin.lib.base import (Zone, ServiceOffering, Account, NetworkOffering, @@ -31,14 +31,14 @@ SecurityGroup, Host) -from marvin.integration.lib.common import (get_domain, +from marvin.lib.common import (get_domain, get_zone, get_template, get_free_vlan, list_virtual_machines, wait_for_cleanup) -from marvin.integration.lib.utils import (cleanup_resources, +from marvin.lib.utils import (cleanup_resources, random_gen, validateList) from marvin.cloudstackAPI import (authorizeSecurityGroupIngress, @@ -54,14 +54,12 @@ class TestCreateZoneSG(cloudstackTestCase): @classmethod def setUpClass(cls): - cloudstackTestClient = super(TestCreateZoneSG,cls).getClsTestClient() - cls.api_client = cloudstackTestClient.getApiClient() - - # Fill services from the external config file - cls.services = cloudstackTestClient.getConfigParser().parsedDict + cls.testClient = super(TestCreateZoneSG, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = cls.testClient.getParsedTestDataConfig() # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) cls._cleanup = [] return @@ -154,14 +152,13 @@ class TestNetworksInAdvancedSG(cloudstackTestCase): @classmethod def setUpClass(cls): - cloudstackTestClient = super(TestNetworksInAdvancedSG,cls).getClsTestClient() - cls.api_client = cloudstackTestClient.getApiClient() - - cls.services = cloudstackTestClient.getConfigParser().parsedDict + cls.testClient = super(TestNetworksInAdvancedSG, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = cls.testClient.getParsedTestDataConfig() # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template(cls.api_client, cls.zone.id, cls.services["ostype"]) @@ -1102,14 +1099,13 @@ class TestNetworksInAdvancedSG_VmOperations(cloudstackTestCase): @classmethod def setUpClass(cls): - cloudstackTestClient = super(TestNetworksInAdvancedSG_VmOperations,cls).getClsTestClient() - cls.api_client = cloudstackTestClient.getApiClient() - - cls.services = cloudstackTestClient.getConfigParser().parsedDict + cls.testClient = super(TestNetworksInAdvancedSG_VmOperations, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = cls.testClient.getParsedTestDataConfig() # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template(cls.api_client,cls.zone.id,cls.services["ostype"]) cls.services["virtual_machine"]["zoneid"] = cls.zone.id @@ -1311,11 +1307,11 @@ def test__16_AccountSpecificNwAccess(self): zoneid=self.zone.id) # Creaint user API client of account 1 - api_client_account_1 = self.testClient.createUserApiClient(UserName=account_1.name, + api_client_account_1 = self.testClient.getUserApiClient(UserName=account_1.name, DomainName=account_1.domain) # Creaint user API client of account 2 - api_client_account_2 = self.testClient.createUserApiClient(UserName=account_2.name, + api_client_account_2 = self.testClient.getUserApiClient(UserName=account_2.name, DomainName=account_2.domain) self.debug("Creating virtual machine in account %s with account specific shared network %s" % @@ -1423,11 +1419,11 @@ def test__17_DomainSpecificNwAccess(self): self.cleanup_networks.append(shared_network_domain_2) # Creaint user API client of account 1 - api_client_domain_1 = self.testClient.createUserApiClient(UserName=account_1.name, + api_client_domain_1 = self.testClient.getUserApiClient(UserName=account_1.name, DomainName=account_1.domain) # Creaint user API client of account 2 - api_client_domain_2 = self.testClient.createUserApiClient(UserName=account_2.name, + api_client_domain_2 = self.testClient.getUserApiClient(UserName=account_2.name, DomainName=account_2.domain) self.debug("Creating virtual machine in domain %s with domain wide shared network %s" % @@ -2086,14 +2082,13 @@ class TestSecurityGroups_BasicSanity(cloudstackTestCase): @classmethod def setUpClass(cls): - cloudstackTestClient = super(TestSecurityGroups_BasicSanity,cls).getClsTestClient() - cls.api_client = cloudstackTestClient.getApiClient() - - cls.services = cloudstackTestClient.getConfigParser().parsedDict + cls.testClient = super(TestSecurityGroups_BasicSanity, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = cls.testClient.getParsedTestDataConfig() # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template(cls.api_client,cls.zone.id,cls.services["ostype"]) cls.services["virtual_machine"]["zoneid"] = cls.zone.id @@ -2548,14 +2543,13 @@ class TestSharedNetworkOperations(cloudstackTestCase): @classmethod def setUpClass(cls): - cloudstackTestClient = super(TestSharedNetworkOperations,cls).getClsTestClient() - cls.api_client = cloudstackTestClient.getApiClient() - - cls.services = cloudstackTestClient.getConfigParser().parsedDict + cls.testClient = super(TestSharedNetworkOperations, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = cls.testClient.getParsedTestDataConfig() # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template(cls.api_client,cls.zone.id,cls.services["ostype"]) cls.services["virtual_machine"]["zoneid"] = cls.zone.id @@ -2815,14 +2809,13 @@ class TestAccountBasedIngressRules(cloudstackTestCase): @classmethod def setUpClass(cls): - cloudstackTestClient = super(TestAccountBasedIngressRules,cls).getClsTestClient() - cls.api_client = cloudstackTestClient.getApiClient() - - cls.services = cloudstackTestClient.getConfigParser().parsedDict + cls.testClient = super(TestAccountBasedIngressRules, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = cls.testClient.getParsedTestDataConfig() # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template(cls.api_client,cls.zone.id,cls.services["ostype"]) cls.services["virtual_machine"]["zoneid"] = cls.zone.id diff --git a/test/integration/component/test_affinity_groups.py b/test/integration/component/test_affinity_groups.py index 7e4fabe547..de5f007dbb 100644 --- a/test/integration/component/test_affinity_groups.py +++ b/test/integration/component/test_affinity_groups.py @@ -15,12 +15,20 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -from marvin.cloudstackTestCase import * -from marvin.cloudstackAPI import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * -from marvin.sshClient import SshClient +from marvin.cloudstackTestCase import cloudstackTestCase, unittest +from marvin.cloudstackAPI import deleteAffinityGroup +from marvin.lib.utils import (cleanup_resources, + random_gen) +from marvin.lib.base import (Account, + ServiceOffering, + VirtualMachine, + AffinityGroup, + Domain) +from marvin.lib.common import (get_zone, + get_domain, + get_template, + list_virtual_machines, + wait_for_cleanup) from nose.plugins.attrib import attr class Services: @@ -89,12 +97,12 @@ class TestCreateAffinityGroup(cloudstackTestCase): @classmethod def setUpClass(cls): - - cls.api_client = super(TestCreateAffinityGroup, cls).getClsTestClient().getApiClient() + cls.testClient = super(TestCreateAffinityGroup, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, @@ -105,11 +113,14 @@ def setUpClass(cls): cls.services["template"] = cls.template.id cls.services["zoneid"] = cls.zone.id + cls._cleanup = [] + cls.account = Account.create( cls.api_client, cls.services["account"], domainid=cls.domain.id ) + cls._cleanup.append(cls.account) cls.services["account"] = cls.account.name cls.services["domainid"] = cls.domain.id @@ -118,11 +129,7 @@ def setUpClass(cls): cls.api_client, cls.services["service_offering"] ) - - cls._cleanup = [ - cls.service_offering, - cls.account, - ] + cls._cleanup.append(cls.service_offering) return def setUp(self): @@ -169,7 +176,7 @@ def create_aff_grp(self, api_client=None, aff_grp=None, except Exception as e: raise Exception("Error: Creation of Affinity Group failed : %s" %e) - @attr(tags=["simulator", "basic", "advanced"]) + @attr(tags=["simulator", "basic", "advanced", "selfservice"]) def test_01_admin_create_aff_grp(self): """ Test create affinity group as admin @@ -184,7 +191,7 @@ def test_01_admin_create_aff_grp(self): self.assert_(list_aff_grps[0].id == aff_grp.id) self.cleanup.append(aff_grp) - @attr(tags=["simulator", "basic", "advanced"]) + @attr(tags=["simulator", "basic", "advanced", "selfservice"]) def test_02_doadmin_create_aff_grp(self): """ Test create affinity group as domain admin @@ -197,14 +204,14 @@ def test_02_doadmin_create_aff_grp(self): self.cleanup.append(self.do_admin) self.cleanup.append(self.new_domain) - domainapiclient = self.testClient.createUserApiClient(self.do_admin.name, self.new_domain.name, 2) + domainapiclient = self.testClient.getUserApiClient(self.do_admin.name, self.new_domain.name, 2) aff_grp = self.create_aff_grp(api_client=domainapiclient, aff_grp=self.services["host_anti_affinity"], acc=self.do_admin.name, domainid=self.new_domain.id) aff_grp.delete(domainapiclient) #@attr(tags=["simulator", "basic", "advanced"]) - @attr(tags=["vogxn", "simulator", "basic", "advanced"]) + @attr(tags=["vogxn", "simulator", "basic", "advanced", "selfservice"]) def test_03_user_create_aff_grp(self): """ Test create affinity group as user @@ -213,16 +220,15 @@ def test_03_user_create_aff_grp(self): self.user = Account.create(self.api_client, self.services["new_account"], domainid=self.domain.id) - - userapiclient = self.testClient.createUserApiClient(self.user.name, self.domain.name) - self.cleanup.append(self.user) + + userapiclient = self.testClient.getUserApiClient(self.user.name, self.domain.name) aff_grp = self.create_aff_grp(api_client=userapiclient, aff_grp=self.services["host_anti_affinity"], acc=self.user.name, domainid=self.domain.id) aff_grp.delete(userapiclient) - @attr(tags=["simulator", "basic", "advanced"]) + @attr(tags=["simulator", "basic", "advanced", "selfservice"]) def test_04_user_create_aff_grp_existing_name(self): """ Test create affinity group that exists (same name) @@ -243,7 +249,7 @@ def test_04_user_create_aff_grp_existing_name(self): self.debug("Deleted Affinity Group: %s" %aff_grp.name) aff_grp.delete(self.api_client) - @attr(tags=["simulator", "basic", "advanced"]) + @attr(tags=["simulator", "basic", "advanced", "selfservice"]) def test_05_create_aff_grp_same_name_diff_acc(self): """ Test create affinity group with existing name but within different account @@ -265,7 +271,7 @@ def test_05_create_aff_grp_same_name_diff_acc(self): self.debug("Deleted Affinity Group: %s" %aff_grp.name) aff_grp.delete(self.api_client) - @attr(tags=["simulator", "basic", "advanced"]) + @attr(tags=["simulator", "basic", "advanced", "selfservice"]) def test_06_create_aff_grp_nonexisting_type(self): """ Test create affinity group of non-existing type @@ -283,12 +289,14 @@ class TestListAffinityGroups(cloudstackTestCase): @classmethod def setUpClass(cls): + cls.testClient = super(TestListAffinityGroups, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() - cls.api_client = super(TestListAffinityGroups, cls).getClsTestClient().getApiClient() cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) + cls.template = get_template( cls.api_client, cls.zone.id, @@ -299,11 +307,14 @@ def setUpClass(cls): cls.services["template"] = cls.template.id cls.services["zoneid"] = cls.zone.id + cls._cleanup = [] + cls.account = Account.create( cls.api_client, cls.services["account"], domainid=cls.domain.id ) + cls._cleanup.append(cls.account) cls.services["account"] = cls.account.name cls.services["domainid"] = cls.domain.id @@ -312,12 +323,7 @@ def setUpClass(cls): cls.api_client, cls.services["service_offering"] ) - - cls.__cleanup = [ - cls.service_offering, - cls.account, - ] - + cls._cleanup.append(cls.service_offering) # Create multiple Affinity Groups return @@ -391,7 +397,7 @@ def create_vm_in_aff_grps(self, ag_list, account_name=None, domain_id=None): msg="VM is not in Running state") return vm, vm_response.hostid - @attr(tags=["simulator", "basic", "advanced"]) + @attr(tags=["simulator", "basic", "advanced", "selfservice"]) def test_01_list_aff_grps_for_vm(self): """ List affinity group for a vm @@ -413,7 +419,7 @@ def test_01_list_aff_grps_for_vm(self): self.aff_grp[0].delete(self.api_client) - @attr(tags=["simulator", "basic", "advanced"]) + @attr(tags=["simulator", "basic", "advanced", "selfservice"]) def test_02_list_multiple_aff_grps_for_vm(self): """ List multiple affinity groups associated with a vm @@ -442,7 +448,7 @@ def test_02_list_multiple_aff_grps_for_vm(self): aff_grp_01.delete(self.api_client) aff_grp_02.delete(self.api_client) - @attr(tags=["simulator", "basic", "advanced"]) + @attr(tags=["simulator", "basic", "advanced", "selfservice"]) def test_03_list_aff_grps_by_id(self): """ List affinity groups by id @@ -457,7 +463,7 @@ def test_03_list_aff_grps_by_id(self): self.aff_grp[0].delete(self.api_client) - @attr(tags=["simulator", "basic", "advanced"]) + @attr(tags=["simulator", "basic", "advanced", "selfservice"]) def test_04_list_aff_grps_by_name(self): """ List Affinity Groups by name @@ -471,7 +477,7 @@ def test_04_list_aff_grps_by_name(self): self.aff_grp[0].delete(self.api_client) - @attr(tags=["simulator", "basic", "advanced"]) + @attr(tags=["simulator", "basic", "advanced", "selfservice"]) def test_05_list_aff_grps_by_non_existing_id(self): """ List Affinity Groups by non-existing id @@ -485,7 +491,7 @@ def test_05_list_aff_grps_by_non_existing_id(self): self.aff_grp[0].delete(self.api_client) - @attr(tags=["simulator", "basic", "advanced"]) + @attr(tags=["simulator", "basic", "advanced", "selfservice"]) def test_06_list_aff_grps_by_non_existing_name(self): """ List Affinity Groups by non-existing name @@ -499,7 +505,7 @@ def test_06_list_aff_grps_by_non_existing_name(self): self.aff_grp[0].delete(self.api_client) - @attr(tags=["simulator", "basic", "advanced"]) + @attr(tags=["simulator", "basic", "advanced", "selfservice"]) def test_07_list_all_vms_in_aff_grp(self): """ List affinity group should list all for a vms associated with that group @@ -530,11 +536,14 @@ class TestDeleteAffinityGroups(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestDeleteAffinityGroups, cls).getClsTestClient().getApiClient() + cls.testClient = super(TestDeleteAffinityGroups, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) + cls.template = get_template( cls.api_client, cls.zone.id, @@ -545,11 +554,14 @@ def setUpClass(cls): cls.services["template"] = cls.template.id cls.services["zoneid"] = cls.zone.id + cls._cleanup = [] + cls.account = Account.create( cls.api_client, cls.services["account"], domainid=cls.domain.id ) + cls._cleanup.append(cls.account) cls.services["account"] = cls.account.name cls.services["domainid"] = cls.domain.id @@ -558,12 +570,7 @@ def setUpClass(cls): cls.api_client, cls.services["service_offering"] ) - - cls.__cleanup = [ - cls.service_offering, - cls.account, - ] - + cls._cleanup.append(cls.service_offering) # Create multiple Affinity Groups return @@ -642,7 +649,7 @@ def delete_aff_group(self, apiclient, **kwargs): [setattr(cmd, k, v) for k, v in kwargs.items()] return apiclient.deleteAffinityGroup(cmd) - @attr(tags=["simulator", "basic", "advanced", "multihost"]) + @attr(tags=["simulator", "basic", "advanced", "multihost", "selfservice"]) def test_01_delete_aff_grp_by_name(self): """ Delete Affinity Group by name @@ -653,7 +660,7 @@ def test_01_delete_aff_grp_by_name(self): self.delete_aff_group(self.api_client, name=aff_0.name) self.assert_(AffinityGroup.list(self.api_client, name=aff_0.name) is None) - @attr(tags=["simulator", "basic", "advanced", "multihost"]) + @attr(tags=["simulator", "basic", "advanced", "multihost", "selfservice"]) def test_02_delete_aff_grp_for_acc(self): """ Delete Affinity Group as admin for an account @@ -669,7 +676,7 @@ def test_02_delete_aff_grp_for_acc(self): self.create_vm_in_aff_grps([aff_0.name], account_name=self.account.name, domain_id=self.domain.id) aff_1.delete(self.api_client) - @attr(tags=["simulator", "basic", "advanced", "multihost"]) + @attr(tags=["simulator", "basic", "advanced", "multihost", "selfservice"]) def test_03_delete_aff_grp_with_vms(self): """ Delete Affinity Group which has vms in it @@ -687,7 +694,7 @@ def test_03_delete_aff_grp_with_vms(self): wait_for_cleanup(self.apiclient, ["expunge.delay", "expunge.interval"]) aff_1.delete(self.api_client) - @attr(tags=["simulator", "basic", "advanced", "multihost"]) + @attr(tags=["simulator", "basic", "advanced", "multihost", "selfservice"]) def test_05_delete_aff_grp_id(self): """ Delete Affinity Group with id which does not belong to this user @@ -704,10 +711,10 @@ def test_05_delete_aff_grp_id(self): self.user2 = Account.create(self.apiclient, self.services["new_account1"]) self.cleanup.append(self.user2) - userapiclient = self.testClient.createUserApiClient( + userapiclient = self.testClient.getUserApiClient( UserName=self.user2.name, DomainName=self.user2.domain, - acctType=0) + type=0) aff_1 = self.create_aff_grp(api_client=userapiclient, aff_grp=self.services["host_anti_affinity"]) @@ -723,7 +730,7 @@ def test_05_delete_aff_grp_id(self): aff_0.delete(self.api_client) aff_1.delete(userapiclient) - @attr(tags=["simulator", "basic", "advanced", "multihost"]) + @attr(tags=["simulator", "basic", "advanced", "multihost", "selfservice"]) def test_06_delete_aff_grp_name(self): """ Delete Affinity Group by name which does not belong to this user @@ -740,10 +747,10 @@ def test_06_delete_aff_grp_name(self): self.user2 = Account.create(self.apiclient, self.services["new_account1"]) self.cleanup.append(self.user2) - userapiclient = self.testClient.createUserApiClient( + userapiclient = self.testClient.getUserApiClient( UserName=self.user2.name, DomainName=self.user2.domain, - acctType=0) + type=0) aff_1 = self.create_aff_grp(api_client=userapiclient, aff_grp=self.services["host_anti_affinity"]) @@ -759,7 +766,7 @@ def test_06_delete_aff_grp_name(self): aff_0.delete(self.api_client) aff_1.delete(userapiclient) - @attr(tags=["simulator", "basic", "advanced"]) + @attr(tags=["simulator", "basic", "advanced", "selfservice"]) def test_08_delete_aff_grp_by_id(self): """ Delete Affinity Group by id. @@ -771,7 +778,7 @@ def test_08_delete_aff_grp_by_id(self): aff_grp_1.delete(self.api_client) aff_grp_2.delete(self.api_client) - @attr(tags=["simulator", "basic", "advanced"]) + @attr(tags=["simulator", "basic", "advanced", "selfservice"]) def test_09_delete_aff_grp_root_admin(self): """ Root admin should be able to delete affinity group of other users @@ -781,10 +788,10 @@ def test_09_delete_aff_grp_root_admin(self): self.services["new_account"]) self.cleanup.append(self.user1) - user1apiclient = self.testClient.createUserApiClient( + user1apiclient = self.testClient.getUserApiClient( UserName=self.user1.name, DomainName=self.user1.domain, - acctType=0) + type=0) aff_grp = self.create_aff_grp(api_client=user1apiclient, aff_grp=self.services["host_anti_affinity"]) @@ -800,11 +807,14 @@ class TestUpdateVMAffinityGroups(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestUpdateVMAffinityGroups, cls).getClsTestClient().getApiClient() + cls.testClient = super(TestUpdateVMAffinityGroups, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) + cls.template = get_template( cls.api_client, cls.zone.id, @@ -815,11 +825,14 @@ def setUpClass(cls): cls.services["template"] = cls.template.id cls.services["zoneid"] = cls.zone.id + cls._cleanup = [] + cls.account = Account.create( cls.api_client, cls.services["account"], domainid=cls.domain.id ) + cls._cleanup.append(cls.account) cls.services["account"] = cls.account.name cls.services["domainid"] = cls.domain.id @@ -828,12 +841,7 @@ def setUpClass(cls): cls.api_client, cls.services["service_offering"] ) - - cls.__cleanup = [ - cls.service_offering, - cls.account, - ] - + cls._cleanup.append(cls.service_offering) # Create multiple Affinity Groups return @@ -909,7 +917,7 @@ def create_vm_in_aff_grps(self, ag_list, account_name=None, domain_id=None): return vm, vm_response.hostid - @attr(tags=["simulator", "basic", "advanced", "multihost"]) + @attr(tags=["simulator", "basic", "advanced", "multihost", "selfservice"]) def test_01_update_aff_grp_by_ids(self): """ Update the list of affinityGroups by using affinity groupids @@ -957,7 +965,7 @@ def test_01_update_aff_grp_by_ids(self): for aff_grp in self.aff_grp: aff_grp.delete(self.api_client) - @attr(tags=["simulator", "basic", "advanced", "multihost"]) + @attr(tags=["simulator", "basic", "advanced", "multihost", "selfservice"]) def test_02_update_aff_grp_by_names(self): """ Update the list of affinityGroups by using affinity groupnames @@ -1000,7 +1008,7 @@ def test_02_update_aff_grp_by_names(self): for aff_grp in self.aff_grp: aff_grp.delete(self.api_client) - @attr(tags=["simulator", "basic", "advanced", "multihost"]) + @attr(tags=["simulator", "basic", "advanced", "multihost", "selfservice"]) def test_03_update_aff_grp_for_vm_with_no_aff_grp(self): """ Update the list of affinityGroups for vm which is not associated @@ -1033,7 +1041,7 @@ def test_03_update_aff_grp_for_vm_with_no_aff_grp(self): aff_grp.delete(self.api_client) @unittest.skip("Skip - Failing - work in progress") - @attr(tags=["simulator", "basic", "advanced", "multihost"]) + @attr(tags=["simulator", "basic", "advanced", "multihost", "NotRun"]) def test_04_update_aff_grp_remove_all(self): """ Update the list of Affinity Groups to empty list @@ -1059,7 +1067,7 @@ def test_04_update_aff_grp_remove_all(self): for aff_grp in aff_grps: aff_grp.delete(self.api_client) - @attr(tags=["simulator", "basic", "advanced", "multihost"]) + @attr(tags=["simulator", "basic", "advanced", "multihost", "selfservice"]) def test_05_update_aff_grp_on_running_vm(self): """ Update the list of Affinity Groups on running vm @@ -1084,11 +1092,14 @@ class TestDeployVMAffinityGroups(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestDeployVMAffinityGroups, cls).getClsTestClient().getApiClient() + cls.testClient = super(TestDeployVMAffinityGroups, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) + cls.template = get_template( cls.api_client, cls.zone.id, @@ -1099,11 +1110,14 @@ def setUpClass(cls): cls.services["template"] = cls.template.id cls.services["zoneid"] = cls.zone.id + cls._cleanup = [] + cls.account = Account.create( cls.api_client, cls.services["account"], domainid=cls.domain.id ) + cls._cleanup.append(cls.account) cls.services["account"] = cls.account.name cls.services["domainid"] = cls.domain.id @@ -1112,13 +1126,7 @@ def setUpClass(cls): cls.api_client, cls.services["service_offering"] ) - - cls.__cleanup = [ - cls.service_offering, - cls.account, - ] - - # Create multiple Affinity Groups + cls._cleanup.append(cls.service_offering) return def setUp(self): @@ -1195,7 +1203,7 @@ def create_vm_in_aff_grps(self, api_client=None, ag_list=None, ag_ids=None, acco return vm, vm_response.hostid - @attr(tags=["simulator", "basic", "advanced", "multihost"]) + @attr(tags=["simulator", "basic", "advanced", "multihost", "selfservice"]) def test_01_deploy_vm_without_aff_grp(self): """ Deploy VM without affinity group @@ -1206,7 +1214,7 @@ def test_01_deploy_vm_without_aff_grp(self): #Wait for expunge interval to cleanup VM wait_for_cleanup(self.apiclient, ["expunge.delay", "expunge.interval"]) - @attr(tags=["simulator", "basic", "advanced", "multihost"]) + @attr(tags=["simulator", "basic", "advanced", "multihost", "selfservice"]) def test_02_deploy_vm_by_aff_grp_name(self): """ Deploy VM by aff grp name @@ -1218,7 +1226,7 @@ def test_02_deploy_vm_by_aff_grp_name(self): wait_for_cleanup(self.apiclient, ["expunge.delay", "expunge.interval"]) self.aff_grp[0].delete(self.api_client) - @attr(tags=["simulator", "basic", "advanced", "multihost"]) + @attr(tags=["simulator", "basic", "advanced", "multihost", "selfservice"]) def test_03_deploy_vm_by_aff_grp_id(self): """ Deploy VM by aff grp id @@ -1234,7 +1242,7 @@ def test_03_deploy_vm_by_aff_grp_id(self): wait_for_cleanup(self.apiclient, ["expunge.delay", "expunge.interval"]) self.aff_grp[0].delete(self.api_client) - @attr(tags=["simulator", "basic", "advanced", "multihost"]) + @attr(tags=["simulator", "basic", "advanced", "multihost", "selfservice"]) def test_04_deploy_vm_anti_affinity_group(self): """ test DeployVM in anti-affinity groups @@ -1255,7 +1263,7 @@ def test_04_deploy_vm_anti_affinity_group(self): wait_for_cleanup(self.apiclient, ["expunge.delay", "expunge.interval"]) self.aff_grp[0].delete(self.api_client) - @attr(tags=["simulator", "basic", "advanced", "multihost"]) + @attr(tags=["simulator", "basic", "advanced", "multihost", "selfservice"]) def test_05_deploy_vm_by_id(self): """ Deploy vms by affinity group id @@ -1277,7 +1285,7 @@ def test_05_deploy_vm_by_id(self): wait_for_cleanup(self.apiclient, ["expunge.delay", "expunge.interval"]) self.aff_grp[0].delete(self.api_client) - @attr(tags=["simulator", "basic", "advanced", "multihost"]) + @attr(tags=["simulator", "basic", "advanced", "multihost", "selfservice"]) def test_06_deploy_vm_aff_grp_of_other_user_by_name(self): """ Deploy vm in affinity group of another user by name @@ -1294,10 +1302,10 @@ def test_06_deploy_vm_aff_grp_of_other_user_by_name(self): self.user2 = Account.create(self.apiclient, self.services["new_account1"]) self.cleanup.append(self.user2) - userapiclient = self.testClient.createUserApiClient( + userapiclient = self.testClient.getUserApiClient( UserName=self.user2.name, DomainName=self.user2.domain, - acctType=0) + type=0) self.create_aff_grp(api_client=userapiclient, aff_grp=self.services["host_anti_affinity"]) @@ -1310,7 +1318,7 @@ def test_06_deploy_vm_aff_grp_of_other_user_by_name(self): self.aff_grp[0].delete(self.api_client) self.aff_grp[1].delete(userapiclient) - @attr(tags=["simulator", "basic", "advanced", "multihost"]) + @attr(tags=["simulator", "basic", "advanced", "multihost", "selfservice"]) def test_07_deploy_vm_aff_grp_of_other_user_by_id(self): """ Deploy vm in affinity group of another user by id @@ -1327,10 +1335,10 @@ def test_07_deploy_vm_aff_grp_of_other_user_by_id(self): self.user2 = Account.create(self.apiclient, self.services["new_account1"]) self.cleanup.append(self.user2) - userapiclient = self.testClient.createUserApiClient( + userapiclient = self.testClient.getUserApiClient( UserName=self.user2.name, DomainName=self.user2.domain, - acctType=0) + type=0) self.create_aff_grp(api_client=userapiclient, aff_grp=self.services["host_anti_affinity"]) @@ -1346,7 +1354,7 @@ def test_07_deploy_vm_aff_grp_of_other_user_by_id(self): self.aff_grp[0].delete(self.api_client) self.aff_grp[1].delete(userapiclient) - @attr(tags=["simulator", "basic", "advanced", "multihost"]) + @attr(tags=["simulator", "basic", "advanced", "multihost", "selfservice"]) def test_08_deploy_vm_multiple_aff_grps(self): """ Deploy vm in multiple affinity groups @@ -1375,7 +1383,7 @@ def test_08_deploy_vm_multiple_aff_grps(self): self.aff_grp[0].delete(self.api_client) self.aff_grp[1].delete(self.api_client) - @attr(tags=["simulator", "basic", "advanced", "multihost"]) + @attr(tags=["simulator", "basic", "advanced", "multihost", "selfservice"]) def test_09_deploy_vm_multiple_aff_grps(self): """ Deploy multiple vms in multiple affinity groups @@ -1410,7 +1418,7 @@ def test_09_deploy_vm_multiple_aff_grps(self): self.aff_grp[0].delete(self.api_client) self.aff_grp[1].delete(self.api_client) - @attr(tags=["simulator", "basic", "advanced", "multihost"]) + @attr(tags=["simulator", "basic", "advanced", "multihost", "selfservice"]) def test_10_deploy_vm_by_aff_grp_name_and_id(self): """ Deploy VM by aff grp name and id @@ -1432,11 +1440,13 @@ class TestAffinityGroupsAdminUser(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestAffinityGroupsAdminUser, cls).getClsTestClient().getApiClient() + cls.testClient = super(TestAffinityGroupsAdminUser, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, @@ -1447,11 +1457,14 @@ def setUpClass(cls): cls.services["template"] = cls.template.id cls.services["zoneid"] = cls.zone.id + cls._cleanup = [] + cls.account = Account.create( cls.api_client, cls.services["account"], domainid=cls.domain.id ) + cls._cleanup.append(cls.account) cls.services["account"] = cls.account.name cls.services["domainid"] = cls.domain.id @@ -1460,13 +1473,7 @@ def setUpClass(cls): cls.api_client, cls.services["service_offering"] ) - - cls.__cleanup = [ - cls.service_offering, - cls.account, - ] - - # Create multiple Affinity Groups + cls._cleanup.append(cls.service_offering) return def setUp(self): @@ -1540,7 +1547,7 @@ def create_vm_in_aff_grps(self, api_client=None, ag_list=None, ag_ids=None, acco return vm, vm_response.hostid - @attr(tags=["simulator", "basic", "advanced", "multihost"]) + @attr(tags=["simulator", "basic", "advanced", "multihost", "selfservice"]) def test_01_deploy_vm_another_user(self): """ Deploy vm as Admin in Affinity Group belonging to regular user (should fail) @@ -1549,10 +1556,10 @@ def test_01_deploy_vm_another_user(self): self.services["new_account"]) self.cleanup.append(self.user1) - userapiclient = self.testClient.createUserApiClient( + userapiclient = self.testClient.getUserApiClient( UserName=self.user1.name, DomainName=self.user1.domain, - acctType=0) + type=0) aff_grp = self.create_aff_grp(api_client=userapiclient, aff_grp=self.services["host_anti_affinity"]) @@ -1578,7 +1585,7 @@ def test_02_create_aff_grp_user(self): aff_grp.delete(self.apiclient) - @attr(tags=["simulator", "basic", "advanced", "multihost"]) + @attr(tags=["simulator", "basic", "advanced", "multihost", "selfservice"]) def test_03_list_aff_grp_all_users(self): """ List Affinity Groups as admin for all the users @@ -1588,10 +1595,10 @@ def test_03_list_aff_grp_all_users(self): self.services["new_account"]) self.cleanup.append(self.user1) - userapiclient = self.testClient.createUserApiClient( + userapiclient = self.testClient.getUserApiClient( UserName=self.user1.name, DomainName=self.user1.domain, - acctType=0) + type=0) aff_grp = self.create_aff_grp(api_client=userapiclient, aff_grp=self.services["host_anti_affinity"]) @@ -1601,7 +1608,7 @@ def test_03_list_aff_grp_all_users(self): "Groups of users") aff_grp.delete(userapiclient) - @attr(tags=["simulator", "basic", "advanced"]) + @attr(tags=["simulator", "basic", "advanced", "selfservice"]) def test_04_list_all_admin_aff_grp(self): """ List Affinity Groups belonging to admin user @@ -1628,7 +1635,7 @@ def test_04_list_all_admin_aff_grp(self): aff_grp1.delete(self.api_client) aff_grp2.delete(self.api_client) - @attr(tags=["simulator", "basic", "advanced"]) + @attr(tags=["simulator", "basic", "advanced", "selfservice"]) def test_05_list_all_users_aff_grp(self): """ List Affinity Groups belonging to regular user passing account id and domain id @@ -1638,10 +1645,10 @@ def test_05_list_all_users_aff_grp(self): self.services["new_account"]) self.cleanup.append(self.user1) - userapiclient = self.testClient.createUserApiClient( + userapiclient = self.testClient.getUserApiClient( UserName=self.user1.name, DomainName=self.user1.domain, - acctType=0) + type=0) aff_grp1 = self.create_aff_grp(api_client=userapiclient, aff_grp=self.services["host_anti_affinity"]) @@ -1664,7 +1671,7 @@ def test_05_list_all_users_aff_grp(self): aff_grp1.delete(self.api_client) aff_grp2.delete(self.api_client) - @attr(tags=["simulator", "basic", "advanced"]) + @attr(tags=["simulator", "basic", "advanced", "selfservice"]) def test_06_list_all_users_aff_grp_by_id(self): """ List Affinity Groups belonging to regular user passing group id @@ -1674,10 +1681,10 @@ def test_06_list_all_users_aff_grp_by_id(self): self.services["new_account"]) self.cleanup.append(self.user1) - userapiclient = self.testClient.createUserApiClient( + userapiclient = self.testClient.getUserApiClient( UserName=self.user1.name, DomainName=self.user1.domain, - acctType=0) + type=0) aff_grp = self.create_aff_grp(api_client=userapiclient, aff_grp=self.services["host_anti_affinity"]) @@ -1696,7 +1703,7 @@ def test_06_list_all_users_aff_grp_by_id(self): aff_grp.delete(self.api_client) - @attr(tags=["simulator", "basic", "advanced"]) + @attr(tags=["simulator", "basic", "advanced", "selfservice"]) def test_07_delete_aff_grp_of_other_user(self): """ Delete Affinity Group belonging to regular user @@ -1706,10 +1713,10 @@ def test_07_delete_aff_grp_of_other_user(self): self.services["new_account"]) self.cleanup.append(self.user1) - userapiclient = self.testClient.createUserApiClient( + userapiclient = self.testClient.getUserApiClient( UserName=self.user1.name, DomainName=self.user1.domain, - acctType=0) + type=0) aff_grp = self.create_aff_grp(api_client=userapiclient, aff_grp=self.services["host_anti_affinity"]) diff --git a/test/integration/component/test_allocation_states.py b/test/integration/component/test_allocation_states.py index 5ce0b21124..9ba246ffd8 100644 --- a/test/integration/component/test_allocation_states.py +++ b/test/integration/component/test_allocation_states.py @@ -15,17 +15,16 @@ # specific language governing permissions and limitations # under the License. -import marvin from nose.plugins.attrib import attr -from marvin.cloudstackTestCase import * -from marvin.cloudstackAPI import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * -from nose.plugins.attrib import attr -import datetime - - +from marvin.cloudstackTestCase import cloudstackTestCase +from marvin.lib.utils import cleanup_resources +from marvin.lib.base import (Host, + Pod, + Zone, + Cluster, + StoragePool) +from marvin.lib.common import get_zone, get_template +from marvin.codes import FAILED class Services: """Test Resource Limits Services """ @@ -86,13 +85,23 @@ class TestAllocationState(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestAllocationState, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestAllocationState, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services + # Get Zone, Domain and templates - cls.zone = get_zone(cls.api_client, cls.services) + + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) + cls.template = get_template( + cls.api_client, + cls.zone.id, + cls.services["ostype"] + ) + if cls.template == FAILED: + assert False, "get_template() failed to return template with description %s" % cls.services["ostype"] + + cls.services['mode'] = cls.zone.networktype cls._cleanup = [] return @@ -120,7 +129,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags = ["advanced", "advancedns", "simulator"]) + @attr(tags=["advanced", "advancedns", "simulator", "selfservice"]) def test_01_zones(self): """Check the status of zones""" @@ -146,7 +155,7 @@ def test_01_zones(self): ) return - @attr(tags = ["advanced", "advancedns", "simulator"]) + @attr(tags=["advanced", "advancedns", "simulator", "selfservice"]) def test_02_pods(self): """Check the status of pods""" @@ -172,7 +181,7 @@ def test_02_pods(self): ) return - @attr(tags = ["advanced", "advancedns", "simulator"]) + @attr(tags=["advanced", "advancedns", "simulator", "selfservice"]) def test_03_clusters(self): """Check the status of clusters""" @@ -198,7 +207,7 @@ def test_03_clusters(self): ) return - @attr(tags = ["advanced", "advancedns", "simulator"]) + @attr(tags=["advanced", "advancedns", "simulator", "selfservice"]) def test_04_hosts(self): """Check the status of hosts""" @@ -225,7 +234,7 @@ def test_04_hosts(self): ) return - @attr(tags = ["advanced", "advancedns", "simulator"]) + @attr(tags=["advanced", "advancedns", "simulator", "selfservice"]) def test_05_storage_pools(self): """Check the status of Storage pools""" @@ -251,7 +260,7 @@ def test_05_storage_pools(self): ) return - @attr(tags = ["advanced", "advancedns", "simulator"]) + @attr(tags=["advanced", "advancedns", "simulator", "selfservice"]) def test_06_secondary_storage(self): """Check the status of secondary storage""" diff --git a/test/integration/component/test_asa1000v_fw.py b/test/integration/component/test_asa1000v_fw.py index c8a11ab170..43d06d1864 100644 --- a/test/integration/component/test_asa1000v_fw.py +++ b/test/integration/component/test_asa1000v_fw.py @@ -18,15 +18,15 @@ """ Cisco ASA1000v external firewall """ #Import Local Modules -import marvin from nose.plugins.attrib import attr -from marvin.cloudstackTestCase import * -from marvin.cloudstackAPI import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * -from marvin.sshClient import SshClient -import datetime +from marvin.cloudstackTestCase import cloudstackTestCase +from marvin.lib.utils import cleanup_resources +from marvin.lib.base import (NetworkOffering, + PhysicalNetwork, + VNMC, + ASA1000V, + Cluster) +from marvin.lib.common import get_zone class Services: @@ -101,7 +101,7 @@ def setUp(self): self.apiclient = self.testClient.getApiClient() self.dbclient = self.testClient.getDbConnection() - self.zone = get_zone(self.apiclient, self.services) + self.zone = get_zone(self.apiclient, self.testClient.getZoneForTests()) self.physicalnetworks = PhysicalNetwork.list(self.apiclient, zoneid=self.zone.id) self.assertNotEqual(len(self.physicalnetworks), 0, "Check if the list physical network API returns a non-empty response") self.clusters = Cluster.list(self.apiclient, hypervisor='VMware') diff --git a/test/integration/component/test_assign_vm.py b/test/integration/component/test_assign_vm.py index 400d5f2e72..24b63a62f1 100644 --- a/test/integration/component/test_assign_vm.py +++ b/test/integration/component/test_assign_vm.py @@ -20,7 +20,7 @@ #Import Local Modules from nose.plugins.attrib import attr from marvin.cloudstackTestCase import cloudstackTestCase -from marvin.integration.lib.base import (Account, +from marvin.lib.base import (Account, Domain, User, Project, @@ -29,7 +29,7 @@ DiskOffering, ServiceOffering, VirtualMachine) -from marvin.integration.lib.common import (get_domain, +from marvin.lib.common import (get_domain, get_zone, get_template, list_volumes, @@ -37,7 +37,7 @@ list_networks, list_snapshots, list_virtual_machines) -from marvin.integration.lib.utils import cleanup_resources +from marvin.lib.utils import cleanup_resources def log_test_exceptions(func): def test_wrap_exception_log(self, *args, **kwargs): @@ -98,12 +98,13 @@ class TestVMOwnership(cloudstackTestCase): @classmethod def setUpClass(cls): cls._cleanup = [] - cls.api_client = super(TestVMOwnership, - cls).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone Domain and create Domains and sub Domains. - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.testClient = super(TestVMOwnership, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + + cls.services = Services().services + # 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 # Get and set template id for VM creation. cls.template = get_template(cls.api_client, @@ -353,8 +354,8 @@ def test_09_move_across_subdomain(self): # 1. deploy VM in sub subdomain1 # 2. stop VM in sub subdomain1 # 3. assignVirtualMachine to subdomain2 - userapiclient = self.testClient.getUserApiClient(account=self.sdomain_account_user1['account'].name, - domain=self.sdomain_account_user1['domain'].name, + userapiclient = self.testClient.getUserApiClient(UserName=self.sdomain_account_user1['account'].name, + DomainName=self.sdomain_account_user1['domain'].name, type=2) self.create_vm(self.sdomain_account_user1['account'], self.sdomain_account_user1['domain']) self.assertRaises(Exception, self.virtual_machine.assign_virtual_machine, userapiclient, self.sdomain_account_user2['account'].name ,self.sdomain_account_user2['domain'].id) @@ -389,8 +390,8 @@ def test_12_move_across_subdomain_vm_volumes(self): # Validate the following: # 1. deploy VM in sub subdomain1 with volumes. # 3. assignVirtualMachine to subdomain2 - userapiclient = self.testClient.getUserApiClient(account=self.sdomain_account_user1['account'].name, - domain=self.sdomain_account_user1['domain'].name, + userapiclient = self.testClient.getUserApiClient(UserName=self.sdomain_account_user1['account'].name, + DomainName=self.sdomain_account_user1['domain'].name, type=2) self.create_vm(self.sdomain_account_user1['account'], self.sdomain_account_user1['domain'],volume=self.sdomain_account_user1['volume']) self.assertRaises(Exception, self.virtual_machine.assign_virtual_machine, userapiclient, self.sdomain_account_user2['account'].name ,self.sdomain_account_user2['domain'].id) @@ -431,8 +432,8 @@ def test_14_move_across_subdomain_vm_project(self): # Validate the following: # 1. deploy VM in sub subdomain1 with snapshot. # 3. assignVirtualMachine to subdomain2 - userapiclient = self.testClient.getUserApiClient(account=self.sdomain_account_user1['account'].name, - domain=self.sdomain_account_user1['domain'].name, + userapiclient = self.testClient.getUserApiClient(UserName=self.sdomain_account_user1['account'].name, + DomainName=self.sdomain_account_user1['domain'].name, type=2) self.create_vm(self.sdomain_account_user1['account'], self.sdomain_account_user1['domain'], project=self.sdomain_account_user1['project']) self.assertRaises(Exception, self.virtual_machine.assign_virtual_machine, userapiclient, self.sdomain_account_user2['account'].name ,self.sdomain_account_user2['domain'].id) @@ -450,8 +451,8 @@ def test_15_move_across_subdomain_account_limit(self): account=self.sdomain_account_user2['account'].name, domainid=self.sdomain_account_user2['domain'].id, max=0) - userapiclient = self.testClient.getUserApiClient(account=self.sdomain_account_user1['account'].name, - domain=self.sdomain_account_user1['domain'].name, + userapiclient = self.testClient.getUserApiClient(UserName=self.sdomain_account_user1['account'].name, + DomainName=self.sdomain_account_user1['domain'].name, type=2) self.create_vm(self.sdomain_account_user1['account'], self.sdomain_account_user1['domain'], snapshot=True) self.assertRaises(Exception, self.virtual_machine.assign_virtual_machine, userapiclient, self.sdomain_account_user2['account'].name ,self.sdomain_account_user2['domain'].id) @@ -470,8 +471,8 @@ def test_16_move_across_subdomain_volume_and_account_limit(self): account=self.sdomain_account_user2['account'].name, domainid=self.sdomain_account_user2['domain'].id, max=0) - userapiclient = self.testClient.getUserApiClient(account=self.sdomain_account_user1['account'].name, - domain=self.sdomain_account_user1['domain'].name, + userapiclient = self.testClient.getUserApiClient(UserName=self.sdomain_account_user1['account'].name, + DomainName=self.sdomain_account_user1['domain'].name, type=2) self.create_vm(self.sdomain_account_user1['account'], self.sdomain_account_user1['domain'], snapshot=True, volume=self.sdomain_account_user1['volume']) self.assertRaises(Exception, self.virtual_machine.assign_virtual_machine, userapiclient, self.sdomain_account_user2['account'].name ,self.sdomain_account_user2['domain'].id) diff --git a/test/integration/component/test_baremetal.py b/test/integration/component/test_baremetal.py index 2439d0d213..6ab91466bd 100644 --- a/test/integration/component/test_baremetal.py +++ b/test/integration/component/test_baremetal.py @@ -17,18 +17,18 @@ """ Test for baremetal """ #Import Local Modules -import marvin -from marvin.cloudstackTestCase import * -from marvin.cloudstackAPI import * -from marvin.sshClient import SshClient -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * +from marvin.cloudstackTestCase import cloudstackTestCase +from marvin.cloudstackAPI import createVlanIpRange +from marvin.lib.utils import cleanup_resources +from marvin.lib.base import (NetworkOffering, + NetworkServiceProvider, + PhysicalNetwork, + Network, + Pod) +#from marvin.lib.common import * from nose.plugins.attrib import attr -import telnetlib #Import System modules -import time _multiprocess_shared_ = True class Services: @@ -89,19 +89,19 @@ def test_baremetal(self): physical_network = PhysicalNetwork.list(self.apiclient, zoneid=self.zoneid)[0]; dhcp_provider = NetworkServiceProvider.list(self.apiclient, name="BaremetalDhcpProvider", physical_network_id=physical_network.id)[0] - response = NetworkServiceProvider.update( + NetworkServiceProvider.update( self.apiclient, id=dhcp_provider.id, state='Enabled' ) pxe_provider = NetworkServiceProvider.list(self.apiclient, name="BaremetalPxeProvider", physical_network_id=physical_network.id)[0] - response = NetworkServiceProvider.update( + NetworkServiceProvider.update( self.apiclient, id=pxe_provider.id, state='Enabled' ) userdata_provider = NetworkServiceProvider.list(self.apiclient, name="BaremetalUserdataProvider", physical_network_id=physical_network.id)[0] - response = NetworkServiceProvider.update( + NetworkServiceProvider.update( self.apiclient, id=userdata_provider.id, state='Enabled' @@ -119,5 +119,5 @@ def test_baremetal(self): cmd.startip = "10.1.1.20" cmd.endip = "10.1.1.40" cmd.forVirtualNetwork="false" - response = self.apiclient.createVlanIpRange(cmd) - \ No newline at end of file + self.apiclient.createVlanIpRange(cmd) + diff --git a/test/integration/component/test_base_image_updation.py b/test/integration/component/test_base_image_updation.py index e31aacfa7e..081d855fca 100644 --- a/test/integration/component/test_base_image_updation.py +++ b/test/integration/component/test_base_image_updation.py @@ -26,11 +26,12 @@ #Import Local Modules from marvin.codes import (PASS, + FAIL, RECURRING) from nose.plugins.attrib import attr from marvin.cloudstackTestCase import cloudstackTestCase -from marvin.integration.lib.base import (ServiceOffering, +from marvin.lib.base import (ServiceOffering, Account, VirtualMachine, Volume, @@ -40,13 +41,13 @@ Template ) -from marvin.integration.lib.common import (get_domain, +from marvin.lib.common import (get_domain, get_zone, get_template, list_templates ) -from marvin.integration.lib.utils import (validateList, +from marvin.lib.utils import (validateList, cleanup_resources) import time @@ -160,14 +161,14 @@ class TestBaseImageUpdate(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestBaseImageUpdate, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestBaseImageUpdate, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) + cls.template = get_template( cls.api_client, cls.zone.id, @@ -237,6 +238,7 @@ def get_root_device_uuid_for_vm(cls, vm_id, root_device_id): def setUp(self): self.apiclient = self.testClient.getApiClient() + self.hypervisor = self.testClient.getHypervisorInfo() self.dbclient = self.testClient.getDbConnection() self.cleanup = [] @@ -291,7 +293,7 @@ def verify_template_listing(self, template): return - @attr(tags=["advanced", "basic"]) + @attr(tags=["advanced", "basic", "selfservice"]) def test_01_deploy_instance_with_is_volatile_offering(self): """ Test deploy an instance with service offerings with IsVolatile set. """ @@ -322,7 +324,7 @@ def test_01_deploy_instance_with_is_volatile_offering(self): ) return - @attr(tags=["advanced", "basic"]) + @attr(tags=["advanced", "basic", "selfservice"]) def test_02_reboot_instance_with_is_volatile_offering(self): """ Test rebooting instances created with isVolatile service offerings """ @@ -400,7 +402,7 @@ def test_02_reboot_instance_with_is_volatile_offering(self): return - @attr(tags=["advanced", "basic"]) + @attr(tags=["advanced", "basic", "selfservice"]) def test_03_restore_vm_with_new_template(self): """ Test restoring a vm with different template than the one it was created with """ @@ -426,7 +428,8 @@ def test_03_restore_vm_with_new_template(self): v, zoneid=self.zone.id, account=self.account.name, - domainid=self.account.domainid + domainid=self.account.domainid, + hypervisor=self.hypervisor ) self.debug( "Registered a template of format: %s with ID: %s" % ( @@ -515,7 +518,7 @@ def test_03_restore_vm_with_new_template(self): ) return - @attr(tags=["advanced", "basic"]) + @attr(tags=["advanced", "basic", "selfservice"]) def test_04_reoccuring_snapshot_rules(self): """ 1) Create a VM using the Service offering IsVolatile enabled @@ -647,9 +650,13 @@ def test_04_reoccuring_snapshot_rules(self): Here we are passing root disk id of vm before reboot which does not exist hence\ listing should fail") - with self.assertRaises(Exception): - list_snapshots_policy = SnapshotPolicy.list( - self.apiclient, - volumeid=vm_with_reset_root_disk_id - ) + try: + listSnapshotPolicies = SnapshotPolicy.list( + self.apiclient, + volumeid=vm_with_reset_root_disk_id) + except Exception as e: + self.fail("Failed to list snapshot policies: %s" % e) + + self.assertEqual(validateList(listSnapshotPolicies)[0], FAIL,\ + "Snapshot policies list should be empty") return diff --git a/test/integration/component/test_blocker_bugs.py b/test/integration/component/test_blocker_bugs.py index 04a26562d0..ba15b186c1 100644 --- a/test/integration/component/test_blocker_bugs.py +++ b/test/integration/component/test_blocker_bugs.py @@ -16,15 +16,30 @@ # under the License. """ Tests for Blocker bugs """ -import marvin from nose.plugins.attrib import attr -from marvin.integration.lib.base import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.common import * +from marvin.lib.base import (Snapshot, + Template, + Domain, + Account, + ServiceOffering, + Network, + VirtualMachine, + PublicIPAddress, + StaticNATRule, + FireWallRule, + Volume) +from marvin.lib.utils import cleanup_resources, validateList +from marvin.lib.common import (get_zone, + get_domain, + get_template, + list_routers, + get_builtin_template_info) #Import Local Modules -from marvin.cloudstackTestCase import * -from marvin.cloudstackAPI import * +from marvin.cloudstackTestCase import cloudstackTestCase, unittest +from marvin.cloudstackAPI import restartNetwork +from marvin.codes import PASS +import time class Services: @@ -95,8 +110,8 @@ def __init__(self): class TestTemplate(cloudstackTestCase): def setUp(self): - self.apiclient = self.testClient.getApiClient() + self.hypervisor = self.testClient.getHypervisorInfo() self.dbclient = self.testClient.getDbConnection() self.cleanup = [] return @@ -110,12 +125,13 @@ def tearDown(self): @classmethod def setUpClass(cls): - cls.services = Services().services - cls.api_client = super(TestTemplate, cls).getClsTestClient().getApiClient() + cls.testClient = super(TestTemplate, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype cls.services["virtual_machine"]["zoneid"] = cls.zone.id cls.services["template"]["zoneid"] = cls.zone.id @@ -149,7 +165,7 @@ def tearDownClass(cls): return - @attr(tags = ["advanced", "advancedns", "basic", "sg"]) + @attr(tags=["advanced", "advancedns", "basic", "sg", "provisioning"]) def test_01_create_template(self): """TS_BUG_002-Test to create and deploy VM using password enabled template """ @@ -173,7 +189,8 @@ def test_01_create_template(self): self.services["template"], zoneid=self.zone.id, account=self.account.name, - domainid=self.account.domainid + domainid=self.account.domainid, + hypervisor=self.hypervisor ) self.debug( "Registered a template of format: %s with ID: %s" % ( @@ -242,12 +259,14 @@ class TestNATRules(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestNATRules, cls).getClsTestClient().getApiClient() - cls.services = Services().services + cls.testClient = super(TestNATRules, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) + cls.services['mode'] = cls.zone.networktype template = get_template( cls.api_client, @@ -308,7 +327,7 @@ def tearDownClass(cls): except Exception as e: raise Exception("Warning: Exception during cleanup : %s" % e) - @attr(tags = ["advanced"]) + @attr(tags=["advanced", "selfservice"]) def test_01_firewall_rules_port_fw(self): """"Checking firewall rules deletion after static NAT disable""" @@ -448,10 +467,12 @@ class TestRouters(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestRouters, cls).getClsTestClient().getApiClient() + cls.testClient = super(TestRouters, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.zone = get_zone(cls.api_client, cls.services) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype cls.template = get_template( cls.api_client, @@ -515,7 +536,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags = ["advanced", "advancedns"]) + @attr(tags=["advanced", "advancedns", "selfservice"]) def test_01_list_routers_admin(self): """TS_BUG_007-Check listRouters() using Admin User """ @@ -573,11 +594,13 @@ class TestRouterRestart(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestRouterRestart, cls).getClsTestClient().getApiClient() + cls.testClient = super(TestRouterRestart, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) + cls.domain = get_domain(cls.api_client) cls.services['mode'] = cls.zone.networktype template = get_template( cls.api_client, @@ -630,7 +653,7 @@ def tearDown(self): # No need return - @attr(tags = ["advanced", "advancedns", "eip"]) + @attr(tags=["advanced", "advancedns", "eip", "selfservice"]) def test_01_restart_network_cleanup(self): """TS_BUG_008-Test restart network """ @@ -706,12 +729,14 @@ class TestTemplates(cloudstackTestCase): @classmethod def setUpClass(cls): + cls.testClient = super(TestTemplates, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services - cls.api_client = super(TestTemplates, cls).getClsTestClient().getApiClient() + # Get Zone, Domain and templates + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) + cls.domain = get_domain(cls.api_client) - # Get Zone, templates etc - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) cls.services['mode'] = cls.zone.networktype template = get_template( @@ -720,20 +745,24 @@ def setUpClass(cls): cls.services["ostype"] ) cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.account = Account.create( + cls._cleanup = [] + try: + cls.account = Account.create( cls.api_client, cls.services["account"], domainid=cls.domain.id ) + cls._cleanup.append(cls.account) - cls.services["account"] = cls.account.name - cls.service_offering = ServiceOffering.create( + cls.services["account"] = cls.account.name + cls.service_offering = ServiceOffering.create( cls.api_client, cls.services["service_offering"], ) + cls._cleanup.append(cls.service_offering) - # create virtual machine - cls.virtual_machine = VirtualMachine.create( + # create virtual machine + cls.virtual_machine = VirtualMachine.create( cls.api_client, cls.services["virtual_machine"], templateid=template.id, @@ -741,27 +770,20 @@ def setUpClass(cls): domainid=cls.account.domainid, serviceofferingid=cls.service_offering.id, ) - #Stop virtual machine - cls.virtual_machine.stop(cls.api_client) + #Stop virtual machine + cls.virtual_machine.stop(cls.api_client) - #Wait before server has be successfully stopped - time.sleep(30) - list_volume = Volume.list( + listvolumes = Volume.list( cls.api_client, virtualmachineid=cls.virtual_machine.id, type='ROOT', listall=True ) - try: - if isinstance(list_volume, list): - cls.volume = list_volume[0] + assert validateList(listvolumes)[0] == PASS, "volumes list is empty" + cls.volume = listvolumes[0] except Exception as e: - raise Exception("Warning: Exception during setup : %s" % e) - - cls._cleanup = [ - cls.service_offering, - cls.account, - ] + cls.tearDownClass() + raise unittest.SkipTest("Exception in setUpClass: %s" % e) @classmethod def tearDownClass(cls): @@ -793,7 +815,7 @@ def tearDown(self): return @attr(speed = "slow") - @attr(tags = ["advanced", "advancedns", "basic", "sg", "eip"]) + @attr(tags=["advanced", "advancedns", "basic", "sg", "eip", "provisioning"]) def test_01_check_template_size(self): """TS_BUG_009-Test the size of template created from root disk """ @@ -821,7 +843,7 @@ def test_01_check_template_size(self): return @attr(speed = "slow") - @attr(tags = ["advanced", "advancedns", "basic", "sg", "eip"]) + @attr(tags=["advanced", "advancedns", "basic", "sg", "eip", "provisioning"]) def test_02_check_size_snapshotTemplate(self): """TS_BUG_010-Test check size of snapshot and template """ @@ -902,7 +924,7 @@ def test_02_check_size_snapshotTemplate(self): return @attr(speed = "slow") - @attr(tags = ["advanced", "advancedns", "basic", "sg", "eip"]) + @attr(tags=["advanced", "advancedns", "basic", "sg", "eip", "provisioning"]) def test_03_reuse_template_name(self): """TS_BUG_011-Test Reusing deleted template name """ diff --git a/test/integration/component/test_cpu_domain_limits.py b/test/integration/component/test_cpu_domain_limits.py index 1247a799c8..6cca7c82c6 100644 --- a/test/integration/component/test_cpu_domain_limits.py +++ b/test/integration/component/test_cpu_domain_limits.py @@ -19,21 +19,21 @@ """ # Import Local Modules from nose.plugins.attrib import attr -from marvin.cloudstackTestCase import cloudstackTestCase, unittest -from marvin.integration.lib.base import ( +from marvin.cloudstackTestCase import cloudstackTestCase +from marvin.lib.base import ( Account, ServiceOffering, VirtualMachine, Resources, Domain ) -from marvin.integration.lib.common import (get_domain, +from marvin.lib.common import (get_domain, get_zone, get_template, findSuitableHostForMigration, get_resource_type ) -from marvin.integration.lib.utils import cleanup_resources +from marvin.lib.utils import cleanup_resources from marvin.codes import ERROR_NO_HOST_FOR_MIGRATION class Services: @@ -91,12 +91,13 @@ class TestDomainCPULimitsUpdateResources(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestDomainCPULimitsUpdateResources, - cls).getClsTestClient().getApiClient() + cls.testClient = super(TestDomainCPULimitsUpdateResources, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + 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, @@ -217,7 +218,7 @@ def setupAccounts(self): ) return - @attr(tags=["advanced", "advancedns","simulator"]) + @attr(tags=["advanced", "advancedns","simulator", "selfservice"]) def test_01_multiple_core_vm_start_stop_instance(self): """Test Deploy VM with 4 core CPU & verify the usage""" @@ -237,7 +238,7 @@ def test_01_multiple_core_vm_start_stop_instance(self): self.account = admin self.domain = domain - api_client = self.testClient.createUserApiClient( + api_client = self.testClient.getUserApiClient( UserName=self.account.name, DomainName=self.account.domain) @@ -290,7 +291,7 @@ def test_01_multiple_core_vm_start_stop_instance(self): "Resource count should be same as before, after starting the instance") return - @attr(tags=["advanced", "advancedns","simulator"]) + @attr(tags=["advanced", "advancedns","simulator", "provisioning"]) def test_02_multiple_core_vm_migrate_instance(self): """Test Deploy VM with 4 core CPU & verify the usage""" @@ -310,7 +311,7 @@ def test_02_multiple_core_vm_migrate_instance(self): self.account = admin self.domain = domain - api_client = self.testClient.createUserApiClient( + api_client = self.testClient.getUserApiClient( UserName=self.account.name, DomainName=self.account.domain) @@ -351,7 +352,7 @@ def test_02_multiple_core_vm_migrate_instance(self): "Resource count should be same as before, after migrating the instance") return - @attr(tags=["advanced", "advancedns","simulator"]) + @attr(tags=["advanced", "advancedns","simulator", "selfservice"]) def test_03_multiple_core_vm_delete_instance(self): """Test Deploy VM with 4 core CPU & verify the usage""" @@ -371,7 +372,7 @@ def test_03_multiple_core_vm_delete_instance(self): self.account = admin self.domain = domain - api_client = self.testClient.createUserApiClient( + api_client = self.testClient.getUserApiClient( UserName=self.account.name, DomainName=self.account.domain) @@ -408,7 +409,7 @@ def test_03_multiple_core_vm_delete_instance(self): "Resource count for %s should be 0" % get_resource_type(resource_id=8))#CPU return - @attr(tags=["advanced", "advancedns","simulator"]) + @attr(tags=["advanced", "advancedns","simulator", "selfservice"]) def test_04_deploy_multiple_vm_with_multiple_core(self): """Test Deploy multiple VM with 4 core CPU & verify the usage""" @@ -435,7 +436,7 @@ def test_04_deploy_multiple_vm_with_multiple_core(self): self.account = admin self.domain = domain - api_client = self.testClient.createUserApiClient( + api_client = self.testClient.getUserApiClient( UserName=self.account.name, DomainName=self.account.domain) @@ -505,12 +506,13 @@ class TestMultipleChildDomains(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestMultipleChildDomains, - cls).getClsTestClient().getApiClient() + cls.testClient = super(TestMultipleChildDomains, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + 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, @@ -662,7 +664,7 @@ def setupAccounts(self): } return users - @attr(tags=["advanced", "advancedns","simulator"]) + @attr(tags=["advanced", "advancedns","simulator", "selfservice"]) def test_01_multiple_child_domains(self): """Test CPU limits with multiple child domains""" @@ -689,11 +691,11 @@ def test_01_multiple_child_domains(self): self.debug("Setting up account and domain hierarchy") self.setupAccounts() - api_client_cadmin_1 = self.testClient.createUserApiClient( + api_client_cadmin_1 = self.testClient.getUserApiClient( UserName=self.cadmin_1.name, DomainName=self.cadmin_1.domain) - api_client_cadmin_2 = self.testClient.createUserApiClient( + api_client_cadmin_2 = self.testClient.getUserApiClient( UserName=self.cadmin_2.name, DomainName=self.cadmin_2.domain) diff --git a/test/integration/component/test_cpu_limits.py b/test/integration/component/test_cpu_limits.py index f043773e7b..2cf92f8c2a 100644 --- a/test/integration/component/test_cpu_limits.py +++ b/test/integration/component/test_cpu_limits.py @@ -19,21 +19,21 @@ """ # Import Local Modules from nose.plugins.attrib import attr -from marvin.cloudstackTestCase import cloudstackTestCase, unittest -from marvin.integration.lib.base import ( +from marvin.cloudstackTestCase import cloudstackTestCase +from marvin.lib.base import ( Account, ServiceOffering, VirtualMachine, Domain, Resources ) -from marvin.integration.lib.common import (get_domain, +from marvin.lib.common import (get_domain, get_zone, get_template, findSuitableHostForMigration, get_resource_type ) -from marvin.integration.lib.utils import cleanup_resources +from marvin.lib.utils import cleanup_resources from marvin.codes import ERROR_NO_HOST_FOR_MIGRATION @@ -92,12 +92,13 @@ class TestCPULimits(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestCPULimits, - cls).getClsTestClient().getApiClient() + cls.testClient = super(TestCPULimits, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + 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( @@ -176,7 +177,7 @@ def createInstance(self, service_off, networks=None, api_client=None): except Exception as e: self.fail("Failed to deploy an instance: %s" % e) - @attr(tags=["advanced", "advancedns","simulator"]) + @attr(tags=["advanced", "advancedns","simulator", "selfservice"]) def test_01_multiplecore_start_stop_instance(self): """Test Deploy VM with multiple core CPU & verify the usage""" @@ -231,7 +232,7 @@ def test_01_multiplecore_start_stop_instance(self): "Resource count should be same after stopping the instance") return - @attr(tags=["advanced", "advancedns","simulator"]) + @attr(tags=["advanced", "advancedns","simulator", "provisioning"]) def test_02_multiplecore_migrate_instance(self): """Test Deploy VM with multiple core CPU & verify the usage""" @@ -272,7 +273,7 @@ def test_02_multiplecore_migrate_instance(self): "Resource count should be same after migrating the instance") return - @attr(tags=["advanced", "advancedns","simulator"]) + @attr(tags=["advanced", "advancedns","simulator", "selfservice"]) def test_03_multiplecore_delete_instance(self): """Test Deploy VM with multiple core CPU & verify the usage""" @@ -308,7 +309,7 @@ def test_03_multiplecore_delete_instance(self): self.assertEqual(resource_count, 0 , "Resource count for %s should be 0" % get_resource_type(resource_id=8))#CPU return - @attr(tags=["advanced", "advancedns","simulator"]) + @attr(tags=["advanced", "advancedns","simulator", "provisioning"]) def test_04_deploy_multiple_vm_with_multiple_cpus(self): """Test Deploy multiple VM with 4 core CPU & verify the usage""" @@ -352,12 +353,14 @@ class TestDomainCPULimitsConfiguration(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestDomainCPULimitsConfiguration, - cls).getClsTestClient().getApiClient() + cls.testClient = super(TestDomainCPULimitsConfiguration, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + 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, @@ -462,7 +465,7 @@ def setupAccounts(self): return - @attr(tags=["advanced", "advancedns","simulator"]) + @attr(tags=["advanced", "advancedns","simulator", "selfservice"]) def test_01_stop_start_instance(self): """Test Deploy VM with 4 core CPU & verify the usage""" @@ -481,7 +484,7 @@ def test_01_stop_start_instance(self): self.account = admin self.domain = domain - api_client = self.testClient.createUserApiClient( + api_client = self.testClient.getUserApiClient( UserName=self.account.name, DomainName=self.account.domain) @@ -534,7 +537,7 @@ def test_01_stop_start_instance(self): "Resource count should be same after starting the instance") return - @attr(tags=["advanced", "advancedns","simulator"]) + @attr(tags=["advanced", "advancedns","simulator", "provisioning"]) def test_02_migrate_instance(self): """Test Deploy VM with 4 core CPU & verify the usage""" @@ -553,7 +556,7 @@ def test_02_migrate_instance(self): self.account = admin self.domain = domain - api_client = self.testClient.createUserApiClient( + api_client = self.testClient.getUserApiClient( UserName=self.account.name, DomainName=self.account.domain) @@ -594,7 +597,7 @@ def test_02_migrate_instance(self): "Resource count should be same after starting the instance") return - @attr(tags=["advanced", "advancedns","simulator"]) + @attr(tags=["advanced", "advancedns","simulator", "selfservice"]) def test_03_delete_instance(self): """Test Deploy VM with 4 core CPU & verify the usage""" @@ -613,7 +616,7 @@ def test_03_delete_instance(self): self.account = admin self.domain = domain - api_client = self.testClient.createUserApiClient( + api_client = self.testClient.getUserApiClient( UserName=self.account.name, DomainName=self.account.domain) @@ -685,7 +688,7 @@ def test_04_deploy_multiple_vm_with_multiple_cpus(self): if cpu_account_gc[0].max != 16: self.skipTest("This test case requires configuration value max.account.cpus to be 16") - api_client = self.testClient.createUserApiClient( + api_client = self.testClient.getUserApiClient( UserName=self.account.name, DomainName=self.account.domain) diff --git a/test/integration/component/test_cpu_max_limits.py b/test/integration/component/test_cpu_max_limits.py index 317df166a5..a08ff6d4b4 100644 --- a/test/integration/component/test_cpu_max_limits.py +++ b/test/integration/component/test_cpu_max_limits.py @@ -19,8 +19,8 @@ """ # Import Local Modules from nose.plugins.attrib import attr -from marvin.cloudstackTestCase import cloudstackTestCase, unittest -from marvin.integration.lib.base import ( +from marvin.cloudstackTestCase import cloudstackTestCase +from marvin.lib.base import ( Account, ServiceOffering, VirtualMachine, @@ -28,11 +28,11 @@ Domain, Project ) -from marvin.integration.lib.common import (get_domain, +from marvin.lib.common import (get_domain, get_zone, get_template ) -from marvin.integration.lib.utils import cleanup_resources +from marvin.lib.utils import cleanup_resources class Services: """Test resource limit services @@ -89,12 +89,13 @@ class TestMaxCPULimits(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestMaxCPULimits, - cls).getClsTestClient().getApiClient() + cls.testClient = super(TestMaxCPULimits, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + 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, @@ -227,7 +228,7 @@ def setupAccounts(self, account_limit=2, domain_limit=2, project_limit=2): return - @attr(tags=["advanced", "advancedns","simulator"]) + @attr(tags=["advanced", "advancedns","simulator", "selfservice"]) def test_01_deploy_vm_domain_limit_reached(self): """Test Try to deploy VM with admin account where account has not used the resources but @ domain they are not available""" @@ -251,7 +252,7 @@ def test_01_deploy_vm_domain_limit_reached(self): self.debug("Setting up account and domain hierarchy") self.setupAccounts(account_limit=4, domain_limit=2) - api_client_admin = self.testClient.createUserApiClient( + api_client_admin = self.testClient.getUserApiClient( UserName=self.child_do_admin.name, DomainName=self.child_do_admin.domain) @@ -260,7 +261,7 @@ def test_01_deploy_vm_domain_limit_reached(self): service_off=self.service_offering, api_client=api_client_admin) return - @attr(tags=["advanced", "advancedns","simulator"]) + @attr(tags=["advanced", "advancedns","simulator", "selfservice"]) def test_02_deploy_vm_account_limit_reached(self): """Test Try to deploy VM with admin account where account has used the resources but @ domain they are available""" @@ -284,7 +285,7 @@ def test_02_deploy_vm_account_limit_reached(self): self.debug("Setting up account and domain hierarchy") self.setupAccounts(account_limit=6, domain_limit=8) - api_client_admin = self.testClient.createUserApiClient( + api_client_admin = self.testClient.getUserApiClient( UserName=self.child_do_admin.name, DomainName=self.child_do_admin.domain) @@ -301,7 +302,7 @@ def test_02_deploy_vm_account_limit_reached(self): service_off=self.service_offering, api_client=api_client_admin) return - @attr(tags=["advanced", "advancedns","simulator"]) + @attr(tags=["advanced", "advancedns","simulator", "selfservice"]) def test_03_deploy_vm_project_limit_reached(self): """Test TTry to deploy VM with admin account where account has not used the resources but @ project they are not available""" @@ -325,7 +326,7 @@ def test_03_deploy_vm_project_limit_reached(self): self.debug("Setting up account and domain hierarchy") self.setupAccounts(account_limit=4, domain_limit=4, project_limit=2) - api_client_admin = self.testClient.createUserApiClient( + api_client_admin = self.testClient.getUserApiClient( UserName=self.child_do_admin.name, DomainName=self.child_do_admin.domain) @@ -336,7 +337,7 @@ def test_03_deploy_vm_project_limit_reached(self): service_off=self.service_offering, api_client=api_client_admin) return - @attr(tags=["advanced", "advancedns","simulator"]) + @attr(tags=["advanced", "advancedns","simulator", "selfservice"]) def test_04_deployVm__account_limit_reached(self): """Test Try to deploy VM with admin account where account has used the resources but @ project they are available""" @@ -360,7 +361,7 @@ def test_04_deployVm__account_limit_reached(self): self.debug("Setting up account and domain hierarchy") self.setupAccounts(account_limit=6, domain_limit=6, project_limit=6) - api_client_admin = self.testClient.createUserApiClient( + api_client_admin = self.testClient.getUserApiClient( UserName=self.child_do_admin.name, DomainName=self.child_do_admin.domain) diff --git a/test/integration/component/test_cpu_project_limits.py b/test/integration/component/test_cpu_project_limits.py index ed7cd88248..e7958289ca 100644 --- a/test/integration/component/test_cpu_project_limits.py +++ b/test/integration/component/test_cpu_project_limits.py @@ -20,20 +20,20 @@ # Import Local Modules from nose.plugins.attrib import attr from marvin.cloudstackTestCase import cloudstackTestCase, unittest -from marvin.integration.lib.base import ( +from marvin.lib.base import ( Account, ServiceOffering, VirtualMachine, Domain, Project ) -from marvin.integration.lib.common import (get_domain, +from marvin.lib.common import (get_domain, get_zone, get_template, findSuitableHostForMigration, get_resource_type ) -from marvin.integration.lib.utils import cleanup_resources +from marvin.lib.utils import cleanup_resources from marvin.codes import ERROR_NO_HOST_FOR_MIGRATION class Services: @@ -91,12 +91,13 @@ class TestProjectsCPULimits(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestProjectsCPULimits, - cls).getClsTestClient().getApiClient() + cls.testClient = super(TestProjectsCPULimits, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + 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, @@ -137,7 +138,7 @@ def setUp(self): self.debug("Setting up account and domain hierarchy") self.setupProjectAccounts() - api_client = self.testClient.createUserApiClient( + api_client = self.testClient.getUserApiClient( UserName=self.admin.name, DomainName=self.admin.domain) @@ -171,7 +172,8 @@ def createInstance(self, project, service_off, networks=None, api_client=None): projectid=project.id, networkids=networks, serviceofferingid=service_off.id) - vms = VirtualMachine.list(api_client, id=self.vm.id, listall=True) + vms = VirtualMachine.list(api_client, projectid=project.id, + id=self.vm.id, listall=True) self.assertIsInstance(vms, list, "List VMs should return a valid response") @@ -216,7 +218,7 @@ def setupProjectAccounts(self): "Check project name from list response") return - @attr(tags=["advanced", "advancedns","simulator"]) + @attr(tags=["advanced", "advancedns","simulator", "selfservice"]) def test_01_project_counts_start_stop_instance(self): # Validate the following @@ -271,7 +273,7 @@ def test_01_project_counts_start_stop_instance(self): "Resource count should be same after starting the instance") return - @attr(tags=["advanced", "advancedns","simulator"]) + @attr(tags=["advanced", "advancedns","simulator", "provisioning"]) def test_02_project_counts_migrate_instance(self): # Validate the following @@ -313,7 +315,7 @@ def test_02_project_counts_migrate_instance(self): "Resource count should be same after migrating the instance") return - @attr(tags=["advanced", "advancedns","simulator"]) + @attr(tags=["advanced", "advancedns","simulator", "selfservice"]) def test_03_project_counts_delete_instance(self): # Validate the following diff --git a/test/integration/component/test_custom_hostname.py b/test/integration/component/test_custom_hostname.py index 1549a20657..637be86d6b 100644 --- a/test/integration/component/test_custom_hostname.py +++ b/test/integration/component/test_custom_hostname.py @@ -17,12 +17,19 @@ """ P1 tests for user provide hostname cases """ #Import Local Modules -import marvin + from nose.plugins.attrib import attr -from marvin.cloudstackTestCase import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * +from marvin.cloudstackTestCase import cloudstackTestCase +from marvin.lib.utils import (cleanup_resources, + random_gen) +from marvin.lib.base import (ServiceOffering, + Configurations, + VirtualMachine, + Account) +from marvin.lib.common import (get_domain, + get_zone, + get_template, + is_config_suitable) class Services: @@ -94,13 +101,13 @@ class TestInstanceNameFlagTrue(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestInstanceNameFlagTrue, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestInstanceNameFlagTrue, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services - # Get Zone, default template - cls.zone = get_zone(cls.api_client, cls.services) + # 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, @@ -108,12 +115,7 @@ def setUpClass(cls): cls.services["ostype"] ) - # Create domains, account etc. - cls.domain = get_domain( - cls.api_client, - cls.services - ) - + # Create account cls.account = Account.create( cls.api_client, cls.services["account"], @@ -157,7 +159,7 @@ def tearDown(self): @attr(configuration='vm.instancename.flag') - @attr(tags=["advanced", "basic", "sg", "eip", "advancedns", "simulator"]) + @attr(tags=["advanced", "basic", "sg", "eip", "advancedns", "simulator", "selfservice"]) def test_01_user_provided_hostname(self): """ Verify user provided hostname to an instance """ @@ -261,7 +263,7 @@ def test_01_user_provided_hostname(self): return @attr(configuration='vm.instancename.flag') - @attr(tags=["advanced", "basic", "sg", "eip", "advancedns", "simulator"]) + @attr(tags=["advanced", "basic", "sg", "eip", "advancedns", "simulator", "selfservice"]) def test_02_instancename_from_default_configuration(self): """ Verify for globally set instancename """ @@ -372,7 +374,7 @@ def test_02_instancename_from_default_configuration(self): return @attr(configuration='vm.instancename.flag') - @attr(tags=["advanced", "basic", "sg", "eip", "advancedns", "simulator"]) + @attr(tags=["advanced", "basic", "sg", "eip", "advancedns", "simulator", "selfservice"]) def test_03_duplicate_name(self): """ Test the duplicate name when old VM is in non-expunged state """ @@ -432,7 +434,7 @@ def test_03_duplicate_name(self): return @attr(configuration='vm.instancename.flag') - @attr(tags=["advanced", "basic", "sg", "eip", "advancedns", "simulator"]) + @attr(tags=["advanced", "basic", "sg", "eip", "advancedns", "simulator", "selfservice"]) def test_04_edit_display_name(self): """ Test Edit the Display name Through the UI. """ @@ -525,7 +527,7 @@ def test_04_edit_display_name(self): return @attr(configuration='vm.instancename.flag') - @attr(tags=["advanced", "basic", "sg", "eip", "advancedns", "simulator"]) + @attr(tags=["advanced", "basic", "sg", "eip", "advancedns", "simulator", "selfservice"]) def test_05_unsupported_chars_in_display_name(self): """ Test Unsupported chars in the display name (eg: Spaces,Exclamation,yet to get unsupported chars from the dev) @@ -561,13 +563,13 @@ class TestInstanceNameFlagFalse(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestInstanceNameFlagFalse, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestInstanceNameFlagFalse, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services - # Get Zone, default template - cls.zone = get_zone(cls.api_client, cls.services) + # Get Zone, Domain and templates + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, @@ -575,12 +577,7 @@ def setUpClass(cls): cls.services["ostype"] ) - # Create domains, account etc. - cls.domain = get_domain( - cls.api_client, - cls.services - ) - + # Create account cls.account = Account.create( cls.api_client, cls.services["account"], @@ -622,7 +619,7 @@ def tearDown(self): return @attr(configuration='vm.instancename.flag') - @attr(tags=["advanced", "basic", "sg", "eip", "advancedns", "simulator"]) + @attr(tags=["advanced", "basic", "sg", "eip", "advancedns", "simulator", "selfservice"]) def test_01_custom_hostname_instancename_false(self): """ Verify custom hostname for the instance when vm.instancename.flag=false diff --git a/test/integration/component/test_deploy_vm_userdata_reg.py b/test/integration/component/test_deploy_vm_userdata_reg.py index b282a86081..1c9f35c579 100755 --- a/test/integration/component/test_deploy_vm_userdata_reg.py +++ b/test/integration/component/test_deploy_vm_userdata_reg.py @@ -19,9 +19,9 @@ # this script will cover VMdeployment with Userdata tests from marvin.cloudstackTestCase import cloudstackTestCase -from marvin.integration.lib.base import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.common import * +from marvin.lib.base import * +from marvin.lib.utils import * +from marvin.lib.common import * from nose.plugins.attrib import attr from marvin.sshClient import SshClient import unittest @@ -71,9 +71,10 @@ class TestDeployVmWithUserData(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.apiClient = super(TestDeployVmWithUserData, cls).getClsTestClient().getApiClient() + cls.testClient = super(TestDeployVmWithUserData, cls).getClsTestClient() + cls.apiClient = cls.testClient.getApiClient() cls.services = Services().services - cls.zone = get_zone(cls.apiClient, cls.services) + cls.zone = get_zone(cls.apiClient, cls.testClient.getZoneForTests()) if cls.zone.localstorageenabled: #For devcloud since localstroage is enabled cls.services["service_offering"]["storagetype"] = "local" @@ -99,8 +100,12 @@ def setUpClass(cls): cls.user_data_2kl = ''.join(random.choice(string.ascii_uppercase + string.digits) for x in range(1900)) + def setUp(self): + self.apiClient = self.testClient.getApiClient() + self.hypervisor = self.testClient.getHypervisorInfo() - @attr(tags=["simulator", "devcloud", "basic", "advanced"]) + + @attr(tags=["simulator", "devcloud", "basic", "advanced", "provisioning"]) def test_deployvm_userdata_post(self): """Test userdata as POST, size > 2k """ @@ -174,7 +179,7 @@ def test_deployvm_userdata_post(self): host.passwd="password" cmd="cat /var/www/html/userdata/"+deployVmResponse.ipaddress+"/user-data" - if self.apiClient.hypervisor.lower() == 'vmware': + if self.hypervisor.lower() == 'vmware': try: result = get_process_status( @@ -184,7 +189,7 @@ def test_deployvm_userdata_post(self): self.apiClient.connection.passwd, router.linklocalip, cmd, - hypervisor=self.apiClient.hypervisor + hypervisor=self.hypervisor ) res = str(result) self.assertEqual(res.__contains__(self.userdata),True,"Userdata Not applied Check the failures") diff --git a/test/integration/component/test_dynamic_compute_offering.py b/test/integration/component/test_dynamic_compute_offering.py index 75cf0d658f..0a07e6cdf7 100644 --- a/test/integration/component/test_dynamic_compute_offering.py +++ b/test/integration/component/test_dynamic_compute_offering.py @@ -24,18 +24,21 @@ Feature Specifications: https://cwiki.apache.org/confluence/display/CLOUDSTACK/Dynamic+Compute+Offering+FS """ from marvin.cloudstackTestCase import cloudstackTestCase -from marvin.integration.lib.utils import (cleanup_resources, - validateList) -from marvin.integration.lib.base import (ServiceOffering, - VirtualMachine, - Account) -from marvin.integration.lib.common import (get_domain, - get_zone, - get_template, - verifyComputeOfferingCreation) - +from marvin.lib.utils import (cleanup_resources, + validateList, + random_gen) +from marvin.lib.base import (Account, + VirtualMachine, + ServiceOffering, + Resources, + AffinityGroup, + Host) +from marvin.lib.common import (get_zone, + get_domain, + get_template, + verifyComputeOfferingCreation) from nose.plugins.attrib import attr -from marvin.codes import PASS, ADMIN_ACCOUNT, USER_ACCOUNT +from marvin.codes import PASS, ADMIN_ACCOUNT, USER_ACCOUNT, FAILED from ddt import ddt, data @ddt @@ -45,21 +48,22 @@ class TestDynamicServiceOffering(cloudstackTestCase): @classmethod def setUpClass(cls): - cloudstackTestClient = super(TestDynamicServiceOffering,cls).getClsTestClient() - cls.api_client = cloudstackTestClient.getApiClient() - - # Fill services from the external config file - cls.services = cloudstackTestClient.getConfigParser().parsedDict + testClient = super(TestDynamicServiceOffering, cls).getClsTestClient() + cls.api_client = cls.apiclient = testClient.getApiClient() + cls.services = testClient.getParsedTestDataConfig() # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - cls.mode = str(cls.zone.networktype).lower() + cls.domain = get_domain(cls.apiclient) + cls.zone = get_zone(cls.apiclient, testClient.getZoneForTests()) + cls.services['mode'] = cls.zone.networktype + cls.template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostype"] - ) + cls.apiclient, + cls.zone.id, + cls.services["ostype"] + ) + if cls.template == FAILED: + assert False, "get_template() failed to return template with description %s" % cls.services["ostype"] cls.services["virtual_machine"]["zoneid"] = cls.zone.id cls.services["virtual_machine"]["template"] = cls.template.id cls._cleanup = [] @@ -230,7 +234,7 @@ def test_deploy_virtual_machines_static_offering(self, value): # Create Account self.account = Account.create(self.apiclient,self.services["account"],domainid=self.domain.id, admin=isadmin) - apiclient = self.testClient.createUserApiClient( + apiclient = self.testClient.getUserApiClient( UserName=self.account.name, DomainName=self.account.domain) self.cleanup.append(self.account) @@ -292,7 +296,7 @@ def test_deploy_virtual_machines_dynamic_offering(self, value): # Create Account and its api client self.account = Account.create(self.apiclient,self.services["account"],domainid=self.domain.id, admin=isadmin) - apiclient = self.testClient.createUserApiClient( + apiclient = self.testClient.getUserApiClient( UserName=self.account.name, DomainName=self.account.domain) self.cleanup.append(self.account) @@ -359,7 +363,7 @@ def test_check_vm_stats(self, value): # Create Account and api client self.account = Account.create(self.apiclient,self.services["account"],domainid=self.domain.id, admin=isadmin) - apiclient = self.testClient.createUserApiClient( + apiclient = self.testClient.getUserApiClient( UserName=self.account.name, DomainName=self.account.domain) self.cleanup.append(self.account) @@ -407,3 +411,1004 @@ def test_check_vm_stats(self, value): not matching with provided custom memory %s" % \ (vm.memory, custommemory)) return + +@ddt +class TestScaleVmDynamicServiceOffering(cloudstackTestCase): + """Test scaling VMs with dynamic Service Offerings + """ + + @classmethod + def setUpClass(cls): + cloudstackTestClient = super(TestScaleVmDynamicServiceOffering,cls).getClsTestClient() + cls.api_client = cloudstackTestClient.getApiClient() + + # Fill services from the external config file + cls.services = cloudstackTestClient.getParsedTestDataConfig() + + # Get Zone, Domain and templates + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cloudstackTestClient.getZoneForTests()) + cls.mode = str(cls.zone.networktype).lower() + cls.template = get_template( + cls.api_client, + cls.zone.id, + cls.services["ostype"] + ) + cls.services["virtual_machine"]["zoneid"] = cls.zone.id + cls.services["virtual_machine"]["template"] = cls.template.id + cls._cleanup = [] + 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) + return + + def setUp(self): + self.apiclient = self.testClient.getApiClient() + self.dbclient = self.testClient.getDbConnection() + self.cleanup_co = [] + self.cleanup = [] + return + + def tearDown(self): + try: + # Clean up compute offerings + cleanup_resources(self.apiclient, self.cleanup) + + # Clean up compute offerings + cleanup_resources(self.apiclient, self.cleanup_co) + + self.cleanup_co[:] = [] + self.cleanup[:] = [] + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + @data(ADMIN_ACCOUNT, USER_ACCOUNT) + @attr(tags=["basic","advanced"]) + def test_change_so_stopped_vm_static_to_static(self, value): + """Test scale stopped VM from static offering to static offering""" + + # Steps: + # 1. Create Account (admin/user) and its api client + # 2. Make two static service offerings + # 3. Deploy VM with one static offering + # 4. Stop the VM + # 5. Scale VM with 2nd static service offering + + # Validations: + # 1. Scaling operation should be successful + + isadmin=True + if value == USER_ACCOUNT: + isadmin=False + + try: + # Create Account + self.account = Account.create(self.apiclient,self.services["account"],domainid=self.domain.id, admin=isadmin) + self.cleanup.append(self.account) + apiclient = self.testClient.getUserApiClient( + UserName=self.account.name, + DomainName=self.account.domain) + + # Create static service offerings (Second offering should have + # one of the custom values greater than 1st one, scaling down is not allowed + self.services["service_offering"]["cpunumber"] = "2" + self.services["service_offering"]["cpuspeed"] = "256" + self.services["service_offering"]["memory"] = "128" + + serviceOffering_static_1 = ServiceOffering.create(self.apiclient, + self.services["service_offering"]) + + self.services["service_offering"]["cpunumber"] = "4" + + serviceOffering_static_2 = ServiceOffering.create(self.apiclient, + self.services["service_offering"]) + + self.cleanup_co.append(serviceOffering_static_1) + self.cleanup_co.append(serviceOffering_static_2) + + # Deploy VM + virtualMachine = VirtualMachine.create(apiclient,self.services["virtual_machine"], + serviceofferingid=serviceOffering_static_1.id, + accountid=self.account.name,domainid=self.account.domainid) + + # Stop VM + virtualMachine.stop(apiclient) + + # Scale VM to new static service offering + virtualMachine.scale(apiclient, serviceOfferingId=serviceOffering_static_2.id) + except Exception as e: + self.fail("Exception occured: %s" % e) + return + + @data(ADMIN_ACCOUNT, USER_ACCOUNT) + @attr(tags=["basic","advanced"]) + def test_change_so_stopped_vm_static_to_dynamic(self, value): + """Test scale stopped VM from static offering to dynamic offering""" + + # Steps: + # 1. Create Account (admin/user) and its api client + # 2. Make static and dynamic service offerings + # 3. Deploy VM with static offering + # 4. Stop the VM + # 5. Scale VM with dynamic service offering providing all required + # custom values + # 6. Deploy another VM with static offring and stop the VM + # 7. Scale VM with dynamic service offering providing only custom cpu number + + # Validations: + # 1. Scale operation in step 5 should be successful + # 2. Scale operation in step 7 should fail + + isadmin=True + if value == USER_ACCOUNT: + isadmin=False + + try: + # Create Account and api client + self.account = Account.create(self.apiclient,self.services["account"],domainid=self.domain.id, admin=isadmin) + apiclient = self.testClient.getUserApiClient( + UserName=self.account.name, + DomainName=self.account.domain) + self.cleanup.append(self.account) + + # Create static and dynamic service offerings + self.services["service_offering"]["cpunumber"] = "2" + self.services["service_offering"]["cpuspeed"] = "256" + self.services["service_offering"]["memory"] = "128" + + serviceOffering_static = ServiceOffering.create(self.apiclient, + self.services["service_offering"]) + + + self.services["service_offering"]["cpunumber"] = "" + self.services["service_offering"]["cpuspeed"] = "" + self.services["service_offering"]["memory"] = "" + + serviceOffering_dynamic = ServiceOffering.create(self.apiclient, + self.services["service_offering"]) + + self.cleanup_co.append(serviceOffering_static) + self.cleanup_co.append(serviceOffering_dynamic) + + # Deploy VM with static service offering + virtualMachine_1 = VirtualMachine.create(apiclient,self.services["virtual_machine"], + serviceofferingid=serviceOffering_static.id, + accountid=self.account.name,domainid=self.account.domainid) + + # Stop VM + virtualMachine_1.stop(apiclient) + + # Scale VM to dynamic service offering proving all custom values + virtualMachine_1.scale(apiclient, serviceOfferingId=serviceOffering_dynamic.id, + customcpunumber=4, customcpuspeed=256, custommemory=128) + + # Deploy VM with static service offering + virtualMachine_2 = VirtualMachine.create(apiclient,self.services["virtual_machine"], + serviceofferingid=serviceOffering_static.id, + accountid=self.account.name,domainid=self.account.domainid) + + # Stop VM + virtualMachine_2.stop(apiclient) + except Exception as e: + self.fail("Exception occuered: %s" % e) + + # Scale VM to dynamic service offering proving only custom cpu number + with self.assertRaises(Exception): + virtualMachine_2.scale(apiclient, serviceOfferingId=serviceOffering_dynamic.id, + customcpunumber=4) + return + + @data(ADMIN_ACCOUNT, USER_ACCOUNT) + @attr(tags=["basic","advanced"]) + def test_change_so_stopped_vm_dynamic_to_static(self, value): + """Test scale stopped VM from dynamic offering to static offering""" + + # Steps: + # 1. Create Account (admin/user) and its api client + # 2. Make static and dynamic service offerings + # 3. Deploy VM with dynamic service offering + # 4. Stop the VM + # 5. Scale VM with static service offering + + # Validations: + # 1. Scale operation in step 5 should be successful + + isadmin=True + if value == USER_ACCOUNT: + isadmin=False + + try: + # Create account and api client + self.account = Account.create(self.apiclient,self.services["account"],domainid=self.domain.id, admin=isadmin) + apiclient = self.testClient.getUserApiClient( + UserName=self.account.name, + DomainName=self.account.domain) + self.cleanup.append(self.account) + + # Create dynamic and static service offering + self.services["service_offering"]["cpunumber"] = "" + self.services["service_offering"]["cpuspeed"] = "" + self.services["service_offering"]["memory"] = "" + + serviceOffering_dynamic = ServiceOffering.create(self.apiclient, + self.services["service_offering"]) + + self.services["service_offering"]["cpunumber"] = "4" + self.services["service_offering"]["cpuspeed"] = "256" + self.services["service_offering"]["memory"] = "128" + + serviceOffering_static = ServiceOffering.create(self.apiclient, + self.services["service_offering"]) + + self.cleanup_co.append(serviceOffering_static) + self.cleanup_co.append(serviceOffering_dynamic) + + # Deploy VM with dynamic service offering + virtualMachine = VirtualMachine.create(apiclient,self.services["virtual_machine"], + serviceofferingid=serviceOffering_dynamic.id, + accountid=self.account.name,domainid=self.account.domainid, + customcpunumber=2, customcpuspeed=256, custommemory=128) + + # Stop VM and verify that it is in stopped state + virtualMachine.stop(apiclient) + + # Scale VM to static service offering + virtualMachine.scale(apiclient, serviceOfferingId=serviceOffering_static.id) + except Exception as e: + self.fail("Exception occured: %s" % e) + return + + @data(ADMIN_ACCOUNT, USER_ACCOUNT) + @attr(tags=["basic","advanced"]) + def test_change_so_stopped_vm_dynamic_to_dynamic(self, value): + """Test scale stopped VM from dynamic offering to dynamic offering""" + + # Steps: + # 1. Create Account (admin/user) and its api client + # 2. Make 2 dynamic service offerings + # 3. Deploy VM with dynamic service offering + # 4. Stop the VM + # 5. Scale VM with same dynamic service offering + # 6. Scale VM with other dynamic service offering + # 7. Scale VM with same/other dynamic offering but providing custom + # value for only cpu number + + # Validations: + # 1. Scale operation in step 5 should be successful + # 2. Scale operation in step 6 should be successful + # 3. Scale operation in step 7 should fail + + isadmin=True + if value == USER_ACCOUNT: + isadmin=False + + try: + # Create Account + self.account = Account.create(self.apiclient,self.services["account"],domainid=self.domain.id, admin=isadmin) + apiclient = self.testClient.getUserApiClient( + UserName=self.account.name, + DomainName=self.account.domain) + self.cleanup.append(self.account) + + # Create dynamic service offerings + self.services["service_offering"]["cpunumber"] = "" + self.services["service_offering"]["cpuspeed"] = "" + self.services["service_offering"]["memory"] = "" + + serviceOffering_dynamic_1 = ServiceOffering.create(self.apiclient, + self.services["service_offering"]) + + serviceOffering_dynamic_2 = ServiceOffering.create(self.apiclient, + self.services["service_offering"]) + + self.cleanup_co.append(serviceOffering_dynamic_1) + self.cleanup_co.append(serviceOffering_dynamic_2) + + # Deploy VM with dynamic service offering + virtualMachine = VirtualMachine.create(apiclient,self.services["virtual_machine"], + serviceofferingid=serviceOffering_dynamic_1.id, + accountid=self.account.name,domainid=self.account.domainid, + customcpunumber=2, customcpuspeed=256, custommemory=128) + + # Stop VM + virtualMachine.stop(apiclient) + + # Scale VM with same dynamic service offering + virtualMachine.scale(apiclient, serviceOfferingId=serviceOffering_dynamic_1.id, + customcpunumber=4, customcpuspeed=512, custommemory=256) + + # Scale VM with other dynamic service offering + virtualMachine.scale(apiclient, serviceOfferingId=serviceOffering_dynamic_2.id, + customcpunumber=4, customcpuspeed=512, custommemory=256) + except Exception as e: + self.fail("Exception occured: %s" % e) + + # Scale VM with dynamic service offering proving custom value + # only for cpu number + with self.assertRaises(Exception): + virtualMachine.scale(apiclient, serviceOfferingId=serviceOffering_dynamic_1.id, + customcpunumber=4) + return + + @data(ADMIN_ACCOUNT, USER_ACCOUNT) + @attr(tags=["basic","advanced"]) + def test_change_so_running_vm_static_to_static(self, value): + """Test scale running VM from static offering to static offering""" + + # Steps: + # 1. Create Account (admin/user) and its api client + # 2. Make two static service offerings + # 3. Deploy VM with one static offering + # 4. Scale VM with 2nd static service offering + + # Validations: + # 1. Scaling operation should be successful + + isadmin=True + if value == USER_ACCOUNT: + isadmin=False + + # Create Account and api client + self.account = Account.create(self.apiclient,self.services["account"],domainid=self.domain.id, admin=isadmin) + apiclient = self.testClient.getUserApiClient( + UserName=self.account.name, + DomainName=self.account.domain) + self.cleanup.append(self.account) + + # Create static service offerings + self.services["service_offering"]["cpunumber"] = "2" + self.services["service_offering"]["cpuspeed"] = "256" + self.services["service_offering"]["memory"] = "128" + + serviceOffering_static_1 = ServiceOffering.create(self.apiclient, + self.services["service_offering"]) + + self.services["service_offering"]["cpunumber"] = "4" + + serviceOffering_static_2 = ServiceOffering.create(self.apiclient, + self.services["service_offering"]) + + self.cleanup_co.append(serviceOffering_static_1) + self.cleanup_co.append(serviceOffering_static_2) + + # Deploy VM with static service offering + try: + virtualMachine = VirtualMachine.create(apiclient,self.services["virtual_machine"], + serviceofferingid=serviceOffering_static_1.id, + accountid=self.account.name,domainid=self.account.domainid) + except Exception as e: + self.fail("vm creation failed: %s" % e) + + # Scale VM to other static service offering + try: + virtualMachine.scale(apiclient, serviceOfferingId=serviceOffering_static_2.id) + except Exception as e: + self.fail("Failure while changing service offering: %s" % e) + return + + @data(ADMIN_ACCOUNT, USER_ACCOUNT) + @attr(tags=["basic","advanced"]) + def test_change_so_running_vm_static_to_dynamic(self, value): + """Test scale running VM from static offering to dynamic offering""" + + # Steps: + # 1. Create Account (admin/user) and its api client + # 2. Make static and dynamic service offerings + # 3. Deploy VM with static offering + # 4. Scale VM with dynamic service offering providing all required + # custom values + # 5. Deploy another VM with static offring + # 6. Scale VM with dynamic service offering providing only custom cpu number + + # Validations: + # 1. Scale operation in step 4 should be successful + # 2. Scale operation in step 6 should fail + + isadmin=True + if value == USER_ACCOUNT: + isadmin=False + + # Crate account and api client + self.account = Account.create(self.apiclient,self.services["account"],domainid=self.domain.id, admin=isadmin) + apiclient = self.testClient.getUserApiClient( + UserName=self.account.name, + DomainName=self.account.domain) + self.cleanup.append(self.account) + + # Create static and dynamic service offerings + self.services["service_offering"]["cpunumber"] = "2" + self.services["service_offering"]["cpuspeed"] = "256" + self.services["service_offering"]["memory"] = "128" + + serviceOffering_static = ServiceOffering.create(self.apiclient, + self.services["service_offering"]) + + + self.services["service_offering"]["cpunumber"] = "" + self.services["service_offering"]["cpuspeed"] = "" + self.services["service_offering"]["memory"] = "" + + serviceOffering_dynamic = ServiceOffering.create(self.apiclient, + self.services["service_offering"]) + + self.cleanup_co.append(serviceOffering_static) + self.cleanup_co.append(serviceOffering_dynamic) + + # Deploy VM with static service offering + try: + virtualMachine_1 = VirtualMachine.create(apiclient,self.services["virtual_machine"], + serviceofferingid=serviceOffering_static.id, + accountid=self.account.name,domainid=self.account.domainid) + except Exception as e: + self.fail("vm creation failed: %s" % e) + + # Scale VM to dynamic service offering + try: + virtualMachine_1.scale(apiclient, serviceOfferingId=serviceOffering_dynamic.id, + customcpunumber=4, customcpuspeed=256, custommemory=128) + except Exception as e: + self.fail("Failure while changing service offering: %s" % e) + + try: + virtualMachine_2 = VirtualMachine.create(apiclient,self.services["virtual_machine"], + serviceofferingid=serviceOffering_static.id, + accountid=self.account.name,domainid=self.account.domainid) + except Exception as e: + self.fail("vm creation failed: %s" % e) + + try: + virtualMachine_2.scale(apiclient, serviceOfferingId=serviceOffering_dynamic.id, + customcpunumber=4) + self.fail("Changing service offering with incomplete data should have failed, it succeded") + except Exception as e: + self.debug("Failure while changing service offering as expected: %s" % e) + + return + + @data(ADMIN_ACCOUNT, USER_ACCOUNT) + @attr(tags=["basic","advanced"]) + def test_change_so_running_vm_dynamic_to_static(self, value): + """Test scale running VM from dynamic offering to static offering""" + + # Steps: + # 1. Create Account (admin/user) and its api client + # 2. Make static and dynamic service offerings + # 3. Deploy VM with dynamic service offering + # 4. Scale VM with static service offering + + # Validations: + # 1. Scale operation in step 4 should be successful + + isadmin=True + if value == USER_ACCOUNT: + isadmin=False + + # Create account and api client + self.account = Account.create(self.apiclient,self.services["account"],domainid=self.domain.id, admin=isadmin) + apiclient = self.testClient.getUserApiClient( + UserName=self.account.name, + DomainName=self.account.domain) + self.cleanup.append(self.account) + + # Create dynamic and static service offerings + self.services["service_offering"]["cpunumber"] = "" + self.services["service_offering"]["cpuspeed"] = "" + self.services["service_offering"]["memory"] = "" + + serviceOffering_dynamic = ServiceOffering.create(self.apiclient, + self.services["service_offering"]) + + self.services["service_offering"]["cpunumber"] = "4" + self.services["service_offering"]["cpuspeed"] = "256" + self.services["service_offering"]["memory"] = "128" + + serviceOffering_static = ServiceOffering.create(self.apiclient, + self.services["service_offering"]) + + self.cleanup_co.append(serviceOffering_static) + self.cleanup_co.append(serviceOffering_dynamic) + + # deploy VM with dynamic service offering + try: + virtualMachine = VirtualMachine.create(apiclient,self.services["virtual_machine"], + serviceofferingid=serviceOffering_dynamic.id, + accountid=self.account.name,domainid=self.account.domainid, + customcpunumber=2, customcpuspeed=256, custommemory=128) + except Exception as e: + self.fail("vm creation failed: %s" % e) + + # Scale VM to static service offering + try: + virtualMachine.scale(apiclient, serviceOfferingId=serviceOffering_static.id) + except Exception as e: + self.fail("Failure while changing service offering: %s" % e) + + return + + @data(ADMIN_ACCOUNT, USER_ACCOUNT) + @attr(tags=["basic","advanced"]) + def test_change_so_running_vm_dynamic_to_dynamic(self, value): + """Test scale running VM from dynamic offering to dynamic offering""" + + # Steps: + # 1. Create Account (admin/user) and its api client + # 2. Make 2 dynamic service offerings + # 3. Deploy VM with dynamic service offering + # 4. Scale VM with same dynamic service offering + # 5. Scale VM with other dynamic service offering + # 6. Scale VM with same/other dynamic offering but providing custom + # value for only cpu number + + # Validations: + # 1. Scale operation in step 4 should be successful + # 2. Scale operation in step 5 should be successful + # 3. Scale operation in step 6 should fail + + isadmin=True + if value == USER_ACCOUNT: + isadmin=False + + # Create account and api client + self.account = Account.create(self.apiclient,self.services["account"],domainid=self.domain.id, admin=isadmin) + apiclient = self.testClient.getUserApiClient( + UserName=self.account.name, + DomainName=self.account.domain) + self.cleanup.append(self.account) + + # Create dynamic service offerings + self.services["service_offering"]["cpunumber"] = "" + self.services["service_offering"]["cpuspeed"] = "" + self.services["service_offering"]["memory"] = "" + + serviceOffering_dynamic_1 = ServiceOffering.create(self.apiclient, + self.services["service_offering"]) + + serviceOffering_dynamic_2 = ServiceOffering.create(self.apiclient, + self.services["service_offering"]) + + self.cleanup_co.append(serviceOffering_dynamic_1) + self.cleanup_co.append(serviceOffering_dynamic_2) + + # Deploy VM with dynamic service offering + try: + virtualMachine = VirtualMachine.create(apiclient,self.services["virtual_machine"], + serviceofferingid=serviceOffering_dynamic_1.id, + accountid=self.account.name,domainid=self.account.domainid, + customcpunumber=2, customcpuspeed=256, custommemory=128) + except Exception as e: + self.fail("vm creation failed: %s" % e) + + # Scale VM with same dynamic offering + try: + virtualMachine.scale(apiclient, serviceOfferingId=serviceOffering_dynamic_1.id, + customcpunumber=4, customcpuspeed=512, custommemory=256) + except Exception as e: + self.fail("Failure while changing service offering: %s" % e) + + # Scale VM with other dynamic service offering + try: + virtualMachine.scale(apiclient, serviceOfferingId=serviceOffering_dynamic_2.id, + customcpunumber=4, customcpuspeed=512, custommemory=512) + except Exception as e: + self.fail("Failure while changing service offering: %s" % e) + + # Scale VM with dynamic offering proving custom value only for cpu number + try: + virtualMachine.scale(apiclient, serviceOfferingId=serviceOffering_dynamic_1.id, + customcpunumber=4) + self.fail("Changing service offering should have failed, it succeded") + except Exception as e: + self.debug("Failure while changing service offering: %s" % e) + + return + +@ddt +class TestAccountLimits(cloudstackTestCase): + """Test max limit of account (cpunumber and memory) with dynamic compute offering + """ + + @classmethod + def setUpClass(cls): + cloudstackTestClient = super(TestAccountLimits,cls).getClsTestClient() + cls.api_client = cloudstackTestClient.getApiClient() + + # Fill services from the external config file + cls.services = cloudstackTestClient.getParsedTestDataConfig() + + # Get Zone, Domain and templates + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cloudstackTestClient.getZoneForTests()) + cls.mode = str(cls.zone.networktype).lower() + cls.template = get_template( + cls.api_client, + cls.zone.id, + cls.services["ostype"] + ) + cls.services["virtual_machine"]["zoneid"] = cls.zone.id + cls.services["virtual_machine"]["template"] = cls.template.id + cls._cleanup = [] + 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) + return + + def setUp(self): + self.apiclient = self.testClient.getApiClient() + self.dbclient = self.testClient.getDbConnection() + self.cleanup_co = [] + self.cleanup = [] + return + + def tearDown(self): + try: + # Clean up compute offerings + cleanup_resources(self.apiclient, self.cleanup) + + # Clean up compute offerings + cleanup_resources(self.apiclient, self.cleanup_co) + + self.cleanup_co[:] = [] + self.cleanup[:] = [] + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + @data(ADMIN_ACCOUNT, USER_ACCOUNT) + @attr(tags=["basic","advanced"]) + def test_max_account_cpus_deploy_VM(self, value): + """Test cpu limits of account while deploying VM with dynamic compute offering""" + + # Steps: + # 1. Create Account (admin/user) + # 2. Update max cpu limit of account to 2 + # 3. Create dynamic service offering + # 4. Deploy VM with dynamic service offering and cpu number 3 + + # Validations: + # 1. VM creation should fail + + isadmin=True + if value == USER_ACCOUNT: + isadmin=False + + # Create account and api client + self.account = Account.create(self.apiclient,self.services["account"],domainid=self.domain.id, admin=isadmin) + self.cleanup.append(self.account) + + Resources.updateLimit(self.apiclient, + resourcetype=8, + max=2, + account=self.account.name, + domainid=self.account.domainid) + + # Create dynamic service offerings + self.services["service_offering"]["cpunumber"] = "" + self.services["service_offering"]["cpuspeed"] = "" + self.services["service_offering"]["memory"] = "" + + serviceOffering_dynamic = ServiceOffering.create(self.apiclient, + self.services["service_offering"]) + + self.cleanup_co.append(serviceOffering_dynamic) + + # Deploy VM with dynamic service offering + try: + VirtualMachine.create(self.apiclient,self.services["virtual_machine"], + serviceofferingid=serviceOffering_dynamic.id, + accountid=self.account.name,domainid=self.account.domainid, + customcpunumber=3, customcpuspeed=256, custommemory=128) + self.fail("vm creation should have failed, it succeeded") + except Exception as e: + self.debug("vm creation failed as expected with error: %s" % e) + + return + + @data(ADMIN_ACCOUNT, USER_ACCOUNT) + @attr(tags=["basic","advanced"]) + def test_max_account_cpus_scale_VM(self, value): + """Test cpu limits of account while scaling VM with dynamic compute offering""" + + # Steps: + # 1. Create Account (admin/user) + # 2. Update max cpu limit of account to 2 + # 3. Create dynamic service offering + # 4. Deploy VM with dynamic service offering and cpu number 2 + # 5. Try to Scale VM with dynamic service offering and cpu number 3 + + # Validations: + # 1. VM creation should succeed + # 2. VM scaling operation should fail + + isadmin=True + if value == USER_ACCOUNT: + isadmin=False + + # Create account and api client + self.account = Account.create(self.apiclient,self.services["account"],domainid=self.domain.id, admin=isadmin) + self.cleanup.append(self.account) + + Resources.updateLimit(self.apiclient, + resourcetype=8, + max=2, + account=self.account.name, + domainid=self.account.domainid) + + # Create dynamic service offerings + self.services["service_offering"]["cpunumber"] = "" + self.services["service_offering"]["cpuspeed"] = "" + self.services["service_offering"]["memory"] = "" + + serviceOffering_dynamic = ServiceOffering.create(self.apiclient, + self.services["service_offering"]) + + self.cleanup_co.append(serviceOffering_dynamic) + + # Deploy VM with dynamic service offering + try: + virtualMachine = VirtualMachine.create(self.apiclient,self.services["virtual_machine"], + serviceofferingid=serviceOffering_dynamic.id, + accountid=self.account.name,domainid=self.account.domainid, + customcpunumber=2, customcpuspeed=256, custommemory=128) + except Exception as e: + self.fail("vm creation failed: %s" % e) + + # Scale VM with same dynamic offering + try: + virtualMachine.scale(self.apiclient, serviceOfferingId=serviceOffering_dynamic.id, + customcpunumber=4, customcpuspeed=512, custommemory=256) + self.fail("Scaling virtual machine with cpu number more than \ + allowed limit (of account) succeded, should have failed") + except Exception as e: + self.debug("Failure while changing service offering as expected: %s" % e) + + return + + @data(ADMIN_ACCOUNT, USER_ACCOUNT) + @attr(tags=["basic","advanced"]) + def test_max_account_memory_deploy_VM(self, value): + """Test memory limits of account while deploying VM with dynamic compute offering""" + + # Steps: + # 1. Create Account (admin/user) + # 2. Update max memory limit of account to 256 + # 3. Create dynamic service offering + # 4. Deploy VM with dynamic service offering and memory 512 + + # Validations: + # 1. VM creation should fail + + isadmin=True + if value == USER_ACCOUNT: + isadmin=False + + # Create account and api client + self.account = Account.create(self.apiclient,self.services["account"],domainid=self.domain.id, admin=isadmin) + self.cleanup.append(self.account) + + Resources.updateLimit(self.apiclient, + resourcetype=9, + max=256, + account=self.account.name, + domainid=self.account.domainid) + + # Create dynamic service offerings + self.services["service_offering"]["cpunumber"] = "" + self.services["service_offering"]["cpuspeed"] = "" + self.services["service_offering"]["memory"] = "" + + serviceOffering_dynamic = ServiceOffering.create(self.apiclient, + self.services["service_offering"]) + + self.cleanup_co.append(serviceOffering_dynamic) + + # Deploy VM with dynamic service offering + try: + VirtualMachine.create(self.apiclient,self.services["virtual_machine"], + serviceofferingid=serviceOffering_dynamic.id, + accountid=self.account.name,domainid=self.account.domainid, + customcpunumber=3, customcpuspeed=256, custommemory=512) + self.fail("vm creation should have failed, it succeeded") + except Exception as e: + self.debug("vm creation failed as expected with error: %s" % e) + + return + + @data(ADMIN_ACCOUNT, USER_ACCOUNT) + @attr(tags=["basic","advanced"]) + def test_max_account_memory_scale_VM(self, value): + """Test memory limits of account while scaling VM with dynamic compute offering""" + + # Steps: + # 1. Create Account (admin/user) + # 2. Update max memory limit of account to 256 + # 3. Create dynamic service offering + # 4. Deploy VM with dynamic service offering and memory 256 + # 5. Try to Scale VM with dynamic service offering and memory 512 + + # Validations: + # 1. VM creation should succeed + # 2. VM scaling operation should fail + + isadmin=True + if value == USER_ACCOUNT: + isadmin=False + + # Create account and api client + self.account = Account.create(self.apiclient,self.services["account"],domainid=self.domain.id, admin=isadmin) + self.cleanup.append(self.account) + + Resources.updateLimit(self.apiclient, + resourcetype=9, + max=256, + account=self.account.name, + domainid=self.account.domainid) + + # Create dynamic service offerings + self.services["service_offering"]["cpunumber"] = "" + self.services["service_offering"]["cpuspeed"] = "" + self.services["service_offering"]["memory"] = "" + + serviceOffering_dynamic = ServiceOffering.create(self.apiclient, + self.services["service_offering"]) + + self.cleanup_co.append(serviceOffering_dynamic) + + # Deploy VM with dynamic service offering + try: + virtualMachine = VirtualMachine.create(self.apiclient,self.services["virtual_machine"], + serviceofferingid=serviceOffering_dynamic.id, + accountid=self.account.name,domainid=self.account.domainid, + customcpunumber=2, customcpuspeed=256, custommemory=256) + except Exception as e: + self.fail("vm creation failed: %s" % e) + + # Scale VM with same dynamic offering + try: + virtualMachine.scale(self.apiclient, serviceOfferingId=serviceOffering_dynamic.id, + customcpunumber=4, customcpuspeed=512, custommemory=512) + self.fail("Scaling virtual machine with cpu number more than \ + allowed limit (of account) succeded, should have failed") + except Exception as e: + self.debug("Failure while changing service offering as expected: %s" % e) + + return + +@ddt +class TestAffinityGroup(cloudstackTestCase): + """Test affinity group working with VMs created with dynamic offering + """ + + @classmethod + def setUpClass(cls): + cloudstackTestClient = super(TestAffinityGroup,cls).getClsTestClient() + cls.api_client = cloudstackTestClient.getApiClient() + + # Fill services from the external config file + cls.services = cloudstackTestClient.getParsedTestDataConfig() + + # Get Zone, Domain and templates + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cloudstackTestClient.getZoneForTests()) + cls.mode = str(cls.zone.networktype).lower() + cls.template = get_template( + cls.api_client, + cls.zone.id, + cls.services["ostype"] + ) + cls.services["virtual_machine"]["zoneid"] = cls.zone.id + cls.services["virtual_machine"]["template"] = cls.template.id + cls._cleanup = [] + 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) + return + + def setUp(self): + self.apiclient = self.testClient.getApiClient() + self.dbclient = self.testClient.getDbConnection() + self.cleanup_co = [] + self.cleanup = [] + return + + def tearDown(self): + try: + # Clean up compute offerings + cleanup_resources(self.apiclient, self.cleanup) + + # Clean up compute offerings + cleanup_resources(self.apiclient, self.cleanup_co) + + self.cleanup_co[:] = [] + self.cleanup[:] = [] + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + @data(ADMIN_ACCOUNT, USER_ACCOUNT) + @attr(tags=["basic","advanced"]) + def test_deploy_VM_with_affinity_group(self, value): + """Test deploy VMs with affinity group and dynamic compute offering""" + + # Steps: + # 1. Create Account (admin/user) + # 2. Update max cpu limit of account to 2 + # 3. Create dynamic service offering + # 4. Deploy VM with dynamic service offering and cpu number 3 + + # Validations: + # 1. VM creation should fail + + isadmin=True + if value == USER_ACCOUNT: + isadmin=False + + # Create account and api client + self.account = Account.create(self.apiclient,self.services["account"],domainid=self.domain.id, admin=isadmin) + self.cleanup.append(self.account) + + # Create dynamic service offerings + self.services["service_offering"]["cpunumber"] = "" + self.services["service_offering"]["cpuspeed"] = "" + self.services["service_offering"]["memory"] = "" + + serviceOffering_dynamic = ServiceOffering.create(self.apiclient, + self.services["service_offering"]) + + self.cleanup_co.append(serviceOffering_dynamic) + + self.services["host_anti_affinity"]["name"] = "aff_grp_" + random_gen(size=6) + affinityGroup = AffinityGroup.create(self.apiclient, self.services["host_anti_affinity"], + self.account.name, self.domain.id) + + # Deploy VM with dynamic service offering + try: + virtualMachine = VirtualMachine.create(self.apiclient,self.services["virtual_machine"], + serviceofferingid=serviceOffering_dynamic.id, + accountid=self.account.name,domainid=self.account.domainid, + customcpunumber=2, customcpuspeed=256, custommemory=128, + affinitygroupnames=[affinityGroup.name]) + except Exception as e: + self.fail("vm creation failed with error: %s" % e) + + otherHostsInCluster = Host.list(self.apiclient, virtualmachineid=virtualMachine.id) + if validateList(otherHostsInCluster)[0] == PASS: + try: + VirtualMachine.create(self.apiclient,self.services["virtual_machine"], + serviceofferingid=serviceOffering_dynamic.id, + accountid=self.account.name,domainid=self.account.domainid, + customcpunumber=2, customcpuspeed=256, custommemory=128, + affinitygroupnames=[affinityGroup.name]) + except Exception as e: + self.fail("vm creation failed with error: %s" % e) + + else: + try: + VirtualMachine.create(self.apiclient,self.services["virtual_machine"], + serviceofferingid=serviceOffering_dynamic.id, + accountid=self.account.name,domainid=self.account.domainid, + customcpunumber=2, customcpuspeed=256, custommemory=128, + affinitygroupnames=[affinityGroup.name]) + self.fail("vm creation should have failed, it succeded") + except Exception as e: + self.debug("vm creation failed as expected with error: %s" % e) + + return diff --git a/test/integration/component/test_egress_fw_rules.py b/test/integration/component/test_egress_fw_rules.py index 8fa8a5ed26..4b4b6eee66 100644 --- a/test/integration/component/test_egress_fw_rules.py +++ b/test/integration/component/test_egress_fw_rules.py @@ -21,7 +21,7 @@ import unittest from nose.plugins.attrib import attr from marvin.cloudstackTestCase import cloudstackTestCase -from marvin.integration.lib.base import (Account, +from marvin.lib.base import (Account, Domain, Router, Network, @@ -31,14 +31,14 @@ FireWallRule, NATRule, PublicIPAddress) -from marvin.integration.lib.common import (get_domain, +from marvin.lib.common import (get_domain, get_zone, get_template, list_routers, wait_for_cleanup, list_virtual_machines ) -from marvin.integration.lib.utils import cleanup_resources, validateList +from marvin.lib.utils import cleanup_resources, validateList from marvin.cloudstackAPI import rebootRouter from marvin.cloudstackAPI.createEgressFirewallRule import createEgressFirewallRuleCmd from marvin.cloudstackAPI.deleteEgressFirewallRule import deleteEgressFirewallRuleCmd @@ -132,12 +132,13 @@ class TestEgressFWRules(cloudstackTestCase): @classmethod def setUpClass(cls): cls._cleanup = [] - cls.api_client = super(TestEgressFWRules, - cls).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone Domain and create Domains and sub Domains. - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.testClient = super(TestEgressFWRules, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + + cls.services = Services().services + # 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 # Get and set template id for VM creation. cls.template = get_template(cls.api_client, @@ -274,17 +275,22 @@ def exec_script_on_user_vm(self, script, exec_cmd_params, expected_result, negat self.debug("script: %s" % script+exec_cmd_params) self.debug("result: %s" % result) - if str(result).strip() == expected_result: + if isinstance(result, list): + str_result = str([str(x) for x in result]) + else: + str_result = str(result) + str_expected_result = str(expected_result).strip() + if str_result == str_expected_result: exec_success = True if negative_test: self.assertEqual(exec_success, True, - "Script result is %s matching with %s" % (result, expected_result)) + "Script result is %s matching with %s" % (str_result, str_expected_result)) else: self.assertEqual(exec_success, True, - "Script result is %s is not matching with %s" % (result, expected_result)) + "Script result is %s is not matching with %s" % (str_result, str_expected_result)) except Exception as e: self.debug('Error=%s' % e) @@ -382,7 +388,7 @@ def tearDown(self): except Exception as e: self.fail("Warning! Cleanup failed: %s" % e) - @attr(tags = ["advanced"]) + @attr(tags=["advanced", "provisioning"]) def test_01_egress_fr1(self): """Test By-default the communication from guest n/w to public n/w is allowed. """ @@ -397,7 +403,7 @@ def test_01_egress_fr1(self): "['0']", negative_test=False) - @attr(tags = ["advanced"]) + @attr(tags=["advanced", "provisioning"]) def test_01_1_egress_fr1(self): """Test By-default the communication from guest n/w to public n/w is NOT allowed. """ @@ -413,7 +419,7 @@ def test_01_1_egress_fr1(self): negative_test=False) - @attr(tags = ["advanced"]) + @attr(tags=["advanced", "provisioning"]) def test_02_egress_fr2(self): """Test Allow Communication using Egress rule with CIDR + Port Range + Protocol. """ @@ -430,7 +436,7 @@ def test_02_egress_fr2(self): "['100']", negative_test=False) - @attr(tags = ["advanced"]) + @attr(tags=["advanced", "provisioning"]) def test_02_1_egress_fr2(self): """Test Allow Communication using Egress rule with CIDR + Port Range + Protocol. """ @@ -447,7 +453,7 @@ def test_02_1_egress_fr2(self): "['0']", negative_test=False) - @attr(tags = ["advanced"]) + @attr(tags=["advanced", "provisioning"]) def test_03_egress_fr3(self): """Test Communication blocked with network that is other than specified """ @@ -468,7 +474,7 @@ def test_03_egress_fr3(self): "[]", negative_test=False) - @attr(tags = ["advanced"]) + @attr(tags=["advanced", "provisioning"]) def test_03_1_egress_fr3(self): """Test Communication blocked with network that is other than specified """ @@ -489,7 +495,7 @@ def test_03_1_egress_fr3(self): "['failed:']", negative_test=False) - @attr(tags = ["advanced"]) + @attr(tags=["advanced", "selfservice"]) def test_04_egress_fr4(self): """Test Create Egress rule and check the Firewall_Rules DB table """ @@ -526,7 +532,7 @@ def test_04_egress_fr4(self): "DB results not matching, expected: 1, found: %s" % qresultset[0][0]) - @attr(tags = ["advanced"]) + @attr(tags=["advanced", "selfservice"]) def test_04_1_egress_fr4(self): """Test Create Egress rule and check the Firewall_Rules DB table """ @@ -563,7 +569,7 @@ def test_04_1_egress_fr4(self): "DB results not matching, expected: 0, found: %s" % qresultset[0][0]) @unittest.skip("Skip") - @attr(tags = ["advanced"]) + @attr(tags=["advanced", "NotRun"]) def test_05_egress_fr5(self): """Test Create Egress rule and check the IP tables """ @@ -582,7 +588,7 @@ def test_05_egress_fr5(self): @unittest.skip("Skip") - @attr(tags = ["advanced"]) + @attr(tags=["advanced", "NotRun"]) def test_05_1_egress_fr5(self): """Test Create Egress rule and check the IP tables """ @@ -600,7 +606,7 @@ def test_05_1_egress_fr5(self): #TODO: Query VR for expected route rules. - @attr(tags = ["advanced"]) + @attr(tags=["advanced", "provisioning"]) def test_06_egress_fr6(self): """Test Create Egress rule without CIDR """ @@ -616,7 +622,7 @@ def test_06_egress_fr6(self): "['100']", negative_test=False) - @attr(tags = ["advanced"]) + @attr(tags=["advanced", "provisioning"]) def test_06_1_egress_fr6(self): """Test Create Egress rule without CIDR """ @@ -632,7 +638,7 @@ def test_06_1_egress_fr6(self): "['0']", negative_test=False) - @attr(tags = ["advanced"]) + @attr(tags=["advanced", "provisioning"]) def test_07_egress_fr7(self): """Test Create Egress rule without End Port """ @@ -648,7 +654,7 @@ def test_07_egress_fr7(self): "['failed:']", negative_test=False) - @attr(tags = ["advanced"]) + @attr(tags=["advanced", "provisioning"]) def test_07_1_egress_fr7(self): """Test Create Egress rule without End Port """ @@ -665,7 +671,7 @@ def test_07_1_egress_fr7(self): negative_test=False) @unittest.skip("Skip") - @attr(tags = ["advanced"]) + @attr(tags=["advanced", "NotRun"]) def test_08_egress_fr8(self): """Test Port Forwarding and Egress Conflict """ @@ -677,7 +683,7 @@ def test_08_egress_fr8(self): self.createEgressRule() @unittest.skip("Skip") - @attr(tags = ["advanced"]) + @attr(tags=["advanced", "NotRun"]) def test_08_1_egress_fr8(self): """Test Port Forwarding and Egress Conflict """ @@ -689,7 +695,7 @@ def test_08_1_egress_fr8(self): self.createEgressRule() - @attr(tags = ["advanced"]) + @attr(tags=["advanced", "provisioning"]) def test_09_egress_fr9(self): """Test Delete Egress rule """ @@ -713,7 +719,7 @@ def test_09_egress_fr9(self): "['0']", negative_test=False) - @attr(tags = ["advanced"]) + @attr(tags=["advanced", "provisioning"]) def test_09_1_egress_fr9(self): """Test Delete Egress rule """ @@ -738,7 +744,7 @@ def test_09_1_egress_fr9(self): negative_test=False) - @attr(tags = ["advanced"]) + @attr(tags=["advanced", "selfservice"]) def test_10_egress_fr10(self): """Test Invalid CIDR and Invalid Port ranges """ @@ -749,7 +755,7 @@ def test_10_egress_fr10(self): self.create_vm() self.assertRaises(Exception, self.createEgressRule, '10.2.2.0/24') - @attr(tags = ["advanced"]) + @attr(tags=["advanced", "selfservice"]) def test_10_1_egress_fr10(self): """Test Invalid CIDR and Invalid Port ranges """ @@ -761,7 +767,7 @@ def test_10_1_egress_fr10(self): self.assertRaises(Exception, self.createEgressRule, '10.2.2.0/24') - @attr(tags = ["advanced"]) + @attr(tags=["advanced", "selfservice"]) def test_11_egress_fr11(self): """Test Regression on Firewall + PF + LB + SNAT """ @@ -771,7 +777,7 @@ def test_11_egress_fr11(self): # 3. All should work fine. self.create_vm(pfrule=True) - @attr(tags = ["advanced"]) + @attr(tags=["advanced", "selfservice"]) def test_11_1_egress_fr11(self): """Test Regression on Firewall + PF + LB + SNAT """ @@ -781,7 +787,7 @@ def test_11_1_egress_fr11(self): # 3. All should work fine. self.create_vm(pfrule=True, egress_policy=False) - @attr(tags = ["advanced"]) + @attr(tags=["advanced", "provisioning"]) def test_12_egress_fr12(self): """Test Reboot Router """ @@ -798,7 +804,7 @@ def test_12_egress_fr12(self): "['100']", negative_test=False) - @attr(tags = ["advanced"]) + @attr(tags=["advanced", "provisioning"]) def test_12_1_egress_fr12(self): """Test Reboot Router """ @@ -815,7 +821,7 @@ def test_12_1_egress_fr12(self): "['0']", negative_test=False) - @attr(tags = ["advanced"]) + @attr(tags=["advanced", "provisioning"]) def test_13_egress_fr13(self): """Test Redundant Router : Master failover """ @@ -870,7 +876,7 @@ def test_13_egress_fr13(self): "['100']", negative_test=False) - @attr(tags = ["advanced"]) + @attr(tags=["advanced", "provisioning"]) def test_13_1_egress_fr13(self): """Test Redundant Router : Master failover """ diff --git a/test/integration/component/test_egress_rules.py b/test/integration/component/test_egress_rules.py index a2443d4940..0f05c07a22 100644 --- a/test/integration/component/test_egress_rules.py +++ b/test/integration/component/test_egress_rules.py @@ -5,9 +5,9 @@ # 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 @@ -20,13 +20,13 @@ #Import Local Modules from nose.plugins.attrib import attr from marvin.cloudstackTestCase import cloudstackTestCase -from marvin.integration.lib.utils import (random_gen, +from marvin.lib.utils import (random_gen, cleanup_resources) -from marvin.integration.lib.base import (SecurityGroup, +from marvin.lib.base import (SecurityGroup, VirtualMachine, Account, ServiceOffering) -from marvin.integration.lib.common import (get_domain, +from marvin.lib.common import (get_domain, get_zone, get_template, list_virtual_machines) @@ -149,15 +149,13 @@ def tearDown(self): @classmethod def setUpClass(cls): - cls.services = Services().services - cls.api_client = super( - TestDefaultSecurityGroupEgress, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestDefaultSecurityGroupEgress, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype template = get_template( @@ -307,15 +305,13 @@ def tearDown(self): @classmethod def setUpClass(cls): - cls.services = Services().services - cls.api_client = super( - TestAuthorizeIngressRule, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestAuthorizeIngressRule, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype template = get_template( @@ -465,15 +461,13 @@ def tearDown(self): @classmethod def setUpClass(cls): - cls.services = Services().services - cls.api_client = super( - TestDefaultGroupEgress, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestDefaultGroupEgress, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype template = get_template( @@ -663,15 +657,13 @@ def tearDown(self): @classmethod def setUpClass(cls): - cls.services = Services().services - cls.api_client = super( - TestDefaultGroupEgressAfterDeploy, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestDefaultGroupEgressAfterDeploy, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype template = get_template( @@ -842,15 +834,13 @@ def tearDown(self): @classmethod def setUpClass(cls): - cls.services = Services().services - cls.api_client = super( - TestRevokeEgressRule, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestRevokeEgressRule, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype template = get_template( @@ -1125,15 +1115,13 @@ def tearDown(self): @classmethod def setUpClass(cls): - cls.services = Services().services - cls.api_client = super( - TestInvalidAccountAuthroize, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestInvalidAccountAuthroize, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype template = get_template( @@ -1246,15 +1234,13 @@ def tearDown(self): @classmethod def setUpClass(cls): - cls.services = Services().services - cls.api_client = super( - TestMultipleAccountsEgressRuleNeg, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestMultipleAccountsEgressRuleNeg, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype template = get_template( @@ -1495,15 +1481,13 @@ def tearDown(self): @classmethod def setUpClass(cls): - cls.services = Services().services - cls.api_client = super( - TestMultipleAccountsEgressRule, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestMultipleAccountsEgressRule, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype template = get_template( @@ -1786,15 +1770,13 @@ def tearDown(self): @classmethod def setUpClass(cls): - cls.services = Services().services - cls.api_client = super( - TestStartStopVMWithEgressRule, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestStartStopVMWithEgressRule, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype template = get_template( @@ -1919,27 +1901,11 @@ def test_start_stop_vm_egress(self): "Check egress rule created properly" ) - # Stop virtual machine - self.debug("Stopping virtual machine: %s" % self.virtual_machine.id) - self.virtual_machine.stop(self.apiclient) - - vms = VirtualMachine.list( - self.apiclient, - id=self.virtual_machine.id, - listall=True - ) - self.assertEqual( - isinstance(vms, list), - True, - "List VM should return a valid list" - ) - vm = vms[0] - self.assertEqual( - vm.state, - "Stopped", - "VM state should be stopped" - ) - self.debug("VM: %s state: %s" % (vm.id, vm.state)) + try: + # Stop virtual machine + self.virtual_machine.stop(self.apiclient) + except Exception as e: + self.fail("Failed to stop instance: %s" % e) # Start virtual machine self.debug("Starting virtual machine: %s" % self.virtual_machine.id) @@ -1993,15 +1959,13 @@ def tearDown(self): @classmethod def setUpClass(cls): - cls.services = Services().services - cls.api_client = super( - TestInvalidParametersForEgress, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestInvalidParametersForEgress, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype template = get_template( diff --git a/test/integration/component/test_eip_elb.py b/test/integration/component/test_eip_elb.py index d639d82d9f..0613c4d053 100644 --- a/test/integration/component/test_eip_elb.py +++ b/test/integration/component/test_eip_elb.py @@ -22,9 +22,9 @@ from nose.plugins.attrib import attr from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * +from marvin.lib.utils import * +from marvin.lib.base import * +from marvin.lib.common import * from marvin.sshClient import SshClient import datetime @@ -91,11 +91,13 @@ class TestEIP(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestEIP, cls).getClsTestClient().getApiClient() + cls.testClient = super(TestEIP, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + 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, @@ -909,11 +911,13 @@ class TestELB(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestELB, cls).getClsTestClient().getApiClient() + cls.testClient = super(TestELB, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + 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, diff --git a/test/integration/component/test_escalations_instances.py b/test/integration/component/test_escalations_instances.py new file mode 100644 index 0000000000..4900ff625e --- /dev/null +++ b/test/integration/component/test_escalations_instances.py @@ -0,0 +1,3460 @@ +# 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 Local Modules +from marvin.cloudstackTestCase import * +from marvin.cloudstackException import * +from marvin.cloudstackAPI import * +from marvin.sshClient import SshClient +from marvin.lib.utils import * +from marvin.lib.base import * +from marvin.lib.common import * +from marvin.lib.utils import checkVolumeSize +from marvin.codes import SUCCESS +from nose.plugins.attrib import attr +from time import sleep +from ctypes.wintypes import BOOLEAN + +class TestListInstances(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + try: + cls._cleanup = [] + cls.testClient = super(TestListInstances, 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()) + cls.template = get_template( + cls.api_client, + cls.zone.id, + cls.services["ostype"] + ) + if cls.zone.localstorageenabled: + cls.storagetype = 'local' + cls.services["service_offerings"]["tiny"]["storagetype"] = 'local' + cls.services["disk_offering"]["storagetype"] = 'local' + else: + cls.storagetype = 'shared' + cls.services["service_offerings"]["tiny"]["storagetype"] = 'shared' + cls.services["disk_offering"]["storagetype"] = 'shared' + + cls.services['mode'] = cls.zone.networktype + cls.services["virtual_machine"]["hypervisor"] = cls.testClient.getHypervisorInfo() + cls.services["virtual_machine"]["zoneid"] = cls.zone.id + cls.services["virtual_machine"]["template"] = cls.template.id + cls.services["custom_volume"]["zoneid"] = cls.zone.id + # Creating Disk offering, Service Offering and Account + cls.disk_offering = DiskOffering.create( + cls.api_client, + cls.services["disk_offering"] + ) + cls.service_offering = ServiceOffering.create( + cls.api_client, + cls.services["service_offerings"]["tiny"] + ) + cls.account = Account.create( + cls.api_client, + cls.services["account"], + domainid=cls.domain.id + ) + # Getting authentication for user in newly created Account + cls.user = cls.account.user[0] + cls.userapiclient = cls.testClient.getUserApiClient(cls.user.username, cls.domain.name) + # Updating resource Limits + for i in range(0, 12): + Resources.updateLimit( + cls.api_client, + account=cls.account.name, + domainid=cls.domain.id, + max=-1, + resourcetype=i + ) + + cls._cleanup.append(cls.account) + cls._cleanup.append(cls.service_offering) + cls._cleanup.append(cls.disk_offering) + except Exception as e: + cls.tearDownClass() + raise Exception("Warning: Exception in setup : %s" % e) + return + + def setUp(self): + + self.apiClient = self.testClient.getApiClient() + self.cleanup = [] + + def tearDown(self): + # Clean up, terminate the created resources + cleanup_resources(self.apiClient, self.cleanup) + return + + @classmethod + def tearDownClass(cls): + try: + cleanup_resources(cls.api_client, cls._cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + + return + + def __verify_values(self, expected_vals, actual_vals): + """ + @Desc: Function to verify expected and actual values + @Steps: + Step1: Initializing return flag to True + Step1: Verifying length of expected and actual dictionaries is matching. + If not matching returning false + Step2: Listing all the keys from expected dictionary + Step3: Looping through each key from step2 and verifying expected and actual dictionaries have same value + If not making return flag to False + Step4: returning the return flag after all the values are verified + """ + return_flag = True + + if len(expected_vals) != len(actual_vals): + return False + + keys = expected_vals.keys() + for i in range(0, len(expected_vals)): + exp_val = expected_vals[keys[i]] + act_val = actual_vals[keys[i]] + if exp_val == act_val: + return_flag = return_flag and True + else: + return_flag = return_flag and False + self.debug("expected Value: %s, is not matching with actual value: %s" % ( + exp_val, + act_val + )) + return return_flag + + @attr(tags=["advanced", "basic", "selfservice"]) + def test_01_list_instances_pagination(self): + """ + @Desc: Test List Instances pagination + @Steps: + Step1: Listing all the Instances for a user + Step2: Verifying listed Instances for account created at class level + Step3: If number of volumes is less than (page size + 1), then creating them + Step4: Listing all the volumes again after creation of volumes + Step5: Verifying the length of the volumes is (page size + 1) + Step6: Listing all the volumes in page1 + Step7: Verifying that the length of the volumes in page 1 is (page size) + Step8: Listing all the volumes in page2 + Step9: Verifying that the length of the volumes in page 2 is 1 + Step10: Deleting the volume present in page 2 + Step11: Listing for the volumes on page 2 + Step12: Verifying that there are no volumes present in page 2 + """ + # Listing all the instances for a user + list_instances_before = VirtualMachine.list(self.userapiclient, listall=self.services["listall"]) + + # Verifying listed instances for account created at class level + self.assertIsNone( + list_instances_before, + "Virtual Machine already exists for newly created user" + ) + # If number of instances are less than (pagesize + 1), then creating them + for i in range(0, (self.services["pagesize"] + 1)): + vm_created = VirtualMachine.create( + self.userapiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + ) + self.assertIsNotNone( + vm_created, + "VM creation failed" + ) + if(i < (self.services["pagesize"])): + self.cleanup.append(vm_created) + + self.assertEqual( + self.services["virtual_machine"]["displayname"], + vm_created.displayname, + "Newly created VM name and the test data VM name are not matching" + ) + + # Listing all the instances again after creating VM's + list_instances_after = VirtualMachine.list(self.userapiclient, listall=self.services["listall"]) + status = validateList(list_instances_after) + self.assertEquals( + PASS, + status[0], + "Listing of instances after creation failed" + ) + # Verifying the length of the instances is (page size + 1) + self.assertEqual( + len(list_instances_after), + (self.services["pagesize"] + 1), + "Number of instances created is not matching as expected" + ) + + # Listing all the volumes in page1 + list_instances_page1 = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + page=1, + pagesize=self.services["pagesize"], + domainid=self.account.domainid + ) + status = validateList(list_instances_page1) + self.assertEquals( + PASS, + status[0], + "Listing of instances in page1 failed" + ) + # Verifying that the length of the instances in page 1 is (page size) + self.assertEqual( + self.services["pagesize"], + len(list_instances_page1), + "List VM response is not matching with the page size length for page 1" + ) + + # Listing all the VM's in page2 + list_instances_page2 = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + page=2, + pagesize=self.services["pagesize"], + domainid=self.account.domainid + ) + status = validateList(list_instances_page2) + self.assertEquals( + PASS, + status[0], + "Listing of instances in page2 failed" + ) + # Verifying that the length of the VM's in page 2 is 1 + self.assertEqual( + 1, + len(list_instances_page2), + "List VM response is not matching with the page size length for page 2" + ) + instance_page2 = list_instances_page2[0] + + # Verifying that the VM on page 2 is not present in page1 + for i in range(0, len(list_instances_page1)): + instance_page1 = list_instances_page1[i] + self.assertNotEquals( + instance_page2.id, + instance_page1.id, + "VM listed in page 2 is also listed in page 1" + ) + + # Deleting a single VM + VirtualMachine.delete(vm_created, self.userapiclient) + + # Listing the VM's in page 2 + list_instance_response = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + page=2, + pagesize=self.services["pagesize"], + domainid=self.account.domainid + ) + # verifying that VM does not exists on page 2 + self.assertEqual( + list_instance_response, + None, + "VM was not deleted" + ) + return + + @attr(tags=["advanced", "basic", "selfservice"]) + def test_02_list_Running_vm(self): + """ + @Desc: Test List Running VM's + @Steps: + Step1: Listing all the Running VMs for a user + Step2: Verifying that the size of the list is 0 + Step3: Deploying a VM + Step4: Listing all the Running VMs for a user again + Step5: Verifying that the size of the list is increased by 1 + Step6: Verifying that the details of the Running VM listed are same as the VM deployed in Step3 + """ + # Listing all the Running VM's for a User + list_running_vms_before = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + page=1, + pagesize=self.services["pagesize"], + domainid=self.account.domainid, + state="Running" + ) + self.assertIsNone( + list_running_vms_before, + "Virtual Machine already exists for newly created user" + ) + # Deploying a VM + vm_created = VirtualMachine.create( + self.userapiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + ) + self.assertIsNotNone( + vm_created, + "VM creation failed" + ) + self.cleanup.append(vm_created) + # Listing all the Running VM's for a User + list_running_vms_after = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + page=1, + pagesize=self.services["pagesize"], + domainid=self.account.domainid, + state="Running" + ) + status = validateList(list_running_vms_after) + self.assertEquals( + PASS, + status[0], + "Newly created VM is not in Running state" + ) + # Verifying list size is 1 + self.assertEquals( + 1, + len(list_running_vms_after), + "Running VM list count is not matching" + ) + running_vm = list_running_vms_after[0] + + # Creating expected and actual values dictionaries + expected_dict = { + "id":vm_created.id, + "name":vm_created.name, + "displayname":vm_created.displayname, + "state":"Running", + "zoneid":vm_created.zoneid, + "account":vm_created.account, + "template":vm_created.templateid + } + actual_dict = { + "id":running_vm.id, + "name":running_vm.name, + "displayname":running_vm.displayname, + "state":running_vm.state, + "zoneid":running_vm.zoneid, + "account":running_vm.account, + "template":running_vm.templateid + } + running_vm_status = self.__verify_values( + expected_dict, + actual_dict + ) + self.assertEqual( + True, + running_vm_status, + "Listed Running VM details are not as expected" + ) + return + + @attr(tags=["advanced", "basic", "selfservice"]) + def test_03_list_Stopped_vm(self): + """ + @Desc: Test List Stopped VM's + @Steps: + Step1: Listing all the Stopped VMs for a user + Step2: Verifying that the size of the list is 0 + Step3: Deploying a VM + Step4: Stopping the VM deployed in step3 + Step5: Listing all the Stopped VMs for a user again + Step6: Verifying that the size of the list is increased by 1 + Step7: Verifying that the details of the Stopped VM listed are same as the VM stopped in Step4 + """ + # Listing all the Stopped VM's for a User + list_stopped_vms_before = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + page=1, + pagesize=self.services["pagesize"], + domainid=self.account.domainid, + state="Stopped" + ) + self.assertIsNone( + list_stopped_vms_before, + "Virtual Machine already exists for newly created user" + ) + # Deploying a VM + vm_created = VirtualMachine.create( + self.userapiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + ) + self.assertIsNotNone( + vm_created, + "VM creation failed" + ) + self.cleanup.append(vm_created) + # Stopping the VM + VirtualMachine.stop(vm_created, self.userapiclient) + # Listing all the Stopped VM's for a User + list_stopped_vms_after = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + page=1, + pagesize=self.services["pagesize"], + domainid=self.account.domainid, + state="Stopped" + ) + status = validateList(list_stopped_vms_after) + self.assertEquals( + PASS, + status[0], + "Stopped VM is not in Stopped state" + ) + # Verifying list size is 1 + self.assertEquals( + 1, + len(list_stopped_vms_after), + "Stopped VM list count is not matching" + ) + stopped_vm = list_stopped_vms_after[0] + # Creating expected and actual values dictionaries + expected_dict = { + "id":vm_created.id, + "name":vm_created.name, + "displayname":vm_created.displayname, + "state":"Stopped", + "zoneid":vm_created.zoneid, + "account":vm_created.account, + "template":vm_created.templateid + } + actual_dict = { + "id":stopped_vm.id, + "name":stopped_vm.name, + "displayname":stopped_vm.displayname, + "state":stopped_vm.state, + "zoneid":stopped_vm.zoneid, + "account":stopped_vm.account, + "template":stopped_vm.templateid + } + stopped_vm_status = self.__verify_values( + expected_dict, + actual_dict + ) + self.assertEqual( + True, + stopped_vm_status, + "Listed Stopped VM details are not as expected" + ) + return + + @attr(tags=["advanced", "basic", "selfservice"]) + def test_04_list_Destroyed_vm(self): + """ + @Desc: Test List Destroyed VM's + @Steps: + Step1: Listing all the Destroyed VMs for a user + Step2: Verifying that the size of the list is 0 + Step3: Deploying a VM + Step4: Destroyed the VM deployed in step3 + Step5: Listing all the Destroyed VMs for a user again + Step6: Verifying that destroyed VM is not listed for User + Step7: Listing all the destroyed VMs as admin + Step8: Verifying that the size of the list is 1 + Step9: Verifying that the details of the Destroyed VM listed are same as the VM destroyed in Step4 + """ + # Listing all the Destroyed VM's for a User + list_destroyed_vms_before = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + page=1, + pagesize=self.services["pagesize"], + domainid=self.account.domainid, + state="Destroyed" + ) + self.assertIsNone( + list_destroyed_vms_before, + "Virtual Machine in Destroyed state already exists for newly created user" + ) + # Deploying a VM + vm_created = VirtualMachine.create( + self.userapiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + ) + self.assertIsNotNone( + vm_created, + "VM creation failed" + ) + # Destroying the VM + VirtualMachine.delete(vm_created, self.userapiclient) + # Listing all the Destroyed VM's for a User + list_destroyed_vms_after = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + page=1, + pagesize=self.services["pagesize"], + domainid=self.account.domainid, + state="Destroyed" + ) + self.assertIsNone( + list_destroyed_vms_after, + "Destroyed VM is not in destroyed state" + ) + # Listing destroyed VMs as admin user + list_destroyed_vms_admin = VirtualMachine.list( + self.apiClient, + listall=self.services["listall"], + page=1, + pagesize=self.services["pagesize"], + domainid=self.account.domainid, + state="Destroyed", + id=vm_created.id + ) + status = validateList(list_destroyed_vms_admin) + self.assertEquals( + PASS, + status[0], + "Destroyed VM is not in Destroyed state" + ) + # Verifying that the length of the destroyed VMs list should be 1 + self.assertEquals( + 1, + len(list_destroyed_vms_admin), + "Destroyed VM list count is not matching" + ) + destroyed_vm = list_destroyed_vms_admin[0] + # Creating expected and actual values dictionaries + expected_dict = { + "id":vm_created.id, + "name":vm_created.name, + "displayname":vm_created.displayname, + "state":"Destroyed", + "zoneid":vm_created.zoneid, + "account":vm_created.account, + "template":vm_created.templateid + } + actual_dict = { + "id":destroyed_vm.id, + "name":destroyed_vm.name, + "displayname":destroyed_vm.displayname, + "state":destroyed_vm.state, + "zoneid":destroyed_vm.zoneid, + "account":destroyed_vm.account, + "template":destroyed_vm.templateid + } + destroyed_vm_status = self.__verify_values( + expected_dict, + actual_dict + ) + self.assertEqual( + True, + destroyed_vm_status, + "Listed Destroyed VM details are not as expected" + ) + return + + @attr(tags=["advanced", "basic", "selfservice"]) + def test_05_list_vm_by_id(self): + """ + @Desc: Test List VM by Id + @Steps: + Step1: Listing all the VMs for a user + Step2: Verifying that the size of the list is 0 + Step3: Deploying a VM + Step4: Listing all the VMs for a user again + Step5: Verifying that the size of the list is increased by 1 + Step6: List a VM by specifying the Id if the VM deployed in Step3 + Step7: Verifying that the details of the Listed VM are same as the VM deployed in Step3 + """ + # Listing all the VM's for a User + list_vms_before = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + page=1, + pagesize=self.services["pagesize"], + domainid=self.account.domainid, + account=self.account.name + ) + self.assertIsNone( + list_vms_before, + "Virtual Machine already exists for newly created user" + ) + # Deploying a VM + vm_created = VirtualMachine.create( + self.userapiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + ) + self.assertIsNotNone( + vm_created, + "VM creation failed" + ) + self.cleanup.append(vm_created) + # Listing all the VM's for a User + list_vms_after = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + page=1, + pagesize=self.services["pagesize"], + domainid=self.account.domainid, + account=self.account.name + ) + status = validateList(list_vms_after) + self.assertEquals( + PASS, + status[0], + "Listing of VM after creation failed" + ) + self.assertEquals( + 1, + len(list_vms_after), + "VM list count is not matching" + ) + # Listing a VM by Id + list_vm_byid = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + id=vm_created.id + ) + status = validateList(list_vm_byid) + self.assertEquals( + PASS, + status[0], + "Listing of VM by Id failed" + ) + listed_vm = list_vm_byid[0] + # Creating expected and actual values dictionaries + expected_dict = { + "id":vm_created.id, + "name":vm_created.name, + "displayname":vm_created.displayname, + "state":vm_created.state, + "zoneid":vm_created.zoneid, + "account":vm_created.account, + "template":vm_created.templateid + } + actual_dict = { + "id":listed_vm.id, + "name":listed_vm.name, + "displayname":listed_vm.displayname, + "state":listed_vm.state, + "zoneid":listed_vm.zoneid, + "account":listed_vm.account, + "template":listed_vm.templateid + } + list_vm_status = self.__verify_values( + expected_dict, + actual_dict + ) + self.assertEqual( + True, + list_vm_status, + "Listed VM by Id details are not as expected" + ) + return + + @attr(tags=["advanced", "basic", "selfservice"]) + def test_06_list_vm_by_name(self): + """ + @Desc: Test List VM's by Name + @Steps: + Step1: Listing all the VMs for a user + Step2: Verifying that the size of the list is 0 + Step3: Deploying a 2 VM's + Step4: Listing all the VMs for a user again + Step5: Verifying that list size is increased by 2 + Step6: Listing the VM by specifying complete name of VM-1 created in step3 + Step7: Verifying that the size of the list is 1 + Step8: Verifying that the details of the listed VM are same as the VM-1 created in step3 + Step9: Listing the VM by specifying the partial name of VM + Step10: Verifying that the size of the list is 2 + """ + # Listing all the VM's for a User + list_vms_before = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + page=1, + pagesize=self.services["pagesize"], + domainid=self.account.domainid, + ) + self.assertIsNone( + list_vms_before, + "Virtual Machine already exists for newly created user" + ) + vms = {} + for i in range(0, 2): + # Deploying a VM + vm_created = VirtualMachine.create( + self.userapiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + ) + self.assertIsNotNone( + vm_created, + "VM creation failed" + ) + self.cleanup.append(vm_created) + vms.update({i: vm_created}) + + # Listing all the VM's for a User + list_vms_after = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + page=1, + pagesize=self.services["pagesize"], + domainid=self.account.domainid, + ) + status = validateList(list_vms_after) + self.assertEquals( + PASS, + status[0], + "VM's creation failed" + ) + self.assertEquals( + 2, + len(list_vms_after), + "VM's list count is not matching" + ) + # Listing the VM by complete name + list_vm_byfullname = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + page=1, + pagesize=self.services["pagesize"], + domainid=self.account.domainid, + name=vms[0].name + ) + status = validateList(list_vm_byfullname) + self.assertEquals( + PASS, + status[0], + "Failed to list VM by Name" + ) + # Verifying that the size of the list is 1 + self.assertEquals( + 1, + len(list_vm_byfullname), + "VM list by full name count is not matching" + ) + # Verifying that the details of the listed VM are same as the VM created above + # Creating expected and actual values dictionaries + expected_dict = { + "id":vms[0].id, + "name":vms[0].name, + "displayname":vms[0].displayname, + "state":vms[0].state, + "zoneid":vms[0].zoneid, + "account":vms[0].account, + "template":vms[0].templateid + } + actual_dict = { + "id":list_vm_byfullname[0].id, + "name":list_vm_byfullname[0].name, + "displayname":list_vm_byfullname[0].displayname, + "state":list_vm_byfullname[0].state, + "zoneid":list_vm_byfullname[0].zoneid, + "account":list_vm_byfullname[0].account, + "template":list_vm_byfullname[0].templateid + } + list_vm_status = self.__verify_values( + expected_dict, + actual_dict + ) + self.assertEqual( + True, + list_vm_status, + "Listed VM details are not as expected" + ) + # Listing the VM by partial name + list_vm_bypartialname = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + domainid=self.account.domainid, + name=vms[0].name[:1] + ) + status = validateList(list_vm_bypartialname) + self.assertEquals( + PASS, + status[0], + "Failed to list VM by Name" + ) + # Verifying that the size of the list is 2 + self.assertEquals( + 2, + len(list_vm_bypartialname), + "VM list by full name count is not matching" + ) + return + + @attr(tags=["advanced", "basic", "selfservice"]) + def test_07_list_vm_by_name_state(self): + """ + @Desc: Test List VM's by Name and State + @Steps: + Step1: Listing all the VMs for a user + Step2: Verifying that the size of the list is 0 + Step3: Deploying a VM + Step4: Listing all the VMs for a user again + Step5: Verifying that list size is increased by 1 + Step6: Listing the VM by specifying name of VM created in step3 and state as Running (matching name and state) + Step7: Verifying that the size of the list is 1 + Step8: Verifying that the details of the listed VM are same as the VM created in step3 + Step9: Listing the VM by specifying name of VM created in step3 and state as Stopped (non matching state) + Step10: Verifying that the size of the list is 0 + Step11: Listing the VM by specifying non matching name and state as Running (non matching name) + Step12: Verifying that the size of the list is 0 + """ + # Listing all the VM's for a User + list_vms_before = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + page=1, + pagesize=self.services["pagesize"], + domainid=self.account.domainid, + ) + self.assertIsNone( + list_vms_before, + "Virtual Machine already exists for newly created user" + ) + # Deploying a VM + vm_created = VirtualMachine.create( + self.userapiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + ) + self.assertIsNotNone( + vm_created, + "VM creation failed" + ) + self.cleanup.append(vm_created) + # Listing all the VM's for a User + list_vms_after = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + page=1, + pagesize=self.services["pagesize"], + domainid=self.account.domainid, + ) + status = validateList(list_vms_after) + self.assertEquals( + PASS, + status[0], + "VM's creation failed" + ) + self.assertEquals( + 1, + len(list_vms_after), + "VM's list count is not matching" + ) + # Listing the VM by matching Name and State + list_running_vm = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + page=1, + pagesize=self.services["pagesize"], + domainid=self.account.domainid, + name=vm_created.name, + state="Running" + ) + status = validateList(list_running_vm) + self.assertEquals( + PASS, + status[0], + "List VM by name and state failed" + ) + # Verifying that the size of the list is 1 + self.assertEquals( + 1, + len(list_running_vm), + "Count of VM list by name and state is not matching" + ) + # Verifying that the details of the listed VM are same as the VM created above + # Creating expected and actual values dictionaries + expected_dict = { + "id":vm_created.id, + "name":vm_created.name, + "displayname":vm_created.displayname, + "state":"Running", + "zoneid":vm_created.zoneid, + "account":vm_created.account, + "template":vm_created.templateid + } + actual_dict = { + "id":list_running_vm[0].id, + "name":list_running_vm[0].name, + "displayname":list_running_vm[0].displayname, + "state":list_running_vm[0].state, + "zoneid":list_running_vm[0].zoneid, + "account":list_running_vm[0].account, + "template":list_running_vm[0].templateid + } + list_vm_status = self.__verify_values( + expected_dict, + actual_dict + ) + self.assertEqual( + True, + list_vm_status, + "Listed VM details are not as expected" + ) + # Listing the VM by matching name and non matching state + list_running_vm = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + page=1, + pagesize=self.services["pagesize"], + domainid=self.account.domainid, + name=vm_created.name, + state="Stopped" + ) + self.assertIsNone( + list_running_vm, + "Listed VM with non matching state" + ) + # Listing the VM by non matching name and matching state + list_running_vm = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + page=1, + pagesize=self.services["pagesize"], + domainid=self.account.domainid, + name="name", + state="Running" + ) + self.assertIsNone( + list_running_vm, + "Listed VM with non matching name" + ) + return + + @attr(tags=["advanced", "basic", "selfservice"]) + def test_08_list_vm_by_zone(self): + """ + @Desc: Test List VM by Zone. + This test case is applicable for a setup having multiple zones. + @Steps: + Step1: Listing all the zones + Step2: Checking if there are multiple zones in the setup. + Continuing below steps only if there are multiple zones + Step3: Listing template for zone + Step4: Listing all the VMs for a user + Step5: Verifying that the size of the list is 0 + Step6: Deploying a VM + Step7: Listing all the VMs for a user again for matching zone + Step8: Verifying that the size of the list is 1 + Step9: Verifying that the details of the Listed VM are same as the VM deployed in Step6 + Step10: Listing all the VMs for a user again for non-matching zone + Step11: Verifying that the size of the list is 0 + """ + # Listing all the zones available + zones_list = Zone.list(self.apiClient) + status = validateList(zones_list) + self.assertEquals( + PASS, + status[0], + "zones not available in the given setup" + ) + current_zone = self.services["virtual_machine"]["zoneid"] + current_template = self.services["virtual_machine"]["template"] + # Checking if there are multiple zones in the setup. + if not len(zones_list) > 1: + self.debug("Setup is not having multiple zones") + else: + # Getting the template available under the zone + template = get_template( + self.apiClient, + zones_list[0].id, + self.services["ostype"] + ) + self.assertIsNotNone( + template, + "Template not found for zone" + ) + self.services["virtual_machine"]["zoneid"] = zones_list[0].id + self.services["virtual_machine"]["template"] = template.id + # Listing all the VM's for a User + list_vms_before = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + page=1, + pagesize=self.services["pagesize"], + domainid=self.account.domainid, + zoneid=zones_list[0].id + ) + self.assertIsNone( + list_vms_before, + "Virtual Machine already exists for newly created user" + ) + # Deploying a VM + vm_created = VirtualMachine.create( + self.userapiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + ) + self.assertIsNotNone( + vm_created, + "VM creation failed" + ) + self.cleanup.append(vm_created) + # Listing all the VMs for a user again for matching zone + list_vms_after = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + page=1, + pagesize=self.services["pagesize"], + domainid=self.account.domainid, + zoneid=zones_list[0].id + ) + status = validateList(list_vms_after) + self.assertEquals( + PASS, + status[0], + "VM creation failed" + ) + # Verifying that the size of the list is 1 + self.assertEquals( + 1, + len(list_vms_after), + "VM list count is not matching" + ) + listed_vm = list_vms_after[0] + # Verifying that the details of the Listed VM are same as the VM deployed above + # Creating expected and actual values dictionaries + expected_dict = { + "id":vm_created.id, + "name":vm_created.name, + "displayname":vm_created.displayname, + "state":vm_created.state, + "zoneid":vm_created.zoneid, + "account":vm_created.account, + "template":vm_created.templateid + } + actual_dict = { + "id":listed_vm.id, + "name":listed_vm.name, + "displayname":listed_vm.displayname, + "state":listed_vm.state, + "zoneid":listed_vm.zoneid, + "account":listed_vm.account, + "template":listed_vm.templateid + } + list_vm_status = self.__verify_values( + expected_dict, + actual_dict + ) + self.assertEqual( + True, + list_vm_status, + "Listed VM by Id details are not as expected" + ) + # Listing all the VMs for a user again for non-matching zone + list_vms = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + page=1, + pagesize=self.services["pagesize"], + domainid=self.account.domainid, + zoneid=zones_list[1].id + ) + self.assertIsNone( + list_vms, + "VM's listed for non matching zone" + ) + self.services["virtual_machine"]["zoneid"] = current_zone + self.services["virtual_machine"]["template"] = current_template + return + + @attr(tags=["advanced", "basic", "selfservice"]) + def test_09_list_vm_by_zone_name(self): + """ + @Desc: Test List VM by Zone. + This test case is applicable for a setup having multiple zones. + @Steps: + Step1: Listing all the zones + Step2: Checking if there are multiple zones in the setup. + Continuing below steps only if there are multiple zones + Step3: Listing template for zone + Step4: Listing all the VMs for a user + Step5: Verifying that the size of the list is 0 + Step6: Deploying a VM + Step7: Listing all the VMs for a user again + Step8: Verifying that list size is increased by 1 + Step9: Listing the VM by specifying name of VM created in step6 and matching zone (matching name and zone) + Step10: Verifying that the size of the list is 1 + Step11: Verifying that the details of the listed VM are same as the VM created in step3 + Step12: Listing the VM by specifying name of VM created in step6 and non matching zone (non matching zone) + Step13: Verifying that the size of the list is 0 + Step14: Listing the VM by specifying non matching name and matching zone (non matching name) + Step15: Verifying that the size of the list is 0 + """ + # Listing all the zones available + zones_list = Zone.list(self.apiClient) + status = validateList(zones_list) + self.assertEquals( + PASS, + status[0], + "zones not available in the given setup" + ) + current_zone = self.services["virtual_machine"]["zoneid"] + current_template = self.services["virtual_machine"]["template"] + # Checking if there are multiple zones in the setup. + if not len(zones_list) > 1: + self.debug("Setup is not having multiple Zones") + else: + # Getting the template available under the zone + template = get_template( + self.apiClient, + zones_list[0].id, + self.services["ostype"] + ) + self.assertIsNotNone( + template, + "Template not found for zone" + ) + self.services["virtual_machine"]["zoneid"] = zones_list[0].id + self.services["virtual_machine"]["template"] = template.id + # Listing all the VM's for a User + list_vms_before = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + page=1, + pagesize=self.services["pagesize"], + domainid=self.account.domainid, + zoneid=zones_list[0].id, + account=self.account.name + ) + self.assertIsNone( + list_vms_before, + "Virtual Machine already exists for newly created user" + ) + # Deploying a VM + vm_created = VirtualMachine.create( + self.userapiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + ) + self.assertIsNotNone( + vm_created, + "VM creation failed" + ) + self.cleanup.append(vm_created) + # Listing all the VMs for a user again for matching zone + list_vms_after = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + page=1, + pagesize=self.services["pagesize"], + domainid=self.account.domainid, + zoneid=zones_list[0].id, + account=self.account.name + ) + status = validateList(list_vms_after) + self.assertEquals( + PASS, + status[0], + "VM creation failed" + ) + # Verifying that the size of the list is 1 + self.assertEquals( + 1, + len(list_vms_after), + "VM list count is not matching" + ) + # Listing the VM by specifying name of VM created in above and matching zone + list_vms = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + page=1, + pagesize=self.services["pagesize"], + domainid=self.account.domainid, + zoneid=zones_list[0].id, + name=vm_created.name + ) + status = validateList(list_vms) + self.assertEquals( + PASS, + status[0], + "Listing VM's by name and zone failed" + ) + # Verifying Verifying that the size of the list is 1 + self.assertEquals( + 1, + len(list_vms), + "Count of listed VM's by name and zone is not as expected" + ) + listed_vm = list_vms[0] + # Verifying that the details of the Listed VM are same as the VM deployed above + # Creating expected and actual values dictionaries + expected_dict = { + "id":vm_created.id, + "name":vm_created.name, + "displayname":vm_created.displayname, + "state":vm_created.state, + "zoneid":vm_created.zoneid, + "account":vm_created.account, + "template":vm_created.templateid + } + actual_dict = { + "id":listed_vm.id, + "name":listed_vm.name, + "displayname":listed_vm.displayname, + "state":listed_vm.state, + "zoneid":listed_vm.zoneid, + "account":listed_vm.account, + "template":listed_vm.templateid + } + list_vm_status = self.__verify_values( + expected_dict, + actual_dict + ) + self.assertEqual( + True, + list_vm_status, + "Listed VM by Id details are not as expected" + ) + # Listing the VM by specifying name of VM created in step3 and non matching zone + list_vms = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + page=1, + pagesize=self.services["pagesize"], + domainid=self.account.domainid, + zoneid=zones_list[1].id, + name=vm_created.name + ) + self.assertIsNone( + list_vms, + "VM's listed for non matching zone" + ) + # Listing the VM by specifying non matching name of VM and matching zone + list_vms = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + page=1, + pagesize=self.services["pagesize"], + domainid=self.account.domainid, + zoneid=zones_list[0].id, + name="name" + ) + self.assertIsNone( + list_vms, + "VM's listed for non matching zone" + ) + self.services["virtual_machine"]["zoneid"] = current_zone + self.services["virtual_machine"]["template"] = current_template + return + + @attr(tags=["advanced", "basic", "selfservice"]) + def test_10_list_vm_by_zone_name_state(self): + """ + @Desc: Test List VM by Zone. + @Steps: + Step1: Listing all the VMs for a user + Step2: Verifying that the size of the list is 0 + Step3: Deploying a VM + Step4: Listing all the VMs for a user again + Step5: Verifying that list size is increased by 1 + Step6: Listing the VM by specifying name of VM created in step3 and matching zone and state as Running + Step7: Verifying that the size of the list is 1 + Step8: Verifying that the details of the listed VM are same as the VM created in step3 + Step9: Listing the VM by specifying name of VM created in step3 and matching zone and state as Stopped + Step10: Verifying that the size of the list is 0 + Step11: Listing the VM by name, Zone and account + Step12: Verifying that the size of the list is 1 + Step13: Verifying that the details of the listed VM are same as the VM created in step3 + """ + # Listing all the VM's for a User + list_vms_before = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + page=1, + pagesize=self.services["pagesize"], + domainid=self.account.domainid, + zoneid=self.zone.id, + account=self.account.name + ) + self.assertIsNone( + list_vms_before, + "Virtual Machine already exists for newly created user" + ) + # Deploying a VM + vm_created = VirtualMachine.create( + self.userapiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + ) + self.assertIsNotNone( + vm_created, + "VM creation failed" + ) + self.cleanup.append(vm_created) + # Listing all the VMs for a user again for matching zone + list_vms_after = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + page=1, + pagesize=self.services["pagesize"], + domainid=self.account.domainid, + zoneid=self.zone.id, + account=self.account.name + ) + status = validateList(list_vms_after) + self.assertEquals( + PASS, + status[0], + "VM creation failed" + ) + # Verifying that the size of the list is 1 + self.assertEquals( + 1, + len(list_vms_after), + "VM list count is not matching" + ) + # Listing the VM by specifying name of VM created in step3 and matching zone and state as Running + list_vms = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + page=1, + pagesize=self.services["pagesize"], + domainid=self.account.domainid, + zoneid=self.zone.id, + name=vm_created.name, + state="Running" + ) + status = validateList(list_vms) + self.assertEquals( + PASS, + status[0], + "Listing VM's by name and zone failed" + ) + # Verifying Verifying that the size of the list is 1 + self.assertEquals( + 1, + len(list_vms), + "Count of listed VM's by name, zone and state is not as expected" + ) + listed_vm = list_vms[0] + # Verifying that the details of the Listed VM are same as the VM deployed above + # Creating expected and actual values dictionaries + expected_dict = { + "id":vm_created.id, + "name":vm_created.name, + "displayname":vm_created.displayname, + "state":vm_created.state, + "zoneid":vm_created.zoneid, + "account":vm_created.account, + "template":vm_created.templateid + } + actual_dict = { + "id":listed_vm.id, + "name":listed_vm.name, + "displayname":listed_vm.displayname, + "state":listed_vm.state, + "zoneid":listed_vm.zoneid, + "account":listed_vm.account, + "template":listed_vm.templateid + } + list_vm_status = self.__verify_values( + expected_dict, + actual_dict + ) + self.assertEqual( + True, + list_vm_status, + "Listed VM by Id details are not as expected" + ) + # Listing the VM by specifying name of VM created in step3, zone and State as Stopped + list_vms = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + page=1, + pagesize=self.services["pagesize"], + domainid=self.account.domainid, + zoneid=self.zone.id, + name=vm_created.name, + state="Stopped" + ) + self.assertIsNone( + list_vms, + "VM's listed for non matching zone" + ) + # Listing the VM by name, zone and account + list_vms = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + page=1, + pagesize=self.services["pagesize"], + domainid=self.account.domainid, + zoneid=self.zone.id, + name=vm_created.name, + account=self.account.name + ) + status = validateList(list_vms) + self.assertEquals( + PASS, + status[0], + "Listing VM's by name, account and zone failed" + ) + # Verifying Verifying that the size of the list is 1 + self.assertEquals( + 1, + len(list_vms), + "Count of listed VM's by name, zone and account is not as expected" + ) + listed_vm = list_vms[0] + # Verifying that the details of the Listed VM are same as the VM deployed above + # Creating expected and actual values dictionaries + expected_dict = { + "id":vm_created.id, + "name":vm_created.name, + "displayname":vm_created.displayname, + "state":vm_created.state, + "zoneid":vm_created.zoneid, + "account":vm_created.account, + "template":vm_created.templateid + } + actual_dict = { + "id":listed_vm.id, + "name":listed_vm.name, + "displayname":listed_vm.displayname, + "state":listed_vm.state, + "zoneid":listed_vm.zoneid, + "account":listed_vm.account, + "template":listed_vm.templateid + } + list_vm_status = self.__verify_values( + expected_dict, + actual_dict + ) + self.assertEqual( + True, + list_vm_status, + "Listed VM by Id details are not as expected" + ) + return + + @attr(tags=["advanced", "basic", "provisioning"]) + def test_11_register_reset_vm_sshkey(self): + """ + @Desc: Test to verify registering and reset of SSH Key for VM + @Steps: + Step1: Deploying a VM + Step2: Stopping the VM deployed in step1 + Step3: Listing all the SSH Key pairs + Step4: Registering a SSH Key pair + Step5: Listing all the SSh Key pairs again + Step6: Verifying that the key pairs list is increased by 1 + Step7: Resetting the VM SSH Key to the key pair registered in step4 + Step8: Verifying that the registered SSH Key pair is set to the VM + """ + # Listing all the VM's for a User + list_vms_before = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + ) + self.assertIsNone( + list_vms_before, + "Virtual Machine already exists for newly created user" + ) + # Deploying a VM + vm_created = VirtualMachine.create( + self.userapiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + ) + self.assertIsNotNone( + vm_created, + "VM creation failed" + ) + self.cleanup.append(vm_created) + # Listing all the VMs for a user again + list_vms_after = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + ) + status = validateList(list_vms_after) + self.assertEquals( + PASS, + status[0], + "VM creation failed" + ) + # Verifying that the size of the list is 1 + self.assertEquals( + 1, + len(list_vms_after), + "VM list count is not matching" + ) + # Stopping the VM deployed above + vm_created.stop( + self.userapiclient, + forced=True + ) + # Listing all the SSH Key pairs + list_keypairs_before = SSHKeyPair.list( + self.userapiclient + ) + list_keypairs_before_size = 0 + if list_keypairs_before is not None: + list_keypairs_before_size = len(list_keypairs_before) + + # Registering new Key pair + new_keypair = SSHKeyPair.register( + self.userapiclient, + name="keypair1", + publickey="ssh-rsa: e6:9a:1e:b5:98:75:88:5d:56:bc:92:7b:43:48:05:b2" + ) + self.assertIsNotNone( + new_keypair, + "New Key pair generation failed" + ) + self.assertEquals( + "keypair1", + new_keypair.name, + "Key Pair not created with given name" + ) + # Listing all the SSH Key pairs again + list_keypairs_after = SSHKeyPair.list( + self.userapiclient + ) + status = validateList(list_keypairs_after) + self.assertEquals( + PASS, + status[0], + "Listing of Key pairs failed" + ) + # Verifying that list size is increased by 1 + self.assertEquals( + list_keypairs_before_size + 1, + len(list_keypairs_after), + "List count is not matching" + ) + # Resetting the VM SSH key to the Key pair created above + vm_created.resetSshKey( + self.userapiclient, + keypair=new_keypair.name + ) + # Listing VM details again + list_vm = VirtualMachine.list( + self.userapiclient, + id=vm_created.id + ) + status = validateList(list_vm) + self.assertEquals( + PASS, + status[0], + "Listing of VM failed" + ) + self.assertEquals( + 1, + len(list_vm), + "VMs list is not as expected" + ) + # Verifying that VM's SSH keypair is set to newly created keypair + self.assertEquals( + new_keypair.name, + list_vm[0].keypair, + "VM is not set to newly created SSH Key pair" + ) + return + + @attr(tags=["advanced", "provisioning"]) + def test_12_vm_nics(self): + """ + @Desc: Test to verify Nics for a VM + @Steps: + Step1: Deploying a VM + Step2: Listing all the Networks + Step3: Verifying that the list size is 1 + Step4: Creating 1 network + Step5: Listing all the networks again + Step6: Verifying that the list size is 2 + Step7: Verifying that VM deployed in step1 has only 1 nic + and it is same as network listed in step3 + Step8: Adding the networks created in step4 to VM deployed in step1 + Step9: Verifying that VM deployed in step1 has 2 nics + Step10: Verifying that isdefault is set to true for only 1 nic + Step11: Verifying that isdefault is set to true for the Network created when deployed a VM + Step12: Making the nic created in step4 as default nic + Step13: Verifying that isdefault is set to true for only 1 nic + Step14: Verifying that the isdefault is set to true for the nic created in step4 + Step15: Removing the non-default nic from VM + Step16: Verifying that VM deployed in step1 has only 1 nic + """ + # Listing all the VM's for a User + list_vms_before = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + ) + self.assertIsNone( + list_vms_before, + "Virtual Machine already exists for newly created user" + ) + # Deploying a VM + vm_created = VirtualMachine.create( + self.userapiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + ) + self.assertIsNotNone( + vm_created, + "VM creation failed" + ) + self.cleanup.append(vm_created) + # Listing all the VMs for a user again + list_vms_after = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + ) + status = validateList(list_vms_after) + self.assertEquals( + PASS, + status[0], + "VM creation failed" + ) + # Verifying that the size of the list is 1 + self.assertEquals( + 1, + len(list_vms_after), + "VM list count is not matching" + ) + # Listing all the networks before + list_network_before = Network.list( + self.userapiclient, + isdefault="true", + zoneid=self.zone.id, + account=self.account.name, + domainid=self.domain.id + ) + status = validateList(list_network_before) + self.assertEquals( + PASS, + status[0], + "Default Network not created when deploying a VM" + ) + # Verifying that only 1 network is created while deploying a VM + self.assertEquals( + 1, + len(list_network_before), + "More than 1 default network exists" + ) + network1 = list_network_before[0] + # Listing Network Offerings + network_offerings_list = NetworkOffering.list( + self.apiClient, + forvpc="false", + guestiptype="Isolated", + state="Enabled", + supportedservices="SourceNat", + zoneid=self.zone.id + ) + self.assertIsNotNone( + network_offerings_list, + "Isolated Network Offerings with sourceNat enabled are not found" + ) + # Creating one more network + network2 = Network.create( + self.userapiclient, + self.services["network"], + accountid=self.account.name, + domainid=self.domain.id, + networkofferingid=network_offerings_list[0].id, + zoneid=self.zone.id + ) + self.assertIsNotNone( + network2, + "Network creation failed" + ) + self.cleanup.append(network2) + # Listing all the networks again + list_network_after = Network.list( + self.userapiclient, + zoneid=self.zone.id, + account=self.account.name, + domainid=self.domain.id + ) + status = validateList(list_network_after) + self.assertEquals( + PASS, + status[0], + "List of Networks failed" + ) + # Verifying that list size is 2 + self.assertEquals( + 2, + len(list_network_after), + "More than 1 default network exists" + ) + # Verifying that VM created is having only 1 nic + vm_nics_before = vm_created.nic + self.assertIsNotNone( + vm_nics_before, + "Nic not found for the VM deployed" + ) + self.assertEquals( + 1, + len(vm_nics_before), + "VM Nic count is not matching" + ) + # Verifying that the nic is same as the default network listed above + self.assertEquals( + network1.id, + vm_nics_before[0].networkid, + "Default NIC for VM is not as expected" + ) + # Adding network2 created above to VM + VirtualMachine.add_nic( + vm_created, + self.userapiclient, + network2.id + ) + # Listing the Vm details again + list_vms_after = VirtualMachine.list( + self.userapiclient, + id=vm_created.id + ) + status = validateList(list_vms_after) + self.assertEquals( + PASS, + status[0], + "Listing of VM failed" + ) + vm = list_vms_after[0] + # Verifying that VM nics size is 2 now + vm_nics_after = vm.nic + self.assertIsNotNone( + vm_nics_after, + "Nic not found for the deployed VM" + ) + self.assertEquals( + 2, + len(vm_nics_after), + "VM NIC's count is not matching" + ) + # Verifying that isdefault is set to true for only 1 nic + default_count = 0 + for i in range(0, len(vm_nics_after)): + if vm_nics_after[i].isdefault is True: + default_count = default_count + 1 + default_nic = vm_nics_after[i] + else: + non_default_nic = vm_nics_after[i] + self.assertEquals( + 1, + default_count, + "Default NIC count is not matching" + ) + # Verifying that default NIC is same the network created when VM is deployed + self.assertEquals( + network1.id, + default_nic.networkid, + "Default NIC is not matching for VM" + ) + # Updating network 2 as default NIC + vm_created.update_default_nic( + self.userapiclient, + non_default_nic.id + ) + # Listing the Vm details again + list_vms_after = VirtualMachine.list( + self.userapiclient, + id=vm_created.id + ) + status = validateList(list_vms_after) + self.assertEquals( + PASS, + status[0], + "Listing of VM failed" + ) + vm = list_vms_after[0] + # Verifying that VM nics size is 2 now + vm_nics_after = vm.nic + self.assertIsNotNone( + vm_nics_after, + "Nic not found for the deployed VM" + ) + self.assertEquals( + 2, + len(vm_nics_after), + "VM NIC's count is not matching" + ) + # Verifying that isdefault is set to true for only 1 nic + default_count = 0 + for i in range(0, len(vm_nics_after)): + if vm_nics_after[i].isdefault is True: + default_count = default_count + 1 + default_nic = vm_nics_after[i] + else: + non_default_nic = vm_nics_after[i] + + self.assertEquals( + 1, + default_count, + "Default NIC count is not matching" + ) + # Verifying that default NIC is same the newly updated network (network 2) + self.assertEquals( + network2.id, + default_nic.networkid, + "Default NIC is not matching for VM" + ) + # Deleting non default NIC + vm_created.remove_nic( + self.userapiclient, + non_default_nic.id + ) + # Listing the Vm details again + list_vms_after = VirtualMachine.list( + self.userapiclient, + id=vm_created.id + ) + status = validateList(list_vms_after) + self.assertEquals( + PASS, + status[0], + "Listing of VM failed" + ) + vm = list_vms_after[0] + # Verifying that VM nics size is 1 now + vm_nics_after = vm.nic + self.assertIsNotNone( + vm_nics_after, + "Nic not found for the deployed VM" + ) + self.assertEquals( + 1, + len(vm_nics_after), + "VM NIC's count is not matching" + ) + # Verifying the nic network is same as the default nic network + self.assertEquals( + network2.id, + vm_nics_after[0].networkid, + "VM NIC is not same as expected" + ) + return + +class TestInstances(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + try: + cls._cleanup = [] + cls.testClient = super(TestInstances, 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()) + cls.template = get_template( + cls.api_client, + cls.zone.id, + cls.services["ostype"] + ) + if cls.zone.localstorageenabled: + cls.storagetype = 'local' + cls.services["service_offerings"]["tiny"]["storagetype"] = 'local' + cls.services["disk_offering"]["storagetype"] = 'local' + else: + cls.storagetype = 'shared' + cls.services["service_offerings"]["tiny"]["storagetype"] = 'shared' + cls.services["disk_offering"]["storagetype"] = 'shared' + + cls.services['mode'] = cls.zone.networktype + cls.services["virtual_machine"]["hypervisor"] = cls.testClient.getHypervisorInfo() + cls.services["virtual_machine"]["zoneid"] = cls.zone.id + cls.services["virtual_machine"]["template"] = cls.template.id + cls.services["custom_volume"]["zoneid"] = cls.zone.id + + # Creating Disk offering, Service Offering and Account + cls.disk_offering = DiskOffering.create( + cls.api_client, + cls.services["disk_offering"] + ) + cls.service_offering = ServiceOffering.create( + cls.api_client, + cls.services["service_offerings"]["tiny"] + ) + cls.account = Account.create( + cls.api_client, + cls.services["account"], + domainid=cls.domain.id + ) + # Getting authentication for user in newly created Account + cls.user = cls.account.user[0] + cls.userapiclient = cls.testClient.getUserApiClient(cls.user.username, cls.domain.name) + # Updating resource Limits + for i in range(0, 12): + Resources.updateLimit( + cls.api_client, + account=cls.account.name, + domainid=cls.domain.id, + max=-1, + resourcetype=i + ) + cls._cleanup.append(cls.account) + cls._cleanup.append(cls.service_offering) + cls._cleanup.append(cls.disk_offering) + except Exception as e: + cls.tearDownClass() + raise Exception("Warning: Exception in setup : %s" % e) + return + + def setUp(self): + + self.apiClient = self.testClient.getApiClient() + self.cleanup = [] + + def tearDown(self): + # Clean up, terminate the created resources + cleanup_resources(self.apiClient, self.cleanup) + return + + @classmethod + def tearDownClass(cls): + try: + cleanup_resources(cls.api_client, cls._cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + + return + + def __verify_values(self, expected_vals, actual_vals): + """ + @Desc: Function to verify expected and actual values + @Steps: + Step1: Initializing return flag to True + Step1: Verifying length of expected and actual dictionaries is matching. + If not matching returning false + Step2: Listing all the keys from expected dictionary + Step3: Looping through each key from step2 and verifying expected and actual dictionaries have same value + If not making return flag to False + Step4: returning the return flag after all the values are verified + """ + return_flag = True + + if len(expected_vals) != len(actual_vals): + return False + + keys = expected_vals.keys() + for i in range(0, len(expected_vals)): + exp_val = expected_vals[keys[i]] + act_val = actual_vals[keys[i]] + if exp_val == act_val: + return_flag = return_flag and True + else: + return_flag = return_flag and False + self.debug("expected Value: %s, is not matching with actual value: %s" % ( + exp_val, + act_val + )) + return return_flag + + @attr(tags=["advanced", "basic", "provisioning"]) + def test_13_attach_detach_iso(self): + """ + @Desc: Test Attach ISO to VM and Detach ISO from VM. + @Steps: + Step1: Listing all the VMs for a user + Step2: Verifying that the size of the list is 0 + Step3: Deploying a VM + Step4: Listing all the VMs for a user again + Step5: Verifying that list size is increased by 1 + Step6: Listing all the ready ISO's + Step7: If size of the list is >= 1 continuing to next steps + Step8: Attaching the ISO listed to VM deployed in Step3 + Step9: Verifying that the attached ISO details are associated with VM + Step10: Detaching the ISO attached in step8 + Step11: Verifying that detached ISO details are not associated with VM + """ + if self.hypervisor.lower() == 'kvm': + raise unittest.SkipTest("VM Snapshot is not supported on KVM. Hence, skipping the test") + # Listing all the VM's for a User + list_vms_before = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + page=1, + pagesize=self.services["pagesize"], + domainid=self.account.domainid, + zoneid=self.zone.id, + account=self.account.name + ) + self.assertIsNone( + list_vms_before, + "Virtual Machine already exists for newly created user" + ) + # Deploying a VM + vm_created = VirtualMachine.create( + self.userapiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + ) + self.assertIsNotNone( + vm_created, + "VM creation failed" + ) + self.cleanup.append(vm_created) + # Listing all the VMs for a user again for matching zone + list_vms_after = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + page=1, + pagesize=self.services["pagesize"], + domainid=self.account.domainid, + zoneid=self.zone.id, + account=self.account.name + ) + status = validateList(list_vms_after) + self.assertEquals( + PASS, + status[0], + "VM creation failed" + ) + # Verifying that the size of the list is 1 + self.assertEquals( + 1, + len(list_vms_after), + "VM list count is not matching" + ) + # Listing the ISO's in ready state + isos_list = Iso.list( + self.userapiclient, + isready="true", + isofilter="executable", + zoneid=self.zone.id + ) + # Verifying if size of the list is >= 1 + if isos_list is not None: + iso_toattach = isos_list[0] + # Attaching ISO listed to VM deployed + VirtualMachine.attach_iso( + vm_created, + self.userapiclient, + iso_toattach + ) + list_vm = VirtualMachine.list( + self.userapiclient, + id=vm_created.id + ) + status = validateList(list_vm) + self.assertEquals( + PASS, + status[0], + "VM listing by Id failed" + ) + # Verifying that attached ISO details are present in VM + self.assertEquals( + iso_toattach.name, + list_vm[0].isoname, + "Attached ISO name is not matching" + ) + self.assertEquals( + iso_toattach.displaytext, + list_vm[0].isodisplaytext, + "Attached ISO display is not matching" + ) + # Detaching ISO from VM + VirtualMachine.detach_iso( + vm_created, + self.userapiclient + ) + list_vm = VirtualMachine.list( + self.userapiclient, + id=vm_created.id + ) + status = validateList(list_vm) + self.assertEquals( + PASS, + status[0], + "VM listing by Id failed" + ) + # Verifying that ISO details are NOT present in VM + self.assertIsNone( + list_vm[0].isoname, + "ISO not detached from VM" + ) + else: + self.fail("Executable ISO in Ready is not found in the given setup") + + return + + @attr(tags=["advanced", "basic", "provisioning"]) + def test_14_vm_snapshot_pagination(self): + """ + @Desc: Test VM Snapshots pagination. + @Steps: + Step1: Deploying a VM + Step2: Listing all the Snapshots of the VM deployed in Step 1 + Step3: Verifying that the list size is 0 + Step4: Creating (pagesize + 1) number of Snapshots for the VM + Step5: Listing all the Snapshots of the VM deployed in Step 1 + Step6: Verifying that the list size is (pagesize + 1) + Step7: Listing all the VM snapshots in Page 1 with page size + Step8: Verifying that size of the list is same as page size + Step9: Listing all the VM snapshots in Page 2 with page size + Step10: Verifying that size of the list is 1 + Step11: Deleting VM snapshot in page 2 + Step12: Listing all the VM snapshots in Page 2 with page size + Step13: Verifying that size of the list is 0 + """ + if self.hypervisor.lower() == 'kvm': + raise unittest.SkipTest("VM Snapshot is not supported on KVM. Hence, skipping the test") + # Listing all the VM's for a User + list_vms_before = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + ) + self.assertIsNone( + list_vms_before, + "Virtual Machine already exists for newly created user" + ) + # Deploying a VM + vm_created = VirtualMachine.create( + self.userapiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + ) + self.assertIsNotNone( + vm_created, + "VM creation failed" + ) + self.cleanup.append(vm_created) + # Listing all the VMs for a user again + list_vms_after = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + ) + status = validateList(list_vms_after) + self.assertEquals( + PASS, + status[0], + "VM creation failed" + ) + # Verifying that the size of the list is 1 + self.assertEquals( + 1, + len(list_vms_after), + "VM list count is not matching" + ) + # Listing all the VM snapshots for VM deployed above + list_snapshots_before = VmSnapshot.list( + self.userapiclient, + listall=self.services["listall"], + virtualmachineid=vm_created.id + ) + # Verifying that the VM snapshot list is None + self.assertIsNone( + list_snapshots_before, + "Snapshots already exists for newly created VM" + ) + # Creating pagesize + 1 number of VM snapshots + for i in range(0, (self.services["pagesize"] + 1)): + snapshot_created = VmSnapshot.create( + self.userapiclient, + vm_created.id, + ) + self.assertIsNotNone( + snapshot_created, + "Snapshot creation failed" + ) + + # Listing all the VM snapshots for VM again + list_snapshots_after = VmSnapshot.list( + self.userapiclient, + listall=self.services["listall"], + virtualmachineid=vm_created.id + ) + status = validateList(list_snapshots_after) + self.assertEquals( + PASS, + status[0], + "VM Snapshots creation failed" + ) + self.assertEquals( + self.services["pagesize"] + 1, + len(list_snapshots_after), + "Count of VM Snapshots is not matching" + ) + # Listing all the VM snapshots in Page 1 with page size + list_snapshots_page1 = VmSnapshot.list( + self.userapiclient, + listall=self.services["listall"], + virtualmachineid=vm_created.id, + page=1, + pagesize=self.services["pagesize"], + ) + status = validateList(list_snapshots_page1) + self.assertEquals( + PASS, + status[0], + "Listing of VM Snapshots failed in page 1" + ) + # Verifying the list size is equal to pagesize + self.assertEquals( + self.services["pagesize"], + len(list_snapshots_page1), + "List VM Snapshot count is not matching in page 1" + ) + # Listing all the VM Snapshots in page 2 + list_snapshots_page2 = VmSnapshot.list( + self.userapiclient, + listall=self.services["listall"], + virtualmachineid=vm_created.id, + page=2, + pagesize=self.services["pagesize"], + ) + status = validateList(list_snapshots_page2) + self.assertEquals( + PASS, + status[0], + "Listing of VM Snapshots failed in page 2" + ) + # Verifying the list size is equal to 1 + self.assertEquals( + 1, + len(list_snapshots_page2), + "List VM Snapshot count is not matching in page 2" + ) + # Deleting VM Snapshot in page 2 + VmSnapshot.deleteVMSnapshot( + self.userapiclient, + snapshot_created.id + ) + # Listing all the VM Snapshots in page 2 again + list_snapshots_page2 = VmSnapshot.list( + self.userapiclient, + listall=self.services["listall"], + virtualmachineid=vm_created.id, + page=2, + pagesize=self.services["pagesize"], + ) + # Verifying the list size is equal to 0 + self.assertIsNone( + list_snapshots_page2, + "VM Snapshots exists in page 2" + ) + return + + @attr(tags=["advanced", "basic", "provisioning"]) + def test_15_revert_vm_to_snapshot(self): + """ + @Desc: Test Revert VM to Snapshot functionality. + @Steps: + Step1: Deploying a VM + Step2: Listing all the Snapshots of the VM deployed in Step 1 + Step3: Verifying that the list size is 0 + Step4: Creating 2 Snapshots for the VM + Step5: Listing all the Snapshots of the VM deployed in Step 1 + Step6: Verifying that the list size is 2 + Step7: Verifying that only 1 snapshot is have current flag set to True + Step8: Verifying that the VM snapshot with current flag set as true is the latest snapshot created + Step9: Reverting VM to snapshot having current flag as false (non current snapshot) + Step10: Verifying that only 1 VM snapshot is having current flag set as true. + Step11: Verifying that the VM Snapshot with current flag set to true is the reverted snapshot in Step 8 + """ + if self.hypervisor.lower() == 'kvm': + raise unittest.SkipTest("VM Snapshot is not supported on KVM. Hence, skipping the test") + # Listing all the VM's for a User + list_vms_before = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + ) + self.assertIsNone( + list_vms_before, + "Virtual Machine already exists for newly created user" + ) + # Deploying a VM + vm_created = VirtualMachine.create( + self.userapiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + ) + self.assertIsNotNone( + vm_created, + "VM creation failed" + ) + self.cleanup.append(vm_created) + # Listing all the VMs for a user again + list_vms_after = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + ) + status = validateList(list_vms_after) + self.assertEquals( + PASS, + status[0], + "VM creation failed" + ) + # Verifying that the size of the list is 1 + self.assertEquals( + 1, + len(list_vms_after), + "VM list count is not matching" + ) + # Listing all the VM snapshots for VM deployed above + list_snapshots_before = VmSnapshot.list( + self.userapiclient, + listall=self.services["listall"], + virtualmachineid=vm_created.id + ) + # Verifying that the VM snapshot list is None + self.assertIsNone( + list_snapshots_before, + "Snapshots already exists for newly created VM" + ) + # Creating 2 of VM snapshots + snapshot1 = VmSnapshot.create( + self.userapiclient, + vm_created.id, + ) + self.assertIsNotNone( + snapshot1, + "Snapshot creation failed" + ) + snapshot2 = VmSnapshot.create( + self.userapiclient, + vm_created.id, + ) + self.assertIsNotNone( + snapshot2, + "Snapshot creation failed" + ) + # Listing all the VM snapshots for VM again + list_snapshots_after = VmSnapshot.list( + self.userapiclient, + listall=self.services["listall"], + virtualmachineid=vm_created.id + ) + status = validateList(list_snapshots_after) + self.assertEquals( + PASS, + status[0], + "VM Snapshots creation failed" + ) + self.assertEquals( + 2, + len(list_snapshots_after), + "Count of VM Snapshots is not matching" + ) + # Verifying that only 1 snapshot is having current flag set to true + # and that snapshot is the latest snapshot created (snapshot2) + current_count = 0 + for i in range(0, len(list_snapshots_after)): + if(list_snapshots_after[i].current is True): + current_count = current_count + 1 + current_snapshot = list_snapshots_after[i] + + self.assertEquals( + 1, + current_count, + "count of VM Snapshot with current flag as true is not matching" + ) + self.assertEquals( + snapshot2.id, + current_snapshot.id, + "Latest snapshot taken is not marked as current" + ) + # Reverting the VM to Snapshot 1 + VmSnapshot.revertToSnapshot( + self.userapiclient, + snapshot1.id + ) + # Listing the VM snapshots again + list_snapshots_after = VmSnapshot.list( + self.userapiclient, + listall=self.services["listall"], + virtualmachineid=vm_created.id + ) + status = validateList(list_snapshots_after) + self.assertEquals( + PASS, + status[0], + "VM Snapshots creation failed" + ) + self.assertEquals( + 2, + len(list_snapshots_after), + "Count of VM Snapshots is not matching" + ) + # Verifying that only 1 snapshot is having current flag set to true + # and that snapshot is snapshot1 + current_count = 0 + for i in range(0, len(list_snapshots_after)): + if(list_snapshots_after[i].current is True): + current_count = current_count + 1 + current_snapshot = list_snapshots_after[i] + self.assertEquals( + 1, + current_count, + "count of VM Snapshot with current flag as true is not matching" + ) + self.assertEquals( + snapshot1.id, + current_snapshot.id, + "Current flag was set properly after reverting the VM to snapshot" + ) + return + + @attr(tags=["advanced", "basic", "selfservice"]) + def test_16_list_vm_volumes_pagination(self): + """ + @Desc: Test to verify pagination of Volumes for a VM + @Steps: + Step1: Deploying a VM + Step2: Listing all the Volumes of the VM deployed in Step 1 + Step3: Verifying that the list size is 1 + Step4: Creating page size number of volumes + Step5: Attaching all the volumes created in step4 to VM deployed in Step1 + Step6: Listing all the Volumes for the VM in step1 + Step7: Verifying that the list size is equal to page size + 1 + Step8: Listing all the volumes of VM in page 1 + Step9: Verifying that the list size is equal to page size + Step10: Listing all the Volumes in Page 2 + Step11: Verifying that the list size is 1 + Step12: Detaching the volume from the VM + Step13: Listing all the Volumes in Page 2 + Step14: Verifying that list size is 0 + """ + # Listing all the VM's for a User + list_vms_before = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + ) + self.assertIsNone( + list_vms_before, + "Virtual Machine already exists for newly created user" + ) + # Deploying a VM + vm_created = VirtualMachine.create( + self.userapiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + ) + self.assertIsNotNone( + vm_created, + "VM creation failed" + ) + self.cleanup.append(vm_created) + # Listing all the VMs for a user again + list_vms_after = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + ) + status = validateList(list_vms_after) + self.assertEquals( + PASS, + status[0], + "VM creation failed" + ) + # Verifying that the size of the list is 1 + self.assertEquals( + 1, + len(list_vms_after), + "VM list count is not matching" + ) + # Listing all the Volumes for the VM deployed + list_volumes_before = Volume.list( + self.userapiclient, + listall=self.services["listall"], + virtualmachineid=vm_created.id + ) + status = validateList(list_volumes_before) + self.assertEquals( + PASS, + status[0], + "Root volume is not created for VM deployed" + ) + # Verifying the size of the list is 1 + self.assertEquals( + 1, + len(list_volumes_before), + "Volumes count is not matching" + ) + # Creating Page size number of volumes + for i in range(0, self.services["pagesize"]): + volume_created = Volume.create( + self.userapiclient, + self.services["volume"], + zoneid=self.zone.id, + diskofferingid=self.disk_offering.id + ) + self.assertIsNotNone( + volume_created, + "Volume is not created" + ) + self.cleanup.append(volume_created) + # Attaching all the volumes created to VM + vm_created.attach_volume( + self.userapiclient, + volume_created + ) + + # List all the volumes for the VM again + list_volumes_after = Volume.list( + self.userapiclient, + listall=self.services["listall"], + virtualmachineid=vm_created.id + ) + status = validateList(list_volumes_after) + self.assertEquals( + PASS, + status[0], + "Volumes are not listed" + ) + # Verifying that size of the list is equal to page size + 1 + self.assertEquals( + self.services["pagesize"] + 1, + len(list_volumes_after), + "VM's volume count is not matching" + ) + # Listing all the volumes for a VM in page 1 + list_volumes_page1 = Volume.list( + self.userapiclient, + listall=self.services["listall"], + virtualmachineid=vm_created.id, + page=1, + pagesize=self.services["pagesize"] + ) + status = validateList(list_volumes_page1) + self.assertEquals( + PASS, + status[0], + "Volumes not listed in page1" + ) + # Verifying that list size is equal to page size + self.assertEquals( + self.services["pagesize"], + len(list_volumes_page1), + "VM's volume count is not matching in page 1" + ) + # Listing all the volumes for a VM in page 2 + list_volumes_page2 = Volume.list( + self.userapiclient, + listall=self.services["listall"], + virtualmachineid=vm_created.id, + page=2, + pagesize=self.services["pagesize"] + ) + status = validateList(list_volumes_page2) + self.assertEquals( + PASS, + status[0], + "Volumes not listed in page2" + ) + # Verifying that list size is equal to 1 + self.assertEquals( + 1, + len(list_volumes_page2), + "VM's volume count is not matching in page 1" + ) + # Detaching 1 volume from VM + vm_created.detach_volume( + self.userapiclient, + volume_created + ) + # Listing all the volumes for a VM in page 2 again + list_volumes_page2 = Volume.list( + self.userapiclient, + listall=self.services["listall"], + virtualmachineid=vm_created.id, + page=2, + pagesize=self.services["pagesize"] + ) + # Verifying that there are no volumes present in page 2 + self.assertIsNone( + list_volumes_page2, + "Volumes listed in page 2" + ) + # Listing all the volumes for a VM again in page 1 + list_volumes_page1 = Volume.list( + self.userapiclient, + listall=self.services["listall"], + virtualmachineid=vm_created.id, + page=1, + pagesize=self.services["pagesize"] + ) + status = validateList(list_volumes_page1) + self.assertEquals( + PASS, + status[0], + "Volumes not listed in page1" + ) + # Verifying that list size is equal to page size + self.assertEquals( + self.services["pagesize"], + len(list_volumes_page1), + "VM's volume count is not matching in page 1" + ) + # Detaching all the volumes attached from VM + for i in range(0, len(list_volumes_page1)): + vm_created.detach_volume( + self.userapiclient, + list_volumes_page1[i] + ) + return + + @attr(tags=["advanced", "basic", "provisioning"]) + def test_17_running_vm_scaleup(self): + """ + @Desc: Test to verify change service for Running VM + @Steps: + Step1: Checking if dynamic scaling of virtual machines is enabled in zone and template. + If yes then continuing. + If not then printing message that scale up is not possible for Running VM + Step2: Deploying a VM + Step3: Listing all the existing service offerings + Step4: If there is a matching Service Offering for scale-up of running VM + use that service offering. If not create one service offering for scale up. + Step5: Perform change service (scale up) the Running VM deployed in step1 + Step6: Verifying that VM's service offerings is changed + """ + if self.hypervisor.lower() == 'kvm': + raise unittest.SkipTest("ScaleVM is not supported on KVM. Hence, skipping the test") + # Checking if Dynamic scaling of VM is supported or not + list_config = Configurations.list( + self.apiClient, + zoneid=self.zone.id, + name="enable.dynamic.scale.vm" + ) + status = validateList(list_config) + self.assertEquals( + PASS, + status[0], + "Listing of configuration failed" + ) + # Checking if dynamic scaling is allowed in Zone and Template + if not ((list_config[0].value is True) and (self.template.isdynamicallyscalable)): + self.debug("Scale up of Running VM is not possible as Zone/Template does not support") + else: + # Listing all the VM's for a User + list_vms_before = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + ) + self.assertIsNone( + list_vms_before, + "Virtual Machine already exists for newly created user" + ) + # Deploying a VM + vm_created = VirtualMachine.create( + self.userapiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + ) + self.assertIsNotNone( + vm_created, + "VM creation failed" + ) + self.cleanup.append(vm_created) + # Listing details of current Service Offering + vm_so_list = ServiceOffering.list( + self.userapiclient, + id=vm_created.serviceofferingid + ) + status = validateList(vm_so_list) + self.assertEquals( + PASS, + status[0], + "Listing of VM Service offering failed" + ) + current_so = vm_so_list[0] + # Listing all the VMs for a user again + list_vms_after = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + ) + status = validateList(list_vms_after) + self.assertEquals( + PASS, + status[0], + "VM creation failed" + ) + # Verifying that the size of the list is 1 + self.assertEquals( + 1, + len(list_vms_after), + "VM list count is not matching" + ) + # Listing all the existing service offerings + service_offerings_list = ServiceOffering.list( + self.userapiclient, + virtualmachineid=vm_created.id + ) + # Verifying if any Service offering available for scale up of VM + so_exists = False + if service_offerings_list is not None: + for i in range(0, len(service_offerings_list)): + if not ((current_so.cpunumber > service_offerings_list[i].cpunumber or\ + current_so.cpuspeed > service_offerings_list[i].cpuspeed or\ + current_so.memory > service_offerings_list[i].memory) or\ + (current_so.cpunumber == service_offerings_list[i].cpunumber and\ + current_so.cpuspeed == service_offerings_list[i].cpuspeed and\ + current_so.memory == service_offerings_list[i].memory)): + if(current_so.storagetype == service_offerings_list[i].storagetype): + so_exists = True + new_so = service_offerings_list[i] + break + # If service offering does not exists, then creating one service offering for scale up + if not so_exists: + self.services["service_offerings"]["small"]["storagetype"] = current_so.storagetype + new_so = ServiceOffering.create( + self.apiClient, + self.services["service_offerings"]["small"] + ) + self.cleanup.append(new_so) + # Scaling up the VM + vm_created.scale_virtualmachine( + self.userapiclient, + new_so.id + ) + # Listing VM details again + list_vms_after = VirtualMachine.list( + self.userapiclient, + id=vm_created.id + ) + status = validateList(list_vms_after) + self.assertEquals( + PASS, + status[0], + "Listing of VM failed" + ) + self.assertEquals( + 1, + len(list_vms_after), + "VMs list is not as expected" + ) + # Verifying that VM's service offerings is changed + self.assertEquals( + new_so.id, + list_vms_after[0].serviceofferingid, + "VM is not containing New Service Offering" + ) + return + + @attr(tags=["advanced", "basic", "provisioning"]) + def test_18_stopped_vm_change_service(self): + """ + @Desc: Test to verify change service for Stopped VM + @Steps: + Step1: Deploying a VM + Step2: Stopping the VM deployed in step1 + Step3: Listing all the existing service offerings + Step4: If there is a matching Service Offering for change service of stopped VM + use that service offering. If not create one service offering for change service. + Step5: Perform change service for the Stopped VM + Step6: Verifying that VM's service offerings is changed + """ + # Listing all the VM's for a User + list_vms_before = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + ) + self.assertIsNone( + list_vms_before, + "Virtual Machine already exists for newly created user" + ) + # Deploying a VM + vm_created = VirtualMachine.create( + self.userapiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + ) + self.assertIsNotNone( + vm_created, + "VM creation failed" + ) + self.cleanup.append(vm_created) + # Listing details of current Service Offering + vm_so_list = ServiceOffering.list( + self.userapiclient, + id=vm_created.serviceofferingid + ) + status = validateList(vm_so_list) + self.assertEquals( + PASS, + status[0], + "Listing of VM Service offering failed" + ) + current_so = vm_so_list[0] + # Listing all the VMs for a user again + list_vms_after = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + ) + status = validateList(list_vms_after) + self.assertEquals( + PASS, + status[0], + "VM creation failed" + ) + # Verifying that the size of the list is 1 + self.assertEquals( + 1, + len(list_vms_after), + "VM list count is not matching" + ) + # Stopping the VM deployed above + vm_created.stop( + self.userapiclient, + forced=True + ) + # Listing all the service offerings + service_offerings_list = ServiceOffering.list( + self.userapiclient, + virtualmachineid=vm_created.id + ) + # Verifying if any Service offering available for change service of VM + so_exists = False + if service_offerings_list is not None: + for i in range(0, len(service_offerings_list)): + if ((current_so.id != service_offerings_list[i].id) and\ + (current_so.storagetype == service_offerings_list[i].storagetype)): + so_exists = True + new_so = service_offerings_list[i] + break + # If service offering does not exists, then creating one service offering for scale up + if not so_exists: + self.services["service_offerings"]["small"]["storagetype"] = current_so.storagetype + new_so = ServiceOffering.create( + self.apiClient, + self.services["service_offerings"]["small"] + ) + self.cleanup.append(new_so) + # Changing service for the VM + vm_created.scale_virtualmachine( + self.userapiclient, + new_so.id + ) + # Listing VM details again + list_vm = VirtualMachine.list( + self.userapiclient, + id=vm_created.id + ) + status = validateList(list_vm) + self.assertEquals( + PASS, + status[0], + "Listing of VM failed" + ) + self.assertEquals( + 1, + len(list_vm), + "VMs list is not as expected" + ) + # Verifying that VM's service offerings is changed + self.assertEquals( + new_so.id, + list_vm[0].serviceofferingid, + "VM is not containing New Service Offering" + ) + return + + @attr(tags=["advanced", "basic", "provisioning"]) + def test_19_create_reset_vm_sshkey(self): + """ + @Desc: Test to verify creation and reset of SSH Key for VM + @Steps: + Step1: Deploying a VM + Step2: Stopping the VM deployed in step1 + Step3: Listing all the SSH Key pairs + Step4: Creating a new SSH Key pair + Step5: Listing all the SSh Key pairs again + Step6: Verifying that the key pairs list is increased by 1 + Step7: Resetting the VM SSH Key to the key pair created in step4 + Step8: Verifying that the new SSH Key pair is set to the VM + """ + # Listing all the VM's for a User + list_vms_before = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + ) + self.assertIsNone( + list_vms_before, + "Virtual Machine already exists for newly created user" + ) + # Deploying a VM + vm_created = VirtualMachine.create( + self.userapiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + ) + self.assertIsNotNone( + vm_created, + "VM creation failed" + ) + self.cleanup.append(vm_created) + # Listing all the VMs for a user again + list_vms_after = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + ) + status = validateList(list_vms_after) + self.assertEquals( + PASS, + status[0], + "VM creation failed" + ) + # Verifying that the size of the list is 1 + self.assertEquals( + 1, + len(list_vms_after), + "VM list count is not matching" + ) + # Stopping the VM deployed above + vm_created.stop( + self.userapiclient, + forced=True + ) + # Listing all the SSH Key pairs + list_keypairs_before = SSHKeyPair.list( + self.userapiclient + ) + list_keypairs_before_size = 0 + if list_keypairs_before is not None: + list_keypairs_before_size = len(list_keypairs_before) + + # Creating a new Key pair + new_keypair = SSHKeyPair.create( + self.userapiclient, + name="keypair1", + account=self.account.name, + domainid=self.domain.id + ) + self.assertIsNotNone( + new_keypair, + "New Key pair generation failed" + ) + self.assertEquals( + "keypair1", + new_keypair.name, + "Key Pair not created with given name" + ) + # Listing all the SSH Key pairs again + list_keypairs_after = SSHKeyPair.list( + self.userapiclient + ) + status = validateList(list_keypairs_after) + self.assertEquals( + PASS, + status[0], + "Listing of Key pairs failed" + ) + # Verifying that list size is increased by 1 + self.assertEquals( + list_keypairs_before_size + 1, + len(list_keypairs_after), + "List count is not matching" + ) + # Resetting the VM SSH key to the Key pair created above + vm_created.resetSshKey( + self.userapiclient, + keypair=new_keypair.name + ) + # Listing VM details again + list_vm = VirtualMachine.list( + self.userapiclient, + id=vm_created.id + ) + status = validateList(list_vm) + self.assertEquals( + PASS, + status[0], + "Listing of VM failed" + ) + self.assertEquals( + 1, + len(list_vm), + "VMs list is not as expected" + ) + # Verifying that VM's SSH keypair is set to newly created keypair + self.assertEquals( + new_keypair.name, + list_vm[0].keypair, + "VM is not set to newly created SSH Key pair" + ) + return + + @attr(tags=["advanced", "basic", "selfservice"]) + def test_20_update_vm_displayname_group(self): + """ + @Desc: Test to verify Update VM details + @Steps: + Step1: List all the VM's for a user + Step2: Deploy a VM with all parameters + Step3: Listing all the VM's again for the user + Step4: Verifying that list size is increased by 1 + Step5: Updating VM details - displayname, group + Step6: Listing the VM deployed in step 2 by ID + Step7: Verifying that displayname, group details of the VM are updated + """ + # Listing all the VM's for a User + list_vms_before = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + ) + self.assertIsNone( + list_vms_before, + "Virtual Machine already exists for newly created user" + ) + self.services["virtual_machine"]["keyboard"] = "us" + # Deploying a VM + vm_created = VirtualMachine.create( + self.userapiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + group="groupName" + ) + self.assertIsNotNone( + vm_created, + "VM creation failed" + ) + self.cleanup.append(vm_created) + # Verifying the displayname and group details for deployed VM + self.assertEquals( + self.services["virtual_machine"]["displayname"], + vm_created.displayname, + "Display name of VM is not as expected" + ) + self.assertEquals( + "groupName", + vm_created.group, + "Group of VM is not as expected" + ) + # Listing all the VMs for a user again + list_vms_after = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + ) + status = validateList(list_vms_after) + self.assertEquals( + PASS, + status[0], + "VM creation failed" + ) + # Verifying that the size of the list is 1 + self.assertEquals( + 1, + len(list_vms_after), + "VM list count is not matching" + ) + # Updating the VM details - displayname and group + vm_created.update( + self.userapiclient, + displayname="DisplayName", + group="Group", + haenable=False + ) + # Listing VM details again + list_vm = VirtualMachine.list( + self.userapiclient, + id=vm_created.id, + ) + status = validateList(list_vm) + self.assertEquals( + PASS, + status[0], + "Listing of VM by Id failed" + ) + self.assertEquals( + 1, + len(list_vm), + "Count of List VM by Id is not matching" + ) + # Verifying that displayname and group details are updated + self.assertEquals( + "DisplayName", + list_vm[0].displayname, + "Displayname of VM is not updated" + ) + self.assertEquals( + "Group", + list_vm[0].group, + "Group of VM is not updated" + ) + return + + @attr(tags=["advanced", "basic", "provisioning"]) + def test_21_restore_vm(self): + """ + @Desc: Test to verify Restore VM + @Steps: + Step1: List all the VM's for a user + Step2: Deploy a VM with all parameters + Step3: Listing all the VM's again for the user + Step4: Verifying that list size is increased by 1 + Step5: Restoring the VM deployed in step2 + Step6: Verifying that restored VM details are same as the VM deployed in step2 + """ + # Listing all the VM's for a User + list_vms_before = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + ) + self.assertIsNone( + list_vms_before, + "Virtual Machine already exists for newly created user" + ) + # Deploying a VM + vm_created = VirtualMachine.create( + self.userapiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + ) + self.assertIsNotNone( + vm_created, + "VM creation failed" + ) + self.cleanup.append(vm_created) + # Listing all the VMs for a user again + list_vms_after = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + ) + status = validateList(list_vms_after) + self.assertEquals( + PASS, + status[0], + "VM creation failed" + ) + # Verifying that the size of the list is 1 + self.assertEquals( + 1, + len(list_vms_after), + "VM list count is not matching" + ) + # Restoring the VM + restored_vm = vm_created.restore(self.userapiclient) + self.assertIsNotNone( + restored_vm, + "VM restore failed" + ) + # Verifying the restored VM details + expected_dict = { + "id":vm_created.id, + "name":vm_created.name, + "displayname":vm_created.displayname, + "state":vm_created.state, + "zoneid":vm_created.zoneid, + "account":vm_created.account, + "template":vm_created.templateid + } + actual_dict = { + "id":restored_vm.id, + "name":restored_vm.name, + "displayname":restored_vm.displayname, + "state":restored_vm.state, + "zoneid":restored_vm.zoneid, + "account":restored_vm.account, + "template":restored_vm.templateid + } + restored_vm_status = self.__verify_values( + expected_dict, + actual_dict + ) + self.assertEqual( + True, + restored_vm_status, + "Restored VM details are not as expected" + ) + return + + @attr(tags=["advanced", "selfservice"]) + def test_22_deploy_vm_multiple_networks(self): + """ + @Desc: Test to verify deploy VM with multiple networks + @Steps: + Step1: List all the networks for user + Step2: If size of list networks is greater than 2 then get all the networks id's + Else create 2 networks and get network id's + Step3: List all the VM's for a user + Step4: Deploy a VM with multiple network id's + Step5: Listing all the VM's again for the user + Step6: Verifying that list size is increased by 1 + Step7: Verify that VM is associated with multiple networks + """ + # Listing all the networks available + networks_list_before = Network.list( + self.userapiclient, + listall=self.services["listall"] + ) + networks_list_size = 0 + if networks_list_before is not None: + networks_list_size = len(networks_list_before) + + # Listing Network Offerings + network_offerings_list = NetworkOffering.list( + self.apiClient, + forvpc="false", + guestiptype="Isolated", + state="Enabled", + supportedservices="SourceNat", + zoneid=self.zone.id + ) + status = validateList(network_offerings_list) + self.assertEquals( + PASS, + status[0], + "Isolated Network Offerings with sourceNat enabled are not found" + ) + while networks_list_size < 2: + # Creating a network + network = Network.create( + self.userapiclient, + self.services["network"], + accountid=self.account.name, + domainid=self.domain.id, + networkofferingid=network_offerings_list[0].id, + zoneid=self.zone.id + ) + self.assertIsNotNone( + network, + "Network creation failed" + ) + self.cleanup.append(network) + networks_list_size = networks_list_size + 1 + + # Listing the networks again + networks_list_after = Network.list( + self.userapiclient, + listall=self.services["listall"] + ) + status = validateList(network_offerings_list) + self.assertEquals( + PASS, + status[0], + "Listing networks failed" + ) + # populating network id's + networkids = networks_list_after[0].id + "," + networks_list_after[1].id + # Listing all the VM's for a User + list_vms_before = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + ) + self.assertIsNone( + list_vms_before, + "Virtual Machine already exists for newly created user" + ) + # Deploying a VM + vm_created = VirtualMachine.create( + self.userapiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + networkids=networkids, + serviceofferingid=self.service_offering.id, + ) + self.assertIsNotNone( + vm_created, + "VM creation failed" + ) + self.cleanup.append(vm_created) + # Listing all the VMs for a user again + list_vms_after = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + ) + status = validateList(list_vms_after) + self.assertEquals( + PASS, + status[0], + "VM creation failed" + ) + # Verifying that the size of the list is 1 + self.assertEquals( + 1, + len(list_vms_after), + "VM list count is not matching" + ) + # Verifying that the NIC's in VM created are same as provided + vm_nics = vm_created.nic + # Verifying that the size of nics is 2 + self.assertEquals( + 2, + len(vm_nics), + "NIC's count in VM created is not matching" + ) + # Verifying that NIC network ID's are as expected + for i in range(0, len(vm_nics)): + if vm_nics[i].isdefault is True: + self.assertEquals( + networks_list_after[0].id, + vm_nics[i].networkid, + "Default NIC is not as expected" + ) + else: + self.assertEquals( + networks_list_after[1].id, + vm_nics[i].networkid, + "Non Default NIC is not as expected" + ) + return + + @attr(tags=["basic", "provisioning"]) + def test_23_deploy_vm_multiple_securitygroups(self): + """ + @Desc: Test to verify deploy VM with multiple Security Groups + @Steps: + Step1: List all the security groups for user + Step2: If size of list security groups is greater than 2 then get all the security groups id's + Else creating 2 security groups and get security groups id's + Step3: List all the VM's for a user + Step4: Deploy a VM with multiple security groups id's + Step5: Listing all the VM's again for the user + Step6: Verifying that list size is increased by 1 + Step7: Verify that VM is associated with multiple security groups + """ + # Listing all the security groups available + security_groups_list = SecurityGroup.list( + self.userapiclient, + listall=self.services["listall"], + domainid=self.domain.id + ) + security_groups_list_size = 0 + if security_groups_list is not None: + security_groups_list_size = len(security_groups_list) + + while security_groups_list_size < 2: + # Creating a security group + security_group = SecurityGroup.create( + self.userapiclient, + self.services["security_group"], + account=self.account.name, + domainid=self.domain.id + ) + self.assertIsNotNone( + security_group, + "Security Group creation failed" + ) + self.cleanup.append(security_group) + security_groups_list_size = security_groups_list_size + 1 + + # Listing the networks again + security_groups_list = SecurityGroup.list( + self.userapiclient, + listall=self.services["listall"], + domainid=self.domain.id + ) + status = validateList(security_groups_list) + self.assertEquals( + PASS, + status[0], + "Listing Security Groups failed" + ) + # populating Security Groups id's + securitygroupids = {security_groups_list[0].id , security_groups_list[1].id} + # Listing all the VM's for a User + list_vms_before = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + ) + self.assertIsNone( + list_vms_before, + "Virtual Machine already exists for newly created user" + ) + # Deploying a VM + vm_created = VirtualMachine.create( + self.userapiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + securitygroupids=securitygroupids, + ) + self.assertIsNotNone( + vm_created, + "VM creation failed" + ) + self.cleanup.append(vm_created) + # Listing all the VMs for a user again + list_vms_after = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + ) + status = validateList(list_vms_after) + self.assertEquals( + PASS, + status[0], + "VM creation failed" + ) + # Verifying that the size of the list is 1 + self.assertEquals( + 1, + len(list_vms_after), + "VM list count is not matching" + ) + # Verifying that the Security Groups's in VM created are same as provided + vm_securitygroups = vm_created.securitygroup + # Verifying that the size of security groups is 2 + self.assertEquals( + 2, + len(vm_securitygroups), + "Security Groups count in VM created is not matching" + ) + # Verifying that Security Group network ID's are as expected + vm_securitygroups_flag = True + for i in range(0, len(vm_securitygroups)): + if ((vm_securitygroups[i].id != security_groups_list[0].id) and\ + (vm_securitygroups[i].id != security_groups_list[1].id)): + vm_securitygroups_flag = False + break + + self.assertEquals( + True, + vm_securitygroups_flag, + "Security Groups in VM are not same as created" + ) + return diff --git a/test/integration/component/test_escalations_ipaddresses.py b/test/integration/component/test_escalations_ipaddresses.py new file mode 100644 index 0000000000..0b31d2edf8 --- /dev/null +++ b/test/integration/component/test_escalations_ipaddresses.py @@ -0,0 +1,4288 @@ +# 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 Local Modules +from marvin.cloudstackTestCase import * +from marvin.cloudstackException import * +from marvin.cloudstackAPI import * +from marvin.sshClient import SshClient +from marvin.lib.utils import * +from marvin.lib.base import * +from marvin.lib.common import * +from marvin.lib.utils import checkVolumeSize +from marvin.codes import SUCCESS +from nose.plugins.attrib import attr +from time import sleep +from ctypes.wintypes import BOOLEAN + +class TestIpAddresses(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + try: + cls._cleanup = [] + cls.testClient = super(TestIpAddresses, 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()) + cls.template = get_template( + cls.api_client, + cls.zone.id, + cls.services["ostype"] + ) + if cls.zone.localstorageenabled: + cls.storagetype = 'local' + cls.services["service_offerings"]["tiny"]["storagetype"] = 'local' + else: + cls.storagetype = 'shared' + cls.services["service_offerings"]["tiny"]["storagetype"] = 'shared' + + cls.services['mode'] = cls.zone.networktype + cls.services["virtual_machine"]["hypervisor"] = cls.testClient.getHypervisorInfo() + cls.services["virtual_machine"]["zoneid"] = cls.zone.id + cls.services["virtual_machine"]["template"] = cls.template.id + cls.service_offering = ServiceOffering.create( + cls.api_client, + cls.services["service_offerings"]["tiny"] + ) + cls._cleanup.append(cls.service_offering) + cls.services['mode'] = cls.zone.networktype + + except Exception as e: + cls.tearDownClass() + raise Exception("Warning: Exception in setup : %s" % e) + return + + def setUp(self): + + self.apiClient = self.testClient.getApiClient() + self.cleanup = [] + self.account = Account.create( + self.apiClient, + self.services["account"], + domainid=self.domain.id + ) + # Getting authentication for user in newly created Account + self.user = self.account.user[0] + self.userapiclient = self.testClient.getUserApiClient(self.user.username, self.domain.name) +# self.cleanup.append(self.account) + + def tearDown(self): + # Clean up, terminate the created volumes + cleanup_resources(self.apiClient, self.cleanup) + return + + @classmethod + def tearDownClass(cls): + try: + cleanup_resources(cls.api_client, cls._cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + + def __verify_values(self, expected_vals, actual_vals): + """ + @summary: Function to verify expected and actual values + Step1: Initializing return flag to True + Step1: Verifying length of expected and actual dictionaries is matching. + If not matching returning false + Step2: Listing all the keys from expected dictionary + Step3: Looping through each key from step2 and verifying expected and actual dictionaries have same value + If not making return flag to False + Step4: returning the return flag after all the values are verified + """ + return_flag = True + + if len(expected_vals) != len(actual_vals): + return False + + keys = expected_vals.keys() + for i in range(0, len(expected_vals)): + exp_val = expected_vals[keys[i]] + act_val = actual_vals[keys[i]] + if exp_val == act_val: + return_flag = return_flag and True + else: + return_flag = return_flag and False + self.debug("expected Value: %s, is not matching with actual value: %s" % ( + exp_val, + act_val + )) + return return_flag + + @attr(tags=["advanced", "provisioning"]) + def test_01_list_ipaddresses_pagination(self): + """ + @summary: Test List IP Addresses pagination + @Steps: + Step1: Creating a network for the user + Step2: Listing all the IP Addresses for a user + Step3: Verifying that no IP Addresses are listed + Step4: Associating (pagesize + 1) number of IP Addresses + Step5: Listing all the IP Addresses again + Step6: Verifying the length of the IP Addresses is (page size + 1) + Step7: Listing all the IP Addresses in page1 + Step8: Verifying that the length of the IP Addresses in page 1 is (page size) + Step9: Listing all the IP Addresses in page2 + Step10: Verifying that the length of the IP Addresses in page 2 is 1 + Step11: Dis-Associating the IP Addresses present in page 2 + Step12: Listing for the IP Addresses on page 2 + Step13: Verifying that no IP Addresses are listed + """ + # Listing all the networks available + networks_list_before = Network.list( + self.userapiclient, + forvpc="false", + domainid=self.domain.id, + account=self.account.name, + ) + self.assertIsNone( + networks_list_before, + "Networks listed for newly created user" + ) + # Listing Network Offerings + network_offerings_list = NetworkOffering.list( + self.apiClient, + forvpc="false", + guestiptype="Isolated", + state="Enabled", + supportedservices="SourceNat", + zoneid=self.zone.id + ) + status = validateList(network_offerings_list) + self.assertEquals( + PASS, + status[0], + "Isolated Network Offerings with sourceNat enabled are not found" + ) + # Creating a network + network = Network.create( + self.userapiclient, + self.services["network"], + accountid=self.account.name, + domainid=self.domain.id, + networkofferingid=network_offerings_list[0].id, + zoneid=self.zone.id + ) + self.assertIsNotNone( + network, + "Network creation failed" + ) + self.cleanup.append(network) + # Listing all the networks available + networks_list_after = Network.list( + self.userapiclient, + forvpc="false", + domainid=self.domain.id, + account=self.account.name, + ) + status = validateList(networks_list_after) + self.assertEquals( + PASS, + status[0], + "Network Creation Failed" + ) + self.assertEquals( + 1, + len(networks_list_after), + "Network creation failed" + ) + # Listing all the IP Addresses for a user + list_ipaddresses_before = PublicIPAddress.list( + self.userapiclient, + listall=self.services["listall"] + ) + self.assertIsNone( + list_ipaddresses_before, + "IP Addresses listed for newly created user" + ) + # Associating (pagesize + 1) number of IP Addresses + for i in range(0, (self.services["pagesize"] + 1)): + ipaddress = PublicIPAddress.create( + self.userapiclient, + services=self.services["network"], + networkid=network.id + ) + self.assertIsNotNone( + ipaddress, + "Failed to Associate IP Address" + ) + + # Listing all the IP Addresses for a user + list_ipaddresses_after = PublicIPAddress.list( + self.userapiclient, + listall=self.services["listall"] + ) + status = validateList(list_ipaddresses_after) + self.assertEquals( + PASS, + status[0], + "IP Addresses Association Failed" + ) + # Verifying the length of the volumes is (page size + 1) + self.assertEqual( + (self.services["pagesize"] + 1), + len(list_ipaddresses_after), + "Number of IP Addresses associated are not matching expected" + ) + # Listing IP Address in page 1 + list_ipaddress_page1 = PublicIPAddress.list( + self.userapiclient, + listall=self.services["listall"], + page=1, + pagesize=self.services["pagesize"] + ) + status = validateList(list_ipaddress_page1) + self.assertEquals( + PASS, + status[0], + "Failed to list IP Addresses in page1" + ) + # Verifying that list size is equals to pagesize + self.assertEquals( + self.services["pagesize"], + len(list_ipaddress_page1), + "Failed to list pagesize number of IP Addresses in page1" + ) + # Listing IP Address in page 2 + list_ipaddress_page2 = PublicIPAddress.list( + self.userapiclient, + listall=self.services["listall"], + page=2, + pagesize=self.services["pagesize"] + ) + status = validateList(list_ipaddress_page2) + self.assertEquals( + PASS, + status[0], + "Failed to list IP Addresses in page2" + ) + # Verifying that List size is equal to 1 + self.assertEquals( + 1, + len(list_ipaddress_page2), + "Failed to list IP Addresses in page2" + ) + # Dis-associating an IP Address + ipaddress.delete(self.userapiclient) + # Listing IP Address in page 2 + list_ipaddress_page2 = PublicIPAddress.list( + self.userapiclient, + listall=self.services["listall"], + page=2, + pagesize=self.services["pagesize"] + ) + # Verifying that no IP Addresses are listed + self.assertIsNone( + list_ipaddress_page2, + "Disassociation of IP Address Failed" + ) + self.cleanup.append(self.account) + return + + @attr(tags=["advanced", "provisioning"]) + def test_02_list_ipaddresses_byid(self): + """ + @summary: Test List IP Addresses details by ID + @Steps: + Step1: Creating a network for the user + Step2: Listing all the IP Addresses for a user + Step3: Verifying that no IP Addresses are listed + Step4: Associating an IP Addresses for Network + Step5: Listing all the IP Addresses again + Step6: Verifying the length of the IP Addresses is 1 + Step7: Listing the IP Addresses by Id + Step8: Verifying that the length of the IP Addresses list is 1 + Step9: Verifying the details of the Listed IP Address + """ + # Listing all the networks available + networks_list_before = Network.list( + self.userapiclient, + forvpc="false", + domainid=self.domain.id, + account=self.account.name, + ) + self.assertIsNone( + networks_list_before, + "Networks listed for newly created user" + ) + # Listing Network Offerings + network_offerings_list = NetworkOffering.list( + self.apiClient, + forvpc="false", + guestiptype="Isolated", + state="Enabled", + supportedservices="SourceNat", + zoneid=self.zone.id + ) + status = validateList(network_offerings_list) + self.assertEquals( + PASS, + status[0], + "Isolated Network Offerings with sourceNat enabled are not found" + ) + # Creating a network + network = Network.create( + self.userapiclient, + self.services["network"], + accountid=self.account.name, + domainid=self.domain.id, + networkofferingid=network_offerings_list[0].id, + zoneid=self.zone.id + ) + self.assertIsNotNone( + network, + "Network creation failed" + ) + self.cleanup.append(network) + # Listing all the networks available + networks_list_after = Network.list( + self.userapiclient, + forvpc="false", + domainid=self.domain.id, + account=self.account.name, + ) + status = validateList(networks_list_after) + self.assertEquals( + PASS, + status[0], + "Network Creation Failed" + ) + self.assertEquals( + 1, + len(networks_list_after), + "Network creation failed" + ) + # Listing the Network By ID + network_list_byid = Network.list( + self.userapiclient, + listall=self.services["listall"], + id=network.id + ) + status = validateList(network_list_byid) + self.assertEquals( + PASS, + status[0], + "Failed to list Network by Id" + ) + self.assertEquals( + 1, + len(network_list_byid), + "Failed to list Network by Id" + ) + # Listing all the IP Addresses for a user + list_ipaddresses_before = PublicIPAddress.list( + self.userapiclient, + listall=self.services["listall"] + ) + self.assertIsNone( + list_ipaddresses_before, + "IP Addresses listed for newly created user" + ) + # Associating an IP Addresses to Network created + associated_ipaddress = PublicIPAddress.create( + self.userapiclient, + services=self.services["network"], + networkid=network_list_byid[0].id + ) + self.assertIsNotNone( + associated_ipaddress, + "Failed to Associate IP Address" + ) + # Listing all the IP Addresses for a user + list_ipaddresses_after = PublicIPAddress.list( + self.userapiclient, + listall=self.services["listall"] + ) + status = validateList(list_ipaddresses_after) + self.assertEquals( + PASS, + status[0], + "IP Addresses Association Failed" + ) + # Verifying the length of the list is 1 + self.assertEqual( + 1, + len(list_ipaddresses_after), + "Number of IP Addresses associated are not matching expected" + ) + # Listing IP Address by id + list_ipaddress_byid = PublicIPAddress.list( + self.userapiclient, + id=associated_ipaddress.ipaddress.id + ) + status = validateList(list_ipaddress_byid) + self.assertEquals( + PASS, + status[0], + "Failed to list IP Addresses by ID" + ) + # Verifying that list size is equals to 1 + self.assertEquals( + 1, + len(list_ipaddress_byid), + "Failed to list IP Addresses by ID" + ) + # Verifying details of the listed IP Address to be same as IP Address created above + # Creating expected and actual values dictionaries + expected_dict = { + "id":associated_ipaddress.ipaddress.id, + "associatednetworkid":associated_ipaddress.ipaddress.associatednetworkid, + "associatednetworkname":associated_ipaddress.ipaddress.associatednetworkname, + "ipaddress":associated_ipaddress.ipaddress.ipaddress, + "issourcenat":associated_ipaddress.ipaddress.issourcenat, + "isstaticnat":associated_ipaddress.ipaddress.isstaticnat, + "networkid":associated_ipaddress.ipaddress.networkid + } + actual_dict = { + "id":list_ipaddress_byid[0].id, + "associatednetworkid":list_ipaddress_byid[0].associatednetworkid, + "associatednetworkname":list_ipaddress_byid[0].associatednetworkname, + "ipaddress":list_ipaddress_byid[0].ipaddress, + "issourcenat":list_ipaddress_byid[0].issourcenat, + "isstaticnat":list_ipaddress_byid[0].isstaticnat, + "networkid":list_ipaddress_byid[0].networkid + } + ipaddress_status = self.__verify_values( + expected_dict, + actual_dict + ) + self.assertEqual( + True, + ipaddress_status, + "Listed IP Address details are not as expected" + ) + self.cleanup.append(self.account) + return + + @attr(tags=["advanced", "provisioning"]) + def test_03_associate_ipaddress_for_vpc(self): + """ + @summary: Test to Associate IP Address for VPC + @Steps: + Step1: Creating a VPC for the user + Step2: Listing all the IP Addresses for a user + Step3: Verifying that 1 IP Addresses is listed + Step4: Associating an IP Addresses for VPC + Step5: Listing all the IP Addresses again + Step6: Verifying the length of the IP Addresses list is 2 + Step7: Listing the IP Addresses by Id + Step8: Verifying that the length of the IP Addresses list is 1 + Step9: Verifying the details of the Listed IP Address + """ + # Listing all the vpc's for a user + list_vpc_before = VPC.list(self.userapiclient) + # Verifying No VPCs are listed + self.assertIsNone( + list_vpc_before, + "VPC's Listed for newly Created User" + ) + # Listing VPC Offerings + list_vpc_offering = VpcOffering.list(self.userapiclient) + status = validateList(list_vpc_offering) + self.assertEquals( + PASS, + status[0], + "list vpc offering is none") + # Creating a vpc + vpc_created = VPC.create( + self.userapiclient, + self.services["vpc"], + list_vpc_offering[0].id, + self.zone.id + ) + self.assertIsNotNone( + vpc_created, + "VPC Creation Failed" + ) + self.cleanup.append(vpc_created) + # Listing the vpc for a user after creating a vpc + list_vpc_after = VPC.list(self.userapiclient) + status = validateList(list_vpc_after) + self.assertEquals( + PASS, + status[0], + "list VPC not as expected" + ) + # Verifying the list vpc size is increased by 1 + self.assertEquals( + 1, + len(list_vpc_after), + "list VPC not equal as expected" + ) + # Listing all the IP Addresses for a user + list_ipaddresses_before = PublicIPAddress.list( + self.userapiclient, + listall=self.services["listall"] + ) + status = validateList(list_ipaddresses_before) + self.assertEquals( + PASS, + status[0], + "Failed to List VPC IP Address" + ) + self.assertEquals( + 1, + len(list_ipaddresses_before), + "Failed to List VPC IP Address" + ) + # Associating an IP Addresses to VPC created + associated_ipaddress = PublicIPAddress.create( + self.userapiclient, + services=self.services["network"], + vpcid=vpc_created.id + ) + self.assertIsNotNone( + associated_ipaddress, + "Failed to Associate IP Address" + ) + # Listing all the IP Addresses for a user + list_ipaddresses_after = PublicIPAddress.list( + self.userapiclient, + listall=self.services["listall"] + ) + status = validateList(list_ipaddresses_after) + self.assertEquals( + PASS, + status[0], + "IP Addresses Association Failed" + ) + # Verifying the length of the list is 1 + self.assertEqual( + len(list_ipaddresses_before) + 1, + len(list_ipaddresses_after), + "Number of IP Addresses associated are not matching expected" + ) + # Listing IP Address by id + list_ipaddress_byid = PublicIPAddress.list( + self.userapiclient, + listall=self.services["listall"], + page=1, + pagesize=self.services["pagesize"], + id=associated_ipaddress.ipaddress.id + ) + status = validateList(list_ipaddress_byid) + self.assertEquals( + PASS, + status[0], + "Failed to list IP Addresses by ID" + ) + # Verifying that list size is equals to 1 + self.assertEquals( + 1, + len(list_ipaddress_byid), + "Failed to list IP Addresses by ID" + ) + # Verifying details of the listed IP Address to be same as IP Address created above + # Creating expected and actual values dictionaries + expected_dict = { + "id":associated_ipaddress.ipaddress.id, + "associatednetworkid":associated_ipaddress.ipaddress.associatednetworkid, + "associatednetworkname":associated_ipaddress.ipaddress.associatednetworkname, + "ipaddress":associated_ipaddress.ipaddress.ipaddress, + "issourcenat":associated_ipaddress.ipaddress.issourcenat, + "isstaticnat":associated_ipaddress.ipaddress.isstaticnat, + "networkid":associated_ipaddress.ipaddress.networkid, + "vpcid":associated_ipaddress.ipaddress.vpcid + } + actual_dict = { + "id":list_ipaddress_byid[0].id, + "associatednetworkid":list_ipaddress_byid[0].associatednetworkid, + "associatednetworkname":list_ipaddress_byid[0].associatednetworkname, + "ipaddress":list_ipaddress_byid[0].ipaddress, + "issourcenat":list_ipaddress_byid[0].issourcenat, + "isstaticnat":list_ipaddress_byid[0].isstaticnat, + "networkid":list_ipaddress_byid[0].networkid, + "vpcid":list_ipaddress_byid[0].vpcid + } + ipaddress_status = self.__verify_values( + expected_dict, + actual_dict + ) + self.assertEqual( + True, + ipaddress_status, + "Listed IP Address details are not as expected" + ) + self.cleanup.append(self.account) + return + + @attr(tags=["advanced", "provisioning"]) + def test_04_create_delete_lbrule_fornonvpc(self): + """ + @summary: Test to list, create and delete Load Balancer Rule for IP Address associated to Non VPC network + @Steps: + Step1: Creating a Network for the user + Step2: Associating an IP Addresses for Network + Step3: Listing Load Balancer Rules for the IP Address associated in Step2 + Step4: Verifying that no Load Balancer Rules are listed + Step5: Creating a Load Balancer Rule for IP Address associated in Step2 + Step6: Listing Load Balancer Rules for the IP Address associated in Step2 + Step7: Verifying 1 Load Balancer Rule is listed + Step8: Deleting the Load Balancer Rule created in Step5 + Step9: Listing Load Balancer Rules for the IP Address associated in Step2 + Step10: Verifying that no Load Balancer Rules are listed + """ + # Listing all the Networks's for a user + list_networks_before = Network.list( + self.userapiclient, + listall=self.services["listall"] + ) + # Verifying No Networks are listed + self.assertIsNone( + list_networks_before, + "Networks listed for newly created User" + ) + # Listing Network Offerings + network_offerings_list = NetworkOffering.list( + self.apiClient, + forvpc="false", + guestiptype="Isolated", + state="Enabled", + supportedservices="SourceNat,Lb", + zoneid=self.zone.id + ) + status = validateList(network_offerings_list) + self.assertEquals( + PASS, + status[0], + "Isolated Network Offerings with sourceNat, Lb enabled are not found" + ) + # Creating a network + network = Network.create( + self.userapiclient, + self.services["network"], + accountid=self.account.name, + domainid=self.domain.id, + networkofferingid=network_offerings_list[0].id, + zoneid=self.zone.id + ) + self.assertIsNotNone( + network, + "Network creation failed" + ) + self.cleanup.append(network) + # Listing all the IP Addresses for a user + list_ipaddresses_before = PublicIPAddress.list( + self.userapiclient, + listall=self.services["listall"] + ) + # Verifying no IP Addresses are listed + self.assertIsNone( + list_ipaddresses_before, + "IP Addresses listed for newly created User" + ) + # Associating an IP Addresses to Network created + associated_ipaddress = PublicIPAddress.create( + self.userapiclient, + services=self.services["network"], + networkid=network.id + ) + self.assertIsNotNone( + associated_ipaddress, + "Failed to Associate IP Address" + ) + # Listing all the IP Addresses for a user + list_ipaddresses_after = PublicIPAddress.list( + self.userapiclient, + listall=self.services["listall"] + ) + status = validateList(list_ipaddresses_after) + self.assertEquals( + PASS, + status[0], + "IP Addresses Association Failed" + ) + # Verifying the length of the list is 1 + self.assertEqual( + 1, + len(list_ipaddresses_after), + "Number of IP Addresses associated are not matching expected" + ) + # Listing Load Balancer Rules for the Ip Address + list_lbrules_before = LoadBalancerRule.list( + self.userapiclient, + listall=self.services["listall"], + publicipid=associated_ipaddress.ipaddress.id + ) + # Verifying no Load Balancer Rules are listed + self.assertIsNone( + list_lbrules_before, + "Load Balancer Rules listed for newly Acquired Ip Address" + ) + self.services["lbrule"]["openfirewall"] = 'false' + # Creating a Load Balancer Rule for Ip Address + lb_rule = LoadBalancerRule.create( + self.userapiclient, + self.services["lbrule"], + ipaddressid=associated_ipaddress.ipaddress.id, + ) + self.assertIsNotNone( + lb_rule, + "Failed to create Load Balancer Rule" + ) + # Verifying details of created Load Balancer Rule + # Creating expected and actual values dictionaries + expected_dict = { + "algorithm":self.services["lbrule"]["alg"], + "privateport":str(self.services["lbrule"]["privateport"]), + "publicport":str(self.services["lbrule"]["publicport"]), + "name":self.services["lbrule"]["name"], + } + actual_dict = { + "algorithm":str(lb_rule.algorithm), + "privateport":str(lb_rule.privateport), + "publicport":str(lb_rule.publicport), + "name":str(lb_rule.name), + } + lbrule_status = self.__verify_values( + expected_dict, + actual_dict + ) + self.assertEqual( + True, + lbrule_status, + "Created Load Balancer Rule details are not as expected" + ) + # Listing Load Balancer Rules for the Ip Address + list_lbrules_after = LoadBalancerRule.list( + self.userapiclient, + listall=self.services["listall"], + publicipid=associated_ipaddress.ipaddress.id + ) + status = validateList(list_lbrules_after) + self.assertEquals( + PASS, + status[0], + "Load Balancer Rule creation Failed" + ) + # Verifying the length of the list is 1 + self.assertEqual( + 1, + len(list_lbrules_after), + "Load Balancer Rule creation Failed" + ) + # Deleting Load Balancer Rule + lb_rule.delete(self.userapiclient) + # Listing Load Balancer Rules for the Ip Address + list_lbrules_after = LoadBalancerRule.list( + self.userapiclient, + listall=self.services["listall"], + publicipid=associated_ipaddress.ipaddress.id + ) + # Verifying no Load Balancer Rules are Listed + self.assertIsNone( + list_lbrules_after, + "Failed to delete Load Balancer Rule" + ) + self.cleanup.append(self.account) + return + + @attr(tags=["advanced", "provisioning"]) + def test_05_create_delete_lbrule_forvpc(self): + """ + @summary: Test to list, create and delete Load Balancer Rule for IP Address associated to VPC + @Steps: + Step1: Creating a VPC for the user + Step2: Creating Network inside VPC + Step3: Associating an IP Addresses for VPC + Step4: Listing Load Balancer Rules for the IP Address associated in Step2 + Step5: Verifying that no Load Balancer Rules are listed + Step6: Creating a Load Balancer Rule for IP Address associated in Step2 + Step7: Listing Load Balancer Rules for the IP Address associated in Step2 + Step8: Verifying 1 Load Balancer Rule is listed + Step9: Deleting the Load Balancer Rule created in Step5 + Step10: Listing Load Balancer Rules for the IP Address associated in Step2 + Step11: Verifying that no Load Balancer Rules are listed + """ + # Listing all the vpc's for a user + list_vpc_before = VPC.list(self.userapiclient) + # Verifying No VPCs are listed + self.assertIsNone( + list_vpc_before, + "VPC's Listed for newly Created User" + ) + # Listing VPC Offerings + list_vpc_offering = VpcOffering.list(self.userapiclient) + status = validateList(list_vpc_offering) + self.assertEquals( + PASS, + status[0], + "list vpc offering is none") + # Creating a vpc + vpc_created = VPC.create( + self.userapiclient, + self.services["vpc"], + list_vpc_offering[0].id, + self.zone.id + ) + self.assertIsNotNone( + vpc_created, + "VPC Creation Failed" + ) + # Listing the vpc for a user after creating a vpc + list_vpc_after = VPC.list(self.userapiclient) + status = validateList(list_vpc_after) + self.assertEquals( + PASS, + status[0], + "list VPC not as expected" + ) + # Verifying the list vpc size is increased by 1 + self.assertEquals( + 1, + len(list_vpc_after), + "list VPC not equal as expected" + ) + # List network offering for vpc = true + network_offering_vpc_true_list = NetworkOffering.list( + self.userapiclient, + forvpc="true", + zoneid=self.zone.id, + supportedServices="Lb", + state="Enabled" + ) + status = validateList(network_offering_vpc_true_list) + self.assertEquals(PASS, status[0], "Default network offering not present for vpc = true with Lb") + # Creating network under VPC + network_created = Network.create( + self.userapiclient, + self.services["ntwk"], + networkofferingid=network_offering_vpc_true_list[0].id, + vpcid=vpc_created.id, + zoneid=self.zone.id, + gateway=self.services["ntwk"]["gateway"], + netmask=self.services["ntwk"]["netmask"] + ) + self.cleanup.append(network_created) + self.assertIsNotNone( + network_created, + "Network is not created" + ) + self.cleanup.append(vpc_created) + # Listing all the IP Addresses for a user + list_ipaddresses_before = PublicIPAddress.list( + self.userapiclient, + listall=self.services["listall"] + ) + status = validateList(list_ipaddresses_before) + self.assertEquals( + PASS, + status[0], + "list IP Addresses not as expected" + ) + # Verifying the list vpc size is increased by 1 + self.assertEquals( + 1, + len(list_ipaddresses_before), + "list IP Addresses not equal as expected" + ) + # Associating an IP Addresses to VPC created + associated_ipaddress = PublicIPAddress.create( + self.userapiclient, + services=self.services["network"], + vpcid=vpc_created.id + ) + self.assertIsNotNone( + associated_ipaddress, + "Failed to Associate IP Address" + ) + # Listing all the IP Addresses for a user + list_ipaddresses_after = PublicIPAddress.list( + self.userapiclient, + listall=self.services["listall"] + ) + status = validateList(list_ipaddresses_after) + self.assertEquals( + PASS, + status[0], + "IP Addresses Association Failed" + ) + # Verifying the length of the list is 1 + self.assertEqual( + len(list_ipaddresses_before) + 1, + len(list_ipaddresses_after), + "Number of IP Addresses associated are not matching expected" + ) + # Listing Load Balancer Rules for the Ip Address + list_lbrules_before = LoadBalancerRule.list( + self.userapiclient, + listall=self.services["listall"], + publicipid=associated_ipaddress.ipaddress.id + ) + # Verifying no Load Balancer Rules are listed + self.assertIsNone( + list_lbrules_before, + "Load Balancer Rules listed for newly Acquired Ip Address" + ) + self.services["lbrule"]["openfirewall"] = 'false' + # Creating a Load Balancer Rule for Ip Address + lb_rule = LoadBalancerRule.create( + self.userapiclient, + self.services["lbrule"], + ipaddressid=associated_ipaddress.ipaddress.id, + networkid=network_created.id + ) + self.assertIsNotNone( + lb_rule, + "Failed to create Load Balancer Rule" + ) + # Verifying details of created Load Balancer Rule + # Creating expected and actual values dictionaries + expected_dict = { + "algorithm":self.services["lbrule"]["alg"], + "privateport":str(self.services["lbrule"]["privateport"]), + "publicport":str(self.services["lbrule"]["publicport"]), + "name":self.services["lbrule"]["name"], + } + actual_dict = { + "algorithm":str(lb_rule.algorithm), + "privateport":str(lb_rule.privateport), + "publicport":str(lb_rule.publicport), + "name":str(lb_rule.name), + } + lbrule_status = self.__verify_values( + expected_dict, + actual_dict + ) + self.assertEqual( + True, + lbrule_status, + "Created Load Balancer Rule details are not as expected" + ) + # Listing Load Balancer Rules for the Ip Address + list_lbrules_after = LoadBalancerRule.list( + self.userapiclient, + listall=self.services["listall"], + publicipid=associated_ipaddress.ipaddress.id, + ) + status = validateList(list_lbrules_after) + self.assertEquals( + PASS, + status[0], + "Load Balancer Rule creation Failed" + ) + # Verifying the length of the list is 1 + self.assertEqual( + 1, + len(list_lbrules_after), + "Load Balancer Rule creation Failed" + ) + # Deleting Load Balancer Rule + lb_rule.delete(self.userapiclient) + # Listing Load Balancer Rules for the Ip Address + list_lbrules_after = LoadBalancerRule.list( + self.userapiclient, + listall=self.services["listall"], + publicipid=associated_ipaddress.ipaddress.id + ) + # Verifying no Load Balancer Rules are Listed + self.assertIsNone( + list_lbrules_after, + "Failed to delete Load Balancer Rule" + ) + self.cleanup.append(self.account) + return + + @attr(tags=["advanced", "provisioning"]) + def test_06_update_lbrule_name(self): + """ + @summary: Test to Update Load Balancer Rule Name for IP Address associated to Non VPC network + @Steps: + Step1: Creating a Network for the user + Step2: Associating an IP Addresses for Network + Step3: Listing Load Balancer Rules for the IP Address associated in Step2 + Step4: Verifying that no Load Balancer Rules are listed + Step5: Creating a Load Balancer Rule for IP Address associated in Step2 + Step6: Listing Load Balancer Rules for the IP Address associated in Step2 + Step7: Verifying 1 Load Balancer Rule is listed + Step8: Updating the Load Balancer Rule created in Step5 + Step9: Verifying that Load Balancer Rule details are updated + """ + # Listing all the Networks's for a user + list_networks_before = Network.list( + self.userapiclient, + listall=self.services["listall"] + ) + # Verifying No Networks are listed + self.assertIsNone( + list_networks_before, + "Networks listed for newly created User" + ) + # Listing Network Offerings + network_offerings_list = NetworkOffering.list( + self.apiClient, + forvpc="false", + guestiptype="Isolated", + state="Enabled", + supportedservices="SourceNat,Lb", + zoneid=self.zone.id + ) + status = validateList(network_offerings_list) + self.assertEquals( + PASS, + status[0], + "Isolated Network Offerings with sourceNat, Lb enabled are not found" + ) + # Creating a network + network = Network.create( + self.userapiclient, + self.services["network"], + accountid=self.account.name, + domainid=self.domain.id, + networkofferingid=network_offerings_list[0].id, + zoneid=self.zone.id + ) + self.assertIsNotNone( + network, + "Network creation failed" + ) + self.cleanup.append(network) + # Listing Networks again + list_networks_after = Network.list( + self.userapiclient, + listall=self.services["listall"] + ) + status = validateList(list_networks_after) + self.assertEquals( + PASS, + status[0], + "Network Creation Failed" + ) + # Verifying network list count is increased by 1 + self.assertEquals( + 1, + len(list_networks_after), + "Network Creation Failed" + ) + # Listing all the IP Addresses for a user + list_ipaddresses_before = PublicIPAddress.list( + self.userapiclient, + listall=self.services["listall"] + ) + # Verifying no IP Addresses are listed + self.assertIsNone( + list_ipaddresses_before, + "IP Addresses listed for newly created User" + ) + # Associating an IP Addresses to Network created + associated_ipaddress = PublicIPAddress.create( + self.userapiclient, + services=self.services["network"], + networkid=network.id + ) + self.assertIsNotNone( + associated_ipaddress, + "Failed to Associate IP Address" + ) + # Listing all the IP Addresses for a user + list_ipaddresses_after = PublicIPAddress.list( + self.userapiclient, + listall=self.services["listall"] + ) + status = validateList(list_ipaddresses_after) + self.assertEquals( + PASS, + status[0], + "IP Addresses Association Failed" + ) + # Verifying the length of the list is 1 + self.assertEqual( + 1, + len(list_ipaddresses_after), + "Number of IP Addresses associated are not matching expected" + ) + # Listing Load Balancer Rules for the Ip Address + list_lbrules_before = LoadBalancerRule.list( + self.userapiclient, + listall=self.services["listall"], + publicipid=associated_ipaddress.ipaddress.id + ) + # Verifying no Load Balancer Rules are listed + self.assertIsNone( + list_lbrules_before, + "Load Balancer Rules listed for newly Acquired Ip Address" + ) + self.services["lbrule"]["openfirewall"] = 'false' + # Creating a Load Balancer Rule for Ip Address + lb_rule = LoadBalancerRule.create( + self.userapiclient, + self.services["lbrule"], + ipaddressid=associated_ipaddress.ipaddress.id, + ) + self.assertIsNotNone( + lb_rule, + "Failed to create Load Balancer Rule" + ) + # Listing Load Balancer Rules for the Ip Address + list_lbrules_after = LoadBalancerRule.list( + self.userapiclient, + listall=self.services["listall"], + publicipid=associated_ipaddress.ipaddress.id + ) + status = validateList(list_lbrules_after) + self.assertEquals( + PASS, + status[0], + "Load Balancer Rule creation Failed" + ) + # Verifying the length of the list is 1 + self.assertEqual( + 1, + len(list_lbrules_after), + "Load Balancer Rule creation Failed" + ) + # Updating Load Balancer Rule Name + updated_lb_rule = LoadBalancerRule.update( + lb_rule, + self.userapiclient, + algorithm="source", + name="NewLBRuleName" + ) + self.assertIsNotNone( + updated_lb_rule, + "Failed to update Load Balancer Rule details" + ) + # Verifying details of the updated Load Balancer Rule + # Creating expected and actual values dictionaries + expected_dict = { + "id":lb_rule.id, + "account":lb_rule.account, + "algorithm":"source", + "domainid":lb_rule.domainid, + "name":"NewLBRuleName", + "networkid":lb_rule.networkid, + "zoneid":lb_rule.zoneid, + "privateport":lb_rule.privateport, + "publicip":lb_rule.publicip, + "publicport":lb_rule.publicport, + } + actual_dict = { + "id":updated_lb_rule.id, + "account":updated_lb_rule.account, + "algorithm":updated_lb_rule.algorithm, + "domainid":updated_lb_rule.domainid, + "name":updated_lb_rule.name, + "networkid":updated_lb_rule.networkid, + "zoneid":updated_lb_rule.zoneid, + "privateport":updated_lb_rule.privateport, + "publicip":updated_lb_rule.publicip, + "publicport":updated_lb_rule.publicport, + } + lbrule_status = self.__verify_values( + expected_dict, + actual_dict + ) + self.assertEqual( + True, + lbrule_status, + "Updated Load Balancer Rule details are not as expected" + ) + self.cleanup.append(self.account) + return + + @attr(tags=["advanced", "provisioning"]) + def test_07_assign_remove_lbrule_toinstance(self): + """ + @summary: Test to Assign and Remove Load Balancer Rule to an Instance + @Steps: + Step1: Creating a Network for the user + Step2: Associating an IP Addresses for Network + Step3: Launching a VM using the network created in Step 1 + Step4: Creating a Load Balancer Rule for IP Address associated in Step2 + Step5: Listing Load Balancer Rule Instances for applied as true + Step6: Verifying no Load balancer rule instances are listed + Step7: Listing Load Balancer Rule Instances for applied as false + Step8: Verifying that list size is 1 + Step9: Assigning the Instance to Load Balancer Rule + Step10: Listing Load Balancer Rule Instances for applied as true + Step11: Verifying list size is 1 + Step12: Listing Load Balancer Rule Instances for applied as false + Step13: Verifying no Load balancer rule instances are listed + Step14: Removing the Load Balancer Rule assigned form Instance + Step15: Listing Load Balancer Rule Instances for applied as true + Step16: Verifying no Load balancer rule instances are listed + Step17: Listing Load Balancer Rule Instances for applied as false + Step18: Verifying that list size is 1 + """ + # Listing all the Networks's for a user + list_networks_before = Network.list( + self.userapiclient, + listall=self.services["listall"] + ) + # Verifying No Networks are listed + self.assertIsNone( + list_networks_before, + "Networks listed for newly created User" + ) + # Listing Network Offerings + network_offerings_list = NetworkOffering.list( + self.apiClient, + forvpc="false", + guestiptype="Isolated", + state="Enabled", + supportedservices="SourceNat,Lb", + zoneid=self.zone.id + ) + status = validateList(network_offerings_list) + self.assertEquals( + PASS, + status[0], + "Isolated Network Offerings with sourceNat, Lb enabled are not found" + ) + # Creating a network + network = Network.create( + self.userapiclient, + self.services["network"], + accountid=self.account.name, + domainid=self.domain.id, + networkofferingid=network_offerings_list[0].id, + zoneid=self.zone.id + ) + self.assertIsNotNone( + network, + "Network creation failed" + ) + # Listing all the IP Addresses for a user + list_ipaddresses_before = PublicIPAddress.list( + self.userapiclient, + listall=self.services["listall"] + ) + # Verifying no IP Addresses are listed + self.assertIsNone( + list_ipaddresses_before, + "IP Addresses listed for newly created User" + ) + # Associating an IP Addresses to Network created + associated_ipaddress = PublicIPAddress.create( + self.userapiclient, + services=self.services["network"], + networkid=network.id + ) + self.assertIsNotNone( + associated_ipaddress, + "Failed to Associate IP Address" + ) + # Listing all the IP Addresses for a user + list_ipaddresses_after = PublicIPAddress.list( + self.userapiclient, + listall=self.services["listall"] + ) + status = validateList(list_ipaddresses_after) + self.assertEquals( + PASS, + status[0], + "IP Addresses Association Failed" + ) + # Verifying the length of the list is 1 + self.assertEqual( + 1, + len(list_ipaddresses_after), + "Number of IP Addresses associated are not matching expected" + ) + # Launching a Virtual Machine with above created Network + vm_created = VirtualMachine.create( + self.userapiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + networkids=network.id, + serviceofferingid=self.service_offering.id, + ) + self.assertIsNotNone( + vm_created, + "Failed to launch a VM under network created" + ) + self.cleanup.append(network) + # Listing Virtual Machines in Running state in the network created above + list_vms_running = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + account=self.account.name, + domainid=self.domain.id, + state="Running", + networkid=network.id + ) + status = validateList(list_vms_running) + self.assertEquals( + PASS, + status[0], + "VM Created is not in Running state" + ) + # Verifying the length of the list is 1 + self.assertEqual( + 1, + len(list_vms_running), + "VM Created is not in Running state" + ) + self.assertEquals( + vm_created.id, + list_vms_running[0].id, + "VM Created is not in Running state" + ) + # Listing Virtual Machines in Stopped state in the network created above + list_vms_stopped = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + account=self.account.name, + domainid=self.domain.id, + state="Stopped", + networkid=network.id + ) + # Verifying that no vms are listed + self.assertIsNone( + list_vms_stopped, + "Created VM is in Stopped state" + ) + # Listing Load Balancer Rules for the Ip Address + list_lbrules_before = LoadBalancerRule.list( + self.userapiclient, + listall=self.services["listall"], + publicipid=associated_ipaddress.ipaddress.id + ) + # Verifying no Load Balancer Rules are listed + self.assertIsNone( + list_lbrules_before, + "Load Balancer Rules listed for newly Acquired Ip Address" + ) + self.services["lbrule"]["openfirewall"] = 'false' + # Creating a Load Balancer Rule for Ip Address + lb_rule = LoadBalancerRule.create( + self.userapiclient, + self.services["lbrule"], + ipaddressid=associated_ipaddress.ipaddress.id, + ) + self.assertIsNotNone( + lb_rule, + "Failed to create Load Balancer Rule" + ) + # Listing Load Balancer Rules for the Ip Address + list_lbrules_after = LoadBalancerRule.list( + self.userapiclient, + listall=self.services["listall"], + publicipid=associated_ipaddress.ipaddress.id + ) + status = validateList(list_lbrules_after) + self.assertEquals( + PASS, + status[0], + "Load Balancer Rule creation Failed" + ) + # Verifying the length of the list is 1 + self.assertEqual( + 1, + len(list_lbrules_after), + "Load Balancer Rule creation Failed" + ) + # Listing Load Balancer Rule Instances for applied as true + list_lbruleinstance_applied_true = LoadBalancerRule.listLoadBalancerRuleInstances( + self.userapiclient, + id=lb_rule.id, + applied="true" + ) + # Verifying No Instances are assigned to the Load Balancer Rule + self.assertIsNone( + list_lbruleinstance_applied_true, + "Instances are assigned to Newly created Load Balancer Rule" + ) + # Listing Load Balancer Rule Instances for applied as false + list_lbruleinstance_applied_false = LoadBalancerRule.listLoadBalancerRuleInstances( + self.userapiclient, + id=lb_rule.id, + applied="false" + ) + status = validateList(list_lbruleinstance_applied_false) + self.assertEquals( + PASS, + status[0], + "No Instances are available to assign to Load Balancer Rule" + ) + # Verifying the length of the list is 1 + self.assertEqual( + 1, + len(list_lbruleinstance_applied_false), + "No Instances are available to assign to Load Balancer Rule" + ) + # Verifying that Instance created above is listed + self.assertEquals( + vm_created.id, + list_lbruleinstance_applied_false[0].id, + "Failed to list Instance available to asign a Load Balancer Rule" + ) + # Assigning Instance created to Load Balancer Rule + LoadBalancerRule.assign( + lb_rule, + self.userapiclient, + vms=[vm_created] + ) + # Listing Load Balancer Rule Instances for applied as true + list_lbruleinstance_applied_true = LoadBalancerRule.listLoadBalancerRuleInstances( + self.userapiclient, + id=lb_rule.id, + applied="true" + ) + status = validateList(list_lbruleinstance_applied_false) + self.assertEquals( + PASS, + status[0], + "No Instances are available to assign to Load Balancer Rule" + ) + # Verifying the length of the list is 1 + self.assertEqual( + 1, + len(list_lbruleinstance_applied_false), + "No Instances are available to assign to Load Balancer Rule" + ) + # Verifying Instances is assigned to the Load Balancer Rule + self.assertEquals( + vm_created.id, + list_lbruleinstance_applied_true[0].id, + "Failed to assign Load Balancer Rule to given Instance" + ) + # Listing Load Balancer Rule Instances for applied as false + list_lbruleinstance_applied_false = LoadBalancerRule.listLoadBalancerRuleInstances( + self.userapiclient, + id=lb_rule.id, + applied="false" + ) + # Verifying No Load Balancer Rules Instances are available to assign + self.assertIsNone( + list_lbruleinstance_applied_false, + "Instances are available for assigning a Load Balancer Rule" + ) + # Removing Load balancer Rule from Instance + LoadBalancerRule.remove( + lb_rule, + self.userapiclient, + vms=[vm_created] + ) + # Listing Load Balancer Rule Instances for applied as true + list_lbruleinstance_applied_true = LoadBalancerRule.listLoadBalancerRuleInstances( + self.userapiclient, + id=lb_rule.id, + applied="true" + ) + # Verifying that there are no Instances assigned to the Load Balancer Rule + self.assertIsNone( + list_lbruleinstance_applied_true, + "Instances is assigned to Load balancer Rule" + ) + # Listing Load Balancer Rule Instances for applied as false + list_lbruleinstance_applied_false = LoadBalancerRule.listLoadBalancerRuleInstances( + self.userapiclient, + id=lb_rule.id, + applied="false" + ) + status = validateList(list_lbruleinstance_applied_false) + self.assertEquals( + PASS, + status[0], + "No Instances are available to assign to Load Balancer Rule" + ) + # Verifying the length of the list is 1 + self.assertEqual( + 1, + len(list_lbruleinstance_applied_false), + "No Instances are available to assign to Load Balancer Rule" + ) + # Verifying that Instance created above is listed + self.assertEquals( + vm_created.id, + list_lbruleinstance_applied_false[0].id, + "Failed to list Instance available to asign a Load Balancer Rule" + ) + # Destroying the VM Launched + vm_created.delete(self.userapiclient) + vm_created.expung(self.apiClient) + self.cleanup.append(self.account) + return + + @attr(tags=["advanced", "provisioning"]) + def test_08_list_create_delete_lbsticky_policy(self): + """ + @summary: Test to List, Create, Delete Load Balancer Stickyness Policy + @Steps: + Step1: Creating a Network for the user + Step2: Associating an IP Addresses for Network + Step3: Creating a Load Balancer Rule for IP Address associated in Step2 + Step4: Listing Load Balancer Sticky Policies for LB Rule created in Step3 + Step5: Verifying that no Load Balancer Sticky Policies are listed + Step6: Creating a Load Balancer Sticky Policies for LB Rule created in Step3 + Step7: Listing Load Balancer Sticky Policies for LB Rule created in Step3 + Step8: Verifying 1 Load Balancer Sticky Policy is listed + Step9: Deleting the Load Balancer Sticky Policies + Step10: Listing Load Balancer Sticky Policies for LB Rule created in Step3 + Step11: Verifying that no Load Balancer Sticky Policies are listed + """ + # Listing all the Networks's for a user + list_networks_before = Network.list( + self.userapiclient, + listall=self.services["listall"] + ) + # Verifying No Networks are listed + self.assertIsNone( + list_networks_before, + "Networks listed for newly created User" + ) + # Listing Network Offerings + network_offerings_list = NetworkOffering.list( + self.apiClient, + forvpc="false", + guestiptype="Isolated", + state="Enabled", + supportedservices="SourceNat,Lb", + zoneid=self.zone.id + ) + status = validateList(network_offerings_list) + self.assertEquals( + PASS, + status[0], + "Isolated Network Offerings with sourceNat, Lb enabled are not found" + ) + # Creating a network + network = Network.create( + self.userapiclient, + self.services["network"], + accountid=self.account.name, + domainid=self.domain.id, + networkofferingid=network_offerings_list[0].id, + zoneid=self.zone.id + ) + self.assertIsNotNone( + network, + "Network creation failed" + ) + self.cleanup.append(network) + # Listing Networks again + list_networks_after = Network.list( + self.userapiclient, + listall=self.services["listall"] + ) + status = validateList(list_networks_after) + self.assertEquals( + PASS, + status[0], + "Network Creation Failed" + ) + # Verifying network list count is increased by 1 + self.assertEquals( + 1, + len(list_networks_after), + "Network Creation Failed" + ) + # Listing all the IP Addresses for a user + list_ipaddresses_before = PublicIPAddress.list( + self.userapiclient, + listall=self.services["listall"] + ) + # Verifying no IP Addresses are listed + self.assertIsNone( + list_ipaddresses_before, + "IP Addresses listed for newly created User" + ) + # Associating an IP Addresses to Network created + associated_ipaddress = PublicIPAddress.create( + self.userapiclient, + services=self.services["network"], + networkid=network.id + ) + self.assertIsNotNone( + associated_ipaddress, + "Failed to Associate IP Address" + ) + # Listing all the IP Addresses for a user + list_ipaddresses_after = PublicIPAddress.list( + self.userapiclient, + listall=self.services["listall"] + ) + status = validateList(list_ipaddresses_after) + self.assertEquals( + PASS, + status[0], + "IP Addresses Association Failed" + ) + # Verifying the length of the list is 1 + self.assertEqual( + 1, + len(list_ipaddresses_after), + "Number of IP Addresses associated are not matching expected" + ) + # Listing Load Balancer Rules for the Ip Address + list_lbrules_before = LoadBalancerRule.list( + self.userapiclient, + listall=self.services["listall"], + publicipid=associated_ipaddress.ipaddress.id + ) + # Verifying no Load Balancer Rules are listed + self.assertIsNone( + list_lbrules_before, + "Load Balancer Rules listed for newly Acquired Ip Address" + ) + self.services["lbrule"]["openfirewall"] = 'false' + # Creating a Load Balancer Rule for Ip Address + lb_rule = LoadBalancerRule.create( + self.userapiclient, + self.services["lbrule"], + ipaddressid=associated_ipaddress.ipaddress.id, + ) + self.assertIsNotNone( + lb_rule, + "Failed to create Load Balancer Rule" + ) + # Listing Load Balancer Rules for the Ip Address + list_lbrules_after = LoadBalancerRule.list( + self.userapiclient, + listall=self.services["listall"], + publicipid=associated_ipaddress.ipaddress.id + ) + status = validateList(list_lbrules_after) + self.assertEquals( + PASS, + status[0], + "Load Balancer Rule creation Failed" + ) + # Verifying the length of the list is 1 + self.assertEqual( + 1, + len(list_lbrules_after), + "Load Balancer Rule creation Failed" + ) + # Listing Load Balancer Stickyness Policies for LB Rule + list_lbstickypolicy_before = LoadBalancerRule.listStickyPolicies( + self.userapiclient, + lbruleid=lb_rule.id, + listall=self.services["listall"] + ) + # Verifying no Sticky Policies are listed + self.assertEquals( + 0, + len(list_lbstickypolicy_before[0].stickinesspolicy), + "Sticky Policy listed for newly created Load Balancer Rule" + ) + # Creating a Sticy Policy for Load Balancer Rule + sticky_policy = LoadBalancerRule.createSticky( + lb_rule, + self.userapiclient, + methodname='LbCookie', + name='LbCookieSticky' + ) + self.assertIsNotNone( + sticky_policy, + "Failed to create Sticky Policy for Load Balancer Rule" + ) + # Verifying details of Sticky Policy created + # Creating expected and actual values dictionaries + expected_dict = { + "account":self.account.name, + "domainid":self.domain.id, + "lbruleid":lb_rule.id, + "methodname":"LbCookie", + "name":"LbCookieSticky", + } + actual_dict = { + "account":sticky_policy.account, + "domainid":sticky_policy.domainid, + "lbruleid":sticky_policy.lbruleid, + "methodname":sticky_policy.stickinesspolicy[0].methodname, + "name":sticky_policy.stickinesspolicy[0].name, + } + lbstickypolicy_status = self.__verify_values( + expected_dict, + actual_dict + ) + self.assertEqual( + True, + lbstickypolicy_status, + "Created Load Balancer Sticky Policy details are not as expected" + ) + # Listing Load Balancer Stickyness Policies for LB Rule + list_lbstickypolicy_after = LoadBalancerRule.listStickyPolicies( + self.userapiclient, + lbruleid=lb_rule.id, + listall=self.services["listall"] + ) + status = validateList(list_lbstickypolicy_after[0].stickinesspolicy) + self.assertEquals( + PASS, + status[0], + "Load Balancer Sticky Policy creation Failed" + ) + # Verifying the length of the list is 1 + self.assertEqual( + 1, + len(list_lbstickypolicy_after[0].stickinesspolicy), + "Load Balancer Sticky Policy creation Failed" + ) + # Deleting the Sticky Policy + deleted = LoadBalancerRule.deleteSticky( + lb_rule, + self.userapiclient, + id=sticky_policy.stickinesspolicy[0].id + ) + # Listing Load Balancer Stickyness Policies for LB Rule + list_lbstickypolicy_after = LoadBalancerRule.listStickyPolicies( + self.userapiclient, + lbruleid=lb_rule.id, + listall=self.services["listall"] + ) + # Verifying no Sticky Policies are listed + self.assertEquals( + 0, + len(list_lbstickypolicy_after[0].stickinesspolicy), + "Sticky Policy listed for newly created Load Balancer Rule" + ) + self.cleanup.append(self.account) + return + + @attr(tags=["advanced", "provisioning"]) + def test_09_create_delete_portforwarding_fornonvpc(self): + """ + @summary: Test to list, create and delete Port Forwarding for IP Address associated to Non VPC network + @Steps: + Step1: Creating a Network for the user + Step2: Associating an IP Addresses for Network + Step3: Launching Virtual Machine in network created in step 2 + Step4: Listing Port Forwarding Rules for the IP Address associated in Step2 + Step5: Verifying that no Port Forwarding Rules are listed + Step6: Creating a Port Forwarding Rule for IP Address associated in Step2 + Step7: Listing Port Forwarding Rules for the IP Address associated in Step2 + Step8: Verifying 1 Port Forwarding Rule is listed + Step9: Deleting the Port Forwarding Rule created in Step6 + Step10: Listing Port Forwarding Rules for the IP Address associated in Step2 + Step11: Verifying that no Port Forwarding Rules are listed + """ + # Listing all the Networks's for a user + list_networks_before = Network.list( + self.userapiclient, + listall=self.services["listall"] + ) + # Verifying No Networks are listed + self.assertIsNone( + list_networks_before, + "Networks listed for newly created User" + ) + # Listing Network Offerings + network_offerings_list = NetworkOffering.list( + self.apiClient, + forvpc="false", + guestiptype="Isolated", + state="Enabled", + supportedservices="SourceNat,PortForwarding", + zoneid=self.zone.id + ) + status = validateList(network_offerings_list) + self.assertEquals( + PASS, + status[0], + "Isolated Network Offerings with sourceNat, PortForwarding enabled are not found" + ) + # Creating a network + network = Network.create( + self.userapiclient, + self.services["network"], + accountid=self.account.name, + domainid=self.domain.id, + networkofferingid=network_offerings_list[0].id, + zoneid=self.zone.id + ) + self.assertIsNotNone( + network, + "Network creation failed" + ) + # Listing all the IP Addresses for a user + list_ipaddresses_before = PublicIPAddress.list( + self.userapiclient, + listall=self.services["listall"] + ) + # Verifying no IP Addresses are listed + self.assertIsNone( + list_ipaddresses_before, + "IP Addresses listed for newly created User" + ) + # Associating an IP Addresses to Network created + associated_ipaddress = PublicIPAddress.create( + self.userapiclient, + services=self.services["network"], + networkid=network.id + ) + self.assertIsNotNone( + associated_ipaddress, + "Failed to Associate IP Address" + ) + # Listing all the IP Addresses for a user + list_ipaddresses_after = PublicIPAddress.list( + self.userapiclient, + listall=self.services["listall"] + ) + status = validateList(list_ipaddresses_after) + self.assertEquals( + PASS, + status[0], + "IP Addresses Association Failed" + ) + # Verifying the length of the list is 1 + self.assertEqual( + 1, + len(list_ipaddresses_after), + "Number of IP Addresses associated are not matching expected" + ) + # Launching a Virtual Machine with above created Network + vm_created = VirtualMachine.create( + self.userapiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + networkids=network.id, + serviceofferingid=self.service_offering.id, + ) + self.assertIsNotNone( + vm_created, + "Failed to launch a VM under network created" + ) + self.cleanup.append(network) + # Listing Virtual Machines in running state in above created network + list_vms_running = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + state="Running", + networkid=network.id + ) + status = validateList(list_vms_running) + self.assertEquals( + PASS, + status[0], + "VM Created is not in Running state" + ) + # Verifying the length of the list is 1 + self.assertEqual( + 1, + len(list_ipaddresses_after), + "VM Created is not in Runnning state" + ) + self.assertEquals( + vm_created.id, + list_vms_running[0].id, + "VM Created is not in Runnning state" + ) + # Listing Virtual Machines in stopped state in above created network + list_vms_stopped = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + state="Stopped", + networkid=network.id + ) + # Verifying no VMs are in stopped state + self.assertIsNone( + list_vms_stopped, + "VM Created is in stopped state" + ) + # Listing Port Forwarding Rules for the IP Address associated + list_prtfwdrule_before = NATRule.list( + self.userapiclient, + listall=self.services["listall"], + ipaddressid=associated_ipaddress.ipaddress.id + ) + # Verifying no port forwarding rules are listed + self.assertIsNone( + list_prtfwdrule_before, + "Port Forwarding Rules listed for newly associated IP Address" + ) + # Creating a Port Forwarding rule + portfwd_rule = NATRule.create( + self.userapiclient, + virtual_machine=vm_created, + services=self.services["natrule"], + ipaddressid=associated_ipaddress.ipaddress.id, + ) + self.assertIsNotNone( + portfwd_rule, + "Failed to create Port Forwarding Rule" + ) + # Verifying details of Sticky Policy created + # Creating expected and actual values dictionaries + expected_dict = { + "ipaddressid":associated_ipaddress.ipaddress.id, + "privateport":str(self.services["natrule"]["privateport"]), + "publicport":str(self.services["natrule"]["publicport"]), + "protocol":str(self.services["natrule"]["protocol"]).lower(), + } + actual_dict = { + "ipaddressid":portfwd_rule.ipaddressid, + "privateport":str(portfwd_rule.privateport), + "publicport":str(portfwd_rule.publicport), + "protocol":portfwd_rule.protocol, + } + portfwd_status = self.__verify_values( + expected_dict, + actual_dict + ) + self.assertEqual( + True, + portfwd_status, + "Created Port Forward Rule details are not as expected" + ) + # Listing Port Forwarding Rules for the IP Address associated + list_prtfwdrule_after = NATRule.list( + self.userapiclient, + listall=self.services["listall"], + ipaddressid=associated_ipaddress.ipaddress.id + ) + status = validateList(list_prtfwdrule_after) + self.assertEquals( + PASS, + status[0], + "Failed to create Port Forwarding Rule" + ) + # Verifying the length of the list is 1 + self.assertEqual( + 1, + len(list_prtfwdrule_after), + "Failed to create Port Forwarding Rule" + ) + # Deleting Port Forwarding Rule + portfwd_rule.delete(self.userapiclient) + # # Listing Port Forwarding Rules for the IP Address associated + list_prtfwdrule_after = NATRule.list( + self.userapiclient, + listall=self.services["listall"], + ipaddressid=associated_ipaddress.ipaddress.id + ) + # Verifying no port forwarding rules are listed + self.assertIsNone( + list_prtfwdrule_after, + "Port Forwarding Rules listed after deletion" + ) + # Destroying the VM Launched + vm_created.delete(self.userapiclient) + vm_created.expung(self.apiClient) + self.cleanup.append(self.account) + return + + @attr(tags=["advanced", "provisioning"]) + def test_10_create_delete_portforwarding_forvpc(self): + """ + @summary: Test to list, create and delete Port Forwarding Rule for IP Address associated to VPC + @Steps: + Step1: Creating a VPC for the user + Step2: Creating Network inside VPC + Step3: Associating an IP Addresses for VPC + Step4: Launching a VM in the Network created in Step 2 + Step5: Listing Port Forwarding Rules for the IP Address associated in Step3 + Step6: Verifying that no Port Forwarding Rules are listed + Step7: Creating a Port Forwarding Rule for IP Address associated in Step3 + Step8: Listing Port Forwarding Rules for the IP Address associated in Step3 + Step9: Verifying 1 Port Forwarding Rule is listed + Step10: Deleting the Port Forwarding Rule created in Step7 + Step11: Listing Port Forwarding Rules for the IP Address associated in Step3 + Step12: Verifying that no Port Forwarding Rules are listed + """ + # Listing all the vpc's for a user + list_vpc_before = VPC.list(self.userapiclient) + # Verifying No VPCs are listed + self.assertIsNone( + list_vpc_before, + "VPC's Listed for newly Created User" + ) + # Listing VPC Offerings + list_vpc_offering = VpcOffering.list(self.userapiclient) + status = validateList(list_vpc_offering) + self.assertEquals( + PASS, + status[0], + "list vpc offering is none" + ) + # Creating a vpc + vpc_created = VPC.create( + self.userapiclient, + self.services["vpc"], + list_vpc_offering[0].id, + self.zone.id + ) + self.assertIsNotNone( + vpc_created, + "VPC Creation Failed" + ) + # Listing the vpc for a user after creating a vpc + list_vpc_after = VPC.list(self.userapiclient) + status = validateList(list_vpc_after) + self.assertEquals( + PASS, + status[0], + "list VPC not as expected" + ) + # Verifying the list vpc size is increased by 1 + self.assertEquals( + 1, + len(list_vpc_after), + "list VPC not equal as expected" + ) + # List network offering for vpc = true + network_offering_vpc_true_list = NetworkOffering.list( + self.userapiclient, + forvpc="true", + zoneid=self.zone.id, + supportedServices="SourceNat,PortForwarding", + state="Enabled" + ) + status = validateList(network_offering_vpc_true_list) + self.assertEquals(PASS, status[0], "Default network offering not present for vpc = true with PortForwarding") + # Creating network under VPC + network_created = Network.create( + self.userapiclient, + self.services["ntwk"], + networkofferingid=network_offering_vpc_true_list[0].id, + vpcid=vpc_created.id, + zoneid=self.zone.id, + gateway=self.services["ntwk"]["gateway"], + netmask=self.services["ntwk"]["netmask"] + ) + self.assertIsNotNone( + network_created, + "Network is not created" + ) + # Listing all the IP Addresses for a user + list_ipaddresses_before = PublicIPAddress.list( + self.userapiclient, + listall=self.services["listall"] + ) + status = validateList(list_ipaddresses_before) + self.assertEquals( + PASS, + status[0], + "list IP Addresses not as expected" + ) + # Verifying the list vpc size is increased by 1 + self.assertEquals( + 1, + len(list_ipaddresses_before), + "list IP Addresses not equal as expected" + ) + # Associating an IP Addresses to VPC created + associated_ipaddress = PublicIPAddress.create( + self.userapiclient, + services=self.services["network"], + vpcid=vpc_created.id + ) + self.assertIsNotNone( + associated_ipaddress, + "Failed to Associate IP Address" + ) + # Listing all the IP Addresses for a user + list_ipaddresses_after = PublicIPAddress.list( + self.userapiclient, + listall=self.services["listall"] + ) + status = validateList(list_ipaddresses_after) + self.assertEquals( + PASS, + status[0], + "IP Addresses Association Failed" + ) + # Verifying the length of the list is 1 + self.assertEqual( + len(list_ipaddresses_before) + 1, + len(list_ipaddresses_after), + "Number of IP Addresses associated are not matching expected" + ) + # Launching a Virtual Machine with above created Network + vm_created = VirtualMachine.create( + self.userapiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + networkids=network_created.id, + serviceofferingid=self.service_offering.id, + ) + self.assertIsNotNone( + vm_created, + "Failed to launch a VM under network created" + ) + self.cleanup.append(network_created) + self.cleanup.append(vpc_created) + # Listing Port Forwarding Rules for the IP Address associated + list_prtfwdrule_before = NATRule.list( + self.userapiclient, + listall=self.services["listall"], + ipaddressid=associated_ipaddress.ipaddress.id + ) + # Verifying no port forwarding rules are listed + self.assertIsNone( + list_prtfwdrule_before, + "Port Forwarding Rules listed for newly associated IP Address" + ) + # Creating a Port Forwarding rule + portfwd_rule = NATRule.create( + self.userapiclient, + virtual_machine=vm_created, + services=self.services["natrule"], + ipaddressid=associated_ipaddress.ipaddress.id, + networkid=network_created.id + ) + self.assertIsNotNone( + portfwd_rule, + "Failed to create Port Forwarding Rule" + ) + # Verifying details of Sticky Policy created + # Creating expected and actual values dictionaries + expected_dict = { + "ipaddressid":associated_ipaddress.ipaddress.id, + "privateport":str(self.services["natrule"]["privateport"]), + "publicport":str(self.services["natrule"]["publicport"]), + "protocol":str(self.services["natrule"]["protocol"]).lower(), + } + actual_dict = { + "ipaddressid":portfwd_rule.ipaddressid, + "privateport":str(portfwd_rule.privateport), + "publicport":str(portfwd_rule.publicport), + "protocol":portfwd_rule.protocol, + } + portfwd_status = self.__verify_values( + expected_dict, + actual_dict + ) + self.assertEqual( + True, + portfwd_status, + "Created Port Forward Rule details are not as expected" + ) + # Listing Port Forwarding Rules for the IP Address associated + list_prtfwdrule_after = NATRule.list( + self.userapiclient, + listall=self.services["listall"], + ipaddressid=associated_ipaddress.ipaddress.id + ) + status = validateList(list_prtfwdrule_after) + self.assertEquals( + PASS, + status[0], + "Failed to create Port Forwarding Rule" + ) + # Verifying the length of the list is 1 + self.assertEqual( + 1, + len(list_prtfwdrule_after), + "Failed to create Port Forwarding Rule" + ) + # Deleting Port Forwarding Rule + portfwd_rule.delete(self.userapiclient) + # # Listing Port Forwarding Rules for the IP Address associated + list_prtfwdrule_after = NATRule.list( + self.userapiclient, + listall=self.services["listall"], + ipaddressid=associated_ipaddress.ipaddress.id + ) + # Verifying no port forwarding rules are listed + self.assertIsNone( + list_prtfwdrule_after, + "Port Forwarding Rules listed after deletion" + ) + # Destroying the VM Launched + vm_created.delete(self.userapiclient) + vm_created.expung(self.apiClient) + self.cleanup.append(self.account) + return + + @attr(tags=["advanced", "provisioning"]) + def test_11_create_delete_firewallrule(self): + """ + @summary: Test to list, create and delete Firewall Rule for IP Address associated to Non VPC network + @Steps: + Step1: Creating a Network for the user + Step2: Associating an IP Addresses for Network + Step3: Listing Firewall Rules for the IP Address associated in Step2 + Step4: Verifying that no Rules are listed + Step5: Creating a Firewall Rule for IP Address associated in Step2 + Step6: Listing Firewall Rules for the IP Address associated in Step2 + Step7: Verifying 1 Firewall Rule is listed + Step8: Deleting the Firewall Rule created in Step5 + Step9: Listing Firewall Rules for the IP Address associated in Step2 + Step10: Verifying that no Firewall Rules are listed + """ + # Listing all the Networks's for a user + list_networks_before = Network.list( + self.userapiclient, + listall=self.services["listall"] + ) + # Verifying No Networks are listed + self.assertIsNone( + list_networks_before, + "Networks listed for newly created User" + ) + # Listing Network Offerings + network_offerings_list = NetworkOffering.list( + self.apiClient, + forvpc="false", + guestiptype="Isolated", + state="Enabled", + supportedservices="SourceNat,Firewall", + zoneid=self.zone.id + ) + status = validateList(network_offerings_list) + self.assertEquals( + PASS, + status[0], + "Isolated Network Offerings with sourceNat, Firewall enabled are not found" + ) + # Creating a network + network = Network.create( + self.userapiclient, + self.services["network"], + accountid=self.account.name, + domainid=self.domain.id, + networkofferingid=network_offerings_list[0].id, + zoneid=self.zone.id + ) + self.assertIsNotNone( + network, + "Network creation failed" + ) + self.cleanup.append(network) + # Listing all the IP Addresses for a user + list_ipaddresses_before = PublicIPAddress.list( + self.userapiclient, + listall=self.services["listall"] + ) + # Verifying no IP Addresses are listed + self.assertIsNone( + list_ipaddresses_before, + "IP Addresses listed for newly created User" + ) + # Associating an IP Addresses to Network created + associated_ipaddress = PublicIPAddress.create( + self.userapiclient, + services=self.services["network"], + networkid=network.id + ) + self.assertIsNotNone( + associated_ipaddress, + "Failed to Associate IP Address" + ) + # Listing all the IP Addresses for a user + list_ipaddresses_after = PublicIPAddress.list( + self.userapiclient, + listall=self.services["listall"] + ) + status = validateList(list_ipaddresses_after) + self.assertEquals( + PASS, + status[0], + "IP Addresses Association Failed" + ) + # Verifying the length of the list is 1 + self.assertEqual( + 1, + len(list_ipaddresses_after), + "Number of IP Addresses associated are not matching expected" + ) + # Listing Firewall rules for the IP Associated + list_firewalls_before = FireWallRule.list( + self.userapiclient, + listall=self.services["listall"], + ipaddressid=associated_ipaddress.ipaddress.id + ) + # Verifying no firewall rules are listed + self.assertIsNone( + list_firewalls_before, + "Firewall Rules listed for newly associated IP Address" + ) + # Creating a Firewall Rule + firewall_rule = FireWallRule.create( + self.userapiclient, + ipaddressid=associated_ipaddress.ipaddress.id, + protocol='tcp', + cidrlist='10.1.1.1/16', + startport='22', + endport='2222' + ) + self.assertIsNotNone( + firewall_rule, + "Failed to create Firewall Rule" + ) + # Verifying details of the created Firewall Rule + # Creating expected and actual values dictionaries + expected_dict = { + "ipaddressid":associated_ipaddress.ipaddress.id, + "startport":"22", + "endport":"2222", + "protocol":"tcp", + "cidrlist":"10.1.1.1/16" + } + actual_dict = { + "ipaddressid":firewall_rule.ipaddressid, + "startport":firewall_rule.startport, + "endport":firewall_rule.endport, + "protocol":firewall_rule.protocol, + "cidrlist":firewall_rule.cidrlist + } + firewall_status = self.__verify_values( + expected_dict, + actual_dict + ) + self.assertEqual( + True, + firewall_status, + "Created Firewall Rule details are not as expected" + ) + # Listing Firewall rules for the IP Associated + list_firewalls_after = FireWallRule.list( + self.userapiclient, + listall=self.services["listall"], + ipaddressid=associated_ipaddress.ipaddress.id + ) + status = validateList(list_firewalls_after) + self.assertEquals( + PASS, + status[0], + "Failed to create Firewall Rule" + ) + # Verifying the length of the list is 1 + self.assertEqual( + 1, + len(list_firewalls_after), + "Failed to create Firewall Rule" + ) + # Deleting the Firewall Rule + firewall_rule.delete(self.userapiclient) + # Listing Firewall rules for the IP Associated + list_firewalls_after = FireWallRule.list( + self.userapiclient, + listall=self.services["listall"], + ipaddressid=associated_ipaddress.ipaddress.id + ) + # Verifying no firewall rules are listed + self.assertIsNone( + list_firewalls_after, + "Failed to create Firewall Rule" + ) + self.cleanup.append(self.account) + return + + @attr(tags=["advanced", "provisioning"]) + def test_12_create_delete_remoteaccessvpn(self): + """ + @summary: Test to list, create and delete Remote Access VPNs + @Steps: + Step1: Creating a Network for the user + Step2: Associating an IP Addresses for Network + Step3: Listing Remore Access VPNs for the IP Address associated in Step2 + Step4: Verifying that no Remore Access VPNs are listed + Step5: Creating a Remore Access VPN for IP Address associated in Step2 + Step6: Listing Remore Access VPNs for the IP Address associated in Step2 + Step7: Verifying 1 Remore Access VPN is listed + Step8: Deleting the Remore Access VPNs created in Step5 + Step9: Listing Remore Access VPNs for the IP Address associated in Step2 + Step10: Verifying that no Remore Access VPNs are listed + """ + # Listing all the Networks's for a user + list_networks_before = Network.list( + self.userapiclient, + listall=self.services["listall"] + ) + # Verifying No Networks are listed + self.assertIsNone( + list_networks_before, + "Networks listed for newly created User" + ) + # Listing Network Offerings + network_offerings_list = NetworkOffering.list( + self.apiClient, + forvpc="false", + guestiptype="Isolated", + state="Enabled", + supportedservices="SourceNat,Vpn", + zoneid=self.zone.id + ) + status = validateList(network_offerings_list) + self.assertEquals( + PASS, + status[0], + "Isolated Network Offerings with sourceNat, Vpn enabled are not found" + ) + # Creating a network + network = Network.create( + self.userapiclient, + self.services["network"], + accountid=self.account.name, + domainid=self.domain.id, + networkofferingid=network_offerings_list[0].id, + zoneid=self.zone.id + ) + self.assertIsNotNone( + network, + "Network creation failed" + ) + self.cleanup.append(network) + # Listing all the IP Addresses for a user + list_ipaddresses_before = PublicIPAddress.list( + self.userapiclient, + listall=self.services["listall"] + ) + # Verifying no IP Addresses are listed + self.assertIsNone( + list_ipaddresses_before, + "IP Addresses listed for newly created User" + ) + # Associating an IP Addresses to Network created + associated_ipaddress = PublicIPAddress.create( + self.userapiclient, + services=self.services["network"], + networkid=network.id + ) + self.assertIsNotNone( + associated_ipaddress, + "Failed to Associate IP Address" + ) + # Listing all the IP Addresses for a user + list_ipaddresses_after = PublicIPAddress.list( + self.userapiclient, + listall=self.services["listall"] + ) + status = validateList(list_ipaddresses_after) + self.assertEquals( + PASS, + status[0], + "IP Addresses Association Failed" + ) + # Verifying the length of the list is 1 + self.assertEqual( + 1, + len(list_ipaddresses_after), + "Number of IP Addresses associated are not matching expected" + ) + # Listing Remote access VPNs for the IP Associated + list_vpns_before = Vpn.list( + self.userapiclient, + listall=self.services["listall"], + ipaddressid=associated_ipaddress.ipaddress.id + ) + # Verifying no Remote Access VPNs are listed + self.assertIsNone( + list_vpns_before, + "Remote Access VPNs listed for newly associated IP Address" + ) + # Creating a Remote Access VPN + vpn_created = Vpn.create( + self.userapiclient, + publicipid=associated_ipaddress.ipaddress.id, + account=self.account.name, + domainid=self.domain.id, + openfirewall='false' + ) + self.assertIsNotNone( + vpn_created, + "Failed to create Remote Access VPN" + ) + # Verifying details of the created Remote Access VPN + # Creating expected and actual values dictionaries + expected_dict = { + "ipaddressid":associated_ipaddress.ipaddress.id, + "account":self.account.name, + "domainid":self.domain.id, + "state":"Running", + } + actual_dict = { + "ipaddressid":vpn_created.publicipid, + "account":vpn_created.account, + "domainid":vpn_created.domainid, + "state":vpn_created.state, + } + vpn_status = self.__verify_values( + expected_dict, + actual_dict + ) + self.assertEqual( + True, + vpn_status, + "Created Remote Access VPN details are not as expected" + ) + # Listing Remote Access VPNs for the IP Associated + list_vpns_after = Vpn.list( + self.userapiclient, + listall=self.services["listall"], + ipaddressid=associated_ipaddress.ipaddress.id + ) + status = validateList(list_vpns_after) + self.assertEquals( + PASS, + status[0], + "Failed to create Remote Access VPN" + ) + # Verifying the length of the list is 1 + self.assertEqual( + 1, + len(list_vpns_after), + "Failed to create Remote Access VPN" + ) + # Deleting the Remote Access VPN + vpn_created.delete(self.userapiclient) + # Listing Remote Access VPNs for the IP Associated + list_vpns_after = Vpn.list( + self.userapiclient, + listall=self.services["listall"], + ipaddressid=associated_ipaddress.ipaddress.id + ) + # Verifying no Remote Access VPNs are listed + self.assertIsNone( + list_vpns_after, + "Failed to create Remote Access VPN" + ) + self.cleanup.append(self.account) + return + + @attr(tags=["advanced", "provisioning"]) + def test_13_add_remove_vpnusers(self): + """ + @summary: Test to list, add and remove VPN Users + @Steps: + Step1: Creating a Network for the user + Step2: Associating an IP Addresses for Network + Step3: Launching a VM under network created in Step1 + Step4: Creating Remote Access VPN + Step5: Listing VPN Users + Step6: Verifying that no VPN Users are listed + Step7: Adding a VPN user + Step8: Listing VPN Users + Step9: Verifying 1 VPN is listed + Step10: Deleting VPN user + Step11: Listing VPN Users + Step12: Verifying that no VPN Users are listed + """ + # Listing all the Networks's for a user + list_networks_before = Network.list( + self.userapiclient, + listall=self.services["listall"] + ) + # Verifying No Networks are listed + self.assertIsNone( + list_networks_before, + "Networks listed for newly created User" + ) + # Listing Network Offerings + network_offerings_list = NetworkOffering.list( + self.apiClient, + forvpc="false", + guestiptype="Isolated", + state="Enabled", + supportedservices="SourceNat,Vpn", + zoneid=self.zone.id + ) + status = validateList(network_offerings_list) + self.assertEquals( + PASS, + status[0], + "Isolated Network Offerings with sourceNat, Vpn enabled are not found" + ) + # Creating a network + network = Network.create( + self.userapiclient, + self.services["network"], + accountid=self.account.name, + domainid=self.domain.id, + networkofferingid=network_offerings_list[0].id, + zoneid=self.zone.id + ) + self.assertIsNotNone( + network, + "Network creation failed" + ) + self.cleanup.append(network) + # Listing all the IP Addresses for a user + list_ipaddresses_before = PublicIPAddress.list( + self.userapiclient, + listall=self.services["listall"] + ) + # Verifying no IP Addresses are listed + self.assertIsNone( + list_ipaddresses_before, + "IP Addresses listed for newly created User" + ) + # Associating an IP Addresses to Network created + associated_ipaddress = PublicIPAddress.create( + self.userapiclient, + services=self.services["network"], + networkid=network.id + ) + self.assertIsNotNone( + associated_ipaddress, + "Failed to Associate IP Address" + ) + # Listing all the IP Addresses for a user + list_ipaddresses_after = PublicIPAddress.list( + self.userapiclient, + listall=self.services["listall"] + ) + status = validateList(list_ipaddresses_after) + self.assertEquals( + PASS, + status[0], + "IP Addresses Association Failed" + ) + # Verifying the length of the list is 1 + self.assertEqual( + 1, + len(list_ipaddresses_after), + "Number of IP Addresses associated are not matching expected" + ) + # Launching Virtual Machine + vm_created = VirtualMachine.create( + self.userapiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + networkids=network.id, + serviceofferingid=self.service_offering.id, + ) + self.assertIsNotNone( + vm_created, + "Failed to launch a VM under network created" + ) + # Listing Remote access VPNs for the IP Associated + list_vpns_before = Vpn.list( + self.userapiclient, + listall=self.services["listall"], + ipaddressid=associated_ipaddress.ipaddress.id + ) + # Verifying no Remote Access VPNs are listed + self.assertIsNone( + list_vpns_before, + "Remote Access VPNs listed for newly associated IP Address" + ) + # Creating a Remote Access VPN + vpn_created = Vpn.create( + self.userapiclient, + publicipid=associated_ipaddress.ipaddress.id, + account=self.account.name, + domainid=self.domain.id, + openfirewall='false' + ) + self.assertIsNotNone( + vpn_created, + "Failed to create Remote Access VPN" + ) + # Listing Remote Access VPNs for the IP Associated + list_vpns_after = Vpn.list( + self.userapiclient, + listall=self.services["listall"], + ipaddressid=associated_ipaddress.ipaddress.id + ) + status = validateList(list_vpns_after) + self.assertEquals( + PASS, + status[0], + "Failed to create Remote Access VPN" + ) + # Verifying the length of the list is 1 + self.assertEqual( + 1, + len(list_vpns_after), + "Failed to create Remote Access VPN" + ) + # Listing VPN Users + list_vpnusers_beore = VpnUser.list( + self.userapiclient, + listall=self.services["listall"], + account=self.account.name, + domainid=self.domain.id + ) + # Verifying no VPN Users listed + self.assertIsNone( + list_vpnusers_beore, + "VPN Users listed for newly created VPN" + ) + # Creating a VPN User + vpnuser_created = VpnUser.create( + self.userapiclient, + username=self.services["vpn_user"]["username"], + password=self.services["vpn_user"]["password"], + account=self.account.name, + domainid=self.domain.id + ) + self.assertIsNotNone( + vpnuser_created, + "Failed to create VPN User" + ) + # Listing VPN Users + list_vpnusers_after = VpnUser.list( + self.userapiclient, + listall=self.services["listall"], + account=self.account.name, + domainid=self.domain.id + ) + status = validateList(list_vpnusers_after) + self.assertEquals( + PASS, + status[0], + "Failed to list VPN user after creation" + ) + # Verifying the length of the list is 1 + self.assertEqual( + 1, + len(list_vpnusers_after), + "Failed to list VPN user after creation" + ) + # Deleting the VPN User + vpnuser_created.delete(self.userapiclient) + # Listing VPN Users + list_vpnusers_after = VpnUser.list( + self.userapiclient, + listall=self.services["listall"], + account=self.account.name, + domainid=self.domain.id + ) + # Verifying no VPN Users are listed + self.assertIsNone( + list_vpnusers_after, + "VPN User listed after deletion" + ) + # Destroying the VM + vm_created.delete(self.userapiclient) + vm_created.expung(self.apiClient) + self.cleanup.append(self.account) + return + + @attr(tags=["advanced", "provisioning"]) + def test_14_enable_disable_staticnat_fornonvpc(self): + """ + @summary: Test to Enable and Disable StaticNat for IP Address associated to Non VPC Network + @Steps: + Step1: Creating a Network for the user + Step2: Associating an IP Addresses for Network created in step1 + Step3: Associating one more Ip Address to Network created in step1 + Step4: Launching the VM in network created in step1 + Step5: Enabling the staticNat to IP Associated in Step3 + Step6: Verifying that StaticNat is enabled + Step7: Disabling the staticNat to IP Associated in Step3 + Step8: Verifying that StaticNat is disabled + """ + # Listing all the Networks's for a user + list_networks_before = Network.list( + self.userapiclient, + listall=self.services["listall"] + ) + # Verifying No Networks are listed + self.assertIsNone( + list_networks_before, + "Networks listed for newly created User" + ) + # Listing Network Offerings + network_offerings_list = NetworkOffering.list( + self.apiClient, + forvpc="false", + guestiptype="Isolated", + state="Enabled", + supportedservices="SourceNat,StaticNat", + zoneid=self.zone.id + ) + status = validateList(network_offerings_list) + self.assertEquals( + PASS, + status[0], + "Isolated Network Offerings with sourceNat, Vpn enabled are not found" + ) + # Creating a network + network = Network.create( + self.userapiclient, + self.services["network"], + accountid=self.account.name, + domainid=self.domain.id, + networkofferingid=network_offerings_list[0].id, + zoneid=self.zone.id + ) + self.assertIsNotNone( + network, + "Network creation failed" + ) + self.cleanup.append(network) + # Listing all the IP Addresses for a user + list_ipaddresses_before = PublicIPAddress.list( + self.userapiclient, + listall=self.services["listall"] + ) + # Verifying no IP Addresses are listed + self.assertIsNone( + list_ipaddresses_before, + "IP Addresses listed for newly created User" + ) + # Associating an IP Addresses to Network created + associated_ipaddress1 = PublicIPAddress.create( + self.userapiclient, + services=self.services["network"], + networkid=network.id + ) + self.assertIsNotNone( + associated_ipaddress1, + "Failed to Associate IP Address" + ) + # Associating another IP Addresses to Network created + associated_ipaddress2 = PublicIPAddress.create( + self.userapiclient, + services=self.services["network"], + networkid=network.id + ) + self.assertIsNotNone( + associated_ipaddress2, + "Failed to Associate IP Address" + ) + # Listing all the IP Addresses for a user + list_ipaddresses_after = PublicIPAddress.list( + self.userapiclient, + listall=self.services["listall"] + ) + status = validateList(list_ipaddresses_after) + self.assertEquals( + PASS, + status[0], + "IP Addresses Association Failed" + ) + # Verifying the length of the list is 1 + self.assertEqual( + 2, + len(list_ipaddresses_after), + "Number of IP Addresses associated are not matching expected" + ) + # Launching a Virtual Machine + vm_created = VirtualMachine.create( + self.userapiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + networkids=network.id, + serviceofferingid=self.service_offering.id, + ) + self.assertIsNotNone( + vm_created, + "Failed to launch a VM under network created" + ) + # Enabling static Nat for Ip Address associated + StaticNATRule.enable( + self.userapiclient, + ipaddressid=associated_ipaddress2.ipaddress.id, + virtualmachineid=vm_created.id, + ) + # Listing Ip Address by id + list_ipaddress = PublicIPAddress.list( + self.userapiclient, + id=associated_ipaddress2.ipaddress.id, + listall=self.services["listall"] + ) + status = validateList(list_ipaddress) + self.assertEquals( + PASS, + status[0], + "Failed to List IP Address" + ) + # Verifying the length of the list is 1 + self.assertEqual( + 1, + len(list_ipaddress), + "Failed to List IP Address" + ) + self.assertEquals( + True, + list_ipaddress[0].isstaticnat, + "Failed to Enable Static Nat" + ) + # Disabling static Nat + StaticNATRule.disable( + self.userapiclient, + ipaddressid=associated_ipaddress2.ipaddress.id + ) + # Listing Ip Address by id + list_ipaddress = PublicIPAddress.list( + self.userapiclient, + id=associated_ipaddress2.ipaddress.id, + listall=self.services["listall"] + ) + status = validateList(list_ipaddress) + self.assertEquals( + PASS, + status[0], + "Failed to List IP Address" + ) + # Verifying the length of the list is 1 + self.assertEqual( + 1, + len(list_ipaddress), + "Failed to List IP Address" + ) + self.assertEquals( + False, + list_ipaddress[0].isstaticnat, + "Failed to Disable Static Nat" + ) + # Destroying the VM + vm_created.delete(self.userapiclient) + vm_created.expung(self.apiClient) + self.cleanup.append(self.account) + return + + @attr(tags=["advanced", "provisioning"]) + def test_15_enable_disable_staticnat_forvpc(self): + """ + @summary: Test to Enable and Disable StaticNat for IP Address associated to VPC Network + @Steps: + Step1: Creating a VPC + Step2: Creating a Network under VPC for the user + Step3: Associating an IP Addresses for Network created in step1 + Step4: Launching the VM in network created in step2 + Step5: Enabling the staticNat to IP Associated in Step3 + Step6: Verifying that StaticNat is enabled + Step7: Disabling the staticNat to IP Associated in Step3 + Step8: Verifying that StaticNat is disabled + """ + # Listing all the vpc's for a user + list_vpc_before = VPC.list(self.userapiclient) + # Verifying No VPCs are listed + self.assertIsNone( + list_vpc_before, + "VPC's Listed for newly Created User" + ) + # Listing VPC Offerings + list_vpc_offering = VpcOffering.list(self.userapiclient) + status = validateList(list_vpc_offering) + self.assertEquals( + PASS, + status[0], + "list vpc offering is none" + ) + # Creating a vpc + vpc_created = VPC.create( + self.userapiclient, + self.services["vpc"], + list_vpc_offering[0].id, + self.zone.id + ) + self.assertIsNotNone( + vpc_created, + "VPC Creation Failed" + ) + # Listing the vpc for a user after creating a vpc + list_vpc_after = VPC.list(self.userapiclient) + status = validateList(list_vpc_after) + self.assertEquals( + PASS, + status[0], + "list VPC not as expected" + ) + # Verifying the list vpc size is increased by 1 + self.assertEquals( + 1, + len(list_vpc_after), + "list VPC not equal as expected" + ) + # List network offering for vpc = true + network_offering_vpc_true_list = NetworkOffering.list( + self.userapiclient, + forvpc="true", + zoneid=self.zone.id, + supportedServices="SourceNat,PortForwarding,StaticNat", + state="Enabled" + ) + status = validateList(network_offering_vpc_true_list) + self.assertEquals(PASS, status[0], "Default network offering not present for vpc = true with PortForwarding") + # Creating network under VPC + network_created = Network.create( + self.userapiclient, + self.services["ntwk"], + networkofferingid=network_offering_vpc_true_list[0].id, + vpcid=vpc_created.id, + zoneid=self.zone.id, + gateway=self.services["ntwk"]["gateway"], + netmask=self.services["ntwk"]["netmask"] + ) + self.assertIsNotNone( + network_created, + "Network is not created" + ) + # Listing all the IP Addresses for a user + list_ipaddresses_before = PublicIPAddress.list( + self.userapiclient, + listall=self.services["listall"] + ) + status = validateList(list_ipaddresses_before) + self.assertEquals( + PASS, + status[0], + "list IP Addresses not as expected" + ) + # Verifying the list vpc size is increased by 1 + self.assertEquals( + 1, + len(list_ipaddresses_before), + "list IP Addresses not equal as expected" + ) + # Associating an IP Addresses to VPC created + associated_ipaddress = PublicIPAddress.create( + self.userapiclient, + services=self.services["network"], + vpcid=vpc_created.id + ) + self.assertIsNotNone( + associated_ipaddress, + "Failed to Associate IP Address" + ) + # Listing all the IP Addresses for a user + list_ipaddresses_after = PublicIPAddress.list( + self.userapiclient, + listall=self.services["listall"] + ) + status = validateList(list_ipaddresses_after) + self.assertEquals( + PASS, + status[0], + "IP Addresses Association Failed" + ) + # Verifying the length of the list is 1 + self.assertEqual( + len(list_ipaddresses_before) + 1, + len(list_ipaddresses_after), + "Number of IP Addresses associated are not matching expected" + ) + # Launching a Virtual Machine with above created Network + vm_created = VirtualMachine.create( + self.userapiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + networkids=network_created.id, + serviceofferingid=self.service_offering.id, + ) + self.assertIsNotNone( + vm_created, + "Failed to launch a VM under network created" + ) + self.cleanup.append(network_created) + self.cleanup.append(vpc_created) + # Enabling static Nat for Ip Address associated + StaticNATRule.enable( + self.userapiclient, + ipaddressid=associated_ipaddress.ipaddress.id, + virtualmachineid=vm_created.id, + networkid=network_created.id + ) + # Listing Ip Address by id + list_ipaddress = PublicIPAddress.list( + self.userapiclient, + id=associated_ipaddress.ipaddress.id, + listall=self.services["listall"] + ) + status = validateList(list_ipaddress) + self.assertEquals( + PASS, + status[0], + "Failed to List IP Address" + ) + # Verifying the length of the list is 1 + self.assertEqual( + 1, + len(list_ipaddress), + "Failed to List IP Address" + ) + self.assertEquals( + True, + list_ipaddress[0].isstaticnat, + "Failed to Enable Static Nat" + ) + # Disabling static Nat + StaticNATRule.disable( + self.userapiclient, + ipaddressid=associated_ipaddress.ipaddress.id + ) + # Listing Ip Address by id + list_ipaddress = PublicIPAddress.list( + self.userapiclient, + id=associated_ipaddress.ipaddress.id, + listall=self.services["listall"] + ) + status = validateList(list_ipaddress) + self.assertEquals( + PASS, + status[0], + "Failed to List IP Address" + ) + # Verifying the length of the list is 1 + self.assertEqual( + 1, + len(list_ipaddress), + "Failed to List IP Address" + ) + self.assertEquals( + False, + list_ipaddress[0].isstaticnat, + "Failed to Disable Static Nat" + ) + # Destroying the VM + vm_created.delete(self.userapiclient) + vm_created.expung(self.apiClient) + self.cleanup.append(self.account) + return + + @attr(tags=["advanced", "provisioning"]) + def test_16_create_delete_ipforwardingrule(self): + """ + @summary: Test to list, create and delete IP Forwarding Rules for IP Address + @Steps: + Step1: Creating a Network for the user + Step2: Associating an IP Addresses for Network created in step1 + Step3: Associating one more Ip Address to Network created in step1 + Step4: Launching the VM in network created in step1 + Step5: Enabling the staticNat to IP Associated in Step3 + Step6: Listing IP Forwarding rules + Step7: Verifying no IP Forwarding rules are listed + Step8: Creating a IP Forwarding Rule + Step9: Listing IP Forwarding rules + Step10: Verifying 1 IP Forwarding rule is listed + Step11: Deleting the IP Forwarding rule + Step12: Listing IP Forwarding rules + Step13: Verifying no IP Forwarding rules are listed + """ + # Listing all the Networks's for a user + list_networks_before = Network.list( + self.userapiclient, + listall=self.services["listall"] + ) + # Verifying No Networks are listed + self.assertIsNone( + list_networks_before, + "Networks listed for newly created User" + ) + # Listing Network Offerings + network_offerings_list = NetworkOffering.list( + self.apiClient, + forvpc="false", + guestiptype="Isolated", + state="Enabled", + supportedservices="SourceNat,Vpn", + zoneid=self.zone.id + ) + status = validateList(network_offerings_list) + self.assertEquals( + PASS, + status[0], + "Isolated Network Offerings with sourceNat, Vpn enabled are not found" + ) + # Creating a network + network = Network.create( + self.userapiclient, + self.services["network"], + accountid=self.account.name, + domainid=self.domain.id, + networkofferingid=network_offerings_list[0].id, + zoneid=self.zone.id + ) + self.assertIsNotNone( + network, + "Network creation failed" + ) + self.cleanup.append(network) + # Listing all the IP Addresses for a user + list_ipaddresses_before = PublicIPAddress.list( + self.userapiclient, + listall=self.services["listall"] + ) + # Verifying no IP Addresses are listed + self.assertIsNone( + list_ipaddresses_before, + "IP Addresses listed for newly created User" + ) + # Associating an IP Addresses to Network created + associated_ipaddress1 = PublicIPAddress.create( + self.userapiclient, + services=self.services["network"], + networkid=network.id + ) + self.assertIsNotNone( + associated_ipaddress1, + "Failed to Associate IP Address" + ) + # Associating another IP Addresses to Network created + associated_ipaddress2 = PublicIPAddress.create( + self.userapiclient, + services=self.services["network"], + networkid=network.id + ) + self.assertIsNotNone( + associated_ipaddress2, + "Failed to Associate IP Address" + ) + # Listing all the IP Addresses for a user + list_ipaddresses_after = PublicIPAddress.list( + self.userapiclient, + listall=self.services["listall"] + ) + status = validateList(list_ipaddresses_after) + self.assertEquals( + PASS, + status[0], + "IP Addresses Association Failed" + ) + # Verifying the length of the list is 1 + self.assertEqual( + 2, + len(list_ipaddresses_after), + "Number of IP Addresses associated are not matching expected" + ) + # Launching a Virtual Machine + vm_created = VirtualMachine.create( + self.userapiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + networkids=network.id, + serviceofferingid=self.service_offering.id, + ) + self.assertIsNotNone( + vm_created, + "Failed to launch a VM under network created" + ) + # Enabling static Nat for Ip Address associated + StaticNATRule.enable( + self.userapiclient, + ipaddressid=associated_ipaddress2.ipaddress.id, + virtualmachineid=vm_created.id, + ) + # Listing Ip Address by id + list_ipaddress = PublicIPAddress.list( + self.userapiclient, + id=associated_ipaddress2.ipaddress.id, + listall=self.services["listall"] + ) + status = validateList(list_ipaddress) + self.assertEquals( + PASS, + status[0], + "Failed to List IP Address" + ) + # Verifying the length of the list is 1 + self.assertEqual( + 1, + len(list_ipaddress), + "Failed to List IP Address" + ) + self.assertEquals( + True, + list_ipaddress[0].isstaticnat, + "Failed to Enable Static Nat" + ) + # Listing IP Forwarding Rules + list_ipfwdrule_before = StaticNATRule.list( + self.userapiclient, + listall=self.services["listall"], + ipaddressid=associated_ipaddress2.ipaddress.id + ) + # Verifying no IP Forwarding Rules are listed + self.assertIsNone( + list_ipfwdrule_before, + "IP Forwardign Rule listed for newly enabled StaticNat IP" + ) + # Creating IP Forwardign Rule + ipfwd_rule = StaticNATRule.createIpForwardingRule( + self.userapiclient, + startport='80', + endport='89', + protocol='tcp', + ipaddressid=associated_ipaddress2.ipaddress.id, + openfirewall=False + ) + self.assertIsNotNone( + ipfwd_rule, + "Failed to create IP Forwarding Rule" + ) + # Listing IP Forwarding Rules + list_ipfwdrule_after = StaticNATRule.list( + self.userapiclient, + listall=self.services["listall"], + ipaddressid=associated_ipaddress2.ipaddress.id + ) + status = validateList(list_ipfwdrule_after) + self.assertEquals( + PASS, + status[0], + "Failed to List IP Forwarding Rule after Creation" + ) + # Verifying the length of the list is 1 + self.assertEqual( + 1, + len(list_ipfwdrule_after), + "Failed to List IP Forwarding Rule after Creation" + ) + # Deleting IP Forwarding Rule + ipfwd_rule.delete(self.userapiclient) + # Listing IP Forwarding Rules + list_ipfwdrule_after = StaticNATRule.list( + self.userapiclient, + listall=self.services["listall"], + ipaddressid=associated_ipaddress2.ipaddress.id + ) + # Verifying no IP Forwarding Rules are listed + self.assertIsNone( + list_ipfwdrule_after, + "IP Forwardign Rule listed after deletion" + ) + # Destroying the VM + vm_created.delete(self.userapiclient) + vm_created.expung(self.apiClient) + self.cleanup.append(self.account) + return + + @attr(tags=["advanced", "provisioning"]) + def test_17_create_update_autoscalepolicy(self): + """ + @summary: Test to list, create and update Autoscale Policy + @Steps: + Step1: Creating a Network Offering for Supported Service LB with Netscaler + Step2: Create a Network using Network Offering created in Step1 + Step3: Launching a VM using Network created in Step2 + Step4: Associating IP Address for Network created in Step2 + Step5: Listing Counters + Step6: Listing Conditions for the user + Step7: Verifying no Conditions are listed + Step8: Creating a 2 conditions + Step9: Listing conditions again + Step10: Verifying 2 conditions are listed + Step11: Listing Autoscale Policies for User + Step12: Verifying No Autoscale policy is listed + Step13: Creating Autoscale Policy using Condition1 + Step14: Verifying that Autoscale Policy is created with Condition1 + Step15: Listing Autoscale Policies + Step16: Verifying 1 Autoscale Policy is listed + Step17: Updating Autoscale Policy created in step13 with condition2 + Step18: Verifying Autoscale policy is updated with condition2 + """ + if self.hypervisor.lower() == 'kvm': + raise unittest.SkipTest("ScaleVM is not supported on KVM. Hence, skipping the test") + + list_physical_networks = PhysicalNetwork.list( + self.apiClient, + zoneid=self.zone.id + ) + physical_networks_size = 0 + if list_physical_networks is not None: + physical_networks_size = len(list_physical_networks) + + run_flag = False + for i in range(0, len(list_physical_networks)): + list_network_serviceprovider = NetworkServiceProvider.list( + self.apiClient, + physicalnetworkid=list_physical_networks[i].id + ) + for j in range(0, len(list_network_serviceprovider)): + if((list_network_serviceprovider[j].name == 'Netscaler') and (list_network_serviceprovider[j].state == 'Enabled')): + run_flag = True + break + + if(run_flag == False): + self.debug("Netscaler is not enabled and auto scale VM is applicable only for Netscaler") + else: + # Listing Network Offerings + list_nwoff_before = NetworkOffering.list( + self.apiClient, + forvpc="false", + guestiptype="Isolated", + state="Enabled", + supportedservices="SourceNat,Lb", + zoneid=self.zone.id + ) + # Creating Network Offerign with LB as Netscalar + nwoff_created = NetworkOffering.create( + self.apiClient, + self.services["nw_off_isolated_netscaler"] + ) + self.assertIsNotNone( + nwoff_created, + "Failed to Create Network Offering with LB sercvice for Netscaler" + ) + # Enable Network offering + nwoff_created.update(self.apiClient, state='Enabled') + # Listing Network Offerings again + list_nwoff_after = NetworkOffering.list( + self.apiClient, + forvpc="false", + guestiptype="Isolated", + state="Enabled", + supportedservices="SourceNat,Lb", + zoneid=self.zone.id + ) + self.assertEquals( + len(list_nwoff_before) + 1, + len(list_nwoff_after), + "Failed to create Network Offering" + ) + # Creating a Network Using the Network Offering + network = Network.create( + self.userapiclient, + self.services["network"], + accountid=self.account.name, + domainid=self.domain.id, + networkofferingid=nwoff_created.id, + zoneid=self.zone.id + ) + self.assertIsNotNone( + network, + "Network creation failed" + ) + self.cleanup.append(network) + self.cleanup.append(nwoff_created) + # Launching a Virtual Machine + vm_created = VirtualMachine.create( + self.userapiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + networkids=network.id, + serviceofferingid=self.service_offering.id, + ) + self.assertIsNotNone( + vm_created, + "Failed to launch a VM under network created" + ) + # Listing all the IP Addresses for a user + list_ipaddresses_before = PublicIPAddress.list( + self.userapiclient, + listall=self.services["listall"] + ) + status = validateList(list_ipaddresses_before) + self.assertEquals( + PASS, + status[0], + "IP Addresses Association Failed while launching a VM" + ) + # Verifying the length of the list is 1 + self.assertEqual( + 1, + len(list_ipaddresses_before), + "IP Addresses Association Failed while launching a VM" + ) + # Associating an IP Addresses to Network created + associated_ipaddress = PublicIPAddress.create( + self.userapiclient, + services=self.services["network"], + networkid=network.id + ) + self.assertIsNotNone( + associated_ipaddress, + "Failed to Associate IP Address" + ) + # Listing all the IP Addresses for a user + list_ipaddresses_after = PublicIPAddress.list( + self.userapiclient, + listall=self.services["listall"] + ) + status = validateList(list_ipaddresses_after) + self.assertEquals( + PASS, + status[0], + "IP Addresses Association Failed" + ) + # Verifying the length of the list is 1 + self.assertEqual( + 2, + len(list_ipaddresses_after), + "Number of IP Addresses associated are not matching expected" + ) + # Listing Counters + list_counters = Autoscale.listCounters( + self.userapiclient, + ) + status = validateList(list_counters) + self.assertEquals( + PASS, + status[0], + "Failed to list counters" + ) + # Listing Conditions + list_conditions_before = Autoscale.listConditions( + self.userapiclient, + listall=self.services["listall"], + account=self.account.name, + domainid=self.domain.id + ) + self.assertIsNone( + list_conditions_before, + "Listed Conditions for newly created user" + ) + # Creating first Condition + condition_created1 = Autoscale.createCondition( + self.userapiclient, + counterid=list_counters[0].id, + relationaloperator='GT', + threshold='1000' + ) + self.assertIsNotNone( + condition_created1, + "Failed to create Condition" + ) + # Creating second Condition + condition_created2 = Autoscale.createCondition( + self.userapiclient, + counterid=list_counters[0].id, + relationaloperator='GT', + threshold='1500' + ) + self.assertIsNotNone( + condition_created2, + "Failed to create Condition" + ) + # Listing Conditions again + list_conditions_after = Autoscale.listConditions( + self.userapiclient, + listall=self.services["listall"], + account=self.account.name, + domainid=self.domain.id + ) + status = validateList(list_conditions_after) + self.assertEquals( + PASS, + status[0], + "Failed to list Conditions after creation" + ) + # Listing Autoscale policies + list_autoscalepolicies_before = Autoscale.listAutoscalePolicies( + self.userapiclient, + listall=self.services["listall"] + ) + # Verifying no Autoscale policies are listed + self.assertIsNone( + list_autoscalepolicies_before, + "Autoscale policies listed" + ) + # Creating Autoscale Policy + autoscalepolicy_created = Autoscale.createAutoscalePolicy( + self.userapiclient, + action='scaleup', + conditionids=condition_created1.id, + duration='100', + quiettime='100' + ) + self.assertIsNotNone( + autoscalepolicy_created, + "Failed to create Autoscale VM Policy" + ) + # Verifying autoscalepolicy is created using condition1 + self.assertEquals( + condition_created1.id, + autoscalepolicy_created.conditions[0].id, + "Autoscale Policy not created by given condition" + ) + # Listing Autoscale policies + list_autoscalepolicies_after = Autoscale.listAutoscalePolicies( + self.userapiclient, + listall=self.services["listall"] + ) + status = validateList(list_autoscalepolicies_after) + self.assertEquals( + PASS, + status[0], + "Failed to list Autoscale Policy after creation" + ) + self.assertEquals( + 1, + len(list_autoscalepolicies_after), + "Autoscale Policies count is not matching" + ) + # Updating Autoscale Policy + autoscalepolicy_updated = Autoscale.updateAutoscalePolicy( + self.userapiclient, + id=autoscalepolicy_created.id, + conditionids=condition_created2.id, + duration='100', + quiettime='100' + ) + self.assertIsNotNone( + autoscalepolicy_updated, + "Failed to update Autoscale Policy" + ) + # Verifying the Autoscale Policy is updated + self.assertEquals( + condition_created2.id, + autoscalepolicy_updated.conditions[0].id, + "Autoscale Policy not updated to given condition" + ) + # Destroying the VM + vm_created.delete(self.userapiclient) + vm_created.expung(self.apiClient) + self.cleanup.append(self.account) + return + + @attr(tags=["advanced", "provisioning"]) + def test_18_create_update_autoscaleprofiles(self): + """ + @summary: Test to list, create and update Autoscale VM Profiles + @Steps: + Step1: Creating a Network Offering for Supported Service LB with Netscaler + Step2: Create a Network using Network Offering created in Step1 + Step3: Launching a VM using Network created in Step2 + Step4: Associating IP Address for Network created in Step2 + Step5: Listing Available Service Offerings + Step6: Listing all types of templates + Step7: Verifying only featured templates are listed for newly created user + Step8: Listing autoscale vm profiles + Step9: Verifying no Autoscale VM Profiles are listed + Step10: Creating a Autoscale VM Profile + Step11: Listing Autoscale VM Profile + Step12: Verifying 1 Autoscale VM Profile is listed + Step13: Listing Autoscale VM Profile by id + Step14: Verifying details of the created autoscale vm profile are matching with listed autoscal vm profile + Step15: Updating Autoscale VM profile with destroy vm grace period + Step16: Verifying that Autoscale VM is updated + """ + if self.hypervisor.lower() == 'kvm': + raise unittest.SkipTest("ScaleVM is not supported on KVM. Hence, skipping the test") + + list_physical_networks = PhysicalNetwork.list( + self.apiClient, + zoneid=self.zone.id + ) + physical_networks_size = 0 + if list_physical_networks is not None: + physical_networks_size = len(list_physical_networks) + + run_flag = False + for i in range(0, len(list_physical_networks)): + list_network_serviceprovider = NetworkServiceProvider.list( + self.apiClient, + physicalnetworkid=list_physical_networks[i].id + ) + for j in range(0, len(list_network_serviceprovider)): + if((list_network_serviceprovider[j].name == 'Netscaler') and (list_network_serviceprovider[j].state == 'Enabled')): + run_flag = True + break + + if(run_flag == False): + self.debug("Netscaler is not enabled and auto scale VM is applicable only for Netscaler") + else: + # Listing Network Offerings + list_nwoff_before = NetworkOffering.list( + self.apiClient, + forvpc="false", + guestiptype="Isolated", + state="Enabled", + supportedservices="SourceNat,Lb", + zoneid=self.zone.id + ) + # Creating Network Offerign with LB as Netscalar + nwoff_created = NetworkOffering.create( + self.apiClient, + self.services["nw_off_isolated_netscaler"] + ) + self.assertIsNotNone( + nwoff_created, + "Failed to Create Network Offering with LB sercvice for Netscaler" + ) + # Enable Network offering + nwoff_created.update(self.apiClient, state='Enabled') + # Listing Network Offerings again + list_nwoff_after = NetworkOffering.list( + self.apiClient, + forvpc="false", + guestiptype="Isolated", + state="Enabled", + supportedservices="SourceNat,Lb", + zoneid=self.zone.id + ) + self.assertEquals( + len(list_nwoff_before) + 1, + len(list_nwoff_after), + "Failed to create Network Offering" + ) + # Creating a Network Using the Network Offering + network = Network.create( + self.userapiclient, + self.services["network"], + accountid=self.account.name, + domainid=self.domain.id, + networkofferingid=nwoff_created.id, + zoneid=self.zone.id + ) + self.assertIsNotNone( + network, + "Network creation failed" + ) + self.cleanup.append(network) + self.cleanup.append(nwoff_created) + # Launching a Virtual Machine + vm_created = VirtualMachine.create( + self.userapiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + networkids=network.id, + serviceofferingid=self.service_offering.id, + ) + self.assertIsNotNone( + vm_created, + "Failed to launch a VM under network created" + ) + # Listing all the IP Addresses for a user + list_ipaddresses_before = PublicIPAddress.list( + self.userapiclient, + listall=self.services["listall"] + ) + status = validateList(list_ipaddresses_before) + self.assertEquals( + PASS, + status[0], + "IP Addresses Association Failed while launching a VM" + ) + # Verifying the length of the list is 1 + self.assertEqual( + 1, + len(list_ipaddresses_before), + "IP Addresses Association Failed while launching a VM" + ) + # Associating an IP Addresses to Network created + associated_ipaddress = PublicIPAddress.create( + self.userapiclient, + services=self.services["network"], + networkid=network.id + ) + self.assertIsNotNone( + associated_ipaddress, + "Failed to Associate IP Address" + ) + # Listing all the IP Addresses for a user + list_ipaddresses_after = PublicIPAddress.list( + self.userapiclient, + listall=self.services["listall"] + ) + status = validateList(list_ipaddresses_after) + self.assertEquals( + PASS, + status[0], + "IP Addresses Association Failed" + ) + # Verifying the length of the list is 1 + self.assertEqual( + 2, + len(list_ipaddresses_after), + "Number of IP Addresses associated are not matching expected" + ) + # Listing Service Offerings + list_service_offerings = ServiceOffering.list( + self.userapiclient, + listall=self.services["listall"], + issystem='false' + ) + status = validateList(list_service_offerings) + self.assertEquals( + PASS, + status[0], + "Failed to list Service Offerings" + ) + # Listing Users + list_users = User.list( + self.apiClient, + listall=self.services["listall"], + account=self.account.name, + domainid=self.domain.id + ) + status = validateList(list_users) + self.assertEquals( + PASS, + status[0], + "Failed to list Users" + ) + # Listing Featured Templates + list_templates_featured = Template.list( + self.userapiclient, + listall=self.services["listall"], + templatefilter="featured", + zoneid=self.zone.id + ) + status = validateList(list_templates_featured) + self.assertEquals( + PASS, + status[0], + "Failed to list Featured Templates" + ) + # Listing Community Templates + list_templates_community = Template.list( + self.userapiclient, + listall=self.services["listall"], + templatefilter="community", + zoneid=self.zone.id + ) + self.assertIsNone( + list_templates_community, + "Community Templates listed for newly created User" + ) + # Listing selfexecutable Templates + list_templates_selfexecutable = Template.list( + self.userapiclient, + listall=self.services["listall"], + templatefilter="selfexecutable", + zoneid=self.zone.id + ) + self.assertIsNone( + list_templates_selfexecutable, + "Self Executable Templates listed for newly created User" + ) + # Listing Autoscale VM Profiles + list_autoscalevm_profiles_before = Autoscale.listAutoscaleVmPofiles( + self.userapiclient, + listall=self.services["listall"] + ) + self.assertIsNone( + list_autoscalevm_profiles_before, + "Autoscale VM Profiles listed" + ) + # Creating Autoscale VM Profile + counterparam = { "snmpcommunity": "public", "snmpport": "161"} + autoscalevm_profile = Autoscale.createAutoscaleVmProfile( + self.userapiclient, + serviceofferingid=list_service_offerings[0].id, + zoneid=self.zone.id, + templateid=list_templates_featured[0].id, + autoscaleuserid=list_users[0].id, + destroyvmgraceperiod='100', + counterparam=counterparam + ) + self.assertIsNotNone( + autoscalevm_profile, + "Failed to create Autoscale VM Profile" + ) + # Listing Autoscale VM Profiles + list_autoscalevm_profiles_after = Autoscale.listAutoscaleVmPofiles( + self.userapiclient, + listall=self.services["listall"] + ) + status = validateList(list_autoscalevm_profiles_after) + self.assertEquals( + PASS, + status[0], + "Failed to list Autoscale VM Profile after creation" + ) + # Verifying only 1 autoscale vm profile is created + self.assertEquals( + 1, + len(list_autoscalevm_profiles_after), + "Count of Autoscale VM profiles listed is not matching" + ) + # Listing the Autoscale VM Profile by id + list_autoscalvmprofile = Autoscale.listAutoscaleVmPofiles( + self.userapiclient, + listall=self.services["listall"], + id=autoscalevm_profile.id + ) + status = validateList(list_autoscalvmprofile) + self.assertEquals( + PASS, + status[0], + "Failed to list Autoscale VM Profile by Id after creation" + ) + # Verifying details of the listed Autoscale VM Profile + # Creating expected and actual values dictionaries + expected_dict = { + "id":autoscalevm_profile.id, + "account":self.account.name, + "domainid":self.domain.id, + "autoscaleuserid":list_users[0].id, + "serviceofferingid":list_service_offerings[0].id, + "zoneid":self.zone.id, + "templateid":list_templates_featured[0].id, + "destroyvmgraceperiod":autoscalevm_profile.destroyvmgraceperiod + } + actual_dict = { + "id":list_autoscalvmprofile[0].id, + "account":list_autoscalvmprofile[0].account, + "domainid":list_autoscalvmprofile[0].domainid, + "autoscaleuserid":list_autoscalvmprofile[0].autoscaleuserid, + "serviceofferingid":list_autoscalvmprofile[0].serviceofferingid, + "zoneid":list_autoscalvmprofile[0].zoneid, + "templateid":list_autoscalvmprofile[0].templateid, + "destroyvmgraceperiod":list_autoscalvmprofile[0].destroyvmgraceperiod + } + autoscalevm_profile_status = self.__verify_values( + expected_dict, + actual_dict + ) + self.assertEqual( + True, + autoscalevm_profile_status, + "Created Autoscale VM Profile details are not as expected" + ) + # Updating destroyvmgrageperiod for created Autoscale VM Profile + autoscalevm_profile_updated = Autoscale.updateAutoscaleVMProfile( + self.userapiclient, + id=autoscalevm_profile.id, + autoscaleuserid=list_users[0].id, + destroyvmgraceperiod='200', + templateid=list_templates_featured[0].id, + ) + self.assertIsNotNone( + autoscalevm_profile_updated, + "Failed to update Autoscale VM Profile" + ) + # Verifyign that Destroy VM Graceperiod is updated in autoscale VM Profile + self.assertEquals( + 200, + autoscalevm_profile_updated.destroyvmgraceperiod, + "Failed to update destroy vm grace period" + ) + # Destroying the VM + vm_created.delete(self.userapiclient) + vm_created.expung(self.apiClient) + self.cleanup.append(self.account) + return + + @attr(tags=["advanced", "provisioning"]) + def test_19_create_update_autoscalevmgroup(self): + """ + @summary: Test to list, create, update, enable, disable Autoscale VM Profiles + @Steps: + Step1: Creating a Network Offering for Supported Service LB with Netscaler + Step2: Create a Network using Network Offering created in Step1 + Step3: Launching a VM using Network created in Step2 + Step4: Associating IP Address for Network created in Step2 + Step5: Creating Scaleup condition and scaleup policy + Step6: Creating Scaledown condition and scaledown policy + Step7: Creating Autoscale VM profile + Step8: Creating Load Balancer Rule + Step9: Listing Autoscale Vm groups and verifying no Autoscale VM groups are listed + Step10: Creating Autoscale VM Group and verifying it was created + Step11: Listing Autoscale Vm groups and verifying 1 Autoscale VM groups is listed + Step12: Disabling Autoscale VM group and verifying it was disabled + Step13: Updating Autoscale VM group and verifying it was updated + Step14: Enabling Autoscale VM group and verifying it was enabled + """ + if self.hypervisor.lower() == 'kvm': + raise unittest.SkipTest("ScaleVM is not supported on KVM. Hence, skipping the test") + + list_physical_networks = PhysicalNetwork.list( + self.apiClient, + zoneid=self.zone.id + ) + physical_networks_size = 0 + if list_physical_networks is not None: + physical_networks_size = len(list_physical_networks) + + run_flag = False + for i in range(0, len(list_physical_networks)): + list_network_serviceprovider = NetworkServiceProvider.list( + self.apiClient, + physicalnetworkid=list_physical_networks[i].id + ) + for j in range(0, len(list_network_serviceprovider)): + if((list_network_serviceprovider[j].name == 'Netscaler') and (list_network_serviceprovider[j].state == 'Enabled')): + run_flag = True + break + + if(run_flag == False): + self.debug("Netscaler is not enabled and auto scale VM is applicable only for Netscaler") + else: + # Listing Network Offerings + list_nwoff_before = NetworkOffering.list( + self.apiClient, + forvpc="false", + guestiptype="Isolated", + state="Enabled", + supportedservices="SourceNat,Lb", + zoneid=self.zone.id + ) + # Creating Network Offerign with LB as Netscalar + nwoff_created = NetworkOffering.create( + self.apiClient, + self.services["nw_off_isolated_netscaler"] + ) + self.assertIsNotNone( + nwoff_created, + "Failed to Create Network Offering with LB sercvice for Netscaler" + ) + # Enable Network offering + nwoff_created.update(self.apiClient, state='Enabled') + # Listing Network Offerings again + list_nwoff_after = NetworkOffering.list( + self.apiClient, + forvpc="false", + guestiptype="Isolated", + state="Enabled", + supportedservices="SourceNat,Lb", + zoneid=self.zone.id + ) + self.assertEquals( + len(list_nwoff_before) + 1, + len(list_nwoff_after), + "Failed to create Network Offering" + ) + # Creating a Network Using the Network Offering + network = Network.create( + self.userapiclient, + self.services["network"], + accountid=self.account.name, + domainid=self.domain.id, + networkofferingid=nwoff_created.id, + zoneid=self.zone.id + ) + self.assertIsNotNone( + network, + "Network creation failed" + ) + self.cleanup.append(network) + # self.cleanup.append(nwoff_created) + # Launching a Virtual Machine + vm_created = VirtualMachine.create( + self.userapiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + networkids=network.id, + serviceofferingid=self.service_offering.id, + ) + self.assertIsNotNone( + vm_created, + "Failed to launch a VM under network created" + ) + # Listing all the IP Addresses for a user + list_ipaddresses_before = PublicIPAddress.list( + self.userapiclient, + listall=self.services["listall"] + ) + status = validateList(list_ipaddresses_before) + self.assertEquals( + PASS, + status[0], + "IP Addresses Association Failed while launching a VM" + ) + # Verifying the length of the list is 1 + self.assertEqual( + 1, + len(list_ipaddresses_before), + "IP Addresses Association Failed while launching a VM" + ) + # Associating an IP Addresses to Network created + associated_ipaddress = PublicIPAddress.create( + self.userapiclient, + services=self.services["network"], + networkid=network.id + ) + self.assertIsNotNone( + associated_ipaddress, + "Failed to Associate IP Address" + ) + # Listing all the IP Addresses for a user + list_ipaddresses_after = PublicIPAddress.list( + self.userapiclient, + listall=self.services["listall"] + ) + status = validateList(list_ipaddresses_after) + self.assertEquals( + PASS, + status[0], + "IP Addresses Association Failed" + ) + # Verifying the length of the list is 1 + self.assertEqual( + 2, + len(list_ipaddresses_after), + "Number of IP Addresses associated are not matching expected" + ) + # Listing Users + list_users = User.list( + self.apiClient, + listall=self.services["listall"], + account=self.account.name, + domainid=self.domain.id + ) + status = validateList(list_users) + self.assertEquals( + PASS, + status[0], + "Failed to list Users" + ) + # Listing counters + list_counters = Autoscale.listCounters(self.userapiclient) + status = validateList(list_counters) + self.assertEquals( + PASS, + status[0], + "Failed to list Counters" + ) + # Create Condition for scaleup Vm Policy + condition_scaleup = Autoscale.createCondition( + self.userapiclient, + counterid=list_counters[0].id, + relationaloperator='GT', + threshold='40' + ) + self.assertIsNotNone( + condition_scaleup, + "Failed to create Scaleup Condition" + ) + # Creating scaleup Vm Policy + scaleup_policy = Autoscale.createAutoscalePolicy( + self.userapiclient, + action='scaleup', + conditionids=condition_scaleup.id, + duration='40', + quiettime='300' + ) + self.assertIsNotNone( + scaleup_policy, + "Failed to create Scaleup VM Policy" + ) + # Create Condition for scaledown Vm Policy + condition_scaledown = Autoscale.createCondition( + self.userapiclient, + counterid=list_counters[0].id, + relationaloperator='GT', + threshold='10' + ) + self.assertIsNotNone( + condition_scaledown, + "Failed to create Scaledown Condition" + ) + # Creating scaledown Vm Policy + scaledown_policy = Autoscale.createAutoscalePolicy( + self.userapiclient, + action='scaledown', + conditionids=condition_scaledown.id, + duration='40', + quiettime='300' + ) + self.assertIsNotNone( + scaledown_policy, + "Failed to create Scaledown VM Policy" + ) + counterparam = { "snmpcommunity": "public", "snmpport": "161"} + # Create Autoscale VM Profile + vmprofile = Autoscale.createAutoscaleVmProfile( + self.userapiclient, + serviceofferingid=self.service_offering.id, + zoneid=self.zone.id, + templateid=self.template.id, + autoscaleuserid=list_users[0].id, + destroyvmgraceperiod='30', + counterparam=counterparam + ) + self.assertIsNotNone( + vmprofile, + "Failed to create Autoscale Vm Profile" + ) + self.services["lbrule"]["openfirewall"] = False + # Creating Load Balancer Rule + lbrule = LoadBalancerRule.create( + self.userapiclient, + self.services["lbrule"], + ipaddressid=associated_ipaddress.ipaddress.id, + accountid=self.account.name, + networkid=network.id, + domainid=self.domain.id + ) + self.assertIsNotNone( + lbrule, + "Failed to create Load Balancer Rule" + ) + # Listing Autoscale VM Groups + list_vmgroup_before = Autoscale.listAutoscaleVmGroup( + self.userapiclient, + listall=self.services["listall"], + lbruleid=lbrule.id + ) + # Verifying No Autoscale VM Groups are listed + self.assertIsNone( + list_vmgroup_before, + "Listed Autoscale VM Groups for newly created LB Rule" + ) + # Creating Autoscale VM Group + vmgroup = Autoscale.createAutoscaleVmGroup( + self.userapiclient, + lbruleid=lbrule.id, + minmembers='3', + maxmembers='10', + scaledownpolicyids=scaledown_policy.id, + scaleuppolicyids=scaleup_policy.id, + vmprofileid=vmprofile.id, + interval='30' + ) + self.assertIsNotNone( + vmgroup, + "Failed to create Autoscale VM Group" + ) + # Listing Autoscale VM Groups + list_vmgroup_after = Autoscale.listAutoscaleVmGroup( + self.userapiclient, + listall=self.services["listall"], + lbruleid=lbrule.id + ) + status = validateList(list_vmgroup_after) + self.assertEquals( + PASS, + status[0], + "Failed to list Autoscale VM group after creation" + ) + # Verifying only 1 Autoscale VM group is listed + self.assertEquals( + 1, + len(list_vmgroup_after), + "Autoscale VM group list count is not matching" + ) + # Disabling Autoscale VM group + vmgroup_disabled = Autoscale.disableAutoscaleVmGroup( + self.userapiclient, + id=vmgroup.id + ) + self.assertIsNotNone( + vmgroup_disabled, + "Failed to disable Autoscale VM group" + ) + # Verifyign the state of the VM Group afte renabling + self.assertEquals( + "disabled", + vmgroup_disabled.state, + "Disabled VM Group state is not matching" + ) + # Updating Autoscale VM Group + vmgroup_updated = Autoscale.updateAutoscaleVMGroup( + self.userapiclient, + id=vmgroup.id, + minmembers='3', + maxmembers='10', + scaledownpolicyids=scaledown_policy.id, + scaleuppolicyids=scaleup_policy.id, + interval='40' + ) + self.assertIsNotNone( + vmgroup_updated, + "Failed to update Autoscale VM group" + ) + self.assertEquals( + 40, + vmgroup_updated.interval, + "Updated Autoscale VM group interval value is not matching" + ) + # Enabling Autoscale VM group + vmgroup_enabled = Autoscale.enableAutoscaleVmGroup( + self.userapiclient, + id=vmgroup.id + ) + self.assertIsNotNone( + vmgroup_enabled, + "Failed to enable Autoscale VM group" + ) + # Verifyign the state of the VM Group afte renabling + self.assertEquals( + "enabled", + vmgroup_enabled.state, + "Enabled VM Group state is not matching" + ) + # Destroying the VM + vm_created.delete(self.userapiclient) + vm_created.expung(self.apiClient) + self.cleanup.append(self.account) + return diff --git a/test/integration/component/test_escalations_isos.py b/test/integration/component/test_escalations_isos.py new file mode 100644 index 0000000000..387a681a03 --- /dev/null +++ b/test/integration/component/test_escalations_isos.py @@ -0,0 +1,783 @@ +# 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 Local Modules +from marvin.cloudstackTestCase import cloudstackTestCase +from marvin.cloudstackAPI import (createVolume, + createTemplate) +from marvin.lib.base import (Volume, + Iso, + VirtualMachine, + Template, + Snapshot, + SecurityGroup, + Account, + Zone, + Network, + NetworkOffering, + DiskOffering, + ServiceOffering, + VmSnapshot, + SnapshotPolicy, + SSHKeyPair, + Resources, + Configurations, + VpnCustomerGateway, + Hypervisor, + VpcOffering, + VPC, + NetworkACL) +from marvin.lib.common import (get_zone, + get_domain, + get_template, + list_os_types) +from marvin.lib.utils import (validateList, + cleanup_resources, + random_gen) +from marvin.codes import (PASS, FAIL, EMPTY_LIST) +from nose.plugins.attrib import attr +import time + +class TestIsos(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + try: + cls._cleanup = [] + cls.testClient = super(TestIsos, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = cls.testClient.getParsedTestDataConfig() + # Get Domain, Zone, Template + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) + cls.template = get_template( + cls.api_client, + cls.zone.id, + cls.services["ostype"] + ) + cls.hypervisor = cls.testClient.getHypervisorInfo() + cls.services['mode'] = cls.zone.networktype + cls.account = Account.create( + cls.api_client, + cls.services["account"], + domainid=cls.domain.id + ) + # Getting authentication for user in newly created Account + cls.user = cls.account.user[0] + cls.userapiclient = cls.testClient.getUserApiClient(cls.user.username, cls.domain.name) + cls._cleanup.append(cls.account) + except Exception as e: + cls.tearDownClass() + raise Exception("Warning: Exception in setup : %s" % e) + return + + def setUp(self): + + self.apiClient = self.testClient.getApiClient() + self.cleanup = [] + + def tearDown(self): + #Clean up, terminate the created resources + cleanup_resources(self.apiClient, self.cleanup) + return + + @classmethod + def tearDownClass(cls): + try: + cleanup_resources(cls.api_client, cls._cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + + return + + def __verify_values(self, expected_vals, actual_vals): + """ + @Desc: Function to verify expected and actual values + @Steps: + Step1: Initializing return flag to True + Step1: Verifying length of expected and actual dictionaries is matching. + If not matching returning false + Step2: Listing all the keys from expected dictionary + Step3: Looping through each key from step2 and verifying expected and actual dictionaries have same value + If not making return flag to False + Step4: returning the return flag after all the values are verified + """ + return_flag = True + + if len(expected_vals) != len(actual_vals): + return False + + keys = expected_vals.keys() + for i in range(0, len(expected_vals)): + exp_val = expected_vals[keys[i]] + act_val = actual_vals[keys[i]] + if exp_val == act_val: + return_flag = return_flag and True + else: + return_flag = return_flag and False + self.debug("expected Value: %s, is not matching with actual value: %s" % ( + exp_val, + act_val + )) + return return_flag + + @attr(tags=["advanced", "basic", "provisioning"]) + def test_01_list_isos_pagination(self): + """ + @Desc: Test to List ISO's pagination + @steps: + Step1: Listing all the ISO's for a user + Step2: Verifying that no ISO's are listed + Step3: Creating (page size + 1) number of ISO's + Step4: Listing all the ISO's again for a user + Step5: Verifying that list size is (page size + 1) + Step6: Listing all the ISO's in page1 + Step7: Verifying that list size is (page size) + Step8: Listing all the ISO's in page2 + Step9: Verifying that list size is 1 + Step10: Listing the ISO's by Id + Step11: Verifying if the ISO is downloaded and ready. + If yes the continuing + If not waiting and checking for iso to be ready till timeout + Step12: Deleting the ISO present in page 2 + Step13: Listing all the ISO's in page2 + Step14: Verifying that no ISO's are listed + """ + # Listing all the ISO's for a User + list_iso_before = Iso.list( + self.userapiclient, + listall=self.services["listall"], + isofilter=self.services["templatefilter"] + ) + # Verifying that no ISOs are listed + self.assertIsNone( + list_iso_before, + "ISOs listed for newly created User" + ) + self.services["iso"]["zoneid"] = self.zone.id + # Creating pagesize + 1 number of ISO's + for i in range(0, (self.services["pagesize"] + 1)): + iso_created = Iso.create( + self.userapiclient, + self.services["iso"] + ) + self.assertIsNotNone( + iso_created, + "ISO creation failed" + ) + if(i < self.services["pagesize"]): + self.cleanup.append(iso_created) + + # Listing all the ISO's for a User + list_iso_after = Iso.list( + self.userapiclient, + listall=self.services["listall"], + isofilter=self.services["templatefilter"] + ) + status = validateList(list_iso_after) + self.assertEquals( + PASS, + status[0], + "ISO's creation failed" + ) + # Verifying that list size is pagesize + 1 + self.assertEquals( + self.services["pagesize"] + 1, + len(list_iso_after), + "Failed to create pagesize + 1 number of ISO's" + ) + # Listing all the ISO's in page 1 + list_iso_page1 = Iso.list( + self.userapiclient, + listall=self.services["listall"], + isofilter=self.services["templatefilter"], + page=1, + pagesize=self.services["pagesize"] + ) + status = validateList(list_iso_page1) + self.assertEquals( + PASS, + status[0], + "Failed to list ISO's in page 1" + ) + # Verifying the list size to be equal to pagesize + self.assertEquals( + self.services["pagesize"], + len(list_iso_page1), + "Size of ISO's in page 1 is not matching" + ) + # Listing all the Templates in page 2 + list_iso_page2 = Iso.list( + self.userapiclient, + listall=self.services["listall"], + isofilter=self.services["templatefilter"], + page=2, + pagesize=self.services["pagesize"] + ) + status = validateList(list_iso_page2) + self.assertEquals( + PASS, + status[0], + "Failed to list ISo's in page 2" + ) + # Verifying the list size to be equal to 1 + self.assertEquals( + 1, + len(list_iso_page2), + "Size of ISO's in page 2 is not matching" + ) + # Verifying the state of the ISO to be ready. If not waiting for state to become ready + iso_ready = False + count = 0 + while iso_ready is False: + list_iso = Iso.list( + self.userapiclient, + listall=self.services["listall"], + isofilter=self.services["templatefilter"], + id=iso_created.id + ) + status = validateList(list_iso) + self.assertEquals( + PASS, + status[0], + "Failed to list ISO by Id" + ) + if list_iso[0].isready is True: + iso_ready = True + elif (str(list_iso[0].status) == "Error"): + self.fail("Created ISO is in Errored state") + break + elif count > 10: + self.fail("Timed out before ISO came into ready state") + break + else: + time.sleep(self.services["sleep"]) + count = count + 1 + + # Deleting the ISO present in page 2 + Iso.delete( + iso_created, + self.userapiclient + ) + # Listing all the ISO's in page 2 again + list_iso_page2 = Iso.list( + self.userapiclient, + listall=self.services["listall"], + isofilter=self.services["templatefilter"], + page=2, + pagesize=self.services["pagesize"] + ) + # Verifying that there are no ISO's listed + self.assertIsNone( + list_iso_page2, + "ISO's not deleted from page 2" + ) + del self.services["iso"]["zoneid"] + return + + @attr(tags=["advanced", "basic", "provisioning"]) + def test_02_download_iso(self): + """ + @Desc: Test to Download ISO + @steps: + Step1: Listing all the ISO's for a user + Step2: Verifying that no ISO's are listed + Step3: Creating an ISO + Step4: Listing all the ISO's again for a user + Step5: Verifying that list size is 1 + Step6: Verifying if the ISO is in ready state. + If yes the continuing + If not waiting and checking for template to be ready till timeout + Step7: Downloading the ISO (Extract) + Step8: Verifying the details of downloaded ISO + """ + # Listing all the ISO's for a User + list_iso_before = Iso.list( + self.userapiclient, + listall=self.services["listall"], + isofilter=self.services["templatefilter"] + ) + # Verifying that no ISOs are listed + self.assertIsNone( + list_iso_before, + "ISOs listed for newly created User" + ) + self.services["iso"]["zoneid"] = self.zone.id + self.services["iso"]["isextractable"] = True + # Creating an ISO's + iso_created = Iso.create( + self.userapiclient, + self.services["iso"] + ) + self.assertIsNotNone( + iso_created, + "ISO creation failed" + ) + self.cleanup.append(iso_created) + # Listing all the ISO's for a User + list_iso_after = Iso.list( + self.userapiclient, + listall=self.services["listall"], + isofilter=self.services["templatefilter"] + ) + status = validateList(list_iso_after) + self.assertEquals( + PASS, + status[0], + "ISO's creation failed" + ) + # Verifying that list size is 1 + self.assertEquals( + 1, + len(list_iso_after), + "Failed to create an ISO's" + ) + # Verifying the state of the ISO to be ready. If not waiting for state to become ready + iso_ready = False + count = 0 + while iso_ready is False: + list_iso = Iso.list( + self.userapiclient, + listall=self.services["listall"], + isofilter=self.services["templatefilter"], + id=iso_created.id + ) + status = validateList(list_iso) + self.assertEquals( + PASS, + status[0], + "Failed to list ISO by Id" + ) + if list_iso[0].isready is True: + iso_ready = True + elif (str(list_iso[0].status) == "Error"): + self.fail("Created ISO is in Errored state") + break + elif count > 10: + self.fail("Timed out before ISO came into ready state") + break + else: + time.sleep(self.services["sleep"]) + count = count + 1 + + # Downloading the ISO + download_iso = Iso.extract( + self.userapiclient, + iso_created.id, + mode="HTTP_DOWNLOAD", + zoneid=self.zone.id + ) + self.assertIsNotNone( + download_iso, + "Download ISO failed" + ) + # Verifying the details of downloaded ISO + self.assertEquals( + "DOWNLOAD_URL_CREATED", + download_iso.state, + "Download URL not created for ISO" + ) + self.assertIsNotNone( + download_iso.url, + "Download URL not created for ISO" + ) + self.assertEquals( + iso_created.id, + download_iso.id, + "Download ISO details are not same as ISO created" + ) + del self.services["iso"]["zoneid"] + del self.services["iso"]["isextractable"] + return + + @attr(tags=["advanced", "basic", "provisioning"]) + def test_03_edit_iso_details(self): + """ + @Desc: Test to Edit ISO name, displaytext, OSType + @steps: + Step1: Listing all the ISO's for a user + Step2: Verifying that no ISO's are listed + Step3: Creating an ISO + Step4: Listing all the ISO's again for a user + Step5: Verifying that list size is 1 + Step6: Verifying if the ISO is in ready state. + If yes the continuing + If not waiting and checking for template to be ready till timeout + Step7: Editing the ISO's name, displaytext + Step8: Verifying that ISO name and displaytext are edited + Step9: Editing the ISO name, displaytext, ostypeid + Step10: Verifying that ISO name, displaytext and ostypeid are edited + """ + # Listing all the ISO's for a User + list_iso_before = Iso.list( + self.userapiclient, + listall=self.services["listall"], + isofilter=self.services["templatefilter"] + ) + # Verifying that no ISOs are listed + self.assertIsNone( + list_iso_before, + "ISOs listed for newly created User" + ) + self.services["iso"]["zoneid"] = self.zone.id + # Creating an ISO's + iso_created = Iso.create( + self.userapiclient, + self.services["iso"] + ) + self.assertIsNotNone( + iso_created, + "ISO creation failed" + ) + self.cleanup.append(iso_created) + # Listing all the ISO's for a User + list_iso_after = Iso.list( + self.userapiclient, + listall=self.services["listall"], + isofilter=self.services["templatefilter"] + ) + status = validateList(list_iso_after) + self.assertEquals( + PASS, + status[0], + "ISO's creation failed" + ) + # Verifying that list size is 1 + self.assertEquals( + 1, + len(list_iso_after), + "Failed to create an ISO's" + ) + # Verifying the state of the ISO to be ready. If not waiting for state to become ready + iso_ready = False + count = 0 + while iso_ready is False: + list_iso = Iso.list( + self.userapiclient, + listall=self.services["listall"], + isofilter=self.services["templatefilter"], + id=iso_created.id + ) + status = validateList(list_iso) + self.assertEquals( + PASS, + status[0], + "Failed to list ISO by Id" + ) + if list_iso[0].isready is True: + iso_ready = True + elif (str(list_iso[0].status) == "Error"): + self.fail("Created ISO is in Errored state") + break + elif count > 10: + self.fail("Timed out before ISO came into ready state") + break + else: + time.sleep(self.services["sleep"]) + count = count + 1 + + # Editing the ISO name, displaytext + edited_iso = Iso.update( + iso_created, + self.userapiclient, + name="NewISOName", + displaytext="NewISODisplayText" + ) + self.assertIsNotNone( + edited_iso, + "Editing ISO failed" + ) + # Verifying the details of edited template + expected_dict = { + "id":iso_created.id, + "name":"NewISOName", + "displaytest":"NewISODisplayText", + "account":iso_created.account, + "domainid":iso_created.domainid, + "isfeatured":iso_created.isfeatured, + "ostypeid":iso_created.ostypeid, + "ispublic":iso_created.ispublic, + } + actual_dict = { + "id":edited_iso.id, + "name":edited_iso.name, + "displaytest":edited_iso.displaytext, + "account":edited_iso.account, + "domainid":edited_iso.domainid, + "isfeatured":edited_iso.isfeatured, + "ostypeid":edited_iso.ostypeid, + "ispublic":edited_iso.ispublic, + } + edit_iso_status = self.__verify_values( + expected_dict, + actual_dict + ) + self.assertEqual( + True, + edit_iso_status, + "Edited ISO details are not as expected" + ) + # Editing the ISO name, displaytext, ostypeid + ostype_list = list_os_types(self.userapiclient) + status = validateList(ostype_list) + self.assertEquals( + PASS, + status[0], + "Failed to list OS Types" + ) + for i in range(0, len(ostype_list)): + if ostype_list[i].id != iso_created.ostypeid: + newostypeid = ostype_list[i].id + break + + edited_iso = Iso.update( + iso_created, + self.userapiclient, + name=iso_created.name, + displaytext=iso_created.displaytext, + ostypeid=newostypeid + ) + self.assertIsNotNone( + edited_iso, + "Editing ISO failed" + ) + # Verifying the details of edited template + expected_dict = { + "id":iso_created.id, + "name":iso_created.name, + "displaytest":iso_created.displaytext, + "account":iso_created.account, + "domainid":iso_created.domainid, + "isfeatured":iso_created.isfeatured, + "ostypeid":newostypeid, + "ispublic":iso_created.ispublic, + } + actual_dict = { + "id":edited_iso.id, + "name":edited_iso.name, + "displaytest":edited_iso.displaytext, + "account":edited_iso.account, + "domainid":edited_iso.domainid, + "isfeatured":edited_iso.isfeatured, + "ostypeid":edited_iso.ostypeid, + "ispublic":edited_iso.ispublic, + } + edit_iso_status = self.__verify_values( + expected_dict, + actual_dict + ) + self.assertEqual( + True, + edit_iso_status, + "Edited ISO details are not as expected" + ) + del self.services["iso"]["zoneid"] + return + + @attr(tags=["advanced", "basic", "provisioning"]) + def test_04_copy_iso(self): + """ + @Desc: Test to copy ISO from one zone to another + @steps: + Step1: Listing Zones available for a user + Step2: Verifying if the zones listed are greater than 1. + If Yes continuing. + If not halting the test. + Step3: Listing all the ISO's for a user in zone1 + Step4: Verifying that no ISO's are listed + Step5: Listing all the ISO's for a user in zone2 + Step6: Verifying that no ISO's are listed + Step7: Creating an ISO in zone 1 + Step8: Listing all the ISO's again for a user in zone1 + Step9: Verifying that list size is 1 + Step10: Listing all the ISO's for a user in zone2 + Step11: Verifying that no ISO's are listed + Step12: Copying the ISO created in step7 from zone1 to zone2 + Step13: Listing all the ISO's for a user in zone2 + Step14: Verifying that list size is 1 + Step15: Listing all the ISO's for a user in zone1 + Step16: Verifying that list size is 1 + """ + # Listing Zones available for a user + zones_list = Zone.list( + self.userapiclient, + available=True + ) + status = validateList(zones_list) + self.assertEquals( + PASS, + status[0], + "Failed to list Zones" + ) + if not len(zones_list) > 1: + self.fail("Enough zones doesnot exists to copy iso") + else: + # Listing all the ISO's for a User in Zone 1 + list_isos_zone1 = Iso.list( + self.userapiclient, + listall=self.services["listall"], + isofilter=self.services["templatefilter"], + zoneid=zones_list[0].id + ) + # Verifying that no ISO's are listed + self.assertIsNone( + list_isos_zone1, + "ISO's listed for newly created User in Zone1" + ) + # Listing all the ISO's for a User in Zone 2 + list_isos_zone2 = Iso.list( + self.userapiclient, + listall=self.services["listall"], + isofilter=self.services["templatefilter"], + zoneid=zones_list[1].id + ) + # Verifying that no ISO's are listed + self.assertIsNone( + list_isos_zone2, + "ISO's listed for newly created User in Zone2" + ) + self.services["iso"]["zoneid"] = zones_list[0].id + # Creating an ISO in Zone 1 + iso_created = Iso.create( + self.userapiclient, + self.services["iso"] + ) + self.assertIsNotNone( + iso_created, + "ISO creation failed" + ) + self.cleanup.append(iso_created) + # Listing all the ISO's for a User in Zone 1 + list_isos_zone1 = Iso.list( + self.userapiclient, + listall=self.services["listall"], + isofilter=self.services["templatefilter"], + zoneid=zones_list[0].id + ) + status = validateList(list_isos_zone1) + self.assertEquals( + PASS, + status[0], + "ISO creation failed in Zone1" + ) + # Verifying that list size is 1 + self.assertEquals( + 1, + len(list_isos_zone1), + "Failed to create a Template" + ) + # Listing all the ISO's for a User in Zone 2 + list_isos_zone2 = Iso.list( + self.userapiclient, + listall=self.services["listall"], + isofilter=self.services["templatefilter"], + zoneid=zones_list[1].id + ) + # Verifying that no ISO's are listed + self.assertIsNone( + list_isos_zone2, + "ISO's listed for newly created User in Zone2" + ) + # Verifying the state of the ISO to be ready. If not waiting for state to become ready + iso_ready = False + count = 0 + while iso_ready is False: + list_iso = Iso.list( + self.userapiclient, + listall=self.services["listall"], + isofilter=self.services["templatefilter"], + id=iso_created.id + ) + status = validateList(list_iso) + self.assertEquals( + PASS, + status[0], + "Failed to list ISO by Id" + ) + if list_iso[0].isready is True: + iso_ready = True + elif (str(list_iso[0].status) == "Error"): + self.fail("Created ISO is in Errored state") + break + elif count > 10: + self.fail("Timed out before ISO came into ready state") + break + else: + time.sleep(self.services["sleep"]) + count = count + 1 + + # Copying the ISO from Zone1 to Zone2 + copied_iso = Iso.copy( + self.userapiclient, + iso_created.id, + sourcezoneid=iso_created.zoneid, + destzoneid=zones_list[1].id + ) + self.assertIsNotNone( + copied_iso, + "Copying ISO from Zone1 to Zone2 failed" + ) + # Listing all the ISO's for a User in Zone 1 + list_isos_zone1 = Iso.list( + self.userapiclient, + listall=self.services["listall"], + isofilter=self.services["templatefilter"], + zoneid=zones_list[0].id + ) + status = validateList(list_isos_zone1) + self.assertEquals( + PASS, + status[0], + "ISO creation failed in Zone1" + ) + # Verifying that list size is 1 + self.assertEquals( + 1, + len(list_isos_zone1), + "Failed to create a Template" + ) + # Listing all the ISO's for a User in Zone 2 + list_isos_zone2 = Iso.list( + self.userapiclient, + listall=self.services["listall"], + isofilter=self.services["templatefilter"], + zoneid=zones_list[1].id + ) + status = validateList(list_isos_zone2) + self.assertEquals( + PASS, + status[0], + "ISO failed to copy into Zone2" + ) + # Verifying that list size is 1 + self.assertEquals( + 1, + len(list_isos_zone2), + "ISO failed to copy into Zone2" + ) + self.assertNotEquals( + "Connection refused", + list_isos_zone2[0].status, + "Failed to copy ISO" + ) + self.assertEquals( + True, + list_isos_zone2[0].isready, + "Failed to copy ISO" + ) + del self.services["iso"]["zoneid"] + return \ No newline at end of file diff --git a/test/integration/component/test_escalations_networks.py b/test/integration/component/test_escalations_networks.py new file mode 100644 index 0000000000..6f9266bd0d --- /dev/null +++ b/test/integration/component/test_escalations_networks.py @@ -0,0 +1,2602 @@ +# 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 Local Modules +from marvin.cloudstackTestCase import * +from marvin.cloudstackException import * +from marvin.cloudstackAPI import * +from marvin.sshClient import SshClient +from marvin.lib.utils import * +from marvin.lib.base import * +from marvin.lib.common import * +from marvin.lib.utils import checkVolumeSize +from marvin.codes import SUCCESS +from nose.plugins.attrib import attr +from time import sleep + +class TestNetworks_1(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + try: + cls._cleanup = [] + cls.testClient = super(TestNetworks_1, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = cls.testClient.getParsedTestDataConfig() + # Get Domain, Zone, Template + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) + cls.template = get_template( + cls.api_client, + cls.zone.id, + cls.services["ostype"] + ) + if cls.zone.localstorageenabled: + cls.storagetype = 'local' + cls.services["service_offerings"]["tiny"]["storagetype"] = 'local' + else: + cls.storagetype = 'shared' + cls.services["service_offerings"]["tiny"]["storagetype"] = 'shared' + + cls.services['mode'] = cls.zone.networktype + cls.services["virtual_machine"]["hypervisor"] = cls.testClient.getHypervisorInfo() + cls.services["virtual_machine"]["zoneid"] = cls.zone.id + cls.services["virtual_machine"]["template"] = cls.template.id + cls.services["network_without_acl"]["zoneid"] = cls.zone.id + # Create Network offering + cls.network_offering = NetworkOffering.create( + cls.api_client, + cls.services["network_offering_vlan"], + ) + # Enable Network offering + cls.network_offering.update(cls.api_client, state='Enabled') + cls.services["network_without_acl"]["networkoffering"] = cls.network_offering.id + cls.service_offering = ServiceOffering.create( + cls.api_client, + cls.services["service_offerings"]["tiny"] + ) + # Creating Disk offering, Service Offering and Account + cls.account = Account.create( + cls.api_client, + cls.services["account"], + domainid=cls.domain.id + ) + # Getting authentication for user in newly created Account + cls.user = cls.account.user[0] + cls.userapiclient = cls.testClient.getUserApiClient(cls.user.username, cls.domain.name) + cls.account_network = Network.create( + cls.userapiclient, + cls.services["network_without_acl"], + cls.account.name, + cls.account.domainid + ) + cls._cleanup.append(cls.account_network) + cls._cleanup.append(cls.account) + cls._cleanup.append(cls.service_offering) + cls._cleanup.append(cls.network_offering) + except Exception as e: + cls.tearDownClass() + raise Exception("Warning: Exception in setup : %s" % e) + return + + def setUp(self): + + self.apiClient = self.testClient.getApiClient() + self.cleanup = [] + + def tearDown(self): + # Clean up, terminate the created volumes + cleanup_resources(self.apiClient, self.cleanup) + return + + @classmethod + def tearDownClass(cls): + try: + cleanup_resources(cls.api_client, cls._cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + + def __verify_values(self, expected_vals, actual_vals): + """ + @summary: Function to verify expected and actual values + Step1: Initializing return flag to True + Step2: Verifying length of expected and actual dictionaries is matching. + If not matching returning false + Step3: Listing all the keys from expected dictionary + Step4: Looping through each key from step2 and verifying expected and actual dictionaries have same value + If not making return flag to False + Step5: returning the return flag after all the values are verified + """ + return_flag = True + + if len(expected_vals) != len(actual_vals): + return False + + keys = expected_vals.keys() + for i in range(0, len(expected_vals)): + exp_val = expected_vals[keys[i]] + act_val = actual_vals[keys[i]] + if exp_val == act_val: + return_flag = return_flag and True + else: + return_flag = return_flag and False + self.debug("expected Value: %s, is not matching with actual value: %s" % ( + exp_val, + act_val + )) + return return_flag + + @attr(tags=["advanced"]) + def test_01_list_networks_pagination(self): + """ + @Desc: Test List Networks pagination + @Steps + Step1 : Listing the networks for a user + Step2 : Verifying listed networks for account created at class level + Step3 : If number of networks is less than (pagesize + 1), then creating them + Step4 : Listing the networks again + Step5 : Verifying for the length of the networks that it is (pagesize + 1) + Step6 : Listing and verifying all the networks in page1 + Step7 : Listing and verifying all the networks in page2 + Step8 : Verifying that on page 2 only 1 network is present and the network on page 2 is not present in page1 + """ + list_zones = Zone.list( + self.userapiclient, + id=self.zone.id + ) + status = validateList(list_zones) + self.assertEquals(PASS, status[0], "No Zones found for a given id") + self.services["network_without_acl"]["zoneid"] = list_zones[0].id + # Listing the networks for a user + list_networks_before = Network.list( + self.userapiclient, + listall=self.services["listall"] + ) + # Verifying listed networks for account created at class level + if list_networks_before is None: + self.assertEqual( + len(list_networks_before), + 0, + "Network create failed at class level" + ) + # If number of networks is less than (pagesize + 1), then creating network + elif len(list_networks_before) == 1: + for i in range(0, (self.services["pagesize"])): + network_created = Network.create( + self.userapiclient, + self.services["network_without_acl"], + ) + self.cleanup.append(network_created) + self.assertIsNotNone( + network_created, + "Network is not created" + ) + # Creating expected and actual values dictionaries + expected_dict = { + "id":list_zones[0].id, + "name":self.services["network_without_acl"]["name"], + } + actual_dict = { + "id":network_created.zoneid, + "name":network_created.name, + } + network_status = self.__verify_values( + expected_dict, + actual_dict + ) + self.assertEqual( + True, + network_status, + "Listed network details are not as expected" + ) + else: + self.assertEqual( + len(list_networks_before), + 1, + "more than 1 network created at class level" + ) + # Listing the networks + list_networks_after = Network.list(self.userapiclient, listall=self.services["listall"]) + status = validateList(list_networks_after) + self.assertEquals(PASS, status[0], "No networks found using list call") + # Asserting for the length of the networks + self.assertEqual( + len(list_networks_after), + (self.services["pagesize"] + 1), + "Number of networks created is not matching expected" + ) + # Listing all the networks in page1 + list_networks_page1 = Network.list( + self.userapiclient, + listall=self.services["listall"], + page=1, + pagesize=self.services["pagesize"] + ) + status = validateList(list_networks_page1) + self.assertEquals(PASS, status[0], "No networks found at page 1") + self.assertEqual( + len(list_networks_page1), + self.services["pagesize"], + "List network response is not matching with the page size length for page 1" + ) + # Listing all the networks in page2 + list_networks_page2 = Network.list( + self.userapiclient, + listall=self.services["listall"], + page=2, + pagesize=self.services["pagesize"] + ) + status = validateList(list_networks_page2) + self.assertEquals(PASS, status[0], "No networks found at page 2") + self.assertEqual( + len(list_networks_page2), + 1, + "List network response is not matching with the page size length for page 2" + ) + network_page2 = list_networks_page2[0] + for i in range(0, len(list_networks_page1)): + network_page1 = list_networks_page1[i] + self.assertNotEquals( + network_page2.id, + network_page1.id, + "Network listed in page 2 is also listed in page 1" + ) + return + + @attr(tags=["advanced"]) + def test_02_create_network_without_sourcenat(self): + """ + @Desc: Test create network if supported services doesn't have sourcenat + @Steps + Step1 : Create Network Offering without sourcenat + Step2 : Enable network offering + Step3 : Create network with sourcenat diasbled network offering + Step4 : Verifying that it raises an exception + """ + # Create Network offering specifically sourcenat disabled + network_offering_without_sourcenat = NetworkOffering.create( + self.apiClient, + self.services["network_offering_without_sourcenat"], + ) + if network_offering_without_sourcenat is None: + self.fail("Creation of network offering without sourcenat failed") + self.cleanup.append(network_offering_without_sourcenat) + + # Enable network offering + network_offering_without_sourcenat.update(self.apiClient, state='Enabled') + self.services["network_without_acl"]["networkoffering"] = network_offering_without_sourcenat.id + + # Network create call raise an exception + with self.assertRaises(Exception): + network_created = Network.create( + self.userapiclient, + self.services["network_without_acl"], + ) + if network_created is not None: + self.cleanup.append(network_created) + self.services["network_without_acl"]["networkoffering"] = self.network_offering.id + return + + @attr(tags=["advanced"]) + def test_03_list_vpc_pagination(self): + """ + @Desc: Test create vpc with network domain as parameter + @Steps + Step1 : List VPC Offering + Step2 : List VPCs for newly created user + Step3 : Create VPCs without network domain based on page size + Step4 : Verify count of VPCs created + Step5 : Listing all the VPCs in page1 + Step6 : Listing all the VPCs in page2 + Step7 : Verifying that on page 2 only 1 vpc is present and the vpc on page 2 is not present in page1 + Step8 : Deleting a single vpc and verifying that vpc does not exists on page 2 + """ + # List VPC Offering + vpc_offs_list = VpcOffering.list(self.userapiclient, isdefault="true") + if vpc_offs_list is None: + self.fail("Default VPC offerings not found") + else: + vpc_offs = vpc_offs_list[0] + # List VPCs + vpc_list = VPC.list( + self.userapiclient, + listall=self.services["listall"] + ) + # verify no vpc is present for newly created user + status = validateList(vpc_list) + self.assertEquals(FAIL, status[0], "VPCs found for newly created user") + vpc_count_before = 0 + for i in range(0, (self.services["pagesize"] + 1)): + vpc_1 = VPC.create( + self.userapiclient, + self.services["vpc"], + vpcofferingid=vpc_offs.id, + zoneid=self.zone.id, + ) + if(i < (self.services["pagesize"])): + self.cleanup.append(vpc_1) + # verify vpc is created and not none + self.assertIsNotNone(vpc_1, "VPC is not created") + # Verify VPC name with test data + self.assertNotEquals( + -1, + vpc_1.name.find(self.services["vpc"]["name"]), + "VPC name not matched" + ) + # verify zone with test data + self.assertEquals( + self.zone.id, + vpc_1.zoneid, + "Zone is not matching in the vpc created" + ) + # Asserting for the length of the VPCs + vpc_count_after = VPC.list(self.userapiclient, listall=self.services["listall"]) + status = validateList(vpc_count_after) + self.assertEquals(PASS, status[0], "VPC list count is null") + self.assertEqual( + len(vpc_count_after), + (self.services["pagesize"] + 1), + "Number of VPCs created is not matching expected" + ) + # Listing all the VPCs in page1 + list_vpcs_page1 = VPC.list( + self.userapiclient, + listall=self.services["listall"], + page=1, + pagesize=self.services["pagesize"] + ) + status = validateList(list_vpcs_page1) + self.assertEquals(PASS, status[0], "No vpcs found in Page 1") + self.assertEqual( + len(list_vpcs_page1), + self.services["pagesize"], + "List vpc response is not matching with the page size length for page 1" + ) + # Listing all the vpcs in page2 + list_vpcs_page2 = VPC.list( + self.userapiclient, + listall=self.services["listall"], + page=2, + pagesize=self.services["pagesize"] + ) + status = validateList(list_vpcs_page2) + self.assertEquals(PASS, status[0], "No vpc found in Page 2") + self.assertEqual( + 1, + len(list_vpcs_page2), + "List VPCs response is not matching with the page size length for page 2" + ) + vpc_page2 = list_vpcs_page2[0] + # Verifying that on page 2 only 1 vpc is present and the vpc on page 2 is not present in page1 + for i in range(0, len(list_vpcs_page1)): + vpc_page1 = list_vpcs_page1[i] + self.assertNotEquals( + vpc_page2.id, + vpc_page1.id, + "VPC listed in page 2 is also listed in page 1" + ) + # Deleting a single vpc and verifying that vpc does not exists on page 2 + VPC.delete(vpc_1, self.userapiclient) + list_vpc_response = VPC.list( + self.userapiclient, + listall=self.services["listall"], + page=2, + pagesize=self.services["pagesize"] + ) + self.assertEqual( + list_vpc_response, + None, + "vpc was not deleted" + ) + return + + @attr(tags=["advanced"]) + def test_04_create_vpc_with_networkdomain(self): + """ + @Desc: Test create vpc with network domain as parameter + @Steps + Step1 : List VPC Offering + Step2 : List VPCs for newly created user + Step3 : Create VPC + Step4 : List VPC and verify that count is increased by 1 + """ + # List VPC Offering + vpc_offs_list = VpcOffering.list(self.userapiclient, isdefault="true") + if vpc_offs_list is None: + self.fail("Default VPC offerings not found") + else: + vpc_offs = vpc_offs_list[0] + # List VPCs for newly created user + vpc_list = VPC.list( + self.userapiclient, + listall=self.services["listall"] + ) + # No VPCs should be present for newly created user + status = validateList(vpc_list) + self.assertEquals(FAIL, status[0], "VPCs found for newly created user") + vpc_count_before = 0 + vpc_1 = VPC.create( + self.userapiclient, + self.services["vpc_network_domain"], + vpcofferingid=vpc_offs.id, + zoneid=self.zone.id, + ) + self.assertIsNotNone(vpc_1, "VPC is not created") + self.cleanup.append(vpc_1) + # List VPCs + vpc_list = VPC.list( + self.userapiclient, + listall=self.services["listall"] + ) + status = validateList(vpc_list) + self.assertEquals(PASS, status[0], "VPC is not created") + self.assertEquals( + vpc_count_before + 1, + len(vpc_list), + "VPC is not created" + ) + return + + @attr(tags=["advanced"]) + def test_05_list_network_offerings_with_and_without_vpc(self): + """ + @Desc: Test list network offerings for vpc true and false parameters + @Steps + Step1 : List network offering + Step2 : Create network offering with default setting of vpc = false + Step3 : List network offering + Step4 : Verify that count is incremented by 1 + Step5 : List network offering with additional parameter of vpc = true + Step6 : Verify that its count is same as step 1 + Step7 : List network offering with additional parameter of vpc = false + Step8 : Verify that its count is same as step 3 + """ + # List all network offering + network_offering_before_count = NetworkOffering.list(self.userapiclient) + status = validateList(network_offering_before_count) + self.assertEquals(PASS, status[0], "Default network offering not present") + # List network offering for vpc = true + network_offering_vpc_true_before_count = NetworkOffering.list( + self.userapiclient, + forvpc="true", + zoneid=self.zone.id, + guestiptype=self.services["network_offering_vlan"]["guestiptype"], + supportedServices="SourceNat", + specifyvlan=self.services["network_offering_vlan"]["specifyvlan"], + state="Enabled" + ) + status = validateList(network_offering_vpc_true_before_count) + self.assertEquals(PASS, status[0], "Default network offering not present for vpc = true") + # List network offering + network_offering_vpc_false_before_count = NetworkOffering.list( + self.userapiclient, + forvpc="false", + zoneid=self.zone.id, + guestiptype=self.services["network_offering_vlan"]["guestiptype"], + supportedServices="SourceNat", + specifyvlan=self.services["network_offering_vlan"]["specifyvlan"], + state="Enabled" + ) + status = validateList(network_offering_vpc_false_before_count) + self.assertEquals(PASS, status[0], "Default network offering not present for vpc = false") + # Create network Offering + network_offering = NetworkOffering.create( + self.apiClient, + self.services["network_offering_vlan"], + ) + self.assertIsNotNone(network_offering, "Network offering is not created") + # Enable Network offering + network_offering.update(self.apiClient, state='Enabled') + self.cleanup.append(network_offering) + # List network offering + network_offering_after_count = NetworkOffering.list(self.userapiclient) + status = validateList(network_offering_after_count) + self.assertEquals(PASS, status[0], "Network Offering list results in null") + # Verify that count is incremented by 1 + self.assertEquals( + len(network_offering_before_count) + 1, + len(network_offering_after_count), + "Network offering is not created" + ) + # List network offering with additional parameter of vpc = true + network_offering_vpc_true_after_count = NetworkOffering.list( + self.userapiclient, + forvpc="true", + zoneid=self.zone.id, + guestiptype=self.services["network_offering_vlan"]["guestiptype"], + supportedServices="SourceNat", + specifyvlan=self.services["network_offering_vlan"]["specifyvlan"], + state="Enabled" + ) + status = validateList(network_offering_vpc_true_after_count) + self.assertEquals(PASS, status[0], "Network Offering list results in null") + # Verify that its count is same as step 1 + self.assertEquals( + len(network_offering_vpc_true_before_count), + len(network_offering_vpc_true_after_count), + "Default Network offering is created with vpc as true" + ) + # List network offering with additional parameter of vpc = false + network_offering_vpc_false_after_count = NetworkOffering.list( + self.userapiclient, + forvpc="false", + zoneid=self.zone.id, + guestiptype=self.services["network_offering_vlan"]["guestiptype"], + supportedServices="SourceNat", + specifyvlan=self.services["network_offering_vlan"]["specifyvlan"], + state="Enabled" + ) + status = validateList(network_offering_vpc_false_after_count) + self.assertEquals(PASS, status[0], "Network Offering list results in null") + # Verify that its count is same as step 3 + self.assertEquals( + len(network_offering_vpc_false_before_count) + 1, + len(network_offering_vpc_false_after_count), + "Default Network offering is not created with vpc as false" + ) + return + + @attr(tags=["advanced"]) + def test_06_create_network_in_vpc(self): + """ + @Desc: Test create network in vpc and verify VPC name + @Steps + Step1 : List VPC Offering + Step2 : List VPCs for newly created user + Step3 : Create VPC + Step4 : List VPC and verify that count is increased by 1 + Step5 : Create network + Step6 : List VPCs for specific network created in vpc + Step7 : Verify vpc name matches for newly created vpc name and name from vpc list + """ + # List VPC Offering + vpc_offs_list = VpcOffering.list(self.userapiclient, + isdefault="true", + ) + if vpc_offs_list is None: + self.fail("Default VPC offerings not found") + else: + vpc_offs = vpc_offs_list[0] + # List VPCs for newly created user + vpc_list = VPC.list( + self.userapiclient, + listall=self.services["listall"] + ) + # No VPCs should be present for newly created user + status = validateList(vpc_list) + self.assertEquals(FAIL, status[0], "VPCs found for newly created user") + vpc_count_before = 0 + vpc_1 = VPC.create( + self.userapiclient, + self.services["vpc"], + vpcofferingid=vpc_offs.id, + zoneid=self.zone.id, + ) + self.assertIsNotNone(vpc_1, "VPC is not created") + # List VPCs + vpc_list = VPC.list( + self.userapiclient, + listall=self.services["listall"] + ) + status = validateList(vpc_list) + self.assertEquals(PASS, status[0], "VPC is not created") + self.assertEquals( + vpc_count_before + 1, + len(vpc_list), + "VPC is not created" + ) + # Listing the networks for a user + list_networks_before = Network.list(self.userapiclient, listall=self.services["listall"]) + # Verifying listed networks for account created at class level + self.assertIsNotNone(list_networks_before, "Network create failed at class level") + # List network offering for vpc = true + network_offering_vpc_true_list = NetworkOffering.list( + self.userapiclient, + forvpc="true", + zoneid=self.zone.id, + guestiptype=self.services["network_offering_vlan"]["guestiptype"], + supportedServices="SourceNat", + specifyvlan=self.services["network_offering_vlan"]["specifyvlan"], + state="Enabled" + ) + status = validateList(network_offering_vpc_true_list) + self.assertEquals(PASS, status[0], "Default network offering not present for vpc = true") + # Listing networks in VPC + list_networks_in_vpc = Network.list(self.userapiclient, + vpcid=vpc_1.id + ) + self.assertIsNone(list_networks_in_vpc, "Networks found for newly created VPC") + # If number of networks is 1, then creating network + if len(list_networks_before) == 1: + network_created = Network.create( + self.userapiclient, + self.services["network_without_acl"], + networkofferingid=network_offering_vpc_true_list[0].id, + vpcid=vpc_1.id, + gateway=self.services["ntwk"]["gateway"], + netmask=self.services["ntwk"]["netmask"], + domainid=self.domain.id, + accountid=self.account.name, + ) + self.assertIsNotNone( + network_created, + "Network is not created" + ) + self.cleanup.append(network_created) + self.cleanup.append(vpc_1) + # Creating expected and actual values dictionaries + expected_dict = { + "id":self.services["network_without_acl"]["zoneid"], + "name":self.services["network_without_acl"]["name"], + } + actual_dict = { + "id":network_created.zoneid, + "name":network_created.name, + } + network_status = self.__verify_values( + expected_dict, + actual_dict + ) + self.assertEqual( + True, + network_status, + "Listed network details are not as expected" + ) + else: + self.assertEqual( + len(list_networks_before), + 1, + "more than 1 network created at class level" + ) + # Listing the networks + list_networks_after = Network.list(self.userapiclient, listall=self.services["listall"]) + status = validateList(list_networks_after) + self.assertEquals(PASS, status[0], "No networks found using list call") + # Asserting for the length of the networks + self.assertEqual( + 2, + len(list_networks_after), + "Number of networks created is not matching expected" + ) + # Listing networks in VPC after creation of network + list_networks_in_vpc = Network.list(self.userapiclient, + vpcid=vpc_1.id + ) + status = validateList(list_networks_in_vpc) + self.assertEquals(PASS, status[0], "No networks found in vpc") + # Asserting for the length of the networks + self.assertEqual( + 1, + len(list_networks_in_vpc), + "Number of networks created in vpc is not matching expected" + ) + # List VPCs for specific network created in vpc + vpc_list = VPC.list( + self.userapiclient, + id=network_created.vpcid + ) + # verify no vpc is present for newly created user + status = validateList(vpc_list) + self.assertEquals(PASS, status[0], "VPCs not found.") + # verify vpc name matches for newly created vpc name and vpc list name + self.assertEqual( + vpc_1.name, + vpc_list[0].name, + "VPC names not matching" + ) + return + + @attr(tags=["advanced"]) + def test_07_creation_deletion_network(self): + """ + @Desc: Test delete network + @Steps + Step1 : Create Network + Step2 : Verify Network is created + Step3 : Delete Network + Step4 : Verify network is deleted + """ + # Listing the networks for a user + list_networks_before = Network.list(self.userapiclient, listall=self.services["listall"]) + # Verifying listed networks for account created at class level + self.assertIsNotNone(list_networks_before, "Network create failed at class level") + # List network offering for vpc = false + network_offering_vpc_false_list = NetworkOffering.list( + self.userapiclient, + forvpc="false", + zoneid=self.zone.id, + guestiptype=self.services["network_offering_vlan"]["guestiptype"], + supportedServices="SourceNat", + specifyvlan=self.services["network_offering_vlan"]["specifyvlan"], + state="Enabled" + ) + status = validateList(network_offering_vpc_false_list) + self.assertEquals(PASS, status[0], "Default network offering not present for vpc = false") + # If number of networks is 1, then creating network + if len(list_networks_before) == 1: + network_created = Network.create( + self.userapiclient, + self.services["network_without_acl"], + networkofferingid=network_offering_vpc_false_list[0].id, + ) + self.assertIsNotNone( + network_created, + "Network is not created" + ) + # Creating expected and actual values dictionaries + expected_dict = { + "id":self.services["network_without_acl"]["zoneid"], + "name":self.services["network_without_acl"]["name"], + } + actual_dict = { + "id":network_created.zoneid, + "name":network_created.name, + } + network_status = self.__verify_values( + expected_dict, + actual_dict + ) + self.assertEqual( + True, + network_status, + "Listed network details are not as expected" + ) + else: + self.assertEqual( + len(list_networks_before), + 1, + "more than 1 network created at class level" + ) + # Listing the networks + list_networks_after = Network.list( + self.userapiclient, + listall=self.services["listall"] + ) + status = validateList(list_networks_after) + self.assertEquals(PASS, status[0], "No networks found using list call") + # Asserting for the length of the networks + self.assertEqual( + 2, + len(list_networks_after), + "Number of networks created is not matching expected" + ) + # Delete Network + Network.delete(network_created, self.userapiclient) + # List Networks + list_networks_after_delete = Network.list( + self.userapiclient, + listall=self.services["listall"] + ) + status = validateList(list_networks_after_delete) + self.assertEquals(PASS, status[0], "No networks found using list call") + self.assertEqual( + 1, + len(list_networks_after_delete), + "Number of networks created is not matching expected" + ) + # Verify deleted network is not present + self.assertNotEquals( + network_created.id, + list_networks_after_delete[0].id, + "Deleted network present" + ) + return + + @attr(tags=["advanced"]) + def test_08_update_network(self): + """ + @Desc: Test update network + @Steps + Step1 : Create Network + Step2 : Verify Network is created + Step3 : Update Network name, display text and network domain + Step4 : Verify network is updated + """ + # Listing the networks for a user + list_networks_before = Network.list(self.userapiclient, listall=self.services["listall"]) + # Verifying listed networks for account created at class level + self.assertIsNotNone(list_networks_before, "Network create failed at class level") + self.assertEquals( + 1, + len(list_networks_before), + "More than 1 network created at class level" + ) + # List network offering for vpc = false + network_offering_vpc_false_list = NetworkOffering.list( + self.userapiclient, + forvpc="false", + zoneid=self.zone.id, + guestiptype=self.services["network_offering_vlan"]["guestiptype"], + supportedServices="SourceNat", + specifyvlan=self.services["network_offering_vlan"]["specifyvlan"], + state="Enabled" + ) + status = validateList(network_offering_vpc_false_list) + self.assertEquals(PASS, status[0], "Default network offering not present for vpc = false") + # creating network + network_created = Network.create( + self.userapiclient, + self.services["network_without_acl"], + networkofferingid=network_offering_vpc_false_list[0].id, + ) + self.assertIsNotNone( + network_created, + "Network is not created" + ) + self.cleanup.append(network_created) + # Creating expected and actual values dictionaries + expected_dict = { + "id":self.services["network_without_acl"]["zoneid"], + "name":self.services["network_without_acl"]["name"], + } + actual_dict = { + "id":network_created.zoneid, + "name":network_created.name, + } + network_status = self.__verify_values( + expected_dict, + actual_dict + ) + self.assertEqual( + True, + network_status, + "Listed network details are not as expected" + ) + # Listing the networks + list_networks_after = Network.list(self.userapiclient, listall=self.services["listall"]) + status = validateList(list_networks_after) + self.assertEquals(PASS, status[0], "No networks found using list call") + # Asserting for the length of the networks + self.assertEqual( + 2, + len(list_networks_after), + "Number of networks created is not matching expected" + ) + # Update Network + network_updated = Network.update(network_created, + self.userapiclient, + name="NewNetworkName", + displaytext="NewNetworkDisplayText", + networkdomain="cs13cloud.internal.new" + ) + # List Networks + list_networks_after_update = Network.list(self.userapiclient, listall=self.services["listall"]) + status = validateList(list_networks_after_update) + self.assertEquals(PASS, status[0], "No networks found using list call") + self.assertEqual( + 2, + len(list_networks_after_update), + "Number of networks created is not matching expected" + ) + # Creating expected and actual values dictionaries + expected_dict = { + "name":"NewNetworkName", + "displaytext":"NewNetworkDisplayText", + "networkdomain":"cs13cloud.internal.new" + } + actual_dict = { + "name":network_updated.name, + "displaytext":network_updated.displaytext, + "networkdomain":network_updated.networkdomain + } + network_status = self.__verify_values( + expected_dict, + actual_dict + ) + self.assertEqual( + True, + network_status, + "Listed network details are not as expected" + ) + return + + @attr(tags=["advanced"]) + def test_09_list_virtual_machines_single_network(self): + """ + @Desc: Test update network + @Steps + Step1 : Create Network + Step2 : Verify Network is created + Step3 : Create Virtual Machine as per page size + Step4 : Verify list Virtual machines and pagination + """ + # Listing the networks for a user + list_networks_before = Network.list(self.userapiclient, listall=self.services["listall"]) + # Verifying listed networks for account created at class level + self.assertIsNotNone(list_networks_before, "Network create failed at class level") + # Create Virtual Machine + # Listing all the instances for a user + list_instances_before = VirtualMachine.list(self.userapiclient, listall=self.services["listall"]) + # Verifying listed instances for account created at class level + self.assertIsNone( + list_instances_before, + "Virtual Machine already exists for newly created user" + ) + # If number of instances are less than (pagesize + 1), then creating them + for i in range(0, (self.services["pagesize"] + 1)): + vm_created = VirtualMachine.create( + self.userapiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + networkids=list_networks_before[0].id, + serviceofferingid=self.service_offering.id, + ) + self.assertIsNotNone( + vm_created, + "VM creation failed" + ) + if(i < (self.services["pagesize"])): + self.cleanup.append(vm_created) + + self.assertEqual( + self.services["virtual_machine"]["displayname"], + vm_created.displayname, + "Newly created VM name and the test data VM name are not matching" + ) + # Listing all the instances again after creating VM's + list_instances_after = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + networkid=list_networks_before[0].id + ) + status = validateList(list_instances_after) + self.assertEquals( + PASS, + status[0], + "Listing of instances after creation failed" + ) + # Verifying the length of the instances is (page size + 1) + self.assertEqual( + len(list_instances_after), + (self.services["pagesize"] + 1), + "Number of instances created is not matching as expected" + ) + # Listing all the volumes in page1 + list_instances_page1 = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + page=1, + pagesize=self.services["pagesize"], + networkid=list_networks_before[0].id + ) + status = validateList(list_instances_page1) + self.assertEquals( + PASS, + status[0], + "Listing of instances in page1 failed" + ) + # Verifying that the length of the instances in page 1 is (page size) + self.assertEqual( + self.services["pagesize"], + len(list_instances_page1), + "List VM response is not matching with the page size length for page 1" + ) + # Listing all the VM's in page2 + list_instances_page2 = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + page=2, + pagesize=self.services["pagesize"], + networkid=list_networks_before[0].id + ) + status = validateList(list_instances_page2) + self.assertEquals( + PASS, + status[0], + "Listing of instances in page2 failed" + ) + # Verifying that the length of the VM's in page 2 is 1 + self.assertEqual( + 1, + len(list_instances_page2), + "List VM response is not matching with the page size length for page 2" + ) + instance_page2 = list_instances_page2[0] + # Deleting a single VM + VirtualMachine.delete(vm_created, self.userapiclient) + # Listing the VM's in page 2 + list_instance_response = VirtualMachine.list( + self.userapiclient, + listall=self.services["listall"], + page=2, + pagesize=self.services["pagesize"], + networkid=list_networks_before[0].id + ) + # verifying that VM does not exists on page 2 + self.assertEqual( + list_instance_response, + None, + "VM was not deleted" + ) + return + + @attr(tags=["advanced"]) + def test_10_list_networks_in_vpc(self): + """ + @Desc: Test list networks in vpc and verify VPC name + @Steps + Step1 : List VPC Offering + Step2 : List VPCs for newly created user + Step3 : Create VPC + Step4 : List VPC and verify that count is increased by 1 + Step5 : Create network + Step6 : List Networks in created vpc + Step7 : Verify network name matches for newly created network name and name from network list + """ + # List VPC Offering + vpc_offs_list = VpcOffering.list(self.userapiclient, isdefault="true") + if vpc_offs_list is None: + self.fail("Default VPC offerings not found") + else: + vpc_offs = vpc_offs_list[0] + # List VPCs for newly created user + vpc_list = VPC.list( + self.userapiclient, + listall=self.services["listall"] + ) + # No VPCs should be present for newly created user + status = validateList(vpc_list) + self.assertEquals(FAIL, status[0], "VPCs found for newly created user") + vpc_count_before = 0 + vpc_1 = VPC.create( + self.userapiclient, + self.services["vpc"], + vpcofferingid=vpc_offs.id, + zoneid=self.zone.id, + ) + self.assertIsNotNone(vpc_1, "VPC is not created") + # List VPCs + vpc_list = VPC.list( + self.userapiclient, + listall=self.services["listall"] + ) + status = validateList(vpc_list) + self.assertEquals(PASS, status[0], "VPC is not created") + self.assertEquals( + vpc_count_before + 1, + len(vpc_list), + "VPC is not created" + ) + # Listing the networks for a user + list_networks_before = Network.list(self.userapiclient, listall=self.services["listall"]) + # Verifying listed networks for account created at class level + self.assertIsNotNone(list_networks_before, "Network create failed at class level") + # List network offering for vpc = true + network_offering_vpc_true_list = NetworkOffering.list( + self.userapiclient, + forvpc="true", + zoneid=self.zone.id, + guestiptype=self.services["network_offering_vlan"]["guestiptype"], + supportedServices="SourceNat", + specifyvlan=self.services["network_offering_vlan"]["specifyvlan"], + state="Enabled" + ) + status = validateList(network_offering_vpc_true_list) + self.assertEquals(PASS, status[0], "Default network offering not present for vpc = true") + # If number of networks is 1, then creating network + if len(list_networks_before) == 1: + network_created = Network.create( + self.userapiclient, + self.services["network_without_acl"], + networkofferingid=network_offering_vpc_true_list[0].id, + vpcid=vpc_1.id, + gateway=self.services["ntwk"]["gateway"], + netmask=self.services["ntwk"]["netmask"] + ) + self.assertIsNotNone( + network_created, + "Network is not created" + ) + self.cleanup.append(network_created) + self.cleanup.append(vpc_1) + # Creating expected and actual values dictionaries + expected_dict = { + "id":self.services["network_without_acl"]["zoneid"], + "name":self.services["network_without_acl"]["name"], + } + actual_dict = { + "id":network_created.zoneid, + "name":network_created.name, + } + network_status = self.__verify_values( + expected_dict, + actual_dict + ) + self.assertEqual( + True, + network_status, + "Listed network details are not as expected" + ) + else: + self.assertEqual( + len(list_networks_before), + 1, + "more than 1 network created at class level" + ) + # Listing the networks + list_networks_after = Network.list(self.userapiclient, listall=self.services["listall"]) + status = validateList(list_networks_after) + self.assertEquals(PASS, status[0], "No networks found using list call") + # Asserting for the length of the networks + self.assertEqual( + 2, + len(list_networks_after), + "Number of networks created is not matching expected" + ) + # Listing the networks + list_networks_in_vpc = Network.list( + self.userapiclient, + listall=self.services["listall"], + vpcid=vpc_1.id + ) + status = validateList(list_networks_in_vpc) + self.assertEquals(PASS, status[0], "No networks found using list call") + # Verify network name matches for newly created network name and name from network list + self.assertEqual( + network_created.name, + list_networks_in_vpc[0].name, + "Network names not matching" + ) + return + + @attr(tags=["advanced"]) + def test_11_update_vpc(self): + """ + @Desc: Test create vpc with network domain as parameter + @Steps + Step1 : List VPC Offering + Step2 : List VPCs for newly created user + Step3 : Create VPCs + Step4 : Verify count of VPCs created + Step5 : Update VPC name and display text + Step6 : Verify name and display text is updated + """ + # List VPC Offering + vpc_offs_list = VpcOffering.list(self.userapiclient, isdefault="true") + if vpc_offs_list is None: + self.fail("Default VPC offerings not found") + else: + vpc_offs = vpc_offs_list[0] + # List VPCs + vpc_list = VPC.list( + self.userapiclient, + listall=self.services["listall"] + ) + # verify no vpc is present for newly created user + status = validateList(vpc_list) + self.assertEquals(FAIL, status[0], "VPCs found for newly created user") + vpc_count_before = 0 + vpc_1 = VPC.create( + self.userapiclient, + self.services["vpc"], + vpcofferingid=vpc_offs.id, + zoneid=self.zone.id, + ) + self.assertIsNotNone(vpc_1, "VPC is not created") + self.cleanup.append(vpc_1) + # verify vpc is created and not none + # Verify VPC name with test data + self.assertNotEquals( + -1, + vpc_1.name.find(self.services["vpc"]["name"]), + "VPC name not matched" + ) + # verify zone with test data + self.assertEquals( + self.zone.id, + vpc_1.zoneid, + "Zone is not matching in the vpc created" + ) + # Asserting for the length of the VPCs + vpc_count_after = VPC.list(self.userapiclient, listall=self.services["listall"]) + status = validateList(vpc_count_after) + self.assertEquals(PASS, status[0], "VPC list count is null") + self.assertEqual( + 1, + len(vpc_count_after), + "Number of VPCs created is not matching expected" + ) + # Update VPC + vpc_updated = VPC.update( + vpc_1, + self.userapiclient, + name="NewVPCName", + displaytext="NewVPCDisplayText", + ) + # List Networks + list_vpcs_after_update = VPC.list( + self.userapiclient, + listall=self.services["listall"] + ) + status = validateList(list_vpcs_after_update) + self.assertEquals(PASS, status[0], "No vpcs found using list call") + self.assertEqual( + 1, + len(list_vpcs_after_update), + "Number of vpcs created is not matching expected" + ) + # Creating expected and actual values dictionaries + expected_dict = { + "name":"NewVPCName", + "displaytext":"NewVPCDisplayText", + } + actual_dict = { + "name":vpc_updated.name, + "displaytext":vpc_updated.displaytext, + } + vpc_status = self.__verify_values( + expected_dict, + actual_dict + ) + self.assertEqual( + True, + vpc_status, + "Listed vpc details are not as expected" + ) + return + + @attr(tags=["advanced"]) + def test_12_list_create_delete_networkACL(self): + """ + @Desc: Test create network in vpc and verify VPC name + @Steps + Step1 : List VPC Offering + Step2 : List VPCs for newly created user + Step3 : Create VPC + Step4 : List VPC and verify that count is increased by 1 + Step5 : Create network + Step6 : Verify network is created + Step7 : List Network ACLs + Step8 : Create Network ACL + Step9 : Verify NetworkACL is created + Step10 : Delete NetworkACL + Step11 : Verify NetworkACL is deleted + """ + # List VPC Offering + vpc_offs_list = VpcOffering.list(self.userapiclient, + isdefault="true", + ) + if vpc_offs_list is None: + self.fail("Default VPC offerings not found") + else: + vpc_offs = vpc_offs_list[0] + # List VPCs for newly created user + vpc_list = VPC.list( + self.userapiclient, + listall=self.services["listall"] + ) + # No VPCs should be present for newly created user + status = validateList(vpc_list) + self.assertEquals(FAIL, status[0], "VPCs found for newly created user") + vpc_count_before = 0 + vpc_1 = VPC.create( + self.userapiclient, + self.services["vpc"], + vpcofferingid=vpc_offs.id, + zoneid=self.zone.id, + ) + self.assertIsNotNone(vpc_1, "VPC is not created") + # List VPCs + vpc_list = VPC.list( + self.userapiclient, + listall=self.services["listall"] + ) + status = validateList(vpc_list) + self.assertEquals(PASS, status[0], "VPC is not created") + self.assertEquals( + vpc_count_before + 1, + len(vpc_list), + "VPC is not created" + ) + # Listing the networks for a user + list_networks_before = Network.list( + self.userapiclient, + listall=self.services["listall"] + ) + # Verifying listed networks for account created at class level + self.assertIsNotNone(list_networks_before, "Network create failed at class level") + # List network offering for vpc = true + network_offering_vpc_true_list = NetworkOffering.list( + self.userapiclient, + forvpc="true", + zoneid=self.zone.id, + guestiptype=self.services["network_offering_vlan"]["guestiptype"], + supportedServices="SourceNat", + specifyvlan=self.services["network_offering_vlan"]["specifyvlan"], + state="Enabled" + ) + status = validateList(network_offering_vpc_true_list) + self.assertEquals(PASS, status[0], "Default network offering not present for vpc = true") + # Listing networks in VPC + list_networks_in_vpc = Network.list(self.userapiclient, + vpcid=vpc_1.id + ) + self.assertIsNone(list_networks_in_vpc, "Networks found for newly created VPC") + # If number of networks is 1, then creating network + if len(list_networks_before) == 1: + network_created = Network.create( + self.userapiclient, + self.services["network_without_acl"], + networkofferingid=network_offering_vpc_true_list[0].id, + vpcid=vpc_1.id, + gateway=self.services["ntwk"]["gateway"], + netmask=self.services["ntwk"]["netmask"], + domainid=self.domain.id, + accountid=self.account.name, + ) + self.cleanup.append(network_created) + self.cleanup.append(vpc_1) + self.assertIsNotNone( + network_created, + "Network is not created" + ) + # Creating expected and actual values dictionaries + expected_dict = { + "id":self.services["network_without_acl"]["zoneid"], + "name":self.services["network_without_acl"]["name"], + } + actual_dict = { + "id":network_created.zoneid, + "name":network_created.name, + } + network_status = self.__verify_values( + expected_dict, + actual_dict + ) + self.assertEqual( + True, + network_status, + "Listed network details are not as expected" + ) + else: + self.assertEqual( + len(list_networks_before), + 1, + "more than 1 network created at class level" + ) + # Listing the networks + list_networks_after = Network.list(self.userapiclient, listall=self.services["listall"]) + status = validateList(list_networks_after) + self.assertEquals(PASS, status[0], "No networks found using list call") + # Asserting for the length of the networks + self.assertEqual( + 2, + len(list_networks_after), + "Number of networks created is not matching expected" + ) + # Listing networks in VPC after creation of network + list_networks_in_vpc = Network.list(self.userapiclient, + vpcid=vpc_1.id + ) + status = validateList(list_networks_in_vpc) + self.assertEquals(PASS, status[0], "No networks found in vpc") + # Asserting for the length of the networks + self.assertEqual( + 1, + len(list_networks_in_vpc), + "Number of networks created in vpc is not matching expected" + ) + # List VPCs for specific network created in vpc + vpc_list = VPC.list( + self.userapiclient, + id=network_created.vpcid + ) + # List Network ACLs + list_network_acl = NetworkACL.list( + self.userapiclient, + networkid=network_created.id + ) + self.assertIsNone(list_network_acl, "ACL list is not empty for newly created network") + # Create NetworkACL + network_acl_created = NetworkACL.create( + self.userapiclient, + self.services["network_acl_rule"], + networkid=network_created.id + ) + self.assertIsNotNone( + network_acl_created, + "NetworkACL is not created" + ) + # List Network ACL + list_network_acl = NetworkACL.list( + self.userapiclient, + networkid=network_created.id + ) + status = validateList(list_network_acl) + self.assertEquals(PASS, status[0], "No networks acls found after creating") + # Asserting for the length of the networks + self.assertEqual( + 1, + len(list_network_acl), + "Number of networks acls reated is not matching expected" + ) + # Delete Network ACL + NetworkACL.delete(network_acl_created, self.userapiclient) + # List Network ACL + list_network_acl = NetworkACL.list( + self.userapiclient, + networkid=network_created.id + ) + self.assertIsNone(list_network_acl, "ACL list is not empty for newly created network") + return + +class TestNetworks_2(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + try: + cls._cleanup = [] + cls.testClient = super(TestNetworks_2, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = cls.testClient.getParsedTestDataConfig() + # Get Domain, Zone, Template + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) + cls.template = get_template( + cls.api_client, + cls.zone.id, + cls.services["ostype"] + ) + cls.services['mode'] = cls.zone.networktype + cls.account = Account.create( + cls.api_client, + cls.services["account"], + domainid=cls.domain.id + ) + # Getting authentication for user in newly created Account + cls.user = cls.account.user[0] + cls.userapiclient = cls.testClient.getUserApiClient(cls.user.username, cls.domain.name) + cls._cleanup.append(cls.account) + except Exception as e: + cls.tearDownClass() + raise Exception("Warning: Exception in setup : %s" % e) + return + + def setUp(self): + + self.apiClient = self.testClient.getApiClient() + self.cleanup = [] + + def tearDown(self): + # Clean up, terminate the created volumes + cleanup_resources(self.apiClient, self.cleanup) + return + + @classmethod + def tearDownClass(cls): + try: + cleanup_resources(cls.api_client, cls._cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + + def __verify_values(self, expected_vals, actual_vals): + """ + @summary: Function to verify expected and actual values + Step1: Initializing return flag to True + Step1: Verifying length of expected and actual dictionaries is matching. + If not matching returning false + Step2: Listing all the keys from expected dictionary + Step3: Looping through each key from step2 and verifying expected and actual dictionaries have same value + If not making return flag to False + Step4: returning the return flag after all the values are verified + """ + return_flag = True + + if len(expected_vals) != len(actual_vals): + return False + + keys = expected_vals.keys() + for i in range(0, len(expected_vals)): + exp_val = expected_vals[keys[i]] + act_val = actual_vals[keys[i]] + if exp_val == act_val: + return_flag = return_flag and True + else: + return_flag = return_flag and False + self.debug("expected Value: %s, is not matching with actual value: %s" % ( + exp_val, + act_val + )) + return return_flag + + @attr(tags=["advanced", "provisioning"]) + def test_13_list_vpc_byid(self): + """ + @summary: Test List VPC with Id + @Steps + Step1: Listing all the vpc for a user before creating a vpc + Step2: Verifying no VPCs are listed + Step3: Creating a vpc + Step4: Listing the vpc for a user after creating a vpc + Step5: Verifying the list vpc size is increased by 1 + Step6: Listing the vpc by specifying vpc ID + Step7: Verifying the list vpc size is 1 + Step8: Verifying the details of the vpc + """ + # Listing all the vpc's for a user + list_vpc_before = VPC.list(self.userapiclient) + # Verifying No VPCs are listed + self.assertIsNone( + list_vpc_before, + "Vpc listed for newly created user" + ) + # Listing VPC Offerings + list_vpc_offering = VpcOffering.list(self.userapiclient) + status = validateList(list_vpc_offering) + self.assertEquals(PASS, status[0], "list vpc offering is none") + # Creating a vpc + vpc_created = VPC.create( + self.userapiclient, + self.services["vpc"], + list_vpc_offering[0].id, + self.zone.id + ) + self.assertIsNotNone(vpc_created, "VPC Creation Failed") + self.cleanup.append(vpc_created) + # Listing the vpc for a user after creating a vpc + list_vpc_after = VPC.list(self.userapiclient) + status = validateList(list_vpc_after) + self.assertEquals( + PASS, + status[0], + "list VPC not as expected" + ) + # Verifying the list vpc size is increased by 1 + self.assertEquals( + 1, + len(list_vpc_after), + "list VPC not equal as expected" + ) + # List the vpc by specifying vpc ID + list_vpc_byid = VPC.list( + self.userapiclient, + id=vpc_created.id, + listall=self.services["listall"] + ) + + status = validateList(list_vpc_byid) + self.assertEquals( + PASS, + status[0], + "list VPC not as expected" + ) + # Verifying the list vpc size is 1 + self.assertEquals( + 1, + len(list_vpc_byid), + "list VPC not equal as expected" + ) + # Verifying the details of the vpc + expected_dict = { + "cidr":self.services["vpc"]["cidr"], + "id":vpc_created.id, + "displaytext":vpc_created.displaytext, + "account":self.account.name, + "domain":vpc_created.domain, + "domainid":self.domain.id, + "name":vpc_created.name + } + actual_dict = { + "cidr":str(list_vpc_byid[0].cidr), + "id":list_vpc_byid[0].id, + "displaytext":list_vpc_byid[0].displaytext, + "account":list_vpc_byid[0].account, + "domain":list_vpc_byid[0].domain, + "domainid":list_vpc_byid[0].domainid, + "name":list_vpc_byid[0].name + } + list_vpc_status = self.__verify_values( + expected_dict, + actual_dict + ) + self.assertEqual( + True, + list_vpc_status, + "Listed VPC details are not as expected" + ) + + return + + @attr(tags=["advanced", "provisioning"]) + def test_14_list_public_ipadress_by_associated_networkid(self): + """ + @summary: Test List Public IPAddress with associatednetworkid + @Steps + Step1: Listing all the public ipadresses for a user before creating a public ipaddress + Step2: Verifying no Public ipaddress are listed + Step3: Creating a network + Step4: Associating public ipaddress for network created in step3 + Step5: Listing the public ipaddress for a user after creating a public ipaddress + Step6: Verifying the list public ipaddress size is increased by 1 + Step7: Listing the public ipaddress by specifying associatednetworkid + Step8: Verifying the list public ipaddress size is 1 + Step9: Verifying the details of the public ipaddress + """ + # Listing all the public ipadresses for a user + list_public_ipadress_before = PublicIPAddress.list(self.userapiclient) + # Verifying No VPCs are listed + self.assertIsNone( + list_public_ipadress_before, + "Public ipaddresses listed for newly created user" + ) + # Listing Network Offerings + network_offerings_list = NetworkOffering.list( + self.apiClient, + forvpc="false", + guestiptype="Isolated", + state="Enabled", + supportedservices="SourceNat", + zoneid=self.zone.id + ) + self.assertIsNotNone( + network_offerings_list, + "Isolated Network Offerings with sourceNat enabled are not found" + ) + #Creating a Network + network = Network.create( + self.userapiclient, + self.services["network"], + accountid=self.account.name, + domainid=self.domain.id, + networkofferingid=network_offerings_list[0].id, + zoneid=self.zone.id + ) + self.assertIsNotNone( + network, + "Network creation failed" + ) + self.cleanup.append(network) + # Associating public ipaddress for network created + public_ipaddress_created = PublicIPAddress.create( + self.userapiclient, + accountid=self.account.name, + zoneid=self.zone.id, + domainid=self.domain.id, + networkid=network.id + ) + self.assertIsNotNone( + public_ipaddress_created, + "Failed to Associate Public IpAddress for Network" + ) + # Listing the public ipaddress for a user after associating a public ipaddress for network + list_public_ipaddress_after = PublicIPAddress.list(self.userapiclient) + status = validateList(list_public_ipaddress_after) + self.assertEquals( + PASS, + status[0], + "list Public IPAddress not as expected" + ) + # Verifying the list public ipaddress size is increased by 1 + self.assertEquals( + 1, + len(list_public_ipaddress_after), + "list Public IPAddress not equal as expected" + ) + # List the public ipaddress by specifying public ipaddress ID + list_public_ipaddress_byid = PublicIPAddress.list( + self.userapiclient, + associatednetworkid=network.id, + listall=self.services["listall"] + ) + status = validateList(list_public_ipaddress_byid) + self.assertEquals( + PASS, + status[0], + "list public ipaddress not as expected" + ) + # Verifying the list public ipaddress size is 1 + self.assertEquals( + 1, + len(list_public_ipaddress_byid), + "list public ipaddress not equal as expected" + ) + # Verifying the details of the public ipaddress + expected_dict = { + "account":public_ipaddress_created.ipaddress.account, + "associatednetworkid":public_ipaddress_created.ipaddress.associatednetworkid, + "associatednetworkname":public_ipaddress_created.ipaddress.associatednetworkname, + "domainid":public_ipaddress_created.ipaddress.domainid, + "forvirtualnetwork":public_ipaddress_created.ipaddress.forvirtualnetwork, + "id":public_ipaddress_created.ipaddress.id, + "ipaddress":public_ipaddress_created.ipaddress.ipaddress, + "isportable":public_ipaddress_created.ipaddress.isportable, + "issourcenat":public_ipaddress_created.ipaddress.issourcenat, + "isstatisnat":public_ipaddress_created.ipaddress.isstaticnat, + "issystem":public_ipaddress_created.ipaddress.issystem, + "networkid":public_ipaddress_created.ipaddress.network, + "physicalnetworkid":public_ipaddress_created.ipaddress.physicalnetworkid, + "zoneid":public_ipaddress_created.ipaddress.zoneid + } + actual_dict = { + "account":list_public_ipaddress_byid[0].account, + "associatednetworkid":list_public_ipaddress_byid[0].associatednetworkid, + "associatednetworkname":list_public_ipaddress_byid[0].associatednetworkname, + "domainid":list_public_ipaddress_byid[0].domainid, + "forvirtualnetwork":list_public_ipaddress_byid[0].forvirtualnetwork, + "id":list_public_ipaddress_byid[0].id, + "ipaddress":list_public_ipaddress_byid[0].ipaddress, + "isportable":list_public_ipaddress_byid[0].isportable, + "issourcenat":list_public_ipaddress_byid[0].issourcenat, + "isstatisnat":list_public_ipaddress_byid[0].isstaticnat, + "issystem":list_public_ipaddress_byid[0].issystem, + "networkid":list_public_ipaddress_byid[0].network, + "physicalnetworkid":list_public_ipaddress_byid[0].physicalnetworkid, + "zoneid":list_public_ipaddress_byid[0].zoneid + } + list_public_ipaddress_status = self.__verify_values( + expected_dict, + actual_dict + ) + self.assertEqual( + True, + list_public_ipaddress_status, + "Listed Public IPAddress details are not as expected" + ) + return + + @attr(tags=["advanced", "provisioning"]) + def test_15_list_privategateway_byvpcid(self): + """ + @summary: Test List PrivateGateway by vpcid + @Steps + Step1: Creating a VPC + Step2: Listing all the private gateway before creating a private gateway + Step3: Verifying no Private Gateway are listed + Step4: Listing the Private Gateway after creating a Private Gateway + Step5: Verifying the list Private Gateway size is increased by 1 + Step6: Listing the Private Gateway by specifying VPCID + Step7: Verifying the list Private Gateway size is 1 + Step8: Verifying the details of the Private Gateway + """ + # Listing VPC Offerings + list_vpc_offering = VpcOffering.list(self.userapiclient) + status = validateList(list_vpc_offering) + self.assertEquals( + PASS, + status[0], + "list vpc offering is none" + ) + # Creating a vpc + vpc_created = VPC.create( + self.userapiclient, + self.services["vpc"], + list_vpc_offering[0].id, + self.zone.id + ) + self.assertIsNotNone(vpc_created, "VPC Creation Failed") + self.cleanup.append(vpc_created) + # Listing all the PrivateGateways + list_private_gateways_before = PrivateGateway.list( + self.apiClient, + listall=self.services["listall"], + vpcid=vpc_created.id + ) + # Verifying No PrivateGateways are listed + self.assertIsNone( + list_private_gateways_before, + "Listed private gateways for newly created VPC " + ) + #Creating a Private Gateway + private_gateway_created= PrivateGateway.create( + self.apiClient, + vpcid=vpc_created.id, + gateway=self.services["private_gateway"]["gateway"], + ipaddress=self.services["private_gateway"]["ipaddress"], + netmask=self.services["private_gateway"]["netmask"], + vlan=self.services["private_gateway"]["vlan"] + ) + self.assertIsNotNone( + private_gateway_created, + "Private Gateway Creation Failed" + ) + # Listing all the PrivateGateways + list_private_gateways_after = PrivateGateway.list( + self.apiClient, + listall=self.services["listall"], + vpcid=vpc_created.id + ) + # Verifying PrivateGateways are listed + status = validateList(list_private_gateways_after) + self.assertEquals(PASS, status[0], "Private Gateway Creation Failed") + self.assertEquals( + 1, + len(list_private_gateways_after), + "list Private Gateway not equal as expected" + ) + #Listing Private Gateway by vpcid + list_privategateway_byvpcid = PrivateGateway.list( + self.userapiclient, + listall=self.services["listall"], + vpcid=vpc_created.id + ) + status = validateList(list_privategateway_byvpcid) + self.assertEquals( + PASS, + status[0], + "list private gateway not as expected" + ) + # Verifying the list private gateway size is 1 + self.assertEquals( + 1, + len(list_privategateway_byvpcid), + "list private gateway not equal as expected" + ) + # Verifying the details of the private gateway + expected_dict = { + "account":private_gateway_created.account, + "aclid":private_gateway_created.aclid, + "domainid":private_gateway_created.domainid, + "gateway":self.services["private_gateway"]["gateway"], + "id":private_gateway_created.id, + "ipaddress":self.services["private_gateway"]["ipaddress"], + "netmask":self.services["private_gateway"]["netmask"], + "sourcenatsupported":private_gateway_created.sourcenatsupported, + "vlan":self.services["private_gateway"]["vlan"], + "vpcid":private_gateway_created.vpcid, + "zoneid":private_gateway_created.zoneid + } + actual_dict = { + "account":list_privategateway_byvpcid[0].account, + "aclid":list_privategateway_byvpcid[0].aclid, + "domainid":list_privategateway_byvpcid[0].domainid, + "gateway":list_privategateway_byvpcid[0].gateway, + "id":list_privategateway_byvpcid[0].id, + "ipaddress":list_privategateway_byvpcid[0].ipaddress, + "netmask":list_privategateway_byvpcid[0].netmask, + "sourcenatsupported":list_privategateway_byvpcid[0].sourcenatsupported, + "vlan":list_privategateway_byvpcid[0].vlan, + "vpcid":list_privategateway_byvpcid[0].vpcid, + "zoneid":list_privategateway_byvpcid[0].zoneid + } + list_private_gateway_status = self.__verify_values( + expected_dict, + actual_dict + ) + self.assertEqual( + True, + list_private_gateway_status, + "Listed Private Gateway details are not as expected" + ) + return + + @attr(tags=["advanced", "provisioning"]) + def test_16_create_list_delete_egressfirewallrule_bynetworkid(self): + """ + @summary: Test Create List Delete Egress Firewall Rule by Network ID + @Steps + Step1: Creating a Nerwork + Step2: Listing all the egressfirewall rule before creating a egressfirewall rule + Step3: Verifying no egressfirewall rule are listed + Step4: Creating a egressfirewall rule for a user + Step5: Listing the egressfirewall rule by specifying Network ID + Step7: Verifying the list egressfirewall rule size is 1 + Step8: Verifying the details of the egressfirewall rule + Step9: Deleting the egressfirewall rule by network id + Step10: Verifying no egressfirewall rule is listed + """ + # Listing all the Networks's for a user + list_networks_before = Network.list( + self.userapiclient, + listall=self.services["listall"] + ) + # Verifying No Networks are listed + self.assertIsNone( + list_networks_before, + "Networks listed for newly created User" + ) + # Listing Network Offerings + network_offerings_list = NetworkOffering.list( + self.apiClient, + forvpc="false", + guestiptype="Isolated", + state="Enabled", + supportedservices="SourceNat", + zoneid=self.zone.id + ) + self.assertIsNotNone( + network_offerings_list, + "Isolated Network Offerings with sourceNat enabled are not found" + ) + # Creating a Network + network = Network.create( + self.userapiclient, + self.services["network"], + accountid=self.account.name, + domainid=self.domain.id, + networkofferingid=network_offerings_list[0].id, + zoneid=self.zone.id + ) + self.assertIsNotNone( + network, + "Network creation failed" + ) + self.cleanup.append(network) + # Listing Networks after + list_networks_after = Network.list( + self.userapiclient, + listall=self.services["listall"] + ) + status = validateList(list_networks_after) + self.assertEquals( + PASS, + status[0], + "Network Creation Failed" + ) + # Verifying network list count is increased by 1 + self.assertEquals( + 1, + len(list_networks_after), + "Network Creation Failed" + ) + # Listing EgressFirewall Rule + list_egressfirewallrule_before = EgressFireWallRule.list( + self.userapiclient, + listall=self.services["listall"], + networkid=network.id + ) + # Verifying No EgressFirewall Rule are listed + self.assertIsNone( + list_egressfirewallrule_before, + "Listed egressfirewall rule for a user" + ) + # Creating a EgressFirewall Rule + egressfirewallrule_created = EgressFireWallRule.create( + self.userapiclient, + networkid=network.id, + protocol=self.services["ingress_rule"]["protocol"], + cidrlist=self.services["ingress_rule"]["cidrlist"], + startport=self.services["ingress_rule"]["startport"], + endport=self.services["ingress_rule"]["endport"], + ) + self.assertIsNotNone( + egressfirewallrule_created, + "EgressFirewall Rule Creation Failed" + ) + # ListingEgressFirewall Rule by networkid + list_egressfirewallrule_bynetworkid = EgressFireWallRule.list( + self.userapiclient, + listall=self.services["listall"], + networkid=network.id + ) + status = validateList(list_egressfirewallrule_bynetworkid) + self.assertEquals( + PASS, + status[0], + "list EgressFirewall Rule not as expected" + ) + # Verifying the list EgressFirewall Rule size is 1 + self.assertEquals( + 1, + len(list_egressfirewallrule_bynetworkid), + "list EgressFirewall Rule not equal as expected" + ) + # Verifying the details of the EgressFirewall Rule + expected_dict = { + "cidrlist":self.services["ingress_rule"]["cidrlist"], + "id":egressfirewallrule_created.id, + "networkid":egressfirewallrule_created.networkid, + "protocol":self.services["ingress_rule"]["protocol"] + } + actual_dict = { + "cidrlist":str(list_egressfirewallrule_bynetworkid[0].cidrlist), + "id":list_egressfirewallrule_bynetworkid[0].id, + "networkid":list_egressfirewallrule_bynetworkid[0].networkid, + "protocol":str(list_egressfirewallrule_bynetworkid[0].protocol).upper() + } + list_egressfirewallrule_status = self.__verify_values( + expected_dict, + actual_dict + ) + self.assertEqual( + True, + list_egressfirewallrule_status, + "Listed EgressFirewall Rule details are not as expected" + ) + # Deleting the EgressFirewall Rule by networkid + egressfirewallrule_created.delete(self.userapiclient); + # Listing the EgressFirewall Rule by networkid + list_deleted_egressfirewallrule_bynetworkid = EgressFireWallRule.list( + self.userapiclient, + listall=self.services["listall"], + networkid=network.id + ) + # Verifying No EgressFirewall Rule are listed + self.assertIsNone( + list_deleted_egressfirewallrule_bynetworkid, + "EgressFirewall Rule deletion fails" + ) + return + + + @attr(tags=["advanced", "provisioning"]) + def test_17_restart_vpc(self): + """ + @summary: Test to restart VPC + @Steps + Step1: Listing the VPC before creating a VPC for a user + Step2: Verifying No VPCs are listed + Step3: Creating a VPC + Step4: Listing the VPC after creating a VPC for a user + Step5: Verifying the list VPC size is increased by 1 + Step6: Restarting the VPC + Step7: Verifying the Restart function return true + Step8: Listing the VPC by specifying VPCID + Step9: Verfying state of vpc + """ + # Listing all the vpc's for a user + list_vpc_before = VPC.list(self.userapiclient) + # Verifying No VPCs are listed + self.assertIsNone( + list_vpc_before, + "Vpc listed for newly created user" + ) + # Listing VPC Offerings + list_vpc_offering = VpcOffering.list(self.userapiclient) + status = validateList(list_vpc_offering) + self.assertEquals( + PASS, + status[0], + "list vpc offering is none" + ) + # Creating a vpc + vpc_created = VPC.create( + self.userapiclient, + self.services["vpc"], + list_vpc_offering[0].id, + self.zone.id + ) + self.assertIsNotNone(vpc_created, "VPC Creation Failed") + # Listing the vpc for a user after creating a vpc + list_vpc_after = VPC.list(self.userapiclient) + status = validateList(list_vpc_after) + self.assertEquals( + PASS, + status[0], + "list VPC not as expected" + ) + # Verifying the list vpc size is increased by 1 + self.assertEquals( + 1, + len(list_vpc_after), + "list VPC not equal as expected" + ) + self.cleanup.append(vpc_created) + #Restarting VPC + vpc_restarted=VPC.restart(vpc_created, self.userapiclient) + #Verifying restart function resturns true + self.assertTrue(vpc_restarted,"Restart fails") + # List the vpc by specifying vpc ID + list_vpc_byid = VPC.list( + self.userapiclient, + id=vpc_created.id, + listall=self.services["listall"] + ) + status = validateList(list_vpc_byid) + self.assertEquals( + PASS, + status[0], + "list VPC not as expected" + ) + # Verifying the list vpc size is 1 + self.assertEquals( + 1, + len(list_vpc_byid), + "list VPC not equal as expected" + ) + #Verfying whether sate is Enabled + self.assertEqual( + "Enabled", + list_vpc_byid[0].state, + "Restarted VPC is not in Enabled state" + ) + return + + + + + @attr(tags=["advanced", "provisioning"]) + def test_18_create_list_vpn_gateway(self): + """ + @Desc: Test to Create and list Vpn Gateway by VPCid + @steps: + Step1: Create VPC + Step2: Listing VPN gateways for user before creating any VPN gateway + Step3: Verifying No VPN Gateways are listed + Step4: Creating a VPN Gateway using the vpc + Step5: Listing VPN gateway for user by vpcid + Step6: Verifying the list size is increased by 1 + Step7: Verifying the details of a VPN gateway + """ + # Listing all the vpc's for a user + list_vpc_before = VPC.list(self.userapiclient) + # Verifying No VPCs are listed + self.assertIsNone( + list_vpc_before, + "Vpc listed for newly created user" + ) + # Listing VPC Offerings + list_vpc_offering = VpcOffering.list(self.userapiclient) + status = validateList(list_vpc_offering) + self.assertEquals(PASS, status[0], "list vpc offering is none") + # Creating a vpc + vpc_created = VPC.create( + self.userapiclient, + self.services["vpc"], + list_vpc_offering[0].id, + self.zone.id + ) + self.assertIsNotNone(vpc_created, "VPC Creation Failed") + self.cleanup.append(vpc_created) + # Listing the vpc for a user after creating a vpc + list_vpc_after = VPC.list(self.userapiclient) + status = validateList(list_vpc_after) + self.assertEquals( + PASS, + status[0], + "list VPC not as expected" + ) + # Verifying the list vpc size is increased by 1 + self.assertEquals( + 1, + len(list_vpc_after), + "list VPC not equal as expected" + ) + # Listing all the vpn gateways for a user + list_vpngateway_before = Vpn.listVpnGateway( + self.userapiclient, + listall=self.services["listall"], + vpcid=vpc_created.id + ) + # Verifying No VPN Gateways are listed + self.assertIsNone( + list_vpngateway_before, + "Vpn gateway listed for newly created user" + ) + #Creating a VPN Gateway + vpngateway_created= Vpn.createVpnGateway( + self.userapiclient, + vpcid=vpc_created.id, + ) + self.assertIsNotNone( + vpngateway_created, + "VPN Gateway creation failed" + ) + # Listing all the VPN Gateways for a User + list_vpngateway_after = Vpn.listVpnGateway( + self.userapiclient, + listall=self.services["listall"], + vpcid=vpc_created.id + ) + status = validateList(list_vpngateway_after) + self.assertEquals( + PASS, + status[0], + "List VPN Gateway not equal as expected" + ) + # Verifying that list size is 1 + self.assertEquals( + 1, + len(list_vpngateway_after + ), + "Failed to list vpn gateway" + ) + # Verifying the details of the vpn gateway + expected_dict = { + "account":vpngateway_created["account"], + "domainid":vpngateway_created["domainid"], + "id":vpngateway_created["id"], + "publicip":vpngateway_created["publicip"], + "vpcid":vpngateway_created["vpcid"] + } + actual_dict = { + "account":list_vpngateway_after[0].account, + "domainid":list_vpngateway_after[0].domainid, + "id":list_vpngateway_after[0].id, + "publicip":list_vpngateway_after[0].publicip, + "vpcid":list_vpngateway_after[0].vpcid + } + list_vpn_gateway_status = self.__verify_values( + expected_dict, + actual_dict + ) + self.assertEqual( + True, + list_vpn_gateway_status, + "Listed VPN Gateway details are not as expected" + ) + return + + @attr(tags=["advanced", "basic", "provisioning"]) + def test_19_create_list_reset_delete_vpnconnections(self): + """ + @Desc: Test to List Create Reset and Delete VPN Customer Gateways pagination + @steps: + Step1: Create VPC + Step2: Create VPN gateway + Step3: Create VPN Customer Gateway + Step4: Listing all the VPN Connections for a user + Step5: Verifying No VPN Connection are listed + Step6: Create a VPN Connection using VPN Gateway and VPN Customer Gateway + Step7: Listing all the VPN Connections by vpcid for a user + Step8: Verifying that list size is 1 + Step9: Reset the vpn connection + Step10:List the Vpn connection by vpcid + Step11: Verify the details of VPN Connection after reset + Step12: Deleting the VPN Connection + Step13: Listing all the VPN Connection for a user + Step14: Verifying that no VPN Connection are listed + """ + # Listing all the vpc's for a user + list_vpc_before = VPC.list(self.userapiclient) + # Verifying No VPCs are listed + self.assertIsNone( + list_vpc_before, + "Vpc listed for newly created user" + ) + # Listing VPC Offerings + list_vpc_offering = VpcOffering.list(self.userapiclient) + status = validateList(list_vpc_offering) + self.assertEquals(PASS, status[0], "list vpc offering is none") + # Creating a vpc + vpc_created = VPC.create( + self.userapiclient, + self.services["vpc"], + list_vpc_offering[0].id, + self.zone.id + ) + self.assertIsNotNone(vpc_created, "VPC Creation Failed") + self.cleanup.append(vpc_created) + # Listing the vpc for a user after creating a vpc + list_vpc_after = VPC.list(self.userapiclient) + status = validateList(list_vpc_after) + self.assertEquals( + PASS, + status[0], + "list VPC not as expected" + ) + # Verifying the list vpc size is increased by 1 + self.assertEquals( + 1, + len(list_vpc_after), + "list VPC not equal as expected" + ) + # Listing all the vpn gateways for a user + list_vpngateway_before = Vpn.listVpnGateway( + self.userapiclient, + listall=self.services["listall"], + vpcid=vpc_created.id + ) + # Verifying No VPN Gateways are listed + self.assertIsNone( + list_vpngateway_before, + "Vpn gateway listed for newly created user" + ) + #Creating a VPN Gateway + vpngateway_created= Vpn.createVpnGateway( + self.userapiclient, + vpcid=vpc_created.id, + ) + self.assertIsNotNone( + vpngateway_created, + "VPN Gateway creation failed" + ) + # Listing all the VPN Gateways for a User + list_vpngateway_after = Vpn.listVpnGateway( + self.userapiclient, + listall=self.services["listall"], + vpcid=vpc_created.id + ) + status = validateList(list_vpngateway_after) + self.assertEquals( + PASS, + status[0], + "List VPN Gateway not equal as expected" + ) + # Verifying that list size is 1 + self.assertEquals( + 1, + len(list_vpngateway_after + ), + "Failed to list vpn gateway" + ) + # Listing all the VPN Customer Gateways for a User + list_vpncustomergateways_before = VpnCustomerGateway.list( + self.userapiclient, + listall=self.services["listall"] + ) + # Verifying that no VPN Customer Gateways are listed + self.assertIsNone( + list_vpncustomergateways_before, + "VPN Customer Gateways listed for newly created User" + ) + # Creating VPN Customer Gateways + vpncustomergateway_created = VpnCustomerGateway.create( + self.userapiclient, + self.services["vpncustomergateway"], + name="VPNCustGateway", + gateway="10.102.153.1", + cidrlist="10.0.0.0/24", + account=self.account.name, + domainid=self.domain.id + ) + self.assertIsNotNone( + vpncustomergateway_created, + "VPN Customer Gateway creation failed" + ) + self.cleanup.append(vpncustomergateway_created) + # Listing all the VPN Customer Gateways for a User + list_vpncustomergateways_after = VpnCustomerGateway.list( + self.userapiclient, + listall=self.services["listall"], + ) + status = validateList(list_vpncustomergateways_after) + self.assertEquals( + PASS, + status[0], + "VPN Customer Gateway list failed" + ) + # Verifying that list size is 1 + self.assertEquals( + 1, + len(list_vpncustomergateways_after), + "Failed to list VPN Customer Gateways" + ) + # Listing all the vpc's for a user + list_vpn_connection_before = Vpn.listVpnConnection( + self.userapiclient, + listall=self.services["listall"], + vpcid=vpc_created.id + ) + # Verifying No VPC Connections are listed + self.assertIsNone( + list_vpn_connection_before, + "Vpn connection listed for newly created user" + ) + #Creating VPN Connection + vpnconnections_created=Vpn.createVpnConnection( + self.userapiclient, + s2scustomergatewayid=vpncustomergateway_created.id, + s2svpngatewayid=vpngateway_created["id"] + ) + self.assertIsNotNone( + vpnconnections_created, + "VPN Connection creation failed" + ) + # Listing the vpn connection for a user after creating a vpn connection + list_vpn_connection_after = Vpn.listVpnConnection( + self.userapiclient, + listall=self.services["listall"], + vpcid=vpc_created.id + ) + status = validateList(list_vpn_connection_after) + self.assertEquals( + PASS, + status[0], + "list VPN Connection not as expected" + ) + # Verifying the list vpn connection size is increased by 1 + self.assertEquals( + 1, + len(list_vpn_connection_after), + "list VPC Connection equal as expected" + ) + # Resets VPN Connection + Vpn.resetVpnConnection( + self.userapiclient, + id=list_vpn_connection_after[0].id, + ) + # Lists VPN Connection by vpcid + list_vpn_connection_after_reset=Vpn.listVpnConnection( + self.userapiclient, + listall=self.services["listall"], + vpcid=vpc_created.id + ) + status = validateList(list_vpn_connection_after_reset) + self.assertEquals( + PASS, + status[0], + "list VPN Connection not as expected" + ) + # Verifying the list vpn connection size is increased by 1 + self.assertEquals( + 1, + len(list_vpn_connection_after_reset), + "list VPN Connection not equal as expected" + ) + # Verifying the details of the vpn connection after reset + expected_dict = { + "account":list_vpn_connection_after[0].account, + "cidrlist":list_vpn_connection_after[0].cidrlist, + "domain":list_vpn_connection_after[0].domain, + "dpd":list_vpn_connection_after[0].dpd, + "gateway":list_vpn_connection_after[0].gateway, + "id":list_vpn_connection_after[0].id, + "passive":list_vpn_connection_after[0].passive, + "publicip":list_vpn_connection_after[0].publicip, + "s2scustomergatewayid":list_vpn_connection_after[0].s2scustomergatewayid, + "s2svpngatewayid":list_vpn_connection_after[0].s2svpngatewayid + } + actual_dict = { + "account":list_vpn_connection_after_reset[0].account, + "cidrlist":list_vpn_connection_after_reset[0].cidrlist, + "domain":list_vpn_connection_after_reset[0].domain, + "dpd":list_vpn_connection_after_reset[0].dpd, + "gateway":list_vpn_connection_after_reset[0].gateway, + "id":list_vpn_connection_after_reset[0].id, + "passive":list_vpn_connection_after_reset[0].passive, + "publicip":list_vpn_connection_after_reset[0].publicip, + "s2scustomergatewayid":list_vpn_connection_after_reset[0].s2scustomergatewayid, + "s2svpngatewayid":list_vpn_connection_after_reset[0].s2svpngatewayid + } + list_vpn_connection_status = self.__verify_values( + expected_dict, + actual_dict + ) + self.assertEqual( + True, + list_vpn_connection_status, + "Listed VPN Connection details are not as expected" + ) + # Delete VPN Connection + Vpn.deleteVpnConnection( + self.userapiclient, + id=list_vpn_connection_after[0].id + ) + # Listing all the vpc connections for a user + list_vpn_connection_after_delete = Vpn.listVpnConnection( + self.userapiclient, + listall=self.services["listall"], + vpcid=vpc_created.id + ) + # Verifying No VPN Connections are listed + self.assertIsNone( + list_vpn_connection_after_delete, + "Vpn connection listed for newly created user" + ) + return + @attr(tags=["advanced", "provisioning"]) + def test_20_list_capabilities(self): + """ + @summary: Test List Capabilities + @Steps + Step1: Listing all the Capabilities for a user + Step2: Verifying the listcapabilities object is not null + Step3: Verifying list.cloudstack version is not null + """ + # Listing all the Capabilities for a user + listCapabilities=Configurations.listCapabilities(self.userapiclient) + # Verifying the listcapabilities object is not null + self.assertIsNotNone( + listCapabilities, + "Failed to list Capabilities" + ) + # Verifying list.cloudstack version is not null + self.assertIsNotNone( + listCapabilities.cloudstackversion, + "Failed to list cloud Stack version" + ) + return + + @attr(tags=["advanced", "provisioning"]) + def test_21_listNetworkacls_by_privategateway_aclid(self): + """ + @summary: Test to list Networkacllists by private gateway aclid + @Steps + Step1: Listing the Network acl's for a user + Step2: Verifying list is not none + Step3: Creating a VPC + Step4: Listing the privategateway for user + Step5: Verifying the no private gateway are listed for a user + Step6: Creating a private gateway using aclid + Step7: Listing private gateway for a user + Step8: Verifying list size is increased by 1 + Step9: Listing Networkacllist by paymentgateway aclid + """ + # Listing all thenetwork acl list for a user + list_networkacl = NetworkACLList.list(self.userapiclient) + self.assertIsNotNone(list_networkacl, "Failed to list network acl list") + # Verfying list is not none + status = validateList(list_networkacl) + self.assertEquals( + PASS, + status[0], + "Failed to list network acl list" + ) + + # Listing VPC Offerings + list_vpc_offering = VpcOffering.list(self.userapiclient) + status = validateList(list_vpc_offering) + self.assertEquals( + PASS, + status[0], + "list vpc offering is none" + ) + # Creating a vpc + vpc_created = VPC.create( + self.userapiclient, + self.services["vpc"], + list_vpc_offering[0].id, + self.zone.id + ) + self.assertIsNotNone(vpc_created, "VPC Creation Failed") + self.cleanup.append(vpc_created) + # Listing all the PrivateGateways + list_private_gateways_before = PrivateGateway.list( + self.apiClient, + listall=self.services["listall"], + vpcid=vpc_created.id + ) + # Verifying No PrivateGateways are listed + self.assertIsNone( + list_private_gateways_before, + "Listed private gateways for newly created VPC " + ) + #Creating a Private Gateway using aclid + private_gateway_created= PrivateGateway.create( + self.apiClient, + vpcid=vpc_created.id, + gateway=self.services["private_gateway"]["gateway"], + ipaddress=self.services["private_gateway"]["ipaddress"], + netmask=self.services["private_gateway"]["netmask"], + vlan=self.services["private_gateway"]["vlan"], + aclid=list_networkacl[0].id + ) + self.assertIsNotNone( + private_gateway_created, + "Private Gateway Creation Failed" + ) + # Listing all the PrivateGateways + list_private_gateways_after = PrivateGateway.list( + self.apiClient, + listall=self.services["listall"], + vpcid=vpc_created.id + ) + # Verifying PrivateGateways are listed + status = validateList(list_private_gateways_after) + self.assertEquals(PASS, status[0], "Failed to list Private Gateway") + self.assertEquals( + 1, + len(list_private_gateways_after), + "list Private Gateway not equal as expected" + ) + #Listing network acl list by paymentgateway.aclid + list=NetworkACLList.list(self.userapiclient, + listall=self.services["listall"], + id=private_gateway_created.aclid + ) + # Verifying the details of the Network acl list + expected_dict = { + "description":list_networkacl[0].description, + "id":list_networkacl[0].id, + "name":list_networkacl[0].name + } + actual_dict = { + "description":list[0].description, + "id":list[0].id, + "name":list[0].name + } + list_networkacl_status = self.__verify_values( + expected_dict, + actual_dict + ) + self.assertEqual( + True, + list_networkacl_status, + "Listed Network acl list details are not as expected" + ) + return \ No newline at end of file diff --git a/test/integration/component/test_escalations_securitygroups.py b/test/integration/component/test_escalations_securitygroups.py new file mode 100644 index 0000000000..8934088774 --- /dev/null +++ b/test/integration/component/test_escalations_securitygroups.py @@ -0,0 +1,588 @@ +# 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 Local Modules +from marvin.cloudstackTestCase import cloudstackTestCase +from marvin.cloudstackAPI import (createVolume, + createTemplate) +from marvin.lib.base import (Volume, + Iso, + VirtualMachine, + Template, + Snapshot, + SecurityGroup, + Account, + Zone, + Network, + NetworkOffering, + DiskOffering, + ServiceOffering, + VmSnapshot, + SnapshotPolicy, + SSHKeyPair, + Resources, + Configurations, + VpnCustomerGateway, + Hypervisor, + VpcOffering, + VPC, + NetworkACL) +from marvin.lib.common import (get_zone, + get_domain, + get_template, + list_os_types) +from marvin.lib.utils import (validateList, + cleanup_resources, + random_gen) +from marvin.codes import (PASS, FAIL, EMPTY_LIST) +from nose.plugins.attrib import attr +import time + +class TestSecurityGroups(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + try: + cls._cleanup = [] + cls.testClient = super(TestSecurityGroups, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = cls.testClient.getParsedTestDataConfig() + # Get Domain, Zone, Template + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) + cls.template = get_template( + cls.api_client, + cls.zone.id, + cls.services["ostype"] + ) + cls.services['mode'] = cls.zone.networktype + cls.account = Account.create( + cls.api_client, + cls.services["account"], + domainid=cls.domain.id + ) + # Getting authentication for user in newly created Account + cls.user = cls.account.user[0] + cls.userapiclient = cls.testClient.getUserApiClient(cls.user.username, cls.domain.name) + cls._cleanup.append(cls.account) + except Exception as e: + cls.tearDownClass() + raise Exception("Warning: Exception in setup : %s" % e) + return + + def setUp(self): + + self.apiClient = self.testClient.getApiClient() + self.cleanup = [] + + def tearDown(self): + #Clean up, terminate the created resources + cleanup_resources(self.apiClient, self.cleanup) + return + + @classmethod + def tearDownClass(cls): + try: + cleanup_resources(cls.api_client, cls._cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + + return + + def __verify_values(self, expected_vals, actual_vals): + """ + @Desc: Function to verify expected and actual values + @Steps: + Step1: Initializing return flag to True + Step1: Verifying length of expected and actual dictionaries is matching. + If not matching returning false + Step2: Listing all the keys from expected dictionary + Step3: Looping through each key from step2 and verifying expected and actual dictionaries have same value + If not making return flag to False + Step4: returning the return flag after all the values are verified + """ + return_flag = True + + if len(expected_vals) != len(actual_vals): + return False + + keys = expected_vals.keys() + for i in range(0, len(expected_vals)): + exp_val = expected_vals[keys[i]] + act_val = actual_vals[keys[i]] + if exp_val == act_val: + return_flag = return_flag and True + else: + return_flag = return_flag and False + self.debug("expected Value: %s, is not matching with actual value: %s" % ( + exp_val, + act_val + )) + return return_flag + + @attr(tags=["basic", "provisioning"]) + def test_01_list_securitygroups_pagination(self): + """ + @Desc: Test to List Security Groups pagination + @steps: + Step1: Listing all the Security Groups for a user + Step2: Verifying that list size is 1 + Step3: Creating (page size) number of Security Groups + Step4: Listing all the Security Groups again for a user + Step5: Verifying that list size is (page size + 1) + Step6: Listing all the Security Groups in page1 + Step7: Verifying that list size is (page size) + Step8: Listing all the Security Groups in page2 + Step9: Verifying that list size is 1 + Step10: Deleting the Security Group present in page 2 + Step11: Listing all the Security Groups in page2 + Step12: Verifying that no security groups are listed + """ + # Listing all the Security Groups for a User + list_securitygroups_before = SecurityGroup.list( + self.userapiclient, + listall=self.services["listall"] + ) + # Verifying that default security group is created + status = validateList(list_securitygroups_before) + self.assertEquals( + PASS, + status[0], + "Default Security Groups creation failed" + ) + # Verifying the size of the list is 1 + self.assertEquals( + 1, + len(list_securitygroups_before), + "Count of Security Groups list is not matching" + ) + # Creating pagesize number of security groups + for i in range(0, (self.services["pagesize"])): + securitygroup_created = SecurityGroup.create( + self.userapiclient, + self.services["security_group"], + account=self.account.name, + domainid=self.domain.id, + description=self.services["security_group"]["name"] + ) + self.assertIsNotNone( + securitygroup_created, + "Security Group creation failed" + ) + if (i < self.services["pagesize"]): + self.cleanup.append(securitygroup_created) + + # Listing all the security groups for user again + list_securitygroups_after = SecurityGroup.list( + self.userapiclient, + listall=self.services["listall"] + ) + status = validateList(list_securitygroups_after) + self.assertEquals( + PASS, + status[0], + "Security Groups creation failed" + ) + # Verifying that list size is pagesize + 1 + self.assertEquals( + self.services["pagesize"] + 1, + len(list_securitygroups_after), + "Failed to create pagesize + 1 number of Security Groups" + ) + # Listing all the security groups in page 1 + list_securitygroups_page1 = SecurityGroup.list( + self.userapiclient, + listall=self.services["listall"], + page=1, + pagesize=self.services["pagesize"] + ) + status = validateList(list_securitygroups_page1) + self.assertEquals( + PASS, + status[0], + "Failed to list security groups in page 1" + ) + # Verifying the list size to be equal to pagesize + self.assertEquals( + self.services["pagesize"], + len(list_securitygroups_page1), + "Size of security groups in page 1 is not matching" + ) + # Listing all the security groups in page 2 + list_securitygroups_page2 = SecurityGroup.list( + self.userapiclient, + listall=self.services["listall"], + page=2, + pagesize=self.services["pagesize"] + ) + status = validateList(list_securitygroups_page2) + self.assertEquals( + PASS, + status[0], + "Failed to list security groups in page 2" + ) + # Verifying the list size to be equal to pagesize + self.assertEquals( + 1, + len(list_securitygroups_page2), + "Size of security groups in page 2 is not matching" + ) + # Deleting the security group present in page 2 + SecurityGroup.delete( + securitygroup_created, + self.userapiclient) + # Listing all the security groups in page 2 again + list_securitygroups_page2 = SecurityGroup.list( + self.userapiclient, + listall=self.services["listall"], + page=2, + pagesize=self.services["pagesize"] + ) + # Verifying that there are no security groups listed + self.assertIsNone( + list_securitygroups_page2, + "Security Groups not deleted from page 2" + ) + return + + @attr(tags=["basic", "provisioning"]) + def test_02_securitygroups_authorize_revoke_ingress(self): + """ + @Desc: Test to Authorize and Revoke Ingress for Security Group + @steps: + Step1: Listing all the Security Groups for a user + Step2: Verifying that list size is 1 + Step3: Creating a Security Groups + Step4: Listing all the Security Groups again for a user + Step5: Verifying that list size is 2 + Step6: Authorizing Ingress for the security group created in step3 + Step7: Listing the security groups by passing id of security group created in step3 + Step8: Verifying that list size is 1 + Step9: Verifying that Ingress is authorized to the security group + Step10: Verifying the details of the Ingress rule are as expected + Step11: Revoking Ingress for the security group created in step3 + Step12: Listing the security groups by passing id of security group created in step3 + Step13: Verifying that list size is 1 + Step14: Verifying that Ingress is revoked from the security group + """ + # Listing all the Security Groups for a User + list_securitygroups_before = SecurityGroup.list( + self.userapiclient, + listall=self.services["listall"] + ) + # Verifying that default security group is created + status = validateList(list_securitygroups_before) + self.assertEquals( + PASS, + status[0], + "Default Security Groups creation failed" + ) + # Verifying the size of the list is 1 + self.assertEquals( + 1, + len(list_securitygroups_before), + "Count of Security Groups list is not matching" + ) + # Creating a security group + securitygroup_created = SecurityGroup.create( + self.userapiclient, + self.services["security_group"], + account=self.account.name, + domainid=self.domain.id, + description=self.services["security_group"]["name"] + ) + self.assertIsNotNone( + securitygroup_created, + "Security Group creation failed" + ) + self.cleanup.append(securitygroup_created) + + # Listing all the security groups for user again + list_securitygroups_after = SecurityGroup.list( + self.userapiclient, + listall=self.services["listall"] + ) + status = validateList(list_securitygroups_after) + self.assertEquals( + PASS, + status[0], + "Security Groups creation failed" + ) + # Verifying that list size is 2 + self.assertEquals( + 2, + len(list_securitygroups_after), + "Failed to create Security Group" + ) + # Authorizing Ingress for the security group created in step3 + securitygroup_created.authorize( + self.userapiclient, + self.services["ingress_rule"], + self.account.name, + self.domain.id, + ) + # Listing the security group by Id + list_securitygroups_byid = SecurityGroup.list( + self.userapiclient, + listall=self.services["listall"], + id=securitygroup_created.id, + domainid=self.domain.id + ) + # Verifying that security group is listed + status = validateList(list_securitygroups_byid) + self.assertEquals( + PASS, + status[0], + "Listing of Security Groups by id failed" + ) + # Verifying size of the list is 1 + self.assertEquals( + 1, + len(list_securitygroups_byid), + "Count of the listing security group by id is not matching" + ) + securitygroup_ingress = list_securitygroups_byid[0].ingressrule + # Validating the Ingress rule + status = validateList(securitygroup_ingress) + self.assertEquals( + PASS, + status[0], + "Security Groups Ingress rule authorization failed" + ) + self.assertEquals( + 1, + len(securitygroup_ingress), + "Security Group Ingress rules count is not matching" + ) + # Verifying the details of the Ingress rule are as expected + #Creating expected and actual values dictionaries + expected_dict = { + "cidr":self.services["ingress_rule"]["cidrlist"], + "protocol":self.services["ingress_rule"]["protocol"], + "startport":self.services["ingress_rule"]["startport"], + "endport":self.services["ingress_rule"]["endport"], + } + actual_dict = { + "cidr":str(securitygroup_ingress[0].cidr), + "protocol":str(securitygroup_ingress[0].protocol.upper()), + "startport":str(securitygroup_ingress[0].startport), + "endport":str(securitygroup_ingress[0].endport), + } + ingress_status = self.__verify_values( + expected_dict, + actual_dict + ) + self.assertEqual( + True, + ingress_status, + "Listed Security group Ingress rule details are not as expected" + ) + # Revoking the Ingress rule from Security Group + securitygroup_created.revoke(self.userapiclient, securitygroup_ingress[0].ruleid) + # Listing the security group by Id + list_securitygroups_byid = SecurityGroup.list( + self.userapiclient, + listall=self.services["listall"], + id=securitygroup_created.id, + domainid=self.domain.id + ) + # Verifying that security group is listed + status = validateList(list_securitygroups_byid) + self.assertEquals( + PASS, + status[0], + "Listing of Security Groups by id failed" + ) + # Verifying size of the list is 1 + self.assertEquals( + 1, + len(list_securitygroups_byid), + "Count of the listing security group by id is not matching" + ) + securitygroup_ingress = list_securitygroups_byid[0].ingressrule + # Verifying that Ingress rule is empty(revoked) + status = validateList(securitygroup_ingress) + self.assertEquals( + EMPTY_LIST, + status[2], + "Security Groups Ingress rule is not revoked" + ) + return + + @attr(tags=["basic", "provisioning"]) + def test_03_securitygroups_authorize_revoke_egress(self): + """ + @Desc: Test to Authorize and Revoke Egress for Security Group + @steps: + Step1: Listing all the Security Groups for a user + Step2: Verifying that list size is 1 + Step3: Creating a Security Groups + Step4: Listing all the Security Groups again for a user + Step5: Verifying that list size is 2 + Step6: Authorizing Egress for the security group created in step3 + Step7: Listing the security groups by passing id of security group created in step3 + Step8: Verifying that list size is 1 + Step9: Verifying that Egress is authorized to the security group + Step10: Verifying the details of the Egress rule are as expected + Step11: Revoking Egress for the security group created in step3 + Step12: Listing the security groups by passing id of security group created in step3 + Step13: Verifying that list size is 1 + Step14: Verifying that Egress is revoked from the security group + """ + # Listing all the Security Groups for a User + list_securitygroups_before = SecurityGroup.list( + self.userapiclient, + listall=self.services["listall"] + ) + # Verifying that default security group is created + status = validateList(list_securitygroups_before) + self.assertEquals( + PASS, + status[0], + "Default Security Groups creation failed" + ) + # Verifying the size of the list is 1 + self.assertEquals( + 1, + len(list_securitygroups_before), + "Count of Security Groups list is not matching" + ) + # Creating a security group + securitygroup_created = SecurityGroup.create( + self.userapiclient, + self.services["security_group"], + account=self.account.name, + domainid=self.domain.id, + description=self.services["security_group"]["name"] + ) + self.assertIsNotNone( + securitygroup_created, + "Security Group creation failed" + ) + self.cleanup.append(securitygroup_created) + + # Listing all the security groups for user again + list_securitygroups_after = SecurityGroup.list( + self.userapiclient, + listall=self.services["listall"] + ) + status = validateList(list_securitygroups_after) + self.assertEquals( + PASS, + status[0], + "Security Groups creation failed" + ) + # Verifying that list size is 2 + self.assertEquals( + 2, + len(list_securitygroups_after), + "Failed to create Security Group" + ) + # Authorizing Egress for the security group created in step3 + securitygroup_created.authorizeEgress( + self.userapiclient, + self.services["ingress_rule"], + self.account.name, + self.domain.id, + ) + # Listing the security group by Id + list_securitygroups_byid = SecurityGroup.list( + self.userapiclient, + listall=self.services["listall"], + id=securitygroup_created.id, + domainid=self.domain.id + ) + # Verifying that security group is listed + status = validateList(list_securitygroups_byid) + self.assertEquals( + PASS, + status[0], + "Listing of Security Groups by id failed" + ) + # Verifying size of the list is 1 + self.assertEquals( + 1, + len(list_securitygroups_byid), + "Count of the listing security group by id is not matching" + ) + securitygroup_egress = list_securitygroups_byid[0].egressrule + # Validating the Ingress rule + status = validateList(securitygroup_egress) + self.assertEquals( + PASS, + status[0], + "Security Groups Egress rule authorization failed" + ) + self.assertEquals( + 1, + len(securitygroup_egress), + "Security Group Egress rules count is not matching" + ) + # Verifying the details of the Egress rule are as expected + #Creating expected and actual values dictionaries + expected_dict = { + "cidr":self.services["ingress_rule"]["cidrlist"], + "protocol":self.services["ingress_rule"]["protocol"], + "startport":self.services["ingress_rule"]["startport"], + "endport":self.services["ingress_rule"]["endport"], + } + actual_dict = { + "cidr":str(securitygroup_egress[0].cidr), + "protocol":str(securitygroup_egress[0].protocol.upper()), + "startport":str(securitygroup_egress[0].startport), + "endport":str(securitygroup_egress[0].endport), + } + ingress_status = self.__verify_values( + expected_dict, + actual_dict + ) + self.assertEqual( + True, + ingress_status, + "Listed Security group Egress rule details are not as expected" + ) + # Revoking the Egress rule from Security Group + securitygroup_created.revokeEgress(self.userapiclient, securitygroup_egress[0].ruleid) + # Listing the security group by Id + list_securitygroups_byid = SecurityGroup.list( + self.userapiclient, + listall=self.services["listall"], + id=securitygroup_created.id, + domainid=self.domain.id + ) + # Verifying that security group is listed + status = validateList(list_securitygroups_byid) + self.assertEquals( + PASS, + status[0], + "Listing of Security Groups by id failed" + ) + # Verifying size of the list is 1 + self.assertEquals( + 1, + len(list_securitygroups_byid), + "Count of the listing security group by id is not matching" + ) + securitygroup_egress = list_securitygroups_byid[0].egressrule + # Verifying that Ingress rule is empty(revoked) + status = validateList(securitygroup_egress) + self.assertEquals( + EMPTY_LIST, + status[2], + "Security Groups Egress rule is not revoked" + ) + return \ No newline at end of file diff --git a/test/integration/component/test_escalations_snapshots.py b/test/integration/component/test_escalations_snapshots.py new file mode 100644 index 0000000000..0aa36c3cf1 --- /dev/null +++ b/test/integration/component/test_escalations_snapshots.py @@ -0,0 +1,629 @@ +# 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 Local Modules +from marvin.cloudstackTestCase import * +from marvin.cloudstackException import * +from marvin.cloudstackAPI import * +from marvin.sshClient import SshClient +from marvin.lib.utils import * +from marvin.lib.base import * +from marvin.lib.common import * +from marvin.lib.utils import checkVolumeSize +from marvin.codes import SUCCESS +from nose.plugins.attrib import attr +from time import sleep +from ctypes.wintypes import BOOLEAN + +class TestSnapshots(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + try: + cls._cleanup = [] + cls.testClient = super(TestSnapshots, 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()) + cls.template = get_template( + cls.api_client, + cls.zone.id, + cls.services["ostype"] + ) + if cls.zone.localstorageenabled: + cls.storagetype = 'local' + cls.services["service_offerings"]["tiny"]["storagetype"] = 'local' + cls.services["disk_offering"]["storagetype"] = 'local' + else: + cls.storagetype = 'shared' + cls.services["service_offerings"]["tiny"]["storagetype"] = 'shared' + cls.services["disk_offering"]["storagetype"] = 'shared' + + cls.services['mode'] = cls.zone.networktype + cls.services["virtual_machine"]["hypervisor"] = cls.testClient.getHypervisorInfo() + cls.services["virtual_machine"]["zoneid"] = cls.zone.id + cls.services["virtual_machine"]["template"] = cls.template.id + cls.services["custom_volume"]["zoneid"] = cls.zone.id + # Creating Disk offering, Service Offering and Account + cls.disk_offering = DiskOffering.create( + cls.api_client, + cls.services["disk_offering"] + ) + cls._cleanup.append(cls.disk_offering) + cls.service_offering = ServiceOffering.create( + cls.api_client, + cls.services["service_offerings"]["tiny"] + ) + cls._cleanup.append(cls.service_offering) + cls.account = Account.create( + cls.api_client, + cls.services["account"], + domainid=cls.domain.id + ) + # Getting authentication for user in newly created Account + cls.user = cls.account.user[0] + cls.userapiclient = cls.testClient.getUserApiClient(cls.user.username, cls.domain.name) + cls._cleanup.append(cls.account) + # Creating Virtual Machine + cls.virtual_machine = VirtualMachine.create( + cls.userapiclient, + cls.services["virtual_machine"], + accountid=cls.account.name, + domainid=cls.account.domainid, + serviceofferingid=cls.service_offering.id, + ) + cls._cleanup.append(cls.virtual_machine) + except Exception as e: + cls.tearDownClass() + raise Exception("Warning: Exception in setup : %s" % e) + return + + def setUp(self): + + self.apiClient = self.testClient.getApiClient() + self.cleanup = [] + + def tearDown(self): + # Clean up, terminate the created resources + cleanup_resources(self.apiClient, self.cleanup) + return + + @classmethod + def tearDownClass(cls): + try: + cleanup_resources(cls.api_client, cls._cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + + return + + def __verify_values(self, expected_vals, actual_vals): + """ + @Desc: Function to verify expected and actual values + @Steps: + Step1: Initializing return flag to True + Step1: Verifying length of expected and actual dictionaries is matching. + If not matching returning false + Step2: Listing all the keys from expected dictionary + Step3: Looping through each key from step2 and verifying expected and actual dictionaries have same value + If not making return flag to False + Step4: returning the return flag after all the values are verified + """ + return_flag = True + + if len(expected_vals) != len(actual_vals): + return False + + keys = expected_vals.keys() + for i in range(0, len(expected_vals)): + exp_val = expected_vals[keys[i]] + act_val = actual_vals[keys[i]] + if exp_val == act_val: + return_flag = return_flag and True + else: + return_flag = return_flag and False + self.debug("expected Value: %s, is not matching with actual value: %s" % ( + exp_val, + act_val + )) + return return_flag + + @attr(tags=["advanced", "basic", "provisioning"]) + def test_01_list_volume_snapshots_pagination(self): + """ + @Desc: Test to List Volume Snapshots pagination + @steps: + Step1: Listing all the volume snapshots for a user + Step2: Verifying that list size is 0 + Step3: Creating (page size + 1) number of volume snapshots + Step4: Listing all the volume snapshots again for a user + Step5: Verifying that list size is (page size + 1) + Step6: Listing all the volume snapshots in page1 + Step7: Verifying that list size is (page size) + Step8: Listing all the volume snapshots in page2 + Step9: Verifying that list size is 1 + Step10: Deleting the volume snapshot present in page 2 + Step11: Listing all the volume snapshots in page2 + Step12: Verifying that list size is 0 + """ + # Listing all the volume snapshots for a User + list_vol_snaps_before = Snapshot.list( + self.userapiclient, + listall=self.services["listall"] + ) + # Verifying list size is 0 + self.assertIsNone( + list_vol_snaps_before, + "Volume snapshots exists for newly created user" + ) + # Listing the root volumes available for the user + volumes_list = Volume.list( + self.userapiclient, + listall=self.services["listall"] + ) + status = validateList(volumes_list) + self.assertEquals( + PASS, + status[0], + "Root volume did not get created while deploying a VM" + ) + # Verifying list size to be 1 + self.assertEquals( + 1, + len(volumes_list), + "More than 1 root volume created for deployed VM" + ) + root_volume = volumes_list[0] + # Creating pagesize + 1 number of volume snapshots + for i in range(0, (self.services["pagesize"] + 1)): + snapshot_created = Snapshot.create( + self.userapiclient, + root_volume.id, + ) + self.assertIsNotNone( + snapshot_created, + "Snapshot creation failed" + ) + self.cleanup.append(snapshot_created) + + # Listing all the volume snapshots for user again + list_vol_snaps_after = Snapshot.list( + self.userapiclient, + listall=self.services["listall"] + ) + status = validateList(list_vol_snaps_after) + self.assertEquals( + PASS, + status[0], + "Volume snapshot creation failed" + ) + # Verifying that list size is pagesize + 1 + self.assertEquals( + self.services["pagesize"] + 1, + len(list_vol_snaps_after), + "Failed to create pagesize + 1 number of Volume snapshots" + ) + # Listing all the volume snapshots in page 1 + list_vol_snaps_page1 = Snapshot.list( + self.userapiclient, + listall=self.services["listall"], + page=1, + pagesize=self.services["pagesize"] + ) + status = validateList(list_vol_snaps_page1) + self.assertEquals( + PASS, + status[0], + "Failed to list volume snapshots in page 1" + ) + # Verifying the list size to be equal to pagesize + self.assertEquals( + self.services["pagesize"], + len(list_vol_snaps_page1), + "Size of volume snapshots in page 1 is not matching" + ) + # Listing all the volume snapshots in page 2 + list_vol_snaps_page2 = Snapshot.list( + self.userapiclient, + listall=self.services["listall"], + page=2, + pagesize=self.services["pagesize"] + ) + status = validateList(list_vol_snaps_page2) + self.assertEquals( + PASS, + status[0], + "Failed to list volume snapshots in page 2" + ) + # Verifying the list size to be equal to pagesize + self.assertEquals( + 1, + len(list_vol_snaps_page2), + "Size of volume snapshots in page 2 is not matching" + ) + # Deleting the volume snapshot present in page 2 + Snapshot.delete( + snapshot_created, + self.userapiclient + ) + # Listing all the snapshots in page 2 again + list_vol_snaps_page2 = Snapshot.list( + self.userapiclient, + listall=self.services["listall"], + page=2, + pagesize=self.services["pagesize"] + ) + # Verifying that list size is 0 + self.assertIsNone( + list_vol_snaps_page2, + "Volume snapshot not deleted from page 2" + ) + return + + @attr(tags=["advanced", "basic", "provisioning"]) + def test_02_list_volume_snapshots_byid(self): + """ + @Desc: Test to List Volume Snapshots by Id + @Steps: + Step1: Listing all the volume snapshots for a user + Step2: Verifying that list size is 0 + Step3: Creating a volume snapshot + Step4: Listing all the volume snapshots again for a user + Step5: Verifying that list size is 1 + Step6: Listing all the volume snapshots by specifying snapshot id + Step7: Verifying that list size is 1 + Step8: Verifying details of the listed volume snapshot + """ + # Listing all the volume snapshots for a User + list_vol_snaps_before = Snapshot.list( + self.userapiclient, + listall=self.services["listall"] + ) + # Verifying list size is 0 + self.assertIsNone( + list_vol_snaps_before, + "Volume snapshots exists for newly created user" + ) + # Listing the root volumes available for the user + volumes_list = Volume.list( + self.userapiclient, + listall=self.services["listall"] + ) + status = validateList(volumes_list) + self.assertEquals( + PASS, + status[0], + "Root volume did not get created while deploying a VM" + ) + # Verifying list size to be 1 + self.assertEquals( + 1, + len(volumes_list), + "More than 1 root volume created for deployed VM" + ) + root_volume = volumes_list[0] + # Creating a volume snapshot + snapshot_created = Snapshot.create( + self.userapiclient, + root_volume.id, + ) + self.assertIsNotNone( + snapshot_created, + "Snapshot creation failed" + ) + self.cleanup.append(snapshot_created) + # Listing all the volume snapshots for user again + list_vol_snaps_after = Snapshot.list( + self.userapiclient, + listall=self.services["listall"] + ) + status = validateList(list_vol_snaps_after) + self.assertEquals( + PASS, + status[0], + "Volume snapshot creation failed" + ) + # Verifying that list size is 1 + self.assertEquals( + 1, + len(list_vol_snaps_after), + "Failed to create Volume snapshot" + ) + # Listing volume snapshot by id + list_vol_snapshot = Snapshot.list( + self.userapiclient, + listall=self.services["listall"], + id=snapshot_created.id + ) + status = validateList(list_vol_snapshot) + self.assertEquals( + PASS, + status[0], + "Failed to list Volume snapshot by Id" + ) + # Verifying that list size is 1 + self.assertEquals( + 1, + len(list_vol_snapshot), + "Size of the list volume snapshot by Id is not matching" + ) + # Verifying details of the listed snapshot to be same as snapshot created above + # Creating expected and actual values dictionaries + expected_dict = { + "id":snapshot_created.id, + "name":snapshot_created.name, + "state":snapshot_created.state, + "intervaltype":snapshot_created.intervaltype, + "account":snapshot_created.account, + "domain":snapshot_created.domainid, + "volume":snapshot_created.volumeid + } + actual_dict = { + "id":list_vol_snapshot[0].id, + "name":list_vol_snapshot[0].name, + "state":list_vol_snapshot[0].state, + "intervaltype":list_vol_snapshot[0].intervaltype, + "account":list_vol_snapshot[0].account, + "domain":list_vol_snapshot[0].domainid, + "volume":list_vol_snapshot[0].volumeid + } + vol_snapshot_status = self.__verify_values( + expected_dict, + actual_dict + ) + self.assertEqual( + True, + vol_snapshot_status, + "Listed Volume Snapshot details are not as expected" + ) + return + + @attr(tags=["advanced", "basic", "provisioning"]) + def test_03_list_vm_snapshots_pagination(self): + """ + @Desc: Test to List VM Snapshots pagination + @Steps: + Step1: Listing all the VM snapshots for a user + Step2: Verifying that list size is 0 + Step3: Creating (page size + 1) number of VM snapshots + Step4: Listing all the VM snapshots again for a user + Step5: Verifying that list size is (page size + 1) + Step6: Listing all the VM snapshots in page1 + Step7: Verifying that list size is (page size) + Step8: Listing all the VM snapshots in page2 + Step9: Verifying that list size is 1 + Step10: Deleting the VM snapshot present in page 2 + Step11: Listing all the volume snapshots in page2 + Step12: Verifying that list size is 0 + """ + if self.hypervisor.lower() == 'kvm': + raise unittest.SkipTest("VM Snapshot is not supported on KVM. Hence, skipping the test") + # Listing all the VM snapshots for a User + list_vm_snaps_before = VmSnapshot.list( + self.userapiclient, + listall=self.services["listall"] + ) + # Verifying list size is 0 + self.assertIsNone( + list_vm_snaps_before, + "VM snapshots exists for newly created user" + ) + # Creating pagesize + 1 number of VM snapshots + for i in range(0, (self.services["pagesize"] + 1)): + snapshot_created = VmSnapshot.create( + self.userapiclient, + self.virtual_machine.id, + ) + self.assertIsNotNone( + snapshot_created, + "Snapshot creation failed" + ) + + # Listing all the VM snapshots for user again + list_vm_snaps_after = VmSnapshot.list( + self.userapiclient, + listall=self.services["listall"] + ) + status = validateList(list_vm_snaps_after) + self.assertEquals( + PASS, + status[0], + "VM snapshot creation failed" + ) + # Verifying that list size is pagesize + 1 + self.assertEquals( + self.services["pagesize"] + 1, + len(list_vm_snaps_after), + "Failed to create pagesize + 1 number of VM snapshots" + ) + # Listing all the VM snapshots in page 1 + list_vm_snaps_page1 = VmSnapshot.list( + self.userapiclient, + listall=self.services["listall"], + page=1, + pagesize=self.services["pagesize"] + ) + status = validateList(list_vm_snaps_page1) + self.assertEquals( + PASS, + status[0], + "Failed to list vm snapshots in page 1" + ) + # Verifying the list size to be equal to pagesize + self.assertEquals( + self.services["pagesize"], + len(list_vm_snaps_page1), + "Size of vm snapshots in page 1 is not matching" + ) + # Listing all the vm snapshots in page 2 + list_vm_snaps_page2 = VmSnapshot.list( + self.userapiclient, + listall=self.services["listall"], + page=2, + pagesize=self.services["pagesize"] + ) + status = validateList(list_vm_snaps_page2) + self.assertEquals( + PASS, + status[0], + "Failed to list vm snapshots in page 2" + ) + # Verifying the list size to be equal to pagesize + self.assertEquals( + 1, + len(list_vm_snaps_page2), + "Size of vm snapshots in page 2 is not matching" + ) + # Deleting the vm snapshot present in page 2 + VmSnapshot.deleteVMSnapshot( + self.userapiclient, + snapshot_created.id + ) + # Listing all the snapshots in page 2 again + list_vm_snaps_page2 = VmSnapshot.list( + self.userapiclient, + listall=self.services["listall"], + page=2, + pagesize=self.services["pagesize"] + ) + # Verifying that list size is 0 + self.assertIsNone( + list_vm_snaps_page2, + "VM snapshot not deleted from page 2" + ) + # Deleting all the existing VM snapshots + list_vm_snaps = VmSnapshot.list( + self.userapiclient, + listall=self.services["listall"], + ) + status = validateList(list_vm_snaps) + self.assertEquals( + PASS, + status[0], + "All VM snapshots deleted" + ) + # Verifying that list size is equal to page size + self.assertEquals( + self.services["pagesize"], + len(list_vm_snaps), + "VM Snapshots count is not matching" + ) + # Deleting all the existing VM snapshots + for i in range(0, len(list_vm_snaps)): + VmSnapshot.deleteVMSnapshot( + self.userapiclient, + list_vm_snaps[i].id + ) + return + + @attr(tags=["advanced", "basic", "provisioning"]) + def test_04_list_vm_snapshots_byid(self): + """ + @summary: Test to List VM Snapshots by Id + + Step1: Listing all the VM snapshots for a user + Step2: Verifying that list size is 0 + Step3: Creating a VM snapshot + Step4: Listing all the VM snapshots again for a user + Step5: Verifying that list size is 1 + Step6: Listing all the VM snapshots by specifying snapshot id + Step7: Verifying that list size is 1 + Step8: Verifying details of the listed VM snapshot + """ + if self.hypervisor.lower() == 'kvm': + raise unittest.SkipTest("VM Snapshot is not supported on KVM. Hence, skipping the test") + # Listing all the VM snapshots for a User + list_vm_snaps_before = VmSnapshot.list( + self.userapiclient, + listall=self.services["listall"] + ) + # Verifying list size is 0 + self.assertIsNone( + list_vm_snaps_before, + "VM snapshots exists for newly created user" + ) + # Creating a VM snapshot + snapshot_created = VmSnapshot.create( + self.userapiclient, + self.virtual_machine.id, + ) + self.assertIsNotNone( + snapshot_created, + "Snapshot creation failed" + ) + # Listing all the VM snapshots for user again + list_vm_snaps_after = VmSnapshot.list( + self.userapiclient, + listall=self.services["listall"] + ) + status = validateList(list_vm_snaps_after) + self.assertEquals( + PASS, + status[0], + "VM snapshot creation failed" + ) + # Verifying that list size is 1 + self.assertEquals( + 1, + len(list_vm_snaps_after), + "Failed to create VM snapshot" + ) + # Listing vm snapshot by id + list_vm_snapshot = VmSnapshot.list( + self.userapiclient, + listall=self.services["listall"], + vmsnapshotid=snapshot_created.id + ) + status = validateList(list_vm_snapshot) + self.assertEquals( + PASS, + status[0], + "Failed to list VM snapshot by Id" + ) + # Verifying that list size is 1 + self.assertEquals( + 1, + len(list_vm_snapshot), + "Size of the list vm snapshot by Id is not matching" + ) + # Verifying details of the listed snapshot to be same as snapshot created above + # Creating expected and actual values dictionaries + expected_dict = { + "id":snapshot_created.id, + "name":snapshot_created.name, + "state":snapshot_created.state, + "vmid":snapshot_created.virtualmachineid, + } + actual_dict = { + "id":list_vm_snapshot[0].id, + "name":list_vm_snapshot[0].name, + "state":list_vm_snapshot[0].state, + "vmid":list_vm_snapshot[0].virtualmachineid, + } + vm_snapshot_status = self.__verify_values( + expected_dict, + actual_dict + ) + self.assertEqual( + True, + vm_snapshot_status, + "Listed VM Snapshot details are not as expected" + ) + return \ No newline at end of file diff --git a/test/integration/component/test_escalations_templates.py b/test/integration/component/test_escalations_templates.py new file mode 100644 index 0000000000..06e3d4287f --- /dev/null +++ b/test/integration/component/test_escalations_templates.py @@ -0,0 +1,905 @@ +# 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 Local Modules +from marvin.cloudstackTestCase import * +from marvin.cloudstackException import * +from marvin.cloudstackAPI import * +from marvin.sshClient import SshClient +from marvin.lib.utils import * +from marvin.lib.base import * +from marvin.lib.common import * +from marvin.lib.utils import checkVolumeSize +from marvin.codes import SUCCESS +from nose.plugins.attrib import attr +from time import sleep +from ctypes.wintypes import BOOLEAN + +class TestTemplates(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + try: + cls._cleanup = [] + cls.testClient = super(TestTemplates, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = cls.testClient.getParsedTestDataConfig() + # Get Domain, Zone, Template + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) + cls.template = get_template( + cls.api_client, + cls.zone.id, + cls.services["ostype"] + ) + cls.hypervisor = cls.testClient.getHypervisorInfo() + cls.services['mode'] = cls.zone.networktype + cls.account = Account.create( + cls.api_client, + cls.services["account"], + domainid=cls.domain.id + ) + # Getting authentication for user in newly created Account + cls.user = cls.account.user[0] + cls.userapiclient = cls.testClient.getUserApiClient(cls.user.username, cls.domain.name) + cls._cleanup.append(cls.account) + except Exception as e: + cls.tearDownClass() + raise Exception("Warning: Exception in setup : %s" % e) + return + + def setUp(self): + + self.apiClient = self.testClient.getApiClient() + self.cleanup = [] + + def tearDown(self): + # Clean up, terminate the created resources + cleanup_resources(self.apiClient, self.cleanup) + return + + @classmethod + def tearDownClass(cls): + try: + cleanup_resources(cls.api_client, cls._cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + + return + + def __verify_values(self, expected_vals, actual_vals): + """ + @Desc: Function to verify expected and actual values + @Steps: + Step1: Initializing return flag to True + Step1: Verifying length of expected and actual dictionaries is matching. + If not matching returning false + Step2: Listing all the keys from expected dictionary + Step3: Looping through each key from step2 and verifying expected and actual dictionaries have same value + If not making return flag to False + Step4: returning the return flag after all the values are verified + """ + return_flag = True + + if len(expected_vals) != len(actual_vals): + return False + + keys = expected_vals.keys() + for i in range(0, len(expected_vals)): + exp_val = expected_vals[keys[i]] + act_val = actual_vals[keys[i]] + if exp_val == act_val: + return_flag = return_flag and True + else: + return_flag = return_flag and False + self.debug("expected Value: %s, is not matching with actual value: %s" % ( + exp_val, + act_val + )) + return return_flag + + @attr(tags=["advanced", "basic", "provisioning"]) + def test_01_list_templates_pagination(self): + """ + @Desc: Test to List Templates pagination + @steps: + Step1: Listing all the Templates for a user + Step2: Verifying that no Templates are listed + Step3: Creating (page size + 1) number of Templates + Step4: Listing all the Templates again for a user + Step5: Verifying that list size is (page size + 1) + Step6: Listing all the Templates in page1 + Step7: Verifying that list size is (page size) + Step8: Listing all the Templates in page2 + Step9: Verifying that list size is 1 + Step10: Listing the template by Id + Step11: Verifying if the template is downloaded and ready. + If yes the continuing + If not waiting and checking for template to be ready till timeout + Step12: Deleting the Template present in page 2 + Step13: Listing all the Templates in page2 + Step14: Verifying that no Templates are listed + """ + # Listing all the Templates for a User + list_templates_before = Template.list( + self.userapiclient, + listall=self.services["listall"], + templatefilter=self.services["templatefilter"] + ) + # Verifying that no Templates are listed + self.assertIsNone( + list_templates_before, + "Templates listed for newly created User" + ) + self.services["templateregister"]["ostype"] = self.services["ostype"] + # Creating pagesize + 1 number of Templates + for i in range(0, (self.services["pagesize"] + 1)): + template_created = Template.register( + self.userapiclient, + self.services["templateregister"], + self.zone.id, + hypervisor=self.hypervisor + ) + self.assertIsNotNone( + template_created, + "Template creation failed" + ) + if(i < self.services["pagesize"]): + self.cleanup.append(template_created) + + # Listing all the Templates for a User + list_templates_after = Template.list( + self.userapiclient, + listall=self.services["listall"], + templatefilter=self.services["templatefilter"] + ) + status = validateList(list_templates_after) + self.assertEquals( + PASS, + status[0], + "Templates creation failed" + ) + # Verifying that list size is pagesize + 1 + self.assertEquals( + self.services["pagesize"] + 1, + len(list_templates_after), + "Failed to create pagesize + 1 number of Templates" + ) + # Listing all the Templates in page 1 + list_templates_page1 = Template.list( + self.userapiclient, + listall=self.services["listall"], + templatefilter=self.services["templatefilter"], + page=1, + pagesize=self.services["pagesize"] + ) + status = validateList(list_templates_page1) + self.assertEquals( + PASS, + status[0], + "Failed to list Templates in page 1" + ) + # Verifying the list size to be equal to pagesize + self.assertEquals( + self.services["pagesize"], + len(list_templates_page1), + "Size of Templates in page 1 is not matching" + ) + # Listing all the Templates in page 2 + list_templates_page2 = Template.list( + self.userapiclient, + listall=self.services["listall"], + templatefilter=self.services["templatefilter"], + page=2, + pagesize=self.services["pagesize"] + ) + status = validateList(list_templates_page2) + self.assertEquals( + PASS, + status[0], + "Failed to list Templates in page 2" + ) + # Verifying the list size to be equal to 1 + self.assertEquals( + 1, + len(list_templates_page2), + "Size of Templates in page 2 is not matching" + ) + # Verifying the state of the template to be ready. If not waiting for state to become ready + template_ready = False + count = 0 + while template_ready is False: + list_template = Template.list( + self.userapiclient, + id=template_created.id, + listall=self.services["listall"], + templatefilter=self.services["templatefilter"], + ) + status = validateList(list_template) + self.assertEquals( + PASS, + status[0], + "Failed to list Templates by Id" + ) + if list_template[0].isready is True: + template_ready = True + elif (str(list_template[0].status) == "Error"): + self.fail("Created Template is in Errored state") + break + elif count > 10: + self.fail("Timed out before Template came into ready state") + break + else: + time.sleep(self.services["sleep"]) + count = count + 1 + + # Deleting the Template present in page 2 + Template.delete( + template_created, + self.userapiclient + ) + # Listing all the Templates in page 2 again + list_templates_page2 = Template.list( + self.userapiclient, + listall=self.services["listall"], + templatefilter=self.services["templatefilter"], + page=2, + pagesize=self.services["pagesize"] + ) + # Verifying that there are no Templates listed + self.assertIsNone( + list_templates_page2, + "Templates not deleted from page 2" + ) + del self.services["templateregister"]["ostype"] + return + + @attr(tags=["advanced", "basic", "provisioning"]) + def test_02_download_template(self): + """ + @Desc: Test to Download Template + @steps: + Step1: Listing all the Templates for a user + Step2: Verifying that no Templates are listed + Step3: Creating a Templates + Step4: Listing all the Templates again for a user + Step5: Verifying that list size is 1 + Step6: Verifying if the template is in ready state. + If yes the continuing + If not waiting and checking for template to be ready till timeout + Step7: Downloading the template (Extract) + Step8: Verifying that Template is downloaded + """ + # Listing all the Templates for a User + list_templates_before = Template.list( + self.userapiclient, + listall=self.services["listall"], + templatefilter=self.services["templatefilter"] + ) + # Verifying that no Templates are listed + self.assertIsNone( + list_templates_before, + "Templates listed for newly created User" + ) + self.services["templateregister"]["ostype"] = self.services["ostype"] + self.services["templateregister"]["isextractable"] = True + # Creating aTemplate + template_created = Template.register( + self.userapiclient, + self.services["templateregister"], + self.zone.id, + hypervisor=self.hypervisor + ) + self.assertIsNotNone( + template_created, + "Template creation failed" + ) + self.cleanup.append(template_created) + # Listing all the Templates for a User + list_templates_after = Template.list( + self.userapiclient, + listall=self.services["listall"], + templatefilter=self.services["templatefilter"] + ) + status = validateList(list_templates_after) + self.assertEquals( + PASS, + status[0], + "Templates creation failed" + ) + # Verifying that list size is 1 + self.assertEquals( + 1, + len(list_templates_after), + "Failed to create a Template" + ) + # Verifying the state of the template to be ready. If not waiting for state to become ready till time out + template_ready = False + count = 0 + while template_ready is False: + list_template = Template.list( + self.userapiclient, + id=template_created.id, + listall=self.services["listall"], + templatefilter=self.services["templatefilter"], + ) + status = validateList(list_template) + self.assertEquals( + PASS, + status[0], + "Failed to list Templates by Id" + ) + if list_template[0].isready is True: + template_ready = True + elif (str(list_template[0].status) == "Error"): + self.fail("Created Template is in Errored state") + break + elif count > 10: + self.fail("Timed out before Template came into ready state") + break + else: + time.sleep(self.services["sleep"]) + count = count + 1 + + # Downloading the Template name + download_template = Template.extract( + self.userapiclient, + template_created.id, + mode="HTTP_DOWNLOAD", + zoneid=self.zone.id + ) + self.assertIsNotNone( + download_template, + "Download Template failed" + ) + # Verifying the details of downloaded template + self.assertEquals( + "DOWNLOAD_URL_CREATED", + download_template.state, + "Download URL not created for Template" + ) + self.assertIsNotNone( + download_template.url, + "Download URL not created for Template" + ) + self.assertEquals( + template_created.id, + download_template.id, + "Download Template details are not same as Template created" + ) + del self.services["templateregister"]["ostype"] + del self.services["templateregister"]["isextractable"] + return + + @attr(tags=["advanced", "basic", "provisioning"]) + def test_03_edit_template_details(self): + """ + @Desc: Test to Edit Template name, displaytext, OSType + @steps: + Step1: Listing all the Templates for a user + Step2: Verifying that no Templates are listed + Step3: Creating a Templates + Step4: Listing all the Templates again for a user + Step5: Verifying that list size is 1 + Step6: Verifying if the template is in ready state. + If yes the continuing + If not waiting and checking for template to be ready till timeout + Step7: Editing the template name + Step8: Verifying that Template name is edited + Step9: Editing the template displaytext + Step10: Verifying that Template displaytext is edited + Step11: Editing the template ostypeid + Step12: Verifying that Template ostypeid is edited + Step13: Editing the template name, displaytext + Step14: Verifying that Template name, displaytext are edited + Step15: Editing the template name, displaytext, ostypeid + Step16: Verifying that Template name, displaytext and ostypeid are edited + """ + # Listing all the Templates for a User + list_templates_before = Template.list( + self.userapiclient, + listall=self.services["listall"], + templatefilter=self.services["templatefilter"] + ) + # Verifying that no Templates are listed + self.assertIsNone( + list_templates_before, + "Templates listed for newly created User" + ) + self.services["templateregister"]["ostype"] = self.services["ostype"] + # Creating aTemplate + template_created = Template.register( + self.userapiclient, + self.services["templateregister"], + self.zone.id, + hypervisor=self.hypervisor + ) + self.assertIsNotNone( + template_created, + "Template creation failed" + ) + self.cleanup.append(template_created) + # Listing all the Templates for a User + list_templates_after = Template.list( + self.userapiclient, + listall=self.services["listall"], + templatefilter=self.services["templatefilter"] + ) + status = validateList(list_templates_after) + self.assertEquals( + PASS, + status[0], + "Templates creation failed" + ) + # Verifying that list size is 1 + self.assertEquals( + 1, + len(list_templates_after), + "Failed to create a Template" + ) + # Verifying the state of the template to be ready. If not waiting for state to become ready till time out + template_ready = False + count = 0 + while template_ready is False: + list_template = Template.list( + self.userapiclient, + id=template_created.id, + listall=self.services["listall"], + templatefilter=self.services["templatefilter"], + ) + status = validateList(list_template) + self.assertEquals( + PASS, + status[0], + "Failed to list Templates by Id" + ) + if list_template[0].isready is True: + template_ready = True + elif (str(list_template[0].status) == "Error"): + self.fail("Created Template is in Errored state") + break + elif count > 10: + self.fail("Timed out before Template came into ready state") + break + else: + time.sleep(self.services["sleep"]) + count = count + 1 + + # Editing the Template name + edited_template = Template.update( + template_created, + self.userapiclient, + name="NewTemplateName" + ) + self.assertIsNotNone( + edited_template, + "Editing Template failed" + ) + # Verifying the details of edited template + expected_dict = { + "id":template_created.id, + "name":"NewTemplateName", + "displaytest":template_created.displaytext, + "account":template_created.account, + "domainid":template_created.domainid, + "format":template_created.format, + "ostypeid":template_created.ostypeid, + "templatetype":template_created.templatetype, + } + actual_dict = { + "id":edited_template.id, + "name":edited_template.name, + "displaytest":edited_template.displaytext, + "account":edited_template.account, + "domainid":edited_template.domainid, + "format":edited_template.format, + "ostypeid":edited_template.ostypeid, + "templatetype":edited_template.templatetype, + } + edit_template_status = self.__verify_values( + expected_dict, + actual_dict + ) + self.assertEqual( + True, + edit_template_status, + "Edited Template details are not as expected" + ) + # Editing the Template displaytext + edited_template = Template.update( + template_created, + self.userapiclient, + displaytext="TemplateDisplaytext" + ) + self.assertIsNotNone( + edited_template, + "Editing Template failed" + ) + # Verifying the details of edited template + expected_dict = { + "id":template_created.id, + "name":"NewTemplateName", + "displaytest":"TemplateDisplaytext", + "account":template_created.account, + "domainid":template_created.domainid, + "format":template_created.format, + "ostypeid":template_created.ostypeid, + "templatetype":template_created.templatetype, + } + actual_dict = { + "id":edited_template.id, + "name":edited_template.name, + "displaytest":edited_template.displaytext, + "account":edited_template.account, + "domainid":edited_template.domainid, + "format":edited_template.format, + "ostypeid":edited_template.ostypeid, + "templatetype":edited_template.templatetype, + } + edit_template_status = self.__verify_values( + expected_dict, + actual_dict + ) + self.assertEqual( + True, + edit_template_status, + "Edited Template details are not as expected" + ) + # Editing the Template ostypeid + ostype_list = list_os_types(self.userapiclient) + status = validateList(ostype_list) + self.assertEquals( + PASS, + status[0], + "Failed to list OS Types" + ) + for i in range(0, len(ostype_list)): + if ostype_list[i].id != template_created.ostypeid: + newostypeid = ostype_list[i].id + break + + edited_template = Template.update( + template_created, + self.userapiclient, + ostypeid=newostypeid + ) + self.assertIsNotNone( + edited_template, + "Editing Template failed" + ) + # Verifying the details of edited template + expected_dict = { + "id":template_created.id, + "name":"NewTemplateName", + "displaytest":"TemplateDisplaytext", + "account":template_created.account, + "domainid":template_created.domainid, + "format":template_created.format, + "ostypeid":newostypeid, + "templatetype":template_created.templatetype, + } + actual_dict = { + "id":edited_template.id, + "name":edited_template.name, + "displaytest":edited_template.displaytext, + "account":edited_template.account, + "domainid":edited_template.domainid, + "format":edited_template.format, + "ostypeid":edited_template.ostypeid, + "templatetype":edited_template.templatetype, + } + edit_template_status = self.__verify_values( + expected_dict, + actual_dict + ) + self.assertEqual( + True, + edit_template_status, + "Edited Template details are not as expected" + ) + # Editing the Template name, displaytext + edited_template = Template.update( + template_created, + self.userapiclient, + name=template_created.name, + displaytext=template_created.displaytext + ) + self.assertIsNotNone( + edited_template, + "Editing Template failed" + ) + # Verifying the details of edited template + expected_dict = { + "id":template_created.id, + "name":template_created.name, + "displaytest":template_created.displaytext, + "account":template_created.account, + "domainid":template_created.domainid, + "format":template_created.format, + "ostypeid":newostypeid, + "templatetype":template_created.templatetype, + } + actual_dict = { + "id":edited_template.id, + "name":edited_template.name, + "displaytest":edited_template.displaytext, + "account":edited_template.account, + "domainid":edited_template.domainid, + "format":edited_template.format, + "ostypeid":edited_template.ostypeid, + "templatetype":edited_template.templatetype, + } + edit_template_status = self.__verify_values( + expected_dict, + actual_dict + ) + self.assertEqual( + True, + edit_template_status, + "Edited Template details are not as expected" + ) + # Editing the Template name, displaytext, ostypeid + edited_template = Template.update( + template_created, + self.userapiclient, + name="NewTemplateName", + displaytext="TemplateDisplaytext", + ostypeid=template_created.ostypeid + ) + self.assertIsNotNone( + edited_template, + "Editing Template failed" + ) + # Verifying the details of edited template + expected_dict = { + "id":template_created.id, + "name":"NewTemplateName", + "displaytest":"TemplateDisplaytext", + "account":template_created.account, + "domainid":template_created.domainid, + "format":template_created.format, + "ostypeid":template_created.ostypeid, + "templatetype":template_created.templatetype, + } + actual_dict = { + "id":edited_template.id, + "name":edited_template.name, + "displaytest":edited_template.displaytext, + "account":edited_template.account, + "domainid":edited_template.domainid, + "format":edited_template.format, + "ostypeid":edited_template.ostypeid, + "templatetype":edited_template.templatetype, + } + edit_template_status = self.__verify_values( + expected_dict, + actual_dict + ) + self.assertEqual( + True, + edit_template_status, + "Edited Template details are not as expected" + ) + del self.services["templateregister"]["ostype"] + return + + @attr(tags=["advanced", "basic", "provisioning"]) + def test_04_copy_template(self): + """ + @Desc: Test to copy Template from one zone to another + @steps: + Step1: Listing Zones available for a user + Step2: Verifying if the zones listed are greater than 1. + If Yes continuing. + If not halting the test. + Step3: Listing all the templates for a user in zone1 + Step4: Verifying that no templates are listed + Step5: Listing all the templates for a user in zone2 + Step6: Verifying that no templates are listed + Step7: Creating a Template in zone 1 + Step8: Listing all the Templates again for a user in zone1 + Step9: Verifying that list size is 1 + Step10: Listing all the templates for a user in zone2 + Step11: Verifying that no templates are listed + Step12: Copying the template created in step7 from zone1 to zone2 + Step13: Listing all the templates for a user in zone2 + Step14: Verifying that list size is 1 + Step15: Listing all the Templates for a user in zone1 + Step16: Verifying that list size is 1 + """ + # Listing Zones available for a user + zones_list = Zone.list( + self.userapiclient, + available=True + ) + status = validateList(zones_list) + self.assertEquals( + PASS, + status[0], + "Failed to list Zones" + ) + if not len(zones_list) > 1: + raise unittest.SkipTest("Enough zones doesnot exists to copy template") + else: + # Listing all the Templates for a User in Zone 1 + list_templates_zone1 = Template.list( + self.userapiclient, + listall=self.services["listall"], + templatefilter=self.services["templatefilter"], + zoneid=zones_list[0].id + ) + # Verifying that no Templates are listed + self.assertIsNone( + list_templates_zone1, + "Templates listed for newly created User in Zone1" + ) + # Listing all the Templates for a User in Zone 2 + list_templates_zone2 = Template.list( + self.userapiclient, + listall=self.services["listall"], + templatefilter=self.services["templatefilter"], + zoneid=zones_list[1].id + ) + # Verifying that no Templates are listed + self.assertIsNone( + list_templates_zone2, + "Templates listed for newly created User in Zone2" + ) + self.services["templateregister"]["ostype"] = self.services["ostype"] + # Listing Hypervisors in Zone 1 + hypervisor_list = Hypervisor.list( + self.apiClient, + zoneid=zones_list[0].id + ) + status = validateList(zones_list) + self.assertEquals( + PASS, + status[0], + "Failed to list Hypervisors in Zone 1" + ) + # Creating aTemplate in Zone 1 + template_created = Template.register( + self.userapiclient, + self.services["templateregister"], + zones_list[0].id, + hypervisor=hypervisor_list[0].name + ) + self.assertIsNotNone( + template_created, + "Template creation failed" + ) + self.cleanup.append(template_created) + # Listing all the Templates for a User in Zone 1 + list_templates_zone1 = Template.list( + self.userapiclient, + listall=self.services["listall"], + templatefilter=self.services["templatefilter"], + zoneid=zones_list[0].id + ) + status = validateList(list_templates_zone1) + self.assertEquals( + PASS, + status[0], + "Templates creation failed in Zone1" + ) + # Verifying that list size is 1 + self.assertEquals( + 1, + len(list_templates_zone1), + "Failed to create a Template" + ) + # Listing all the Templates for a User in Zone 2 + list_templates_zone2 = Template.list( + self.userapiclient, + listall=self.services["listall"], + templatefilter=self.services["templatefilter"], + zoneid=zones_list[1].id + ) + # Verifying that no Templates are listed + self.assertIsNone( + list_templates_zone2, + "Templates listed for newly created User in Zone2" + ) + # Verifying the state of the template to be ready. If not waiting for state to become ready till time out + template_ready = False + count = 0 + while template_ready is False: + list_template = Template.list( + self.userapiclient, + id=template_created.id, + listall=self.services["listall"], + templatefilter=self.services["templatefilter"], + ) + status = validateList(list_template) + self.assertEquals( + PASS, + status[0], + "Failed to list Templates by Id" + ) + if list_template[0].isready is True: + template_ready = True + elif (str(list_template[0].status) == "Error"): + self.fail("Created Template is in Errored state") + break + elif count > 10: + self.fail("Timed out before Template came into ready state") + break + else: + time.sleep(self.services["sleep"]) + count = count + 1 + + # Copying the Template from Zone1 to Zone2 + copied_template = Template.copy( + self.userapiclient, + template_created.id, + sourcezoneid=template_created.zoneid, + destzoneid=zones_list[1].id + ) + self.assertIsNotNone( + copied_template, + "Copying Template from Zone1 to Zone2 failed" + ) + # Listing all the Templates for a User in Zone 1 + list_templates_zone1 = Template.list( + self.userapiclient, + listall=self.services["listall"], + templatefilter=self.services["templatefilter"], + zoneid=zones_list[0].id + ) + status = validateList(list_templates_zone1) + self.assertEquals( + PASS, + status[0], + "Templates creation failed in Zone1" + ) + # Verifying that list size is 1 + self.assertEquals( + 1, + len(list_templates_zone1), + "Failed to create a Template" + ) + # Listing all the Templates for a User in Zone 2 + list_templates_zone2 = Template.list( + self.userapiclient, + listall=self.services["listall"], + templatefilter=self.services["templatefilter"], + zoneid=zones_list[1].id + ) + status = validateList(list_templates_zone2) + self.assertEquals( + PASS, + status[0], + "Template failed to copy into Zone2" + ) + # Verifying that list size is 1 + self.assertEquals( + 1, + len(list_templates_zone2), + "Template failed to copy into Zone2" + ) + self.assertNotEquals( + "Connection refused", + list_templates_zone2[0].status, + "Failed to copy Template" + ) + self.assertEquals( + True, + list_templates_zone2[0].isready, + "Failed to copy Template" + ) + del self.services["templateregister"]["ostype"] + return \ No newline at end of file diff --git a/test/integration/component/test_escalations_volumes.py b/test/integration/component/test_escalations_volumes.py new file mode 100644 index 0000000000..d1dae12681 --- /dev/null +++ b/test/integration/component/test_escalations_volumes.py @@ -0,0 +1,1703 @@ +# 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 Local Modules +from marvin.cloudstackTestCase import * +from marvin.cloudstackException import * +from marvin.cloudstackAPI import * +from marvin.sshClient import SshClient +from marvin.lib.utils import * +from marvin.lib.base import * +from marvin.lib.common import * +from marvin.lib.utils import checkVolumeSize +from marvin.codes import SUCCESS +from nose.plugins.attrib import attr +from time import sleep + +class TestVolumes(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + try: + cls._cleanup = [] + cls.testClient = super(TestVolumes, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = cls.testClient.getParsedTestDataConfig() + # Get Domain, Zone, Template + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) + cls.template = get_template( + cls.api_client, + cls.zone.id, + cls.services["ostype"] + ) + if cls.zone.localstorageenabled: + cls.storagetype = 'local' + cls.services["service_offerings"]["tiny"]["storagetype"] = 'local' + cls.services["disk_offering"]["storagetype"] = 'local' + else: + cls.storagetype = 'shared' + cls.services["service_offerings"]["tiny"]["storagetype"] = 'shared' + cls.services["disk_offering"]["storagetype"] = 'shared' + + cls.services['mode'] = cls.zone.networktype + cls.services["virtual_machine"]["hypervisor"] = cls.testClient.getHypervisorInfo() + cls.services["virtual_machine"]["zoneid"] = cls.zone.id + cls.services["virtual_machine"]["template"] = cls.template.id + cls.services["custom_volume"]["zoneid"] = cls.zone.id + # Creating Disk offering, Service Offering and Account + cls.disk_offering = DiskOffering.create( + cls.api_client, + cls.services["disk_offering"] + ) + cls.service_offering = ServiceOffering.create( + cls.api_client, + cls.services["service_offerings"]["tiny"] + ) + cls.account = Account.create( + cls.api_client, + cls.services["account"], + domainid=cls.domain.id + ) + # Getting authentication for user in newly created Account + cls.user = cls.account.user[0] + cls.userapiclient = cls.testClient.getUserApiClient(cls.user.username, cls.domain.name) + # Creating Virtual Machine + cls.virtual_machine = VirtualMachine.create( + cls.userapiclient, + cls.services["virtual_machine"], + accountid=cls.account.name, + domainid=cls.account.domainid, + serviceofferingid=cls.service_offering.id, + ) + cls._cleanup.append(cls.virtual_machine) + cls._cleanup.append(cls.disk_offering) + cls._cleanup.append(cls.service_offering) + cls._cleanup.append(cls.account) + except Exception as e: + cls.tearDownClass() + raise Exception("Warning: Exception in setup : %s" % e) + return + + def setUp(self): + + self.apiClient = self.testClient.getApiClient() + self.cleanup = [] + + def tearDown(self): + #Clean up, terminate the created volumes + cleanup_resources(self.apiClient, self.cleanup) + return + + @classmethod + def tearDownClass(cls): + try: + cleanup_resources(cls.api_client, cls._cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + + + def __verify_values(self, expected_vals, actual_vals): + """ + @summary: Function to verify expected and actual values + Step1: Initializing return flag to True + Step1: Verifying length of expected and actual dictionaries is matching. + If not matching returning false + Step2: Listing all the keys from expected dictionary + Step3: Looping through each key from step2 and verifying expected and actual dictionaries have same value + If not making return flag to False + Step4: returning the return flag after all the values are verified + """ + return_flag = True + + if len(expected_vals) != len(actual_vals): + return False + + keys = expected_vals.keys() + for i in range(0, len(expected_vals)): + exp_val = expected_vals[keys[i]] + act_val = actual_vals[keys[i]] + if exp_val == act_val: + return_flag = return_flag and True + else: + return_flag = return_flag and False + self.debug("expected Value: %s, is not matching with actual value: %s" % ( + exp_val, + act_val + )) + return return_flag + + @attr(tags=["advanced", "basic", "provisioning"]) + def test_01_list_volumes_pagination(self): + """ + @summary: Test List Volumes pagination + + Step1: Listing all the volumes for a user + Step2: Verifying listed volumes for account created at class level + Step3: If number of volumes is less than (page size + 1), then creating them + Step4: Listing all the volumes again after creation of volumes + Step5: Verifying the length of the volumes is (page size + 1) + Step6: Listing all the volumes in page1 + Step7: Verifying that the length of the volumes in page 1 is (page size) + Step8: Listing all the volumes in page2 + Step9: Verifying that the length of the volumes in page 2 is 1 + Step10: Deleting the volume present in page 2 + Step11: Listing for the volumes on page 2 + Step12: Verifying that there are no volumes present in page 2 + """ + # Listing all the volumes for a user + list_volumes_before = Volume.list(self.userapiclient, listall=self.services["listall"]) + + # Verifying listed volumes for account created at class level + self.assertIsNotNone( + list_volumes_before, + "create volume from VM failed at class setup method" + ) + self.assertEqual( + len(list_volumes_before), + 1, + "more than 1 volume created from VM at class level" + ) + + # If number of volumes is less than (pagesize + 1), then creating them + for i in range(0, (self.services["pagesize"])): + volume_created = Volume.create( + self.userapiclient, + self.services["volume"], + zoneid=self.zone.id, + diskofferingid=self.disk_offering.id + ) + self.assertIsNotNone( + volume_created, + "Volume is not created" + ) + if(i < (self.services["pagesize"] - 1)): + self.cleanup.append(volume_created) + + self.assertEqual( + self.services["volume"]["diskname"], + volume_created.name, + "Newly created volume name and the test data volume name are not matching" + ) + + # Listing all the volumes again after creation of volumes + list_volumes_after = Volume.list(self.userapiclient, listall=self.services["listall"]) + + # Verifying the length of the volumes is (page size + 1) + self.assertEqual( + len(list_volumes_after), + (self.services["pagesize"] + 1), + "Number of volumes created is not matching expected" + ) + + # Listing all the volumes in page1 + list_volumes_page1 = Volume.list( + self.userapiclient, + listall=self.services["listall"], + page=1, + pagesize=self.services["pagesize"] + ) + self.assertIsNotNone( + list_volumes_page1, + "No volumes found in Page 1" + ) + # Verifying that the length of the volumes in page 1 is (page size) + self.assertEqual( + len(list_volumes_page1), + self.services["pagesize"], + "List Volume response is not matching with the page size length for page 1" + ) + + # Listing all the volumes in page2 + list_volumes_page2 = Volume.list( + self.userapiclient, + listall=self.services["listall"], + page=2, + pagesize=self.services["pagesize"] + ) + self.assertIsNotNone( + list_volumes_page2, + "No volumes found in Page 2" + ) + # Verifying that the length of the volumes in page 2 is 1 + self.assertEqual( + len(list_volumes_page2), + 1, + "List Volume response is not matching with the page size length for page 2" + ) + volume_page2 = list_volumes_page2[0] + + # Verifying that the volume on page 2 is not present in page1 + for i in range(0, len(list_volumes_page1)): + volume_page1 = list_volumes_page1[i] + self.assertNotEquals( + volume_page2.id, + volume_page1.id, + "Volume listed in page 2 is also listed in page 1" + ) + + # Deleting a single volume + Volume.delete(volume_created, self.userapiclient) + + # Listing the volumes in page 2 + list_volume_response = Volume.list( + self.userapiclient, + listall=self.services["listall"], + page=2, + pagesize=self.services["pagesize"] + ) + # verifying that volume does not exists on page 2 + self.assertEqual( + list_volume_response, + None, + "Volume was not deleted" + ) + return + + @attr(tags=["advanced", "basic", "provisioning"]) + def test_02_list_volume_byid(self): + """ + @summary: Test List Volumes with Id + + Step1: Listing all the volumes for a user before creating a data volume + Step2: Verifying the length of the list as 1 + Step3: Creating a data volume + Step4: Listing all the volumes for a user after creating a data volume + Step5: Verifying the list volume size is increased by 1 + Step6: List the volumes by specifying root volume Id + Step7: Verifying the details of the root volume + Step8: List the volumes by specifying data volume Id + Step9: Verifying the details of the data volume + """ + # Listing all the volumes for a user before creating a data volume + list_volumes_before = Volume.list( + self.userapiclient, + listall=self.services["listall"] + ) + self.assertIsNotNone( + list_volumes_before, + "create volume from VM failed at class setup method") + # Verifying the length of the list as 1 + self.assertEqual( + len(list_volumes_before), + 1, + "more than 1 volume created at class level" + ) + root_volume = list_volumes_before[0] + + # Creating a data volume + volume_created = Volume.create( + self.userapiclient, + self.services["volume"], + zoneid=self.zone.id, + diskofferingid=self.disk_offering.id + ) + self.assertIsNotNone( + volume_created, + "Volume is not created" + ) + self.cleanup.append(volume_created) + + self.assertEqual( + self.services["volume"]["diskname"], + volume_created.name, + "Newly created volume name and the test data volume name are not matching" + ) + # Listing all the volumes for a user after creating a data volume + list_volumes_after = Volume.list( + self.userapiclient, + listall=self.services["listall"] + ) + self.assertIsNotNone( + list_volumes_after, + "Volume creation failed" + ) + # Verifying the list volume size is increased by 1 + self.assertEqual( + len(list_volumes_before) + 1, + len(list_volumes_after), + "list volume is not matching with Number of volumes created" + ) + + # Listing a Root Volume by Id and verifying the volume details + list_volumes_by_id = Volume.list( + self.userapiclient, + listall=self.services["listall"], + id=root_volume.id + ) + self.assertIsNotNone( + list_volumes_by_id, + "Root volume is not listed" + ) + self.assertEqual( + 1, + len(list_volumes_by_id), + "list volume is not matching with Number of volumes created" + ) + obtained_volume = list_volumes_by_id[0] + + #Creating expected and actual values dictionaries + expected_dict = { + "id":root_volume.id, + "name":root_volume.name, + "vmname":self.virtual_machine.name, + "state":"Ready", + "type":"ROOT", + "zoneid":self.zone.id, + "account":self.account.name, + "storagetype":self.storagetype, + "size":self.template.size + } + actual_dict = { + "id":obtained_volume.id, + "name":obtained_volume.name, + "vmname":obtained_volume.vmname, + "state":obtained_volume.state, + "type":obtained_volume.type, + "zoneid":obtained_volume.zoneid, + "account":obtained_volume.account, + "storagetype":obtained_volume.storagetype, + "size":obtained_volume.size, + } + root_volume_status = self.__verify_values( + expected_dict, + actual_dict + ) + self.assertEqual( + True, + root_volume_status, + "Listed Root Volume details are not as expected" + ) + # Listing a Data Volume by Id and verifying the volume details + list_volumes_by_id = Volume.list( + self.userapiclient, + listall=self.services["listall"], + id=volume_created.id + ) + self.assertIsNotNone( + list_volumes_by_id, + "Data volume is not listed" + ) + self.assertEqual( + len(list_volumes_by_id), + 1, + "list volume is not matching with Number of volumes created" + ) + obtained_volume = list_volumes_by_id[0] + + #Creating expected and actual values dictionaries + expected_dict = { + "id":volume_created.id, + "name":volume_created.name, + "state":"Allocated", + "type":"DATADISK", + "zoneid":self.zone.id, + "account":self.account.name, + "storagetype":self.storagetype, + "size":self.disk_offering.disksize + } + actual_dict = { + "id":obtained_volume.id, + "name":obtained_volume.name, + "state":obtained_volume.state, + "type":obtained_volume.type, + "zoneid":obtained_volume.zoneid, + "account":obtained_volume.account, + "storagetype":obtained_volume.storagetype, + "size":obtained_volume.size/(1024*1024*1024), + } + root_volume_status = self.__verify_values( + expected_dict, + actual_dict + ) + self.assertEqual( + True, + root_volume_status, + "Listed Data Volume details are not as expected" + ) + return + + @attr(tags=["advanced", "basic", "provisioning"]) + def test_03_data_volume_resize(self): + """ + @summary: Test to verify creation and resize of data volume + + Step1: Listing the volumes for a user before creating data volume + Step2: Creating a data volume + Step3: Listing the volumes for a user after creating data volume + Step4: Attaching and Detaching data volume created to Virtual Machine + Step5: Verifying if there exists a disk offering with higher size + If not present creating it + Step6: Resizing data volume + """ + # Listing volumes for a user before creating a volume + list_volumes_before = Volume.list(self.userapiclient, listall=self.services["listall"]) + + # Creating a data volume + volume_created = Volume.create( + self.userapiclient, + self.services["volume"], + zoneid=self.zone.id, + diskofferingid=self.disk_offering.id + ) + self.assertIsNotNone(volume_created, "Data volume creation failed") + + self.cleanup.append(volume_created) + + # Listing volumes for a user after creating data volume + list_volumes_after = Volume.list(self.userapiclient, listall=self.services["listall"]) + self.assertEquals( + len(list_volumes_before) + 1, + len(list_volumes_after), + "Data volume creation failed" + ) + + # Attaching data volume created to Virtual Machine + self.virtual_machine.attach_volume( + self.userapiclient, + volume_created + ) + + list_volumes = Volume.list( + self.userapiclient, + listall=self.services["listall"], + id=volume_created.id + ) + attached_volume = list_volumes[0] + + self.assertIsNotNone( + attached_volume.vmname, + "VM is not attached to Volume" + ) + self.assertEquals( + self.virtual_machine.name, + attached_volume.vmname, + "VM Name is not matching with attached vm" + ) + + # Detaching data volume from Virtual Machine + self.virtual_machine.detach_volume( + self.userapiclient, + volume_created + ) + list_volumes = Volume.list( + self.userapiclient, + listall=self.services["listall"], + id=volume_created.id + ) + detached_volume = list_volumes[0] + self.assertIsNone( + detached_volume.vmname, + "VM is not detached from volume" + ) + + # Verifying if there exists a disk offering with higher size. If not present creating it + list_disk_offerings = DiskOffering.list(self.apiClient) + + large_disk_offering_exists = False + # Converting disk_size in bytes to GB + current_disk_size = volume_created.size/(1024*1024*1024) + + for disk_offering in list_disk_offerings: + if ((disk_offering.disksize > current_disk_size) and (not disk_offering.iscustomized) and disk_offering.storagetype == self.storagetype): + new_disk_offering = disk_offering + large_disk_offering_exists = True + break + + if large_disk_offering_exists == False: + new_size = (volume_created.size/(1024*1024*1024)) + 1 + self.services["disk_offering"]["disksize"] = new_size + new_disk_offering = DiskOffering.create( + self.apiClient, + self.services["disk_offering"] + ) + if new_disk_offering is not None: + self.cleanup.append(new_disk_offering) + else: + new_size = new_disk_offering.disksize + + # Resizing data volume + resized_volume = volume_created.resize( + self.userapiclient, + diskofferingid=new_disk_offering.id, + shrinkok='false', + ) + self.assertIsNotNone(resized_volume, "Resize Volume failed") + # Verifying data volume size is increased + self.assertEquals( + new_size, + (resized_volume.size/(1024*1024*1024)), + "volume not resized to expected value" + ) + return + + @attr(tags=["advanced", "basic", "provisioning"]) + def test_04_custom_volume_resize(self): + """ + @summary: Test to verify creation and resize of custom volume + + Step1: Checking if Custom disk offering already exists. + If not present then creating custom Disk Offering + Step2: Listing the volumes for a user before creating custom volume + Step3: Creating a custom volume + Step4: Listing the volumes for a user after creating custom volume + Step5: Attaching and Detaching custom volume created to Virtual Machine + Step6: Resizing custom volume + """ + # Listing all the disk offerings + list_disk_offerings = DiskOffering.list(self.apiClient) + + custom_disk_offering_exists = False + + # Verifying if a custom disk offering already exists + if list_disk_offerings is not None: + for disk_offering in list_disk_offerings: + if (disk_offering.iscustomized and disk_offering.storagetype == self.storagetype): + custom_disk_offering = disk_offering + custom_disk_offering_exists = True + break + + # If a custom disk offering does not exists, then creating a custom disk offering + if custom_disk_offering_exists == False: + custom_disk_offering = DiskOffering.create( + self.apiClient, + self.services["disk_offering"], + custom=True + ) + if custom_disk_offering is not None: + self.cleanup.append(custom_disk_offering) + + # Listing the volumes for a user before creating custom volume + list_volumes_before = Volume.list(self.userapiclient, listall=self.services["listall"]) + + # Creating a custom volume + volume_created = Volume.create_custom_disk( + self.userapiclient, + self.services["custom_volume"], + account=self.account.name, + domainid=self.account.domainid, + diskofferingid=custom_disk_offering.id + ) + self.assertIsNotNone( + volume_created, + "Custom volume did not get created" + ) + + self.cleanup.append(volume_created) + + # Listing the volumes for a user after creating custom volume + list_volumes_after = Volume.list(self.userapiclient, listall=self.services["listall"]) + + # Verifyign that volume list is increased by 1 after creation of custion volume + self.assertEquals( + len(list_volumes_before) + 1, + len(list_volumes_after), + "Custom volume did not get created" + ) + + # Attaching custom volume created to Virtual Machine + self.virtual_machine.attach_volume( + self.userapiclient, + volume_created + ) + list_volumes = Volume.list( + self.userapiclient, + listall=self.services["listall"], + id=volume_created.id + ) + attached_volume = list_volumes[0] + + self.assertIsNotNone( + attached_volume.vmname, + "VM is not attached to Volume" + ) + self.assertEquals( + self.virtual_machine.name, + attached_volume.vmname, + "VM Name is not matching with attached vm" + ) + + # Detaching custom volume from Virtual Machine + self.virtual_machine.detach_volume( + self.userapiclient, + volume_created + ) + list_volumes = Volume.list( + self.userapiclient, + listall=self.services["listall"], + id=volume_created.id + ) + detached_volume = list_volumes[0] + self.assertIsNone( + detached_volume.vmname, + "VM is not detached from volume" + ) + + # Resizing custom volume + # Increasing custom disk size by 1 + new_size = self.services["custom_volume"]["customdisksize"] + 1 + resized_volume = volume_created.resize( + self.userapiclient, + diskofferingid=custom_disk_offering.id, + shrinkok='false', + size=new_size) + self.assertIsNotNone(resized_volume, "Resize Volume failed") + # Verifying that custom disk size is increased + self.assertEquals( + new_size, + (resized_volume.size/(1024*1024*1024)), + "volume not resized to expected value" + ) + return + + @attr(tags=["advanced", "basic", "provisioning"]) + def test_05_volume_snapshot(self): + """ + @summary: Test to verify creation of snapshot from volume and creation of template, volume from snapshot + + Step1: Creating a volume + Step2: Attaching and Detaching custom volume created to Virtual Machine + Step3: Creating Snapshot from volume + Step4: Creating Volume from snapshot + Step5: Creating Template from Snapshot + """ + list_volumes_before = Volume.list(self.userapiclient, listall=self.services["listall"]) + + volume_created = Volume.create( + self.userapiclient, + self.services["volume"], + zoneid=self.zone.id, + diskofferingid=self.disk_offering.id + ) + + self.assertIsNotNone(volume_created, "Volume not created") + + if volume_created is not None: + self.cleanup.append(volume_created) + + list_volumes_after = Volume.list(self.userapiclient, listall=self.services["listall"]) + + self.assertEquals( + len(list_volumes_before) + 1, + len(list_volumes_after), + "Volume not created" + ) + # Attaching and Detaching custom volume created to Virtual Machine + self.virtual_machine.attach_volume( + self.userapiclient, + volume_created + ) + + list_volumes = Volume.list( + self.userapiclient, + listall=self.services["listall"], + id=volume_created.id + ) + attached_volume = list_volumes[0] + + self.assertIsNotNone( + attached_volume.vmname, + "VM is not attached to Volume" + ) + self.assertEquals( + self.virtual_machine.name, + attached_volume.vmname, + "VM Name is not matching with attached vm" + ) + self.virtual_machine.detach_volume( + self.userapiclient, + volume_created + ) + list_volumes = Volume.list( + self.userapiclient, + listall=self.services["listall"], + id=volume_created.id + ) + detached_volume = list_volumes[0] + self.assertIsNone( + detached_volume.vmname, + "VM is not detached from volume" + ) + # Creating Snapshot from volume + snapshot_created = Snapshot.create( + self.userapiclient, + volume_created.id, + ) + + self.assertIsNotNone(snapshot_created, "Snapshot not created") + + self.cleanup.append(snapshot_created) + + #Creating expected and actual values dictionaries + expected_dict = { + "id":volume_created.id, + "intervaltype":"MANUAL", + "snapshottype":"MANUAL", + "volumetype":volume_created.type, + "domain":self.domain.id + } + actual_dict = { + "id":snapshot_created.volumeid, + "intervaltype":snapshot_created.intervaltype, + "snapshottype":snapshot_created.snapshottype, + "volumetype":snapshot_created.volumetype, + "domain":snapshot_created.domainid, + } + status = self.__verify_values( + expected_dict, + actual_dict + ) + self.assertEqual( + True, + status, + "Snapshot created from Volume details are not as expected" + ) + # Creating Volume from snapshot + cmd = createVolume.createVolumeCmd() + cmd.name = "-".join([self.services["volume"]["diskname"], random_gen()]) + cmd.snapshotid = snapshot_created.id + + volume_from_snapshot = Volume(self.userapiclient.createVolume(cmd).__dict__) + + self.assertIsNotNone( + volume_from_snapshot, + "Volume creation failed from snapshot" + ) + self.cleanup.append(volume_from_snapshot) + + #Creating expected and actual values dictionaries + expected_dict = { + "snapshotid":snapshot_created.id, + "volumetype":snapshot_created.volumetype, + "size":self.disk_offering.disksize, + "accounr":self.account.name, + "domain":self.domain.id, + "storagetype":self.storagetype, + "zone":self.zone.id + } + actual_dict = { + "snapshotid":volume_from_snapshot.snapshotid, + "volumetype":volume_from_snapshot.type, + "size":volume_from_snapshot.size/(1024*1024*1024), + "accounr":volume_from_snapshot.account, + "domain":volume_from_snapshot.domainid, + "storagetype":volume_from_snapshot.storagetype, + "zone":volume_from_snapshot.zoneid, + } + status = self.__verify_values( + expected_dict, + actual_dict + ) + self.assertEqual( + True, + status, + "Volume created from Snapshot details are not as expected" + ) + # Creating Template from Snapshot + list_templates_before = Template.list(self.userapiclient, templatefilter='self') + + if list_templates_before is None: + templates_before_size = 0 + else: + templates_before_size = len(list_templates_before) + + cmd = createTemplate.createTemplateCmd() + cmd.name = self.services["ostype"] + cmd.displaytext = self.services["ostype"] + cmd.ostypeid = self.template.ostypeid + cmd.snapshotid = snapshot_created.id + cmd.ispublic = False + cmd.passwordenabled = False + + template_from_snapshot = Template(self.userapiclient.createTemplate(cmd).__dict__) + + self.assertIsNotNone( + template_from_snapshot, + "Template creation failed from snapshot" + ) + + self.cleanup.append(template_from_snapshot) + + #Creating expected and actual values dictionaries + expected_dict = { + "name":self.services["ostype"], + "ostypeid":self.template.ostypeid, + "type":"USER", + "zone":self.zone.id, + "domain":self.domain.id, + "account":self.account.name, + "passwordenabled":False, + "ispublic":False, + "size":self.disk_offering.disksize + } + actual_dict = { + "name":template_from_snapshot.name, + "ostypeid":template_from_snapshot.ostypeid, + "type":template_from_snapshot.templatetype, + "zone":template_from_snapshot.zoneid, + "domain":template_from_snapshot.domainid, + "account":template_from_snapshot.account, + "passwordenabled":template_from_snapshot.passwordenabled, + "ispublic":template_from_snapshot.ispublic, + "size":template_from_snapshot.size/(1024*1024*1024) + } + status = self.__verify_values( + expected_dict, + actual_dict + ) + self.assertEqual( + True, + status, + "Template created from Snapshot details are not as expected" + ) + + list_templates_after = Template.list(self.userapiclient, templatefilter='self') + + self.assertEquals( + templates_before_size + 1, + len(list_templates_after), + "Template creation failed from snapshot" + ) + return + + @attr(tags=["advanced", "basic", "provisioning"]) + def test_06_volume_snapshot_policy_hourly(self): + """ + @summary: Test to verify creation of Hourly Snapshot policies from volume + + Step1: Creating a Volume. + Step2: Attaching volume created in Step2 to virtual machine + Step3: Detaching the volume created in step2 from virtual machine + Step4: Listing snapshot policies for a volume created in step1 + Step5: Creating Hourly snapshot policy + Step6: Listing snapshot policies for a volume created in step1 again + Step7: Verifyign that the list snapshot policy length is increased by 1 + """ + list_volumes_before = Volume.list(self.userapiclient, listall=self.services["listall"]) + + volume_created = Volume.create( + self.userapiclient, + self.services["volume"], + zoneid=self.zone.id, + diskofferingid=self.disk_offering.id + ) + + self.assertIsNotNone(volume_created, "Volume not created") + self.cleanup.append(volume_created) + + list_volumes_after = Volume.list(self.userapiclient, listall=self.services["listall"]) + + self.assertEquals( + len(list_volumes_before) + 1, + len(list_volumes_after), + "Volume not created" + ) + + # Attaching volume created to Virtual Machine + self.virtual_machine.attach_volume( + self.userapiclient, + volume_created + ) + + list_volumes = Volume.list( + self.userapiclient, + listall=self.services["listall"], + id=volume_created.id + ) + attached_volume = list_volumes[0] + + self.assertIsNotNone( + attached_volume.vmname, + "VM is not attached to Volume" + ) + self.assertEquals( + self.virtual_machine.name, + attached_volume.vmname, + "VM Name is not matching with attached vm" + ) + # Detaching volume created from Virtual Machine + self.virtual_machine.detach_volume( + self.userapiclient, + volume_created + ) + list_volumes = Volume.list( + self.userapiclient, + listall=self.services["listall"], + id=volume_created.id + ) + detached_volume = list_volumes[0] + self.assertIsNone( + detached_volume.vmname, + "VM is not detached from volume" + ) + # Creating Hourly Snapshot Policy from volume + self.services["recurring_snapshot"]["intervaltype"] = 'hourly' + self.services["recurring_snapshot"]["schedule"] = '1' + + list_snapshot_policy_before = SnapshotPolicy.list(self.userapiclient, volumeid=volume_created.id) + + snapshot_policy_before_size = 0 + + if list_snapshot_policy_before is not None: + snapshot_policy_before_size = len(list_snapshot_policy_before) + + snapshot_policy_hourly = SnapshotPolicy.create( + self.userapiclient, + volume_created.id, + self.services["recurring_snapshot"] + ) + self.assertIsNotNone( + snapshot_policy_hourly, + "Hourly Snapshot policy creation failed" + ) + #Creating expected and actual values dictionaries + expected_dict = { + "schedule":self.services["recurring_snapshot"]["schedule"], + "intervaltype":0, + "volumeid":volume_created.id + } + actual_dict = { + "schedule":snapshot_policy_hourly.schedule, + "intervaltype":snapshot_policy_hourly.intervaltype, + "volumeid":snapshot_policy_hourly.volumeid + } + status = self.__verify_values( + expected_dict, + actual_dict + ) + self.assertEqual( + True, + status, + "Hourly Snapshot Policy details are not as expected" + ) + + list_snapshot_policy_after = SnapshotPolicy.list(self.userapiclient, volumeid=volume_created.id) + + self.assertIsNotNone( + list_snapshot_policy_after, + "Hourly Snapshot policy creation failed" + ) + self.assertEquals( + snapshot_policy_before_size + 1, + len(list_snapshot_policy_after), + "Hourly Snapshot policy creation failed" + ) + return + + @attr(tags=["advanced", "basic", "provisioning"]) + def test_07_volume_snapshot_policy_daily(self): + """ + @summary: Test to verify creation of Daily Snapshot policies from volume + + Step1: Creating a Volume. + Step2: Attaching volume created in Step2 to virtual machine + Step3: Detaching the volume created in step2 from virtual machine + Step4: Listing snapshot policies for a volume created in step1 + Step5: Creating Daily snapshot policy + Step6: Listing snapshot policies for a volume created in step1 again + Step7: Verifyign that the list snapshot policy length is increased by 1 + """ + list_volumes_before = Volume.list(self.userapiclient, listall=self.services["listall"]) + + volume_created = Volume.create( + self.userapiclient, + self.services["volume"], + zoneid=self.zone.id, + diskofferingid=self.disk_offering.id + ) + + self.assertIsNotNone(volume_created, "Volume not created") + self.cleanup.append(volume_created) + + list_volumes_after = Volume.list(self.userapiclient, listall=self.services["listall"]) + + self.assertEquals( + len(list_volumes_before) + 1, + len(list_volumes_after), + "Volume not created" + ) + # Attaching volume created to Virtual Machine + self.virtual_machine.attach_volume( + self.userapiclient, + volume_created + ) + + list_volumes = Volume.list( + self.userapiclient, + listall=self.services["listall"], + id=volume_created.id + ) + attached_volume = list_volumes[0] + + self.assertIsNotNone( + attached_volume.vmname, + "VM is not attached to Volume" + ) + self.assertEquals( + self.virtual_machine.name, + attached_volume.vmname, + "VM Name is not matching with attached vm" + ) + # Detaching volume created from Virtual Machine + self.virtual_machine.detach_volume( + self.userapiclient, + volume_created + ) + list_volumes = Volume.list( + self.userapiclient, + listall=self.services["listall"], + id=volume_created.id + ) + detached_volume = list_volumes[0] + self.assertIsNone( + detached_volume.vmname, + "VM is not detached from volume" + ) + # Creating Daily Snapshot Policy from volume + self.services["recurring_snapshot"]["intervaltype"] = 'daily' + self.services["recurring_snapshot"]["schedule"] = '00:00' + + list_snapshot_policy_before = SnapshotPolicy.list(self.userapiclient, volumeid=volume_created.id) + + snapshot_policy_before_size = 0 + + if list_snapshot_policy_before is not None: + snapshot_policy_before_size = len(list_snapshot_policy_before) + + snapshot_policy_daily = SnapshotPolicy.create( + self.userapiclient, + volume_created.id, + self.services["recurring_snapshot"] + ) + self.assertIsNotNone( + snapshot_policy_daily, + "Daily Snapshot policy creation failed" + ) + #Creating expected and actual values dictionaries + expected_dict = { + "schedule":self.services["recurring_snapshot"]["schedule"], + "intervaltype":1, + "volumeid":volume_created.id + } + actual_dict = { + "schedule":snapshot_policy_daily.schedule, + "intervaltype":snapshot_policy_daily.intervaltype, + "volumeid":snapshot_policy_daily.volumeid + } + status = self.__verify_values( + expected_dict, + actual_dict + ) + self.assertEqual( + True, + status, + "Daily Snapshot Policy details are not as expected" + ) + + list_snapshot_policy_after = SnapshotPolicy.list(self.userapiclient, volumeid=volume_created.id) + + self.assertIsNotNone( + list_snapshot_policy_after, + "Daily Snapshot policy creation failed" + ) + self.assertEquals( + snapshot_policy_before_size + 1, + len(list_snapshot_policy_after), + "Daily Snapshot policy creation failed" + ) + return + + @attr(tags=["advanced", "basic", "provisioning"]) + def test_08_volume_snapshot_policy_weekly(self): + """ + @summary: Test to verify creation of Weekly Snapshot policies from volume + + Step1: Creating a Volume. + Step2: Attaching volume created in Step2 to virtual machine + Step3: Detaching the volume created in step2 from virtual machine + Step4: Listing snapshot policies for a volume created in step1 + Step5: Creating Weekly snapshot policy + Step6: Listing snapshot policies for a volume created in step1 again + Step7: Verifyign that the list snapshot policy length is increased by 1 + """ + list_volumes_before = Volume.list(self.userapiclient, listall=self.services["listall"]) + + volume_created = Volume.create( + self.userapiclient, + self.services["volume"], + zoneid=self.zone.id, + diskofferingid=self.disk_offering.id + ) + + self.assertIsNotNone(volume_created, "Volume not created") + self.cleanup.append(volume_created) + + list_volumes_after = Volume.list(self.userapiclient, listall=self.services["listall"]) + + self.assertEquals( + len(list_volumes_before) + 1, + len(list_volumes_after), + "Volume not created" + ) + + # Attaching volume created to Virtual Machine + self.virtual_machine.attach_volume( + self.userapiclient, + volume_created + ) + list_volumes = Volume.list( + self.userapiclient, + listall=self.services["listall"], + id=volume_created.id + ) + attached_volume = list_volumes[0] + + self.assertIsNotNone( + attached_volume.vmname, + "VM is not attached to Volume" + ) + self.assertEquals( + self.virtual_machine.name, + attached_volume.vmname, + "VM Name is not matching with attached vm" + ) + # Detaching volume created to Virtual Machine + self.virtual_machine.detach_volume( + self.userapiclient, + volume_created + ) + list_volumes = Volume.list( + self.userapiclient, + listall=self.services["listall"], + id=volume_created.id + ) + detached_volume = list_volumes[0] + self.assertIsNone( + detached_volume.vmname, + "VM is not detached from volume" + ) + # Creating Weekly Snapshot Policy from volume + self.services["recurring_snapshot"]["intervaltype"] = 'weekly' + self.services["recurring_snapshot"]["schedule"] = '00:00:1' + + list_snapshot_policy_before = SnapshotPolicy.list(self.userapiclient, volumeid=volume_created.id) + + snapshot_policy_before_size = 0 + + if list_snapshot_policy_before is not None: + snapshot_policy_before_size = len(list_snapshot_policy_before) + + snapshot_policy_weekly = SnapshotPolicy.create( + self.userapiclient, + volume_created.id, + self.services["recurring_snapshot"] + ) + self.assertIsNotNone( + snapshot_policy_weekly, + "Weekly Snapshot policy creation failed" + ) + #Creating expected and actual values dictionaries + expected_dict = { + "schedule":self.services["recurring_snapshot"]["schedule"], + "intervaltype":2, + "volumeid":volume_created.id + } + actual_dict = { + "schedule":snapshot_policy_weekly.schedule, + "intervaltype":snapshot_policy_weekly.intervaltype, + "volumeid":snapshot_policy_weekly.volumeid + } + status = self.__verify_values( + expected_dict, + actual_dict + ) + self.assertEqual( + True, + status, + "Weekly Snapshot Policy details are not as expected" + ) + + list_snapshot_policy_after = SnapshotPolicy.list(self.userapiclient, volumeid=volume_created.id) + + self.assertIsNotNone( + list_snapshot_policy_after, + "Weekly Snapshot policy creation failed" + ) + self.assertEquals( + snapshot_policy_before_size + 1, + len(list_snapshot_policy_after), + "Weekly Snapshot policy creation failed" + ) + return + + @attr(tags=["advanced", "basic", "provisioning"]) + def test_09_volume_snapshot_policy_monthly(self): + """ + @summary: Test to verify creation of Monthly Snapshot policies from volume + + Step1: Creating a Volume. + Step2: Attaching volume created in Step2 to virtual machine + Step3: Detaching the volume created in step2 from virtual machine + Step4: Listing snapshot policies for a volume created in step1 + Step5: Creating Monthly snapshot policy + Step6: Listing snapshot policies for a volume created in step1 again + Step7: Verifyign that the list snapshot policy length is increased by 1 + Step8: Deleting monthly snapshot policy created in step5 + Step9: List snapshot policies for a volume again + Step10: Verifying that the list snapshot policy length is decreased by 1 + """ + list_volumes_before = Volume.list(self.userapiclient, listall=self.services["listall"]) + + volume_created = Volume.create( + self.userapiclient, + self.services["volume"], + zoneid=self.zone.id, + diskofferingid=self.disk_offering.id + ) + self.assertIsNotNone(volume_created, "Volume not created") + self.cleanup.append(volume_created) + + list_volumes_after = Volume.list(self.userapiclient, listall=self.services["listall"]) + + self.assertEquals( + len(list_volumes_before) + 1, + len(list_volumes_after), + "Volume not created" + ) + # Attaching and Detaching custom volume created to Virtual Machine + self.virtual_machine.attach_volume( + self.userapiclient, + volume_created + ) + list_volumes = Volume.list( + self.userapiclient, + listall=self.services["listall"], + id=volume_created.id + ) + attached_volume = list_volumes[0] + + self.assertIsNotNone( + attached_volume.vmname, + "VM is not attached to Volume" + ) + self.assertEquals( + self.virtual_machine.name, + attached_volume.vmname, + "VM Name is not matching with attached vm" + ) + self.virtual_machine.detach_volume( + self.userapiclient, + volume_created + ) + list_volumes = Volume.list( + self.userapiclient, + listall=self.services["listall"], + id=volume_created.id + ) + detached_volume = list_volumes[0] + self.assertIsNone( + detached_volume.vmname, + "VM is not detached from volume" + ) + # Creating Monthly Snapshot Policy from volume + self.services["recurring_snapshot"]["intervaltype"] = 'monthly' + self.services["recurring_snapshot"]["schedule"] = '00:00:1' + + list_snapshot_policy_before = SnapshotPolicy.list(self.userapiclient, volumeid=volume_created.id) + + snapshot_policy_before_size = 0 + + if list_snapshot_policy_before is not None: + snapshot_policy_before_size = len(list_snapshot_policy_before) + + snapshot_policy_monthly = SnapshotPolicy.create( + self.userapiclient, + volume_created.id, + self.services["recurring_snapshot"]) + self.assertIsNotNone( + snapshot_policy_monthly, + "Monthly Snapshot policy creation failed" + ) + #Creating expected and actual values dictionaries + expected_dict = { + "schedule":self.services["recurring_snapshot"]["schedule"], + "intervaltype":3, + "volumeid":volume_created.id + } + actual_dict = { + "schedule":snapshot_policy_monthly.schedule, + "intervaltype":snapshot_policy_monthly.intervaltype, + "volumeid":snapshot_policy_monthly.volumeid + } + status = self.__verify_values( + expected_dict, + actual_dict + ) + self.assertEqual( + True, + status, + "Monthly Snapshot Policy details are not as expected" + ) + + list_snapshot_policy_after = SnapshotPolicy.list(self.userapiclient, volumeid=volume_created.id) + + self.assertIsNotNone( + list_snapshot_policy_after, + "Monthly Snapshot policy creation failed" + ) + self.assertEquals( + snapshot_policy_before_size + 1, + len(list_snapshot_policy_after), + "Monthly Snapshot policy creation failed" + ) + # Deleting monthly snapshot policy + SnapshotPolicy.delete(snapshot_policy_monthly, self.userapiclient) + + list_snapshot_policies = SnapshotPolicy.list(self.userapiclient, volumeid=volume_created.id) + + self.assertIsNone( + list_snapshot_policies, + "Deletion of Monthly Snapshot policy failed" + ) + return + + @attr(tags=["advanced", "basic", "provisioning"]) + def test_10_volume_snapshots_pagination(self): + """ + @summary: Test to verify pagination of snapshots for Volume + + Step1: Creating a Volume. + Step2: Attaching volume created in Step2 to virtual machine + Step3: Detaching the volume created in step2 from virtual machine + Step4: Listing all the snapshots for a volume + Step5: Creating Pagesize + 1 number of snapshots for a volume + Step6: Listing all the snapshots for a volume + Step7: Verifying that there are pagesize + 1 number of snapshots listsed + Step8: Listing all the snapshots in page 1 + Step9: Listing all the snapshots in page 2 + Step10: Deleting the snapshot present in page 2 + Step11: Listign the snapshots from page 2 again and verifyign that list returns none + """ + list_volumes_before = Volume.list(self.userapiclient, listall=self.services["listall"]) + + # Creating a Volume + volume_created = Volume.create( + self.userapiclient, + self.services["volume"], + zoneid=self.zone.id, + diskofferingid=self.disk_offering.id + ) + self.assertIsNotNone(volume_created, "Volume not created") + self.cleanup.append(volume_created) + + list_volumes_after = Volume.list(self.userapiclient, listall=self.services["listall"]) + + self.assertEquals( + len(list_volumes_before) + 1, + len(list_volumes_after), + "Volume not created" + ) + #Attaching volume to virtual machine + self.virtual_machine.attach_volume( + self.userapiclient, + volume_created + ) + list_volumes = Volume.list( + self.userapiclient, + listall=self.services["listall"], + id=volume_created.id + ) + attached_volume = list_volumes[0] + + self.assertIsNotNone( + attached_volume.vmname, + "VM is not attached to Volume" + ) + self.assertEquals( + self.virtual_machine.name, + attached_volume.vmname, + "VM Name is not matching with attached vm" + ) + #Detaching volume from virtual machine + self.virtual_machine.detach_volume( + self.userapiclient, + volume_created + ) + list_volumes = Volume.list( + self.userapiclient, + listall=self.services["listall"], + id=volume_created.id + ) + detached_volume = list_volumes[0] + self.assertIsNone( + detached_volume.vmname, + "VM is not detached from volume" + ) + + #Creating 3 Snapshots from volume + list_snapshot_before = Snapshot.list( + self.userapiclient, + volumeid=volume_created.id, + listall=self.services["listall"] + ) + self.assertIsNone( + list_snapshot_before, + "Newly created volume is already having snapshots" + ) + + list_snapshot_before_size = 0 + for i in range(0, 3): + snapshot_created = Snapshot.create( + self.userapiclient, + volume_created.id, + ) + self.assertIsNotNone(snapshot_created, "Snapshot not created") + self.cleanup.append(snapshot_created) + + self.assertEquals( + volume_created.id, + snapshot_created.volumeid, + "Snapshot not created for given volume" + ) + + list_snapshot_after = Snapshot.list( + self.userapiclient, + volumeid=volume_created.id, + listall=self.services["listall"] + ) + self.assertEqual( + list_snapshot_before_size+3, + len(list_snapshot_after), + "Number of snapshots created is not matching expected" + ) + #Listing all the snapshots in page1 + list_snapshots_page1 = Snapshot.list( + self.userapiclient, + volumeid=volume_created.id, + listall=self.services["listall"], + page=1, + pagesize=2 + ) + self.assertEqual( + 2, + len(list_snapshots_page1), + "List snapshots response is not matching with the page size length for page 1" + ) + + #Listing all the snapshots in page2 and ensuring only 1 snapshot is present + list_snapshots_page2 = Snapshot.list( + self.userapiclient, + volumeid=volume_created.id, + listall=self.services["listall"], + page=2, + pagesize=2 + ) + self.assertEqual( + len(list_snapshots_page2), + 1, + "List snapshots response is not matching with the page size length for page 2" + ) + snapshot_page2 = list_snapshots_page2[0] + + # Verifying that the snapshot on page 2 is not present in page1 + for i in range(0, len(list_snapshots_page1)): + snapshot_page1 = list_snapshots_page1[i] + self.assertNotEquals( + snapshot_page2.id, + snapshot_page1.id, + "Snapshot listed in page 2 is also listed in page 1" + ) + # Deleting a single snapshot and verifying that snapshot does not exists on page 2 + Snapshot.delete(snapshot_created, self.userapiclient) + + list_snapshot_page2 = Snapshot.list( + self.userapiclient, + volumeid=volume_created.id, + listall=self.services["listall"], + page=2, + pagesize=2 + ) + self.assertEqual( + None, + list_snapshot_page2, + "Snapshot was not deleted" + ) + list_snapshot_page1 = Snapshot.list( + self.userapiclient, + volumeid=volume_created.id, + listall=self.services["listall"], + page=1, + pagesize=2 + ) + self.assertEqual( + 2, + len(list_snapshot_page1), + "Snapshots on page 1 are not matching" + ) + return + + @attr(tags=["advanced", "basic", "provisioning"]) + def test_11_volume_extract(self): + """ + @summary: Test to verify extract/download a Volume + + Step1: Listing Volumes before creating a Volume + Step2: Creating a Volume. + Step3: Verifying that created volume is not none and adding to clean up + Step4: Listing the volumes after creation + Step5: Verifying that the list volume size is increased by 1 + Step6: Attaching volume created in Step2 to virtual machine + Step7: Detaching the volume created in step2 from virtual machine + Step8: Extracting/Downloadign the volume + Step9: Verifyign that a download URL is created for volume download + """ + list_volumes_before = Volume.list(self.userapiclient, listall=self.services["listall"]) + + self.assertIsNotNone( + list_volumes_before, + "volume not created for the vm launched at class level" + ) + volume_created = Volume.create( + self.userapiclient, + self.services["volume"], + zoneid=self.zone.id, + diskofferingid=self.disk_offering.id + ) + + self.assertIsNotNone(volume_created, "Volume not created") + self.cleanup.append(volume_created) + + list_volumes_after = Volume.list(self.userapiclient, listall=self.services["listall"]) + + self.assertIsNotNone( + list_volumes_after, + "volume creation failed" + ) + self.assertEquals( + len(list_volumes_before) + 1, + len(list_volumes_after), + "Volume not created" + ) + #Attaching and Detaching volume created to Virtual Machine + self.virtual_machine.attach_volume( + self.userapiclient, + volume_created + ) + list_volumes = Volume.list( + self.userapiclient, + listall=self.services["listall"], + id=volume_created.id + ) + attached_volume = list_volumes[0] + + self.assertIsNotNone( + attached_volume.vmname, + "VM is not attached to Volume" + ) + self.assertEquals( + self.virtual_machine.name, + attached_volume.vmname, + "VM Name is not matching with attached vm" + ) + self.virtual_machine.detach_volume( + self.userapiclient, + volume_created + ) + list_volumes = Volume.list( + self.userapiclient, + listall=self.services["listall"], + id=volume_created.id + ) + detached_volume = list_volumes[0] + self.assertIsNone( + detached_volume.vmname, + "VM is not detached from volume" + ) + #Extract/Download the volume + self.services["mode"] = "HTTP_DOWNLOAD" + + extract_volume_response = Volume.extract( + self.userapiclient, + volume_created.id, + self.zone.id, + self.services["mode"] + ) + self.assertIsNotNone(extract_volume_response, "Extract/Download volume failed") + + self.assertEquals( + "DOWNLOAD_URL_CREATED", + extract_volume_response.state, + "Failed to create Download URL" + ) + self.assertIsNotNone( + extract_volume_response.url, + "Extract/Download volume URL is NULL" + ) + self.assertTrue( + (extract_volume_response.url.find("http")!=-1), + "Extract/Download volume URL doesnot contain http" + ) + self.assertEquals( + volume_created.id, + extract_volume_response.id, + "Extracted/Downloaded volume is not matching with original volume" + ) + return + + @attr(tags=["advanced", "basic", "provisioning"]) + def test_12_volume_upload(self): + """ + @summary: Test to verify upload volume + + Step1: Listing the volumes for a user before uploading volume + Step2: Uploading a volume + Step3: Listing the volumes for a user after uploading data volume + Step4: Verifying that the list volume length after upload is increased by 1 + """ + list_volumes_before = Volume.list(self.userapiclient, listall=self.services["listall"]) + + self.assertIsNotNone( + list_volumes_before, + "volume not created for the vm launched at class level" + ) + #Uploading a Volume + volume_uploaded = Volume.upload( + self.userapiclient, + self.services["upload_volume"], + self.zone.id + ) + self.assertIsNotNone(volume_uploaded, "volume uploading failed") + + self.assertEquals( + self.services["upload_volume"]["diskname"], + volume_uploaded.name, + "Uploaded volume name is not matching with name provided while uploading") + + #Listing the volumes for a user after uploading data volume + list_volumes_after = Volume.list(self.userapiclient, listall=self.services["listall"]) + + self.assertIsNotNone( + list_volumes_after, + "volume not created for the vm launched at class level" + ) + #Asserting that the list volume length after upload is increased by 1 + self.assertEquals( + len(list_volumes_before) + 1, + len(list_volumes_after), + "upload volume failed" + ) + return \ No newline at end of file diff --git a/test/integration/component/test_escalations_vpncustomergateways.py b/test/integration/component/test_escalations_vpncustomergateways.py new file mode 100644 index 0000000000..dc6576863d --- /dev/null +++ b/test/integration/component/test_escalations_vpncustomergateways.py @@ -0,0 +1,382 @@ +# 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 Local Modules +from marvin.cloudstackTestCase import cloudstackTestCase +from marvin.cloudstackAPI import (createVolume, + createTemplate) +from marvin.lib.base import (Volume, + Iso, + VirtualMachine, + Template, + Snapshot, + SecurityGroup, + Account, + Zone, + Network, + NetworkOffering, + DiskOffering, + ServiceOffering, + VmSnapshot, + SnapshotPolicy, + SSHKeyPair, + Resources, + Configurations, + VpnCustomerGateway, + Hypervisor, + VpcOffering, + VPC, + NetworkACL) +from marvin.lib.common import (get_zone, + get_domain, + get_template, + list_os_types) +from marvin.lib.utils import (validateList, + cleanup_resources, + random_gen) +from marvin.codes import (PASS, FAIL, EMPTY_LIST) +from nose.plugins.attrib import attr +import time + +class TestVpnCustomerGateways(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + try: + cls._cleanup = [] + cls.testClient = super(TestVpnCustomerGateways, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = cls.testClient.getParsedTestDataConfig() + # Get Domain, Zone, Template + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) + cls.template = get_template( + cls.api_client, + cls.zone.id, + cls.services["ostype"] + ) + cls.services['mode'] = cls.zone.networktype + cls.account = Account.create( + cls.api_client, + cls.services["account"], + domainid=cls.domain.id + ) + # Getting authentication for user in newly created Account + cls.user = cls.account.user[0] + cls.userapiclient = cls.testClient.getUserApiClient(cls.user.username, cls.domain.name) + cls._cleanup.append(cls.account) + except Exception as e: + cls.tearDownClass() + raise Exception("Warning: Exception in setup : %s" % e) + return + + def setUp(self): + + self.apiClient = self.testClient.getApiClient() + self.cleanup = [] + + def tearDown(self): + #Clean up, terminate the created resources + cleanup_resources(self.apiClient, self.cleanup) + return + + @classmethod + def tearDownClass(cls): + try: + cleanup_resources(cls.api_client, cls._cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + + return + + def __verify_values(self, expected_vals, actual_vals): + """ + @Desc: Function to verify expected and actual values + @Steps: + Step1: Initializing return flag to True + Step1: Verifying length of expected and actual dictionaries is matching. + If not matching returning false + Step2: Listing all the keys from expected dictionary + Step3: Looping through each key from step2 and verifying expected and actual dictionaries have same value + If not making return flag to False + Step4: returning the return flag after all the values are verified + """ + return_flag = True + + if len(expected_vals) != len(actual_vals): + return False + + keys = expected_vals.keys() + for i in range(0, len(expected_vals)): + exp_val = expected_vals[keys[i]] + act_val = actual_vals[keys[i]] + if exp_val == act_val: + return_flag = return_flag and True + else: + return_flag = return_flag and False + self.debug("expected Value: %s, is not matching with actual value: %s" % ( + exp_val, + act_val + )) + return return_flag + + @attr(tags=["advanced", "basic", "provisioning"]) + def test_01_list_vpncustomergateways_pagination(self): + """ + @Desc: Test to List VPN Customer Gateways pagination + @steps: + Step1: Listing all the VPN Customer Gateways for a user + Step2: Verifying that no VPN Customer Gateways are listed + Step3: Creating (page size + 1) number of VPN Customer Gateways + Step4: Listing all the VPN Customer Gateways again for a user + Step5: Verifying that list size is (page size + 1) + Step6: Listing all the VPN Customer Gateways in page1 + Step7: Verifying that list size is (page size) + Step8: Listing all the VPN Customer Gateways in page2 + Step9: Verifying that list size is 1 + Step10: Deleting the VPN Customer Gateways present in page 2 + Step11: Listing all the VPN Customer Gateways in page2 + Step12: Verifying that no VPN Customer Gateways are listed + """ + # Listing all the VPN Customer Gateways for a User + list_vpncustomergateways_before = VpnCustomerGateway.list( + self.userapiclient, + listall=self.services["listall"] + ) + # Verifying that no VPN Customer Gateways are listed + self.assertIsNone( + list_vpncustomergateways_before, + "VPN Customer Gateways listed for newly created User" + ) + # Creating pagesize + 1 number of VPN Customer Gateways + for i in range(0, (self.services["pagesize"] + 1)): + vpncustomergateway_created = VpnCustomerGateway.create( + self.userapiclient, + self.services["vpncustomergateway"], + name="VPNCustGateway"+str(i+1), + gateway="10.102.153." + str(i+1), + cidrlist="10.0.0.0/24", + account=self.account.name, + domainid=self.domain.id + ) + self.assertIsNotNone( + vpncustomergateway_created, + "VPN Customer Gateway creation failed" + ) + if (i < self.services["pagesize"] + 1): + self.cleanup.append(vpncustomergateway_created) + + # Listing all the VPN Customer Gateways for a User + list_vpncustomergateways_after = VpnCustomerGateway.list( + self.userapiclient, + listall=self.services["listall"] + ) + status = validateList(list_vpncustomergateways_after) + self.assertEquals( + PASS, + status[0], + "VPN Customer Gateway creation failed" + ) + # Verifying that list size is pagesize + 1 + self.assertEquals( + self.services["pagesize"] + 1, + len(list_vpncustomergateways_after), + "Failed to create pagesize + 1 number of VPN Customer Gateways" + ) + # Listing all the VPN Customer Gateways in page 1 + list_vpncustomergateways_page1 = VpnCustomerGateway.list( + self.userapiclient, + listall=self.services["listall"], + page=1, + pagesize=self.services["pagesize"] + ) + status = validateList(list_vpncustomergateways_page1) + self.assertEquals( + PASS, + status[0], + "Failed to list VPN Customer Gateways in page 1" + ) + # Verifying the list size to be equal to pagesize + self.assertEquals( + self.services["pagesize"], + len(list_vpncustomergateways_page1), + "Size of VPN Customer Gateways in page 1 is not matching" + ) + # Listing all the VPN Customer Gateways in page 2 + list_vpncustomergateways_page2 = VpnCustomerGateway.list( + self.userapiclient, + listall=self.services["listall"], + page=2, + pagesize=self.services["pagesize"] + ) + status = validateList(list_vpncustomergateways_page2) + self.assertEquals( + PASS, + status[0], + "Failed to list VPN Customer Gateways in page 2" + ) + # Verifying the list size to be equal to 1 + self.assertEquals( + 1, + len(list_vpncustomergateways_page2), + "Size of VPN Customer Gateways in page 2 is not matching" + ) + # Deleting the VPM Customer Gateway present in page 2 + VpnCustomerGateway.delete( + vpncustomergateway_created, + self.userapiclient + ) + # Listing all the VPN Customer Gateways in page 2 again + list_vpncustomergateways_page2 = VpnCustomerGateway.list( + self.userapiclient, + listall=self.services["listall"], + page=2, + pagesize=self.services["pagesize"] + ) + # Verifying that there are no VPN Customer Gateways listed + self.assertIsNone( + list_vpncustomergateways_page2, + "VPN Customer Gateways not deleted from page 2" + ) + return + + @attr(tags=["advanced", "basic", "provisioning"]) + def test_02_update_vpncustomergateways(self): + """ + @Desc: Test to update VPN Customer Gateways pagination + @steps: + Step1: Listing all the VPN Customer Gateways for a user + Step2: Verifying that no VPN Customer Gateways are listed + Step3: Creating a VPN Customer Gateways + Step4: Listing all the VPN Customer Gateways again for a user + Step5: Verifying that list size is 1 + Step6: Updating the VPN Customer Gateways created in step3 + Step7: Listing the VPN customer gateway by id + Step8: Verifying that list size is 1 + Step9: Verifying the details of the listed VPN customer gateway are same as updated in step6 + """ + # Listing all the VPN Customer Gateways for a User + list_vpncustomergateways_before = VpnCustomerGateway.list( + self.userapiclient, + listall=self.services["listall"] + ) + # Verifying that no VPN Customer Gateways are listed + self.assertIsNone( + list_vpncustomergateways_before, + "VPN Customer Gateways listed for newly created User" + ) + # Creating A VPN Customer Gateways + vpncustomergateway_created = VpnCustomerGateway.create( + self.userapiclient, + self.services["vpncustomergateway"], + name="VPNCustGateway", + gateway="10.102.153.90", + cidrlist="10.0.0.0/24", + account=self.account.name, + domainid=self.domain.id + ) + self.assertIsNotNone( + vpncustomergateway_created, + "VPN Customer Gateway creation failed" + ) + self.cleanup.append(vpncustomergateway_created) + # Listing all the VPN Customer Gateways for a User + list_vpncustomergateways_after = VpnCustomerGateway.list( + self.userapiclient, + listall=self.services["listall"] + ) + status = validateList(list_vpncustomergateways_after) + self.assertEquals( + PASS, + status[0], + "VPN Customer Gateway creation failed" + ) + # Verifying that list size is 1 + self.assertEquals( + 1, + len(list_vpncustomergateways_after), + "Failed to create VPN Customer Gateways" + ) + # Updating the VPN Customer gateway + vpncustomergateway_updated = VpnCustomerGateway.update( + vpncustomergateway_created, + self.userapiclient, + self.services["vpncustomergateway"], + name="NewVPNCustGateway", + gateway="10.102.153.90", + cidrlist="10.0.0.0/24", + ) + self.assertIsNotNone( + vpncustomergateway_updated, + "Updation of VPN Customer Gateway failed" + ) + # Listing the VPN Customer Gateways by Id + list_vpncustomergateway = VpnCustomerGateway.list( + self.userapiclient, + listall=self.services["listall"], + id=vpncustomergateway_created.id + ) + status = validateList(list_vpncustomergateway) + self.assertEquals( + PASS, + status[0], + "Failed to list VPN Customer Gateways by Id" + ) + # Verifying the list size to be equal to 1 + self.assertEquals( + 1, + len(list_vpncustomergateway), + "Size of VPN Customer Gateways by id is not matching" + ) + # Verifying the details of the listed VPN Customer Gateway are same as updated + #Creating expected and actual values dictionaries + expected_dict = { + "name":vpncustomergateway_updated.name, + "id":vpncustomergateway_updated.id, + "account":vpncustomergateway_updated.account, + "domainid":vpncustomergateway_updated.domainid, + "gateway":vpncustomergateway_updated.gateway, + "cidrlist":vpncustomergateway_updated.cidrlist, + "seckey":vpncustomergateway_updated.ipsecpsk, + "ikepolicy":vpncustomergateway_updated.ikepolicy, + "ikelifetime":vpncustomergateway_updated.ikelifetime, + "esppolicy":vpncustomergateway_updated.esppolicy, + "esplifetime":vpncustomergateway_updated.esplifetime, + } + actual_dict = { + "name":list_vpncustomergateway[0].name, + "id":list_vpncustomergateway[0].id, + "account":list_vpncustomergateway[0].account, + "domainid":list_vpncustomergateway[0].domainid, + "gateway":list_vpncustomergateway[0].gateway, + "cidrlist":list_vpncustomergateway[0].cidrlist, + "seckey":list_vpncustomergateway[0].ipsecpsk, + "ikepolicy":list_vpncustomergateway[0].ikepolicy, + "ikelifetime":list_vpncustomergateway[0].ikelifetime, + "esppolicy":list_vpncustomergateway[0].esppolicy, + "esplifetime":list_vpncustomergateway[0].esplifetime, + } + vpncustomergateway_status = self.__verify_values( + expected_dict, + actual_dict + ) + self.assertEqual( + True, + vpncustomergateway_status, + "Listed VPN Customer Gateway details are not as Updated" + ) + return \ No newline at end of file diff --git a/test/integration/component/test_explicit_dedication.py b/test/integration/component/test_explicit_dedication.py index 7aefc21a1f..4ce5c15fa9 100644 --- a/test/integration/component/test_explicit_dedication.py +++ b/test/integration/component/test_explicit_dedication.py @@ -21,9 +21,9 @@ from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * from marvin.sshClient import SshClient -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * +from marvin.lib.utils import * +from marvin.lib.base import * +from marvin.lib.common import * from nose.plugins.attrib import attr #Import System modules import time @@ -96,12 +96,13 @@ class TestExplicitDedication(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestExplicitDedication, cls).getClsTestClient().getApiClient() - cls.services = Services().services + cls.testClient = super(TestExplicitDedication, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + 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( @@ -152,7 +153,7 @@ def tearDown(self): # This test requires multi host and at least one host which is empty (no vms should # be running on that host). It explicitly dedicates empty host to an account, deploys # a vm for that account and verifies that the vm gets deployed to the dedicated host. - @attr(tags = ["advanced", "basic", "multihosts", "explicitdedication"]) + @attr(tags=["advanced", "basic", "multihosts", "explicitdedication", "selfservice"]) def test_01_deploy_vm_with_explicit_dedication(self): """Test explicit dedication is placing vms of an account on dedicated hosts. """ diff --git a/test/integration/component/test_haproxy.py b/test/integration/component/test_haproxy.py index f77e4ec61c..e3b45b5ab3 100644 --- a/test/integration/component/test_haproxy.py +++ b/test/integration/component/test_haproxy.py @@ -19,7 +19,7 @@ # Import Local Modules from nose.plugins.attrib import attr from marvin.cloudstackTestCase import cloudstackTestCase -from marvin.integration.lib.base import ( +from marvin.lib.base import ( Account, ServiceOffering, VirtualMachine, @@ -31,11 +31,11 @@ Vpn, NATRule ) -from marvin.integration.lib.common import (get_domain, +from marvin.lib.common import (get_domain, get_zone, get_template ) -from marvin.integration.lib.utils import (cleanup_resources, +from marvin.lib.utils import (cleanup_resources, random_gen) from marvin.cloudstackAPI import createLBStickinessPolicy from marvin.sshClient import SshClient @@ -118,12 +118,13 @@ class TestHAProxyStickyness(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestHAProxyStickyness, - cls).getClsTestClient().getApiClient() + cls.testClient = super(TestHAProxyStickyness, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, @@ -694,7 +695,7 @@ def test_06_release_ip(self): listall=True) return - @attr(tags=["advanced", "advancedns"]) + @attr(tags=["advanced", "advancedns", "provisioning"]) def test_07_delete_account(self): """Test Delete account and check the router and its rules""" @@ -735,7 +736,7 @@ def test_07_delete_account(self): listall=True) return - @attr(tags=["advanced", "advancedns"]) + @attr(tags=["advanced", "advancedns", "provisioning"]) def test_08_create_policy_router_stopped(self): """Test verify create stickiness policy when router is stopped state""" @@ -768,7 +769,7 @@ def test_08_create_policy_router_stopped(self): self.validate_Stickiness_Policy(lb_rule, "LbCookie", self.public_ip.ipaddress.ipaddress) return - @attr(tags=["advanced", "advancedns"]) + @attr(tags=["advanced", "advancedns", "provisioning"]) def test_09_create_policy_router_destroy(self): """Test check the stickiness policy rules after destroying router""" @@ -799,7 +800,7 @@ def test_09_create_policy_router_destroy(self): return - @attr(tags=["advanced", "advancedns"]) + @attr(tags=["advanced", "advancedns", "provisioning"]) def test_10_create_policy_enable_disable_vpn(self): """Test enable/disable the VPN after applying sticky policy rules""" @@ -830,7 +831,7 @@ def test_10_create_policy_enable_disable_vpn(self): self.validate_Stickiness_Policy(lb_rule, "LbCookie", self.public_ip.ipaddress.ipaddress) return - @attr(tags=["advanced", "advancedns"]) + @attr(tags=["advanced", "advancedns", "selfservice"]) def test_11_invalid_params(self): """Test verfify functionality syncronous and asyncronous validations""" diff --git a/test/integration/component/test_implicit_planner.py b/test/integration/component/test_implicit_planner.py index 2b656d9f2c..9cbd73c6f8 100644 --- a/test/integration/component/test_implicit_planner.py +++ b/test/integration/component/test_implicit_planner.py @@ -21,9 +21,9 @@ from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * from marvin.sshClient import SshClient -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * +from marvin.lib.utils import * +from marvin.lib.base import * +from marvin.lib.common import * from nose.plugins.attrib import attr #Import System modules import time @@ -91,12 +91,13 @@ class TestImplicitPlanner(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestImplicitPlanner, cls).getClsTestClient().getApiClient() - cls.services = Services().services + cls.testClient = super(TestImplicitPlanner, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype template = get_template( @@ -144,7 +145,7 @@ def tearDown(self): # be running on that host). It uses an implicit planner to deploy instances and the # instances of a new account should go to an host that doesn't have vms of any other # account. - @attr(tags = ["advanced", "basic", "multihosts", "implicitplanner"]) + @attr(tags=["advanced", "basic", "multihosts", "implicitplanner", "selfservice"]) def test_01_deploy_vm_with_implicit_planner(self): """Test implicit planner is placing vms of an account on implicitly dedicated hosts. """ diff --git a/test/integration/component/test_ip_reservation.py b/test/integration/component/test_ip_reservation.py old mode 100755 new mode 100644 index 224212f21d..8b91f37060 --- a/test/integration/component/test_ip_reservation.py +++ b/test/integration/component/test_ip_reservation.py @@ -15,134 +15,567 @@ # specific language governing permissions and limitations # under the License. """ Tests for IP reservation feature + + Test Plan: https://cwiki.apache.org/confluence/display/CLOUDSTACK/IP+Range+Reservation+within+a+Network+Test+Cases + + Issue Link: https://issues.apache.org/jira/browse/CLOUDSTACK-2266 + + Feature Specifications: https://cwiki.apache.org/confluence/display/CLOUDSTACK/FS+-+IP+Range+Reservation+within+a+Network """ -import marvin -from marvin.cloudstackTestCase import * -from marvin.cloudstackAPI import * -from marvin.cloudstackException import cloudstackAPIException -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * +from marvin.cloudstackTestCase import cloudstackTestCase, unittest +from marvin.lib.utils import validateList, cleanup_resources, verifyRouterState +from marvin.lib.base import (Account, + Network, + VirtualMachine, + Router, + ServiceOffering, + NetworkOffering) +from marvin.lib.common import (get_zone, + get_template, + get_domain, + wait_for_cleanup, + createEnabledNetworkOffering, + createNetworkRulesForVM, + verifyNetworkState) +from marvin.codes import (PASS, FAIL, FAILED, UNKNOWN, FAULT, MASTER, + NAT_RULE, STATIC_NAT_RULE) import netaddr +import random from nose.plugins.attrib import attr +from ddt import ddt, data -class Services(object): - """Test IP Reservation - """ - def __init__(self): - self.services = { - "account": { - "email": "test@test.com", - "firstname": "Test", - "lastname": "User", - "username": "test", - # Random characters are appended for unique - # username - "password": "password", - }, - "service_offering": { - "name": "Tiny Instance ", - "displaytext": "Tiny Instance", - "cpunumber": 1, - "cpuspeed": 200, # in MHz - "memory": 256, # In MBs - }, - "isolated_network_offering": { - "name": 'Network offering for Isolated Network', - "displaytext": 'Network offering-DA services', - "guestiptype": 'Isolated', - "supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding,Vpn,Firewall,Lb,UserData,StaticNat', - "traffictype": 'GUEST', - "availability": 'Optional', - "serviceProviderList": { - "Dhcp": 'VirtualRouter', - "Dns": 'VirtualRouter', - "SourceNat": 'VirtualRouter', - "PortForwarding": 'VirtualRouter', - "Vpn": 'VirtualRouter', - "Firewall": 'VirtualRouter', - "Lb": 'VirtualRouter', - "UserData": 'VirtualRouter', - "StaticNat": 'VirtualRouter', - }, - }, - "isolated_persistent_network_offering": { - "name": 'Network offering for Isolated Network', - "displaytext": 'Network offering-DA services', - "guestiptype": 'Isolated', - "supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding,Vpn,Firewall,Lb,UserData,StaticNat', - "traffictype": 'GUEST', - "availability": 'Optional', - "ispersistent": 'True', - "serviceProviderList": { - "Dhcp": 'VirtualRouter', - "Dns": 'VirtualRouter', - "SourceNat": 'VirtualRouter', - "PortForwarding": 'VirtualRouter', - "Vpn": 'VirtualRouter', - "Firewall": 'VirtualRouter', - "Lb": 'VirtualRouter', - "UserData": 'VirtualRouter', - "StaticNat": 'VirtualRouter', - }, - }, - "isolated_network": { - "name": "Isolated Network", - "displaytext": "Isolated Network", - "netmask": "255.255.255.0", - "gateway": "10.1.1.1" - }, - # update CIDR according to netmask and gateway in isolated_network - "isolated_network_cidr": "10.1.1.0/24", - "virtual_machine": { - "displayname": "Test VM", - }, - "ostype": 'CentOS 5.3 (64-bit)', - # Cent OS 5.3 (64 bit) - "sleep": 90, - "timeout": 10, - "mode": 'advanced' - } +def createIsolatedNetwork(self, network_offering_id, gateway=None): + """Create isolated network with given network offering and gateway if provided + and return""" + try: + isolated_network = Network.create(self.apiclient, self.testData["isolated_network"], + networkofferingid=network_offering_id,accountid=self.account.name, + domainid=self.domain.id,zoneid=self.zone.id, + gateway=gateway, netmask='255.255.255.0' if gateway else None) + except Exception as e: + return [FAIL, e] + return [PASS, isolated_network] + +def matchNetworkGuestVmCIDR(self, networkid, guestvmcidr): + """List networks with given network id and check if the guestvmcidr matches + with the given cidr""" + + networks = Network.list(self.apiclient, id=networkid, listall=True) + self.assertEqual(validateList(networks)[0], PASS, "network list validation failed") + self.assertEqual(str(networks[0].cidr), guestvmcidr, "guestvmcidr of network %s \ + does not match with the given value %s" % (networks[0].cidr, guestvmcidr)) + + return +def createVirtualMachine(self, network_id=None, ip_address=None): + """Create and return virtual machine within network and ipaddress""" + virtual_machine = VirtualMachine.create(self.apiclient, + self.testData["virtual_machine"], + networkids=network_id, + serviceofferingid=self.service_offering.id, + accountid=self.account.name, + domainid=self.domain.id, + ipaddress=ip_address) + return virtual_machine +def CreateEnabledNetworkOffering(apiclient, networkServices): + """Create network offering of given test data and enable it""" + + result = createEnabledNetworkOffering(apiclient, networkServices) + assert result[0] == PASS, "Network offering creation/enabling failed due to %s" % result[2] + return result[1] + +@ddt class TestIpReservation(cloudstackTestCase): """Test IP Range Reservation with a Network """ @classmethod def setUpClass(cls): - cls.api_client = super(TestIpReservation, cls).getClsTestClient().getApiClient() - cls.services = Services().services + cls.testClient = super(TestIpReservation, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + + # Fill services from the external config file + cls.testData = cls.testClient.getParsedTestDataConfig() + # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, - cls.services["ostype"] + cls.testData["ostype"] ) - cls.services["domainid"] = cls.domain.id - cls.services["zoneid"] = cls.zone.id - cls.account = Account.create( + if cls.template == FAILED: + assert False, "get_template() failed to return template with description %s" % cls.testData["ostype"] + cls.testData["domainid"] = cls.domain.id + cls.testData["zoneid"] = cls.zone.id + cls.testData["virtual_machine"]["zoneid"] = cls.zone.id + cls.testData["virtual_machine"]["template"] = cls.template.id + cls._cleanup = [] + try: + cls.service_offering = ServiceOffering.create( + cls.api_client, + cls.testData["service_offering"] + ) + cls._cleanup.append(cls.service_offering) + cls.isolated_network_offering = CreateEnabledNetworkOffering(cls.api_client, + cls.testData["isolated_network_offering"]) + cls._cleanup.append(cls.isolated_network_offering) + cls.isolated_persistent_network_offering = CreateEnabledNetworkOffering(cls.api_client, + cls.testData["nw_off_isolated_persistent"]) + cls._cleanup.append(cls.isolated_persistent_network_offering) + cls.isolated_network_offering_RVR = CreateEnabledNetworkOffering(cls.api_client, + cls.testData["nw_off_isolated_RVR"]) + cls._cleanup.append(cls.isolated_network_offering_RVR) + except Exception as e: + cls.tearDownClass() + raise unittest.SkipTest("Failure in setUpClass: %s" % e) + 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) + return + + def setUp(self): + self.apiclient = self.testClient.getApiClient() + self.dbclient = self.testClient.getDbConnection() + self.cleanup = [] + try: + self.account = Account.create(self.apiclient, self.testData["account"], + domainid=self.domain.id) + self.cleanup.append(self.account) + except Exception as e: + self.skipTest("Failed to create account: %s" % e) + return + + def tearDown(self): + try: + # Clean up, terminate the resources created + cleanup_resources(self.apiclient, self.cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + @attr(tags=["advanced"]) + def test_vm_create_after_reservation(self): + """ Test creating VM in network after IP reservation + # steps + # 1. Create vm in isolated network (LB through VR or Netscaler) with ip in guestvmcidr + # 2. Update guestvmcidr + # 3. Create another VM + # validation + # 1. Guest vm cidr should be successfully updated with correct value + # 2. Existing guest vm ip should not be changed after reservation + # 3. Newly created VM should get ip in guestvmcidr""" + + networkOffering = self.isolated_network_offering + subnet = "10.1."+str(random.randrange(1,254)) + gateway = subnet +".1" + resultSet = createIsolatedNetwork(self, networkOffering.id, gateway=gateway) + if resultSet[0] == FAIL: + self.fail("Failed to create isolated network") + else: + isolated_network = resultSet[1] + guest_vm_cidr = subnet +".0/29" + + try: + virtual_machine_1 = createVirtualMachine(self, network_id=isolated_network.id, + ip_address = subnet+".3") + except Exception as e: + self.fail("VM creation failed: %s" % e) + + isolated_network.update(self.apiclient, guestvmcidr=guest_vm_cidr) + matchNetworkGuestVmCIDR(self, isolated_network.id, guest_vm_cidr) + vms = VirtualMachine.list(self.apiclient, + id=virtual_machine_1.id) + self.assertEqual(validateList(vms)[0], PASS, "vm list validation failed") + self.assertEqual(vms[0].nic[0].ipaddress, + virtual_machine_1.ipaddress, + "VM IP should not change after reservation") + try: + virtual_machine_2 = createVirtualMachine(self, network_id=isolated_network.id) + if netaddr.IPAddress(virtual_machine_2.ipaddress) not in netaddr.IPNetwork(guest_vm_cidr): + self.fail("Newly created VM doesn't get IP from reserverd CIDR") + except Exception as e: + self.fail("VM creation failed, cannot validate the condition: %s" % e) + return + + @attr(tags=["advanced"]) + def test_vm_create_outside_cidr_after_reservation(self): + """ Test create VM outside the range of reserved IPs + # steps + # 1. update guestvmcidr of persistent isolated network (LB through VR or + # Netscaler + # 2. create another VM with ip outside guestvmcidr + """ + # validation + # 1. guest vm cidr should be successfully updated with correct value + # 2 newly created VM should not be created and result in exception + + networkOffering = self.isolated_persistent_network_offering + subnet = "10.1."+str(random.randrange(1,254)) + gateway = subnet +".1" + resultSet = createIsolatedNetwork(self, networkOffering.id, gateway=gateway) + if resultSet[0] == FAIL: + self.fail("Failed to create isolated network") + else: + isolated_network = resultSet[1] + guest_vm_cidr = subnet+".0/29" + + isolated_network.update(self.apiclient, guestvmcidr=guest_vm_cidr) + matchNetworkGuestVmCIDR(self, isolated_network.id, guest_vm_cidr) + try: + createVirtualMachine(self, network_id=self.isolated_network.id, + ip_address=subnet+".9") + self.fail("vm should not be created ") + except Exception as e: + self.debug("exception as IP is outside of guestvmcidr %s" % e) + return + + @attr(tags=["advanced"]) + def test_update_cidr_multiple_vms_not_all_inclusive(self): + """ Test reserve IP range such that one of the VM is not included + # steps + # 1. Create two vms in isolated network + # 2. Update guestvmcidr of network such that only one of the ipaddress of vms + # is in the given range + # validation + # 1. Network updation with this new range should fail""" + + subnet = "10.1."+str(random.randrange(1,254)) + gateway = subnet +".1" + resultSet = createIsolatedNetwork(self, self.isolated_network_offering.id, + gateway=gateway) + if resultSet[0] == FAIL: + self.fail("Failed to create isolated network") + else: + isolated_network = resultSet[1] + guest_vm_cidr = subnet+".0/29" + + try: + createVirtualMachine(self, network_id=isolated_network.id, + ip_address=subnet+".3") + except Exception as e: + self.fail("VM creation failed: %s" % e) + + try: + createVirtualMachine(self, network_id=isolated_network.id, + ip_address=subnet+".9") + except Exception as e: + self.fail("VM creation failed: %s" % e) + + with self.assertRaises(Exception): + isolated_network.update(self.apiclient, guestvmcidr=guest_vm_cidr) + return + + @attr(tags=["advanced"]) + def test_update_cidr_single_vm_not_inclusive(self): + """ Test reserving IP range in network such that existing VM is outside the range + # steps + # 1. Create vm in isolated network + # 2. Update guestvmcidr of network such that ip address of vm + # is outside the given range + # + # validation + # 1. Network updation with this new range should fail""" + subnet = "10.1."+str(random.randrange(1,254)) + gateway = subnet +".1" + resultSet = createIsolatedNetwork(self, self.isolated_network_offering.id, + gateway=gateway) + if resultSet[0] == FAIL: + self.fail("Failed to create isolated network") + else: + isolated_network = resultSet[1] + guest_vm_cidr = subnet+".0/29" + + try: + createVirtualMachine(self, network_id=isolated_network.id, + ip_address=subnet+".9") + except Exception as e: + self.fail("VM creation failed: %s" % e) + + with self.assertRaises(Exception): + isolated_network.update(self.apiclient, guestvmcidr=guest_vm_cidr) + return + + @data(NAT_RULE, STATIC_NAT_RULE) + @attr(tags=["advanced"]) + def test_nat_rules(self, value): + """ Test NAT rules working with IP reservation + # steps + # 1. Create vm in persistent isolated network with ip in guestvmcidr + # 2. Create NAT/static NAT rule for this VM + # 3. Update guestvmcidr + # 4. Create another VM and create network rules for this vm too + # + # validation + # 1. Guest vm cidr should be successfully updated with correct value + # 2. Existing guest vm ip should not be changed after reservation + # 3. Newly created VM should get ip in guestvmcidr + # 4. The network rules should be working""" + + subnet = "10.1."+str(random.randrange(1,254)) + gateway = subnet +".1" + resultSet = createIsolatedNetwork(self, self.isolated_network_offering.id, + gateway=gateway) + if resultSet[0] == FAIL: + self.fail("Failed to create isolated network") + else: + isolated_network = resultSet[1] + guest_vm_cidr = subnet+".0/29" + + try: + virtual_machine_1 = createVirtualMachine(self, network_id=isolated_network.id, + ip_address=subnet+".3") + except Exception as e: + self.fail("VM creation failed: %s" % e) + + result = createNetworkRulesForVM(self.apiclient, virtual_machine_1,value, + self.account, self.testData) + if result[0] == FAIL: + self.fail("Failed to create network rules for VM: %s" % result[1]) + else: + ipaddress_1 = result[1] + virtual_machine_1.get_ssh_client(ipaddress=ipaddress_1.ipaddress.ipaddress) + + isolated_network.update(self.apiclient, guestvmcidr=guest_vm_cidr) + matchNetworkGuestVmCIDR(self, isolated_network.id, guest_vm_cidr) + vms = VirtualMachine.list(self.apiclient, id=virtual_machine_1.id) + self.assertEqual(validateList(vms)[0], PASS, "vm list validation failed") + self.assertEqual(vms[0].nic[0].ipaddress, + virtual_machine_1.ipaddress, + "VM IP should not change after reservation") + try: + virtual_machine_2 = createVirtualMachine(self, network_id=isolated_network.id) + if netaddr.IPAddress(virtual_machine_2.ipaddress) not in netaddr.IPNetwork(guest_vm_cidr): + self.fail("Newly created VM doesn't get IP from reserverd CIDR") + except Exception as e: + self.fail("VM creation failed, cannot validate the condition: %s" % e) + + result = createNetworkRulesForVM(self.apiclient, virtual_machine_2, value, + self.account, self.testData) + if result[0] == FAIL: + self.fail("Failed to create network rules for VM: %s" % result[1]) + else: + ipaddress_2 = result[1] + virtual_machine_2.get_ssh_client(ipaddress=ipaddress_2.ipaddress.ipaddress) + return + + @unittest.skip("Skip - WIP") + @attr(tags=["advanced"]) + def test_RVR_network(self): + """ Test IP reservation in network with RVR + # steps + # 1. create vm in isolated network with RVR and ip in guestvmcidr + # 2. update guestvmcidr + # 3. List routers and stop the master router, wait till backup router comes up + # 4. create another VM + # + # validation + # 1. Guest vm cidr should be successfully updated with correct value + # 2. Existing guest vm ip should not be changed after reservation + # 3. Newly created VM should get ip in guestvmcidr + # 4. Verify that the network has two routers associated with it + # 5. Backup router should come up when master router is stopped""" + + subnet = "10.1."+str(random.randrange(1,254)) + gateway = subnet +".1" + resultSet = createIsolatedNetwork(self, self.isolated_network_offering_RVR.id, + gateway=gateway) + if resultSet[0] == FAIL: + self.fail("Failed to create isolated network") + else: + isolated_network_RVR= resultSet[1] + guest_vm_cidr = subnet+".0/29" + + try: + virtual_machine_1 = createVirtualMachine(self, network_id=isolated_network_RVR.id, + ip_address=subnet+".3") + except Exception as e: + self.fail("VM creation failed: %s" % e) + + isolated_network_RVR.update(self.apiclient, guestvmcidr=guest_vm_cidr) + matchNetworkGuestVmCIDR(self, isolated_network_RVR.id, guest_vm_cidr) + vms = VirtualMachine.list(self.apiclient, + id=virtual_machine_1.id) + self.assertEqual(validateList(vms)[0], PASS, "vm list validation failed") + self.assertEqual(vms[0].nic[0].ipaddress, + virtual_machine_1.ipaddress, + "VM IP should not change after reservation") + + self.debug("Listing routers for network: %s" % isolated_network_RVR.name) + routers = Router.list(self.apiclient, networkid=isolated_network_RVR.id, listall=True) + self.assertEqual(validateList(routers)[0], PASS, "Routers list validation failed") + self.assertEqual(len(routers), 2, "Length of the list router should be 2 (Backup & master)") + + if routers[0].redundantstate == MASTER: + master_router = routers[0] + backup_router = routers[1] + else: + master_router = routers[1] + backup_router = routers[0] + + self.debug("Stopping router ID: %s" % master_router.id) + + try: + Router.stop(self.apiclient, id=master_router.id) + except Exception as e: + self.fail("Failed to stop master router due to error %s" % e) + + # wait for VR to update state + wait_for_cleanup(self.apiclient, ["router.check.interval"]) + + result = verifyRouterState(master_router.id, [UNKNOWN,FAULT]) + if result[0] == FAIL: + self.fail(result[1]) + result = verifyRouterState(backup_router.id, [MASTER]) + if result[0] == FAIL: + self.fail(result[1]) + + try: + virtual_machine_2 = createVirtualMachine(self, network_id=isolated_network_RVR.id) + if netaddr.IPAddress(virtual_machine_2.ipaddress) not in netaddr.IPNetwork(guest_vm_cidr): + self.fail("Newly created VM doesn't get IP from reserverd CIDR") + except Exception as e: + self.fail("VM creation failed, cannot validate the condition: %s" % e) + return + + @attr(tags=["advanced"]) + def test_ip_reservation_in_multiple_networks_same_account(self): + """ Test IP reservation in multiple networks created in same account + # steps + # 1. Create two isolated networks with user defined cidr in same account + # Test below conditions for both the networks in the account + # 2. Create vm in persistent isolated network with ip in guestvmcidr + # 3. Update guestvmcidr + # 4. Create another VM + # + # validation + # 1. Guest vm cidr should be successfully updated with correct value + # 2. Existing guest vm ip should not be changed after reservation + # 3. Newly created VM should get ip in guestvmcidr""" + + account_1 = Account.create(self.apiclient, self.testData["account"], + domainid=self.domain.id) + self.cleanup.append(account_1) + + random_subnet = str(random.randrange(1,254)) + gateway = "10.1." + random_subnet +".1" + isolated_network_1 = Network.create(self.apiclient, self.testData["isolated_network"], + networkofferingid=self.isolated_network_offering.id,accountid=account_1.name, + domainid=self.domain.id,zoneid=self.zone.id, + gateway=gateway, netmask='255.255.255.0') + guest_vm_cidr = "10.1."+random_subnet+".0/29" + + try: + virtual_machine_1 = VirtualMachine.create(self.apiclient, self.testData["virtual_machine"], + networkids=isolated_network_1.id, serviceofferingid=self.service_offering.id, + accountid=account_1.name, domainid=self.domain.id, + ipaddress="10.1."+random_subnet+".3") + except Exception as e: + self.fail("VM creation failed: %s" % e) + + isolated_network_1.update(self.apiclient, guestvmcidr=guest_vm_cidr) + matchNetworkGuestVmCIDR(self, isolated_network_1.id, guest_vm_cidr) + vms = VirtualMachine.list(self.apiclient, + id=virtual_machine_1.id) + self.assertEqual(validateList(vms)[0], PASS, "vm list validation failed") + self.assertEqual(vms[0].nic[0].ipaddress, + virtual_machine_1.ipaddress, + "VM IP should not change after reservation") + + try: + virtual_machine_2 = VirtualMachine.create(self.apiclient, self.testData["virtual_machine"], + networkids=isolated_network_1.id, serviceofferingid=self.service_offering.id, + accountid=account_1.name, domainid=self.domain.id) + if netaddr.IPAddress(virtual_machine_2.ipaddress) not in netaddr.IPNetwork(guest_vm_cidr): + self.fail("Newly created VM doesn't get IP from reserverd CIDR") + except Exception as e: + self.fail("VM creation failed, cannot validate the condition: %s" % e) + + random_subnet = str(random.randrange(1,254)) + gateway = "10.1." + random_subnet +".1" + isolated_network_2 = Network.create(self.apiclient, self.testData["isolated_network"], + networkofferingid=self.isolated_network_offering.id,accountid=account_1.name, + domainid=self.domain.id,zoneid=self.zone.id, + gateway=gateway, netmask='255.255.255.0') + guest_vm_cidr = "10.1."+random_subnet+".0/29" + + try: + virtual_machine_3 = VirtualMachine.create(self.apiclient, self.testData["virtual_machine"], + networkids=isolated_network_2.id, serviceofferingid=self.service_offering.id, + accountid=account_1.name, domainid=self.domain.id, + ipaddress="10.1."+random_subnet+".3") + except Exception as e: + self.fail("VM creation failed: %s" % e) + + isolated_network_2.update(self.apiclient, guestvmcidr=guest_vm_cidr) + matchNetworkGuestVmCIDR(self, isolated_network_2.id, guest_vm_cidr) + vms = VirtualMachine.list(self.apiclient, + id=virtual_machine_3.id) + self.assertEqual(validateList(vms)[0], PASS, "vm list validation failed") + self.assertEqual(vms[0].nic[0].ipaddress, + virtual_machine_3.ipaddress, + "VM IP should not change after reservation") + + try: + virtual_machine_4 = VirtualMachine.create(self.apiclient, self.testData["virtual_machine"], + networkids=isolated_network_2.id, serviceofferingid=self.service_offering.id, + accountid=account_1.name, domainid=self.domain.id) + if netaddr.IPAddress(virtual_machine_4.ipaddress) not in netaddr.IPNetwork(guest_vm_cidr): + self.fail("Newly created VM doesn't get IP from reserverd CIDR") + except Exception as e: + self.fail("VM creation failed, cannot validate the condition: %s" % e) + return + +@ddt +class TestRestartNetwork(cloudstackTestCase): + """Test Restart Network + """ + @classmethod + def setUpClass(cls): + cls.testClient = super(TestRestartNetwork, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + + # Fill services from the external config file + cls.testData = cls.testClient.getParsedTestDataConfig() + + # Get Zone, Domain and templates + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) + cls.template = get_template( cls.api_client, - cls.services["account"], - domainid=cls.domain.id + cls.zone.id, + cls.testData["ostype"] ) - cls.services["account"] = cls.account.name - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["virtual_machine"]["template"] = cls.template.id - cls.service_offering = ServiceOffering.create( + if cls.template == FAILED: + assert False, "get_template() failed to return template with description %s" % cls.testData["ostype"] + cls.testData["domainid"] = cls.domain.id + cls.testData["zoneid"] = cls.zone.id + cls.testData["virtual_machine"]["zoneid"] = cls.zone.id + cls.testData["virtual_machine"]["template"] = cls.template.id + cls._cleanup = [] + try: + cls.service_offering = ServiceOffering.create( cls.api_client, - cls.services["service_offering"] + cls.testData["service_offering"] ) - cls.isolated_network_offering = cls.create_isolated_network_offering("isolated_network_offering") - cls.isolated_persistent_network_offering = cls.create_isolated_network_offering("isolated_persistent_network_offering") - cls.isolated_network = cls.create_isolated_network(cls.isolated_network_offering.id) - cls.isolated_persistent_network = cls.create_isolated_network(cls.isolated_persistent_network_offering.id) - # network will be deleted as part of account cleanup - cls._cleanup = [ - cls.account, cls.service_offering, cls.isolated_network_offering, cls.isolated_persistent_network_offering, - ] + cls._cleanup.append(cls.service_offering) + cls.isolated_network_offering = CreateEnabledNetworkOffering(cls.api_client, + cls.testData["isolated_network_offering"]) + cls._cleanup.append(cls.isolated_network_offering) + cls.isolated_persistent_network_offering = CreateEnabledNetworkOffering(cls.api_client, + cls.testData["nw_off_isolated_persistent"]) + cls._cleanup.append(cls.isolated_persistent_network_offering) + except Exception as e: + cls.tearDownClass() + raise unittest.SkipTest("Failure in setUpClass: %s" % e) return @classmethod @@ -154,44 +587,291 @@ def tearDownClass(cls): raise Exception("Warning: Exception during cleanup : %s" % e) return + def setUp(self): + self.apiclient = self.testClient.getApiClient() + self.dbclient = self.testClient.getDbConnection() + self.cleanup = [] + try: + self.account = Account.create(self.apiclient, self.testData["account"], + domainid=self.domain.id) + self.cleanup.append(self.account) + except Exception as e: + self.skipTest("Failed to create account: %s" % e) + return + + def tearDown(self): + try: + # Clean up, terminate the resources created + cleanup_resources(self.apiclient, self.cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + @data(True, False) + @attr(tags=["advanced"]) + def test_restart_network_with_cleanup(self, value): + """ Test IP reservation rules with network restart operation + # steps + # 1. Create vm in isolated network with ip in guestvmcidr + # 2. Update guestvmcidr + # 3. Restart network with cleanup True/False + # 4. Deploy another VM in the network + # + # validation + # 1. Guest vm cidr should be successfully updated with correct value + # 2. Existing guest vm ip should not be changed after reservation + # 3. Network should be restarted successfully with and without cleanup + # 4. Newly created VM should get ip in guestvmcidr""" + + subnet = "10.1."+str(random.randrange(1,254)) + gateway = subnet +".1" + resultSet = createIsolatedNetwork(self, self.isolated_network_offering.id, + gateway=gateway) + if resultSet[0] == FAIL: + self.fail("Failed to create isolated network") + else: + isolated_network= resultSet[1] + guest_vm_cidr = subnet+".0/29" + + try: + virtual_machine_1 = createVirtualMachine(self, network_id=isolated_network.id, + ip_address=subnet+".3") + except Exception as e: + self.fail("VM creation failed: %s" % e) + + isolated_network.update(self.apiclient, guestvmcidr=guest_vm_cidr) + matchNetworkGuestVmCIDR(self, isolated_network.id, guest_vm_cidr) + vms = VirtualMachine.list(self.apiclient, + id=virtual_machine_1.id) + self.assertEqual(validateList(vms)[0], PASS, "vm list validation failed") + self.assertEqual(vms[0].nic[0].ipaddress, + virtual_machine_1.ipaddress, + "VM IP should not change after reservation") + + #Restart Network + isolated_network.restart(self.apiclient, cleanup=value) + + try: + virtual_machine_2 = createVirtualMachine(self, network_id=isolated_network.id) + if netaddr.IPAddress(virtual_machine_2.ipaddress) not in netaddr.IPNetwork(guest_vm_cidr): + self.fail("Newly created VM doesn't get IP from reserverd CIDR") + except Exception as e: + self.fail("VM creation failed, cannot validate the condition: %s" % e) + return + +@ddt +class TestUpdateIPReservation(cloudstackTestCase): + """Test Updating IP reservation multiple times + """ @classmethod - def create_isolated_network_offering(cls, network_offering): - isolated_network_offering = NetworkOffering.create( - cls.api_client, - cls.services[network_offering], - conservemode=False - ) - # Update network offering state from disabled to enabled. - network_offering_update_response = NetworkOffering.update( - isolated_network_offering, - cls.api_client, - id=isolated_network_offering.id, - state="enabled" - ) - return isolated_network_offering + def setUpClass(cls): + cls.testClient = super(TestUpdateIPReservation, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + + # Fill services from the external config file + cls.testData = cls.testClient.getParsedTestDataConfig() + + # Get Zone, Domain and templates + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) + cls.template = get_template( + cls.api_client, + cls.zone.id, + cls.testData["ostype"] + ) + if cls.template == FAILED: + assert False, "get_template() failed to return template with description %s" % cls.testData["ostype"] + cls.testData["domainid"] = cls.domain.id + cls.testData["zoneid"] = cls.zone.id + cls.testData["virtual_machine"]["zoneid"] = cls.zone.id + cls.testData["virtual_machine"]["template"] = cls.template.id + cls._cleanup = [] + try: + cls.service_offering = ServiceOffering.create( + cls.api_client, + cls.testData["service_offering"] + ) + cls._cleanup.append(cls.service_offering) + cls.isolated_network_offering = CreateEnabledNetworkOffering(cls.api_client, + cls.testData["isolated_network_offering"]) + cls._cleanup.append(cls.isolated_network_offering) + cls.isolated_persistent_network_offering = CreateEnabledNetworkOffering(cls.api_client, + cls.testData["nw_off_isolated_persistent"]) + cls._cleanup.append(cls.isolated_persistent_network_offering) + except Exception as e: + cls.tearDownClass() + raise unittest.SkipTest("Failure in setUpClass: %s" % e) + return @classmethod - def create_isolated_network(cls, network_offering_id): - isolated_network = Network.create( - cls.api_client, - cls.services["isolated_network"], - networkofferingid=network_offering_id, - accountid=cls.account.name, - domainid=cls.domain.id, - zoneid=cls.zone.id - ) - cls.debug("isolated network is created: " + isolated_network.id) - return isolated_network + 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) + return + + def setUp(self): + self.apiclient = self.testClient.getApiClient() + self.dbclient = self.testClient.getDbConnection() + self.cleanup = [] + try: + self.account = Account.create(self.apiclient, self.testData["account"], + domainid=self.domain.id) + self.cleanup.append(self.account) + except Exception as e: + self.skipTest("Failed to create account: %s" % e) + return + + def tearDown(self): + try: + # Clean up, terminate the resources created + cleanup_resources(self.apiclient, self.cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + @data("existingVmInclusive", "existingVmExclusive") + @attr(tags=["advanced"]) + def test_update_network_guestvmcidr(self, value): + """ Test updating guest vm cidr of the network after + VMs are already deployed in previous guest VM cidr + # steps + # 1. Create isolated network with user defined cidr + # 2. Deploy VM in the network + # 3. Try to update the guestvmcidr of the network with VM ip in the guestvmcidr and + # deploy another VM + # 4. Try to update the guestvmcidr of the network with VM ip outside the guestvmcidr + # + # validation + # 1. When vm IP is in the guestvmcidr, updation should be successful and + # new VM should get IP from this range + # 2. When VM IP is outside the guestvmcidr, updation should be unsuccessful""" + + random_subnet = str(random.randrange(1,254)) + gateway = "10.1." + random_subnet +".1" + resultSet = createIsolatedNetwork(self, self.isolated_network_offering.id, + gateway=gateway) + if resultSet[0] == FAIL: + self.fail("Failed to create isolated network") + else: + isolated_network= resultSet[1] + guest_vm_cidr = "10.1."+random_subnet+".0/29" + + try: + virtual_machine_1 = createVirtualMachine(self, network_id=isolated_network.id, + ip_address=u"10.1."+random_subnet+".3") + except Exception as e: + self.fail("VM creation failed: %s" % e) + + isolated_network.update(self.apiclient, guestvmcidr=guest_vm_cidr) + matchNetworkGuestVmCIDR(self, isolated_network.id, guest_vm_cidr) + vms = VirtualMachine.list(self.apiclient, + id=virtual_machine_1.id) + self.assertEqual(validateList(vms)[0], PASS, "vm list validation failed") + self.assertEqual(vms[0].nic[0].ipaddress, + virtual_machine_1.ipaddress, + "VM IP should not change after reservation") + + try: + virtual_machine_2 = createVirtualMachine(self, network_id=isolated_network.id) + if netaddr.IPAddress(virtual_machine_2.ipaddress) not in netaddr.IPNetwork(guest_vm_cidr): + self.fail("Newly created VM doesn't get IP from reserverd CIDR") + except Exception as e: + self.fail("VM creation failed, cannot validate the condition: %s" % e) + + # Update guest vm cidr of network again + if value == "existingVmExclusive": + guest_vm_cidr = "10.1."+random_subnet+".10/29" + + try: + isolated_network.update(self.apiclient, guestvmcidr=guest_vm_cidr) + self.fail("Network updation should fail") + except Exception as e: + self.debug("Failed to update guest VM cidr of network: %s" % e) + elif value == "existingVmInclusive": + guest_vm_cidr = "10.1."+random_subnet+".0/28" + + try: + isolated_network.update(self.apiclient, guestvmcidr=guest_vm_cidr) + except Exception as e: + self.fail("Failed to update guest VM cidr of network: %s" % e) + + matchNetworkGuestVmCIDR(self, isolated_network.id, guest_vm_cidr) + + try: + virtual_machine_3 = createVirtualMachine(self, network_id=isolated_network.id) + if netaddr.IPAddress(virtual_machine_3.ipaddress) not in netaddr.IPNetwork(guest_vm_cidr): + self.fail("Newly created VM doesn't get IP from reserverd CIDR") + except Exception as e: + self.fail("VM creation failed, cannot validate the condition: %s" % e) + return + +@ddt +class TestRouterOperations(cloudstackTestCase): + """Test Router operations of network with IP reservation + """ + @classmethod + def setUpClass(cls): + cls.testClient = super(TestRouterOperations, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + + # Fill services from the external config file + cls.testData = cls.testClient.getParsedTestDataConfig() + + # Get Zone, Domain and templates + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) + cls.template = get_template( + cls.api_client, + cls.zone.id, + cls.testData["ostype"] + ) + if cls.template == FAILED: + assert False, "get_template() failed to return template with description %s" % cls.testData["ostype"] + cls.testData["domainid"] = cls.domain.id + cls.testData["zoneid"] = cls.zone.id + cls.testData["virtual_machine"]["zoneid"] = cls.zone.id + cls.testData["virtual_machine"]["template"] = cls.template.id + cls._cleanup = [] + try: + cls.service_offering = ServiceOffering.create( + cls.api_client, + cls.testData["service_offering"] + ) + cls._cleanup.append(cls.service_offering) + cls.isolated_network_offering = CreateEnabledNetworkOffering(cls.api_client, + cls.testData["isolated_network_offering"]) + cls._cleanup.append(cls.isolated_network_offering) + cls.isolated_persistent_network_offering = CreateEnabledNetworkOffering(cls.api_client, + cls.testData["nw_off_isolated_persistent"]) + cls._cleanup.append(cls.isolated_persistent_network_offering) + except Exception as e: + cls.tearDownClass() + raise unittest.SkipTest("Failure in setUpClass: %s" % e) + 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) + return def setUp(self): self.apiclient = self.testClient.getApiClient() self.dbclient = self.testClient.getDbConnection() - self.cleanup = [ ] - update_response = Network.update(self.isolated_persistent_network, self.apiclient, id=self.isolated_persistent_network.id, guestvmcidr=self.services["isolated_network_cidr"]) - if self.services["isolated_network_cidr"] <> update_response.cidr: - raise Exception("problem in updating cidr for test setup") + self.cleanup = [] + try: + self.account = Account.create(self.apiclient, self.testData["account"], + domainid=self.domain.id) + self.cleanup.append(self.account) + except Exception as e: + self.skipTest("Failed to create account: %s" % e) return def tearDown(self): @@ -202,33 +882,212 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - def create_virtual_machine(self, network_id=None, ip_address=None): - virtual_machine = VirtualMachine.create(self.apiclient, - self.services["virtual_machine"], - networkids=network_id, - serviceofferingid=self.service_offering.id, - accountid=self.account.name, - domainid=self.domain.id, - ipaddress=ip_address - ) - self.debug("Virtual Machine is created: " + virtual_machine.id) - self.cleanup.append(virtual_machine) - return virtual_machine + @attr(tags=["advanced"]) + def test_reservation_after_router_restart(self): + """ Test IP reservation working before and after router is restarted + # steps + # 1. Update guestvmcidr of persistent isolated network + # 2. Reboot router + # + # validation + # 1. Guest vm cidr should be successfully updated with correct value + # 2. Network cidr should remain same after router restart""" + subnet = "10.1."+str(random.randrange(1,254)) + gateway = subnet +".1" + resultSet = createIsolatedNetwork(self, self.isolated_persistent_network_offering.id, + gateway=gateway) + if resultSet[0] == FAIL: + self.fail("Failed to create isolated network") + else: + isolated_network= resultSet[1] + guest_vm_cidr = subnet+".0/29" + + isolated_network.update(self.apiclient, guestvmcidr=guest_vm_cidr) + matchNetworkGuestVmCIDR(self, isolated_network.id, guest_vm_cidr) + + routers = Router.list(self.apiclient, + networkid=isolated_network.id, + listall=True) + self.assertEqual(validateList(routers)[0], PASS, "routers list validation failed") + if not routers: + self.fail("Router list should not be empty") + + Router.reboot(self.apiclient, routers[0].id) + networks = Network.list(self.apiclient, id=isolated_network.id) + self.assertEqual(validateList(networks)[0], PASS, "networks list validation failed") + self.assertEqual(networks[0].cidr, guest_vm_cidr, "guestvmcidr should match after router reboot") + return @attr(tags=["advanced"]) + def test_destroy_recreate_router(self): + """ Test IP reservation working after destroying and recreating router + # steps + # 1. Create isolated network and deploy VM in it and update network with + # guestvmcidr + # 2. List the router associated with network and destroy the router + # 3. Restart the network + # 3. Deploy another VM in the network + # + # validation + # 1. Guest vm cidr should be successfully updated with correct value + # 2. existing guest vm ip should not be changed after reservation + # 3. Router should be destroyed and recreated when network is restarted + # 4. New VM should be deployed in the guestvmcidr""" + + subnet = "10.1."+str(random.randrange(1,254)) + gateway = subnet +".1" + resultSet = createIsolatedNetwork(self, self.isolated_network_offering.id, + gateway=gateway) + if resultSet[0] == FAIL: + self.fail("Failed to create isolated network") + else: + isolated_network= resultSet[1] + guest_vm_cidr = subnet+".0/29" + + try: + virtual_machine_1 = createVirtualMachine(self, network_id=isolated_network.id, + ip_address=subnet+".3") + except Exception as e: + self.fail("VM creation failed: %s" % e) + + isolated_network.update(self.apiclient, guestvmcidr=guest_vm_cidr) + matchNetworkGuestVmCIDR(self, isolated_network.id, guest_vm_cidr) + vms = VirtualMachine.list(self.apiclient, + id=virtual_machine_1.id) + self.assertEqual(validateList(vms)[0], PASS, "vm list validation failed") + self.assertEqual(vms[0].nic[0].ipaddress, + virtual_machine_1.ipaddress, + "VM IP should not change after reservation") + + # List router and destroy it + routers = Router.list(self.apiclient, networkid=isolated_network.id, listall=True) + self.assertEqual(validateList(routers)[0], PASS, "Routers list validation failed") + + # Destroy Router + try: + Router.destroy(self.apiclient, id=routers[0].id) + except Exception as e: + self.fail("Failed to destroy router: %s" % e) + + #Restart Network + try: + isolated_network.restart(self.apiclient) + except Exception as e: + self.fail("Failed to restart network: %s" % e) + + try: + virtual_machine_2 = createVirtualMachine(self, network_id=isolated_network.id) + if netaddr.IPAddress(virtual_machine_2.ipaddress) not in netaddr.IPNetwork(guest_vm_cidr): + self.fail("Newly created VM doesn't get IP from reserverd CIDR") + except Exception as e: + self.fail("VM creation failed, cannot validate the condition: %s" % e) + return + +@ddt +class TestFailureScnarios(cloudstackTestCase): + """Test failure scenarios related to IP reservation in network + """ + @classmethod + def setUpClass(cls): + cls.testClient = super(TestFailureScnarios, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + + # Fill services from the external config file + cls.testData = cls.testClient.getParsedTestDataConfig() + + # Get Zone, Domain and templates + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) + cls.template = get_template( + cls.api_client, + cls.zone.id, + cls.testData["ostype"] + ) + if cls.template == FAILED: + assert False, "get_template() failed to return template with description %s" % cls.testData["ostype"] + cls.testData["domainid"] = cls.domain.id + cls.testData["zoneid"] = cls.zone.id + cls.testData["virtual_machine"]["zoneid"] = cls.zone.id + cls.testData["virtual_machine"]["template"] = cls.template.id + cls._cleanup = [] + try: + cls.service_offering = ServiceOffering.create( + cls.api_client, + cls.testData["service_offering"] + ) + cls._cleanup.append(cls.service_offering) + cls.isolated_network_offering = CreateEnabledNetworkOffering(cls.api_client, + cls.testData["isolated_network_offering"]) + cls._cleanup.append(cls.isolated_network_offering) + cls.isolated_persistent_network_offering = CreateEnabledNetworkOffering(cls.api_client, + cls.testData["nw_off_isolated_persistent"]) + cls._cleanup.append(cls.isolated_persistent_network_offering) + + cls.testData["shared_network_offering"]["specifyVlan"] = "True" + cls.testData["shared_network_offering"]["specifyIpRanges"] = "True" + + #Create Network Offering + cls.shared_network_offering = NetworkOffering.create(cls.api_client, + cls.testData["shared_network_offering"], + conservemode=False) + cls._cleanup.append(cls.shared_network_offering) + + #Update network offering state from disabled to enabled. + NetworkOffering.update(cls.shared_network_offering,cls.api_client,state="enabled") + except Exception as e: + cls.tearDownClass() + raise unittest.SkipTest("Failure in setUpClass: %s" % e) + 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) + return + + def setUp(self): + self.apiclient = self.testClient.getApiClient() + self.dbclient = self.testClient.getDbConnection() + self.cleanup = [] + try: + self.account = Account.create(self.apiclient, self.testData["account"], + domainid=self.domain.id) + self.cleanup.append(self.account) + except Exception as e: + self.skipTest("Failed to create account: %s" % e) + return + + def tearDown(self): + try: + # Clean up, terminate the resources created + cleanup_resources(self.apiclient, self.cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + @attr(tags=["advanced", "selfservice"]) def test_network_not_implemented(self): # steps # 1. update guestvmcidr of isolated network (non persistent) # # validation # should throw exception as network is not in implemented state as no vm is created - try: - update_response = Network.update(self.isolated_network, self.apiclient, id=isolated_network.id, guestvmcidr="10.1.1.0/26") - self.fail("Network Update of guest VM CIDR is successful withot any VM deployed in network") - except Exception as e: - self.debug("Network Update of guest VM CIDR should fail as there is no VM deployed in network") - @attr(tags=["advanced"]) + networkOffering = self.isolated_network_offering + resultSet = createIsolatedNetwork(self, networkOffering.id) + if resultSet[0] == FAIL: + self.fail("Failed to create isolated network") + else: + isolated_network = resultSet[1] + + with self.assertRaises(Exception): + response = isolated_network.update(self.apiclient, guestvmcidr="10.1.1.0/26") + return + + @attr(tags=["advanced", "selfservice"]) def test_vm_create_after_reservation(self): # steps # 1. create vm in persistent isolated network with ip in guestvmcidr @@ -239,14 +1098,31 @@ def test_vm_create_after_reservation(self): # 1. guest vm cidr should be successfully updated with correct value # 2. existing guest vm ip should not be changed after reservation # 3. newly created VM should get ip in guestvmcidr - guest_vm_cidr = u"10.1.1.0/29" + + networkOffering = self.isolated_persistent_network_offering + subnet = "10.1."+str(random.randrange(1,254)) + gateway = subnet + ".1" + isolated_persistent_network = None + resultSet = createIsolatedNetwork(self, networkOffering.id, gateway=gateway) + if resultSet[0] == FAIL: + self.fail("Failed to create isolated network") + else: + isolated_persistent_network = resultSet[1] + guest_vm_cidr = subnet +".0/29" virtual_machine_1 = None try: - virtual_machine_1 = self.create_virtual_machine(network_id=self.isolated_persistent_network.id, ip_address=u"10.1.1.3") + virtual_machine_1 = VirtualMachine.create(self.apiclient, + self.testData["virtual_machine"], + networkids=isolated_persistent_network.id, + serviceofferingid=self.service_offering.id, + accountid=self.account.name, + domainid=self.domain.id, + ipaddress=subnet+".3" + ) except Exception as e: - self.skipTest("VM creation fails in network ") + self.fail("VM creation fails in network: %s" % e) - update_response = Network.update(self.isolated_persistent_network, self.apiclient, id=self.isolated_persistent_network.id, guestvmcidr=guest_vm_cidr) + update_response = Network.update(isolated_persistent_network, self.apiclient, id=isolated_persistent_network.id, guestvmcidr=guest_vm_cidr) self.assertEqual(guest_vm_cidr, update_response.cidr, "cidr in response is not as expected") vm_list = VirtualMachine.list(self.apiclient, id=virtual_machine_1.id) @@ -257,13 +1133,20 @@ def test_vm_create_after_reservation(self): virtual_machine_1.ipaddress, "VM IP should not change after reservation") try: - virtual_machine_2 = self.create_virtual_machine(network_id=self.isolated_persistent_network.id) + virtual_machine_2 = VirtualMachine.create(self.apiclient, + self.testData["virtual_machine"], + networkids=isolated_persistent_network.id, + serviceofferingid=self.service_offering.id, + accountid=self.account.name, + domainid=self.domain.id + ) if netaddr.IPAddress(virtual_machine_2.ipaddress) not in netaddr.IPNetwork(guest_vm_cidr): self.fail("Newly created VM doesn't get IP from reserverd CIDR") except Exception as e: - self.skipTest("VM creation fails, cannot validate the condition") + self.skipTest("VM creation fails, cannot validate the condition: %s" % e) + return - @attr(tags=["advanced"]) + @attr(tags=["advanced", "selfservice"]) def test_reservation_after_router_restart(self): # steps # 1. update guestvmcidr of persistent isolated network @@ -272,32 +1155,45 @@ def test_reservation_after_router_restart(self): # validation # 1. guest vm cidr should be successfully updated with correct value # 2. network cidr should remain same after router restart - guest_vm_cidr = u"10.1.1.0/29" + networkOffering = self.isolated_persistent_network_offering + subnet = "10.1."+str(random.randrange(1,254)) + gateway = subnet + ".1" + isolated_persistent_network = None + resultSet = createIsolatedNetwork(self, networkOffering.id, gateway=gateway) + if resultSet[0] == FAIL: + self.fail("Failed to create isolated network") + else: + isolated_persistent_network = resultSet[1] + + response = verifyNetworkState(self.apiclient, isolated_persistent_network.id,\ + "implemented") + exceptionOccured = response[0] + isNetworkInDesiredState = response[1] + exceptionMessage = response[2] + + if (exceptionOccured or (not isNetworkInDesiredState)): + self.fail(exceptionMessage) + guest_vm_cidr = subnet +".0/29" - update_response = Network.update(self.isolated_persistent_network, self.apiclient, id=self.isolated_persistent_network.id, guestvmcidr=guest_vm_cidr) + update_response = Network.update(isolated_persistent_network, self.apiclient, id=isolated_persistent_network.id, guestvmcidr=guest_vm_cidr) self.assertEqual(guest_vm_cidr, update_response.cidr, "cidr in response is not as expected") routers = Router.list(self.apiclient, - networkid=self.isolated_persistent_network.id, + networkid=isolated_persistent_network.id, listall=True) - self.assertEqual( - isinstance(routers, list), - True, - "list router should return valid response" - ) - if not routers: - self.skipTest("Router list should not be empty, skipping test") + self.assertEqual(validateList(routers)[0], PASS, + "routers list validation failed") Router.reboot(self.apiclient, routers[0].id) - networks = Network.list(self.apiclient, id=self.isolated_persistent_network.id) + networks = Network.list(self.apiclient, id=isolated_persistent_network.id) self.assertEqual( - isinstance(networks, list), - True, + validateList(networks)[0], PASS, "list Networks should return valid response" ) self.assertEqual(networks[0].cidr, guest_vm_cidr, "guestvmcidr should match after router reboot") + return - @attr(tags=["advanced"]) + @attr(tags=["advanced", "selfservice"]) def test_vm_create_outside_cidr_after_reservation(self): # steps # 1. update guestvmcidr of persistent isolated network @@ -306,11 +1202,25 @@ def test_vm_create_outside_cidr_after_reservation(self): # validation # 1. guest vm cidr should be successfully updated with correct value # 2 newly created VM should not be created and result in exception - guest_vm_cidr = u"10.1.1.0/29" - update_response = Network.update(self.isolated_persistent_network, self.apiclient, id=self.isolated_persistent_network.id, guestvmcidr=guest_vm_cidr) + networkOffering = self.isolated_persistent_network_offering + subnet = "10.1."+str(random.randrange(1,254)) + gateway = subnet + ".1" + isolated_persistent_network = None + resultSet = createIsolatedNetwork(self, networkOffering.id, gateway=gateway) + if resultSet[0] == FAIL: + self.fail("Failed to create isolated network") + else: + isolated_persistent_network = resultSet[1] + guest_vm_cidr = subnet +".0/29" + update_response = Network.update(isolated_persistent_network, self.apiclient, id=isolated_persistent_network.id, guestvmcidr=guest_vm_cidr) self.assertEqual(guest_vm_cidr, update_response.cidr, "cidr in response is not as expected") - try: - self.create_virtual_machine(network_id=self.isolated_persistent_network.id, ip_address=u"10.1.1.9") - self.fail("vm should not be created ") - except Exception as e: - self.debug("exception as IP is outside of guestvmcidr") + with self.assertRaises(Exception): + VirtualMachine.create(self.apiclient, + self.testData["virtual_machine"], + networkids=isolated_persistent_network.id, + serviceofferingid=self.service_offering.id, + accountid=self.account.name, + domainid=self.domain.id, + ipaddress="10.1.1.9" + ) + return diff --git a/test/integration/component/test_ldap.py b/test/integration/component/test_ldap.py index d9e7c351cd..5dd9692837 100644 --- a/test/integration/component/test_ldap.py +++ b/test/integration/component/test_ldap.py @@ -29,9 +29,9 @@ import random from marvin.cloudstackAPI import * from marvin.cloudstackAPI import login -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * +from marvin.lib.utils import * +from marvin.lib.base import * +from marvin.lib.common import * from nose.plugins.attrib import attr import urllib @@ -128,7 +128,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags=["advanced", "basic"]) + @attr(tags=["advanced", "basic", "selfservice"]) def test_01_addLdapConfiguration(self): """ This test configures LDAP and attempts to authenticate as a user. diff --git a/test/integration/component/test_memory_limits.py b/test/integration/component/test_memory_limits.py index 231307f693..5dd3ba0e5b 100644 --- a/test/integration/component/test_memory_limits.py +++ b/test/integration/component/test_memory_limits.py @@ -19,21 +19,21 @@ # Import Local Modules from nose.plugins.attrib import attr from marvin.cloudstackTestCase import cloudstackTestCase, unittest -from marvin.integration.lib.base import ( +from marvin.lib.base import ( Account, ServiceOffering, VirtualMachine, Resources, Domain ) -from marvin.integration.lib.common import (get_domain, +from marvin.lib.common import (get_domain, get_zone, get_template, wait_for_cleanup, findSuitableHostForMigration, get_resource_type ) -from marvin.integration.lib.utils import cleanup_resources +from marvin.lib.utils import cleanup_resources from marvin.codes import ERROR_NO_HOST_FOR_MIGRATION class Services: @@ -91,12 +91,13 @@ class TestMemoryLimits(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestMemoryLimits, - cls).getClsTestClient().getApiClient() + cls.testClient = super(TestMemoryLimits, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services["mode"] = cls.zone.networktype @@ -176,7 +177,7 @@ def createInstance(self, service_off, networks=None, api_client=None): except Exception as e: self.fail("Failed to deploy an instance: %s" % e) - @attr(tags=["advanced", "advancedns","simulator"]) + @attr(tags=["advanced", "advancedns","simulator", "selfservice"]) def test_01_stop_start_instance(self): """Test Deploy VM with specified RAM & verify the usage""" @@ -228,7 +229,7 @@ def test_01_stop_start_instance(self): "Resource count should be same after stopping the instance") return - @attr(tags=["advanced", "advancedns","simulator"]) + @attr(tags=["advanced", "advancedns","simulator", "provisioning"]) def test_02_migrate_instance(self): """Test Deploy VM with specified RAM & verify the usage""" @@ -269,7 +270,7 @@ def test_02_migrate_instance(self): "Resource count should be same after stopping the instance") return - @attr(tags=["advanced", "advancedns","simulator"]) + @attr(tags=["advanced", "advancedns","simulator", "selfservice"]) def test_03_delete_instance(self): """Test Deploy VM with specified GB RAM & verify the usage""" @@ -308,7 +309,7 @@ def test_03_delete_instance(self): self.assertEqual(resource_count_after_delete, 0 , "Resource count for %s should be 0" % get_resource_type(resource_id=9))#RAM return - @attr(tags=["advanced", "advancedns","simulator"]) + @attr(tags=["advanced", "advancedns","simulator", "selfservice"]) def test_04_deploy_multiple_vm(self): """Test Deploy multiple VM with specified RAM & verify the usage""" @@ -370,12 +371,13 @@ class TestDomainMemoryLimitsConfiguration(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestDomainMemoryLimitsConfiguration, - cls).getClsTestClient().getApiClient() + cls.testClient = super(TestDomainMemoryLimitsConfiguration, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + 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( @@ -479,7 +481,7 @@ def setupAccounts(self): return - @attr(tags=["advanced", "advancedns","simulator"]) + @attr(tags=["advanced", "advancedns","simulator", "selfservice"]) def test_01_stop_start_instance(self): """Test Deploy VM with 5 GB memory & verify the usage""" @@ -498,7 +500,7 @@ def test_01_stop_start_instance(self): self.account = admin self.domain = domain - api_client = self.testClient.createUserApiClient( + api_client = self.testClient.getUserApiClient( UserName=self.account.name, DomainName=self.account.domain) @@ -551,7 +553,7 @@ def test_01_stop_start_instance(self): "Resource count should be same after starting the instance") return - @attr(tags=["advanced", "advancedns","simulator"]) + @attr(tags=["advanced", "advancedns","simulator", "provisioning"]) def test_02_migrate_instance(self): """Test Deploy VM with specified memory & verify the usage""" @@ -570,7 +572,7 @@ def test_02_migrate_instance(self): self.account = admin self.domain = domain - api_client = self.testClient.createUserApiClient( + api_client = self.testClient.getUserApiClient( UserName=self.account.name, DomainName=self.account.domain) @@ -611,7 +613,7 @@ def test_02_migrate_instance(self): "Resource count should be same after starting the instance") return - @attr(tags=["advanced", "advancedns","simulator"]) + @attr(tags=["advanced", "advancedns","simulator", "selfservice"]) def test_03_delete_instance(self): """Test Deploy VM with specified RAM & verify the usage""" @@ -630,7 +632,7 @@ def test_03_delete_instance(self): self.account = admin self.domain = domain - api_client = self.testClient.createUserApiClient( + api_client = self.testClient.getUserApiClient( UserName=self.account.name, DomainName=self.account.domain) @@ -703,7 +705,7 @@ def test_04_deploy_multiple_vm(self): if memory_account_gc[0].max != 8192: self.skipTest("This test case requires configuration value max.account.memory to be 8192") - api_client = self.testClient.createUserApiClient( + api_client = self.testClient.getUserApiClient( UserName=self.account.name, DomainName=self.account.domain) diff --git a/test/integration/component/test_mm_domain_limits.py b/test/integration/component/test_mm_domain_limits.py index a2b7395cd1..bc8c9ea553 100644 --- a/test/integration/component/test_mm_domain_limits.py +++ b/test/integration/component/test_mm_domain_limits.py @@ -19,14 +19,14 @@ # Import Local Modules from nose.plugins.attrib import attr from marvin.cloudstackTestCase import cloudstackTestCase, unittest -from marvin.integration.lib.base import ( +from marvin.lib.base import ( Account, ServiceOffering, VirtualMachine, Resources, Domain ) -from marvin.integration.lib.common import (get_domain, +from marvin.lib.common import (get_domain, get_zone, get_template, wait_for_cleanup, @@ -34,7 +34,7 @@ get_resource_type, update_resource_count ) -from marvin.integration.lib.utils import cleanup_resources +from marvin.lib.utils import cleanup_resources from marvin.codes import ERROR_NO_HOST_FOR_MIGRATION class Services: @@ -92,12 +92,13 @@ class TestDomainMemoryLimits(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestDomainMemoryLimits, - cls).getClsTestClient().getApiClient() + cls.testClient = super(TestDomainMemoryLimits, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + 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( @@ -209,7 +210,7 @@ def setupAccounts(self): domainid=self.child_do_admin_2.domainid) return - @attr(tags=["advanced", "advancedns","simulator"]) + @attr(tags=["advanced", "advancedns","simulator", "selfservice"]) def test_01_change_service_offering(self): """Test Deploy VM with specified RAM & verify the usage""" @@ -234,7 +235,7 @@ def test_01_change_service_offering(self): self.debug("Creating an instance with service offering: %s" % self.service_offering.name) - api_client = self.testClient.createUserApiClient( + api_client = self.testClient.getUserApiClient( UserName=self.account.name, DomainName=self.account.domain) @@ -348,7 +349,7 @@ def test_01_change_service_offering(self): return - @attr(tags=["advanced", "advancedns","simulator"]) + @attr(tags=["advanced", "advancedns","simulator", "provisioning"]) def test_02_migrate_vm(self): """Test Deploy VM with specified RAM & verify the usage""" @@ -371,7 +372,7 @@ def test_02_migrate_vm(self): self.debug("Creating an instance with service offering: %s" % self.service_offering.name) - api_client = self.testClient.createUserApiClient( + api_client = self.testClient.getUserApiClient( UserName=self.account.name, DomainName=self.account.domain) @@ -409,7 +410,7 @@ def test_02_migrate_vm(self): "Resource count should be same after migrating the instance") return - @attr(tags=["advanced", "advancedns","simulator"]) + @attr(tags=["advanced", "advancedns","simulator", "selfservice"]) def test_03_delete_vm(self): """Test Deploy VM with specified RAM & verify the usage""" @@ -432,7 +433,7 @@ def test_03_delete_vm(self): self.debug("Creating an instance with service offering: %s" % self.service_offering.name) - api_client = self.testClient.createUserApiClient( + api_client = self.testClient.getUserApiClient( UserName=self.account.name, DomainName=self.account.domain) @@ -468,7 +469,7 @@ def test_03_delete_vm(self): self.assertEqual(resource_count_after_delete, 0 , "Resource count for %s should be 0" % get_resource_type(resource_id=9))#RAM return - @attr(tags=["advanced", "advancedns","simulator"]) + @attr(tags=["advanced", "advancedns","simulator", "selfservice"]) def test_04_deploy_multiple_vm(self): """Test Deploy multiple VM with specified RAM & verify the usage""" @@ -492,7 +493,7 @@ def test_04_deploy_multiple_vm(self): self.debug("Creating an instance with service offering: %s" % self.service_offering.name) - api_client = self.testClient.createUserApiClient( + api_client = self.testClient.getUserApiClient( UserName=self.account.name, DomainName=self.account.domain) @@ -524,12 +525,13 @@ class TestMultipleChildDomainsMemory(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestMultipleChildDomainsMemory, - cls).getClsTestClient().getApiClient() + cls.testClient = super(TestMultipleChildDomainsMemory, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + 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( @@ -682,7 +684,7 @@ def setupAccounts(self): } return users - @attr(tags=["advanced", "advancedns","simulator"]) + @attr(tags=["advanced", "advancedns","simulator", "selfservice"]) def test_01_multiple_child_domains(self): """Test memory limits with multiple child domains""" @@ -709,11 +711,11 @@ def test_01_multiple_child_domains(self): self.debug("Setting up account and domain hierarchy") self.setupAccounts() - api_client_cadmin_1 = self.testClient.createUserApiClient( + api_client_cadmin_1 = self.testClient.getUserApiClient( UserName=self.cadmin_1.name, DomainName=self.cadmin_1.domain) - api_client_cadmin_2 = self.testClient.createUserApiClient( + api_client_cadmin_2 = self.testClient.getUserApiClient( UserName=self.cadmin_2.name, DomainName=self.cadmin_2.domain) diff --git a/test/integration/component/test_mm_max_limits.py b/test/integration/component/test_mm_max_limits.py index e10c119f07..34d4147b90 100644 --- a/test/integration/component/test_mm_max_limits.py +++ b/test/integration/component/test_mm_max_limits.py @@ -19,7 +19,7 @@ # Import Local Modules from nose.plugins.attrib import attr from marvin.cloudstackTestCase import cloudstackTestCase, unittest -from marvin.integration.lib.base import ( +from marvin.lib.base import ( Account, ServiceOffering, VirtualMachine, @@ -27,11 +27,11 @@ Domain, Project ) -from marvin.integration.lib.common import (get_domain, +from marvin.lib.common import (get_domain, get_zone, get_template ) -from marvin.integration.lib.utils import cleanup_resources +from marvin.lib.utils import cleanup_resources class Services: """Test memory resource limit services @@ -88,12 +88,13 @@ class TestMaxMemoryLimits(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestMaxMemoryLimits, - cls).getClsTestClient().getApiClient() + cls.testClient = super(TestMaxMemoryLimits, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + 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( @@ -239,7 +240,7 @@ def setupAccounts(self, account_limit=2, domain_limit=2, project_limit=2): (responses.domain, responses.domainid, responses.max)) return - @attr(tags=["advanced", "advancedns","simulator"]) + @attr(tags=["advanced", "advancedns","simulator", "selfservice"]) def test_01_deploy_vm_domain_limit_reached(self): """Test Try to deploy VM with admin account where account has not used the resources but @ domain they are not available""" @@ -253,7 +254,7 @@ def test_01_deploy_vm_domain_limit_reached(self): self.debug("Setting up account and domain hierarchy") self.setupAccounts(account_limit=8, domain_limit=4) - api_client = self.testClient.createUserApiClient( + api_client = self.testClient.getUserApiClient( UserName=self.child_do_admin.name, DomainName=self.child_do_admin.domain) @@ -266,7 +267,7 @@ def test_01_deploy_vm_domain_limit_reached(self): service_off=self.service_offering, api_client=api_client) return - @attr(tags=["advanced", "advancedns","simulator"]) + @attr(tags=["advanced", "advancedns","simulator", "selfservice"]) def test_02_deploy_vm_account_limit_reached(self): """Test Try to deploy VM with admin account where account has used the resources but @ domain they are available""" @@ -280,7 +281,7 @@ def test_02_deploy_vm_account_limit_reached(self): self.debug("Setting up account and domain hierarchy") self.setupAccounts(account_limit=7, domain_limit=14) - api_client = self.testClient.createUserApiClient( + api_client = self.testClient.getUserApiClient( UserName=self.child_do_admin.name, DomainName=self.child_do_admin.domain) @@ -296,7 +297,7 @@ def test_02_deploy_vm_account_limit_reached(self): service_off=self.service_offering, api_client=api_client) return - @attr(tags=["advanced", "advancedns","simulator"]) + @attr(tags=["advanced", "advancedns","simulator", "selfservice"]) def test_03_deploy_vm_project_limit_reached(self): """Test TTry to deploy VM with admin account where account has not used the resources but @ project they are not available""" @@ -310,7 +311,7 @@ def test_03_deploy_vm_project_limit_reached(self): self.debug("Setting up account and domain hierarchy") self.setupAccounts(account_limit=8,domain_limit=8, project_limit=4) - api_client = self.testClient.createUserApiClient( + api_client = self.testClient.getUserApiClient( UserName=self.child_do_admin.name, DomainName=self.child_do_admin.domain) @@ -320,7 +321,7 @@ def test_03_deploy_vm_project_limit_reached(self): service_off=self.service_offering, api_client=api_client) return - @attr(tags=["advanced", "advancedns"]) + @attr(tags=["advanced", "advancedns", "selfservice"]) def test_04_deployVm__account_limit_reached(self): """Test Try to deploy VM with admin account where account has used the resources but @ project they are available""" @@ -334,7 +335,7 @@ def test_04_deployVm__account_limit_reached(self): self.debug("Setting up account and domain hierarchy") self.setupAccounts(account_limit=6, project_limit=12, domain_limit=12) - api_client = self.testClient.createUserApiClient( + api_client = self.testClient.getUserApiClient( UserName=self.child_do_admin.name, DomainName=self.child_do_admin.domain) diff --git a/test/integration/component/test_mm_project_limits.py b/test/integration/component/test_mm_project_limits.py index 29a3b54972..593b2b6400 100644 --- a/test/integration/component/test_mm_project_limits.py +++ b/test/integration/component/test_mm_project_limits.py @@ -19,21 +19,21 @@ # Import Local Modules from nose.plugins.attrib import attr from marvin.cloudstackTestCase import cloudstackTestCase, unittest -from marvin.integration.lib.base import ( +from marvin.lib.base import ( Account, ServiceOffering, VirtualMachine, Domain, Project ) -from marvin.integration.lib.common import (get_domain, +from marvin.lib.common import (get_domain, get_zone, get_template, wait_for_cleanup, findSuitableHostForMigration, get_resource_type ) -from marvin.integration.lib.utils import cleanup_resources +from marvin.lib.utils import cleanup_resources from marvin.codes import ERROR_NO_HOST_FOR_MIGRATION class Services: @@ -91,12 +91,13 @@ class TestProjectsMemoryLimits(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestProjectsMemoryLimits, - cls).getClsTestClient().getApiClient() + cls.testClient = super(TestProjectsMemoryLimits, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + 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( @@ -137,7 +138,7 @@ def setUp(self): self.debug("Setting up account and domain hierarchy") self.setupProjectAccounts() - api_client = self.testClient.createUserApiClient( + api_client = self.testClient.getUserApiClient( UserName=self.admin.name, DomainName=self.admin.domain) @@ -216,7 +217,7 @@ def setupProjectAccounts(self): "Check project name from list response") return - @attr(tags=["advanced", "advancedns","simulator"]) + @attr(tags=["advanced", "advancedns","simulator", "selfservice"]) def test_01_project_vmlifecycle_start_stop_instance(self): # Validate the following @@ -273,7 +274,7 @@ def test_01_project_vmlifecycle_start_stop_instance(self): "Resource count should be same after starting the instance") return - @attr(tags=["advanced", "advancedns","simulator"]) + @attr(tags=["advanced", "advancedns","simulator", "provisioning"]) def test_02_project_vmlifecycle_migrate_instance(self): # Validate the following @@ -314,7 +315,7 @@ def test_02_project_vmlifecycle_migrate_instance(self): "Resource count should be same after migrating the instance") return - @attr(tags=["advanced", "advancedns","simulator"]) + @attr(tags=["advanced", "advancedns","simulator", "selfservice"]) def test_03_project_vmlifecycle_delete_instance(self): # Validate the following diff --git a/test/integration/component/test_multiple_ip_ranges.py b/test/integration/component/test_multiple_ip_ranges.py index aae90c4cd4..32c39f7c6a 100644 --- a/test/integration/component/test_multiple_ip_ranges.py +++ b/test/integration/component/test_multiple_ip_ranges.py @@ -18,10 +18,10 @@ """ from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * -from marvin.cloudstackException import cloudstackAPIException -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * +from marvin.cloudstackException import CloudstackAPIException +from marvin.lib.utils import * +from marvin.lib.base import * +from marvin.lib.common import * from netaddr import * from nose.plugins.attrib import attr @@ -78,12 +78,14 @@ class TestMultipleIpRanges(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestMultipleIpRanges, cls).getClsTestClient().getApiClient() + cls.testClient = super(TestMultipleIpRanges, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - cls.pod = get_pod(cls.api_client, cls.zone.id, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) + cls.pod = get_pod(cls.api_client, cls.zone.id) cls.services['mode'] = cls.zone.networktype cls.services["domainid"] = cls.domain.id cls.services["zoneid"] = cls.zone.id @@ -296,7 +298,7 @@ def test_03_del_ip_range(self): #listing vlan ip ranges with the id should through exception , if not mark the test case as failed try: new_vlan.list(self.apiclient, id=new_vlan.vlan.id) - except cloudstackAPIException as cs: + except CloudstackAPIException as cs: self.debug(cs.errorMsg) self.assertTrue(cs.errorMsg.find("entity does not exist")>0, msg="Failed to delete IP range") return @@ -387,7 +389,7 @@ def test_05_add_overlapped_ip_range(self): self.debug("Adding overlapped ip range") try: new_vlan2 = PublicIpRange.create(self.apiclient, self.services["vlan_ip_range"]) - except cloudstackAPIException as cs: + except CloudstackAPIException as cs: self.debug(cs.errorMsg) self.assertTrue(cs.errorMsg.find("already has IPs that overlap with the new range")>0, msg="Fail:CS allowed adding overlapped ip ranges in guest cidr") return @@ -443,7 +445,7 @@ def test_06_add_ip_range_overlapped_with_two_ranges(self): self.debug("Adding ip range overlapped with two cidrs") try: new_vlan3 = PublicIpRange.create(self.apiclient, self.services["vlan_ip_range"]) - except cloudstackAPIException as cs: + except CloudstackAPIException as cs: self.debug(cs.errorMsg) self.assertTrue(cs.errorMsg.find("already has IPs that overlap with the new range")>0, msg="Fail:CS allowed adding overlapped ip ranges in guest cidr") return @@ -496,7 +498,7 @@ def test_07_add_iprange_superset(self): self.debug("Adding IP range super set to existing CIDR") try: new_vlan2 = PublicIpRange.create(self.apiclient, self.services["vlan_ip_range"]) - except cloudstackAPIException as cs: + except CloudstackAPIException as cs: self.debug(cs.errorMsg) self.assertTrue(cs.errorMsg.find("superset")>0, msg="Fail: CS allowed adding ip range superset to existing CIDR") return @@ -549,7 +551,7 @@ def test_08_add_iprange_subset(self): self.debug("Adding ip range subset to existing cidr") try: new_vlan2 = PublicIpRange.create(self.apiclient, self.services["vlan_ip_range"]) - except cloudstackAPIException as cs: + except CloudstackAPIException as cs: self.debug(cs.errorMsg) self.assertTrue(cs.errorMsg.find("subset")>0, msg="Fail: CS allowed adding ip range subset to existing CIDR") return diff --git a/test/integration/component/test_multiple_ips_per_nic.py b/test/integration/component/test_multiple_ips_per_nic.py index dcbb453e7e..2db15e5da5 100644 --- a/test/integration/component/test_multiple_ips_per_nic.py +++ b/test/integration/component/test_multiple_ips_per_nic.py @@ -23,32 +23,35 @@ Design Document: https://cwiki.apache.org/confluence/display/CLOUDSTACK/Multiple+IP+address+per+NIC """ from marvin.cloudstackTestCase import cloudstackTestCase -from marvin.integration.lib.utils import (cleanup_resources, - validateList, - random_gen) -from marvin.integration.lib.base import (Account, - ServiceOffering, - Network, - VirtualMachine, - VpcOffering, - VPC, - NIC, - Domain, - PublicIPAddress, - StaticNATRule, - FireWallRule, - NATRule) -from marvin.integration.lib.common import (get_domain, - get_zone, - get_template, - get_free_vlan, - setSharedNetworkParams, - createEnabledNetworkOffering, - shouldTestBeSkipped) - +from marvin.lib.utils import (cleanup_resources, + validateList, + random_gen) +from marvin.lib.base import (Account, + VirtualMachine, + ServiceOffering, + PublicIPAddress, + NIC, + FireWallRule, + NATRule, + StaticNATRule, + VpcOffering, + Domain, + Network, + Router, + VPC + ) +from marvin.lib.common import (get_domain, + get_zone, + get_template, + get_free_vlan, + setSharedNetworkParams, + createEnabledNetworkOffering, + shouldTestBeSkipped, + wait_for_cleanup) from nose.plugins.attrib import attr -from marvin.codes import PASS, ISOLATED_NETWORK, VPC_NETWORK, SHARED_NETWORK, FAIL +from marvin.codes import PASS, ISOLATED_NETWORK, VPC_NETWORK, SHARED_NETWORK, FAIL, FAILED from ddt import ddt, data +import time def createNetwork(self, networkType): """Create a network of given type (isolated/shared/isolated in VPC)""" @@ -137,21 +140,23 @@ class TestBasicOperations(cloudstackTestCase): @classmethod def setUpClass(cls): - cloudstackTestClient = super(TestBasicOperations,cls).getClsTestClient() - cls.api_client = cloudstackTestClient.getApiClient() + cls.testClient = super(TestBasicOperations, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() # Fill services from the external config file - cls.services = cloudstackTestClient.getConfigParser().parsedDict + cls.services = cls.testClient.getParsedTestDataConfig() # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - cls.mode = str(cls.zone.networktype).lower() + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, cls.services["ostype"] ) + if cls.template == FAILED: + assert False, "get_template() failed to return template with description %s" % cls.services["ostype"] + cls.services["virtual_machine"]["zoneid"] = cls.zone.id cls.services["virtual_machine"]["template"] = cls.template.id cls.service_offering = ServiceOffering.create( @@ -159,14 +164,14 @@ def setUpClass(cls): cls.services["service_offering"] ) cls._cleanup = [cls.service_offering] - cls.services["shared_network_offering"]["specifyVlan"] = "True" - cls.services["shared_network_offering"]["specifyIpRanges"] = "True" + cls.services["shared_network_offering_all_services"]["specifyVlan"] = "True" + cls.services["shared_network_offering_all_services"]["specifyIpRanges"] = "True" cls.shared_network_offering = CreateEnabledNetworkOffering(cls.api_client, - cls.services["shared_network_offering"]) + cls.services["shared_network_offering_all_services"]) cls._cleanup.append(cls.shared_network_offering) - - if cls.mode == "advanced": + cls.mode = cls.zone.networktype + if cls.mode.lower() == "advanced": cls.isolated_network_offering = CreateEnabledNetworkOffering(cls.api_client, cls.services["isolated_network_offering"]) cls._cleanup.append(cls.isolated_network_offering) @@ -442,7 +447,7 @@ def test_operations_non_root_admin_api_client(self, value): self.cleanup.append(self.account) self.cleanup.append(child_domain) - apiclient = self.testClient.createUserApiClient(UserName=self.account.name, DomainName=self.account.domain) + apiclient = self.testClient.getUserApiClient(UserName=self.account.name, DomainName=self.account.domain) if(shouldTestBeSkipped(networkType=value, zoneType=self.mode)): self.skipTest("Skipping test as %s network is not supported in basic zone" % value) @@ -459,7 +464,7 @@ def test_operations_non_root_admin_api_client(self, value): try: ipaddress_1 = NIC.addIp(apiclient, id=virtual_machine.nic[0].id) except Exception as e: - self.fail("Failed while adding secondary IP to NIC of vm %s" % virtual_machine.id) + self.fail("Failed while adding secondary IP to NIC of vm %s: %s" % (virtual_machine.id, e)) try: NIC.list(apiclient, virtualmachineid=virtual_machine.id) @@ -486,21 +491,23 @@ class TestNetworkRules(cloudstackTestCase): @classmethod def setUpClass(cls): - cloudstackTestClient = super(TestNetworkRules,cls).getClsTestClient() - cls.api_client = cloudstackTestClient.getApiClient() + cls.testClient = super(TestNetworkRules, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() # Fill services from the external config file - cls.services = cloudstackTestClient.getConfigParser().parsedDict + cls.services = cls.testClient.getParsedTestDataConfig() # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - cls.mode = str(cls.zone.networktype).lower() + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, cls.services["ostype"] ) + if cls.template == FAILED: + assert False, "get_template() failed to return template with description %s" % cls.services["ostype"] + cls.services["virtual_machine"]["zoneid"] = cls.zone.id cls.services["virtual_machine"]["template"] = cls.template.id cls.service_offering = ServiceOffering.create( @@ -508,13 +515,14 @@ def setUpClass(cls): cls.services["service_offering"] ) cls._cleanup = [cls.service_offering] - cls.services["shared_network_offering"]["specifyVlan"] = "True" - cls.services["shared_network_offering"]["specifyIpRanges"] = "True" + cls.services["shared_network_offering_all_services"]["specifyVlan"] = "True" + cls.services["shared_network_offering_all_services"]["specifyIpRanges"] = "True" - cls.shared_network_offering = CreateEnabledNetworkOffering(cls.api_client, cls.services["shared_network_offering"]) + cls.shared_network_offering = CreateEnabledNetworkOffering(cls.api_client, + cls.services["shared_network_offering_all_services"]) cls._cleanup.append(cls.shared_network_offering) - - if cls.mode == "advanced": + cls.mode = cls.zone.networktype + if cls.mode.lower() == "advanced": cls.isolated_network_offering = CreateEnabledNetworkOffering(cls.api_client, cls.services["isolated_network_offering"]) cls._cleanup.append(cls.isolated_network_offering) cls.isolated_network_offering_vpc = CreateEnabledNetworkOffering(cls.api_client, cls.services["nw_offering_isolated_vpc"]) @@ -851,3 +859,440 @@ def test_disable_static_nat(self, value): public_ip.delete(self.apiclient) return + +@ddt +class TestVmNetworkOperations(cloudstackTestCase): + """Test VM and Network operations with network rules created on secondary IP + """ + + @classmethod + def setUpClass(cls): + cls.testClient = super(TestVmNetworkOperations, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + + # Fill services from the external config file + cls.services = cls.testClient.getParsedTestDataConfig() + + # Get Zone, Domain and templates + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) + cls.template = get_template( + cls.api_client, + cls.zone.id, + cls.services["ostype"] + ) + if cls.template == FAILED: + assert False, "get_template() failed to return template with description %s" % cls.services["ostype"] + cls.services["virtual_machine"]["zoneid"] = cls.zone.id + cls.services["virtual_machine"]["template"] = cls.template.id + cls.service_offering = ServiceOffering.create( + cls.api_client, + cls.services["service_offering"] + ) + cls._cleanup = [cls.service_offering] + cls.services["shared_network_offering_all_services"]["specifyVlan"] = "True" + cls.services["shared_network_offering_all_services"]["specifyIpRanges"] = "True" + + cls.shared_network_offering = CreateEnabledNetworkOffering(cls.api_client, + cls.services["shared_network_offering_all_services"]) + cls._cleanup.append(cls.shared_network_offering) + cls.mode = cls.zone.networktype + if cls.mode.lower() == "advanced": + cls.isolated_network_offering = CreateEnabledNetworkOffering(cls.api_client, cls.services["isolated_network_offering"]) + cls._cleanup.append(cls.isolated_network_offering) + cls.isolated_network_offering_vpc = CreateEnabledNetworkOffering(cls.api_client, cls.services["nw_offering_isolated_vpc"]) + cls._cleanup.append(cls.isolated_network_offering_vpc) + cls.vpc_off = VpcOffering.create(cls.api_client, cls.services["vpc_offering"]) + cls.vpc_off.update(cls.api_client, state='Enabled') + cls._cleanup.append(cls.vpc_off) + 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) + return + + def setUp(self): + self.apiclient = self.testClient.getApiClient() + self.dbclient = self.testClient.getDbConnection() + self.cleanup = [ ] + return + + def tearDown(self): + try: + # Clean up, terminate the resources created + cleanup_resources(self.apiclient, self.cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + def VerifyStaticNatForPublicIp(self, ipaddressid, natrulestatus): + """ List public IP and verify that NAT rule status for the IP is as desired """ + + publiciplist = PublicIPAddress.list(self.apiclient, id=ipaddressid, listall=True) + self.assertEqual(validateList(publiciplist)[0], PASS, "Public IP list validation failed") + self.assertEqual(publiciplist[0].isstaticnat, natrulestatus, "isstaticnat should be %s, it is %s" % + (natrulestatus, publiciplist[0].isstaticnat)) + + return + + @data(ISOLATED_NETWORK, SHARED_NETWORK, VPC_NETWORK) + @attr(tags=["advanced"]) + def test_delete_vm(self, value): + """ Test delete VM and verify network rules are cleaned up""" + + # Steps: + # 1. Create Account and create network in it (isoalted/ shared/ vpc) + # 2. Deploy a VM in this network and account + # 3. Add 2 secondary IPs to the default nic of VM + # 4. Acquire 2 public IPs in the network + # 5. For 1st public IP create nat rule to 1st private IP, for 2nd public IP, create + # static nat rule to 2nd private IP + # 6. Destroy the virtual machine + # 7. Verify that nat rule does not exist and static nat is not enabled for + # secondary IP + + self.account = Account.create(self.apiclient,self.services["account"],domainid=self.domain.id) + self.cleanup.append(self.account) + + network = createNetwork(self, value) + + try: + virtual_machine = VirtualMachine.create(self.apiclient,self.services["virtual_machine"], + networkids=[network.id],serviceofferingid=self.service_offering.id, + accountid=self.account.name,domainid=self.account.domainid) + except Exception as e: + self.fail("vm creation failed: %s" % e) + + # Add secondary IPs to default NIC of VM + try: + ipaddress_1 = NIC.addIp(self.apiclient, id=virtual_machine.nic[0].id) + ipaddress_2 = NIC.addIp(self.apiclient, id=virtual_machine.nic[0].id) + except Exception as e: + self.fail("Failed while adding secondary IP to NIC of vm %s" % virtual_machine.id) + + # Acquire public IP addresses in the network + try: + public_ip_1 = PublicIPAddress.create(self.api_client,accountid=self.account.name, + zoneid=self.zone.id,domainid=self.account.domainid, + networkid=network.id, vpcid = network.vpcid if value == VPC_NETWORK else None) + + public_ip_2 = PublicIPAddress.create(self.api_client,accountid=self.account.name, + zoneid=self.zone.id,domainid=self.account.domainid, + networkid=network.id, vpcid = network.vpcid if value == VPC_NETWORK else None) + except Exception as e: + self.fail("Exception while acquiring public ip address: %s" % e) + + # Create Firewall and natrule for 1st IP and static nat rule for 2nd IP + if value != VPC_NETWORK: + FireWallRule.create(self.apiclient,ipaddressid=public_ip_1.ipaddress.id, + protocol='TCP', cidrlist=[self.services["fwrule"]["cidr"]], + startport=self.services["fwrule"]["startport"],endport=self.services["fwrule"]["endport"]) + + natrule = NATRule.create(self.api_client, virtual_machine, + self.services["natrule"],ipaddressid=public_ip_1.ipaddress.id, + networkid=network.id, vmguestip = ipaddress_1.ipaddress) + + StaticNATRule.enable(self.apiclient, public_ip_2.ipaddress.id, virtual_machine.id, + network.id, vmguestip=ipaddress_2.ipaddress) + + # Delete VM + virtual_machine.delete(self.apiclient) + + # Wait for VMs to expunge + wait_for_cleanup(self.api_client, ["expunge.delay", "expunge.interval"]) + + # Make sure the VM is expunged + retriesCount = 20 + while True: + vms = VirtualMachine.list(self.apiclient, id=virtual_machine.id) + if vms is None: + break + elif retriesCount == 0: + self.fail("Failed to expunge vm even after 20 minutes") + time.sleep(60) + retriesCount -= 1 + + # Try to list nat rule + with self.assertRaises(Exception): + NATRule.list(self.apiclient, id=natrule.id, listall=True) + + # Verify static nat rule is no longer enabled + self.VerifyStaticNatForPublicIp(public_ip_2.ipaddress.id, False) + return + + @data(ISOLATED_NETWORK, SHARED_NETWORK, VPC_NETWORK) + @attr(tags=["advanced"]) + def test_recover_vm(self, value): + """ Test recover VM operation with VM having secondary IPs""" + + # Steps: + # 1. Create Account and create network in it (isoalted/ shared/ vpc) + # 2. Deploy a VM in this network and account + # 3. Add 2 secondary IPs to the default nic of VM + # 4. Acquire 2 public IPs in the network + # 5. For 1st public IP create nat rule to 1st private IP, for 2nd public IP, create + # static nat rule to 2nd private IP + # 6. Destroy the virtual machine and recover it + # 7. Verify that nat and static nat rules exist + + self.account = Account.create(self.apiclient,self.services["account"],domainid=self.domain.id) + self.cleanup.append(self.account) + + network = createNetwork(self, value) + + try: + virtual_machine = VirtualMachine.create(self.apiclient,self.services["virtual_machine"], + networkids=[network.id],serviceofferingid=self.service_offering.id, + accountid=self.account.name,domainid=self.account.domainid) + except Exception as e: + self.fail("vm creation failed: %s" % e) + + try: + ipaddress_1 = NIC.addIp(self.apiclient, id=virtual_machine.nic[0].id) + ipaddress_2 = NIC.addIp(self.apiclient, id=virtual_machine.nic[0].id) + except Exception as e: + self.fail("Failed while adding secondary IP to NIC of vm %s" % virtual_machine.id) + + try: + public_ip_1 = PublicIPAddress.create(self.api_client,accountid=self.account.name, + zoneid=self.zone.id,domainid=self.account.domainid, + networkid=network.id, vpcid = network.vpcid if value == VPC_NETWORK else None) + + public_ip_2 = PublicIPAddress.create(self.api_client,accountid=self.account.name, + zoneid=self.zone.id,domainid=self.account.domainid, + networkid=network.id, vpcid = network.vpcid if value == VPC_NETWORK else None) + except Exception as e: + self.fail("Exception while acquiring public ip address: %s" % e) + + if value != VPC_NETWORK: + FireWallRule.create(self.apiclient,ipaddressid=public_ip_1.ipaddress.id, + protocol='TCP', cidrlist=[self.services["fwrule"]["cidr"]], + startport=self.services["fwrule"]["startport"],endport=self.services["fwrule"]["endport"]) + + natrule = NATRule.create(self.api_client, virtual_machine, + self.services["natrule"],ipaddressid=public_ip_1.ipaddress.id, + networkid=network.id, vmguestip = ipaddress_1.ipaddress) + + StaticNATRule.enable(self.apiclient, public_ip_2.ipaddress.id, virtual_machine.id, + network.id, vmguestip=ipaddress_2.ipaddress) + + virtual_machine.delete(self.apiclient) + virtual_machine.recover(self.apiclient) + + retriesCount = 10 + while True: + vms = VirtualMachine.list(self.apiclient, id=virtual_machine.id) + self.assertEqual(validateList(vms)[0], PASS, "vms list validation failed") + if str(vms[0].state).lower() == "stopped": + break + elif retriesCount == 0: + self.fail("Failed to recover vm even after 10 mins") + time.sleep(60) + retriesCount -= 1 + + natrules = NATRule.list(self.apiclient, id=natrule.id, listall=True) + self.assertEqual(validateList(natrules)[0], PASS, "nat rules validation failed") + + self.VerifyStaticNatForPublicIp(public_ip_2.ipaddress.id, True) + + return + + @data(ISOLATED_NETWORK, SHARED_NETWORK, VPC_NETWORK) + @attr(tags=["advanced"]) + def test_network_restart_cleanup_true(self, value): + """Test network restart (cleanup True) with VM having secondary IPs and related network rules""" + + # Steps: + # 1. Create Account and create network in it (isoalted/ shared/ vpc) + # 2. Deploy a VM in this network and account + # 3. Add 2 secondary IPs to the default nic of VM + # 4. Acquire 2 public IPs in the network + # 5. For 1st public IP create nat rule to 1st private IP, for 2nd public IP, create + # static nat rule to 2nd private IP + # 6. Restart the network with cleanup option True + # 7. Verify that nat and static nat rules exist after network restart + + self.account = Account.create(self.apiclient,self.services["account"],domainid=self.domain.id) + self.cleanup.append(self.account) + + network = createNetwork(self, value) + + try: + virtual_machine = VirtualMachine.create(self.apiclient,self.services["virtual_machine"], + networkids=[network.id],serviceofferingid=self.service_offering.id, + accountid=self.account.name,domainid=self.account.domainid) + except Exception as e: + self.fail("vm creation failed: %s" % e) + + try: + ipaddress_1 = NIC.addIp(self.apiclient, id=virtual_machine.nic[0].id) + ipaddress_2 = NIC.addIp(self.apiclient, id=virtual_machine.nic[0].id) + except Exception as e: + self.fail("Failed while adding secondary IP to NIC of vm %s" % virtual_machine.id) + + try: + public_ip_1 = PublicIPAddress.create(self.api_client,accountid=self.account.name, + zoneid=self.zone.id,domainid=self.account.domainid, + networkid=network.id, vpcid = network.vpcid if value == VPC_NETWORK else None) + + public_ip_2 = PublicIPAddress.create(self.api_client,accountid=self.account.name, + zoneid=self.zone.id,domainid=self.account.domainid, + networkid=network.id, vpcid = network.vpcid if value == VPC_NETWORK else None) + except Exception as e: + self.fail("Exception while acquiring public ip address: %s" % e) + + if value != VPC_NETWORK: + FireWallRule.create(self.apiclient,ipaddressid=public_ip_1.ipaddress.id, + protocol='TCP', cidrlist=[self.services["fwrule"]["cidr"]], + startport=self.services["fwrule"]["startport"],endport=self.services["fwrule"]["endport"]) + + natrule = NATRule.create(self.api_client, virtual_machine, + self.services["natrule"],ipaddressid=public_ip_1.ipaddress.id, + networkid=network.id, vmguestip = ipaddress_1.ipaddress) + + StaticNATRule.enable(self.apiclient, public_ip_2.ipaddress.id, virtual_machine.id, + network.id, vmguestip=ipaddress_2.ipaddress) + + network.restart(self.apiclient, cleanup=True) + + natrulelist = NATRule.list(self.apiclient, id=natrule.id, listall=True) + self.assertEqual(validateList(natrulelist)[0], PASS, "nat rules list validation failed") + + self.VerifyStaticNatForPublicIp(public_ip_2.ipaddress.id, True) + return + + @data(ISOLATED_NETWORK, SHARED_NETWORK, VPC_NETWORK) + @attr(tags=["advanced"]) + def test_network_restart_cleanup_false(self, value): + """Test network restart (cleanup True) with VM having secondary IPs and related network rules""" + + # Steps: + # 1. Create Account and create network in it (isoalted/ shared/ vpc) + # 2. Deploy a VM in this network and account + # 3. Add 2 secondary IPs to the default nic of VM + # 4. Acquire 2 public IPs in the network + # 5. For 1st public IP create nat rule to 1st private IP, for 2nd public IP, create + # static nat rule to 2nd private IP + # 6. Restart the network with cleanup option False + # 7. Verify that nat and static nat rules exist after network restart + + self.account = Account.create(self.apiclient,self.services["account"],domainid=self.domain.id) + self.cleanup.append(self.account) + + network = createNetwork(self, value) + + try: + virtual_machine = VirtualMachine.create(self.apiclient,self.services["virtual_machine"], + networkids=[network.id],serviceofferingid=self.service_offering.id, + accountid=self.account.name,domainid=self.account.domainid) + except Exception as e: + self.fail("vm creation failed: %s" % e) + + try: + ipaddress_1 = NIC.addIp(self.apiclient, id=virtual_machine.nic[0].id) + ipaddress_2 = NIC.addIp(self.apiclient, id=virtual_machine.nic[0].id) + except Exception as e: + self.fail("Failed while adding secondary IP to NIC of vm %s" % virtual_machine.id) + + try: + public_ip_1 = PublicIPAddress.create(self.api_client,accountid=self.account.name, + zoneid=self.zone.id,domainid=self.account.domainid, + networkid=network.id, vpcid = network.vpcid if value == VPC_NETWORK else None) + + public_ip_2 = PublicIPAddress.create(self.api_client,accountid=self.account.name, + zoneid=self.zone.id,domainid=self.account.domainid, + networkid=network.id, vpcid = network.vpcid if value == VPC_NETWORK else None) + except Exception as e: + self.fail("Exception while acquiring public ip address: %s" % e) + + if value != VPC_NETWORK: + FireWallRule.create(self.apiclient,ipaddressid=public_ip_1.ipaddress.id, + protocol='TCP', cidrlist=[self.services["fwrule"]["cidr"]], + startport=self.services["fwrule"]["startport"],endport=self.services["fwrule"]["endport"]) + + natrule = NATRule.create(self.api_client, virtual_machine, + self.services["natrule"],ipaddressid=public_ip_1.ipaddress.id, + networkid=network.id, vmguestip = ipaddress_1.ipaddress) + + StaticNATRule.enable(self.apiclient, public_ip_2.ipaddress.id, virtual_machine.id, + network.id, vmguestip=ipaddress_2.ipaddress) + + network.restart(self.apiclient, cleanup=False) + + natrulelist = NATRule.list(self.apiclient, id=natrule.id, listall=True) + self.assertEqual(validateList(natrulelist)[0], PASS, "nat rules list validation failed") + + self.VerifyStaticNatForPublicIp(public_ip_2.ipaddress.id, True) + return + + @data(ISOLATED_NETWORK, SHARED_NETWORK, VPC_NETWORK) + @attr(tags=["advanced"]) + def test_reboot_router_VM(self, value): + """ Test reboot router and persistence of network rules""" + + # Steps: + # 1. Create Account and create network in it (isoalted/ shared/ vpc) + # 2. Deploy a VM in this network and account + # 3. Add 2 secondary IPs to the default nic of VM + # 4. Acquire 2 public IPs in the network + # 5. For 1st public IP create nat rule to 1st private IP, for 2nd public IP, create + # static nat rule to 2nd private IP + # 6. Reboot router VM + # 7. Verify that nat and static nat rules exist after router restart + + self.account = Account.create(self.apiclient,self.services["account"],domainid=self.domain.id) + self.cleanup.append(self.account) + + network = createNetwork(self, value) + + try: + virtual_machine = VirtualMachine.create(self.apiclient,self.services["virtual_machine"], + networkids=[network.id],serviceofferingid=self.service_offering.id, + accountid=self.account.name,domainid=self.account.domainid) + except Exception as e: + self.fail("vm creation failed: %s" % e) + + try: + ipaddress_1 = NIC.addIp(self.apiclient, id=virtual_machine.nic[0].id) + ipaddress_2 = NIC.addIp(self.apiclient, id=virtual_machine.nic[0].id) + except Exception as e: + self.fail("Failed while adding secondary IP to NIC of vm %s" % virtual_machine.id) + + try: + public_ip_1 = PublicIPAddress.create(self.api_client,accountid=self.account.name, + zoneid=self.zone.id,domainid=self.account.domainid, + networkid=network.id, vpcid = network.vpcid if value == VPC_NETWORK else None) + + public_ip_2 = PublicIPAddress.create(self.api_client,accountid=self.account.name, + zoneid=self.zone.id,domainid=self.account.domainid, + networkid=network.id, vpcid = network.vpcid if value == VPC_NETWORK else None) + except Exception as e: + self.fail("Exception while acquiring public ip address: %s" % e) + + if value != VPC_NETWORK: + FireWallRule.create(self.apiclient,ipaddressid=public_ip_1.ipaddress.id, + protocol='TCP', cidrlist=[self.services["fwrule"]["cidr"]], + startport=self.services["fwrule"]["startport"],endport=self.services["fwrule"]["endport"]) + + natrule = NATRule.create(self.api_client, virtual_machine, + self.services["natrule"],ipaddressid=public_ip_1.ipaddress.id, + networkid=network.id, vmguestip = ipaddress_1.ipaddress) + + StaticNATRule.enable(self.apiclient, public_ip_2.ipaddress.id, virtual_machine.id, + network.id, vmguestip=ipaddress_2.ipaddress) + + routers = Router.list(self.apiclient, networkid=network.id, listall=True) + self.assertEqual(validateList(routers)[0], PASS, "routers list validation failed") + + Router.reboot(self.apiclient, id=routers[0].id) + + natrulelist = NATRule.list(self.apiclient, id=natrule.id, listall=True) + self.assertEqual(validateList(natrulelist)[0], PASS, "nat rules list validation failed") + + self.VerifyStaticNatForPublicIp(public_ip_2.ipaddress.id, True) + return diff --git a/test/integration/component/test_netscaler_configs.py b/test/integration/component/test_netscaler_configs.py index 98c47485e3..6d856094f7 100644 --- a/test/integration/component/test_netscaler_configs.py +++ b/test/integration/component/test_netscaler_configs.py @@ -18,15 +18,28 @@ """ P1 tests for netscaler configurations """ #Import Local Modules -import marvin from nose.plugins.attrib import attr -from marvin.cloudstackTestCase import * -from marvin.cloudstackAPI import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * +from marvin.cloudstackTestCase import cloudstackTestCase +#from marvin.cloudstackAPI import * +from marvin.lib.utils import (cleanup_resources, + random_gen) +from marvin.lib.base import (VirtualMachine, + NetworkServiceProvider, + PublicIPAddress, + Account, + Network, + NetScaler, + LoadBalancerRule, + NetworkOffering, + ServiceOffering, + PhysicalNetwork, + Configurations) +from marvin.lib.common import (get_domain, + get_zone, + get_template, + add_netscaler) from marvin.sshClient import SshClient -import datetime +import time class Services: @@ -156,14 +169,13 @@ class TestAddNetScaler(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestAddNetScaler, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestAddNetScaler, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls._cleanup = [] return @@ -192,7 +204,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags = ["advancedns"]) + @attr(tags=["advancedns", "provisioning"]) def test_add_netscaler_device(self): """Test add netscaler device """ @@ -282,14 +294,13 @@ class TestInvalidParametersNetscaler(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestInvalidParametersNetscaler, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestInvalidParametersNetscaler, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls._cleanup = [] return @@ -318,7 +329,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags = ["advancedns"]) + @attr(tags=["advancedns", "provisioning"]) def test_invalid_cred(self): """Test add netscaler device with invalid credential """ @@ -387,7 +398,7 @@ def test_invalid_cred(self): ) return - @attr(tags = ["advancedns"]) + @attr(tags=["advancedns", "provisioning"]) def test_invalid_public_interface(self): """Test add netscaler device with invalid public interface """ @@ -454,7 +465,7 @@ def test_invalid_public_interface(self): ) return - @attr(tags = ["advancedns"]) + @attr(tags=["advancedns", "provisioning"]) def test_invalid_private_interface(self): """Test add netscaler device with invalid private interface """ @@ -526,14 +537,13 @@ class TestNetScalerDedicated(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestNetScalerDedicated, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestNetScalerDedicated, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, @@ -562,7 +572,7 @@ def setUpClass(cls): netscaler_provider = nw_service_providers[0] if netscaler_provider.state != 'Enabled': - response = NetworkServiceProvider.update( + NetworkServiceProvider.update( cls.api_client, id=netscaler_provider.id, state='Enabled' @@ -624,11 +634,11 @@ def tearDown(self): self.debug("Cleaning up the resources") #Clean up, terminate the created network offerings cleanup_resources(self.apiclient, self.cleanup) - interval = list_configurations( + interval = Configurations.list( self.apiclient, name='network.gc.interval' ) - wait = list_configurations( + wait = Configurations.list( self.apiclient, name='network.gc.wait' ) @@ -749,14 +759,13 @@ class TestNetScalerShared(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestNetScalerShared, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestNetScalerShared, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, @@ -785,7 +794,7 @@ def setUpClass(cls): netscaler_provider = nw_service_providers[0] if netscaler_provider.state != 'Enabled': - response = NetworkServiceProvider.update( + NetworkServiceProvider.update( cls.api_client, id=netscaler_provider.id, state='Enabled' @@ -843,11 +852,11 @@ def tearDown(self): self.debug("Cleaning up the resources") #Clean up, terminate the created network offerings cleanup_resources(self.apiclient, self.cleanup) - interval = list_configurations( + interval = Configurations.list( self.apiclient, name='network.gc.interval' ) - wait = list_configurations( + wait = Configurations.list( self.apiclient, name='network.gc.wait' ) @@ -992,14 +1001,13 @@ class TestNetScalerCustomCapacity(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestNetScalerCustomCapacity, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestNetScalerCustomCapacity, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, @@ -1028,7 +1036,7 @@ def setUpClass(cls): netscaler_provider = nw_service_providers[0] if netscaler_provider.state != 'Enabled': - response = NetworkServiceProvider.update( + NetworkServiceProvider.update( cls.api_client, id=netscaler_provider.id, state='Enabled' @@ -1092,11 +1100,11 @@ def tearDown(self): self.debug("Cleaning up the resources") #Clean up, terminate the created network offerings cleanup_resources(self.apiclient, self.cleanup) - interval = list_configurations( + interval = Configurations.list( self.apiclient, name='network.gc.interval' ) - wait = list_configurations( + wait = Configurations.list( self.apiclient, name='network.gc.wait' ) @@ -1249,7 +1257,7 @@ def test_netscaler_custom_capacity(self): self.debug("Deploying VM in account: %s" % self.account_3.name) with self.assertRaises(Exception): # Spawn an instance in that network - virtual_machine_3 = VirtualMachine.create( + VirtualMachine.create( self.apiclient, self.services["virtual_machine"], accountid=self.account_3.name, @@ -1265,14 +1273,13 @@ class TestNetScalerNoCapacity(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestNetScalerNoCapacity, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestNetScalerNoCapacity, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, @@ -1301,7 +1308,7 @@ def setUpClass(cls): netscaler_provider = nw_service_providers[0] if netscaler_provider.state != 'Enabled': - response = NetworkServiceProvider.update( + NetworkServiceProvider.update( cls.api_client, id=netscaler_provider.id, state='Enabled' @@ -1365,11 +1372,11 @@ def tearDown(self): self.debug("Cleaning up the resources") #Clean up, terminate the created network offerings cleanup_resources(self.apiclient, self.cleanup) - interval = list_configurations( + interval = Configurations.list( self.apiclient, name='network.gc.interval' ) - wait = list_configurations( + wait = Configurations.list( self.apiclient, name='network.gc.wait' ) @@ -1523,7 +1530,7 @@ def test_netscaler_no_capacity(self): self.debug("Deploying VM in account: %s" % self.account_3.name) with self.assertRaises(Exception): # Spawn an instance in that network - virtual_machine_3 = VirtualMachine.create( + VirtualMachine.create( self.apiclient, self.services["virtual_machine"], accountid=self.account_3.name, @@ -1539,14 +1546,13 @@ class TestGuestNetworkWithNetScaler(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestGuestNetworkWithNetScaler, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestGuestNetworkWithNetScaler, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, @@ -1575,7 +1581,7 @@ def setUpClass(cls): netscaler_provider = nw_service_providers[0] if netscaler_provider.state != 'Enabled': - response = NetworkServiceProvider.update( + NetworkServiceProvider.update( cls.api_client, id=netscaler_provider.id, state='Enabled' @@ -1633,11 +1639,11 @@ def tearDown(self): self.debug("Cleaning up the resources") #Clean up, terminate the created network offerings cleanup_resources(self.apiclient, self.cleanup) - interval = list_configurations( + interval = Configurations.list( self.apiclient, name='network.gc.interval' ) - wait = list_configurations( + wait = Configurations.list( self.apiclient, name='network.gc.wait' ) @@ -2037,11 +2043,11 @@ def test_03_delete_account(self): self.debug("Account: %s is deleted!" % self.account_1.name) self.debug("Waiting for network.gc.interval & network.gc.wait..") - interval = list_configurations( + interval = Configurations.list( self.apiclient, name='network.gc.interval' ) - wait = list_configurations( + wait = Configurations.list( self.apiclient, name='network.gc.wait' ) @@ -2096,14 +2102,13 @@ class TestGuestNetworkShutDown(cloudstackTestCase): @classmethod def setUpClass(cls): cls._cleanup = [] - cls.api_client = super( - TestGuestNetworkShutDown, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestGuestNetworkShutDown, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, @@ -2231,15 +2236,18 @@ def test_01_stop_all_vms(self): "Stopping all the VM instances for the account: %s" % self.account.name) - self.vm_1.stop(self.apiclient) - self.vm_2.stop(self.apiclient) + try: + self.vm_1.stop(self.apiclient) + self.vm_2.stop(self.apiclient) + except Exception as e: + self.fail("Failed to stop instance: %s" % e) self.debug("Sleep for network.gc.interval + network.gc.wait") - interval = list_configurations( + interval = Configurations.list( self.apiclient, name='network.gc.interval' ) - wait = list_configurations( + wait = Configurations.list( self.apiclient, name='network.gc.wait' ) @@ -2502,14 +2510,13 @@ class TestServiceProvider(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestServiceProvider, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestServiceProvider, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, @@ -2538,7 +2545,7 @@ def setUpClass(cls): cls.netscaler_provider = nw_service_providers[0] if cls.netscaler_provider.state != 'Enabled': - response = NetworkServiceProvider.update( + NetworkServiceProvider.update( cls.api_client, id=cls.netscaler_provider.id, state='Enabled' @@ -2595,11 +2602,11 @@ def tearDown(self): self.debug("Cleaning up the resources") #Clean up, terminate the created network offerings cleanup_resources(self.apiclient, self.cleanup) - interval = list_configurations( + interval = Configurations.list( self.apiclient, name='network.gc.interval' ) - wait = list_configurations( + wait = Configurations.list( self.apiclient, name='network.gc.wait' ) @@ -2817,14 +2824,13 @@ class TestDeleteNetscaler(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestDeleteNetscaler, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestDeleteNetscaler, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, @@ -2853,7 +2859,7 @@ def setUpClass(cls): netscaler_provider = nw_service_providers[0] if netscaler_provider.state != 'Enabled': - response = NetworkServiceProvider.update( + NetworkServiceProvider.update( cls.api_client, id=netscaler_provider.id, state='Enabled' @@ -2911,11 +2917,11 @@ def tearDown(self): self.debug("Cleaning up the resources") #Clean up, terminate the created network offerings cleanup_resources(self.apiclient, self.cleanup) - interval = list_configurations( + interval = Configurations.list( self.apiclient, name='network.gc.interval' ) - wait = list_configurations( + wait = Configurations.list( self.apiclient, name='network.gc.wait' ) diff --git a/test/integration/component/test_netscaler_lb.py b/test/integration/component/test_netscaler_lb.py index 26df5459b5..4c99aa36d4 100644 --- a/test/integration/component/test_netscaler_lb.py +++ b/test/integration/component/test_netscaler_lb.py @@ -18,15 +18,27 @@ """ P1 tests for netscaler load balancing """ #Import Local Modules -import marvin from nose.plugins.attrib import attr -from marvin.cloudstackTestCase import * -from marvin.cloudstackAPI import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * +from marvin.cloudstackTestCase import cloudstackTestCase +from marvin.cloudstackAPI import migrateVirtualMachine +from marvin.lib.utils import (cleanup_resources, + random_gen) +from marvin.lib.base import (Account, + VirtualMachine, + PublicIPAddress, + LoadBalancerRule, + ServiceOffering, + NetworkOffering, + Host, + Network, + NATRule, + Configurations) +from marvin.lib.common import (get_domain, + get_zone, + get_template, + add_netscaler) from marvin.sshClient import SshClient -import datetime +import time class Services: @@ -150,14 +162,13 @@ class TestLbSourceNat(cloudstackTestCase): @classmethod def setUpClass(cls): cls._cleanup = [] - cls.api_client = super( - TestLbSourceNat, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestLbSourceNat, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, @@ -210,11 +221,11 @@ def tearDown(self): self.debug("Cleaning up the resources") #Clean up, terminate the created network offerings cleanup_resources(self.apiclient, self.cleanup) - interval = list_configurations( + interval = Configurations.list( self.apiclient, name='network.gc.interval' ) - wait = list_configurations( + wait = Configurations.list( self.apiclient, name='network.gc.wait' ) @@ -359,14 +370,13 @@ class TestLbOnIpWithPf(cloudstackTestCase): @classmethod def setUpClass(cls): cls._cleanup = [] - cls.api_client = super( - TestLbOnIpWithPf, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestLbOnIpWithPf, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, @@ -420,11 +430,11 @@ def tearDown(self): self.debug("Cleaning up the resources") #Clean up, terminate the created network offerings cleanup_resources(self.apiclient, self.cleanup) - interval = list_configurations( + interval = Configurations.list( self.apiclient, name='network.gc.interval' ) - wait = list_configurations( + wait = Configurations.list( self.apiclient, name='network.gc.wait' ) @@ -572,14 +582,13 @@ class TestPfOnIpWithLb(cloudstackTestCase): @classmethod def setUpClass(cls): cls._cleanup = [] - cls.api_client = super( - TestPfOnIpWithLb, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestPfOnIpWithLb, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, @@ -633,11 +642,11 @@ def tearDown(self): self.debug("Cleaning up the resources") #Clean up, terminate the created network offerings cleanup_resources(self.apiclient, self.cleanup) - interval = list_configurations( + interval = Configurations.list( self.apiclient, name='network.gc.interval' ) - wait = list_configurations( + wait = Configurations.list( self.apiclient, name='network.gc.wait' ) @@ -774,7 +783,7 @@ def test_pf_on_ip_with_lb(self): with self.assertRaises(Exception): NATRule.create( self.apiclient, - virtual_machine, + virtual_machine_1, self.services["natrule"], ipaddressid=ip_with_lb_rule.ipaddress.id ) @@ -786,14 +795,13 @@ class TestLbOnNonSourceNat(cloudstackTestCase): @classmethod def setUpClass(cls): cls._cleanup = [] - cls.api_client = super( - TestLbOnNonSourceNat, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestLbOnNonSourceNat, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, @@ -847,11 +855,11 @@ def tearDown(self): self.debug("Cleaning up the resources") #Clean up, terminate the created network offerings cleanup_resources(self.apiclient, self.cleanup) - interval = list_configurations( + interval = Configurations.list( self.apiclient, name='network.gc.interval' ) - wait = list_configurations( + wait = Configurations.list( self.apiclient, name='network.gc.wait' ) @@ -1003,14 +1011,13 @@ class TestAddMultipleVmsLb(cloudstackTestCase): @classmethod def setUpClass(cls): cls._cleanup = [] - cls.api_client = super( - TestAddMultipleVmsLb, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestAddMultipleVmsLb, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, @@ -1064,11 +1071,11 @@ def tearDown(self): self.debug("Cleaning up the resources") #Clean up, terminate the created network offerings cleanup_resources(self.apiclient, self.cleanup) - interval = list_configurations( + interval = Configurations.list( self.apiclient, name='network.gc.interval' ) - wait = list_configurations( + wait = Configurations.list( self.apiclient, name='network.gc.wait' ) @@ -1282,14 +1289,13 @@ class TestMultipleLbRules(cloudstackTestCase): @classmethod def setUpClass(cls): cls._cleanup = [] - cls.api_client = super( - TestMultipleLbRules, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestMultipleLbRules, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, @@ -1344,11 +1350,11 @@ def tearDown(self): self.debug("Cleaning up the resources") #Clean up, terminate the created network offerings cleanup_resources(self.apiclient, self.cleanup) - interval = list_configurations( + interval = Configurations.list( self.apiclient, name='network.gc.interval' ) - wait = list_configurations( + wait = Configurations.list( self.apiclient, name='network.gc.wait' ) @@ -1601,14 +1607,13 @@ class TestMultipleLbRulesSameIp(cloudstackTestCase): @classmethod def setUpClass(cls): cls._cleanup = [] - cls.api_client = super( - TestMultipleLbRulesSameIp, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestMultipleLbRulesSameIp, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, @@ -1663,11 +1668,11 @@ def tearDown(self): self.debug("Cleaning up the resources") #Clean up, terminate the created network offerings cleanup_resources(self.apiclient, self.cleanup) - interval = list_configurations( + interval = Configurations.list( self.apiclient, name='network.gc.interval' ) - wait = list_configurations( + wait = Configurations.list( self.apiclient, name='network.gc.wait' ) @@ -1926,14 +1931,13 @@ class TestLoadBalancingRule(cloudstackTestCase): @classmethod def setUpClass(cls): cls._cleanup = [] - cls.api_client = super( - TestLoadBalancingRule, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestLoadBalancingRule, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, @@ -2140,14 +2144,13 @@ class TestDeleteCreateLBRule(cloudstackTestCase): @classmethod def setUpClass(cls): cls._cleanup = [] - cls.api_client = super( - TestDeleteCreateLBRule, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestDeleteCreateLBRule, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, @@ -2255,7 +2258,7 @@ def test_01_create_with_same_public_port(self): self.debug("Create a new LB rule with different public port") self.services["lbrule"]["publicport"] = 23 - lb_rule = LoadBalancerRule.create( + LoadBalancerRule.create( self.apiclient, self.services["lbrule"], ipaddressid=self.public_ip.ipaddress.id, @@ -2269,14 +2272,13 @@ class TestVmWithLb(cloudstackTestCase): @classmethod def setUpClass(cls): cls._cleanup = [] - cls.api_client = super( - TestVmWithLb, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestVmWithLb, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, @@ -2472,18 +2474,11 @@ def test_02_stop_user_vm(self): # 4. In netscaler, LB rules for this VM still remain configured.But # it will be marked as being down - self.debug("Adding instances: %s, %s to LB rule: %s" % ( - self.vm_1.name, - self.vm_2.name, - self.lb_rule_1.name)) - self.lb_rule_1.assign(self.apiclient, [self.vm_1, self.vm_2]) - self.debug("Assigned instances: %s, %s to LB rule: %s" % ( - self.vm_1.name, - self.vm_2.name, - self.lb_rule_1.name)) - self.debug("Stopping VM instance: %s" % self.vm_2.name) - self.vm_2.stop(self.apiclient) - self.debug("Stopped VM: %s" % self.vm_2.name) + try: + self.lb_rule_1.assign(self.apiclient, [self.vm_1, self.vm_2]) + self.vm_2.stop(self.apiclient) + except Exception as e: + self.fail("Exception occured: %s" % e) try: self.debug( @@ -2652,7 +2647,7 @@ def test_04_migrate_user_vm(self): cmd.virtualmachineid = self.vm_2.id self.apiclient.migrateVirtualMachine(cmd) - list_vm_response = list_virtual_machines( + list_vm_response = VirtualMachine.list( self.apiclient, id=self.vm_2.id ) @@ -2862,11 +2857,11 @@ def test_06_destroy_user_vm(self): self.fail("Exception occured during SSH: %s - %s" % ( self.public_ip_1.ipaddress.ipaddress, e)) - delay = list_configurations( + delay = Configurations.list( self.apiclient, name='expunge.delay' ) - wait = list_configurations( + wait = Configurations.list( self.apiclient, name='expunge.interval' ) diff --git a/test/integration/component/test_netscaler_lb_algo.py b/test/integration/component/test_netscaler_lb_algo.py index 3c18fcd36d..6eda9a3f40 100644 --- a/test/integration/component/test_netscaler_lb_algo.py +++ b/test/integration/component/test_netscaler_lb_algo.py @@ -22,11 +22,10 @@ from nose.plugins.attrib import attr from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * +from marvin.lib.utils import * +from marvin.lib.base import * +from marvin.lib.common import * from marvin.sshClient import SshClient -import datetime class Services: @@ -117,14 +116,13 @@ class TestLbWithRoundRobin(cloudstackTestCase): @classmethod def setUpClass(cls): cls._cleanup = [] - cls.api_client = super( - TestLbWithRoundRobin, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestLbWithRoundRobin, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, @@ -330,14 +328,13 @@ class TestLbWithLeastConn(cloudstackTestCase): @classmethod def setUpClass(cls): cls._cleanup = [] - cls.api_client = super( - TestLbWithLeastConn, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestLbWithLeastConn, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, @@ -552,14 +549,13 @@ class TestLbWithSourceIp(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestLbWithSourceIp, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestLbWithSourceIp, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, @@ -768,14 +764,13 @@ class TestLbAlgoRrLc(cloudstackTestCase): @classmethod def setUpClass(cls): cls._cleanup = [] - cls.api_client = super( - TestLbAlgoRrLc, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestLbAlgoRrLc, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, @@ -973,14 +968,13 @@ class TestLbAlgoLcRr(cloudstackTestCase): @classmethod def setUpClass(cls): cls._cleanup = [] - cls.api_client = super( - TestLbAlgoLcRr, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestLbAlgoLcRr, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, @@ -1175,14 +1169,13 @@ class TestLbAlgoRrSb(cloudstackTestCase): @classmethod def setUpClass(cls): cls._cleanup = [] - cls.api_client = super( - TestLbAlgoRrSb, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestLbAlgoRrSb, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, @@ -1380,14 +1373,13 @@ class TestLbAlgoSbRr(cloudstackTestCase): @classmethod def setUpClass(cls): cls._cleanup = [] - cls.api_client = super( - TestLbAlgoSbRr, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestLbAlgoSbRr, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, @@ -1588,14 +1580,13 @@ class TestLbAlgoSbLc(cloudstackTestCase): @classmethod def setUpClass(cls): cls._cleanup = [] - cls.api_client = super( - TestLbAlgoSbLc, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestLbAlgoSbLc, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, @@ -1795,14 +1786,13 @@ class TestLbAlgoLcSb(cloudstackTestCase): @classmethod def setUpClass(cls): cls._cleanup = [] - cls.api_client = super( - TestLbAlgoLcSb, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestLbAlgoLcSb, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, diff --git a/test/integration/component/test_netscaler_lb_sticky.py b/test/integration/component/test_netscaler_lb_sticky.py index 6c27a08052..c333f60c68 100644 --- a/test/integration/component/test_netscaler_lb_sticky.py +++ b/test/integration/component/test_netscaler_lb_sticky.py @@ -22,9 +22,9 @@ from nose.plugins.attrib import attr from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * +from marvin.lib.utils import * +from marvin.lib.base import * +from marvin.lib.common import * from marvin.sshClient import SshClient import datetime @@ -117,14 +117,13 @@ class TestLbStickyPolicy(cloudstackTestCase): @classmethod def setUpClass(cls): cls._cleanup = [] - cls.api_client = super( - TestLbStickyPolicy, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestLbStickyPolicy, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, diff --git a/test/integration/component/test_netscaler_nw_off.py b/test/integration/component/test_netscaler_nw_off.py index 3372612aba..af53eb7677 100644 --- a/test/integration/component/test_netscaler_nw_off.py +++ b/test/integration/component/test_netscaler_nw_off.py @@ -18,15 +18,32 @@ """ P1 tests for multiple netscaler instances """ #Import Local Modules -import marvin from nose.plugins.attrib import attr -from marvin.cloudstackTestCase import * -from marvin.cloudstackAPI import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * -from marvin.sshClient import SshClient -import datetime +from marvin.cloudstackTestCase import cloudstackTestCase +#from marvin.cloudstackAPI import * +from marvin.lib.utils import (cleanup_resources) +from marvin.lib.base import (NATRule, + LoadBalancerRule, + FireWallRule, + PublicIPAddress, + VirtualMachine, + Network, + Account, + NetScaler, + PhysicalNetwork, + NetworkServiceProvider, + NetworkOffering, + Vpn, + Zone, + ServiceOffering, + Configurations + ) +from marvin.lib.common import (get_domain, + get_zone, + get_template, + add_netscaler, + ) +import time class Services: @@ -191,14 +208,13 @@ class TestAddMultipleNetScaler(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestAddMultipleNetScaler, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestAddMultipleNetScaler, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls._cleanup = [] return @@ -227,7 +243,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags = ["advancedns"]) + @attr(tags=["advancedns", "provisioning"]) def test_add_netscaler_device(self): """Test add netscaler device """ @@ -385,7 +401,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags = ["advancedns", "multizone"]) + @attr(tags=["advancedns", "multizone", "provisioning"]) def test_add_mul_netscaler_diff_zone(self): """Test add netscaler devices in different zones """ @@ -506,14 +522,13 @@ class TestNetScalerSharedMode(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestNetScalerSharedMode, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestNetScalerSharedMode, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, @@ -542,7 +557,7 @@ def setUpClass(cls): netscaler_provider = nw_service_providers[0] if netscaler_provider.state != 'Enabled': - response = NetworkServiceProvider.update( + NetworkServiceProvider.update( cls.api_client, id=netscaler_provider.id, state='Enabled' @@ -769,7 +784,7 @@ def test_01_netscaler_shared_mode(self): with self.assertRaises(Exception): # Spawn an instance in that network - virtual_machine_3 = VirtualMachine.create( + VirtualMachine.create( self.apiclient, self.services["virtual_machine"], accountid=self.account_3.name, @@ -957,7 +972,7 @@ def test_03_multiple_netscaler_full_capacilty(self): with self.assertRaises(Exception): # Spawn an instance in that network - virtual_machine_5 = VirtualMachine.create( + VirtualMachine.create( self.apiclient, self.services["virtual_machine"], accountid=self.account_5.name, @@ -985,14 +1000,10 @@ def test_04_delete_account_after_capacity_full(self): self.account_4.delete(self.apiclient) self.debug("Account: %s is deleted" % self.account_4.name) - interval = list_configurations( - self.apiclient, - name='network.gc.interval' - ) - wait = list_configurations( - self.apiclient, - name='network.gc.wait' - ) + interval = Configurations.list(self.apiclient, + name='network.gc.interval') + wait = Configurations.list(self.apiclient, + name='network.gc.wait') self.debug("Sleeping for: network.gc.interval + network.gc.wait") # Sleep to ensure that all resources are deleted time.sleep(int(interval[0].value) + int(wait[0].value)) @@ -1051,14 +1062,13 @@ class TestNwOffDedicatedNetscaler(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestNwOffDedicatedNetscaler, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestNwOffDedicatedNetscaler, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, @@ -1087,7 +1097,7 @@ def setUpClass(cls): netscaler_provider = nw_service_providers[0] if netscaler_provider.state != 'Enabled': - response = NetworkServiceProvider.update( + NetworkServiceProvider.update( cls.api_client, id=netscaler_provider.id, state='Enabled' @@ -1138,11 +1148,11 @@ def tearDown(self): self.debug("Cleaning up the resources") #Clean up, terminate the created network offerings cleanup_resources(self.apiclient, self.cleanup) - interval = list_configurations( + interval = Configurations.list( self.apiclient, name='network.gc.interval' ) - wait = list_configurations( + wait = Configurations.list( self.apiclient, name='network.gc.wait' ) @@ -1217,14 +1227,13 @@ class TestNwOffNetscaler(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestNwOffNetscaler, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestNwOffNetscaler, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, @@ -1260,7 +1269,7 @@ def setUpClass(cls): netscaler_provider = nw_service_providers[0] if netscaler_provider.state != 'Enabled': - response = NetworkServiceProvider.update( + NetworkServiceProvider.update( cls.api_client, id=netscaler_provider.id, state='Enabled' @@ -1330,11 +1339,11 @@ def tearDown(self): self.debug("Cleaning up the resources") #Clean up, terminate the created network offerings cleanup_resources(self.apiclient, self.cleanup) - interval = list_configurations( + interval = Configurations.list( self.apiclient, name='network.gc.interval' ) - wait = list_configurations( + wait = Configurations.list( self.apiclient, name='network.gc.wait' ) @@ -1390,14 +1399,13 @@ def test_ns_shared_nw_dedicated(self): zoneid=self.zone.id ) self.debug("Deploying VM in account: %s" % self.account_1.name) - virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account_1.name, - domainid=self.account_1.domainid, - serviceofferingid=self.service_offering.id, - networkids=[str(self.network.id)] - ) + VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account_1.name, + domainid=self.account_1.domainid, + serviceofferingid=self.service_offering.id, + networkids=[str(self.network.id)]) # Creating network using the network offering created self.debug("Creating different network with network offering: %s" % self.network_offering.id) @@ -1425,14 +1433,12 @@ def test_ns_shared_nw_dedicated(self): self.debug("Deleting account: %s" % self.account_1.name) self.account_1.delete(self.apiclient) self.debug("Account: %s deleted!" % self.account_1.name) - interval = list_configurations( + interval = Configurations.list( self.apiclient, name='network.gc.interval' ) - wait = list_configurations( - self.apiclient, - name='network.gc.wait' - ) + wait = Configurations.list(self.apiclient, + name='network.gc.wait') self.debug("Sleeping for: network.gc.interval + network.gc.wait") # Sleep to ensure that all resources are deleted time.sleep(int(interval[0].value) + int(wait[0].value)) @@ -1525,14 +1531,13 @@ class TestNwOffSToDUpgrade(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestNwOffSToDUpgrade, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestNwOffSToDUpgrade, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, @@ -1569,7 +1574,7 @@ def setUpClass(cls): netscaler_provider = nw_service_providers[0] if netscaler_provider.state != 'Enabled': - response = NetworkServiceProvider.update( + NetworkServiceProvider.update( cls.api_client, id=netscaler_provider.id, state='Enabled' @@ -1639,11 +1644,11 @@ def tearDown(self): self.debug("Cleaning up the resources") #Clean up, terminate the created network offerings cleanup_resources(self.apiclient, self.cleanup) - interval = list_configurations( + interval = Configurations.list( self.apiclient, name='network.gc.interval' ) - wait = list_configurations( + wait = Configurations.list( self.apiclient, name='network.gc.wait' ) @@ -1828,29 +1833,6 @@ def test_shared_to_dedicated_upgrade(self): self.account_1.name) virtual_machine_1.stop(self.apiclient) - list_vm_response = VirtualMachine.list( - self.apiclient, - id=virtual_machine_1.id - ) - - self.debug( - "Verify listVirtualMachines response for virtual machine: %s" \ - % virtual_machine_1.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, - "Stopped", - "VM state should be running after deployment" - ) - self.debug("All Vms are in stopped state") self.debug("Upgrading the network: %s" % self.network_1.id) self.network_1.update( self.apiclient, @@ -1922,7 +1904,7 @@ def test_shared_to_dedicated_upgrade(self): "Creating LB rule for IP address: %s with round robin algo" % public_ip.ipaddress.ipaddress) - lb_rule = LoadBalancerRule.create( + LoadBalancerRule.create( self.apiclient, self.services["lbrule"], ipaddressid=public_ip.ipaddress.id, @@ -1940,14 +1922,13 @@ class TestNwOffDToSUpgrade(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestNwOffDToSUpgrade, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestNwOffDToSUpgrade, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, @@ -1984,7 +1965,7 @@ def setUpClass(cls): netscaler_provider = nw_service_providers[0] if netscaler_provider.state != 'Enabled': - response = NetworkServiceProvider.update( + NetworkServiceProvider.update( cls.api_client, id=netscaler_provider.id, state='Enabled' @@ -2054,11 +2035,11 @@ def tearDown(self): self.debug("Cleaning up the resources") #Clean up, terminate the created network offerings cleanup_resources(self.apiclient, self.cleanup) - interval = list_configurations( + interval = Configurations.list( self.apiclient, name='network.gc.interval' ) - wait = list_configurations( + wait = Configurations.list( self.apiclient, name='network.gc.wait' ) @@ -2233,29 +2214,6 @@ def test_shared_to_dedicated_upgrade(self): self.debug("Stopping all VMs in account: %s" % self.account_3.name) virtual_machine_3.stop(self.apiclient) - list_vm_response = VirtualMachine.list( - self.apiclient, - id=virtual_machine_3.id - ) - - self.debug( - "Verify listVirtualMachines response for virtual machine: %s" \ - % virtual_machine_3.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, - "Stopped", - "VM state should be stopped" - ) - self.debug("All user VMs stopped") self.debug("Upgrading the network: %s" % self.network_3.id) self.network_3.update( self.apiclient, @@ -2324,7 +2282,7 @@ def test_shared_to_dedicated_upgrade(self): "Creating LB rule for IP address: %s with round robin algo" % public_ip.ipaddress.ipaddress) - lb_rule = LoadBalancerRule.create( + LoadBalancerRule.create( self.apiclient, self.services["lbrule"], ipaddressid=public_ip.ipaddress.id, @@ -2341,15 +2299,13 @@ class TestNOWithNetscaler(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestNOWithNetscaler, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestNOWithNetscaler, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + 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, @@ -2944,7 +2900,7 @@ def test_02_net_off_conserve_mode_ns(self): # User should be able to enable VPN on source NAT self.debug("Created VPN with source NAT IP: %s" % src_nat.ipaddress) # Assign VPN to source NAT - vpn = Vpn.create( + Vpn.create( self.apiclient, src_nat.id, account=self.account.name, diff --git a/test/integration/component/test_network_offering.py b/test/integration/component/test_network_offering.py index 33c4305933..f2251ff873 100644 --- a/test/integration/component/test_network_offering.py +++ b/test/integration/component/test_network_offering.py @@ -18,14 +18,23 @@ """ P1 tests for network offering """ #Import Local Modules -import marvin from nose.plugins.attrib import attr -from marvin.cloudstackTestCase import * -from marvin.cloudstackAPI import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * -import datetime +from marvin.cloudstackTestCase import cloudstackTestCase +#from marvin.cloudstackAPI import * +from marvin.lib.utils import (cleanup_resources) +from marvin.lib.base import (VirtualMachine, + Account, + Network, + LoadBalancerRule, + PublicIPAddress, + FireWallRule, + NATRule, + Vpn, + ServiceOffering, + NetworkOffering) +from marvin.lib.common import (get_domain, + get_zone, + get_template) class Services: @@ -160,14 +169,13 @@ class TestNOVirtualRouter(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestNOVirtualRouter, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestNOVirtualRouter, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + 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, @@ -215,7 +223,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags = ["advanced"]) + @attr(tags=["advanced", "selfservice"]) def test_01_network_off_without_conserve_mode(self): """Test Network offering with Conserve mode off and VR - All services """ @@ -460,7 +468,7 @@ def test_01_network_off_without_conserve_mode(self): ) return - @attr(tags = ["advanced"]) + @attr(tags=["advanced", "selfservice"]) def test_02_network_off_with_conserve_mode(self): """Test Network offering with Conserve mode ON and VR - All services """ @@ -701,7 +709,7 @@ def test_02_network_off_with_conserve_mode(self): # User should be able to enable VPN on source NAT self.debug("Created VPN with source NAT IP: %s" % src_nat.ipaddress) # Assign VPN to source NAT - vpn = Vpn.create( + Vpn.create( self.apiclient, src_nat.id, account=self.account.name, @@ -733,14 +741,13 @@ class TestNetworkUpgrade(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestNetworkUpgrade, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestNetworkUpgrade, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + 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, @@ -798,7 +805,7 @@ def tearDown(self): return @attr(speed = "slow") - @attr(tags = ["advancedns"]) + @attr(tags=["advancedns", "provisioning"]) def test_01_nwupgrade_netscaler_conserve_on(self): """Test Nw upgrade to netscaler lb service and conserve mode ON """ @@ -944,7 +951,7 @@ def test_01_nwupgrade_netscaler_conserve_on(self): # Assign VPN to source NAT self.debug("Enabling VPN on source NAT") - vpn = Vpn.create( + Vpn.create( self.apiclient, src_nat.id, account=self.account.name, @@ -998,7 +1005,7 @@ def test_01_nwupgrade_netscaler_conserve_on(self): return @attr(speed = "slow") - @attr(tags = ["advancedns"]) + @attr(tags=["advancedns", "provisioning"]) def test_02_nwupgrade_netscaler_conserve_off(self): """Test Nw upgrade to netscaler lb service and conserve mode OFF """ @@ -1144,7 +1151,7 @@ def test_02_nwupgrade_netscaler_conserve_off(self): # Assign VPN to source NAT self.debug("Enabling VPN on source NAT") - vpn = Vpn.create( + Vpn.create( self.apiclient, src_nat.id, account=self.account.name, @@ -1181,14 +1188,13 @@ def test_02_nwupgrade_netscaler_conserve_off(self): class TestNOWithOnlySourceNAT(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.apiclient = super( - TestNOWithOnlySourceNAT, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestNOWithOnlySourceNAT, cls).getClsTestClient() + cls.apiclient = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.apiclient, cls.services) - cls.zone = get_zone(cls.apiclient, cls.services) + cls.domain = get_domain(cls.apiclient) + cls.zone = get_zone(cls.apiclient, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype cls.template = get_template( cls.apiclient, @@ -1218,7 +1224,7 @@ def tearDownClass(cls): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags=["advanced", "advancedns"]) + @attr(tags=["advanced", "advancedns", "selfservice"]) def test_create_network_with_snat(self): """Test to create a network with SourceNAT service only""" @@ -1265,7 +1271,7 @@ def test_create_network_with_snat(self): self.debug("Deploying VM in account: %s on the network %s" % (self.account.name, self.network.id)) # Spawn an instance in that network - virtual_machine = VirtualMachine.create( + VirtualMachine.create( self.apiclient, self.services["virtual_machine"], accountid=self.account.name, diff --git a/test/integration/component/test_non_contiguous_vlan.py b/test/integration/component/test_non_contiguous_vlan.py index 3ebaf3a97e..4609af95f1 100644 --- a/test/integration/component/test_non_contiguous_vlan.py +++ b/test/integration/component/test_non_contiguous_vlan.py @@ -28,17 +28,17 @@ from marvin.cloudstackTestCase import (cloudstackTestCase,unittest) -from marvin.integration.lib.base import (Account, +from marvin.lib.base import (Account, ServiceOffering, PhysicalNetwork, VirtualMachine, ) -from marvin.integration.lib.common import (get_zone, +from marvin.lib.common import (get_zone, get_pod, get_domain, get_template, setNonContiguousVlanIds) -from marvin.integration.lib.utils import (cleanup_resources, +from marvin.lib.utils import (cleanup_resources, xsplit) from nose.plugins.attrib import attr @@ -47,7 +47,7 @@ class Services(): def __init__(self): self.services = { - "vlan": { + "vlan_nc": { "partial_range": ["",""], "full_range": "", }, @@ -89,12 +89,14 @@ class TestNonContiguousVLANRanges(cloudstackTestCase): """ @classmethod def setUpClass(cls): - cls.api_client = super(TestNonContiguousVLANRanges, cls).getClsTestClient().getApiClient() + cls.testClient = super(TestNonContiguousVLANRanges, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services - # Get Zone, pod, domain - cls.zone = get_zone(cls.api_client, cls.services) - cls.pod = get_pod(cls.api_client, cls.zone.id, cls.services) - cls.domain = get_domain(cls.api_client, cls.services) + # Get Zone, Domain and templates + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) + cls.pod = get_pod(cls.api_client, cls.zone.id) + cls.domain = get_domain(cls.api_client) cls.service_offering = ServiceOffering.create( cls.api_client, @@ -123,7 +125,7 @@ def tearDownClass(cls): def setUp(self): self.apiclient = self.testClient.getApiClient() - self.vlan = self.services["vlan"] + self.vlan = self.services["vlan_nc"] self.apiClient = self.testClient.getApiClient() self.physicalnetwork, self.vlan = setNonContiguousVlanIds(self.apiclient, self.zone.id) diff --git a/test/integration/component/test_persistent_networks.py b/test/integration/component/test_persistent_networks.py index 8c1d54d192..d848f2a56c 100644 --- a/test/integration/component/test_persistent_networks.py +++ b/test/integration/component/test_persistent_networks.py @@ -14,64 +14,56 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -""" Tests for Persistent Networks without running VMs feature - - Test Plan: https://cwiki.apache.org/confluence/display/CLOUDSTACK/Persistent+Networks+without+a+running+VM - - Issue Link: https://issues.apache.org/jira/browse/CLOUDSTACK-2232 - - Feature Specifications: https://cwiki.apache.org/confluence/display/CLOUDSTACK/FS+-+Persistent+Networks -""" -from marvin.cloudstackTestCase import cloudstackTestCase, unittest -from marvin.integration.lib.utils import (cleanup_resources, - validateList, - get_hypervisor_type) -from marvin.integration.lib.base import (Account, - ServiceOffering, - NetworkOffering, - Network, - VirtualMachine, - PublicIPAddress, - FireWallRule, - Router, - Host, - NATRule, - Project, - LoadBalancerRule, - VpcOffering, - VPC, - Domain, - StaticNATRule, - NetworkACL) -from marvin.integration.lib.common import (get_domain, - get_zone, - get_template, - wait_for_cleanup, - add_netscaler, - verifyNetworkState) - +""" Tests for Persistent Networks without running VMs feature""" +from marvin.lib.utils import (cleanup_resources, + validateList, + get_hypervisor_type) +from marvin.lib.base import (Account, + VPC, + VirtualMachine, + LoadBalancerRule, + Network, + Domain, + Router, + NetworkACL, + PublicIPAddress, + VpcOffering, + ServiceOffering, + Project, + NetworkOffering, + NATRule, + FireWallRule, + Host, + StaticNATRule) +from marvin.lib.common import (get_domain, + get_zone, + get_template, + verifyNetworkState, + add_netscaler, + wait_for_cleanup) from nose.plugins.attrib import attr -from marvin.codes import PASS, FAIL +from marvin.codes import PASS, FAIL, FAILED from marvin.sshClient import SshClient +from marvin.cloudstackTestCase import cloudstackTestCase, unittest from ddt import ddt, data import time @ddt class TestPersistentNetworks(cloudstackTestCase): - """Test Persistent Networks without running VMs - """ - + ''' + Test Persistent Networks without running VMs + ''' @classmethod def setUpClass(cls): - cloudstackTestClient = super(TestPersistentNetworks,cls).getClsTestClient() - cls.api_client = cloudstackTestClient.getApiClient() + cls.testClient = super(TestPersistentNetworks, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() # Fill services from the external config file - cls.services = cloudstackTestClient.getConfigParser().parsedDict + cls.services = cls.testClient.getParsedTestDataConfig() # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, @@ -190,8 +182,8 @@ def verifyVmExpungement(self, virtual_machine): retriesCount -= 1 # end while - if not isVmExpunged: - self.fail("Failed to expunge vm even after 20 minutes") + if not isVmExpunged: + self.fail("Failed to expunge vm even after 20 minutes") return def setUp(self): @@ -209,7 +201,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags=["advanced"]) + @attr(tags=["advanced", "selfservice"]) def test_network_state_after_destroying_vms(self): # steps # 1. Create an isolated persistent network @@ -227,7 +219,13 @@ def test_network_state_after_destroying_vms(self): accountid=self.account.name,domainid=self.domain.id, zoneid=self.zone.id) self.cleanup.append(network) - verifyNetworkState(self.apiclient, network.id, "implemented") + response = verifyNetworkState(self.apiclient, network.id, "implemented") + exceptionOccured = response[0] + isNetworkInDesiredState = response[1] + exceptionMessage = response[2] + + if (exceptionOccured or (not isNetworkInDesiredState)): + self.fail(exceptionMessage) self.assertIsNotNone(network.vlan, "vlan must not be null for persistent network") try: @@ -246,9 +244,15 @@ def test_network_state_after_destroying_vms(self): wait_for_cleanup(self.api_client, ["network.gc.interval", "network.gc.wait"]) verifyNetworkState(self.api_client, network.id, "implemented") + exceptionOccured = response[0] + isNetworkInDesiredState = response[1] + exceptionMessage = response[2] + + if (exceptionOccured or (not isNetworkInDesiredState)): + self.fail(exceptionMessage) return - @attr(tags=["advanced"]) + @attr(tags=["advanced", "selfservice"]) def test_shared_network_offering_with_persistent(self): # steps # 1. create shared network offering with persistent field enabled @@ -333,7 +337,13 @@ def test_upgrade_to_persistent_services_VR(self, value): networkofferingid=networkOffering.id, accountid=account.name,domainid=self.domain.id, zoneid=self.zone.id) - verifyNetworkState(self.api_client, isolated_network.id, "allocated") + response = verifyNetworkState(self.api_client, isolated_network.id, "allocated") + exceptionOccured = response[0] + isNetworkInDesiredState = response[1] + exceptionMessage = response[2] + + if (exceptionOccured or (not isNetworkInDesiredState)): + self.fail(exceptionMessage) # Update the network with persistent network offering isolated_network.update(self.apiclient, networkofferingid=self.isolated_persistent_network_offering.id, changecidr=changecidr) @@ -377,7 +387,13 @@ def test_upgrade_to_persistent_services_VR(self, value): wait_for_cleanup(self.api_client, ["network.gc.interval", "network.gc.wait"]) # Check network state now, this will bolster that network updation has taken effect - verifyNetworkState(self.api_client, isolated_network.id, "implemented") + response = verifyNetworkState(self.api_client, isolated_network.id, "implemented") + exceptionOccured = response[0] + isNetworkInDesiredState = response[1] + exceptionMessage = response[2] + + if (exceptionOccured or (not isNetworkInDesiredState)): + self.fail(exceptionMessage) return @attr(tags=["advanced"]) @@ -402,7 +418,13 @@ def test_upgrade_network_VR_to_PersistentRVR(self): networkofferingid=self.isolated_network_offering.id, accountid=account.name,domainid=self.domain.id, zoneid=self.zone.id) - verifyNetworkState(self.api_client, isolated_network.id, "allocated") + response = verifyNetworkState(self.api_client, isolated_network.id, "allocated") + exceptionOccured = response[0] + isNetworkInDesiredState = response[1] + exceptionMessage = response[2] + + if (exceptionOccured or (not isNetworkInDesiredState)): + self.fail(exceptionMessage) # Update network with network offering which has RVR isolated_network.update(self.apiclient, networkofferingid=self.isolated_persistent_network_offering_RVR.id) @@ -444,7 +466,13 @@ def test_upgrade_network_VR_to_PersistentRVR(self): wait_for_cleanup(self.api_client, ["network.gc.interval", "network.gc.wait"]) # Check network state now, this will bolster that network updation has taken effect - verifyNetworkState(self.api_client, isolated_network.id, "implemented") + response = verifyNetworkState(self.api_client, isolated_network.id, "implemented") + exceptionOccured = response[0] + isNetworkInDesiredState = response[1] + exceptionMessage = response[2] + + if (exceptionOccured or (not isNetworkInDesiredState)): + self.fail(exceptionMessage) return @attr(tags=["advanced", "advancedns"]) @@ -475,7 +503,13 @@ def test_upgrade_network_NS_to_persistent_NS(self): networkofferingid=self.isolated_network_offering_netscaler.id, accountid=account.name,domainid=self.domain.id, zoneid=self.zone.id) - verifyNetworkState(self.api_client, isolated_network.id, "allocated") + response = verifyNetworkState(self.api_client, isolated_network.id, "allocated") + exceptionOccured = response[0] + isNetworkInDesiredState = response[1] + exceptionMessage = response[2] + + if (exceptionOccured or (not isNetworkInDesiredState)): + self.fail(exceptionMessage) isolated_network.update(self.apiclient, networkofferingid=self.isolated_persistent_network_offering_netscaler.id, changecidr=True) @@ -515,7 +549,13 @@ def test_upgrade_network_NS_to_persistent_NS(self): wait_for_cleanup(self.api_client, ["network.gc.interval", "network.gc.wait"]) # Check network state now, this will bolster that network updation has taken effect - verifyNetworkState(self.api_client, isolated_network.id, "implemented") + response = verifyNetworkState(self.api_client, isolated_network.id, "implemented") + exceptionOccured = response[0] + isNetworkInDesiredState = response[1] + exceptionMessage = response[2] + + if (exceptionOccured or (not isNetworkInDesiredState)): + self.fail(exceptionMessage) return @data("LB-VR","LB-Netscaler") @@ -888,7 +928,13 @@ def test_change_persistent_network_to_non_persistent(self): wait_for_cleanup(self.api_client, ["network.gc.interval", "network.gc.wait"]) # Check network state now, this will bolster that network updation has taken effect - verifyNetworkState(self.api_client, network.id, "allocated") + response = verifyNetworkState(self.api_client, network.id, "allocated") + exceptionOccured = response[0] + isNetworkInDesiredState = response[1] + exceptionMessage = response[2] + + if (exceptionOccured or (not isNetworkInDesiredState)): + self.fail(exceptionMessage) return @attr(tags=["advanced"]) @@ -951,20 +997,22 @@ class TestAssignVirtualMachine(cloudstackTestCase): @classmethod def setUpClass(cls): - cloudstackTestClient = super(TestAssignVirtualMachine,cls).getClsTestClient() - cls.api_client = cloudstackTestClient.getApiClient() + cls.testClient = super(TestAssignVirtualMachine, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() # Fill services from the external config file - cls.services = cloudstackTestClient.getConfigParser().parsedDict + cls.services = cls.testClient.getParsedTestDataConfig() # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, cls.services["ostype"] ) + if cls.template == FAILED: + assert False, "get_template() failed to return template" cls.services["virtual_machine"]["zoneid"] = cls.zone.id cls.services["virtual_machine"]["template"] = cls.template.id cls.service_offering = ServiceOffering.create( @@ -1070,7 +1118,13 @@ def test_assign_vm_different_account_VR(self, value): networkofferingid=network_offering.id, accountid=account_1.name,domainid=self.domain.id, zoneid=self.zone.id) - verifyNetworkState(self.api_client, network.id, "implemented") + response = verifyNetworkState(self.api_client, network.id, "implemented") + exceptionOccured = response[0] + isNetworkInDesiredState = response[1] + exceptionMessage = response[2] + + if (exceptionOccured or (not isNetworkInDesiredState)): + self.fail(exceptionMessage) self.assertIsNotNone(network.vlan, "vlan must not be null for persistent network") try: @@ -1078,24 +1132,20 @@ def test_assign_vm_different_account_VR(self, value): networkids=[network.id], serviceofferingid=self.service_offering.id, accountid=account_1.name,domainid=self.domain.id) - except Exception as e: - self.fail("vm creation failed: %s" % e) - virtual_machine.stop(self.apiclient) + virtual_machine.stop(self.apiclient) - vms = VirtualMachine.list(self.apiclient, id=virtual_machine.id) - self.assertEqual(validateList(vms)[0], PASS, "vm list validation failed, vm list is %s" % vms) - self.assertEqual(str(vms[0].state).lower(), "stopped", "vm state should be stopped, it is %s" % vms[0].state) + # Assign virtual machine to different account + virtual_machine.assign_virtual_machine(self.apiclient, account=account_2.name, domainid=self.domain.id) - # Assign virtual machine to different account - virtual_machine.assign_virtual_machine(self.apiclient, account=account_2.name, domainid=self.domain.id) + # Start VM + virtual_machine.start(self.apiclient) - # Start VM - virtual_machine.start(self.apiclient) - - # Verify that new network is created in other account - networks = Network.list(self.apiclient, account=account_2.name, domainid = account_2.domainid) - self.assertEqual(validateList(networks)[0], PASS, "networks list validation failed, list is %s" % networks) + # Verify that new network is created in other account + networks = Network.list(self.apiclient, account=account_2.name, domainid = account_2.domainid) + self.assertEqual(validateList(networks)[0], PASS, "networks list validation failed, list is %s" % networks) + except Exception as e: + self.fail("Exception occured: %s" % e) return @ddt @@ -1105,20 +1155,22 @@ class TestProjectAccountOperations(cloudstackTestCase): @classmethod def setUpClass(cls): - cloudstackTestClient = super(TestProjectAccountOperations,cls).getClsTestClient() - cls.api_client = cloudstackTestClient.getApiClient() + cls.testClient = super(TestProjectAccountOperations, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() # Fill services from the external config file - cls.services = cloudstackTestClient.getConfigParser().parsedDict + cls.services = cls.testClient.getParsedTestDataConfig() # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, cls.services["ostype"] ) + if cls.template == FAILED: + assert False, "get_template() failed to return template" cls.services["virtual_machine"]["zoneid"] = cls.zone.id cls.services["virtual_machine"]["template"] = cls.template.id cls.service_offering = ServiceOffering.create( @@ -1181,7 +1233,13 @@ def test_account_operations(self, value): networkofferingid=self.isolated_persistent_network_offering.id, accountid=account.name,domainid=self.domain.id, zoneid=self.zone.id) - verifyNetworkState(self.api_client, network.id, "implemented") + response = verifyNetworkState(self.api_client, network.id, "implemented") + exceptionOccured = response[0] + isNetworkInDesiredState = response[1] + exceptionMessage = response[2] + + if (exceptionOccured or (not isNetworkInDesiredState)): + self.fail(exceptionMessage) self.assertIsNotNone(network.vlan, "vlan must not be null for persistent network") if value == "disabled": @@ -1199,7 +1257,13 @@ def test_account_operations(self, value): networks = Network.list(self.apiclient, account=account.name, domainid = account.domainid) self.assertEqual(validateList(networks)[0], PASS, "networks list validation failed, list is %s" % networks) - verifyNetworkState(self.api_client, networks[0].id, "implemented") + response = verifyNetworkState(self.api_client, networks[0].id, "implemented") + exceptionOccured = response[0] + isNetworkInDesiredState = response[1] + exceptionMessage = response[2] + + if (exceptionOccured or (not isNetworkInDesiredState)): + self.fail(exceptionMessage) self.assertIsNotNone(networks[0].vlan, "vlan must not be null for persistent network") return @@ -1250,7 +1314,13 @@ def test_project_operations(self): # Wait for network cleanup interval wait_for_cleanup(self.api_client, ["network.gc.interval", "network.gc.wait"]) - verifyNetworkState(self.apiclient, network.id, "implemented") + response = verifyNetworkState(self.apiclient, network.id, "implemented") + exceptionOccured = response[0] + isNetworkInDesiredState = response[1] + exceptionMessage = response[2] + + if (exceptionOccured or (not isNetworkInDesiredState)): + self.fail(exceptionMessage) return @ddt @@ -1260,20 +1330,22 @@ class TestRestartPersistentNetwork(cloudstackTestCase): @classmethod def setUpClass(cls): - cloudstackTestClient = super(TestRestartPersistentNetwork,cls).getClsTestClient() - cls.api_client = cloudstackTestClient.getApiClient() + cls.testClient = super(TestRestartPersistentNetwork, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() # Fill services from the external config file - cls.services = cloudstackTestClient.getConfigParser().parsedDict + cls.services = cls.testClient.getParsedTestDataConfig() # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, cls.services["ostype"] ) + if cls.template == FAILED: + assert False, "get_template() failed to return template" cls.services["virtual_machine"]["zoneid"] = cls.zone.id cls.services["virtual_machine"]["template"] = cls.template.id cls.service_offering = ServiceOffering.create( @@ -1384,7 +1456,13 @@ def test_cleanup_persistent_network(self, value): networkofferingid=self.isolated_persistent_network_offering.id, accountid=account.name,domainid=self.domain.id, zoneid=self.zone.id) - verifyNetworkState(self.apiclient, isolated_persistent_network.id, "implemented") + response = verifyNetworkState(self.apiclient, isolated_persistent_network.id, "implemented") + exceptionOccured = response[0] + isNetworkInDesiredState = response[1] + exceptionMessage = response[2] + + if (exceptionOccured or (not isNetworkInDesiredState)): + self.fail(exceptionMessage) self.assertIsNotNone(isolated_persistent_network.vlan, "vlan must not be null for persistent network") self.debug("Listing routers for network: %s" % isolated_persistent_network.name) @@ -1419,6 +1497,12 @@ def test_cleanup_persistent_network(self, value): self.assertEqual(validateList(networks)[0], PASS, "networks list validation failed, list is %s" % networks) verifyNetworkState(self.apiclient, networks[0].id, "implemented") + exceptionOccured = response[0] + isNetworkInDesiredState = response[1] + exceptionMessage = response[2] + + if (exceptionOccured or (not isNetworkInDesiredState)): + self.fail(exceptionMessage) self.assertIsNotNone(networks[0].vlan, "vlan must not be null for persistent network") # Deploy VM @@ -1459,7 +1543,13 @@ def test_cleanup_persistent_network_lb_netscaler(self, value): networkofferingid=self.isolated_persistent_network_offering_netscaler.id, accountid=account.name,domainid=self.domain.id, zoneid=self.zone.id) - verifyNetworkState(self.apiclient, isolated_persistent_network.id, "implemented") + response = verifyNetworkState(self.apiclient, isolated_persistent_network.id, "implemented") + exceptionOccured = response[0] + isNetworkInDesiredState = response[1] + exceptionMessage = response[2] + + if (exceptionOccured or (not isNetworkInDesiredState)): + self.fail(exceptionMessage) self.assertIsNotNone(isolated_persistent_network.vlan, "vlan must not be null for persistent network") self.debug("Listing routers for network: %s" % isolated_persistent_network.name) @@ -1489,7 +1579,13 @@ def test_cleanup_persistent_network_lb_netscaler(self, value): networks = Network.list(self.apiclient, account=account.name, domainid = account.domainid) self.assertEqual(validateList(networks)[0], PASS, "networks list validation failed, list is %s" % networks) - verifyNetworkState(self.apiclient, networks[0].id, "implemented") + response = verifyNetworkState(self.apiclient, networks[0].id, "implemented") + exceptionOccured = response[0] + isNetworkInDesiredState = response[1] + exceptionMessage = response[2] + + if (exceptionOccured or (not isNetworkInDesiredState)): + self.fail(exceptionMessage) self.assertIsNotNone(networks[0].vlan, "vlan must not be null for persistent network") # Deploy VM @@ -1516,25 +1612,28 @@ class TestVPCNetworkOperations(cloudstackTestCase): @classmethod def setUpClass(cls): - cloudstackTestClient = super(TestVPCNetworkOperations,cls).getClsTestClient() - cls.api_client = cloudstackTestClient.getApiClient() + cls.testClient = super(TestVPCNetworkOperations, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() # Fill services from the external config file - cls.services = cloudstackTestClient.getConfigParser().parsedDict + cls.services = cls.testClient.getParsedTestDataConfig() # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, cls.services["ostype"] ) + if cls.template == FAILED: + assert False, "get_template() failed to return template" + cls.services["virtual_machine"]["zoneid"] = cls.zone.id cls.services["virtual_machine"]["template"] = cls.template.id cls.service_offering = ServiceOffering.create( cls.api_client, - cls.services["service_offering"] + cls.services["service_offerings"]["small"] ) cls.persistent_network_offering_NoLB = NetworkOffering.create(cls.api_client, cls.services["nw_off_persistent_VPCVR_NoLB"], conservemode=False) @@ -1688,21 +1787,45 @@ def test_vpc_network_life_cycle(self, value): networkofferingid=self.persistent_network_offering_NoLB.id, accountid=account.name,domainid=self.domain.id, zoneid=self.zone.id, vpcid=vpc.id, gateway="10.1.1.1", netmask="255.255.255.0") - verifyNetworkState(self.apiclient, persistent_network_1.id, "implemented") + response = verifyNetworkState(self.apiclient, persistent_network_1.id, "implemented") + exceptionOccured = response[0] + isNetworkInDesiredState = response[1] + exceptionMessage = response[2] + + if (exceptionOccured or (not isNetworkInDesiredState)): + self.fail(exceptionMessage) self.assertIsNotNone(persistent_network_1.vlan, "vlan must not be null for persistent network %s" % persistent_network_1.id) persistent_network_2 = Network.create(self.api_client,self.services["isolated_network"], networkofferingid=self.persistent_network_offering_NoLB.id, accountid=account.name,domainid=self.domain.id, zoneid=self.zone.id, vpcid=vpc.id, gateway="10.1.2.1", netmask="255.255.255.0") - verifyNetworkState(self.apiclient, persistent_network_2.id, "implemented") + response = verifyNetworkState(self.apiclient, persistent_network_2.id, "implemented") + exceptionOccured = response[0] + isNetworkInDesiredState = response[1] + exceptionMessage = response[2] + + if (exceptionOccured or (not isNetworkInDesiredState)): + self.fail(exceptionMessage) self.assertIsNotNone(persistent_network_2.vlan, "vlan must not be null for persistent network: %s" % persistent_network_2.id) if value == "restart": # Restart VPC vpc.restart(self.apiclient) - verifyNetworkState(self.apiclient, persistent_network_1.id, "implemented") - verifyNetworkState(self.apiclient, persistent_network_2.id, "implemented") + response = verifyNetworkState(self.apiclient, persistent_network_1.id, "implemented") + exceptionOccured = response[0] + isNetworkInDesiredState = response[1] + exceptionMessage = response[2] + + if (exceptionOccured or (not isNetworkInDesiredState)): + self.fail(exceptionMessage) + response = verifyNetworkState(self.apiclient, persistent_network_2.id, "implemented") + exceptionOccured = response[0] + isNetworkInDesiredState = response[1] + exceptionMessage = response[2] + + if (exceptionOccured or (not isNetworkInDesiredState)): + self.fail(exceptionMessage) elif value == "delete": vpc.delete(self.apiclient) @@ -1726,47 +1849,88 @@ def test_vpc_force_delete_domain(self): # 3. Restart/delete VPC network # Validations - # 1. In case of Restart operation, restart should be successful and persistent networks should be back in persistent state - # 2. In case of Delete operation, VR servicing the VPC should get destroyed and sourceNAT ip should get released + # 1. In case of Restart operation, restart should be successful + # and persistent networks should be back in persistent state + # 2. In case of Delete operation, VR servicing the VPC should + # get destroyed and sourceNAT ip should get released - child_domain = Domain.create(self.apiclient,services=self.services["domain"], + child_domain = Domain.create(self.apiclient, + services=self.services["domain"], parentdomainid=self.domain.id) - account_1 = Account.create(self.apiclient,self.services["account"],domainid=child_domain.id) - account_2 = Account.create(self.apiclient,self.services["account"],domainid=child_domain.id) + try: + account_1 = Account.create( + self.apiclient,self.services["account"], + domainid=child_domain.id + ) + account_2 = Account.create( + self.apiclient,self.services["account"], + domainid=child_domain.id + ) - self.services["vpc"]["cidr"] = "10.1.1.1/16" - vpc_1 = VPC.create(self.apiclient, self.services["vpc"], + self.services["vpc"]["cidr"] = "10.1.1.1/16" + vpc_1 = VPC.create(self.apiclient, self.services["vpc"], vpcofferingid=self.vpc_off.id, zoneid=self.zone.id, account=account_1.name, domainid=account_1.domainid) - vpcs = VPC.list(self.apiclient, id=vpc_1.id) - self.assertEqual(validateList(vpcs)[0], PASS, "VPC list validation failed, vpc list is %s" % vpcs) + vpcs = VPC.list(self.apiclient, id=vpc_1.id) + self.assertEqual(validateList(vpcs)[0], PASS,\ + "VPC list validation failed, vpc list is %s" % vpcs) - vpc_2 = VPC.create(self.apiclient, self.services["vpc"], + vpc_2 = VPC.create(self.apiclient, self.services["vpc"], vpcofferingid=self.vpc_off.id, zoneid=self.zone.id, account=account_2.name, domainid=account_2.domainid) - vpcs = VPC.list(self.apiclient, id=vpc_2.id) - self.assertEqual(validateList(vpcs)[0], PASS, "VPC list validation failed, vpc list is %s" % vpcs) - - persistent_network_1 = Network.create(self.api_client,self.services["isolated_network"], - networkofferingid=self.persistent_network_offering_NoLB.id, - accountid=account_1.name,domainid=account_1.domainid, - zoneid=self.zone.id, vpcid=vpc_1.id, gateway="10.1.1.1", netmask="255.255.255.0") - verifyNetworkState(self.apiclient, persistent_network_1.id, "implemented") - self.assertIsNotNone(persistent_network_1.vlan, "vlan must not be null for persistent network %s" % persistent_network_1.id) - - persistent_network_2 = Network.create(self.api_client,self.services["isolated_network"], - networkofferingid=self.persistent_network_offering_NoLB.id, - accountid=account_2.name,domainid=account_2.domainid, - zoneid=self.zone.id, vpcid=vpc_2.id, gateway="10.1.1.1", netmask="255.255.255.0") - verifyNetworkState(self.apiclient, persistent_network_2.id, "implemented") - self.assertIsNotNone(persistent_network_2.vlan, "vlan must not be null for persistent network: %s" % persistent_network_2.id) - - # Force delete domain - try: + vpcs = VPC.list(self.apiclient, id=vpc_2.id) + self.assertEqual(validateList(vpcs)[0], PASS,\ + "VPC list validation failed, vpc list is %s" % vpcs) + + persistent_network_1 = Network.create( + self.api_client,self.services["isolated_network"], + networkofferingid=self.persistent_network_offering_NoLB.id, + accountid=account_1.name,domainid=account_1.domainid, + zoneid=self.zone.id, vpcid=vpc_1.id, gateway="10.1.1.1", + netmask="255.255.255.0") + + response = verifyNetworkState(self.apiclient, + persistent_network_1.id, + "implemented" + ) + exceptionOccured = response[0] + isNetworkInDesiredState = response[1] + exceptionMessage = response[2] + + if (exceptionOccured or (not isNetworkInDesiredState)): + raise Exception(exceptionMessage) + self.assertIsNotNone( + persistent_network_1.vlan,\ + "vlan must not be null for persistent network %s" %\ + persistent_network_1.id) + + persistent_network_2 = Network.create( + self.api_client,self.services["isolated_network"], + networkofferingid=self.persistent_network_offering_NoLB.id, + accountid=account_2.name,domainid=account_2.domainid, + zoneid=self.zone.id, vpcid=vpc_2.id, gateway="10.1.1.1", + netmask="255.255.255.0") + response = verifyNetworkState(self.apiclient, persistent_network_2.id, + "implemented") + exceptionOccured = response[0] + isNetworkInDesiredState = response[1] + exceptionMessage = response[2] + + if (exceptionOccured or (not isNetworkInDesiredState)): + raise Exception(exceptionMessage) + self.assertIsNotNone(persistent_network_2.vlan,\ + "vlan must not be null for persistent network: %s" %\ + persistent_network_2.id) + + # Force delete domain child_domain.delete(self.apiclient, cleanup=True) + except Exception as e: - self.fail("Failed to delete domain: %s" % e) + self.cleanup.append(account_1) + self.cleanup.append(account_2) + self.cleanup.append(child_domain) + self.fail(e) self.debug("Waiting for account.cleanup.interval" + " to cleanup any remaining resouces") @@ -1774,11 +1938,17 @@ def test_vpc_force_delete_domain(self): wait_for_cleanup(self.apiclient, ["account.cleanup.interval"]*3) self.VerifyDomainCleanup(child_domain.id) - with self.assertRaises(Exception) as e: - Account.list(self.apiclient,name=account_1.name, domainid=account_1.domainid,listall=True) + with self.assertRaises(Exception): + Account.list( + self.apiclient,name=account_1.name, + domainid=account_1.domainid,listall=True + ) - with self.assertRaises(Exception) as e: - Account.list(self.apiclient,name=account_2.name, domainid=account_2.domainid,listall=True) + with self.assertRaises(Exception): + Account.list( + self.apiclient,name=account_2.name, + domainid=account_2.domainid,listall=True + ) self.VerifyVpcCleanup(vpc_1.id) self.VerifyVpcCleanup(vpc_2.id) @@ -1797,34 +1967,46 @@ def test_vpc_delete_account(self): # 1. In case of Restart operation, restart should be successful and persistent networks should be back in persistent state # 2. In case of Delete operation, VR servicing the VPC should get destroyed and sourceNAT ip should get released - # Create Account - account = Account.create(self.apiclient,self.services["account"],domainid=self.domain.id) + try: + # Create Account + account = Account.create(self.apiclient,self.services["account"],domainid=self.domain.id) - # Create VPC - self.services["vpc"]["cidr"] = "10.1.1.1/16" - vpc = VPC.create(self.apiclient, self.services["vpc"], + # Create VPC + self.services["vpc"]["cidr"] = "10.1.1.1/16" + vpc = VPC.create(self.apiclient, self.services["vpc"], vpcofferingid=self.vpc_off.id, zoneid=self.zone.id, account=account.name, domainid=account.domainid) - vpcs = VPC.list(self.apiclient, id=vpc.id) - self.assertEqual(validateList(vpcs)[0], PASS, "VPC list validation failed, vpc list is %s" % vpcs) + vpcs = VPC.list(self.apiclient, id=vpc.id) + self.assertEqual(validateList(vpcs)[0], PASS, "VPC list validation failed, vpc list is %s" % vpcs) - # Create Persistent Networks as tiers of VPC - persistent_network_1 = Network.create(self.api_client,self.services["isolated_network"], + # Create Persistent Networks as tiers of VPC + persistent_network_1 = Network.create(self.api_client,self.services["isolated_network"], networkofferingid=self.persistent_network_offering_NoLB.id, accountid=account.name,domainid=account.domainid, zoneid=self.zone.id, vpcid=vpc.id, gateway="10.1.1.1", netmask="255.255.255.0") - verifyNetworkState(self.apiclient, persistent_network_1.id, "implemented") - self.assertIsNotNone(persistent_network_1.vlan, "vlan must not be null for persistent network %s" % persistent_network_1.id) + response = verifyNetworkState(self.apiclient, persistent_network_1.id, "implemented") + exceptionOccured = response[0] + isNetworkInDesiredState = response[1] + exceptionMessage = response[2] - persistent_network_2 = Network.create(self.api_client,self.services["isolated_network"], + if (exceptionOccured or (not isNetworkInDesiredState)): + raise Exception(exceptionMessage) + self.assertIsNotNone(persistent_network_1.vlan, "vlan must not be null for persistent network %s" % persistent_network_1.id) + + persistent_network_2 = Network.create(self.api_client,self.services["isolated_network"], networkofferingid=self.persistent_network_offering_LB.id, accountid=account.name,domainid=account.domainid, zoneid=self.zone.id, vpcid=vpc.id, gateway="10.1.2.1", netmask="255.255.255.0") - verifyNetworkState(self.apiclient, persistent_network_2.id, "implemented") - self.assertIsNotNone(persistent_network_2.vlan, "vlan must not be null for persistent network: %s" % persistent_network_2.id) + response = verifyNetworkState(self.apiclient, persistent_network_2.id, "implemented") + exceptionOccured = response[0] + isNetworkInDesiredState = response[1] + exceptionMessage = response[2] - # Deploy VMs in above networks (VM1, VM2 in network1 and VM3, VM4 in network2) - try: + if (exceptionOccured or (not isNetworkInDesiredState)): + raise Exception(exceptionMessage) + self.assertIsNotNone(persistent_network_2.vlan, "vlan must not be null for persistent network: %s" % persistent_network_2.id) + + # Deploy VMs in above networks (VM1, VM2 in network1 and VM3, VM4 in network2) virtual_machine_1 = VirtualMachine.create(self.apiclient,self.services["virtual_machine"], networkids=[persistent_network_1.id],serviceofferingid=self.service_offering.id, accountid=account.name,domainid=self.domain.id) @@ -1840,38 +2022,39 @@ def test_vpc_delete_account(self): virtual_machine_4 = VirtualMachine.create(self.apiclient,self.services["virtual_machine"], networkids=[persistent_network_2.id],serviceofferingid=self.service_offering.id, accountid=account.name,domainid=self.domain.id) - except Exception as e: - self.fail("vm creation failed: %s" % e) - # Associate IP addresses to persistent networks - ipaddress_1 = self.GetAssociatedIpForNetwork(persistent_network_1.id, vpcid=vpc.id, account=account) - ipaddress_2 = self.GetAssociatedIpForNetwork(persistent_network_1.id, vpcid=vpc.id, account=account) - ipaddress_3 = self.GetAssociatedIpForNetwork(persistent_network_2.id, vpcid=vpc.id, account=account) + # Associate IP addresses to persistent networks + ipaddress_1 = self.GetAssociatedIpForNetwork(persistent_network_1.id, vpcid=vpc.id, account=account) + ipaddress_2 = self.GetAssociatedIpForNetwork(persistent_network_1.id, vpcid=vpc.id, account=account) + ipaddress_3 = self.GetAssociatedIpForNetwork(persistent_network_2.id, vpcid=vpc.id, account=account) - # Create NAT rule for VM 1 - NATRule.create(self.api_client, virtual_machine_1, + # Create NAT rule for VM 1 + NATRule.create(self.api_client, virtual_machine_1, self.services["natrule"],ipaddressid=ipaddress_1.ipaddress.id, networkid=persistent_network_1.id) - # Create Static NAT rule for VM 2 - StaticNATRule.enable(self.apiclient, ipaddressid=ipaddress_2.ipaddress.id, + # Create Static NAT rule for VM 2 + StaticNATRule.enable(self.apiclient, ipaddressid=ipaddress_2.ipaddress.id, virtualmachineid=virtual_machine_2.id, networkid=persistent_network_1.id) - # Create load balancer rule for ipaddress3 and assign to VM3 and VM4 - lb_rule = LoadBalancerRule.create(self.apiclient,self.services["lbrule"], + # Create load balancer rule for ipaddress3 and assign to VM3 and VM4 + lb_rule = LoadBalancerRule.create(self.apiclient,self.services["lbrule"], ipaddressid=ipaddress_3.ipaddress.id, accountid=account.name, networkid=persistent_network_2.id, domainid=account.domainid) - lb_rule.assign(self.api_client, [virtual_machine_3, virtual_machine_4]) + lb_rule.assign(self.api_client, [virtual_machine_3, virtual_machine_4]) - # Create network ACL for both ther persistent networks (tiers of VPC) - ingressAclNetwork1, egressAclNetwork1 = self.CreateIngressEgressNetworkACLForNetwork(persistent_network_1.id) - ingressAclNetwork2, egressAclNetwork2 = self.CreateIngressEgressNetworkACLForNetwork(persistent_network_2.id) + # Create network ACL for both ther persistent networks (tiers of VPC) + ingressAclNetwork1, egressAclNetwork1 = self.CreateIngressEgressNetworkACLForNetwork(persistent_network_1.id) + ingressAclNetwork2, egressAclNetwork2 = self.CreateIngressEgressNetworkACLForNetwork(persistent_network_2.id) - self.CheckIngressEgressConnectivityofVM(virtual_machine_1, ipaddress_1.ipaddress.ipaddress) - self.CheckIngressEgressConnectivityofVM(virtual_machine_2, ipaddress_2.ipaddress.ipaddress) - self.CheckIngressEgressConnectivityofVM(virtual_machine_3, ipaddress_3.ipaddress.ipaddress) - self.CheckIngressEgressConnectivityofVM(virtual_machine_4, ipaddress_3.ipaddress.ipaddress) + self.CheckIngressEgressConnectivityofVM(virtual_machine_1, ipaddress_1.ipaddress.ipaddress) + self.CheckIngressEgressConnectivityofVM(virtual_machine_2, ipaddress_2.ipaddress.ipaddress) + self.CheckIngressEgressConnectivityofVM(virtual_machine_3, ipaddress_3.ipaddress.ipaddress) + self.CheckIngressEgressConnectivityofVM(virtual_machine_4, ipaddress_3.ipaddress.ipaddress) + except Exception as e: + self.cleanup.append(account) + self.fail(e) # Delete account account.delete(self.apiclient) @@ -1924,14 +2107,26 @@ def test_vpc_private_gateway_static_route(self): networkofferingid=self.persistent_network_offering_NoLB.id, accountid=account.name,domainid=account.domainid, zoneid=self.zone.id, vpcid=vpc.id, gateway="10.1.1.1", netmask="255.255.255.0") - verifyNetworkState(self.apiclient, persistent_network_1.id, "implemented") + response = verifyNetworkState(self.apiclient, persistent_network_1.id, "implemented") + exceptionOccured = response[0] + isNetworkInDesiredState = response[1] + exceptionMessage = response[2] + + if (exceptionOccured or (not isNetworkInDesiredState)): + self.fail(exceptionMessage) self.assertIsNotNone(persistent_network_1.vlan, "vlan must not be null for persistent network %s" % persistent_network_1.id) persistent_network_2 = Network.create(self.api_client,self.services["isolated_network"], networkofferingid=self.persistent_network_offering_LB.id, accountid=account.name,domainid=account.domainid, zoneid=self.zone.id, vpcid=vpc.id, gateway="10.1.2.1", netmask="255.255.255.0") - verifyNetworkState(self.apiclient, persistent_network_2.id, "implemented") + response = verifyNetworkState(self.apiclient, persistent_network_2.id, "implemented") + exceptionOccured = response[0] + isNetworkInDesiredState = response[1] + exceptionMessage = response[2] + + if (exceptionOccured or (not isNetworkInDesiredState)): + self.fail(exceptionMessage) self.assertIsNotNone(persistent_network_2.vlan, "vlan must not be null for persistent network: %s" % persistent_network_2.id) # Deploy VMs in above networks (VM1, VM2 in network1 and VM3, VM4 in network2) diff --git a/test/integration/component/test_portable_ip.py b/test/integration/component/test_portable_ip.py index 40d80abbea..b9c9059d2b 100644 --- a/test/integration/component/test_portable_ip.py +++ b/test/integration/component/test_portable_ip.py @@ -21,27 +21,27 @@ Feature Specifications: https://cwiki.apache.org/confluence/display/CLOUDSTACK/portable+public+IP """ from marvin.cloudstackTestCase import cloudstackTestCase -from marvin.integration.lib.utils import cleanup_resources -from marvin.integration.lib.base import (Account, - NetworkOffering, - ServiceOffering, - Network, - VirtualMachine, - PublicIPAddress, - FireWallRule, - NATRule, - PortablePublicIpRange, - StaticNATRule) -from marvin.integration.lib.common import (get_zone, - get_pod, - get_domain, - get_region, - get_template, - get_portable_ip_range_services, - is_public_ip_in_correct_state) +from marvin.lib.utils import cleanup_resources +from marvin.lib.base import (VirtualMachine, + PublicIPAddress, + Network, + NetworkOffering, + ServiceOffering, + NATRule, + Account, + PortablePublicIpRange, + StaticNATRule, + FireWallRule) +from marvin.lib.common import (get_zone, + get_template, + get_domain, + get_region, + get_pod, + isIpInDesiredState, + getPortableIpRangeServices) from netaddr import IPAddress from marvin.sshClient import SshClient - +from marvin.codes import FAILED from nose.plugins.attrib import attr class Services: @@ -143,7 +143,7 @@ def __init__(self): "publicport": 22, "protocol": 'TCP', }, - "ostype": 'CentOS 5.3 (64-bit)', + "ostype": 'CentOS 5.3 (64-bit)' } class TestCreatePortablePublicIpRanges(cloudstackTestCase): @@ -153,13 +153,15 @@ class TestCreatePortablePublicIpRanges(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestCreatePortablePublicIpRanges, cls).getClsTestClient().getApiClient() + cls.testClient = super(TestCreatePortablePublicIpRanges, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.region = get_region(cls.api_client, cls.services) - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - cls.pod = get_pod(cls.api_client, cls.zone.id, cls.services) + cls.region = get_region(cls.api_client) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) + cls.pod = get_pod(cls.api_client, cls.zone.id) cls.services['mode'] = cls.zone.networktype cls.services["domainid"] = cls.domain.id cls.services["zoneid"] = cls.zone.id @@ -192,82 +194,76 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags=["advanced"]) + @attr(tags=["advanced", "selfservice"]) def test_create_portable_ip_range(self): """Test create new portable ip range """ # 1. Create new portable ip range with root admin api # 2. Portable ip range should be created successfully - portable_ip_range_services = get_portable_ip_range_services(self.config) - - self.debug(portable_ip_range_services) - - if portable_ip_range_services is None: + portable_ip_range_services = getPortableIpRangeServices(self.config) + if portable_ip_range_services is FAILED: self.skipTest('Failed to read config values related to portable ip range') portable_ip_range_services["regionid"] = self.region.id - self.debug("Creating new portable IP range with startip:%s and endip:%s" % - (str(portable_ip_range_services["startip"]), - str(portable_ip_range_services["endip"]))) - - #create new portable ip range - new_portable_ip_range = PortablePublicIpRange.create(self.apiclient, + try: + #create new portable ip range + new_portable_ip_range = PortablePublicIpRange.create(self.apiclient, portable_ip_range_services) - self.debug("Created new portable IP range with startip:%s and endip:%s and id:%s" % - (new_portable_ip_range.startip, - new_portable_ip_range.endip, - new_portable_ip_range.id)) - - self.cleanup.append(new_portable_ip_range) - + self.cleanup.append(new_portable_ip_range) + except Exception as e: + self.fail("Failed to create portable IP range: %s" % e) return - @attr(tags=["advanced"]) + @attr(tags=["advanced", "selfservice"]) def test_create_portable_ip_range_non_root_admin(self): """Test create new portable ip range with non admin root account """ # 1. Create new portable ip range with non root admin api client # 2. Portable ip range should not be created - self.account = Account.create( + portable_ip_range_services = getPortableIpRangeServices(self.config) + + if portable_ip_range_services is FAILED: + self.skipTest('Failed to read config values related to portable ip range') + + try: + self.account = Account.create( self.apiclient, self.services["account"], domainid=self.domain.id ) + self.cleanup.append(self.account) - self.api_client_user = self.testClient.createUserApiClient( + self.api_client_user = self.testClient.getUserApiClient( UserName=self.account.name, DomainName=self.account.domain ) - portable_ip_range_services = get_portable_ip_range_services(self.config) - - if portable_ip_range_services is None: - self.skipTest('Failed to read config values related to portable ip range') - - portable_ip_range_services["regionid"] = self.region.id + portable_ip_range_services["regionid"] = self.region.id - self.debug("Trying to create portable ip range with non root-admin api client, should raise exception") - with self.assertRaises(Exception): - portable_ip_range = PortablePublicIpRange.create(self.api_client_user, + self.debug("Trying to create portable ip range with non root-admin api client, should raise exception") + with self.assertRaises(Exception): + portable_ip_range = PortablePublicIpRange.create(self.api_client_user, portable_ip_range_services) - self.cleanup.append(portable_ip_range) + self.cleanup.append(portable_ip_range) + except Exception as e: + self.fail(e) return - @attr(tags=["advanced"]) + @attr(tags=["advanced", "selfservice"]) def test_create_portable_ip_range_invalid_region(self): """Test create portable ip range with invalid region id""" # 1. Try to create new portable ip range with invalid region id # 2. Portable ip range creation should fail - portable_ip_range_services = get_portable_ip_range_services(self.config) + portable_ip_range_services = getPortableIpRangeServices(self.config) - if portable_ip_range_services is None: + if portable_ip_range_services is FAILED: self.skipTest('Failed to read config values related to portable ip range') portable_ip_range_services["regionid"] = -1 @@ -289,13 +285,15 @@ class TestDeletePortablePublicIpRanges(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestDeletePortablePublicIpRanges, cls).getClsTestClient().getApiClient() + cls.testClient = super(TestDeletePortablePublicIpRanges, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.region = get_region(cls.api_client, cls.services) - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - cls.pod = get_pod(cls.api_client, cls.zone.id, cls.services) + cls.region = get_region(cls.api_client) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) + cls.pod = get_pod(cls.api_client, cls.zone.id) cls.services['mode'] = cls.zone.networktype cls.services["domainid"] = cls.domain.id cls.services["zoneid"] = cls.zone.id @@ -317,26 +315,17 @@ def setUp(self): self.apiclient = self.testClient.getApiClient() self.dbclient = self.testClient.getDbConnection() - portable_ip_range_services = get_portable_ip_range_services(self.config) + portable_ip_range_services = getPortableIpRangeServices(self.config) - if portable_ip_range_services is None: + if portable_ip_range_services is FAILED: self.skipTest('Failed to read config values related to portable ip range') portable_ip_range_services["regionid"] = self.region.id - self.debug("Creating new portable IP range with startip:%s and endip:%s" % - (str(portable_ip_range_services["startip"]), - str(portable_ip_range_services["endip"]))) - #create new portable ip range self.portable_ip_range = PortablePublicIpRange.create(self.apiclient, portable_ip_range_services) - self.debug("Created new portable IP range with startip:%s and endip:%s and id:%s" % - (self.portable_ip_range.startip, - self.portable_ip_range.endip, - self.portable_ip_range.id)) - self.cleanup = [] return @@ -348,48 +337,49 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags=["advanced"]) + @attr(tags=["advanced", "selfservice"]) def test_delete_portable_ip_range(self): """Test delete ip range """ # 1. Try to delete the created range with root admin api client # 2. Portable range should be deleted successfully - self.debug("Deleting portable ip range with root-admin api") - self.portable_ip_range.delete(self.apiclient) - - self.debug("Deleted portable ip range") - return - @attr(tags=["advanced"]) + @attr(tags=["advanced", "selfservice"]) def test_delete_portable_ip_range_non_root_admin(self): """Test delete ip range - non admin root """ # 1. Try to delete the created range with non root admin api client # 2. Portable range deletion should fail - self.account = Account.create( + try: + self.account = Account.create( self.apiclient, self.services["account"], domainid=self.domain.id ) - self.cleanup.append(self.account) + self.cleanup.append(self.account) - self.api_client_user = self.testClient.createUserApiClient( + self.api_client_user = self.testClient.getUserApiClient( UserName=self.account.name, DomainName=self.account.domain ) + except Exception as e: + self.fail(e) - with self.assertRaises(Exception): - self.portable_ip_range.delete(self.api_client_user) - - self.portable_ip_range.delete(self.apiclient) + try: + with self.assertRaises(Exception): + self.portable_ip_range.delete(self.api_client_user) + except Exception as e: + self.fail(e) + finally: + self.portable_ip_range.delete(self.apiclient) return - @attr(tags=["advanced"]) + @attr(tags=["advanced", "selfservice"]) def test_delete_portable_ip_range_in_use(self): """Test delete ip range """ @@ -397,30 +387,23 @@ def test_delete_portable_ip_range_in_use(self): # 2. Try to delete the portable ip range with root admin api client # 3. Portable ip range should not be deleted unless currently used ip is disassociated - self.account = Account.create( + try: + self.account = Account.create( self.apiclient, self.services["account"], domainid=self.domain.id ) - self.cleanup.append(self.account) - - self.debug( - "Creating n/w offering" - ) - self.network_offering = NetworkOffering.create( + self.cleanup.append(self.account) + self.network_offering = NetworkOffering.create( self.apiclient, self.services["network_offering"], conservemode=False ) + # Enable Network offering + self.network_offering.update(self.apiclient, state='Enabled') - self.debug("Created n/w offering with ID: %s" % - self.network_offering.id) - # Enable Network offering - self.network_offering.update(self.apiclient, state='Enabled') - self.debug("Creating network") - - self.network = Network.create( + self.network = Network.create( self.apiclient, self.services["network"], accountid=self.account.name, @@ -428,10 +411,7 @@ def test_delete_portable_ip_range_in_use(self): networkofferingid=self.network_offering.id, zoneid=self.zone.id ) - - self.debug("Created network with id: %s" % self.network.id) - self.debug("Associating public ip address with network: %s with isportable=True" % self.network.id) - portableip = PublicIPAddress.create( + portableip = PublicIPAddress.create( self.apiclient, accountid=self.account.name, zoneid=self.zone.id, @@ -439,19 +419,21 @@ def test_delete_portable_ip_range_in_use(self): networkid=self.network.id, isportable=True ) - self.debug("Associated public ip address (portable): %s" % portableip.ipaddress.ipaddress) - with self.assertRaises(Exception): - self.debug("Trying to Delete portable ip range with root-admin api, this should fail") - self.portable_ip_range.delete(self.apiclient) - - self.debug("Deleting portable ip range failed") - self.debug("Disassociating portable ip") - portableip.delete(self.apiclient) - - self.debug("Deleting portable ip range") - self.portable_ip_range.delete(self.apiclient) + except Exception as e: + self.fail(e) + try: + with self.assertRaises(Exception): + self.debug("Trying to Delete portable ip range with root-admin api, this should fail") + self.portable_ip_range.delete(self.apiclient) + except Exception as e: + self.fail(e) + finally: + self.debug("Disassociating portable ip") + portableip.delete(self.apiclient) + self.debug("Deleting portable ip range") + self.portable_ip_range.delete(self.apiclient) return class TestListPortablePublicIpRanges(cloudstackTestCase): @@ -461,13 +443,15 @@ class TestListPortablePublicIpRanges(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestListPortablePublicIpRanges, cls).getClsTestClient().getApiClient() + cls.testClient = super(TestListPortablePublicIpRanges, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.region = get_region(cls.api_client, cls.services) - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - cls.pod = get_pod(cls.api_client, cls.zone.id, cls.services) + cls.region = get_region(cls.api_client) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) + cls.pod = get_pod(cls.api_client, cls.zone.id) cls.services['mode'] = cls.zone.networktype cls.services["domainid"] = cls.domain.id cls.services["zoneid"] = cls.zone.id @@ -490,9 +474,9 @@ def setUp(self): self.dbclient = self.testClient.getDbConnection() #create new portable ip range - self.portable_ip_range_services = get_portable_ip_range_services(self.config) + self.portable_ip_range_services = getPortableIpRangeServices(self.config) - if self.portable_ip_range_services is None: + if self.portable_ip_range_services is FAILED: self.skipTest('Failed to read config values related to portable ip range') self.portable_ip_range_services["regionid"] = self.region.id @@ -521,7 +505,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags=["advanced"]) + @attr(tags=["advanced", "selfservice"]) def test_list_portable_ip_range(self): """Test list portable ip ranges """ @@ -553,7 +537,7 @@ def test_list_portable_ip_range(self): "Listed netmask not matching with the netmask of created public ip range") return - @attr(tags=["advanced"]) + @attr(tags=["advanced","swamy", "selfservice"]) def test_list_portable_ip_range_non_root_admin(self): """Test list portable ip ranges with non admin root account """ @@ -569,7 +553,7 @@ def test_list_portable_ip_range_non_root_admin(self): self.cleanup.append(self.account) - self.api_client_user = self.testClient.createUserApiClient( + self.api_client_user = self.testClient.getUserApiClient( UserName=self.account.name, DomainName=self.account.domain ) @@ -585,13 +569,15 @@ class TestAssociatePublicIp(cloudstackTestCase): """ @classmethod def setUpClass(cls): - cls.api_client = super(TestAssociatePublicIp, cls).getClsTestClient().getApiClient() + cls.testClient = super(TestAssociatePublicIp, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.region = get_region(cls.api_client, cls.services) - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - cls.pod = get_pod(cls.api_client, cls.zone.id, cls.services) + cls.region = get_region(cls.api_client) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) + cls.pod = get_pod(cls.api_client, cls.zone.id) cls.services['mode'] = cls.zone.networktype cls.services["domainid"] = cls.domain.id cls.services["zoneid"] = cls.zone.id @@ -612,6 +598,7 @@ def setUpClass(cls): domainid=cls.domain.id, admin=True ) + cls._cleanup = [cls.account, ] cls.network_offering = NetworkOffering.create( cls.api_client, @@ -630,8 +617,6 @@ def setUpClass(cls): networkofferingid=cls.network_offering.id, zoneid=cls.zone.id ) - - cls._cleanup = [cls.account] return @classmethod @@ -651,28 +636,17 @@ def setUp(self): self.cleanup = [] - portable_ip_range_services = get_portable_ip_range_services(self.config) + portable_ip_range_services = getPortableIpRangeServices(self.config) - if portable_ip_range_services is None: + if portable_ip_range_services is FAILED: self.skipTest('Failed to read config values related to portable ip range') portable_ip_range_services["regionid"] = self.region.id - self.debug("Creating new portable IP range with startip:%s and endip:%s" % - (str(portable_ip_range_services["startip"]), - str(portable_ip_range_services["endip"]))) - #create new portable ip range self.portable_ip_range = PortablePublicIpRange.create(self.apiclient, portable_ip_range_services) - - self.debug("Created new portable IP range with startip:%s and endip:%s and id:%s" % - (self.portable_ip_range.startip, - self.portable_ip_range.endip, - self.portable_ip_range.id)) - self.cleanup.append(self.portable_ip_range) - return def tearDown(self): @@ -684,7 +658,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags=["advanced"]) + @attr(tags=["advanced", "selfservice"]) def test_associate_ip_address(self): """ Test assocoate public ip address """ @@ -733,7 +707,7 @@ def test_associate_ip_address(self): return - @attr(tags=["advanced"]) + @attr(tags=["advanced", "selfservice"]) def test_associate_ip_address_invalid_zone(self): """ Test Associate IP with invalid zone id """ @@ -753,10 +727,9 @@ def test_associate_ip_address_invalid_zone(self): isportable=True ) publicipaddress.delete(self.apiclient) - self.debug("Associating ip address failed") return - @attr(tags=["advanced"]) + @attr(tags=["advanced", "provisioning"]) def test_associate_ip_address_services_enable_disable(self): """ Test enabling and disabling NAT, Firewall services on portable ip """ @@ -801,10 +774,13 @@ def test_associate_ip_address_services_enable_disable(self): ) self.debug("created public ip address (portable): %s" % portableip.ipaddress.ipaddress) - ipInCorrectState = is_public_ip_in_correct_state(self.apiclient, portableip.ipaddress.id, state="allocated") - if not ipInCorrectState: + response = isIpInDesiredState(self.apiclient, portableip.ipaddress.id, state="allocated") + exceptionOccured = response[0] + ipInDesiredState = response[1] + exceptionMessage = response[2] + if (exceptionOccured or (not ipInDesiredState)): portableip.delete(self.apiclient) - self.fail("Portable IP not in allocated state even after 10 mins") + self.fail(exceptionMessage) try: # Open up firewall port for SSH @@ -852,7 +828,7 @@ def test_associate_ip_address_services_enable_disable(self): portableip.delete(self.apiclient) return - @attr(tags=["advanced"]) + @attr(tags=["advanced", "selfservice"]) def test_associate_ip_address_no_free_ip(self): """ Test assocoate public ip address """ @@ -909,13 +885,15 @@ class TestDisassociatePublicIp(cloudstackTestCase): """ @classmethod def setUpClass(cls): - cls.api_client = super(TestDisassociatePublicIp, cls).getClsTestClient().getApiClient() + cls.testClient = super(TestDisassociatePublicIp, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.region = get_region(cls.api_client, cls.services) - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - cls.pod = get_pod(cls.api_client, cls.zone.id, cls.services) + cls.region = get_region(cls.api_client) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) + cls.pod = get_pod(cls.api_client, cls.zone.id) cls.services['mode'] = cls.zone.networktype cls.services["domainid"] = cls.domain.id cls.services["zoneid"] = cls.zone.id @@ -929,6 +907,7 @@ def setUpClass(cls): # Set Zones and disk offerings cls.services["small"]["zoneid"] = cls.zone.id cls.services["small"]["template"] = template.id + cls._cleanup = [] cls.account = Account.create( cls.api_client, @@ -936,11 +915,13 @@ def setUpClass(cls): domainid=cls.domain.id, admin=True ) + cls._cleanup.append(cls.account) cls.service_offering = ServiceOffering.create( cls.api_client, cls.services["service_offering"] ) + cls._cleanup.append(cls.service_offering) cls.network_offering = NetworkOffering.create( cls.api_client, @@ -950,6 +931,7 @@ def setUpClass(cls): # Enable Network offering cls.network_offering.update(cls.api_client, state='Enabled') + cls._cleanup.append(cls.network_offering) cls.network = Network.create( cls.api_client, @@ -969,12 +951,6 @@ def setUpClass(cls): networkids = [cls.network.id], mode=cls.services['mode'] ) - - cls._cleanup = [ - cls.account, - cls.service_offering, - cls.network_offering - ] return @classmethod @@ -993,28 +969,17 @@ def setUp(self): self.dbclient = self.testClient.getDbConnection() self.cleanup = [] - portable_ip_range_services = get_portable_ip_range_services(self.config) + portable_ip_range_services = getPortableIpRangeServices(self.config) - if portable_ip_range_services is None: + if portable_ip_range_services is FAILED: self.skipTest('Failed to read config values related to portable ip range') portable_ip_range_services["regionid"] = self.region.id - self.debug("Creating new portable IP range with startip:%s and endip:%s" % - (str(portable_ip_range_services["startip"]), - str(portable_ip_range_services["endip"]))) - #create new portable ip range new_portable_ip_range = PortablePublicIpRange.create(self.apiclient, portable_ip_range_services) - - self.debug("Created new portable IP range with startip:%s and endip:%s and id:%s" % - (new_portable_ip_range.startip, - new_portable_ip_range.endip, - new_portable_ip_range.id)) - self.cleanup.append(new_portable_ip_range) - return def tearDown(self): @@ -1026,7 +991,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags=["advanced"]) + @attr(tags=["advanced", "selfservice"]) def test_disassociate_ip_address_no_services(self): """ Test disassociating portable ip """ @@ -1035,7 +1000,8 @@ def test_disassociate_ip_address_no_services(self): # 3. Disassociate the portable ip with root admin api client # 4. Disassociating should be successful - portableip = PublicIPAddress.create( + try: + portableip = PublicIPAddress.create( self.apiclient, accountid=self.account.name, zoneid=self.zone.id, @@ -1043,21 +1009,12 @@ def test_disassociate_ip_address_no_services(self): networkid=self.network.id, isportable=True ) - self.debug("created public ip address (portable): %s" % portableip.ipaddress.ipaddress) - - try: - self.debug("Disassociating portable ip: %s with id: %s" % - (portableip.ipaddress.ipaddress, portableip.ipaddress.id) - ) - portableip.delete(self.apiclient) - except Exception as e: - raise Exception("Exception while disassociating portable ip: %s" % e) - + raise Exception("Exception occured: %s" % e) return - @attr(tags=["advanced"]) + @attr(tags=["advanced", "selfservice"]) def test_disassociate_ip_address_services_enabled(self): """ Test disassociating portable ip """ @@ -1075,12 +1032,14 @@ def test_disassociate_ip_address_services_enabled(self): networkid=self.network.id, isportable=True ) - self.debug("created public ip address (portable): %s" % portableip.ipaddress.ipaddress) - ipInCorrectState = is_public_ip_in_correct_state(self.apiclient, portableip.ipaddress.id, state="allocated") - if not ipInCorrectState: + response = isIpInDesiredState(self.apiclient, portableip.ipaddress.id, state="allocated") + exceptionOccured = response[0] + ipInDesiredState = response[1] + exceptionMessage = response[2] + if (exceptionOccured or (not ipInDesiredState)): portableip.delete(self.apiclient) - self.fail("Portable IP not in allocated state even after 10 mins") + self.fail(exceptionMessage) try: # Open up firewall port for SSH @@ -1107,18 +1066,12 @@ def test_disassociate_ip_address_services_enabled(self): self.fail("Error: %s" % e) try: - self.debug("Disassociating portable ip: %s with id: %s" % - (portableip.ipaddress.ipaddress, portableip.ipaddress.id) - ) - portableip.delete(self.apiclient) - except Exception as e: raise Exception("Exception while disassociating portable ip: %s" % e) - return - @attr(tags=["advanced"]) + @attr(tags=["advanced", "selfservice"]) def test_disassociate_ip_address_other_account(self): """ Test disassociating portable IP with non-owner account """ @@ -1128,7 +1081,8 @@ def test_disassociate_ip_address_other_account(self): # 3. Try to Disassociate the portable ip with an account which is not owner of portable ip # 4. Disassociating should fail - portableip = PublicIPAddress.create( + try: + portableip = PublicIPAddress.create( self.apiclient, accountid=self.account.name, zoneid=self.zone.id, @@ -1136,30 +1090,32 @@ def test_disassociate_ip_address_other_account(self): networkid=self.network.id, isportable=True ) - self.debug("created public ip address (portable): %s" % portableip.ipaddress.ipaddress) + except Exception as e: + self.fail("Failed to create portable ip: %s" % e) - self.user_account = Account.create( + try: + self.otherAccount = Account.create( self.apiclient, self.services["account"], domainid=self.domain.id ) + self.cleanup.append(self.otherAccount) - self.api_client_user = self.testClient.createUserApiClient( - UserName=self.user_account.name, - DomainName=self.user_account.domain + self.apiclientOtherAccount = self.testClient.getUserApiClient( + UserName=self.otherAccount.name, + DomainName=self.otherAccount.domain ) - try: - self.debug("Disassociating portable ip: %s with id: %s with other account :%s" % - (portableip.ipaddress.ipaddress, portableip.ipaddress.id, self.user_account.name) - ) + # Trying to disassociate portable ip using + # api client of other account than the one + # used to create portable ip with self.assertRaises(Exception): - portableip.delete(self.api_client_user) + portableip.delete(self.apiclientOtherAccount) + # Disassociate IP using api client of account used to create it + portableip.delete(self.apiclient) except Exception as e: - raise Exception("Exception while disassociating portable ip: %s" % e) - - portableip.delete(self.apiclient) + self.fail("Exception while disassociating portable ip: %s" % e) return class TestDeleteAccount(cloudstackTestCase): @@ -1168,14 +1124,16 @@ class TestDeleteAccount(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestDeleteAccount, cls).getClsTestClient().getApiClient() + cls.testClient = super(TestDeleteAccount, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.region = get_region(cls.api_client, cls.services) - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.region = get_region(cls.api_client) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype - cls.pod = get_pod(cls.api_client, cls.zone.id, cls.services) + cls.pod = get_pod(cls.api_client, cls.zone.id) cls.services['mode'] = cls.zone.networktype cls.services["domainid"] = cls.domain.id cls.services["zoneid"] = cls.zone.id @@ -1188,7 +1146,7 @@ def setUpClass(cls): # Set Zones and disk offerings cls.services["small"]["zoneid"] = cls.zone.id cls.services["small"]["template"] = template.id - + cls._cleanup = [] return @@ -1205,52 +1163,33 @@ def setUp(self): self.apiclient = self.testClient.getApiClient() self.dbclient = self.testClient.getDbConnection() - self.account = Account.create( + portable_ip_range_services = getPortableIpRangeServices(self.config) + if portable_ip_range_services is FAILED: + self.skipTest('Failed to read config values related to portable ip range') + + self.cleanup = [] + try: + self.account = Account.create( self.apiclient, self.services["account"], domainid=self.domain.id, admin=True ) - self.cleanup = [] - - portable_ip_range_services = get_portable_ip_range_services(self.config) - - if portable_ip_range_services is None: - self.skipTest('Failed to read config values related to portable ip range') - - portable_ip_range_services["regionid"] = self.region.id - - self.debug("Creating new portable IP range with startip:%s and endip:%s" % - (str(portable_ip_range_services["startip"]), - str(portable_ip_range_services["endip"]))) - - #create new portable ip range - new_portable_ip_range = PortablePublicIpRange.create(self.apiclient, + self.cleanup.append(self.account) + portable_ip_range_services["regionid"] = self.region.id + #create new portable ip range + new_portable_ip_range = PortablePublicIpRange.create(self.apiclient, portable_ip_range_services) - - self.debug("Created new portable IP range with startip:%s and endip:%s and id:%s" % - (new_portable_ip_range.startip, - new_portable_ip_range.endip, - new_portable_ip_range.id)) - - self.cleanup.append(new_portable_ip_range) - - self.debug( - "Creating n/w offering" - ) - self.network_offering = NetworkOffering.create( + self.cleanup.append(new_portable_ip_range) + self.network_offering = NetworkOffering.create( self.apiclient, self.services["network_offering"], conservemode=False ) + # Enable Network offering + self.network_offering.update(self.apiclient, state='Enabled') - self.debug("Created n/w offering with ID: %s" % - self.network_offering.id) - # Enable Network offering - self.network_offering.update(self.apiclient, state='Enabled') - self.debug("Creating network") - - self.network = Network.create( + self.network = Network.create( self.apiclient, self.services["network"], accountid=self.account.name, @@ -1258,24 +1197,20 @@ def setUp(self): networkofferingid=self.network_offering.id, zoneid=self.zone.id ) - - self.cleanup.append(self.network_offering) - - self.debug("Created network with id: %s" % self.network.id) + self.cleanup.append(self.network_offering) + except Exception as e: + self.fail("Exception in setupClass: %s" % e) return def tearDown(self): try: - # Disable Network offering - self.network_offering.update(self.apiclient, state='Enabled') - #Clean up, terminate the resources created cleanup_resources(self.apiclient, self.cleanup) except Exception as e: raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags=["advanced"]) + @attr(tags=["advanced", "selfservice"]) def test_delete_account_services_disabled(self): """ test delete account with portable ip with no services enabled """ @@ -1283,7 +1218,8 @@ def test_delete_account_services_disabled(self): # 2. Delete account # 3. Account should get deleted successfully - portableip = PublicIPAddress.create( + try: + portableip = PublicIPAddress.create( self.apiclient, accountid=self.account.name, zoneid=self.zone.id, @@ -1291,21 +1227,15 @@ def test_delete_account_services_disabled(self): networkid=self.network.id, isportable=True ) - self.debug("created public ip address (portable): %s" % portableip.ipaddress.ipaddress) - - self.debug("Deleting account: %s :" % self.account.name) - - self.account.delete(self.apiclient) - - self.debug("Account deleted successfully") - - with self.assertRaises(Exception): - PublicIPAddress.list(self.apiclient, + self.account.delete(self.apiclient) + with self.assertRaises(Exception): + PublicIPAddress.list(self.apiclient, id=portableip.ipaddress.id) - + except Exception as e: + self.fail(e) return - @attr(tags=["advanced"]) + @attr(tags=["advanced", "selfservice"]) def test_delete_account_services_enabled(self): """ test delete account with portable ip with PF and firewall services enabled """ @@ -1342,11 +1272,14 @@ def test_delete_account_services_enabled(self): ) self.debug("created public ip address (portable): %s" % portableip.ipaddress.ipaddress) - ipInCorrectState = is_public_ip_in_correct_state(self.apiclient, portableip.ipaddress.id, state="allocated") - if not ipInCorrectState: + response = isIpInDesiredState(self.apiclient, portableip.ipaddress.id, state="allocated") + exceptionOccured = response[0] + ipInDesiredState = response[1] + exceptionMessage = response[2] + if (exceptionOccured or (not ipInDesiredState)): portableip.delete(self.apiclient) self.account.delete(self.apiclient) - self.fail("Portable IP not in allocated state even after 10 mins") + self.fail(exceptionMessage) try: # Open up firewall port for SSH @@ -1393,13 +1326,15 @@ class TestPortableIpTransferAcrossNetworks(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestPortableIpTransferAcrossNetworks, cls).getClsTestClient().getApiClient() + cls.testClient = super(TestPortableIpTransferAcrossNetworks, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.region = get_region(cls.api_client, cls.services) - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - cls.pod = get_pod(cls.api_client, cls.zone.id, cls.services) + cls.region = get_region(cls.api_client) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) + cls.pod = get_pod(cls.api_client, cls.zone.id) cls.services['mode'] = cls.zone.networktype cls.services["domainid"] = cls.domain.id cls.services["zoneid"] = cls.zone.id @@ -1416,6 +1351,8 @@ def setUpClass(cls): cls.services["vm2"]["zoneid"] = cls.zone.id cls.services["vm2"]["template"] = template.id + cls._cleanup = [] + # Set Zones and Network offerings cls.account = Account.create( cls.api_client, @@ -1423,12 +1360,14 @@ def setUpClass(cls): domainid=cls.domain.id, admin=True ) + cls._cleanup.append(cls.account) cls.network_offering = NetworkOffering.create( cls.api_client, cls.services["network_offering"], conservemode=False ) + cls._cleanup.append(cls.network_offering) # Enable Network offering cls.network_offering.update(cls.api_client, state='Enabled') @@ -1470,8 +1409,6 @@ def setUpClass(cls): serviceofferingid=cls.service_offering.id, networkids = [cls.network2.id], ) - cls._cleanup = [cls.account, cls.network_offering] - return @classmethod @@ -1488,26 +1425,17 @@ def setUp(self): self.dbclient = self.testClient.getDbConnection() #create new portable ip range - self.portable_ip_range_services = get_portable_ip_range_services(self.config) + self.portable_ip_range_services = getPortableIpRangeServices(self.config) - if self.portable_ip_range_services is None: + if self.portable_ip_range_services is FAILED: self.skipTest('Failed to read config values related to portable ip range') self.portable_ip_range_services["regionid"] = self.region.id - self.debug("Creating new portable IP range with startip:%s and endip:%s" % - (str(self.portable_ip_range_services["startip"]), - str(self.portable_ip_range_services["endip"]))) - #create new portable ip range self.portable_ip_range = PortablePublicIpRange.create(self.apiclient, self.portable_ip_range_services) - self.debug("Created new portable IP range with startip:%s and endip:%s and id:%s" % - (self.portable_ip_range.startip, - self.portable_ip_range.endip, - self.portable_ip_range.id)) - self.cleanup = [self.portable_ip_range, ] return @@ -1519,7 +1447,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags=["advanced","swamy"]) + @attr(tags=["advanced","swamy", "selfservice"]) def test_list_portable_ip_range_non_root_admin(self): """Test list portable ip ranges with non admin root account """ @@ -1538,10 +1466,13 @@ def test_list_portable_ip_range_non_root_admin(self): isportable=True ) - ipInCorrectState = is_public_ip_in_correct_state(self.apiclient, portableip.ipaddress.id, state="allocated") - if not ipInCorrectState: + response = isIpInDesiredState(self.apiclient, portableip.ipaddress.id, state="allocated") + exceptionOccured = response[0] + ipInDesiredState = response[1] + exceptionMessage = response[2] + if (exceptionOccured or (not ipInDesiredState)): portableip.delete(self.apiclient) - self.fail("Portable IP not in allocated state even after 10 mins") + self.fail(exceptionMessage) self.debug("created public ip address (portable): %s" % portableip.ipaddress.ipaddress) #Create NAT rule diff --git a/test/integration/component/test_project_configs.py b/test/integration/component/test_project_configs.py index be6cf1ce27..4b777fecec 100644 --- a/test/integration/component/test_project_configs.py +++ b/test/integration/component/test_project_configs.py @@ -21,9 +21,9 @@ from nose.plugins.attrib import attr from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * +from marvin.lib.utils import * +from marvin.lib.base import * +from marvin.lib.common import * from marvin.sshClient import SshClient import datetime @@ -109,13 +109,11 @@ class TestUserProjectCreation(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestUserProjectCreation, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestUserProjectCreation, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services - # Get Zone - cls.zone = get_zone(cls.api_client, cls.services) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype configs = Configurations.list( @@ -175,7 +173,7 @@ def tearDown(self): return @attr(configuration = "allow.user.create.projects") - @attr(tags = ["advanced", "basic", "sg", "eip", "advancedns", "simulator"]) + @attr(tags=["advanced", "basic", "sg", "eip", "advancedns", "simulator", "selfservice"]) def test_admin_project_creation(self): """Test create project as a domain admin and domain user """ @@ -275,13 +273,11 @@ class TestProjectCreationNegative(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestProjectCreationNegative, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestProjectCreationNegative, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services - # Get Zone - cls.zone = get_zone(cls.api_client, cls.services) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype # Checking for prereqisits - global configs @@ -420,17 +416,15 @@ class TestProjectInviteRequired(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestProjectInviteRequired, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestProjectInviteRequired, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services - # Get Zone - cls.zone = get_zone(cls.api_client, cls.services) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype # Create domains, account etc. - cls.domain = get_domain(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) # Verify 'project.invite.required' is set to false configs = Configurations.list( @@ -483,7 +477,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags = ["advanced", "basic", "sg", "eip", "advancedns", "simulator"]) + @attr(tags=["advanced", "basic", "sg", "eip", "advancedns", "selfservice"]) def test_add_user_to_project(self): """Add user to project when 'project.invite.required' is false""" @@ -572,17 +566,15 @@ class TestProjectInviteRequiredTrue(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestProjectInviteRequiredTrue, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestProjectInviteRequiredTrue, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services - # Get Zone - cls.zone = get_zone(cls.api_client, cls.services) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype # Create domains, account etc. - cls.domain = get_domain(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) # Verify 'project.invite.required' is set to true configs = Configurations.list( @@ -636,7 +628,7 @@ def tearDown(self): return @attr(configuration = "project.invite.required") - @attr(tags = ["advanced", "basic", "sg", "eip", "advancedns"]) + @attr(tags=["advanced", "basic", "sg", "eip", "advancedns", "selfservice"]) def test_add_user_to_project(self): """Add user to project when 'project.invite.required' is true""" @@ -725,17 +717,15 @@ class TestProjectInviteTimeout(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestProjectInviteTimeout, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestProjectInviteTimeout, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services - # Get Zone - cls.zone = get_zone(cls.api_client, cls.services) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype # Create domains, account etc. - cls.domain = get_domain(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) # Verify 'project.invite.required' is set to true configs = Configurations.list( diff --git a/test/integration/component/test_project_limits.py b/test/integration/component/test_project_limits.py index 7cb29b7d27..7941313182 100644 --- a/test/integration/component/test_project_limits.py +++ b/test/integration/component/test_project_limits.py @@ -21,9 +21,9 @@ from nose.plugins.attrib import attr from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * +from marvin.lib.utils import * +from marvin.lib.base import * +from marvin.lib.common import * from marvin.codes import PASS import datetime @@ -124,13 +124,11 @@ class TestProjectLimits(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestProjectLimits, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestProjectLimits, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services - # Get Zone - cls.zone = get_zone(cls.api_client, cls.services) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype # Create domains, account etc. @@ -185,7 +183,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags=["advanced", "basic", "sg", "eip", "advancedns", "simulator"]) + @attr(tags=["advanced", "basic", "sg", "eip", "advancedns", "simulator", "selfservice"]) def test_01_project_limits(self): """ Test project limits for domain admin """ @@ -352,7 +350,7 @@ def test_01_project_limits(self): return - @attr(tags=["advanced", "basic", "sg", "eip", "advancedns", "simulator"]) + @attr(tags=["advanced", "basic", "sg", "eip", "advancedns", "simulator", "selfservice"]) def test_02_project_limits_normal_user(self): """ Test project limits for normal user """ @@ -502,10 +500,11 @@ class TestResourceLimitsProject(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestResourceLimitsProject, cls).getClsTestClient().getApiClient() + cls.testClient = super(TestResourceLimitsProject, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services - # Get Zone, Domain and templates - cls.zone = get_zone(cls.api_client, cls.services) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype cls.template = get_template( @@ -576,7 +575,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags=["advanced", "basic", "sg", "eip", "advancedns", "simulator"]) + @attr(tags=["advanced", "basic", "sg", "eip", "advancedns", "simulator", "selfservice"]) def test_03_vm_per_project(self): """Test VM limit per project """ @@ -638,7 +637,7 @@ def test_03_vm_per_project(self): ) return - @attr(tags=["advanced", "eip", "advancedns", "simulator"]) + @attr(tags=["advanced", "eip", "advancedns", "simulator", "selfservice"]) def test_04_publicip_per_project(self): """Test Public IP limit per project """ @@ -723,7 +722,7 @@ def test_04_publicip_per_project(self): ) return - @attr(tags=["advanced", "basic", "sg", "eip", "advancedns", "simulator"]) + @attr(tags=["advanced", "basic", "sg", "eip", "advancedns", "simulator", "selfservice"]) def test_05_snapshots_per_project(self): """Test Snapshot limit per project """ @@ -799,7 +798,7 @@ def test_05_snapshots_per_project(self): ) return - @attr(tags=["advanced", "basic", "sg", "eip", "advancedns", "simulator"]) + @attr(tags=["advanced", "basic", "sg", "eip", "advancedns", "simulator", "selfservice"]) def test_06_volumes_per_project(self): """Test Volumes limit per project """ @@ -855,7 +854,7 @@ def test_06_volumes_per_project(self): ) return - @attr(tags=["advanced", "basic", "sg", "eip", "advancedns"]) + @attr(tags=["advanced", "basic", "sg", "eip", "advancedns", "selfservice"]) def test_07_templates_per_project(self): """Test Templates limit per project """ @@ -945,14 +944,12 @@ class TestMaxProjectNetworks(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestMaxProjectNetworks, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestMaxProjectNetworks, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) + cls.domain = get_domain(cls.api_client) cls.services['mode'] = cls.zone.networktype cls.template = get_template( cls.api_client, diff --git a/test/integration/component/test_project_resources.py b/test/integration/component/test_project_resources.py index d6a732d549..4f61cb0cab 100644 --- a/test/integration/component/test_project_resources.py +++ b/test/integration/component/test_project_resources.py @@ -5,9 +5,9 @@ # 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 @@ -18,8 +18,8 @@ """ #Import Local Modules from nose.plugins.attrib import attr -from marvin.cloudstackTestCase import cloudstackTestCase, unittest -from marvin.integration.lib.base import (VirtualMachine, +from marvin.cloudstackTestCase import cloudstackTestCase +from marvin.lib.base import (VirtualMachine, Account, Project, NATRule, @@ -35,7 +35,7 @@ DiskOffering, LoadBalancerRule) -from marvin.integration.lib.common import (get_zone, +from marvin.lib.common import (get_zone, get_template, get_domain, list_volumes, @@ -44,7 +44,7 @@ get_free_vlan, wait_for_cleanup) -from marvin.integration.lib.utils import cleanup_resources +from marvin.lib.utils import cleanup_resources import random @@ -161,13 +161,11 @@ class TestOfferings(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestOfferings, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestOfferings, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services - # Get Zone and template - cls.zone = get_zone(cls.api_client, cls.services) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype cls.template = get_template( cls.api_client, @@ -227,7 +225,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags = ["advanced", "basic", "sg", "eip", "advancedns", "simulator"]) + @attr(tags=["advanced", "basic", "sg", "eip", "advancedns", "simulator", "selfservice"]) def test_01_service_offerings(self): """ Test service offerings in a project """ @@ -269,7 +267,7 @@ def test_01_service_offerings(self): return - @attr(tags = ["advanced", "basic", "sg", "eip", "advancedns", "simulator"]) + @attr(tags=["advanced", "basic", "sg", "eip", "advancedns", "simulator", "selfservice"]) def test_02_project_disk_offerings(self): """ Test project disk offerings """ @@ -342,13 +340,11 @@ class TestNetwork(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestNetwork, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestNetwork, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services - # Get Zone and template - cls.zone = get_zone(cls.api_client, cls.services) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype cls.template = get_template( cls.api_client, @@ -403,7 +399,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags = ["advanced", "advancedns", "simulator"]) + @attr(tags=["advanced", "advancedns", "simulator", "selfservice"]) def test_03_network_create(self): """ Test create network in project """ @@ -462,7 +458,6 @@ def test_03_network_create(self): True, "Check for the valid network list response" ) - network_response = networks[0] self.debug("Deploying VM with network: %s" % network.id) @@ -550,13 +545,11 @@ class TestTemplates(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestTemplates, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestTemplates, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services - # Get Zone, Domain and templates - cls.zone = get_zone(cls.api_client, cls.services) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype cls.template = get_template( @@ -628,7 +621,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags = ["advanced", "basic", "sg", "eip", "advancedns"]) + @attr(tags=["advanced", "basic", "sg", "eip", "advancedns", "selfservice"]) def test_04_public_template_use_in_project(self): """Test Templates creation in projects """ @@ -637,56 +630,59 @@ def test_04_public_template_use_in_project(self): # 3. Verify that template created in project can be used in project # without any restrictions - self.debug("Deploying VM for with public template: %s" % + try: + self.debug("Deploying VM for with public template: %s" % self.template.id) - virtual_machine_1 = VirtualMachine.create( + virtual_machine_1 = VirtualMachine.create( self.apiclient, self.services["server"], templateid=self.template.id, serviceofferingid=self.service_offering.id, projectid=self.project.id ) - self.cleanup.append(virtual_machine_1) - # Verify VM state - self.assertEqual( + self.cleanup.append(virtual_machine_1) + # Verify VM state + self.assertEqual( virtual_machine_1.state, 'Running', "Check VM state is Running or not" ) - virtual_machine_1.stop(self.apiclient) - # Get the Root disk of VM - volumes = list_volumes( + virtual_machine_1.stop(self.apiclient) + # Get the Root disk of VM + volumes = list_volumes( self.apiclient, projectid=self.project.id, type='ROOT', listall=True ) - self.assertEqual( + self.assertEqual( isinstance(volumes, list), True, "Check for list volume response return valid data" ) - volume = volumes[0] + volume = volumes[0] - self.debug("Creating template from volume: %s" % volume.id) - # Create a template from the ROOTDISK - template_1 = Template.create( + self.debug("Creating template from volume: %s" % volume.id) + # Create a template from the ROOTDISK + template_1 = Template.create( self.apiclient, self.services["template"], volumeid=volume.id, projectid=self.project.id ) - self.cleanup.append(template_1) - # Verify Template state - self.assertEqual( + self.cleanup.append(template_1) + # Verify Template state + self.assertEqual( template_1.isready, True, "Check Template is in ready state or not" ) + except Exception as e: + self.fail("Exception occured: %s" % e) return - @attr(tags = ["advanced", "basic", "sg", "eip", "advancedns"]) + @attr(tags=["advanced", "basic", "sg", "eip", "advancedns", "selfservice"]) def test_05_use_private_template_in_project(self): """Test use of private template in a project """ @@ -696,83 +692,83 @@ def test_05_use_private_template_in_project(self): # be granted to the Project (use API 'updateTemplatePermissions' # with project id to achieve that). - self.debug("Deploying VM for with public template: %s" % + try: + self.debug("Deploying VM for with public template: %s" % self.template.id) - virtual_machine_1 = VirtualMachine.create( + virtual_machine_1 = VirtualMachine.create( self.apiclient, self.services["server"], templateid=self.template.id, serviceofferingid=self.service_offering.id, projectid=self.project.id ) - self.cleanup.append(virtual_machine_1) - # Verify VM state - self.assertEqual( - virtual_machine_1.state, - 'Running', - "Check VM state is Running or not" - ) - self.debug("Stopping the VM: %s" % virtual_machine_1.id) - virtual_machine_1.stop(self.apiclient) - # Get the Root disk of VM - volumes = list_volumes( + self.cleanup.append(virtual_machine_1) + # Verify VM state + self.assertEqual(virtual_machine_1.state, + 'Running', + "Check VM state is Running or not") + virtual_machine_1.stop(self.apiclient) + # Get the Root disk of VM + volumes = list_volumes( self.apiclient, projectid=self.project.id, type='ROOT', listall=True ) - self.assertEqual( + self.assertEqual( isinstance(volumes, list), True, "Check for list volume response return valid data" ) - volume = volumes[0] + volume = volumes[0] - self.debug("Creating template from volume: %s" % volume.id) - # Create a template from the ROOTDISK - template_1 = Template.create( + self.debug("Creating template from volume: %s" % volume.id) + # Create a template from the ROOTDISK + template_1 = Template.create( self.apiclient, self.services["template"], volumeid=volume.id, projectid=self.project.id ) - self.cleanup.append(template_1) - # Verify Template state - self.assertEqual( + self.cleanup.append(template_1) + # Verify Template state + self.assertEqual( template_1.isready, True, "Check Template is in ready state or not" ) - # Update template permissions to grant permission to project - self.debug( - "Updating template permissions:%s to grant access to project: %s" % ( + # Update template permissions to grant permission to project + self.debug( + "Updating template permissions:%s to grant access to project: %s" % ( template_1.id, self.project.id )) - template_1.updatePermissions( + template_1.updatePermissions( self.apiclient, op='add', projectids=self.project.id ) - self.debug("Deploying VM for with privileged template: %s" % + self.debug("Deploying VM for with privileged template: %s" % self.template.id) - virtual_machine_2 = VirtualMachine.create( + virtual_machine_2 = VirtualMachine.create( self.apiclient, self.services["server"], templateid=template_1.id, serviceofferingid=self.service_offering.id, projectid=self.project.id ) - self.cleanup.append(virtual_machine_2) - # Verify VM state - self.assertEqual( + self.cleanup.append(virtual_machine_2) + # Verify VM state + self.assertEqual( virtual_machine_2.state, 'Running', "Check VM state is Running or not" ) + except Exception as e: + self.fail("Exception occured: %s" % e) return @@ -780,13 +776,11 @@ class TestSnapshots(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestSnapshots, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestSnapshots, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services - # Get Zone, Domain and templates - cls.zone = get_zone(cls.api_client, cls.services) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype cls.template = get_template( @@ -852,7 +846,7 @@ def tearDown(self): return @attr(speed = "slow") - @attr(tags = ["advanced", "basic", "sg", "eip", "advancedns", "simulator"]) + @attr(tags=["advanced", "basic", "sg", "eip", "advancedns", "simulator", "selfservice"]) def test_06_create_snapshots_in_project(self): """Test create snapshots in project """ @@ -890,7 +884,6 @@ def test_06_create_snapshots_in_project(self): True, "Check for list volume response return valid data" ) - volume = volumes[0] self.debug("Creating snapshot from volume: %s" % volumes[0].id) # Create a snapshot from the ROOTDISK @@ -928,13 +921,11 @@ class TestPublicIpAddress(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestPublicIpAddress, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestPublicIpAddress, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services - # Get Zone, Domain and templates - cls.zone = get_zone(cls.api_client, cls.services) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype cls.template = get_template( @@ -1008,7 +999,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags = ["advanced", "advancedns"]) + @attr(tags=["advanced", "advancedns", "selfservice"]) def test_07_associate_public_ip(self): """Test associate public IP within the project """ @@ -1213,15 +1204,12 @@ def tearDown(self): @classmethod def setUpClass(cls): + cls.testClient = super(TestSecurityGroup, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services - cls.api_client = super( - TestSecurityGroup, - cls - ).getClsTestClient().getApiClient() - - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) + cls.domain = get_domain(cls.api_client) cls.services['mode'] = cls.zone.networktype template = get_template( diff --git a/test/integration/component/test_project_usage.py b/test/integration/component/test_project_usage.py index ba0a63c97e..5e0dda5aff 100644 --- a/test/integration/component/test_project_usage.py +++ b/test/integration/component/test_project_usage.py @@ -5,9 +5,9 @@ # 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 @@ -17,16 +17,29 @@ """ P1 tests for Snapshots """ #Import Local Modules -import marvin from nose.plugins.attrib import attr -from marvin.cloudstackTestCase import * -from marvin.cloudstackAPI import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * -from marvin.sshClient import SshClient -import datetime - +from marvin.cloudstackTestCase import cloudstackTestCase, unittest +from marvin.cloudstackAPI import deleteVolume +from marvin.lib.utils import (cleanup_resources) +from marvin.lib.base import (Project, + VirtualMachine, + Account, + Network, + PublicIPAddress, + NATRule, + ServiceOffering, + Vpn, + VpnUser, + Snapshot, + ImageStore, + DiskOffering, + LoadBalancerRule, + Template, + Iso) +from marvin.lib.common import (get_domain, + get_zone, + get_template, + list_volumes) class Services: """Test Snapshots Services @@ -116,14 +129,13 @@ class TestVmUsage(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestVmUsage, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestVmUsage, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype template = get_template( @@ -192,7 +204,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags = ["advanced", "basic", "sg", "eip", "advancedns", "simulator"]) + @attr(tags=["advanced", "basic", "sg", "eip", "advancedns", "simulator", "selfservice"]) def test_01_vm_usage(self): """Test Create/Destroy VM and verify usage calculation """ @@ -205,14 +217,19 @@ def test_01_vm_usage(self): # VM.Destroy and volume .delete Event for the created account # 4. Delete the account - self.debug("Stopping the VM: %s" % self.virtual_machine.id) - # Stop the VM - self.virtual_machine.stop(self.apiclient) + try: + self.debug("Stopping the VM: %s" % self.virtual_machine.id) + # Stop the VM + self.virtual_machine.stop(self.apiclient) + except Exception as e: + self.fail("Failed to stop VM: %s" % e) - time.sleep(self.services["sleep"]) - # Destroy the VM - self.debug("Destroying the VM: %s" % self.virtual_machine.id) - self.virtual_machine.delete(self.apiclient) + try: + # Destroy the VM + self.debug("Destroying the VM: %s" % self.virtual_machine.id) + self.virtual_machine.delete(self.apiclient) + except Exception as e: + self.fail("Failed to delete VM: %s" % e) # Fetch project account ID from project UUID self.debug( @@ -311,14 +328,13 @@ class TestPublicIPUsage(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestPublicIPUsage, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestPublicIPUsage, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + 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( @@ -404,7 +420,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags = ["advanced", "eip", "advancedns", "simulator"]) + @attr(tags=["advanced", "eip", "advancedns", "simulator", "selfservice"]) def test_01_public_ip_usage(self): """Test Assign new IP and verify usage calculation """ @@ -483,14 +499,13 @@ class TestVolumeUsage(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestVolumeUsage, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestVolumeUsage, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype cls.disk_offering = DiskOffering.create( cls.api_client, @@ -563,7 +578,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags = ["advanced", "basic", "sg", "eip", "advancedns", "simulator"]) + @attr(tags=["advanced", "basic", "sg", "eip", "advancedns", "simulator", "selfservice"]) def test_01_volume_usage(self): """Test Create/delete a volume and verify correct usage is recorded """ @@ -577,7 +592,10 @@ def test_01_volume_usage(self): # Stop VM self.debug("Stopping VM with ID: %s" % self.virtual_machine.id) - self.virtual_machine.stop(self.apiclient) + try: + self.virtual_machine.stop(self.apiclient) + except Exception as e: + self.fail("Failed to stop VM: %s" % e) volume_response = list_volumes( self.apiclient, @@ -597,7 +615,10 @@ def test_01_volume_usage(self): data_volume.id, self.virtual_machine.id )) - self.virtual_machine.detach_volume(self.apiclient, data_volume) + try: + self.virtual_machine.detach_volume(self.apiclient, data_volume) + except Exception as e: + self.fail("Failed to detach volume: %s" % e) # Delete Data disk self.debug("Delete volume ID: %s" % data_volume.id) @@ -668,14 +689,13 @@ class TestTemplateUsage(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestTemplateUsage, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestTemplateUsage, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype cls.services["server"]["zoneid"] = cls.zone.id template = get_template( @@ -684,26 +704,28 @@ def setUpClass(cls): cls.services["ostype"] ) cls.services["server"]["zoneid"] = cls.zone.id - cls.account = Account.create( + cls._cleanup = [] + try: + cls.account = Account.create( cls.api_client, cls.services["account"], domainid=cls.domain.id ) - cls.services["account"] = cls.account.name + cls._cleanup.append(cls.account) + cls.services["account"] = cls.account.name - cls.project = Project.create( + cls.project = Project.create( cls.api_client, cls.services["project"], account=cls.account.name, domainid=cls.account.domainid ) - - cls.service_offering = ServiceOffering.create( + cls._cleanup.append(cls.account) + cls.service_offering = ServiceOffering.create( cls.api_client, - cls.services["service_offering"] - ) - #create virtual machine - cls.virtual_machine = VirtualMachine.create( + cls.services["service_offering"]) + #create virtual machine + cls.virtual_machine = VirtualMachine.create( cls.api_client, cls.services["server"], templateid=template.id, @@ -711,25 +733,22 @@ def setUpClass(cls): projectid=cls.project.id ) - #Stop virtual machine - cls.virtual_machine.stop(cls.api_client) + #Stop virtual machine + cls.virtual_machine.stop(cls.api_client) - #Wait before server has be successfully stopped - time.sleep(30) - list_volume = list_volumes( + list_volume = list_volumes( cls.api_client, projectid=cls.project.id, type='ROOT', listall=True ) - if isinstance(list_volume, list): - cls.volume = list_volume[0] - else: - raise Exception("List Volumes failed!") - cls._cleanup = [ - cls.project, - cls.account, - ] + if isinstance(list_volume, list): + cls.volume = list_volume[0] + else: + raise Exception("List Volumes failed!") + except Exception as e: + cls.tearDownClass() + raise unittest.SkipTest("Failed during setUpClass: %s" % e) return @classmethod @@ -755,7 +774,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags = ["advanced", "basic", "sg", "eip", "advancedns"]) + @attr(tags=["advanced", "basic", "sg", "eip", "advancedns", "selfservice"]) def test_01_template_usage(self): """Test Upload/ delete a template and verify correct usage is generated for the template uploaded @@ -844,11 +863,13 @@ class TestISOUsage(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestISOUsage, cls).getClsTestClient().getApiClient() + cls.testClient = super(TestISOUsage, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype cls.services["server"]["zoneid"] = cls.zone.id cls.services["iso"]["zoneid"] = cls.zone.id @@ -908,7 +929,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags = ["advanced", "basic", "sg", "eip", "advancedns"]) + @attr(tags=["advanced", "basic", "sg", "eip", "advancedns", "selfservice"]) def test_01_ISO_usage(self): """Test Create/Delete a ISO and verify its usage is generated correctly """ @@ -990,14 +1011,13 @@ class TestLBRuleUsage(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestLBRuleUsage, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestLBRuleUsage, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype template = get_template( cls.api_client, @@ -1082,7 +1102,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags = ["advanced", "eip", "advancedns", "simulator"]) + @attr(tags=["advanced", "eip", "advancedns", "simulator", "selfservice"]) def test_01_lb_usage(self): """Test Create/Delete a LB rule and verify correct usage is recorded """ @@ -1173,14 +1193,13 @@ class TestSnapshotUsage(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestSnapshotUsage, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestSnapshotUsage, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype template = get_template( @@ -1250,7 +1269,7 @@ def tearDown(self): return @attr(speed = "slow") - @attr(tags = ["advanced", "basic", "sg", "eip", "advancedns", "simulator"]) + @attr(tags=["advanced", "basic", "sg", "eip", "advancedns", "simulator", "selfservice"]) def test_01_snapshot_usage(self): """Test Create/Delete a manual snap shot and verify correct usage is recorded @@ -1275,8 +1294,6 @@ def test_01_snapshot_usage(self): "Check if list volumes return a valid data" ) - volume = volumes[0] - # Create a snapshot from the ROOTDISK self.debug("Creating snapshot from volume: %s" % volumes[0].id) snapshot = Snapshot.create(self.apiclient, volumes[0].id) @@ -1351,14 +1368,13 @@ class TestNatRuleUsage(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestNatRuleUsage, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestNatRuleUsage, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype template = get_template( cls.api_client, @@ -1443,7 +1459,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags = ["advanced", "advancedns", "simulator"]) + @attr(tags=["advanced", "advancedns", "simulator", "selfservice"]) def test_01_nat_usage(self): """Test Create/Delete a PF rule and verify correct usage is recorded """ @@ -1534,14 +1550,13 @@ class TestVpnUsage(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestVpnUsage, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestVpnUsage, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype template = get_template( cls.api_client, @@ -1627,7 +1642,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags = ["advanced", "advancedns", "simulator"]) + @attr(tags=["advanced", "advancedns", "simulator", "selfservice"]) def test_01_vpn_usage(self): """Test Create/Delete a VPN and verify correct usage is recorded """ diff --git a/test/integration/component/test_projects.py b/test/integration/component/test_projects.py index 4b82fc2639..15c4d5e729 100644 --- a/test/integration/component/test_projects.py +++ b/test/integration/component/test_projects.py @@ -21,9 +21,9 @@ from nose.plugins.attrib import attr from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * +from marvin.lib.utils import * +from marvin.lib.base import * +from marvin.lib.common import * from marvin.sshClient import SshClient import datetime @@ -103,21 +103,15 @@ class TestMultipleProjectCreation(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestMultipleProjectCreation, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestMultipleProjectCreation, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services - # Get Zone - cls.zone = get_zone(cls.api_client, cls.services) + # 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 - # Create domains, account etc. - cls.domain = get_domain( - cls.api_client, - cls.services - ) - configs = Configurations.list( cls.api_client, name='project.invite.required' @@ -168,7 +162,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags = ["advanced", "basic", "sg", "eip", "advancedns", "simulator"]) + @attr(tags=["advanced", "basic", "sg", "eip", "advancedns", "simulator", "selfservice"]) def test_01_create_multiple_projects_by_account(self): """ Verify an account can own multiple projects and can belong to multiple projects """ @@ -320,18 +314,14 @@ class TestCrossDomainAccountAdd(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestCrossDomainAccountAdd, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestCrossDomainAccountAdd, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services - # Get Zone - cls.zone = get_zone(cls.api_client, cls.services) + # 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.domain = get_domain( - cls.api_client, - cls.services - ) configs = Configurations.list( cls.api_client, @@ -389,7 +379,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags = ["advanced", "basic", "sg", "eip", "advancedns", "simulator"]) + @attr(tags=["advanced", "basic", "sg", "eip", "advancedns", "simulator", "selfservice"]) def test_02_cross_domain_account_add(self): """ Verify No cross domain projects """ @@ -454,18 +444,14 @@ class TestDeleteAccountWithProject(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestDeleteAccountWithProject, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestDeleteAccountWithProject, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services - # Get Zone - cls.zone = get_zone(cls.api_client, cls.services) + # 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.domain = get_domain( - cls.api_client, - cls.services - ) configs = Configurations.list( cls.api_client, @@ -510,7 +496,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags = ["advanced", "basic", "sg", "eip", "advancedns", "simulator"]) + @attr(tags=["advanced", "basic", "sg", "eip", "advancedns", "simulator", "selfservice"]) def test_03_delete_account_with_project(self): """ Test As long as the project exists, its owner can't be removed """ @@ -567,13 +553,12 @@ class TestDeleteDomainWithProject(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestDeleteDomainWithProject, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestDeleteDomainWithProject, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone - cls.zone = get_zone(cls.api_client, cls.services) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype configs = Configurations.list( @@ -624,7 +609,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags = ["advanced", "basic", "sg", "eip", "advancedns", "simulator"]) + @attr(tags=["advanced", "basic", "sg", "eip", "advancedns", "simulator", "selfservice"]) def test_04_delete_domain_with_project(self): """ Test Verify delete domain with cleanup=true should delete projects belonging to the domain @@ -708,17 +693,13 @@ class TestProjectOwners(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestProjectOwners, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestProjectOwners, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone - cls.domain = get_domain( - cls.api_client, - cls.services - ) - cls.zone = get_zone(cls.api_client, cls.services) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) + cls.domain = get_domain(cls.api_client) cls.services['mode'] = cls.zone.networktype configs = Configurations.list( @@ -770,7 +751,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags = ["advanced", "basic", "sg", "eip", "advancedns", "simulator"]) + @attr(tags=["advanced", "basic", "sg", "eip", "advancedns", "simulator", "selfservice"]) def test_05_user_project_owner_promotion(self): """ Test Verify a project user can be later promoted to become a owner @@ -912,7 +893,7 @@ def test_05_user_project_owner_promotion(self): ) return - @attr(tags = ["advanced", "basic", "sg", "eip", "advancedns", "simulator"]) + @attr(tags=["advanced", "basic", "sg", "eip", "advancedns", "simulator", "selfservice"]) def test_06_max_one_project_owner(self): """ Test Verify there can only be one owner of a project at a time """ @@ -1136,18 +1117,14 @@ class TestProjectResources(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestProjectResources, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestProjectResources, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone - cls.zone = get_zone(cls.api_client, cls.services) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) + cls.domain = get_domain(cls.api_client) cls.services['mode'] = cls.zone.networktype - cls.domain = get_domain( - cls.api_client, - cls.services - ) configs = Configurations.list( cls.api_client, @@ -1203,7 +1180,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags = ["advanced", "basic", "sg", "eip", "advancedns", "simulator"]) + @attr(tags=["advanced", "basic", "sg", "eip", "advancedns", "simulator", "selfservice"]) def test_07_project_resources_account_delete(self): """ Test Verify after an account is removed from the project, all its resources stay with the project. """ @@ -1317,7 +1294,7 @@ def test_07_project_resources_account_delete(self): ) return - @attr(tags = ["advanced", "basic", "sg", "eip", "advancedns", "simulator"]) + @attr(tags=["advanced", "basic", "sg", "eip", "advancedns", "simulator", "selfservice"]) def test_08_cleanup_after_project_delete(self): """ Test accounts are unassigned from project after project deletion """ @@ -1440,18 +1417,14 @@ class TestProjectSuspendActivate(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestProjectSuspendActivate, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestProjectSuspendActivate, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services - # Get Zone, domain, template etc - cls.zone = get_zone(cls.api_client, cls.services) + # Get Zone + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) + cls.domain = get_domain(cls.api_client) cls.services['mode'] = cls.zone.networktype - cls.domain = get_domain( - cls.api_client, - cls.services - ) cls.template = get_template( cls.api_client, cls.zone.id, @@ -1501,6 +1474,7 @@ def setUpClass(cls): cls._cleanup = [ cls.project, cls.account, + cls.user, cls.disk_offering, cls.service_offering ] @@ -1529,7 +1503,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags = ["advanced", "basic", "sg", "eip", "advancedns", "simulator"]) + @attr(tags=["advanced", "basic", "sg", "eip", "advancedns", "simulator", "selfservice"]) def test_09_project_suspend(self): """ Test Verify after an account is removed from the project, all his resources stay with the project. @@ -1666,7 +1640,7 @@ def test_09_project_suspend(self): ) return - @attr(tags = ["advanced", "basic", "sg", "eip", "advancedns", "simulator"]) + @attr(tags=["advanced", "basic", "sg", "eip", "advancedns", "simulator", "selfservice"]) def test_10_project_activation(self): """ Test project activation after suspension """ diff --git a/test/integration/component/test_ps_domain_limits.py b/test/integration/component/test_ps_domain_limits.py new file mode 100644 index 0000000000..afb0955704 --- /dev/null +++ b/test/integration/component/test_ps_domain_limits.py @@ -0,0 +1,690 @@ +# 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. + +""" P1 tests for primary storage domain limits + + Test Plan: https://cwiki.apache.org/confluence/display/CLOUDSTACK/Limit+Resources+to+domain+or+accounts + + Issue Link: https://issues.apache.org/jira/browse/CLOUDSTACK-1466 + + Feature Specifications: https://cwiki.apache.org/confluence/display/CLOUDSTACK/Limit+Resources+to+domains+and+accounts +""" +# Import Local Modules +from nose.plugins.attrib import attr +from marvin.cloudstackTestCase import cloudstackTestCase, unittest +from marvin.lib.base import (Account, + ServiceOffering, + VirtualMachine, + Resources, + Domain, + Volume, + DiskOffering, + Snapshot) +from marvin.lib.common import (get_domain, + get_zone, + get_template, + createSnapshotFromVirtualMachineVolume, + isVmExpunged, + isDomainResourceCountEqualToExpectedCount) +from marvin.lib.utils import (cleanup_resources) +from marvin.codes import (PASS, + FAIL, + FAILED, + RESOURCE_PRIMARY_STORAGE) + +class TestMultipleChildDomain(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + cloudstackTestClient = super(TestMultipleChildDomain, + cls).getClsTestClient() + cls.api_client = cloudstackTestClient.getApiClient() + # Fill services from the external config file + cls.services = cloudstackTestClient.getParsedTestDataConfig() + # Get Zone, Domain and templates + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cloudstackTestClient.getZoneForTests()) + cls.services["mode"] = cls.zone.networktype + + cls.template = get_template( + cls.api_client, + cls.zone.id, + cls.services["ostype"] + ) + + cls.services["virtual_machine"]["zoneid"] = cls.zone.id + cls.services["virtual_machine"]["template"] = cls.template.id + cls.services["volume"]["zoneid"] = cls.zone.id + + cls._cleanup = [] + try: + cls.service_offering = ServiceOffering.create(cls.api_client, + cls.services["service_offering"]) + cls._cleanup.append(cls.service_offering) + except Exception as e: + cls.tearDownClass() + raise unittest.SkipTest("Exception in setUpClass: %s" % e) + 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) + return + + def setUp(self): + self.apiclient = self.testClient.getApiClient() + self.dbclient = self.testClient.getDbConnection() + self.cleanup = [] + self.services["disk_offering"]["disksize"] = 5 + try: + self.disk_offering = DiskOffering.create( + self.apiclient, + self.services["disk_offering"] + ) + self.assertNotEqual(self.disk_offering, None, \ + "Disk offering is None") + self.cleanup.append(self.disk_offering) + except Exception as e: + self.tearDown() + self.skipTest("Failure while creating disk offering: %s" % e) + return + + def tearDown(self): + try: + # Clean up, terminate the created instance, volumes and snapshots + cleanup_resources(self.apiclient, self.cleanup) + pass + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + def updateDomainResourceLimits(self, parentdomainlimit, subdomainlimit): + """Update primary storage limits of the parent domain and its + child domains""" + + try: + #Update resource limit for domain + Resources.updateLimit(self.apiclient, resourcetype=10, + max=parentdomainlimit, + domainid=self.parent_domain.id) + + # Update Resource limit for sub-domains + Resources.updateLimit(self.apiclient, resourcetype=10, + max=subdomainlimit, + domainid=self.cadmin_1.domainid) + + Resources.updateLimit(self.apiclient, resourcetype=10, + max=subdomainlimit, + domainid=self.cadmin_2.domainid) + except Exception as e: + return [FAIL, e] + return [PASS, None] + + def setupAccounts(self): + try: + self.parent_domain = Domain.create(self.apiclient, + services=self.services["domain"], + parentdomainid=self.domain.id) + self.parentd_admin = Account.create(self.apiclient, self.services["account"], + admin=True, domainid=self.parent_domain.id) + + # Create sub-domains and their admin accounts + self.cdomain_1 = Domain.create(self.apiclient, + services=self.services["domain"], + parentdomainid=self.parent_domain.id) + self.cdomain_2 = Domain.create(self.apiclient, + services=self.services["domain"], + parentdomainid=self.parent_domain.id) + + self.cadmin_1 = Account.create(self.apiclient, self.services["account"], + admin=True, domainid=self.cdomain_1.id) + + self.cadmin_2 = Account.create(self.apiclient, self.services["account"], + admin=True, domainid=self.cdomain_2.id) + + # Cleanup the resources created at end of test + self.cleanup.append(self.cadmin_1) + self.cleanup.append(self.cadmin_2) + self.cleanup.append(self.cdomain_1) + self.cleanup.append(self.cdomain_2) + self.cleanup.append(self.parentd_admin) + self.cleanup.append(self.parent_domain) + + users = { + self.cdomain_1: self.cadmin_1, + self.cdomain_2: self.cadmin_2 + } + except Exception as e: + return [FAIL, e, None] + return [PASS, None, users] + + @attr(tags=["advanced","selfservice"]) + def test_01_multiple_domains_primary_storage_limits(self): + """Test primary storage limit of domain and its sub-domains + + # Steps + 1. Create a parent domain and two sub-domains in it (also admin accounts + of each domain) + 2. Update primary storage limits of the parent domain and child domains + 3. Deploy VM in child domain 1 so that total primary storage + is less than the limit of child domain + 4. Repeat step 3 for child domain 2 + 5. Try to deploy VM in parent domain now so that the total primary storage in + parent domain (including that in sub-domains is more than the primary + storage limit of the parent domain + 6. Delete the admin account of child domain 1 and check resource count + of the parent domain + 7. Delete VM deployed in account 2 and check primary storage count + of parent domain + + # Validations: + 1. Step 3 and 4 should succeed + 2. Step 5 should fail as the resource limit exceeds in parent domain + 3. After step 6, resource count in parent domain should decrease by equivalent + quantity + 4. After step 7, resource count in parent domain should be 0""" + + # Setting up account and domain hierarchy + result = self.setupAccounts() + self.assertEqual(result[0], PASS,\ + "Failure while setting up accounts and domains: %s" % result[1]) + + templatesize = (self.template.size / (1024**3)) + disksize = 10 + subdomainlimit = (templatesize + disksize) + + result = self.updateDomainResourceLimits(((subdomainlimit*3)- 1), subdomainlimit) + self.assertEqual(result[0], PASS,\ + "Failure while updating resource limits: %s" % result[1]) + + try: + self.services["disk_offering"]["disksize"] = disksize + disk_offering_custom = DiskOffering.create(self.apiclient, + services=self.services["disk_offering"]) + self.cleanup.append(disk_offering_custom) + except Exception as e: + self.fail("Failed to create disk offering") + + # Get API clients of parent and child domain admin accounts + api_client_admin = self.testClient.getUserApiClient( + UserName=self.parentd_admin.name, + DomainName=self.parentd_admin.domain) + self.assertNotEqual(api_client_admin, FAILED,\ + "Failed to create api client for account: %s" % self.parentd_admin.name) + + api_client_cadmin_1 = self.testClient.getUserApiClient( + UserName=self.cadmin_1.name, + DomainName=self.cadmin_1.domain) + self.assertNotEqual(api_client_cadmin_1, FAILED,\ + "Failed to create api client for account: %s" % self.cadmin_1.name) + + api_client_cadmin_2 = self.testClient.getUserApiClient( + UserName=self.cadmin_2.name, + DomainName=self.cadmin_2.domain) + self.assertNotEqual(api_client_cadmin_2, FAILED,\ + "Failed to create api client for account: %s" % self.cadmin_2.name) + + VirtualMachine.create( + api_client_cadmin_1, self.services["virtual_machine"], + accountid=self.cadmin_1.name, domainid=self.cadmin_1.domainid, + diskofferingid=disk_offering_custom.id, serviceofferingid=self.service_offering.id + ) + + self.initialResourceCount = (templatesize + disksize) + result = isDomainResourceCountEqualToExpectedCount( + self.apiclient, self.parent_domain.id, + self.initialResourceCount, RESOURCE_PRIMARY_STORAGE) + self.assertFalse(result[0], result[1]) + self.assertTrue(result[2], "Resource count does not match") + + # Create VM in second child domain + vm_2 = VirtualMachine.create( + api_client_cadmin_2, self.services["virtual_machine"], + accountid=self.cadmin_2.name, domainid=self.cadmin_2.domainid, + diskofferingid=disk_offering_custom.id, serviceofferingid=self.service_offering.id + ) + + # Now the VMs in two child domains have exhausted the primary storage limit + # of parent domain, hence VM creation in parent domain with custom disk offering + # should fail + with self.assertRaises(Exception): + VirtualMachine.create( + api_client_admin, self.services["virtual_machine"], + accountid=self.parentd_admin.name, domainid=self.parentd_admin.domainid, + diskofferingid=disk_offering_custom.id, serviceofferingid=self.service_offering.id + ) + + # Deleting user account + self.cadmin_1.delete(self.apiclient) + self.cleanup.remove(self.cadmin_1) + + expectedCount = self.initialResourceCount + result = isDomainResourceCountEqualToExpectedCount( + self.apiclient, self.parent_domain.id, + expectedCount, RESOURCE_PRIMARY_STORAGE) + self.assertFalse(result[0], result[1]) + self.assertTrue(result[2], "Resource count does not match") + + try: + vm_2.delete(self.apiclient) + except Exception as e: + self.fail("Failed to delete instance: %s" % e) + + self.assertTrue(isVmExpunged(self.apiclient, vm_2.id), "VM not expunged \ + in allotted time") + + expectedCount = 0 + result = isDomainResourceCountEqualToExpectedCount( + self.apiclient, self.parent_domain.id, + expectedCount, RESOURCE_PRIMARY_STORAGE) + self.assertFalse(result[0], result[1]) + self.assertTrue(result[2], "Resource count does not match") + return + + @attr(tags=["advanced", "selfservice"]) + def test_02_multiple_domains_primary_storage_limits(self): + """Test primary storage counts in multiple child domains + # Steps + 1. Create a parent domain and two sub-domains in it (also admin accounts + of each domain) + Repeat following steps for both the child domains + 2. Deploy VM in child domain + 3. Check if the resource count for domain is updated correctly + 4. Create a volume and attach it to the VM + 5. Check if the primary storage resource count is updated correctly + + """ + + # Setting up account and domain hierarchy + result = self.setupAccounts() + self.assertEqual(result[0], PASS,\ + "Failure while setting up accounts and domains: %s" % result[1]) + users = result[2] + + templatesize = (self.template.size / (1024**3)) + + for domain, admin in users.items(): + self.account = admin + self.domain = domain + + apiclient = self.testClient.getUserApiClient( + UserName=self.account.name, + DomainName=self.account.domain) + self.assertNotEqual(apiclient, FAILED,\ + "Failed to create api client for account: %s" % self.account.name) + try: + vm = VirtualMachine.create( + apiclient, self.services["virtual_machine"], + accountid=self.account.name, domainid=self.account.domainid, + diskofferingid=self.disk_offering.id, serviceofferingid=self.service_offering.id + ) + + expectedCount = templatesize + self.disk_offering.disksize + result = isDomainResourceCountEqualToExpectedCount( + self.apiclient, self.domain.id, + expectedCount, RESOURCE_PRIMARY_STORAGE) + self.assertFalse(result[0], result[1]) + self.assertTrue(result[2], "Resource count does not match") + + # Creating service offering with 10 GB volume + self.services["disk_offering"]["disksize"] = 10 + disk_offering_10_GB = DiskOffering.create(self.apiclient, + services=self.services["disk_offering"]) + + self.cleanup.append(disk_offering_10_GB) + + volume = Volume.create( + apiclient, self.services["volume"], + zoneid=self.zone.id, account=self.account.name, + domainid=self.account.domainid, diskofferingid=disk_offering_10_GB.id + ) + + volumeSize = (volume.size / (1024**3)) + expectedCount += volumeSize + + vm.attach_volume(apiclient, volume=volume) + result = isDomainResourceCountEqualToExpectedCount( + self.apiclient, self.domain.id, + expectedCount, RESOURCE_PRIMARY_STORAGE) + self.assertFalse(result[0], result[1]) + self.assertTrue(result[2], "Resource count does not match") + + expectedCount -= volumeSize + vm.detach_volume(apiclient, volume=volume) + result = isDomainResourceCountEqualToExpectedCount( + self.apiclient, self.domain.id, + expectedCount, RESOURCE_PRIMARY_STORAGE) + self.assertFalse(result[0], result[1]) + self.assertTrue(result[2], "Resource count does not match") + except Exception as e: + self.fail("Failure: %s" % e) + return + + @attr(tags=["advanced", "selfservice"]) + def test_03_multiple_domains_multiple_volumes(self): + """Test primary storage counts in multiple child domains + # Steps + 1. Create a parent domain and two sub-domains in it (also admin accounts + of each domain) + Repeat following steps for both the child domains + 2. Deploy VM in child domain + 3. Check if the resource count for domain is updated correctly + 4. Create multiple volumes and attach it to the VM + 5. Check if the primary storage resource count is updated correctly + 6. Delete one of the volumes and check if the primary storage resource count + reduced by equivalent number + 7. Detach other volume and check primary storage resource count remains the same + + """ + # Setting up account and domain hierarchy + result = self.setupAccounts() + if result[0] == FAIL: + self.fail("Failure while setting up accounts and domains: %s" % result[1]) + else: + users = result[2] + + templatesize = (self.template.size / (1024**3)) + + for domain, admin in users.items(): + self.account = admin + self.domain = domain + + apiclient = self.testClient.getUserApiClient( + UserName=self.account.name, + DomainName=self.account.domain) + self.assertNotEqual(apiclient, FAILED,\ + "Failed to create api client for account: %s" % self.account.name) + + try: + vm = VirtualMachine.create( + apiclient, self.services["virtual_machine"], + accountid=self.account.name, domainid=self.account.domainid, + diskofferingid=self.disk_offering.id, serviceofferingid=self.service_offering.id + ) + + expectedCount = templatesize + self.disk_offering.disksize + result = isDomainResourceCountEqualToExpectedCount( + self.apiclient, self.domain.id, + expectedCount, RESOURCE_PRIMARY_STORAGE) + self.assertFalse(result[0], result[1]) + self.assertTrue(result[2], "Resource count does not match") + + volume1size = self.services["disk_offering"]["disksize"] = 15 + disk_offering_15_GB = DiskOffering.create(self.apiclient, + services=self.services["disk_offering"]) + + self.cleanup.append(disk_offering_15_GB) + + volume2size = self.services["disk_offering"]["disksize"] = 20 + disk_offering_20_GB = DiskOffering.create(self.apiclient, + services=self.services["disk_offering"]) + + self.cleanup.append(disk_offering_20_GB) + + volume_1 = Volume.create( + apiclient, self.services["volume"], + zoneid=self.zone.id, account=self.account.name, + domainid=self.account.domainid, diskofferingid=disk_offering_15_GB.id + ) + + volume_2 = Volume.create( + apiclient, self.services["volume"], + zoneid=self.zone.id, account=self.account.name, + domainid=self.account.domainid, diskofferingid=disk_offering_20_GB.id + ) + + vm.attach_volume(apiclient, volume=volume_1) + vm.attach_volume(apiclient, volume=volume_2) + + expectedCount += volume1size + volume2size + result = isDomainResourceCountEqualToExpectedCount( + self.apiclient, self.domain.id, + expectedCount, RESOURCE_PRIMARY_STORAGE) + self.assertFalse(result[0], result[1]) + self.assertTrue(result[2], "Resource count does not match") + + vm.detach_volume(apiclient, volume=volume_1) + volume_1.delete(apiclient) + + expectedCount -= volume1size + result = isDomainResourceCountEqualToExpectedCount( + self.apiclient, self.domain.id, + expectedCount, RESOURCE_PRIMARY_STORAGE) + self.assertFalse(result[0], result[1]) + self.assertTrue(result[2], "Resource count does not match") + + expectedCount -= volume2size + vm.detach_volume(apiclient, volume=volume_2) + result = isDomainResourceCountEqualToExpectedCount( + self.apiclient, self.domain.id, + expectedCount, RESOURCE_PRIMARY_STORAGE) + self.assertFalse(result[0], result[1]) + self.assertTrue(result[2], "Resource count does not match") + except Exception as e: + self.fail("Failure: %s" % e) + return + + @attr(tags=["advanced", "selfservice"]) + def test_04_create_template_snapshot(self): + """Test create snapshot and templates from volume + + # Validate the following + 1. Create parent domain with two child sub-domains (and their admin accounts) + Follow these steps for both the domains + # 1. Create template from snapshot and verify secondary storage resource count + # 2. Create Volume from Snapshot and verify primary storage resource count + # 3. Attach volume to instance which was created from snapshot and + # verify primary storage resource count + # 4. Detach volume from instance which was created from snapshot and + # verify the primary storage resource count + # 5. Delete volume which was created from snapshot and verify primary storage + resource count""" + + result = self.setupAccounts() + if result[0] == FAIL: + self.fail("Failure while setting up accounts and domains: %s" % result[1]) + users = result[2] + + for domain, admin in users.items(): + self.account = admin + self.domain = domain + + try: + apiclient = self.testClient.getUserApiClient( + UserName=self.account.name, + DomainName=self.account.domain) + self.assertNotEqual(apiclient, FAILED,\ + "Failed to create api client for account: %s" % self.account.name) + + vm = VirtualMachine.create( + apiclient, self.services["virtual_machine"], + accountid=self.account.name, domainid=self.account.domainid, + diskofferingid=self.disk_offering.id, serviceofferingid=self.service_offering.id + ) + + templatesize = (self.template.size / (1024**3)) + + initialResourceCount = expectedCount = templatesize + self.disk_offering.disksize + result = isDomainResourceCountEqualToExpectedCount( + self.apiclient, self.domain.id, + initialResourceCount, RESOURCE_PRIMARY_STORAGE) + self.assertFalse(result[0], result[1]) + self.assertTrue(result[2], "Resource count does not match") + + vm.stop(self.apiclient) + + response = createSnapshotFromVirtualMachineVolume(apiclient, self.account, vm.id) + self.assertEqual(response[0], PASS, response[1]) + snapshot = response[1] + + response = snapshot.validateState(apiclient, Snapshot.BACKED_UP) + self.assertEqual(response[0], PASS, response[1]) + + self.services["volume"]["size"] = self.services["disk_offering"]["disksize"] + volume = Volume.create_from_snapshot(apiclient, + snapshot_id=snapshot.id, + services=self.services["volume"], + account=self.account.name, + domainid=self.account.domainid) + volumeSize = (volume.size / (1024**3)) + vm.attach_volume(apiclient, volume) + expectedCount = initialResourceCount + (volumeSize) + result = isDomainResourceCountEqualToExpectedCount( + self.apiclient, self.domain.id, + expectedCount, RESOURCE_PRIMARY_STORAGE) + self.assertFalse(result[0], result[1]) + self.assertTrue(result[2], "Resource count does not match") + + expectedCount -= volumeSize + vm.detach_volume(apiclient, volume) + result = isDomainResourceCountEqualToExpectedCount( + self.apiclient, self.domain.id, + expectedCount, RESOURCE_PRIMARY_STORAGE) + self.assertFalse(result[0], result[1]) + self.assertTrue(result[2], "Resource count does not match") + + volume.delete(apiclient) + result = isDomainResourceCountEqualToExpectedCount( + self.apiclient, self.domain.id, + expectedCount, RESOURCE_PRIMARY_STORAGE) + self.assertFalse(result[0], result[1]) + self.assertTrue(result[2], "Resource count does not match") + except Exception as e: + self.fail("Failed with exception : %s" % e) + return + + @attr(tags=["advanced", "selfservice"]) + def test_05_assign_virtual_machine_different_domain(self): + """Test assign virtual machine to account belonging to different domain + + # Steps + 1. Create a parent domain and two sub-domains in it (also admin accounts + of each domain) + 2. Deploy VM in child domain 1 + 3. Check if the resource count for domain 1 is updated correctly + 4. Assign this virtual machine to account 2 in domain 2 + 5. Verify that primaru storage resource count of domain 1 is now 0 and + primary storage resource count of domain 2 is increased by equivalent number + """ + + # Setting up account and domain hierarchy + result = self.setupAccounts() + self.assertEqual(result[0], PASS, result[1]) + + apiclient = self.testClient.getUserApiClient( + UserName=self.cadmin_1.name, + DomainName=self.cadmin_1.domain) + self.assertNotEqual(apiclient, FAILED,\ + "Failed to create api client for account: %s" % self.cadmin_1.name) + + try: + vm_1 = VirtualMachine.create( + apiclient, self.services["virtual_machine"], + accountid=self.cadmin_1.name, domainid=self.cadmin_1.domainid, + diskofferingid=self.disk_offering.id, serviceofferingid=self.service_offering.id + ) + + templatesize = (self.template.size / (1024**3)) + + expectedCount = templatesize + self.disk_offering.disksize + result = isDomainResourceCountEqualToExpectedCount( + self.apiclient, self.cadmin_1.domainid, + expectedCount, RESOURCE_PRIMARY_STORAGE) + self.assertFalse(result[0], result[1]) + self.assertTrue(result[2], "Resource count does not match") + + vm_1.stop(apiclient) + vm_1.assign_virtual_machine(self.apiclient, account=self.cadmin_2.name, + domainid=self.cadmin_2.domainid) + + result = isDomainResourceCountEqualToExpectedCount( + self.apiclient, self.cadmin_2.domainid, + expectedCount, RESOURCE_PRIMARY_STORAGE) + self.assertFalse(result[0], result[1]) + self.assertTrue(result[2], "Resource count does not match") + + expectedCount = 0 + result = isDomainResourceCountEqualToExpectedCount( + self.apiclient, self.cadmin_1.domainid, + expectedCount, RESOURCE_PRIMARY_STORAGE) + self.assertFalse(result[0], result[1]) + self.assertTrue(result[2], "Resource count does not match") + except Exception as e: + self.fail("Failed with exception: %s" % e) + return + + @attr(tags=["advanced", "selfservice"]) + def test_06_destroy_recover_vm(self): + """Test primary storage counts while destroying and recovering VM + # Steps + 1. Create a parent domain and two sub-domains in it (also admin accounts + of each domain) + Repeat following steps for both the child domains + 2. Deploy VM in child domain + 3. Check if the resource count for domain is updated correctly + 4. Destroy the VM + 5. Verify that the primary storage resource count remains the same + 6. Recover the VM + 7. Verify that the primary storage resource count remains the same + """ + + # Setting up account and domain hierarchy + result = self.setupAccounts() + self.assertEqual(result[0], PASS, result[1]) + users = result[2] + + for domain, admin in users.items(): + self.account = admin + self.domain = domain + try: + vm_1 = VirtualMachine.create( + self.apiclient, self.services["virtual_machine"], + accountid=self.account.name, domainid=self.account.domainid, + diskofferingid=self.disk_offering.id, serviceofferingid=self.service_offering.id + ) + + templatesize = (self.template.size / (1024**3)) + + expectedCount = templatesize + self.disk_offering.disksize + result = isDomainResourceCountEqualToExpectedCount( + self.apiclient, self.account.domainid, + expectedCount, RESOURCE_PRIMARY_STORAGE) + self.assertFalse(result[0], result[1]) + self.assertTrue(result[2], "Resource count does not match") + + vm_1.delete(self.apiclient) + + result = isDomainResourceCountEqualToExpectedCount( + self.apiclient, self.account.domainid, + expectedCount, RESOURCE_PRIMARY_STORAGE) + self.assertFalse(result[0], result[1]) + self.assertTrue(result[2], "Resource count does not match") + + vm_1.recover(self.apiclient) + + result = isDomainResourceCountEqualToExpectedCount( + self.apiclient, self.account.domainid, + expectedCount, RESOURCE_PRIMARY_STORAGE) + self.assertFalse(result[0], result[1]) + self.assertTrue(result[2], "Resource count does not match") + except Exception as e: + self.fail("Failed with exception: %s" % e) + return diff --git a/test/integration/component/test_ps_limits.py b/test/integration/component/test_ps_limits.py new file mode 100644 index 0000000000..1993e934b3 --- /dev/null +++ b/test/integration/component/test_ps_limits.py @@ -0,0 +1,588 @@ +# 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. + +""" P1 tests for primary storage limits + + Test Plan: https://cwiki.apache.org/confluence/display/CLOUDSTACK/Limit+Resources+to+domain+or+accounts + + Issue Link: https://issues.apache.org/jira/browse/CLOUDSTACK-1466 + + Feature Specifications: https://cwiki.apache.org/confluence/display/CLOUDSTACK/Limit+Resources+to+domains+and+accounts +""" +# Import Local Modules +from nose.plugins.attrib import attr +from marvin.cloudstackTestCase import cloudstackTestCase, unittest +from marvin.lib.base import ( + Account, + ServiceOffering, + VirtualMachine, + Domain, + Volume, + DiskOffering) +from marvin.lib.common import (get_domain, + get_zone, + get_template, + matchResourceCount, + createSnapshotFromVirtualMachineVolume, + isVmExpunged) +from marvin.lib.utils import (cleanup_resources, + validateList) +from marvin.codes import (PASS, + FAIL, + RESOURCE_PRIMARY_STORAGE, + CHILD_DOMAIN_ADMIN, + ROOT_DOMAIN_ADMIN) +from ddt import ddt, data + +@ddt +class TestVolumeLimits(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + cloudstackTestClient = super(TestVolumeLimits, + cls).getClsTestClient() + cls.api_client = cloudstackTestClient.getApiClient() + # Fill services from the external config file + cls.services = cloudstackTestClient.getParsedTestDataConfig() + # Get Zone, Domain and templates + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cloudstackTestClient.getZoneForTests()) + cls.services["mode"] = cls.zone.networktype + + cls.template = get_template( + cls.api_client, + cls.zone.id, + cls.services["ostype"] + ) + + cls.services["virtual_machine"]["zoneid"] = cls.zone.id + cls.services["virtual_machine"]["template"] = cls.template.id + cls.services["volume"]["zoneid"] = cls.zone.id + cls._cleanup = [] + try: + cls.service_offering = ServiceOffering.create(cls.api_client, cls.services["service_offering"]) + cls._cleanup.append(cls.service_offering) + except Exception as e: + cls.tearDownClass() + raise unittest.SkipTest("Exception in setUpClass: %s" % e) + 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) + return + + def setUp(self): + self.apiclient = self.testClient.getApiClient() + self.dbclient = self.testClient.getDbConnection() + self.cleanup = [] + try: + self.services["disk_offering"]["disksize"] = 2 + self.disk_offering = DiskOffering.create(self.apiclient, self.services["disk_offering"]) + self.assertNotEqual(self.disk_offering, None,\ + "Disk offering is None") + self.cleanup.append(self.disk_offering) + except Exception as e: + self.tearDown() + self.skipTest("Failure in setup: %s" % e) + return + + def tearDown(self): + try: + # Clean up, terminate the created instance, volumes and snapshots + cleanup_resources(self.apiclient, self.cleanup) + pass + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + def setupAccount(self, accountType): + """Setup the account required for the test""" + + try: + if accountType == CHILD_DOMAIN_ADMIN: + self.domain = Domain.create(self.apiclient, + services=self.services["domain"], + parentdomainid=self.domain.id) + + self.account = Account.create(self.apiclient, self.services["account"], + domainid=self.domain.id, admin=True) + self.cleanup.append(self.account) + if accountType == CHILD_DOMAIN_ADMIN: + self.cleanup.append(self.domain) + + self.virtualMachine = VirtualMachine.create(self.api_client, self.services["virtual_machine"], + accountid=self.account.name, domainid=self.account.domainid, + diskofferingid=self.disk_offering.id, + serviceofferingid=self.service_offering.id) + + accounts = Account.list(self.apiclient, id=self.account.id) + + self.assertEqual(validateList(accounts)[0], PASS, + "accounts list validation failed") + + self.initialResourceCount = int(accounts[0].primarystoragetotal) + except Exception as e: + return [FAIL, e] + return [PASS, None] + + @data(ROOT_DOMAIN_ADMIN, CHILD_DOMAIN_ADMIN) + @attr(tags=["advanced", "selfservice"]) + def test_stop_start_vm(self, value): + """Test Deploy VM with 5 GB volume & verify the usage + + # Validate the following + # 1. Create a VM with custom disk offering and check the primary storage count + # 2. Stop VM and verify the resource count remains same + # 3. Start VM and verify resource count remains same""" + + response = self.setupAccount(value) + self.assertEqual(response[0], PASS, response[1]) + + expectedCount = self.initialResourceCount + # Stopping instance + try: + self.virtualMachine.stop(self.apiclient) + except Exception as e: + self.fail("Failed to stop instance: %s" % e) + response = matchResourceCount( + self.apiclient, expectedCount, + RESOURCE_PRIMARY_STORAGE, + accountid=self.account.id) + self.assertEqual(response[0], PASS, response[1]) + + # Starting instance + try: + self.virtualMachine.start(self.apiclient) + except Exception as e: + self.fail("Failed to start instance: %s" % e) + + response = matchResourceCount( + self.apiclient, expectedCount, + RESOURCE_PRIMARY_STORAGE, + accountid=self.account.id) + self.assertEqual(response[0], PASS, response[1]) + return + + @unittest.skip("skip") + @data(ROOT_DOMAIN_ADMIN, CHILD_DOMAIN_ADMIN) + @attr(tags=["advanced", "selfservice"]) + def test_destroy_recover_vm(self, value): + """Test delete and recover instance + + # Validate the following + # 1. Create a VM with custom disk offering and check the primary storage count + # 2. Destroy VM and verify the resource count remains same + # 3. Recover VM and verify resource count remains same""" + + response = self.setupAccount(value) + self.assertEqual(response[0], PASS, response[1]) + + expectedCount = self.initialResourceCount + # Stopping instance + try: + self.virtualMachine.delete(self.apiclient) + except Exception as e: + self.fail("Failed to destroy instance: %s" % e) + response = matchResourceCount( + self.apiclient, expectedCount, + RESOURCE_PRIMARY_STORAGE, + accountid=self.account.id) + self.assertEqual(response[0], PASS, response[1]) + + # Recovering instance + try: + self.virtualMachine.recover(self.apiclient) + except Exception as e: + self.fail("Failed to start instance: %s" % e) + + response = matchResourceCount( + self.apiclient, expectedCount, + RESOURCE_PRIMARY_STORAGE, + accountid=self.account.id) + self.assertEqual(response[0], PASS, response[1]) + return + + @data(ROOT_DOMAIN_ADMIN, CHILD_DOMAIN_ADMIN) + @attr(tags=["advanced", "selfservice"]) + def test_attach_detach_volume(self, value): + """Stop attach and detach volume from VM + + # Validate the following + # 1. Create a VM with custom disk offering and check the primary storage count + # of account + # 2. Create custom volume in account + # 3. Verify that primary storage count increases by same amount + # 4. Attach volume to VM and verify resource count remains the same + # 5. Detach volume and verify resource count remains the same""" + + response = self.setupAccount(value) + self.assertEqual(response[0], PASS, response[1]) + + apiclient = self.apiclient + if value == CHILD_DOMAIN_ADMIN: + apiclient = self.testClient.getUserApiClient( + UserName=self.account.name, + DomainName=self.account.domain + ) + self.assertNotEqual(apiclient, FAIL, "Failure while getting\ + api client of account: %s" % self.account.name) + + try: + self.services["disk_offering"]["disksize"] = 4 + expectedCount = self.initialResourceCount + int(self.services["disk_offering"]["disksize"]) + disk_offering = DiskOffering.create(self.apiclient, + services=self.services["disk_offering"]) + + self.cleanup.append(disk_offering) + + volume = Volume.create( + apiclient,self.services["volume"],zoneid=self.zone.id, + account=self.account.name,domainid=self.account.domainid, + diskofferingid=disk_offering.id) + except Exception as e: + self.fail("Failure: %s" % e) + + response = matchResourceCount( + self.apiclient, expectedCount, + RESOURCE_PRIMARY_STORAGE, + accountid=self.account.id) + self.assertEqual(response[0], PASS, response[1]) + + try: + self.virtualMachine.attach_volume(apiclient, volume=volume) + except Exception as e: + self.fail("Failed while attaching volume to VM: %s" % e) + + response = matchResourceCount( + self.apiclient, expectedCount, + RESOURCE_PRIMARY_STORAGE, + accountid=self.account.id) + self.assertEqual(response[0], PASS, response[1]) + + try: + self.virtualMachine.detach_volume(apiclient, volume=volume) + except Exception as e: + self.fail("Failure while detaching volume: %s" % e) + + response = matchResourceCount( + self.apiclient, expectedCount, + RESOURCE_PRIMARY_STORAGE, + accountid=self.account.id) + self.assertEqual(response[0], PASS, response[1]) + return + + @data(ROOT_DOMAIN_ADMIN, CHILD_DOMAIN_ADMIN) + @attr(tags=["advanced", "selfservice"]) + def test_create_multiple_volumes(self, value): + """Test create multiple volumes + + # Validate the following + # 1. Create a VM with custom disk offering and check the primary storage count + # of account + # 2. Create multiple volumes in account + # 3. Verify that primary storage count increases by same amount + # 4. Attach volumes to VM and verify resource count remains the same + # 5. Detach and delete both volumes one by one and verify resource count decreases + # proportionately""" + + # Creating service offering with 10 GB volume + + response = self.setupAccount(value) + self.assertEqual(response[0], PASS, response[1]) + + apiclient = self.apiclient + if value == CHILD_DOMAIN_ADMIN: + apiclient = self.testClient.getUserApiClient( + UserName=self.account.name, + DomainName=self.account.domain + ) + self.assertNotEqual(apiclient, FAIL, "Failure while getting\ + api client of account %s" % self.account.name) + + try: + self.services["disk_offering"]["disksize"] = 5 + disk_offering_5_GB = DiskOffering.create(self.apiclient, + services=self.services["disk_offering"]) + self.cleanup.append(disk_offering_5_GB) + + self.services["disk_offering"]["disksize"] = 10 + disk_offering_10_GB = DiskOffering.create(self.apiclient, + services=self.services["disk_offering"]) + + self.cleanup.append(disk_offering_10_GB) + + volume_1 = Volume.create( + apiclient,self.services["volume"],zoneid=self.zone.id, + account=self.account.name,domainid=self.account.domainid, + diskofferingid=disk_offering_5_GB.id) + + volume_2 = Volume.create( + apiclient,self.services["volume"],zoneid=self.zone.id, + account=self.account.name,domainid=self.account.domainid, + diskofferingid=disk_offering_10_GB.id) + + self.debug("Attaching volume %s to vm %s" % (volume_1.name, self.virtualMachine.name)) + self.virtualMachine.attach_volume(apiclient, volume=volume_1) + + self.debug("Attaching volume %s to vm %s" % (volume_2.name, self.virtualMachine.name)) + self.virtualMachine.attach_volume(apiclient, volume=volume_2) + except Exception as e: + self.fail("Failure: %s" % e) + + expectedCount = self.initialResourceCount + 15 # (5 + 10) + response = matchResourceCount( + self.apiclient, expectedCount, + RESOURCE_PRIMARY_STORAGE, + accountid=self.account.id) + self.assertEqual(response[0], PASS, response[1]) + + try: + # Detaching and deleting volume 1 + self.virtualMachine.detach_volume(apiclient, volume=volume_1) + volume_1.delete(apiclient) + except Exception as e: + self.fail("Failure while volume operation: %s" % e) + + expectedCount -= 5 #After deleting first volume + response = matchResourceCount( + self.apiclient, expectedCount, + RESOURCE_PRIMARY_STORAGE, + accountid=self.account.id) + self.assertEqual(response[0], PASS, response[1]) + + try: + # Detaching and deleting volume 2 + self.virtualMachine.detach_volume(apiclient, volume=volume_2) + volume_2.delete(apiclient) + except Exception as e: + self.fail("Failure while volume operation: %s" % e) + + expectedCount -= 10 + response = matchResourceCount( + self.apiclient, expectedCount, + RESOURCE_PRIMARY_STORAGE, + accountid=self.account.id) + self.assertEqual(response[0], PASS, response[1]) + return + + @data(ROOT_DOMAIN_ADMIN, CHILD_DOMAIN_ADMIN) + @attr(tags=["advanced", "selfservice"]) + def test_deploy_multiple_vm(self, value): + """Test Deploy multiple VMs with & verify the usage + # Validate the following + # 1. Deploy multiple VMs with this service offering + # 2. Update Resource count for the root admin Primary Storage usage + # 3. Primary Storage usage should list properly + # 4. Destroy one VM among multiple VM's and verify that primary storage count + # decreases by equivalent amount + """ + + response = self.setupAccount(value) + self.assertEqual(response[0], PASS, response[1]) + + self.virtualMachine_2 = VirtualMachine.create(self.api_client, self.services["virtual_machine"], + accountid=self.account.name, domainid=self.account.domainid, + diskofferingid=self.disk_offering.id, + serviceofferingid=self.service_offering.id) + + expectedCount = (self.initialResourceCount * 2) #Total 2 vms + response = matchResourceCount( + self.apiclient, expectedCount, + RESOURCE_PRIMARY_STORAGE, + accountid=self.account.id) + self.assertEqual(response[0], PASS, response[1]) + + self.virtualMachine_3 = VirtualMachine.create(self.api_client, self.services["virtual_machine"], + accountid=self.account.name, domainid=self.account.domainid, + diskofferingid=self.disk_offering.id, + serviceofferingid=self.service_offering.id) + + expectedCount = (self.initialResourceCount * 3) #Total 3 vms + response = matchResourceCount( + self.apiclient, expectedCount, + RESOURCE_PRIMARY_STORAGE, + accountid=self.account.id) + self.assertEqual(response[0], PASS, response[1]) + + self.debug("Destroying instance: %s" % self.virtualMachine_2.name) + try: + self.virtualMachine_2.delete(self.apiclient) + except Exception as e: + self.fail("Failed to delete instance: %s" % e) + + self.assertTrue(isVmExpunged(self.apiclient, self.virtualMachine_2.id), "VM not expunged \ + in allotted time") + + expectedCount = (self.initialResourceCount * 2) #Total 2 vms + response = matchResourceCount( + self.apiclient, expectedCount, + RESOURCE_PRIMARY_STORAGE, + accountid=self.account.id) + self.assertEqual(response[0], PASS, response[1]) + return + + @data(ROOT_DOMAIN_ADMIN, CHILD_DOMAIN_ADMIN) + @attr(tags=["advanced","selfservice"]) + def test_assign_vm_different_account(self, value): + """Test assign Vm to different account + # Validate the following + # 1. Deploy VM in account and check the primary storage resource count + # 2. Assign VM to another account + # 3. Resource count for first account should now equal to 0 + # 4. Resource count for the account to which VM is assigned should + # increase to that of initial resource count of first account + """ + + response = self.setupAccount(value) + self.assertEqual(response[0], PASS, response[1]) + + try: + account_2 = Account.create(self.apiclient, self.services["account"], + domainid=self.domain.id, admin=True) + self.cleanup.insert(0, account_2) + except Exception as e: + self.fail("Failed to create account: %s" % e) + + expectedCount = self.initialResourceCount + response = matchResourceCount( + self.apiclient, expectedCount, + RESOURCE_PRIMARY_STORAGE, + accountid=self.account.id) + self.assertEqual(response[0], PASS, response[1]) + + try: + self.virtualMachine.stop(self.apiclient) + self.virtualMachine.assign_virtual_machine(self.apiclient, + account_2.name ,account_2.domainid) + except Exception as e: + self.fail("Failed to assign virtual machine to account %s: %s" % + (account_2.name,e)) + + # Checking resource count for account 2 + response = matchResourceCount( + self.apiclient, expectedCount, + RESOURCE_PRIMARY_STORAGE, + accountid=account_2.id) + self.assertEqual(response[0], PASS, response[1]) + + expectedCount = 0 + # Checking resource count for original account + response = matchResourceCount( + self.apiclient, expectedCount, + RESOURCE_PRIMARY_STORAGE, + accountid=self.account.id) + self.assertEqual(response[0], PASS, response[1]) + return + + @data(ROOT_DOMAIN_ADMIN, CHILD_DOMAIN_ADMIN) + @attr(tags=["advanced", "selfservice"]) + def test_create_template_snapshot(self, value): + """Test create snapshot and templates from volume + + # Validate the following + # 1. Deploy VM with custoom disk offering and check the + # primary storage resource count + # 2. Stop the VM and create Snapshot from VM's volume + # 3. Create volume againt from this snapshto and attach to VM + # 4. Verify that primary storage count increases by the volume size + # 5. Detach and delete volume, verify primary storage count decreaes by volume size""" + + response = self.setupAccount(value) + self.debug(response[0]) + self.debug(response[1]) + self.assertEqual(response[0], PASS, response[1]) + + apiclient = self.apiclient + if value == CHILD_DOMAIN_ADMIN: + apiclient = self.testClient.getUserApiClient( + UserName=self.account.name, + DomainName=self.account.domain + ) + self.assertNotEqual(apiclient, FAIL, "Failure while getting api\ + client of account: %s" % self.account.name) + + try: + self.virtualMachine.stop(apiclient) + except Exception as e: + self.fail("Failed to stop instance: %s" % e) + expectedCount = self.initialResourceCount + response = matchResourceCount( + self.apiclient, expectedCount, + RESOURCE_PRIMARY_STORAGE, + accountid=self.account.id) + self.assertEqual(response[0], PASS, response[1]) + + self.debug("Creating snapshot from ROOT volume: %s" % self.virtualMachine.name) + snapshot = None + response = createSnapshotFromVirtualMachineVolume(apiclient, self.account, self.virtualMachine.id) + self.assertEqual(response[0], PASS, response[1]) + snapshot = response[1] + response = matchResourceCount( + self.apiclient, expectedCount, + RESOURCE_PRIMARY_STORAGE, + accountid=self.account.id) + self.assertEqual(response[0], PASS, response[1]) + + try: + self.services["volume"]["size"] = self.services["disk_offering"]["disksize"] + volume = Volume.create_from_snapshot(apiclient, + snapshot_id=snapshot.id, + services=self.services["volume"], + account=self.account.name, + domainid=self.account.domainid) + + self.debug("Attaching the volume to vm: %s" % self.virtualMachine.name) + self.virtualMachine.attach_volume(apiclient, volume) + except Exception as e: + self.fail("Failure in volume operation: %s" % e) + + expectedCount += int(self.services["volume"]["size"]) + response = matchResourceCount( + self.apiclient, expectedCount, + RESOURCE_PRIMARY_STORAGE, + accountid=self.account.id) + self.assertEqual(response[0], PASS, response[1]) + + try: + self.virtualMachine.detach_volume(apiclient, volume) + except Exception as e: + self.fail("Failure in detach volume operation: %s" % e) + + response = matchResourceCount( + self.apiclient, expectedCount, + RESOURCE_PRIMARY_STORAGE, + accountid=self.account.id) + self.assertEqual(response[0], PASS, response[1]) + + try: + self.debug("deleting the volume: %s" % volume.name) + volume.delete(apiclient) + except Exception as e: + self.fail("Failure while deleting volume: %s" % e) + + expectedCount -= int(self.services["volume"]["size"]) + response = matchResourceCount( + self.apiclient, expectedCount, + RESOURCE_PRIMARY_STORAGE, + accountid=self.account.id) + self.assertEqual(response[0], PASS, response[1]) + return diff --git a/test/integration/component/test_ps_max_limits.py b/test/integration/component/test_ps_max_limits.py new file mode 100644 index 0000000000..8d047ef992 --- /dev/null +++ b/test/integration/component/test_ps_max_limits.py @@ -0,0 +1,300 @@ +# 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. + +""" Tests for praimary storage - Maximum Limits + + Test Plan: https://cwiki.apache.org/confluence/display/CLOUDSTACK/Limit+Resources+to+domain+or+accounts + + Issue Link: https://issues.apache.org/jira/browse/CLOUDSTACK-1466 + + Feature Specifications: https://cwiki.apache.org/confluence/display/CLOUDSTACK/Limit+Resources+to+domains+and+accounts +""" +# Import Local Modules +from nose.plugins.attrib import attr +from marvin.cloudstackTestCase import cloudstackTestCase, unittest +from marvin.lib.base import (Account, + ServiceOffering, + VirtualMachine, + Resources, + Domain, + Project, + Volume, + DiskOffering) +from marvin.lib.common import (get_domain, + get_zone, + get_template) +from marvin.lib.utils import (cleanup_resources, + validateList) +from marvin.codes import PASS, FAIL + +class TestMaxPrimaryStorageLimits(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + cloudstackTestClient = super(TestMaxPrimaryStorageLimits, + cls).getClsTestClient() + cls.api_client = cloudstackTestClient.getApiClient() + # Fill services from the external config file + cls.services = cloudstackTestClient.getParsedTestDataConfig() + # Get Zone, Domain and templates + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cloudstackTestClient.getZoneForTests()) + cls.services["mode"] = cls.zone.networktype + + cls.template = get_template( + cls.api_client, + cls.zone.id, + cls.services["ostype"] + ) + + cls.services["virtual_machine"]["zoneid"] = cls.zone.id + cls.services["virtual_machine"]["template"] = cls.template.id + cls.services["volume"]["zoneid"] = cls.zone.id + cls._cleanup = [] + try: + cls.service_offering = ServiceOffering.create(cls.api_client, cls.services["service_offering"]) + cls._cleanup.append(cls.service_offering) + except Exception as e: + cls.tearDownClass() + raise unittest.SkipTest("Exception in setUpClass: %s" % e) + 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) + return + + def setUp(self): + self.apiclient = self.testClient.getApiClient() + self.dbclient = self.testClient.getDbConnection() + self.cleanup = [] + try: + response = self.setupAccounts() + if response[0] == FAIL: + self.skipTest("Failure while setting up accounts: %s" % response[1]) + self.services["disk_offering"]["disksize"] = 2 + self.disk_offering = DiskOffering.create(self.apiclient, self.services["disk_offering"]) + self.cleanup.append(self.disk_offering) + except Exception as e: + self.tearDown() + self.skipTest("Failure in setup: %s" % e) + return + + def tearDown(self): + try: + # Clean up, terminate the created instance, volumes and snapshots + cleanup_resources(self.apiclient, self.cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + def setupAccounts(self): + + try: + self.child_domain = Domain.create(self.apiclient,services=self.services["domain"], + parentdomainid=self.domain.id) + + self.child_do_admin = Account.create(self.apiclient, self.services["account"], admin=True, + domainid=self.child_domain.id) + + # Create project as a domain admin + self.project = Project.create(self.apiclient, self.services["project"], + account=self.child_do_admin.name, + domainid=self.child_do_admin.domainid) + + # Cleanup created project at end of test + self.cleanup.append(self.project) + + # Cleanup accounts created + self.cleanup.append(self.child_do_admin) + self.cleanup.append(self.child_domain) + except Exception as e: + return [FAIL, e] + return [PASS, None] + + def updatePrimaryStorageLimits(self, accountLimit=None, domainLimit=None, + projectLimit=None): + + try: + # Update resource limits for account + if accountLimit: + Resources.updateLimit(self.apiclient, resourcetype=10, + max=accountLimit, account=self.child_do_admin.name, + domainid=self.child_do_admin.domainid) + + if projectLimit: + Resources.updateLimit(self.apiclient, resourcetype=10, + max=projectLimit, projectid=self.project.id) + + if domainLimit: + Resources.updateLimit(self.apiclient, resourcetype=10, + max=domainLimit, domainid=self.child_domain.id) + except Exception as e: + return [FAIL, e] + return [PASS, None] + + @attr(tags=["advanced","selfservice"]) + def test_01_deploy_vm_domain_limit_reached(self): + """Test Try to deploy VM with admin account where account has not used + the resources but @ domain they are not available + + # Validate the following + # 1. Try to deploy VM with admin account where account has not used the + # resources but @ domain they are not available + # 2. Deploy VM should error out saying ResourceAllocationException + # with "resource limit exceeds""" + + self.virtualMachine = VirtualMachine.create(self.api_client, self.services["virtual_machine"], + accountid=self.child_do_admin.name, domainid=self.child_do_admin.domainid, + serviceofferingid=self.service_offering.id) + + accounts = Account.list(self.apiclient, id=self.child_do_admin.id) + self.assertEqual(validateList(accounts)[0], PASS, + "accounts list validation failed") + + self.initialResourceCount = int(accounts[0].primarystoragetotal) + domainLimit = self.initialResourceCount + 3 + + self.debug("Setting up account and domain hierarchy") + response = self.updatePrimaryStorageLimits(domainLimit=domainLimit) + self.assertEqual(response[0], PASS, response[1]) + + self.services["volume"]["size"] = self.services["disk_offering"]["disksize"] = 2 + + try: + disk_offering = DiskOffering.create(self.apiclient, + services=self.services["disk_offering"]) + self.cleanup.append(disk_offering) + Volume.create(self.apiclient, + self.services["volume"], + zoneid=self.zone.id, + account=self.child_do_admin.name, + domainid=self.child_do_admin.domainid, + diskofferingid=disk_offering.id) + except Exception as e: + self.fail("Exception occured: %s" % e) + + with self.assertRaises(Exception): + Volume.create(self.apiclient, + self.services["volume"], + zoneid=self.zone.id, + account=self.child_do_admin.name, + domainid=self.child_do_admin.domainid, + diskofferingid=disk_offering.id) + return + + @attr(tags=["advanced","selfservice"]) + def test_02_deploy_vm_account_limit_reached(self): + """Test Try to deploy VM with admin account where account has used + the resources but @ domain they are available""" + + self.virtualMachine = VirtualMachine.create(self.api_client, self.services["virtual_machine"], + accountid=self.child_do_admin.name, domainid=self.child_do_admin.domainid, + diskofferingid=self.disk_offering.id, + serviceofferingid=self.service_offering.id) + + accounts = Account.list(self.apiclient, id=self.child_do_admin.id) + self.assertEqual(validateList(accounts)[0], PASS, + "accounts list validation failed") + + self.initialResourceCount = int(accounts[0].primarystoragetotal) + accountLimit = self.initialResourceCount + 3 + + self.debug("Setting up account and domain hierarchy") + response = self.updatePrimaryStorageLimits(accountLimit=accountLimit) + self.assertEqual(response[0], PASS, response[1]) + + self.services["volume"]["size"] = self.services["disk_offering"]["disksize"] = 2 + + try: + disk_offering = DiskOffering.create(self.apiclient, + services=self.services["disk_offering"]) + self.cleanup.append(disk_offering) + Volume.create(self.apiclient, + self.services["volume"], + zoneid=self.zone.id, + account=self.child_do_admin.name, + domainid=self.child_do_admin.domainid, + diskofferingid=disk_offering.id) + except Exception as e: + self.fail("failed to create volume: %s" % e) + + with self.assertRaises(Exception): + Volume.create(self.apiclient, + self.services["volume"], + zoneid=self.zone.id, + account=self.child_do_admin.name, + domainid=self.child_do_admin.domainid, + diskofferingid=disk_offering.id) + return + + @attr(tags=["advanced","selfservice"]) + def test_03_deploy_vm_project_limit_reached(self): + """Test TTry to deploy VM with admin account where account has not used + the resources but @ project they are not available + + # Validate the following + # 1. Try to deploy VM with admin account where account has not used the + # resources but @ project they are not available + # 2. Deploy VM should error out saying ResourceAllocationException + # with "resource limit exceeds""" + + self.virtualMachine = VirtualMachine.create(self.api_client, self.services["virtual_machine"], + projectid=self.project.id, + diskofferingid=self.disk_offering.id, + serviceofferingid=self.service_offering.id) + + try: + projects = Project.list(self.apiclient, id=self.project.id, listall=True) + except Exception as e: + self.fail("failed to get projects list: %s" % e) + + self.assertEqual(validateList(projects)[0], PASS, + "projects list validation failed") + self.initialResourceCount = int(projects[0].primarystoragetotal) + + projectLimit = self.initialResourceCount + 3 + + self.debug("Setting up account and domain hierarchy") + response = self.updatePrimaryStorageLimits(projectLimit=projectLimit) + self.assertEqual(response[0], PASS, response[1]) + + self.services["volume"]["size"] = self.services["disk_offering"]["disksize"] = 2 + + try: + disk_offering = DiskOffering.create(self.apiclient, + services=self.services["disk_offering"]) + self.cleanup.append(disk_offering) + Volume.create(self.apiclient, + self.services["volume"], + zoneid=self.zone.id, + projectid=self.project.id, + diskofferingid=disk_offering.id) + except Exception as e: + self.fail("Exception occured: %s" % e) + + with self.assertRaises(Exception): + Volume.create(self.apiclient, + self.services["volume"], + zoneid=self.zone.id, + projectid=self.project.id, + diskofferingid=disk_offering.id) + return diff --git a/test/integration/component/test_ps_project_limits.py b/test/integration/component/test_ps_project_limits.py new file mode 100644 index 0000000000..471b4a187a --- /dev/null +++ b/test/integration/component/test_ps_project_limits.py @@ -0,0 +1,238 @@ +# 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. + +""" P1 tests for primary storage Project limits + + Test Plan: https://cwiki.apache.org/confluence/display/CLOUDSTACK/Limit+Resources+to+domain+or+accounts + + Issue Link: https://issues.apache.org/jira/browse/CLOUDSTACK-1466 + + Feature Specifications: https://cwiki.apache.org/confluence/display/CLOUDSTACK/Limit+Resources+to+domains+and+accounts +""" +# Import Local Modules +from nose.plugins.attrib import attr +from marvin.cloudstackTestCase import cloudstackTestCase, unittest +from marvin.lib.base import (Account, + ServiceOffering, + VirtualMachine, + Host, + Domain, + Project, + Volume) +from marvin.lib.common import (get_domain, + get_zone, + get_template, + matchResourceCount, + isVmExpunged) +from marvin.lib.utils import (cleanup_resources, + validateList) +from marvin.codes import (PASS, + FAIL, + RESOURCE_PRIMARY_STORAGE) +import time + +class TestProjectsVolumeLimits(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + cloudstackTestClient = super(TestProjectsVolumeLimits, + cls).getClsTestClient() + cls.api_client = cloudstackTestClient.getApiClient() + # Fill services from the external config file + cls.services = cloudstackTestClient.getParsedTestDataConfig() + # Get Zone, Domain and templates + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cloudstackTestClient.getZoneForTests()) + cls.services["mode"] = cls.zone.networktype + + cls.template = get_template( + cls.api_client, + cls.zone.id, + cls.services["ostype"] + ) + + cls.services["virtual_machine"]["zoneid"] = cls.zone.id + cls.services["volume"]["zoneid"] = cls.zone.id + cls._cleanup = [] + try: + cls.service_offering = ServiceOffering.create(cls.api_client, cls.services["service_offering"]) + cls._cleanup.append(cls.service_offering) + except Exception as e: + cls.tearDownClass() + raise unittest.SkipTest("Exception in setUpClass: %s" % e) + 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) + return + + def setUp(self): + self.apiclient = self.testClient.getApiClient() + self.dbclient = self.testClient.getDbConnection() + + self.cleanup = [] + response = self.setupProjectAccounts() + self.assertEqual(response[0], PASS, response[1]) + + try: + self.vm = VirtualMachine.create( + self.apiclient,self.services["virtual_machine"], + templateid=self.template.id,projectid=self.project.id, + serviceofferingid=self.service_offering.id) + projects = Project.list(self.apiclient,id=self.project.id, listall=True) + self.assertEqual(validateList(projects)[0], PASS,\ + "projects list validation failed") + self.initialResourceCount = projects[0].primarystoragetotal + except Exception as e: + self.tearDown() + self.skipTest("Exception occured in setup: %s" % e) + return + + def tearDown(self): + try: + # Clean up, terminate the created instance, volumes and snapshots + cleanup_resources(self.apiclient, self.cleanup) + pass + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + def setupProjectAccounts(self): + + try: + self.domain = Domain.create(self.apiclient, + services=self.services["domain"], + parentdomainid=self.domain.id) + self.admin = Account.create( + self.apiclient, self.services["account"], + admin=True, domainid=self.domain.id) + + # Create project as a domain admin + self.project = Project.create( + self.apiclient,self.services["project"], + account=self.admin.name,domainid=self.admin.domainid) + # Cleanup created project at end of test + self.cleanup.append(self.project) + self.cleanup.append(self.admin) + self.cleanup.append(self.domain) + except Exception as e: + return [FAIL, e] + return [PASS, None] + + @attr(tags=["advanced", "selfservice"]) + def test_01_VM_start_stop(self): + """Test project primary storage count with VM stop/start operation + + # Validate the following + # 1. Create VM with custom disk offering in a project and check + # initial primary storage count + # 2. Stop the VM and verify primary storage count remains the same + # 3. Start the VM and verify priamay storage count remains the same + """ + + try: + self.vm.stop(self.apiclient) + except Exception as e: + self.fail("Faield to stop VM: %s" % e) + + expectedCount = self.initialResourceCount + response = matchResourceCount( + self.apiclient, expectedCount, + RESOURCE_PRIMARY_STORAGE, + projectid=self.project.id) + self.assertEqual(response[0], PASS, response[1]) + + try: + self.vm.start(self.apiclient) + except Exception as e: + self.fail("Failed to start VM: %s" % e) + + response = matchResourceCount( + self.apiclient, expectedCount, + RESOURCE_PRIMARY_STORAGE, + projectid=self.project.id) + self.assertEqual(response[0], PASS, response[1]) + return + + @attr(tags=["advanced", "selfservice"]) + def test_02_migrate_vm(self): + """Test migrate VM in project + + # Validate the following + # 1. Create VM with custom disk offering in a project and check + # initial primary storage count + # 2. List the hosts suitable for migrating the VM + # 3. Migrate the VM and verify that primary storage count of project remains same""" + + try: + hosts = Host.list(self.apiclient,virtualmachineid=self.vm.id, + listall=True) + self.assertEqual(validateList(hosts)[0], PASS, "hosts list validation failed") + host = hosts[0] + self.vm.migrate(self.apiclient, host.id) + except Exception as e: + self.fail("Exception occured" % e) + + expectedCount = self.initialResourceCount + response = matchResourceCount( + self.apiclient, expectedCount, + RESOURCE_PRIMARY_STORAGE, + projectid=self.project.id) + self.assertEqual(response[0], PASS, response[1]) + return + + @attr(tags=["advanced", "selfservice"]) + def test_03_delete_vm(self): + """Test delete VM belonging to project + + # Validate the following + # 1. Create VM with custom disk offering in a project and check + # initial primary storage count + # 2. Delete VM and verify that it's expunged + # 3. Verify that primary storage count of project equals 0""" + + try: + self.vm.delete(self.apiclient) + except Exception as e: + self.fail("Failed to detroy VM: %s" % e) + + self.assertTrue(isVmExpunged(self.apiclient, self.vm.id, self.project.id),\ + "VM not expunged") + + totalallottedtime = timeout = 600 + while timeout >= 0: + volumes = Volume.list(self.apiclient, projectid=self.project.id, listall=True) + if volumes is None: + break + if timeout == 0: + self.fail("Volume attached to VM not cleaned up even\ + after %s seconds" % totalallottedtime) + timeout -= 60 + time.sleep(60) + + expectedCount = 0 + response = matchResourceCount( + self.apiclient, expectedCount, + RESOURCE_PRIMARY_STORAGE, + projectid=self.project.id) + self.assertEqual(response[0], PASS, response[1]) + return diff --git a/test/integration/component/test_ps_resize_volume.py b/test/integration/component/test_ps_resize_volume.py new file mode 100644 index 0000000000..737f910331 --- /dev/null +++ b/test/integration/component/test_ps_resize_volume.py @@ -0,0 +1,339 @@ +# 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. + +""" P1 tests for testing resize volume functionality with primary storage limit constraints on + account/domain + + Test Plan: https://cwiki.apache.org/confluence/display/CLOUDSTACK/Limit+Resources+to+domain+or+accounts + + Issue Link: https://issues.apache.org/jira/browse/CLOUDSTACK-1466 + + Feature Specifications: https://cwiki.apache.org/confluence/display/CLOUDSTACK/Limit+Resources+to+domains+and+accounts +""" +# Import Local Modules +from nose.plugins.attrib import attr +from marvin.cloudstackTestCase import cloudstackTestCase, unittest +from marvin.lib.base import (Account, + ServiceOffering, + VirtualMachine, + Resources, + Domain, + DiskOffering, + Volume) +from marvin.lib.common import (get_domain, + get_zone, + get_template, + matchResourceCount, + isDomainResourceCountEqualToExpectedCount) +from marvin.lib.utils import (cleanup_resources, + get_hypervisor_type) +from marvin.codes import (PASS, + FAIL, + FAILED, + RESOURCE_PRIMARY_STORAGE, + RESOURCE_SECONDARY_STORAGE, + XEN_SERVER) + +class TestResizeVolume(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + cloudstackTestClient = super(TestResizeVolume, + cls).getClsTestClient() + cls.api_client = cloudstackTestClient.getApiClient() + # Fill services from the external config file + cls.services = cloudstackTestClient.getParsedTestDataConfig() + # Get Zone, Domain and templates + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cloudstackTestClient.getZoneForTests()) + cls.services["mode"] = cls.zone.networktype + cls.resourcetypemapping = {RESOURCE_PRIMARY_STORAGE: 10, + RESOURCE_SECONDARY_STORAGE: 11} + + cls.template = get_template( + cls.api_client, + cls.zone.id, + cls.services["ostype"] + ) + + cls.services["virtual_machine"]["zoneid"] = cls.zone.id + cls.services["virtual_machine"]["template"] = cls.template.id + cls.services["volume"]["zoneid"] = cls.zone.id + + cls._cleanup = [] + try: + cls.hypervisor = str(get_hypervisor_type(cls.api_client)).lower() + + # Creating service offering with normal config + cls.service_offering = ServiceOffering.create(cls.api_client, + cls.services["service_offering"]) + cls._cleanup.append(cls.service_offering) + + cls.services["disk_offering"]["disksize"] = 5 + cls.disk_offering_5_GB = DiskOffering.create( + cls.api_client, + cls.services["disk_offering"] + ) + cls._cleanup.append(cls.disk_offering_5_GB) + + cls.services["disk_offering"]["disksize"] = 20 + cls.disk_offering_20_GB = DiskOffering.create( + cls.api_client, + cls.services["disk_offering"] + ) + cls._cleanup.append(cls.disk_offering_20_GB) + except Exception as e: + cls.tearDownClass() + raise unittest.SkipTest("Failure while creating disk offering: %s" % e) + 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) + return + + def setUp(self): + self.apiclient = self.testClient.getApiClient() + self.dbclient = self.testClient.getDbConnection() + self.cleanup = [] + return + + def tearDown(self): + try: + # Clean up, terminate the created instance, volumes and snapshots + cleanup_resources(self.apiclient, self.cleanup) + pass + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + def updateResourceLimits(self, accountLimit=None, domainLimit=None): + """Update primary storage limits of the parent domain and its + child domains""" + + try: + if domainLimit: + #Update resource limit for domain + Resources.updateLimit(self.apiclient, resourcetype=10, + max=domainLimit, + domainid=self.parent_domain.id) + if accountLimit: + #Update resource limit for domain + Resources.updateLimit(self.apiclient, resourcetype=10, + max=accountLimit, account=self.parentd_admin.name, + domainid=self.parent_domain.id) + except Exception as e: + return [FAIL, e] + return [PASS, None] + + def setupAccounts(self): + try: + self.parent_domain = Domain.create(self.apiclient, + services=self.services["domain"], + parentdomainid=self.domain.id) + self.parentd_admin = Account.create(self.apiclient, self.services["account"], + admin=True, domainid=self.parent_domain.id) + + # Cleanup the resources created at end of test + self.cleanup.append(self.parentd_admin) + self.cleanup.append(self.parent_domain) + except Exception as e: + return [FAIL, e] + return [PASS, None] + + @attr(tags=["advanced", "selfservice"]) + def test_01_increase_volume_size_within_account_limit(self): + """Test increasing volume size within the account limit and verify primary storage usage + + # Validate the following + # 1. Create a domain and its admin account + # 2. Set account primary storage limit well beyond (20 GB volume + template size of VM) + # 3. Deploy a VM without any disk offering (only root disk) + # 4. Create a volume of 5 GB in the account and attach it to the VM + # 5. Increase (resize) the volume to 20 GB + # 6. Resize opearation should be successful and primary storage counnt for + # account should be updated successfully""" + + # Setting up account and domain hierarchy + result = self.setupAccounts() + self.assertEqual(result[0], PASS, result[1]) + + apiclient = self.testClient.getUserApiClient( + UserName=self.parentd_admin.name, + DomainName=self.parentd_admin.domain) + self.assertNotEqual(apiclient, FAILED, "Failed to get api client\ + of account: %s" % self.parentd_admin.name) + + templateSize = (self.template.size / (1024**3)) + accountLimit = (templateSize + self.disk_offering_20_GB.disksize) + response = self.updateResourceLimits(accountLimit=accountLimit) + self.assertEqual(response[0], PASS, response[1]) + try: + virtualMachine = VirtualMachine.create( + apiclient, self.services["virtual_machine"], + accountid=self.parentd_admin.name, domainid=self.parent_domain.id, + serviceofferingid=self.service_offering.id + ) + + volume = Volume.create( + apiclient,self.services["volume"],zoneid=self.zone.id, + account=self.parentd_admin.name,domainid=self.parent_domain.id, + diskofferingid=self.disk_offering_5_GB.id) + + virtualMachine.attach_volume(apiclient, volume=volume) + + expectedCount = (templateSize + self.disk_offering_5_GB.disksize) + response = matchResourceCount( + self.apiclient, expectedCount, + RESOURCE_PRIMARY_STORAGE, + accountid=self.parentd_admin.id) + if response[0] == FAIL: + raise Exception(response[1]) + + if self.hypervisor == str(XEN_SERVER).lower(): + virtualMachine.stop(self.apiclient) + volume.resize(apiclient, diskofferingid=self.disk_offering_20_GB.id) + + expectedCount = (templateSize + self.disk_offering_20_GB.disksize) + response = matchResourceCount( + self.apiclient, expectedCount, + RESOURCE_PRIMARY_STORAGE, + accountid=self.parentd_admin.id) + if response[0] == FAIL: + raise Exception(response[1]) + except Exception as e: + self.fail("Failed with exception: %s" % e) + return + + @attr(tags=["advanced", "selfservice"]) + def test_02_increase_volume_size_above_account_limit(self): + """Test increasing volume size above the account limit + + # Validate the following + # 1. Create a domain and its admin account + # 2. Set account primary storage limit more than (5 GB volume + template size of VM) + # and less than (20 GB volume+ template size of VM) + # 3. Deploy a VM without any disk offering (only root disk) + # 4. Create a volume of 5 GB in the account and attach it to the VM + # 5. Try to (resize) the volume to 20 GB + # 6. Resize opearation should fail""" + + # Setting up account and domain hierarchy + result = self.setupAccounts() + self.assertEqual(result[0], PASS, result[1]) + + templateSize = (self.template.size / (1024**3)) + accountLimit = ((templateSize + self.disk_offering_20_GB.disksize) - 1) + response = self.updateResourceLimits(accountLimit=accountLimit) + self.assertEqual(response[0], PASS, response[1]) + + apiclient = self.testClient.getUserApiClient( + UserName=self.parentd_admin.name, + DomainName=self.parentd_admin.domain) + self.assertNotEqual(apiclient, FAILED, "Failed to get api client\ + of account: %s" % self.parentd_admin.name) + + try: + virtualMachine = VirtualMachine.create( + apiclient, self.services["virtual_machine"], + accountid=self.parentd_admin.name, domainid=self.parent_domain.id, + serviceofferingid=self.service_offering.id + ) + + volume = Volume.create( + apiclient,self.services["volume"],zoneid=self.zone.id, + account=self.parentd_admin.name,domainid=self.parent_domain.id, + diskofferingid=self.disk_offering_5_GB.id) + + virtualMachine.attach_volume(apiclient, volume=volume) + + expectedCount = (templateSize + self.disk_offering_5_GB.disksize) + response = matchResourceCount( + self.apiclient, expectedCount, + RESOURCE_PRIMARY_STORAGE, + accountid=self.parentd_admin.id) + if response[0] == FAIL: + raise Exception(response[1]) + except Exception as e: + self.fail("Failed with exception: %s" % e) + + if self.hypervisor == str(XEN_SERVER).lower(): + virtualMachine.stop(self.apiclient) + with self.assertRaises(Exception): + volume.resize(apiclient, diskofferingid=self.disk_offering_20_GB.id) + return + + @attr(tags=["advanced", "selfservice"]) + def test_03_increase_volume_size_above_domain_limit(self): + """Test increasing volume size above the domain limit + + # Validate the following + # 1. Create a domain and its admin account + # 2. Set domain primary storage limit more than (5 GB volume + template size of VM) + # and less than (20 GB volume+ template size of VM) + # 3. Deploy a VM without any disk offering (only root disk) + # 4. Create a volume of 5 GB in the account and attach it to the VM + # 5. Try to (resize) the volume to 20 GB + # 6. Resize opearation should fail""" + + # Setting up account and domain hierarchy + result = self.setupAccounts() + self.assertEqual(result[0], PASS, result[1]) + + templateSize = (self.template.size / (1024**3)) + domainLimit = ((templateSize + self.disk_offering_20_GB.disksize) - 1) + response = self.updateResourceLimits(domainLimit=domainLimit) + self.assertEqual(response[0], PASS, response[1]) + + apiclient = self.testClient.getUserApiClient( + UserName=self.parentd_admin.name, + DomainName=self.parentd_admin.domain) + self.assertNotEqual(apiclient, FAILED, "Failed to get api client\ + of account: %s" % self.parentd_admin.name) + + try: + virtualMachine = VirtualMachine.create( + apiclient, self.services["virtual_machine"], + accountid=self.parentd_admin.name, domainid=self.parent_domain.id, + serviceofferingid=self.service_offering.id + ) + + volume = Volume.create( + apiclient,self.services["volume"],zoneid=self.zone.id, + account=self.parentd_admin.name,domainid=self.parent_domain.id, + diskofferingid=self.disk_offering_5_GB.id) + + virtualMachine.attach_volume(apiclient, volume=volume) + + expectedCount = (templateSize + self.disk_offering_5_GB.disksize) + result = isDomainResourceCountEqualToExpectedCount( + self.apiclient, self.parent_domain.id, + expectedCount, RESOURCE_PRIMARY_STORAGE) + self.assertFalse(result[0], result[1]) + self.assertTrue(result[2], "Resource count does not match") + except Exception as e: + self.fail("Failed with exception: %s" % e) + + if self.hypervisor == str(XEN_SERVER).lower(): + virtualMachine.stop(self.apiclient) + with self.assertRaises(Exception): + volume.resize(apiclient, diskofferingid=self.disk_offering_20_GB.id) + return diff --git a/test/integration/component/test_recurring_snapshots.py b/test/integration/component/test_recurring_snapshots.py index 06df1708d9..2ef2bc3678 100644 --- a/test/integration/component/test_recurring_snapshots.py +++ b/test/integration/component/test_recurring_snapshots.py @@ -18,9 +18,9 @@ from nose.plugins.attrib import attr from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * +from marvin.lib.utils import * +from marvin.lib.base import * +from marvin.lib.common import * class Services: """Test Snapshots Services @@ -126,11 +126,13 @@ class TestRecurringSnapshots(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestRecurringSnapshots, cls).getClsTestClient().getApiClient() + cls.testClient = super(TestRecurringSnapshots, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype cls.disk_offering = DiskOffering.create( cls.api_client, @@ -216,7 +218,7 @@ def tearDown(self): return @attr(speed = "slow") - @attr(tags = ["advanced", "advancedns", "smoke"]) + @attr(tags=["advanced", "advancedns", "smoke", "selfservice"]) def test_recurring_snapshot_root_disk(self): """Test Recurring Snapshot Root Disk """ @@ -309,7 +311,7 @@ def test_recurring_snapshot_root_disk(self): return @attr(speed = "slow") - @attr(tags = ["advanced", "advancedns", "smoke"]) + @attr(tags=["advanced", "advancedns", "smoke", "selfservice"]) def test_recurring_snapshot_data_disk(self): """Test Recurring Snapshot data Disk """ @@ -402,4 +404,4 @@ def test_recurring_snapshot_data_disk(self): self.services["recurring_snapshot"]["maxsnaps"], "Check maximum number of recurring snapshots retained" ) - return \ No newline at end of file + return diff --git a/test/integration/component/test_redundant_router_cleanups.py b/test/integration/component/test_redundant_router_cleanups.py index e30c102024..444fa3a66b 100644 --- a/test/integration/component/test_redundant_router_cleanups.py +++ b/test/integration/component/test_redundant_router_cleanups.py @@ -5,9 +5,9 @@ # 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 @@ -16,13 +16,22 @@ # under the License. from nose.plugins.attrib import attr -from marvin.integration.lib.base import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.common import * +from marvin.lib.base import (Account, + Network, + ServiceOffering, + NetworkOffering, + VirtualMachine, + Router, + Configurations) +from marvin.lib.utils import cleanup_resources +from marvin.lib.common import (get_domain, + get_zone, + get_template) #Import Local Modules from marvin.cloudstackTestCase import cloudstackTestCase -from marvin.cloudstackAPI import * +from marvin.cloudstackAPI import startRouter +import time class Services: """Test Services for customer defects @@ -137,14 +146,13 @@ class TestRedundantRouterNetworkCleanups(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestRedundantRouterNetworkCleanups, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestRedundantRouterNetworkCleanups, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, @@ -201,7 +209,7 @@ def tearDown(self): #raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags=["advanced", "advancedns", "ssh"]) + @attr(tags=["advanced", "advancedns", "ssh", "selfservice"]) def test_restart_ntwk_no_cleanup(self): """Test restarting RvR network without cleanup """ @@ -305,13 +313,6 @@ def test_restart_ntwk_no_cleanup(self): "Length of the list router should be 2 (Backup & master)" ) - if routers[0].redundantstate == 'MASTER': - master_router = routers[0] - backup_router = routers[1] - else: - master_router = routers[1] - backup_router = routers[0] - self.debug("restarting network with cleanup=False") try: network.restart(self.apiclient, cleanup=False) @@ -342,7 +343,7 @@ def test_restart_ntwk_no_cleanup(self): ) return - @attr(tags=["advanced", "advancedns", "ssh"]) + @attr(tags=["advanced", "advancedns", "ssh", "selfservice"]) def test_restart_ntwk_with_cleanup(self): """Test restart RvR network with cleanup """ @@ -446,13 +447,6 @@ def test_restart_ntwk_with_cleanup(self): "Length of the list router should be 2 (Backup & master)" ) - if routers[0].redundantstate == 'MASTER': - master_router = routers[0] - backup_router = routers[1] - else: - master_router = routers[1] - backup_router = routers[0] - self.debug("restarting network with cleanup=True") try: network.restart(self.apiclient, cleanup=True) @@ -483,7 +477,7 @@ def test_restart_ntwk_with_cleanup(self): ) return - @attr(tags=["advanced", "advancedns", "ssh"]) + @attr(tags=["advanced", "advancedns", "ssh", "selfservice"]) def test_network_gc(self): """Test network garbage collection with RVR """ @@ -598,12 +592,12 @@ def test_network_gc(self): self.fail("Failed to stop guest Vm: %s - %s" % (virtual_machine.name, e)) - interval = list_configurations( + interval = Configurations( self.apiclient, name='network.gc.interval' ) delay = int(interval[0].value) - interval = list_configurations( + interval = Configurations.list( self.apiclient, name='network.gc.wait' ) diff --git a/test/integration/component/test_redundant_router_services.py b/test/integration/component/test_redundant_router_services.py index 64bb6e99ac..707b673b53 100644 --- a/test/integration/component/test_redundant_router_services.py +++ b/test/integration/component/test_redundant_router_services.py @@ -17,9 +17,9 @@ from nose.plugins.attrib import attr -from marvin.integration.lib.base import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.common import * +from marvin.lib.base import * +from marvin.lib.utils import * +from marvin.lib.common import * #Import Local Modules from marvin.cloudstackTestCase import cloudstackTestCase @@ -138,14 +138,13 @@ class TestEnableVPNOverRvR(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestEnableVPNOverRvR, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestEnableVPNOverRvR, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, @@ -201,7 +200,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags=["advanced", "advancedns", "ssh"]) + @attr(tags=["advanced", "advancedns", "ssh", "selfservice"]) def test_enableVPNOverRvR(self): """Test redundant router internals """ diff --git a/test/integration/component/test_redundant_router_upgrades.py b/test/integration/component/test_redundant_router_upgrades.py index e9303c0126..6c177effa2 100644 --- a/test/integration/component/test_redundant_router_upgrades.py +++ b/test/integration/component/test_redundant_router_upgrades.py @@ -17,9 +17,9 @@ from nose.plugins.attrib import attr -from marvin.integration.lib.base import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.common import * +from marvin.lib.base import * +from marvin.lib.utils import * +from marvin.lib.common import * #Import Local Modules from marvin.cloudstackTestCase import cloudstackTestCase @@ -137,14 +137,13 @@ class TestRvRUpgradeDowngrade(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestRvRUpgradeDowngrade, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestRvRUpgradeDowngrade, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, @@ -200,7 +199,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags=["advanced", "advancedns", "ssh"]) + @attr(tags=["advanced", "advancedns", "ssh", "selfservice"]) def test_upgradeVR_to_redundantVR(self): """Test upgrade virtual router to redundant virtual router """ @@ -345,7 +344,7 @@ def test_upgradeVR_to_redundantVR(self): ) return - @attr(tags=["advanced", "advancedns", "ssh"]) + @attr(tags=["advanced", "advancedns", "ssh", "selfservice"]) def test_downgradeRvR_to_VR(self): """Test downgrade redundant virtual router to virtual router """ diff --git a/test/integration/component/test_region_vpc.py b/test/integration/component/test_region_vpc.py new file mode 100644 index 0000000000..e34806521d --- /dev/null +++ b/test/integration/component/test_region_vpc.py @@ -0,0 +1,523 @@ +# 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 unittest + +""" Component tests for region level VPC functionality +""" +#Import Local Modules +import marvin +from nose.plugins.attrib import attr +from marvin.cloudstackTestCase import * +from marvin.cloudstackAPI import * +from marvin.lib.utils import * +from marvin.lib.base import * +from marvin.lib.common import * +from marvin.sshClient import SshClient +import datetime + + +class Services: + """Test inter VLAN services + """ + + def __init__(self): + self.services = { + "account": { + "email": "test@test.com", + "firstname": "Test", + "lastname": "User", + "username": "test", + # Random characters are appended for unique + # username + "password": "password", + }, + "service_offering": { + "name": "Tiny Instance", + "displaytext": "Tiny Instance", + "cpunumber": 1, + "cpuspeed": 100, + "memory": 128, + }, + "network_offering": { + "name": 'VPC Network offering', + "displaytext": 'VPC Network off', + "guestiptype": 'Isolated', + "supportedservices": 'Vpn,Dhcp,Dns,SourceNat,PortForwarding,Lb,UserData,StaticNat,NetworkACL, Connectivity', + "traffictype": 'GUEST', + "availability": 'Optional', + "useVpc": 'on', + "serviceProviderList": { + "Vpn": 'VpcVirtualRouter', + "Dhcp": 'VpcVirtualRouter', + "Dns": 'VpcVirtualRouter', + "SourceNat": 'VpcVirtualRouter', + "PortForwarding": 'VpcVirtualRouter', + "Lb": 'VpcVirtualRouter', + "UserData": 'VpcVirtualRouter', + "StaticNat": 'VpcVirtualRouter', + "NetworkACL": 'VpcVirtualRouter', + "Connectivity": 'Ovs' + }, + "serviceCapabilityList": { + "Connectivity": { + "StretchedL2Subnet": "true" + }, + }, + }, + "vpc_offering": { + "name": 'VPC off', + "displaytext": 'VPC off', + "supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding,Vpn,Lb,UserData,StaticNat,Connectivity', + "serviceProviderList": { + "Vpn": 'VpcVirtualRouter', + "Dhcp": 'VpcVirtualRouter', + "Dns": 'VpcVirtualRouter', + "SourceNat": 'VpcVirtualRouter', + "PortForwarding": 'VpcVirtualRouter', + "Lb": 'VpcVirtualRouter', + "UserData": 'VpcVirtualRouter', + "StaticNat": 'VpcVirtualRouter', + "Connectivity": 'Ovs' + }, + "serviceCapabilityList": { + "Connectivity": { + "RegionLevelVpc": "true" + }, + }, + }, + "vpc": { + "name": "TestVPC", + "displaytext": "TestVPC", + "cidr": '10.0.0.1/24' + }, + "network": { + "name": "Test Network", + "displaytext": "Test Network", + "netmask": '255.255.255.0' + }, + "lbrule": { + "name": "SSH", + "alg": "leastconn", + # Algorithm used for load balancing + "privateport": 22, + "publicport": 2222, + "openfirewall": False, + "startport": 2222, + "endport": 2222, + "cidrlist": '0.0.0.0/0', + "protocol": 'TCP' + }, + "natrule": { + "privateport": 22, + "publicport": 22, + "startport": 22, + "endport": 22, + "protocol": "TCP", + "cidrlist": '0.0.0.0/0', + }, + "fw_rule": { + "startport": 1, + "endport": 6000, + "cidr": '0.0.0.0/0', + # Any network (For creating FW rule) + "protocol": "TCP" + }, + "virtual_machine": { + "displayname": "Test VM", + "username": "root", + "password": "password", + "ssh_port": 22, + "hypervisor": 'XenServer', + # Hypervisor type should be same as + # hypervisor type of cluster + "privateport": 22, + "publicport": 22, + "protocol": 'TCP', + }, + "ostype": 'CentOS 5.3 (64-bit)', + # Cent OS 5.3 (64 bit) + "sleep": 60, + "timeout": 10, + } + + +class TestRegionVpcOffering(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + testClient = super(TestRegionVpcOffering, cls).getClsTestClient() + cls.apiclient = testClient.getApiClient() + cls.services = testClient.getParsedTestDataConfig() + + # Get Zone, Domain and templates + cls.domain = get_domain(cls.apiclient) + cls.zone = get_zone(cls.apiclient, testClient.getZoneForTests()) + cls.services['mode'] = cls.zone.networktype + + + cls.template = get_template( + cls.apiclient, + cls.zone.id, + cls.services["ostype"] + ) + if cls.template == FAILED: + assert False, "get_template() failed to return template with description %s" % cls.services["ostype"] + + + cls.services["virtual_machine"]["zoneid"] = cls.zone.id + cls.services["virtual_machine"]["template"] = cls.template.id + + cls.service_offering = ServiceOffering.create( + cls.apiclient, + cls.services["service_offering"] + ) + cls._cleanup = [ + cls.service_offering, + ] + return + + @classmethod + def tearDownClass(cls): + try: + #Cleanup resources used + cleanup_resources(cls.apiclient, cls._cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + def setUp(self): + self.apiclient = self.testClient.getApiClient() + self.dbclient = self.testClient.getDbConnection() + self.account = Account.create( + self.apiclient, + self.services["account"], + admin=True, + domainid=self.domain.id + ) + self.cleanup = [] + self.cleanup.insert(0, self.account) + return + + def tearDown(self): + try: + cleanup_resources(self.apiclient, self.cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + def validate_vpc_offering(self, vpc_offering): + """Validates the VPC offering""" + + self.debug("Check if the VPC offering is created successfully?") + vpc_offs = VpcOffering.list( + self.apiclient, + id=vpc_offering.id + ) + self.assertEqual( + isinstance(vpc_offs, list), + True, + "List VPC offerings should return a valid list" + ) + self.assertEqual( + vpc_offering.name, + vpc_offs[0].name, + "Name of the VPC offering should match with listVPCOff data" + ) + self.assertEqual( + vpc_offering.name, + vpc_offs[0].name, + "Name of the VPC offering should match with listVPCOff data" + ) + self.assertEqual( + vpc_offs[0].regionlevelvpc,True, + "VPC offering is not set up for region level VPC" + ) + self.debug( + "VPC offering is created successfully - %s" % + vpc_offering.name) + return + + def validate_vpc_network(self, network): + """Validates the VPC network""" + + self.debug("Check if the VPC network is created successfully?") + vpc_networks = VPC.list( + self.apiclient, + id=network.id + ) + self.assertEqual( + isinstance(vpc_networks, list), + True, + "List VPC network should return a valid list" + ) + self.assertEqual( + network.name, + vpc_networks[0].name, + "Name of the VPC network should match with listVPC data" + ) + self.debug("VPC network created successfully - %s" % network.name) + return + + @attr(tags=["advanced", "intervlan"]) + def test_01_create_vpc_offering_with_regionlevelvpc_service_capability(self): + """ Test create VPC offering + """ + + # Steps for validation + # 1. Create VPC Offering by specifying all supported Services + # 2. VPC offering should be created successfully. + + self.debug("Creating inter VPC offering") + vpc_off = VpcOffering.create( + self.apiclient, + self.services["vpc_offering"] + ) + + self.debug("Check if the VPC offering is created successfully?") + self.cleanup.append(vpc_off) + self.validate_vpc_offering(vpc_off) + return + + @attr(tags=["advanced", "intervlan"]) + def test_02_create_vpc_from_offering_with_regionlevelvpc_service_capability(self): + """ Test create VPC offering + """ + + # Steps for validation + # 1. Create VPC Offering by specifying all supported Services + # 2. VPC offering should be created successfully. + + self.debug("Creating inter VPC offering") + vpc_off = VpcOffering.create( + self.apiclient, + self.services["vpc_offering"] + ) + vpc_off.update(self.apiclient, state='Enabled') + vpc = VPC.create( + self.apiclient, + self.services["vpc"], + vpcofferingid=vpc_off.id, + zoneid=self.zone.id, + account=self.account.name, + domainid=self.account.domainid + ) + self.assertEqual(vpc.distributedvpcrouter, True, "VPC created should have 'distributedvpcrouter' set to True") + + try: + vpc.delete(self.apiclient) + except Exception as e: + self.fail("Failed to delete VPC network - %s" % e) + return + + @attr(tags=["advanced", "intervlan"]) + def test_03_deploy_vms_in_vpc_with_regionlevelvpc(self): + """Test deploy virtual machines in VPC networks""" + + # 1. Create VPC Offering by specifying all supported Services + # (Vpn,dhcpdns,UserData, SourceNat,Static NAT and PF,LB,NetworkAcl) + # 2. Create a VPC using the above VPC offering + # 3. Create a network as part of this VPC. + # 4. Deploy few Vms. + # 5. Create a LB rule for this VM. + # 6. Create a PF rule for this VM. + # 7. Create a Static Nat rule for this VM. + # 8. Create Ingress rules on the network to open the above created + # LB PF and Static Nat rule + # 9. Create Egress Network ACL for this network to access google.com. + # 10. Enable VPN services + + self.debug("Creating a VPC offering..") + vpc_off = VpcOffering.create( + self.apiclient, + self.services["vpc_offering"] + ) + + vpc_off.update(self.apiclient, state='Enabled') + + self.debug("creating a VPC network in the account: %s" % + self.account.name) + vpc = VPC.create( + self.apiclient, + self.services["vpc"], + vpcofferingid=vpc_off.id, + zoneid=self.zone.id, + account=self.account.name, + domainid=self.account.domainid + ) + self.validate_vpc_network(vpc) + + self.network_offering = NetworkOffering.create( + self.apiclient, + self.services["network_offering"], + conservemode=False + ) + # Enable Network offering + self.network_offering.update(self.apiclient, state='Enabled') + + gateway = vpc.cidr.split('/')[0] + # Split the cidr to retrieve gateway + # for eg. cidr = 10.0.0.1/24 + # Gateway = 10.0.0.1 + + # Creating network using the network offering created + self.debug("Creating network with network offering: %s" % + self.network_offering.id) + 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, + gateway=gateway, + vpcid=vpc.id + ) + self.debug("Created network with ID: %s" % network.id) + # Spawn an instance in that network + virtual_machine = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + networkids=[str(network.id)] + ) + self.debug("Deployed VM in network: %s" % network.id) + + self.debug("Associating public IP for network: %s" % network.name) + public_ip = PublicIPAddress.create( + self.apiclient, + accountid=self.account.name, + zoneid=self.zone.id, + domainid=self.account.domainid, + networkid=network.id, + vpcid=vpc.id + ) + self.debug("Associated %s with network %s" % ( + public_ip.ipaddress.ipaddress, + network.id + )) + + self.debug("Creating LB rule for IP address: %s" % + public_ip.ipaddress.ipaddress) + + lb_rule = LoadBalancerRule.create( + self.apiclient, + self.services["lbrule"], + ipaddressid=public_ip.ipaddress.id, + accountid=self.account.name, + networkid=network.id, + vpcid=vpc.id, + domainid=self.account.domainid + ) + + self.debug("Associating public IP for network: %s" % vpc.name) + public_ip_2 = PublicIPAddress.create( + self.apiclient, + accountid=self.account.name, + zoneid=self.zone.id, + domainid=self.account.domainid, + networkid=network.id, + vpcid=vpc.id + ) + self.debug("Associated %s with network %s" % ( + public_ip_2.ipaddress.ipaddress, + network.id + )) + + nat_rule = NATRule.create( + self.apiclient, + virtual_machine, + self.services["natrule"], + ipaddressid=public_ip_2.ipaddress.id, + openfirewall=False, + networkid=network.id, + vpcid=vpc.id + ) + + self.debug("Adding NetwrokACl rules to make PF and LB accessible") + networkacl_1 = NetworkACL.create( + self.apiclient, + networkid=network.id, + services=self.services["natrule"], + traffictype='Ingress' + ) + + networkacl_2 = NetworkACL.create( + self.apiclient, + networkid=network.id, + services=self.services["lbrule"], + traffictype='Ingress' + ) + self.debug("Checking if we can SSH into VM?") + try: + virtual_machine.get_ssh_client( + ipaddress=public_ip_2.ipaddress.ipaddress, + ) + self.debug("SSH into VM is successfully") + except Exception as e: + self.fail("Failed to SSH into VM - %s, %s" % + (public_ip_2.ipaddress.ipaddress, e)) + + self.debug("Associating public IP for network: %s" % network.name) + public_ip_3 = PublicIPAddress.create( + self.apiclient, + accountid=self.account.name, + zoneid=self.zone.id, + domainid=self.account.domainid, + networkid=network.id, + vpcid=vpc.id + ) + self.debug("Associated %s with network %s" % ( + public_ip_3.ipaddress.ipaddress, + network.id + )) + self.debug("Enabling static NAT for IP: %s" % + public_ip_3.ipaddress.ipaddress) + try: + StaticNATRule.enable( + self.apiclient, + ipaddressid=public_ip_3.ipaddress.id, + virtualmachineid=virtual_machine.id, + networkid=network.id + ) + self.debug("Static NAT enabled for IP: %s" % + public_ip_3.ipaddress.ipaddress) + except Exception as e: + self.fail("Failed to enable static NAT on IP: %s - %s" % ( + public_ip_3.ipaddress.ipaddress, e)) + + public_ips = PublicIPAddress.list( + self.apiclient, + networkid=network.id, + listall=True, + isstaticnat=True, + account=self.account.name, + domainid=self.account.domainid + ) + self.assertEqual( + isinstance(public_ips, list), + True, + "List public Ip for network should list the Ip addr" + ) + self.assertEqual( + public_ips[0].ipaddress, + public_ip_3.ipaddress.ipaddress, + "List public Ip for network should list the Ip addr" + ) + # TODO: Remote Access VPN is not yet supported in VPC + return \ No newline at end of file diff --git a/test/integration/component/test_regions.py b/test/integration/component/test_regions.py index 252ba702b2..7b7c4a4db0 100644 --- a/test/integration/component/test_regions.py +++ b/test/integration/component/test_regions.py @@ -17,9 +17,9 @@ from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * +from marvin.lib.utils import * +from marvin.lib.base import * +from marvin.lib.common import * from nose.plugins.attrib import attr from random import choice @@ -41,7 +41,7 @@ class TestRegions(cloudstackTestCase): def setUpClass(cls): cls.api_client = super(TestRegions, cls).getClsTestClient().getApiClient() cls.services = Services().services - cls.domain = get_domain(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) cls.cleanup = [] return @@ -67,14 +67,14 @@ def setUp(self): msg="Region creation failed" ) - @attr(tags=["simulator", "basic", "advanced"]) + @attr(tags=["simulator", "basic", "advanced", "selfservice"]) def test_createRegionWithExistingRegionId(self): """Test for duplicate checks on region id """ self.services["region"]["regionname"] = random_gen() #alter region name but not id self.assertRaises(Exception, Region.create, self.api_client, self.services["region"]) - @attr(tags=["simulator", "basic", "advanced"]) + @attr(tags=["simulator", "basic", "advanced", "selfservice"]) def test_createRegionWithExistingRegionName(self): """Test for duplicate checks on region name """ @@ -83,7 +83,7 @@ def test_createRegionWithExistingRegionName(self): self.services["region"]["regionendpoint"] = "http://region" + str(random_int) + ":8080/client" self.assertRaises(Exception, Region.create, self.api_client, self.services["region"]) - @attr(tags=["simulator", "basic", "advanced"]) + @attr(tags=["simulator", "basic", "advanced", "selfservice"]) def test_updateRegion(self): """ Test for update Region """ diff --git a/test/integration/component/test_regions_accounts.py b/test/integration/component/test_regions_accounts.py index 886e6209f2..a554893468 100644 --- a/test/integration/component/test_regions_accounts.py +++ b/test/integration/component/test_regions_accounts.py @@ -17,9 +17,9 @@ from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * +from marvin.lib.utils import * +from marvin.lib.base import * +from marvin.lib.common import * from nose.plugins.attrib import attr class Services: @@ -57,11 +57,11 @@ class TestRegionsAccounts(cloudstackTestCase): def setUpClass(cls): cls.api_client = super(TestRegionsAccounts, cls).getClsTestClient().getApiClient() cls.services = Services().services - cls.domain = get_domain(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) cls.cleanup = [] return - @attr(tags=["simulator", "basic", "advanced"]) + @attr(tags=["simulator", "basic", "advanced", "selfservice"]) def test_createAccountWithUUID(self): """Test for creating account by passing id parameter @@ -101,7 +101,7 @@ def test_createAccountWithUUID(self): self.cleanup.append(account) return - @attr(tags=["simulator", "basic", "advanced"]) + @attr(tags=["simulator", "basic", "advanced", "selfservice"]) def test_createUserWithUUID(self): """Test for creating User by passing id parameter @@ -152,7 +152,7 @@ def test_createUserWithUUID(self): ) return - @attr(tags=["simulator", "basic", "advanced"]) + @attr(tags=["simulator", "basic", "advanced", "selfservice"]) def test_createdomainWithUUID(self): """Test for creating Domain by passing id parameter diff --git a/test/integration/component/test_reset_ssh_keypair.py b/test/integration/component/test_reset_ssh_keypair.py index ded2529381..d0ddb18aa1 100644 --- a/test/integration/component/test_reset_ssh_keypair.py +++ b/test/integration/component/test_reset_ssh_keypair.py @@ -19,18 +19,17 @@ """ #Import Local Modules -from marvin.integration.lib.base import (VirtualMachine, +from marvin.lib.base import (VirtualMachine, SSHKeyPair, Account, Template, ServiceOffering, - EgressFireWallRule) -from marvin.integration.lib.common import (get_domain, + EgressFireWallRule, + Volume) +from marvin.lib.common import (get_domain, get_zone, - get_template, - list_virtual_machines, - list_volumes) -from marvin.integration.lib.utils import (cleanup_resources, + get_template) +from marvin.lib.utils import (cleanup_resources, random_gen, validateList) from marvin.cloudstackTestCase import cloudstackTestCase, unittest @@ -114,14 +113,13 @@ class TestResetSSHKeypair(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestResetSSHKeypair, - cls).getClsTestClient().getApiClient() + cls.testClient = super(TestResetSSHKeypair, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() cls.services = Services().services # Get Zone, Domain and templates - domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype # Set Zones and disk offerings @@ -137,118 +135,93 @@ def setUpClass(cls): cls.services["virtual_machine"]["zoneid"] = cls.zone.id cls.services["virtual_machine"]["template"] = template.id - # Create VMs, NAT Rules etc - cls.account = Account.create( - cls.api_client, - cls.services["account"], - domainid=domain.id - ) - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - - cls.virtual_machine = VirtualMachine.create( - cls.api_client, - cls.services["virtual_machine"], - accountid=cls.account.name, - domainid=cls.account.domainid, - serviceofferingid=cls.service_offering.id, - mode=cls.services["mode"] - ) - - networkid = cls.virtual_machine.nic[0].networkid - - # create egress rule to allow wget of my cloud-set-guest-password script - if cls.zone.networktype.lower() == 'advanced': - EgressFireWallRule.create(cls.api_client, + cls._cleanup = [] + try: + # Create VMs, NAT Rules etc + cls.account = Account.create( + cls.api_client, + cls.services["account"], + domainid=domain.id) + cls._cleanup.append(cls.account) + + cls.service_offering = ServiceOffering.create( + cls.api_client, + cls.services["service_offering"]) + cls._cleanup.append(cls.service_offering) + + cls.virtual_machine = VirtualMachine.create( + cls.api_client, + cls.services["virtual_machine"], + accountid=cls.account.name, + domainid=cls.account.domainid, + serviceofferingid=cls.service_offering.id, + mode=cls.services["mode"]) + + networkid = cls.virtual_machine.nic[0].networkid + + # create egress rule to allow wget of my cloud-set-guest-password script + if cls.zone.networktype.lower() == 'advanced': + EgressFireWallRule.create(cls.api_client, networkid=networkid, protocol=cls.services["egress"]["protocol"], startport=cls.services["egress"]["startport"], endport=cls.services["egress"]["endport"], cidrlist=cls.services["egress"]["cidrlist"]) - cls.virtual_machine.password = cls.services["virtual_machine"]["password"] - ssh = cls.virtual_machine.get_ssh_client() - - # below steps are required to get the new password from VR(reset password) - # http://cloudstack.org/dl/cloud-set-guest-password - # Copy this file to /etc/init.d - # chmod +x /etc/init.d/cloud-set-guest-password - # chkconfig --add cloud-set-guest-password - # similar steps to get SSH key from web so as to make it ssh enabled - - cmds = [ - "cd /etc/init.d;wget http://people.apache.org/~tsp/cloud-set-guest-password", - "chmod +x /etc/init.d/cloud-set-guest-password", - "chkconfig --add cloud-set-guest-password", - "cd /etc/init.d;wget http://downloads.sourceforge.net/project/cloudstack/SSH%20Key%20Gen%20Script/" + \ - "cloud-set-guest-sshkey.in?r=http%3A%2F%2Fsourceforge" + \ - ".net%2Fprojects%2Fcloudstack%2Ffiles%2FSSH%2520Key%2520Gen%2520Script%2F&ts=1331225219&use_mirror=iweb", - "chmod +x /etc/init.d/cloud-set-guest-sshkey.in", - "chkconfig --add cloud-set-guest-sshkey.in" - ] - for c in cmds: - result = ssh.execute(c) - - #Stop virtual machine - cls.virtual_machine.stop(cls.api_client) - - # Poll listVM to ensure VM is stopped properly - timeout = cls.services["timeout"] - while True: - time.sleep(cls.services["sleep"]) - - # Ensure that VM is in stopped state - list_vm_response = list_virtual_machines( - cls.api_client, - id=cls.virtual_machine.id - ) - - if isinstance(list_vm_response, list): - - vm = list_vm_response[0] - if vm.state == 'Stopped': - break - - if timeout == 0: + cls.virtual_machine.password = cls.services["virtual_machine"]["password"] + ssh = cls.virtual_machine.get_ssh_client() + + # below steps are required to get the new password from VR(reset password) + # http://cloudstack.org/dl/cloud-set-guest-password + # Copy this file to /etc/init.d + # chmod +x /etc/init.d/cloud-set-guest-password + # chkconfig --add cloud-set-guest-password + # similar steps to get SSH key from web so as to make it ssh enabled + + cmds = [ + "cd /etc/init.d;wget http://people.apache.org/~tsp/cloud-set-guest-password", + "chmod +x /etc/init.d/cloud-set-guest-password", + "chkconfig --add cloud-set-guest-password", + "cd /etc/init.d;wget http://downloads.sourceforge.net/project/cloudstack/SSH%20Key%20Gen%20Script/" + \ + "cloud-set-guest-sshkey.in?r=http%3A%2F%2Fsourceforge" + \ + ".net%2Fprojects%2Fcloudstack%2Ffiles%2FSSH%2520Key%2520Gen%2520Script%2F&ts=1331225219&use_mirror=iweb", + "chmod +x /etc/init.d/cloud-set-guest-sshkey.in", + "chkconfig --add cloud-set-guest-sshkey.in" + ] + for c in cmds: + ssh.execute(c) + + #Stop virtual machine + cls.virtual_machine.stop(cls.api_client) + + list_volume = Volume.list( + cls.api_client, + virtualmachineid=cls.virtual_machine.id, + type='ROOT', + listall=True) + + if isinstance(list_volume, list): + cls.volume = list_volume[0] + else: raise Exception( - "Failed to stop VM (ID: %s) " % - vm.id) - - timeout = timeout - 1 - - list_volume = list_volumes( - cls.api_client, - virtualmachineid=cls.virtual_machine.id, - type='ROOT', - listall=True - ) - if isinstance(list_volume, list): - cls.volume = list_volume[0] - else: - raise Exception( "Exception: Unable to find root volume for VM: %s" % cls.virtual_machine.id) - cls.services["template"]["ostype"] = cls.services["ostype"] - #Create templates for Edit, Delete & update permissions testcases - cls.pw_ssh_enabled_template = Template.create( - cls.api_client, - cls.services["template"], - cls.volume.id, - account=cls.account.name, - domainid=cls.account.domainid - ) - # Delete the VM - No longer needed - cls.virtual_machine.delete(cls.api_client) - - cls._cleanup = [ - cls.service_offering, - cls.pw_ssh_enabled_template, - cls.account - ] + cls.services["template"]["ostype"] = cls.services["ostype"] + #Create templates for Edit, Delete & update permissions testcases + cls.pw_ssh_enabled_template = Template.create( + cls.api_client, + cls.services["template"], + cls.volume.id, + account=cls.account.name, + domainid=cls.account.domainid + ) + cls._cleanup.append(cls.pw_ssh_enabled_template) + # Delete the VM - No longer needed + cls.virtual_machine.delete(cls.api_client) + except Exception as e: + cls.tearDownClass() + raise unittest.SkipTest("Exception in setUpClass: %s" % e) @classmethod def tearDownClass(cls): @@ -955,14 +928,13 @@ class TestResetSSHKeyUserRights(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestResetSSHKeyUserRights, - cls).getClsTestClient().getApiClient() + cls.testClient = super(TestResetSSHKeyUserRights, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype # Set Zones and disk offerings @@ -1028,36 +1000,16 @@ def setUpClass(cls): "chkconfig --add cloud-set-guest-sshkey.in" ] for c in cmds: - result = ssh.execute(c) - - #Stop virtual machine - cls.virtual_machine.stop(cls.api_client) + ssh.execute(c) - # Poll listVM to ensure VM is stopped properly - timeout = cls.services["timeout"] - while True: - time.sleep(cls.services["sleep"]) - - # Ensure that VM is in stopped state - list_vm_response = list_virtual_machines( - cls.api_client, - id=cls.virtual_machine.id - ) - - if isinstance(list_vm_response, list): - - vm = list_vm_response[0] - if vm.state == 'Stopped': - break - - if timeout == 0: - raise Exception( - "Failed to stop VM (ID: %s) " % - vm.id) - - timeout = timeout - 1 + try: + #Stop virtual machine + cls.virtual_machine.stop(cls.api_client) + except Exception as e: + cls.tearDownClass() + raise unittest.SkipTest("Exception in setUpClass: %s" % e) - list_volume = list_volumes( + list_volume = Volume.list( cls.api_client, virtualmachineid=cls.virtual_machine.id, type='ROOT', diff --git a/test/integration/component/test_resource_limits.py b/test/integration/component/test_resource_limits.py index f0d558ec2d..9f9cdfa06e 100644 --- a/test/integration/component/test_resource_limits.py +++ b/test/integration/component/test_resource_limits.py @@ -5,9 +5,9 @@ # 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 @@ -19,7 +19,7 @@ #Import Local Modules from nose.plugins.attrib import attr from marvin.cloudstackTestCase import cloudstackTestCase -from marvin.integration.lib.base import (VirtualMachine, +from marvin.lib.base import (VirtualMachine, Snapshot, Template, PublicIPAddress, @@ -31,14 +31,14 @@ NetworkOffering, ServiceOffering, Configurations) -from marvin.integration.lib.common import (list_volumes, +from marvin.lib.common import (list_volumes, get_domain, get_zone, get_template, update_resource_limit, list_configurations, wait_for_cleanup) -from marvin.integration.lib.utils import cleanup_resources +from marvin.lib.utils import cleanup_resources import time @@ -127,11 +127,13 @@ class TestResourceLimitsAccount(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestResourceLimitsAccount, cls).getClsTestClient().getApiClient() + cls.testClient = super(TestResourceLimitsAccount, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + 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( @@ -195,7 +197,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags=["advanced", "advancedns", "simulator"]) + @attr(tags=["advanced", "advancedns", "simulator", "selfservice"]) def test_01_vm_per_account(self): """Test VM limit per account """ @@ -288,7 +290,7 @@ def test_01_vm_per_account(self): ) return - @attr(tags=["advanced", "advancedns", "simulator"]) + @attr(tags=["advanced", "advancedns", "simulator", "selfservice"]) def test_02_publicip_per_account(self): """Test Public IP limit per account """ @@ -432,7 +434,7 @@ def test_02_publicip_per_account(self): return @attr(speed="slow") - @attr(tags=["advanced", "advancedns", "simulator"]) + @attr(tags=["advanced", "advancedns", "simulator", "selfservice"]) def test_03_snapshots_per_account(self): """Test Snapshot limit per account """ @@ -591,7 +593,7 @@ def test_03_snapshots_per_account(self): ) return - @attr(tags=["advanced", "advancedns", "simulator"]) + @attr(tags=["advanced", "advancedns", "simulator", "selfservice"]) def test_04_volumes_per_account(self): """Test Volumes limit per account """ @@ -733,7 +735,7 @@ def test_04_volumes_per_account(self): ) return - @attr(tags=["advanced", "advancedns"]) + @attr(tags=["advanced", "advancedns", "selfservice"]) def test_05_templates_per_account(self): """Test Templates limit per account """ @@ -745,11 +747,12 @@ def test_05_templates_per_account(self): # 3. Try to create 2 templates in account 2. Verify account 2 should be # able to create template without any error - self.debug( - "Updating template resource limit for account: %s" % + try: + self.debug( + "Updating template resource limit for account: %s" % self.account_1.name) - # Set usage_vm=1 for Account 1 - update_resource_limit( + # Set usage_vm=1 for Account 1 + update_resource_limit( self.apiclient, 4, # Template account=self.account_1.name, @@ -757,10 +760,10 @@ def test_05_templates_per_account(self): max=1 ) - self.debug( - "Updating volume resource limit for account: %s" % + self.debug( + "Updating volume resource limit for account: %s" % self.account_1.name) - virtual_machine_1 = VirtualMachine.create( + virtual_machine_1 = VirtualMachine.create( self.apiclient, self.services["server"], templateid=self.template.id, @@ -768,19 +771,19 @@ def test_05_templates_per_account(self): domainid=self.account_1.domainid, serviceofferingid=self.service_offering.id ) - self.cleanup.append(virtual_machine_1) - # Verify VM state - self.assertEqual( + self.cleanup.append(virtual_machine_1) + # Verify VM state + self.assertEqual( virtual_machine_1.state, 'Running', "Check VM state is Running or not" ) - self.debug( - "Deploying virtual machine for account: %s" % + self.debug( + "Deploying virtual machine for account: %s" % self.account_2.name) - # Create VM for second account - virtual_machine_2 = VirtualMachine.create( + # Create VM for second account + virtual_machine_2 = VirtualMachine.create( self.apiclient, self.services["server"], templateid=self.template.id, @@ -788,33 +791,33 @@ def test_05_templates_per_account(self): domainid=self.account_2.domainid, serviceofferingid=self.service_offering.id ) - self.cleanup.append(virtual_machine_2) - # Verify VM state - self.assertEqual( + self.cleanup.append(virtual_machine_2) + # Verify VM state + self.assertEqual( virtual_machine_2.state, 'Running', "Check VM state is Running or not" ) - virtual_machine_1.stop(self.apiclient) - # Get the Root disk of VM - volumes = list_volumes( + virtual_machine_1.stop(self.apiclient) + # Get the Root disk of VM + volumes = list_volumes( self.apiclient, virtualmachineid=virtual_machine_1.id, type='ROOT', listall=True ) - self.assertEqual( + self.assertEqual( isinstance(volumes, list), True, "Check for list volume response return valid data" ) - volume = volumes[0] + volume = volumes[0] - self.debug( - "Creating template from volume: %s" % volume.id) - # Create a template from the ROOTDISK (Account 1) - template_1 = Template.create( + self.debug( + "Creating template from volume: %s" % volume.id) + # Create a template from the ROOTDISK (Account 1) + template_1 = Template.create( self.apiclient, self.services["template"], volumeid=volume.id, @@ -822,14 +825,15 @@ def test_05_templates_per_account(self): domainid=self.account_1.domainid, ) - self.cleanup.append(template_1) - # Verify Template state - self.assertEqual( + self.cleanup.append(template_1) + # Verify Template state + self.assertEqual( template_1.isready, True, "Check Template is in ready state or not" ) - + except Exception as e: + self.fail("Exception occured: %s" % e) # Exception should be raised for second snapshot (account_1) with self.assertRaises(Exception): Template.create( @@ -839,25 +843,27 @@ def test_05_templates_per_account(self): account=self.account_1.name, domainid=self.account_1.domainid, ) - virtual_machine_2.stop(self.apiclient) - # Get the Root disk of VM - volumes = list_volumes( + + try: + virtual_machine_2.stop(self.apiclient) + # Get the Root disk of VM + volumes = list_volumes( self.apiclient, virtualmachineid=virtual_machine_2.id, type='ROOT', listall=True ) - self.assertEqual( + self.assertEqual( isinstance(volumes, list), True, "Check for list volume response return valid data" ) - volume = volumes[0] + volume = volumes[0] - self.debug( - "Creating template from volume: %s" % volume.id) - # Create a snapshot from the ROOTDISK (Account 1) - template_2 = Template.create( + self.debug( + "Creating template from volume: %s" % volume.id) + # Create a snapshot from the ROOTDISK (Account 1) + template_2 = Template.create( self.apiclient, self.services["template"], volumeid=volume.id, @@ -865,17 +871,17 @@ def test_05_templates_per_account(self): domainid=self.account_2.domainid, ) - self.cleanup.append(template_2) - # Verify Template state - self.assertEqual( + self.cleanup.append(template_2) + # Verify Template state + self.assertEqual( template_2.isready, True, "Check Template is in ready state or not" - ) - self.debug( - "Creating template from volume: %s" % volume.id) - # Create a second volume from the ROOTDISK (Account 2) - template_3 = Template.create( + ) + self.debug( + "Creating template from volume: %s" % volume.id) + # Create a second volume from the ROOTDISK (Account 2) + template_3 = Template.create( self.apiclient, self.services["template"], volumeid=volume.id, @@ -883,13 +889,15 @@ def test_05_templates_per_account(self): domainid=self.account_2.domainid, ) - self.cleanup.append(template_3) - # Verify Template state - self.assertEqual( + self.cleanup.append(template_3) + # Verify Template state + self.assertEqual( template_3.isready, True, "Check Template is in ready state or not" ) + except Exception as e: + self.fail("Exception occured: %s" % e) return @@ -897,10 +905,11 @@ class TestResourceLimitsDomain(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestResourceLimitsDomain, cls).getClsTestClient().getApiClient() + cls.testClient = super(TestResourceLimitsDomain, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services - # Get Zone, Domain and templates - cls.zone = get_zone(cls.api_client, cls.services) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype cls.template = get_template( @@ -966,7 +975,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags=["advanced", "advancedns", "simulator"]) + @attr(tags=["advanced", "advancedns", "simulator", "selfservice"]) def test_01_vm_per_domain(self): """Test VM limit per domain """ @@ -1032,7 +1041,7 @@ def test_01_vm_per_domain(self): ) return - @attr(tags=["advanced", "advancedns", "simulator"]) + @attr(tags=["advanced", "advancedns", "simulator", "selfservice"]) def test_01_publicip_per_domain(self): """Test Public IP limit per domain """ @@ -1103,7 +1112,7 @@ def test_01_publicip_per_domain(self): return @attr(speed="slow") - @attr(tags=["advanced", "advancedns", "simulator"]) + @attr(tags=["advanced", "advancedns", "simulator", "selfservice"]) def test_03_snapshots_per_domain(self): """Test Snapshot limit per domain """ @@ -1187,7 +1196,7 @@ def test_03_snapshots_per_domain(self): ) return - @attr(tags=["advanced", "advancedns", "simulator"]) + @attr(tags=["advanced", "advancedns", "simulator", "selfservice"]) def test_04_volumes_per_domain(self): """Test Volumes limit per domain """ @@ -1240,7 +1249,7 @@ def test_04_volumes_per_domain(self): ) return - @attr(tags=["advanced", "advancedns"]) + @attr(tags=["advanced", "advancedns", "selfservice"]) def test_05_templates_per_domain(self): """Test Templates limit per domain """ @@ -1253,27 +1262,23 @@ def test_05_templates_per_domain(self): # 4. Try create 3rd template in the domain. It should give the user an # appropriate error and an alert should be generated. - # Set usage_vm=1 for Account 1 - update_resource_limit( + try: + # Set usage_vm=1 for Account 1 + update_resource_limit( self.apiclient, 2, # Volume domainid=self.account.domainid, max=5 ) - self.debug( - "Updating template resource limits for domain: %s" % - self.account.domainid) - # Set usage_vm=1 for Account 1 - update_resource_limit( + # Set usage_vm=1 for Account 1 + update_resource_limit( self.apiclient, 4, # Template domainid=self.account.domainid, max=2 ) - - self.debug("Deploying VM for account: %s" % self.account.name) - virtual_machine_1 = VirtualMachine.create( + virtual_machine_1 = VirtualMachine.create( self.apiclient, self.services["server"], templateid=self.template.id, @@ -1281,31 +1286,31 @@ def test_05_templates_per_domain(self): domainid=self.account.domainid, serviceofferingid=self.service_offering.id ) - self.cleanup.append(virtual_machine_1) - # Verify VM state - self.assertEqual( + self.cleanup.append(virtual_machine_1) + # Verify VM state + self.assertEqual( virtual_machine_1.state, 'Running', "Check VM state is Running or not" ) - virtual_machine_1.stop(self.apiclient) - # Get the Root disk of VM - volumes = list_volumes( + virtual_machine_1.stop(self.apiclient) + # Get the Root disk of VM + volumes = list_volumes( self.apiclient, virtualmachineid=virtual_machine_1.id, type='ROOT', listall=True ) - self.assertEqual( + self.assertEqual( isinstance(volumes, list), True, "Check for list volume response return valid data" ) - volume = volumes[0] + volume = volumes[0] - self.debug("Creating template from volume: %s" % volume.id) - # Create a template from the ROOTDISK - template_1 = Template.create( + self.debug("Creating template from volume: %s" % volume.id) + # Create a template from the ROOTDISK + template_1 = Template.create( self.apiclient, self.services["template"], volumeid=volume.id, @@ -1313,16 +1318,16 @@ def test_05_templates_per_domain(self): domainid=self.account.domainid, ) - self.cleanup.append(template_1) - # Verify Template state - self.assertEqual( + self.cleanup.append(template_1) + # Verify Template state + self.assertEqual( template_1.isready, True, "Check Template is in ready state or not" ) - self.debug("Creating template from volume: %s" % volume.id) - # Create a template from the ROOTDISK - template_2 = Template.create( + self.debug("Creating template from volume: %s" % volume.id) + # Create a template from the ROOTDISK + template_2 = Template.create( self.apiclient, self.services["template"], volumeid=volume.id, @@ -1330,13 +1335,15 @@ def test_05_templates_per_domain(self): domainid=self.account.domainid, ) - self.cleanup.append(template_2) - # Verify Template state - self.assertEqual( + self.cleanup.append(template_2) + # Verify Template state + self.assertEqual( template_2.isready, True, "Check Template is in ready state or not" ) + except Exception as e: + self.fail("Exception occured: %s" % e) # Exception should be raised for second template with self.assertRaises(Exception): @@ -1354,14 +1361,12 @@ class TestMaxAccountNetworks(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestMaxAccountNetworks, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestMaxAccountNetworks, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) + cls.domain = get_domain(cls.api_client) cls.services['mode'] = cls.zone.networktype cls.template = get_template( cls.api_client, diff --git a/test/integration/component/test_routers.py b/test/integration/component/test_routers.py index ced3f525ca..d729a0779d 100644 --- a/test/integration/component/test_routers.py +++ b/test/integration/component/test_routers.py @@ -21,9 +21,9 @@ from nose.plugins.attrib import attr from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * +from marvin.lib.utils import * +from marvin.lib.base import * +from marvin.lib.common import * #Import System modules import time @@ -98,11 +98,13 @@ class TestRouterServices(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestRouterServices, cls).getClsTestClient().getApiClient() + cls.testClient = super(TestRouterServices, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + 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, @@ -167,7 +169,7 @@ def setUp(self): self.cleanup = [] return - @attr(tags = ["advanced"]) + @attr(tags=["advanced", "selfservice"]) def test_01_AdvancedZoneRouterServices(self): """Test advanced zone router services """ @@ -318,7 +320,7 @@ def test_01_AdvancedZoneRouterServices(self): return @attr(configuration = "network.gc") - @attr(tags = ["advanced"]) + @attr(tags=["advanced", "selfservice"]) def test_02_NetworkGarbageCollection(self): """Test network garbage collection """ @@ -496,7 +498,7 @@ def test_02_NetworkGarbageCollection(self): self.cleanup.append(self.vm_2) return - @attr(tags = ["advanced"]) + @attr(tags=["advanced", "selfservice"]) def test_03_RouterStartOnVmDeploy(self): """Test router start on VM deploy """ @@ -641,11 +643,13 @@ class TestRouterStopCreatePF(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestRouterStopCreatePF, cls).getClsTestClient().getApiClient() + cls.testClient = super(TestRouterStopCreatePF, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype template = get_template( cls.api_client, @@ -703,7 +707,7 @@ def setUp(self): self.cleanup = [] return - @attr(tags = ["advanced", "advancedns"]) + @attr(tags=["advanced", "advancedns", "provisioning"]) def test_01_RouterStopCreatePF(self): """Test router stop create port forwarding """ @@ -853,11 +857,13 @@ class TestRouterStopCreateLB(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestRouterStopCreateLB, cls).getClsTestClient().getApiClient() + cls.testClient = super(TestRouterStopCreateLB, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype template = get_template( cls.api_client, @@ -914,7 +920,7 @@ def setUp(self): self.cleanup = [] return - @attr(tags = ["advanced", "advancedns"]) + @attr(tags=["advanced", "advancedns", "provisioning"]) def test_01_RouterStopCreateLB(self): """Test router stop create Load balancing """ @@ -1065,11 +1071,13 @@ class TestRouterStopCreateFW(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestRouterStopCreateFW, cls).getClsTestClient().getApiClient() + cls.testClient = super(TestRouterStopCreateFW, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype template = get_template( cls.api_client, @@ -1122,10 +1130,11 @@ def tearDown(self): def setUp(self): self.apiclient = self.testClient.getApiClient() + self.hypervisor = self.testClient.getHypervisorInfo() self.cleanup = [] return - @attr(tags = ["advanced", "advancedns"]) + @attr(tags=["advanced", "advancedns", "provisioning"]) def test_01_RouterStopCreateFW(self): """Test router stop create Firewall rule """ @@ -1255,8 +1264,8 @@ def test_01_RouterStopCreateFW(self): "Check end port of firewall rule" ) # For DNS and DHCP check 'dnsmasq' process status - if (self.apiclient.hypervisor.lower() == 'vmware' - or self.apiclient.hypervisor.lower() == 'hyperv'): + if (self.hypervisor.lower() == 'vmware' + or self.hypervisor.lower() == 'hyperv'): result = get_process_status( self.apiclient.connection.mgtSvr, 22, @@ -1264,7 +1273,7 @@ def test_01_RouterStopCreateFW(self): self.apiclient.connection.passwd, router.linklocalip, 'iptables -t nat -L', - hypervisor=self.apiclient.hypervisor + hypervisor=self.hypervisor ) else: hosts = list_hosts( diff --git a/test/integration/component/test_security_groups.py b/test/integration/component/test_security_groups.py index 8e0739658a..63436131fe 100644 --- a/test/integration/component/test_security_groups.py +++ b/test/integration/component/test_security_groups.py @@ -18,13 +18,21 @@ """ P1 for Security groups """ #Import Local Modules -import marvin from nose.plugins.attrib import attr -from marvin.cloudstackTestCase import * -from marvin.cloudstackAPI import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * +from marvin.cloudstackTestCase import cloudstackTestCase +#from marvin.cloudstackAPI import * +from marvin.lib.utils import cleanup_resources +from marvin.lib.base import (Account, + ServiceOffering, + VirtualMachine, + SecurityGroup, + Router, + Host, + Configurations) +from marvin.lib.common import (get_domain, + get_zone, + get_template, + get_process_status) from marvin.sshClient import SshClient #Import System modules @@ -117,12 +125,13 @@ def tearDown(self): @classmethod def setUpClass(cls): - cls.services = Services().services - cls.api_client = super(TestDefaultSecurityGroup, cls).getClsTestClient().getApiClient() + cls.testClient = super(TestDefaultSecurityGroup, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype template = get_template( @@ -185,7 +194,7 @@ def test_01_deployVM_InDefaultSecurityGroup(self): self.debug("Deployed VM with ID: %s" % self.virtual_machine.id) self.cleanup.append(self.virtual_machine) - list_vm_response = list_virtual_machines( + list_vm_response = VirtualMachine.list( self.apiclient, id=self.virtual_machine.id ) @@ -224,7 +233,7 @@ def test_01_deployVM_InDefaultSecurityGroup(self): "Verify list routers response for account: %s" \ % self.account.name ) - routers = list_routers( + routers = Router.list( self.apiclient, zoneid=self.zone.id, listall=True @@ -299,7 +308,7 @@ def test_03_accessInDefaultSecurityGroup(self): self.debug("Deployed VM with ID: %s" % self.virtual_machine.id) self.cleanup.append(self.virtual_machine) - list_vm_response = list_virtual_machines( + list_vm_response = VirtualMachine.list( self.apiclient, id=self.virtual_machine.id ) @@ -361,12 +370,12 @@ def test_03_accessInDefaultSecurityGroup(self): # SSH Attempt to VM should fail with self.assertRaises(Exception): self.debug("SSH into VM: %s" % self.virtual_machine.ssh_ip) - ssh = SshClient( - self.virtual_machine.ssh_ip, - self.virtual_machine.ssh_port, - self.virtual_machine.username, - self.virtual_machine.password - ) + SshClient( + self.virtual_machine.ssh_ip, + self.virtual_machine.ssh_port, + self.virtual_machine.username, + self.virtual_machine.password + ) return @@ -390,12 +399,13 @@ def tearDown(self): @classmethod def setUpClass(cls): - cls.services = Services().services - cls.api_client = super(TestAuthorizeIngressRule, cls).getClsTestClient().getApiClient() + cls.testClient = super(TestAuthorizeIngressRule, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype template = get_template( @@ -526,12 +536,13 @@ def tearDown(self): @classmethod def setUpClass(cls): - cls.services = Services().services - cls.api_client = super(TestRevokeIngressRule, cls).getClsTestClient().getApiClient() + cls.testClient = super(TestRevokeIngressRule, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype template = get_template( @@ -648,7 +659,7 @@ def test_01_revokeIngressRule(self): self.debug("Revoking ingress rule for sec group ID: %s for ssh access" % security_group.id) # Revoke Security group to SSH to VM - result = security_group.revoke( + security_group.revoke( self.apiclient, id=ssh_rule["ruleid"] ) @@ -684,12 +695,13 @@ def tearDown(self): @classmethod def setUpClass(cls): - cls.services = Services().services - cls.api_client = super(TestDhcpOnlyRouter, cls).getClsTestClient().getApiClient() + cls.testClient = super(TestDhcpOnlyRouter, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype template = get_template( @@ -748,7 +760,7 @@ def test_01_dhcpOnlyRouter(self): #2. The only service supported by this router should be dhcp # Find router associated with user account - list_router_response = list_routers( + list_router_response = Router.list( self.apiclient, zoneid=self.zone.id, listall=True @@ -760,7 +772,7 @@ def test_01_dhcpOnlyRouter(self): ) router = list_router_response[0] - hosts = list_hosts( + hosts = Host.list( self.apiclient, zoneid=router.zoneid, type='Routing', @@ -821,12 +833,13 @@ def tearDown(self): @classmethod def setUpClass(cls): - cls.services = Services().services - cls.api_client = super(TestdeployVMWithUserData, cls).getClsTestClient().getApiClient() + cls.testClient = super(TestdeployVMWithUserData, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype template = get_template( @@ -881,7 +894,7 @@ def test_01_deployVMWithUserData(self): # router for this VM # Find router associated with user account - list_router_response = list_routers( + list_router_response = Router.list( self.apiclient, zoneid=self.zone.id, listall=True @@ -985,8 +998,8 @@ def setUp(self): self.services = Services().services # Get Zone, Domain and templates - self.domain = get_domain(self.apiclient, self.services) - self.zone = get_zone(self.apiclient, self.services) + self.domain = get_domain(self.apiclient) + self.zone = get_zone(self.apiclient, self.testClient.getZoneForTests()) self.services['mode'] = self.zone.networktype template = get_template( @@ -1196,7 +1209,7 @@ def test_02_delete_security_grp_withoout_running_vm(self): # Destroy the VM self.virtual_machine.delete(self.apiclient) - config = list_configurations( + config = Configurations.list( self.apiclient, name='expunge.delay' ) @@ -1215,8 +1228,8 @@ def test_02_delete_security_grp_withoout_running_vm(self): self.debug("Deleting Security Group: %s" % security_group.id) security_group.delete(self.apiclient) except Exception as e: - self.fail("Failed to delete security group - ID: %s" \ - % security_group.id + self.fail("Failed to delete security group - ID: %s: %s" \ + % (security_group.id, e) ) return @@ -1232,8 +1245,8 @@ def setUp(self): self.services = Services().services # Get Zone, Domain and templates - self.domain = get_domain(self.apiclient, self.services) - self.zone = get_zone(self.apiclient, self.services) + self.domain = get_domain(self.apiclient) + self.zone = get_zone(self.apiclient, self.testClient.getZoneForTests()) self.services['mode'] = self.zone.networktype template = get_template( @@ -1634,15 +1647,13 @@ def test_03_stopStartVM_verifyIngressAccess(self): % ingress_rule["id"] ) - self.virtual_machine.stop(self.apiclient) - - # Sleep to ensure that VM is in stopped state - time.sleep(self.services["sleep"]) - - self.virtual_machine.start(self.apiclient) - - # Sleep to ensure that VM is in running state - time.sleep(self.services["sleep"]) + try: + self.virtual_machine.stop(self.apiclient) + self.virtual_machine.start(self.apiclient) + # Sleep to ensure that VM is in running state + time.sleep(self.services["sleep"]) + except Exception as e: + self.fail("Exception occured: %s" % e) # SSH should be allowed on 22 port after restart try: diff --git a/test/integration/component/test_shared_networks.py b/test/integration/component/test_shared_networks.py index 99cce19488..f99bfbf8ed 100644 --- a/test/integration/component/test_shared_networks.py +++ b/test/integration/component/test_shared_networks.py @@ -20,7 +20,7 @@ #Import Local Modules from nose.plugins.attrib import attr from marvin.cloudstackTestCase import cloudstackTestCase, unittest -from marvin.integration.lib.base import (Account, +from marvin.lib.base import (Account, Network, NetworkOffering, VirtualMachine, @@ -31,9 +31,9 @@ FireWallRule, ServiceOffering, PublicIPAddress) -from marvin.integration.lib.utils import (cleanup_resources, +from marvin.lib.utils import (cleanup_resources, xsplit) -from marvin.integration.lib.common import (get_domain, +from marvin.lib.common import (get_domain, get_zone, get_template, wait_for_cleanup, @@ -154,16 +154,13 @@ class TestSharedNetworks(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestSharedNetworks, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestSharedNetworks, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, @@ -260,7 +257,7 @@ def tearDown(self): return - @attr(tags=["advanced", "advancedns"]) + @attr(tags=["advanced", "advancedns", "selfservice"]) def test_sharedNetworkOffering_01(self): """ Test shared network Offering 01 """ @@ -396,7 +393,7 @@ def test_sharedNetworkOffering_01(self): ) self.debug("NetworkOffering created and enabled: %s" % self.shared_network_offering.id) - @attr(tags=["advanced", "advancedns"]) + @attr(tags=["advanced", "advancedns", "selfservice"]) def test_sharedNetworkOffering_02(self): """ Test Shared Network Offering 02 """ @@ -485,7 +482,7 @@ def test_sharedNetworkOffering_02(self): self.debug("Network Offering creation failed with vlan as False in advance mode and shared guest type. Exception: %s" % e) - @attr(tags=["advanced", "advancedns"]) + @attr(tags=["advanced", "advancedns", "selfservice"]) def test_sharedNetworkOffering_03(self): """ Test Shared Network Offering 03 """ @@ -575,7 +572,7 @@ def test_sharedNetworkOffering_03(self): self.debug("Network Offering creation failed with vlan as true and ip ranges as False in advance mode and with shared guest type.\ Exception : %s" % e) - @attr(tags=["advanced", "advancedns"]) + @attr(tags=["advanced", "advancedns", "selfservice"]) def test_createSharedNetwork_All(self): """ Test Shared Network ALL """ @@ -846,7 +843,7 @@ def test_createSharedNetwork_All(self): if netaddr.IPAddress(unicode(vms[0].nic[0].ipaddress)) not in ip_range: self.fail("Virtual machine ip should be from the ip range assigned to network created.") - @attr(tags=["advanced", "advancedns"]) + @attr(tags=["advanced", "advancedns", "selfservice"]) def test_createSharedNetwork_accountSpecific(self): """ Test Shared Network with scope account """ @@ -1095,7 +1092,7 @@ def test_createSharedNetwork_accountSpecific(self): if netaddr.IPAddress(unicode(vms[0].nic[0].ipaddress)) not in ip_range: self.fail("Virtual machine ip should be from the ip range assigned to network created.") - @attr(tags=["advanced", "advancedns"]) + @attr(tags=["advanced", "advancedns", "selfservice"]) def test_createSharedNetwork_domainSpecific(self): """ Test Shared Network with scope domain """ @@ -1439,7 +1436,7 @@ def test_createSharedNetwork_domainSpecific(self): if netaddr.IPAddress(unicode(vms[0].nic[0].ipaddress)) not in ip_range: self.fail("Virtual machine ip should be from the ip range assigned to network created.") - @attr(tags=["advanced", "advancedns"]) + @attr(tags=["advanced", "advancedns", "selfservice"]) def test_createSharedNetwork_projectSpecific(self): """ Test Shared Network with scope project """ @@ -1716,7 +1713,7 @@ def test_createSharedNetwork_projectSpecific(self): self.fail("Virtual machine ip should be from the ip range assigned to network created.") @unittest.skip("skipped - This is a redundant case and also this is causing issue for rest fo the cases ") - @attr(tags=["advanced", "advancedns"]) + @attr(tags=["advanced", "advancedns", "NA"]) def test_createSharedNetwork_usedVlan(self): """ Test Shared Network with used vlan 01 """ @@ -1860,7 +1857,7 @@ def test_createSharedNetwork_usedVlan(self): self.debug("Network creation failed because the valn id being used by another network. Exception: %s" % e) - @attr(tags=["advanced", "advancedns"]) + @attr(tags=["advanced", "advancedns", "selfservice"]) def test_createSharedNetwork_usedVlan2(self): """ Test Shared Network with used vlan 02 """ @@ -2042,7 +2039,7 @@ def test_createSharedNetwork_usedVlan2(self): except Exception as e: self.debug("Network creation failed because the valn id being used by another network. Exception: %s" % e) - @attr(tags=["advanced", "advancedns"]) + @attr(tags=["advanced", "advancedns", "selfservice"]) def test_deployVM_multipleSharedNetwork(self): """ Test Vm deployment with multiple shared networks """ @@ -2292,7 +2289,7 @@ def test_deployVM_multipleSharedNetwork(self): self.assertTrue(self.network1_admin_account_virtual_machine.nic[0].ipaddress is not None, "ip should be assigned to running virtual machine") - @attr(tags=["advanced", "advancedns"]) + @attr(tags=["advanced", "advancedns", "provisioning"]) def test_deployVM_isolatedAndShared(self): """ Test VM deployment in shared and isolated networks """ @@ -2631,7 +2628,7 @@ def test_deployVM_isolatedAndShared(self): except Exception as e: self.fail("SSH Access failed for %s: %s" % (self.isolated_network_admin_account_virtual_machine.ipaddress, e)) - @attr(tags=["advanced", "advancedns"]) + @attr(tags=["advanced", "advancedns", "selfservice"]) def test_networkWithsubdomainaccessTrue(self): """ Test Shared Network with subdomainaccess=True """ @@ -2762,7 +2759,7 @@ def test_networkWithsubdomainaccessTrue(self): except: self.debug("Network creation failed because subdomainaccess parameter was passed when scope was account.") - @attr(tags=["advanced", "advancedns"]) + @attr(tags=["advanced", "advancedns", "selfservice"]) def test_networkWithsubdomainaccessFalse(self): """ Test shared Network with subdomainaccess=False """ diff --git a/test/integration/component/test_snapshot_gc.py b/test/integration/component/test_snapshot_gc.py index 1e1cc5dd80..5c475af09c 100644 --- a/test/integration/component/test_snapshot_gc.py +++ b/test/integration/component/test_snapshot_gc.py @@ -16,13 +16,22 @@ # under the License. from nose.plugins.attrib import attr -from marvin.cloudstackTestCase import * -from marvin.cloudstackAPI import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * -from marvin.integration.lib.utils import is_snapshot_on_nfs - +from marvin.cloudstackTestCase import cloudstackTestCase, unittest +#from marvin.cloudstackAPI import * +from marvin.lib.utils import ( + is_snapshot_on_nfs, + cleanup_resources) +from marvin.lib.base import (Account, + Snapshot, + ServiceOffering, + VirtualMachine) +from marvin.lib.common import (get_domain, + get_zone, + get_template, + list_volumes, + list_accounts, + list_snapshots, + wait_for_cleanup) class Services: """Test Snapshots Services @@ -122,11 +131,13 @@ class TestAccountSnapshotClean(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestAccountSnapshotClean, cls).getClsTestClient().getApiClient() + cls.testClient = super(TestAccountSnapshotClean, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype template = get_template( @@ -175,7 +186,7 @@ def setUpClass(cls): volume = volumes[0] # Create a snapshot from the ROOTDISK - cls.snapshot = Snapshot.create(cls.api_client, volumes[0].id) + cls.snapshot = Snapshot.create(cls.api_client, volume.id) except Exception, e: cls.tearDownClass() unittest.SkipTest("setupClass fails for %s" % cls.__name__) @@ -206,7 +217,7 @@ def tearDown(self): return @attr(speed = "slow") - @attr(tags = ["advanced", "advancedns", "basic", "sg"]) + @attr(tags=["advanced", "advancedns", "basic", "sg", "provisioning"]) def test_02_accountSnapshotClean(self): """Test snapshot cleanup after account deletion """ @@ -221,70 +232,50 @@ def test_02_accountSnapshotClean(self): # b) snapshot image($snapshot_id) should be deleted from the # /secondary/snapshots/$accountid/$volumeid/ - accounts = list_accounts( + try: + accounts = list_accounts( self.apiclient, id=self.account.id ) - self.assertEqual( + self.assertEqual( isinstance(accounts, list), True, "Check list response returns a valid list" ) - self.assertNotEqual( + self.assertNotEqual( len(accounts), 0, "Check list Accounts response" ) - # VM should be in 'Running' state - virtual_machines = list_virtual_machines( - self.apiclient, - id=self.virtual_machine.id - ) - self.assertEqual( - isinstance(virtual_machines, list), - True, - "Check list response returns a valid list" - ) - self.assertNotEqual( - len(virtual_machines), - 0, - "Check list virtual machines response" - ) - for virtual_machine in virtual_machines: - self.debug("VM ID: %s, VM state: %s" % ( - virtual_machine.id, - virtual_machine.state - )) - self.assertEqual( - virtual_machine.state, - 'Running', - "Check list VM response for Running state" - ) - - # Verify the snapshot was created or not - snapshots = list_snapshots( + # Verify the snapshot was created or not + snapshots = list_snapshots( self.apiclient, id=self.snapshot.id ) - self.assertEqual( + self.assertEqual( isinstance(snapshots, list), True, "Check list response returns a valid list" ) - self.assertNotEqual( + self.assertNotEqual( snapshots, None, "No such snapshot %s found" % self.snapshot.id ) - self.assertEqual( + self.assertEqual( snapshots[0].id, self.snapshot.id, "Check snapshot id in list resources call" ) - self.assertTrue(is_snapshot_on_nfs(self.apiclient, self.dbclient, self.config, self.zone.id, self.snapshot.id), - "Snapshot was not found on NFS") + self.assertTrue(is_snapshot_on_nfs(self.apiclient, self.dbclient, self.config, self.zone.id, self.snapshot.id), + "Snapshot was not found on NFS") + + raise Exception("self raised exception") + except Exception as e: + self._cleanup.append(self.account) + self.fail("Exception occured: %s" % e) self.debug("Deleting account: %s" % self.account.name) # Delete account diff --git a/test/integration/component/test_snapshot_limits.py b/test/integration/component/test_snapshot_limits.py index a1bf1ba2f5..a7da0dbc63 100644 --- a/test/integration/component/test_snapshot_limits.py +++ b/test/integration/component/test_snapshot_limits.py @@ -18,10 +18,10 @@ from nose.plugins.attrib import attr from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * -from marvin.integration.lib.utils import is_snapshot_on_nfs +from marvin.lib.utils import * +from marvin.lib.base import * +from marvin.lib.common import * +from marvin.lib.utils import is_snapshot_on_nfs import os @@ -123,11 +123,13 @@ class TestSnapshotLimit(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestSnapshotLimit, cls).getClsTestClient().getApiClient() + cls.testClient = super(TestSnapshotLimit, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype cls._cleanup = [] @@ -171,8 +173,6 @@ def setUpClass(cls): cls.tearDownClass() unittest.SkipTest("setupClass fails for %s" % cls.__name__) raise e - else: - cls._cleanup.remove(cls.account) return @classmethod @@ -199,7 +199,7 @@ def tearDown(self): return @attr(speed = "slow") - @attr(tags = ["advanced", "advancedns"]) + @attr(tags=["advanced", "advancedns", "provisioning"]) def test_04_snapshot_limit(self): """Test snapshot limit in snapshot policies """ diff --git a/test/integration/component/test_snapshots.py b/test/integration/component/test_snapshots.py index 17579d63d4..f874bd3770 100644 --- a/test/integration/component/test_snapshots.py +++ b/test/integration/component/test_snapshots.py @@ -20,7 +20,7 @@ from nose.plugins.attrib import attr from marvin.cloudstackTestCase import cloudstackTestCase, unittest -from marvin.integration.lib.base import (Snapshot, +from marvin.lib.base import (Snapshot, Template, VirtualMachine, Account, @@ -28,7 +28,7 @@ DiskOffering, Volume) -from marvin.integration.lib.common import (get_domain, +from marvin.lib.common import (get_domain, get_zone, get_template, list_events, @@ -38,7 +38,7 @@ list_virtual_machines, ) -from marvin.integration.lib.utils import (cleanup_resources, +from marvin.lib.utils import (cleanup_resources, format_volume_to_ext3, random_gen, is_snapshot_on_nfs, @@ -158,11 +158,13 @@ class TestSnapshots(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestSnapshots, cls).getClsTestClient().getApiClient() + cls.testClient = super(TestSnapshots, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype cls.disk_offering = DiskOffering.create( cls.api_client, @@ -229,6 +231,7 @@ def tearDownClass(cls): def setUp(self): self.apiclient = self.testClient.getApiClient() + self.hypervisor = self.testClient.getHypervisorInfo() self.dbclient = self.testClient.getDbConnection() self.cleanup = [] return @@ -242,7 +245,7 @@ def tearDown(self): return @attr(speed = "slow") - @attr(tags = ["advanced", "advancedns", "smoke"]) + @attr(tags=["advanced", "advancedns", "smoke", "provisioning"]) def test_02_snapshot_data_disk(self): """Test Snapshot Data Disk """ @@ -289,7 +292,7 @@ def test_02_snapshot_data_disk(self): return @attr(speed = "slow") - @attr(tags = ["advanced", "advancedns", "basic", "sg"]) + @attr(tags=["advanced", "advancedns", "basic", "sg", "provisioning"]) def test_01_volume_from_snapshot(self): """Test Creating snapshot from volume having spaces in name(KVM) """ @@ -534,7 +537,7 @@ def test_01_volume_from_snapshot(self): return @attr(speed = "slow") - @attr(tags = ["advanced", "advancedns", "smoke"]) + @attr(tags=["advanced", "advancedns", "smoke", "provisioning"]) def test_04_delete_snapshot(self): """Test Delete Snapshot """ @@ -593,7 +596,7 @@ def test_04_delete_snapshot(self): return @attr(speed = "slow") - @attr(tags = ["advanced", "advancedns", "basic", "sg"]) + @attr(tags=["advanced", "advancedns", "basic", "sg", "provisioning"]) def test_03_snapshot_detachedDisk(self): """Test snapshot from detached disk """ @@ -719,7 +722,7 @@ def test_03_snapshot_detachedDisk(self): return @attr(speed = "slow") - @attr(tags = ["advanced", "advancedns", "smoke", "xen"]) + @attr(tags=["advanced", "advancedns", "smoke", "xen", "provisioning"]) def test_07_template_from_snapshot(self): """Create Template from snapshot """ @@ -910,11 +913,13 @@ class TestCreateVMSnapshotTemplate(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestCreateVMSnapshotTemplate, cls).getClsTestClient().getApiClient() + cls.testClient = super(TestCreateVMSnapshotTemplate, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + 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( @@ -956,6 +961,7 @@ def tearDownClass(cls): def setUp(self): self.apiclient = self.testClient.getApiClient() + self.hypervisor = self.testClient.getHypervisorInfo() self.dbclient = self.testClient.getDbConnection() self.cleanup = [] return @@ -969,7 +975,7 @@ def tearDown(self): return @attr(speed = "slow") - @attr(tags = ["advanced", "advancedns"]) + @attr(tags=["advanced", "advancedns", "provisioning"]) def test_01_createVM_snapshotTemplate(self): """Test create VM, Snapshot and Template """ @@ -1108,11 +1114,14 @@ class TestSnapshotEvents(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestSnapshotEvents, cls).getClsTestClient().getApiClient() + cls.testClient = super(TestSnapshotEvents, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype template = get_template( @@ -1163,6 +1172,7 @@ def tearDownClass(cls): def setUp(self): self.apiclient = self.testClient.getApiClient() + self.hypervisor = self.testClient.getHypervisorInfo() self.dbclient = self.testClient.getDbConnection() self.cleanup = [] return @@ -1176,7 +1186,7 @@ def tearDown(self): return @attr(speed = "slow") - @attr(tags = ["advanced", "advancedns"]) + @attr(tags=["advanced", "advancedns", "selfservice"]) def test_05_snapshot_events(self): """Test snapshot events """ diff --git a/test/integration/component/test_snapshots_improvement.py b/test/integration/component/test_snapshots_improvement.py index 77c240d34f..b2b0a546d5 100644 --- a/test/integration/component/test_snapshots_improvement.py +++ b/test/integration/component/test_snapshots_improvement.py @@ -20,10 +20,10 @@ # Import Local Modules from nose.plugins.attrib import attr from marvin.cloudstackTestCase import cloudstackTestCase, unittest -from marvin.integration.lib.utils import (random_gen, +from marvin.lib.utils import (random_gen, is_snapshot_on_nfs, cleanup_resources) -from marvin.integration.lib.base import ( +from marvin.lib.base import ( Account, ServiceOffering, VirtualMachine, @@ -32,7 +32,7 @@ Volume, DiskOffering ) -from marvin.integration.lib.common import (get_domain, +from marvin.lib.common import (get_domain, get_zone, get_template, list_snapshots @@ -126,11 +126,13 @@ class TestSnapshotOnRootVolume(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestSnapshotOnRootVolume, - cls).getClsTestClient().getApiClient() + cls.testClient = super(TestSnapshotOnRootVolume, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + # Get Zone, Domain and templates + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, @@ -183,7 +185,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags=["advanced", "basic"]) + @attr(tags=["advanced", "basic", "provisioning"]) def test_01_snapshot_on_rootVolume(self): """Test create VM with default cent os template and create snapshot on root disk of the vm @@ -299,13 +301,13 @@ class TestCreateSnapshot(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestCreateSnapshot, - cls).getClsTestClient().getApiClient() + cls.testClient = super(TestCreateSnapshot, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, diff --git a/test/integration/component/test_stopped_vm.py b/test/integration/component/test_stopped_vm.py index 4ba94bfc29..04dd859d0c 100644 --- a/test/integration/component/test_stopped_vm.py +++ b/test/integration/component/test_stopped_vm.py @@ -18,13 +18,27 @@ """ P1 for stopped Virtual Maschine life cycle """ #Import Local Modules -import marvin from nose.plugins.attrib import attr -from marvin.cloudstackTestCase import * -from marvin.cloudstackAPI import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * +from marvin.cloudstackTestCase import cloudstackTestCase +#from marvin.cloudstackAPI import * +from marvin.lib.utils import cleanup_resources +from marvin.lib.base import (Account, + VirtualMachine, + ServiceOffering, + Volume, + Router, + DiskOffering, + Host, + Iso, + Cluster, + StoragePool, + Configurations, + Template) +from marvin.lib.common import (get_zone, + get_domain, + get_template, + get_builtin_template_info, + update_resource_limit) #Import System modules import time @@ -108,14 +122,13 @@ class TestDeployVM(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestDeployVM, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestDeployVM, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, @@ -170,7 +183,7 @@ def tearDown(self): except Exception as e: self.debug("Warning! Exception in tearDown: %s" % e) - @attr(tags = ["advanced", "eip", "advancedns", "basic", "sg"]) + @attr(tags=["advanced", "eip", "advancedns", "selfservice"]) def test_01_deploy_vm_no_startvm(self): """Test Deploy Virtual Machine with no startVM parameter """ @@ -195,7 +208,7 @@ def test_01_deploy_vm_no_startvm(self): self.debug("Deployed instance in account: %s" % self.account.name) - list_vm_response = list_virtual_machines( + list_vm_response = VirtualMachine.list( self.apiclient, id=self.virtual_machine.id ) @@ -220,7 +233,7 @@ def test_01_deploy_vm_no_startvm(self): ) return - @attr(tags = ["advanced", "eip", "advancedns", "basic", "sg"]) + @attr(tags=["advanced", "eip", "advancedns", "basic", "sg", "selfservice"]) def test_02_deploy_vm_startvm_true(self): """Test Deploy Virtual Machine with startVM=true parameter """ @@ -246,7 +259,7 @@ def test_02_deploy_vm_startvm_true(self): self.debug("Deployed instance in account: %s" % self.account.name) - list_vm_response = list_virtual_machines( + list_vm_response = VirtualMachine.list( self.apiclient, id=self.virtual_machine.id ) @@ -271,7 +284,7 @@ def test_02_deploy_vm_startvm_true(self): ) return - @attr(tags = ["advanced", "eip", "advancedns", "basic", "sg"]) + @attr(tags=["advanced", "eip", "advancedns", "basic", "sg", "selfservice"]) def test_03_deploy_vm_startvm_false(self): """Test Deploy Virtual Machine with startVM=false parameter """ @@ -298,7 +311,7 @@ def test_03_deploy_vm_startvm_false(self): self.debug("Deployed instance in account: %s" % self.account.name) - list_vm_response = list_virtual_machines( + list_vm_response = VirtualMachine.list( self.apiclient, id=self.virtual_machine.id ) @@ -341,17 +354,17 @@ def test_03_deploy_vm_startvm_false(self): ) self.debug("Instance destroyed..waiting till expunge interval") - interval = list_configurations( + interval = Configurations.list( self.apiclient, name='expunge.interval' ) - delay = list_configurations( + delay = Configurations.list( self.apiclient, name='expunge.delay' ) # Sleep to ensure that all resources are deleted time.sleep((int(interval[0].value) + int(delay[0].value))) - list_vm_response = list_virtual_machines( + list_vm_response = VirtualMachine.list( self.apiclient, id=self.virtual_machine.id ) @@ -363,7 +376,7 @@ def test_03_deploy_vm_startvm_false(self): ) return - @attr(tags = ["advanced", "eip", "advancedns", "basic", "sg"]) + @attr(tags=["advanced", "eip", "advancedns", "basic", "sg", "selfservice"]) def test_04_deploy_startvm_false_attach_volume(self): """Test Deploy Virtual Machine with startVM=false and attach volume """ @@ -388,7 +401,7 @@ def test_04_deploy_startvm_false_attach_volume(self): self.debug("Deployed instance in account: %s" % self.account.name) - list_vm_response = list_virtual_machines( + list_vm_response = VirtualMachine.list( self.apiclient, id=self.virtual_machine.id ) @@ -426,10 +439,10 @@ def test_04_deploy_startvm_false_attach_volume(self): try: self.virtual_machine.attach_volume(self.apiclient, volume) except Exception as e: - self.fail("Attach volume failed!") + self.fail("Attach volume failed with Exception: %s" % e) return - @attr(tags = ["advanced", "eip", "advancedns", "basic", "sg"]) + @attr(tags=["advanced", "eip", "advancedns", "basic", "sg", "selfservice"]) def test_05_deploy_startvm_false_change_so(self): """Test Deploy Virtual Machine with startVM=false and change service offering """ @@ -453,7 +466,7 @@ def test_05_deploy_startvm_false_change_so(self): self.debug("Deployed instance in account: %s" % self.account.name) - list_vm_response = list_virtual_machines( + list_vm_response = VirtualMachine.list( self.apiclient, id=self.virtual_machine.id ) @@ -502,7 +515,7 @@ def test_05_deploy_startvm_false_change_so(self): return - @attr(tags = ["advanced", "eip", "advancedns", "basic", "sg"]) + @attr(tags=["advanced", "eip", "advancedns", "basic", "sg", "selfservice"]) def test_06_deploy_startvm_attach_detach(self): """Test Deploy Virtual Machine with startVM=false and attach detach volumes @@ -529,7 +542,7 @@ def test_06_deploy_startvm_attach_detach(self): self.debug("Deployed instance in account: %s" % self.account.name) - list_vm_response = list_virtual_machines( + list_vm_response = VirtualMachine.list( self.apiclient, id=self.virtual_machine.id ) @@ -567,7 +580,7 @@ def test_06_deploy_startvm_attach_detach(self): try: self.virtual_machine.attach_volume(self.apiclient, volume) except Exception as e: - self.fail("Attach volume failed!") + self.fail("Attach volume failed with Exception: %s" % e) self.debug("Detaching the disk: %s" % volume.name) self.virtual_machine.detach_volume(self.apiclient, volume) @@ -587,7 +600,7 @@ def test_06_deploy_startvm_attach_detach(self): ) return - @attr(tags = ["advanced", "eip", "advancedns", "basic", "sg"]) + @attr(tags=["advanced", "eip", "advancedns", "basic", "sg", "selfservice"]) def test_07_deploy_startvm_attach_iso(self): """Test Deploy Virtual Machine with startVM=false and attach ISO """ @@ -612,7 +625,7 @@ def test_07_deploy_startvm_attach_iso(self): self.debug("Deployed instance in account: %s" % self.account.name) - list_vm_response = list_virtual_machines( + list_vm_response = VirtualMachine.list( self.apiclient, id=self.virtual_machine.id ) @@ -678,7 +691,7 @@ def test_07_deploy_startvm_attach_iso(self): ) return - @attr(tags = ["advanced", "eip", "advancedns", "basic", "sg"]) + @attr(tags=["advanced", "eip", "advancedns", "basic", "sg", "selfservice"]) def test_08_deploy_attached_volume(self): """Test Deploy Virtual Machine with startVM=false and attach volume already attached to different machine """ @@ -703,7 +716,7 @@ def test_08_deploy_attached_volume(self): self.debug("Deployed instance in account: %s" % self.account.name) - list_vm_response = list_virtual_machines( + list_vm_response = VirtualMachine.list( self.apiclient, id=self.virtual_machine_1.id ) @@ -739,7 +752,7 @@ def test_08_deploy_attached_volume(self): self.debug("Deployed instance in account: %s" % self.account.name) - list_vm_response = list_virtual_machines( + list_vm_response = VirtualMachine.list( self.apiclient, id=self.virtual_machine_2.id ) @@ -808,7 +821,7 @@ def test_08_deploy_attached_volume(self): ) return - @attr(tags = ["advanced", "eip", "advancedns", "basic", "sg"]) + @attr(tags=["advanced", "eip", "advancedns", "basic", "sg", "selfservice"]) def test_09_stop_vm_migrate_vol(self): """Test Stopped Virtual Machine's ROOT volume migration """ @@ -869,7 +882,7 @@ def test_09_stop_vm_migrate_vol(self): self.debug("Deployed instance in account: %s" % self.account.name) - list_vm_response = list_virtual_machines( + list_vm_response = VirtualMachine.list( self.apiclient, id=self.virtual_machine.id ) @@ -890,28 +903,10 @@ def test_09_stop_vm_migrate_vol(self): "Running", "VM should be in Running state after deployment" ) - self.debug("Stopping instance: %s" % self.virtual_machine.name) - self.virtual_machine.stop(self.apiclient) - self.debug("Instance is stopped!") - self.debug( - "Verify listVirtualMachines response for virtual machine: %s" \ - % self.virtual_machine.id - ) - list_vm_response = list_virtual_machines( - self.apiclient, - id=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, - "Stopped", - "VM should be in Stopped state after stoping vm" - ) + try: + self.virtual_machine.stop(self.apiclient) + except Exception as e: + self.fail("failed to stop instance: %s" % e) volumes = Volume.list( self.apiclient, virtualmachineid=self.virtual_machine.id, @@ -962,14 +957,13 @@ class TestDeployHaEnabledVM(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestDeployHaEnabledVM, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestDeployHaEnabledVM, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, @@ -1025,7 +1019,7 @@ def tearDown(self): except Exception as e: self.debug("Warning! Exception in tearDown: %s" % e) - @attr(tags = ["advanced", "eip", "advancedns", "basic", "sg"]) + @attr(tags=["advanced", "eip", "advancedns", "basic", "sg", "selfservice"]) def test_01_deploy_ha_vm_startvm_false(self): """Test Deploy HA enabled Virtual Machine with startvm=false """ @@ -1049,7 +1043,7 @@ def test_01_deploy_ha_vm_startvm_false(self): self.debug("Deployed instance in account: %s" % self.account.name) - list_vm_response = list_virtual_machines( + list_vm_response = VirtualMachine.list( self.apiclient, id=self.virtual_machine.id ) @@ -1074,7 +1068,7 @@ def test_01_deploy_ha_vm_startvm_false(self): ) return - @attr(tags = ["advanced", "eip", "advancedns", "basic", "sg"]) + @attr(tags=["advanced", "eip", "advancedns", "basic", "sg", "selfservice"]) def test_02_deploy_ha_vm_from_iso(self): """Test Deploy HA enabled Virtual Machine from ISO """ @@ -1114,7 +1108,7 @@ def test_02_deploy_ha_vm_from_iso(self): self.debug("Deployed instance in account: %s" % self.account.name) - list_vm_response = list_virtual_machines( + list_vm_response = VirtualMachine.list( self.apiclient, id=self.virtual_machine.id ) @@ -1139,7 +1133,7 @@ def test_02_deploy_ha_vm_from_iso(self): ) return - @attr(tags = ["advanced", "eip", "advancedns", "basic", "sg"]) + @attr(tags=["advanced", "eip", "advancedns", "basic", "sg", "selfservice"]) def test_03_deploy_ha_vm_iso_startvm_false(self): """Test Deploy HA enabled Virtual Machine from ISO with startvm=false """ @@ -1163,7 +1157,7 @@ def test_03_deploy_ha_vm_iso_startvm_false(self): self.debug("Deployed instance in account: %s" % self.account.name) - list_vm_response = list_virtual_machines( + list_vm_response = VirtualMachine.list( self.apiclient, id=self.virtual_machine.id ) @@ -1194,14 +1188,13 @@ class TestRouterStateAfterDeploy(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestRouterStateAfterDeploy, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestRouterStateAfterDeploy, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, @@ -1256,7 +1249,7 @@ def tearDown(self): except Exception as e: self.debug("Warning! Exception in tearDown: %s" % e) - @attr(tags = ["advanced", "eip", "advancedns"]) + @attr(tags=["advanced", "eip", "advancedns", "selfservice"]) def test_01_deploy_vm_no_startvm(self): """Test Deploy Virtual Machine with no startVM parameter """ @@ -1281,7 +1274,7 @@ def test_01_deploy_vm_no_startvm(self): self.debug("Deployed instance in account: %s" % self.account.name) - list_vm_response = list_virtual_machines( + list_vm_response = VirtualMachine.list( self.apiclient, id=self.virtual_machine_1.id ) @@ -1331,7 +1324,7 @@ def test_01_deploy_vm_no_startvm(self): self.debug("Deployed instance in account: %s" % self.account.name) - list_vm_response = list_virtual_machines( + list_vm_response = VirtualMachine.list( self.apiclient, id=self.virtual_machine_2.id ) @@ -1378,11 +1371,11 @@ def test_01_deploy_vm_no_startvm(self): self.virtual_machine_2.delete(self.apiclient) self.debug("Instance destroyed..waiting till expunge interval") - interval = list_configurations( + interval = Configurations.list( self.apiclient, name='expunge.interval' ) - delay = list_configurations( + delay = Configurations.list( self.apiclient, name='expunge.delay' ) @@ -1409,14 +1402,13 @@ class TestDeployVMBasicZone(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestDeployVMBasicZone, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestDeployVMBasicZone, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, @@ -1477,14 +1469,13 @@ class TestDeployVMFromTemplate(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestDeployVMFromTemplate, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestDeployVMFromTemplate, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) # Create service, disk offerings etc cls.service_offering = ServiceOffering.create( @@ -1511,8 +1502,8 @@ def tearDownClass(cls): raise Exception("Warning: Exception during cleanup : %s" % e) def setUp(self): - self.apiclient = self.testClient.getApiClient() + self.hypervisor = self.testClient.getHypervisorInfo() self.dbclient = self.testClient.getDbConnection() self.services = Services().services self.services["virtual_machine"]["zoneid"] = self.zone.id @@ -1523,8 +1514,8 @@ def setUp(self): ) builtin_info = get_builtin_template_info(self.apiclient, self.zone.id) - self.services["template"]["url"] = builtin_info[0] - self.services["template"]["hypervisor"] = builtin_info[1] + self.services["template"]["url"] = builtin_info[0] + self.services["template"]["hypervisor"] = builtin_info[1] self.services["template"]["format"] = builtin_info[2] # Register new template @@ -1533,7 +1524,8 @@ def setUp(self): self.services["template"], zoneid=self.zone.id, account=self.account.name, - domainid=self.account.domainid + domainid=self.account.domainid, + hypervisor=self.hypervisor ) self.debug( "Registered a template of format: %s with ID: %s" % ( @@ -1556,7 +1548,7 @@ def tearDown(self): except Exception as e: self.debug("Warning! Exception in tearDown: %s" % e) - @attr(tags = ["advanced", "eip", "advancedns", "basic", "sg"]) + @attr(tags=["advanced", "eip", "advancedns", "basic", "sg", "provisioning"]) def test_deploy_vm_password_enabled(self): """Test Deploy Virtual Machine with startVM=false & enabledpassword in template @@ -1582,7 +1574,7 @@ def test_deploy_vm_password_enabled(self): self.debug("Deployed instance in account: %s" % self.account.name) - list_vm_response = list_virtual_machines( + list_vm_response = VirtualMachine.list( self.apiclient, id=self.virtual_machine.id ) @@ -1609,7 +1601,7 @@ def test_deploy_vm_password_enabled(self): self.virtual_machine.start(self.apiclient) self.debug("Started the instance: %s" % self.virtual_machine.name) - list_vm_response = list_virtual_machines( + list_vm_response = VirtualMachine.list( self.apiclient, id=self.virtual_machine.id ) @@ -1638,14 +1630,13 @@ class TestVMAccountLimit(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestVMAccountLimit, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestVMAccountLimit, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, @@ -1694,7 +1685,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags = ["advanced", "eip", "advancedns", "basic", "sg"]) + @attr(tags=["advanced", "eip", "advancedns", "basic", "sg", "selfservice"]) def test_vm_per_account(self): """Test VM limit per account """ @@ -1754,14 +1745,13 @@ class TestUploadAttachVolume(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestUploadAttachVolume, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestUploadAttachVolume, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, @@ -1810,7 +1800,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags = ["advanced", "eip", "advancedns", "basic", "sg"]) + @attr(tags=["advanced", "eip", "advancedns", "basic", "sg", "selfservice"]) def test_upload_attach_volume(self): """Test Upload volume and attach to VM in stopped state """ @@ -1864,14 +1854,13 @@ class TestDeployOnSpecificHost(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestDeployOnSpecificHost, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestDeployOnSpecificHost, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, diff --git a/test/integration/component/test_storage_motion.py b/test/integration/component/test_storage_motion.py index 194ba97709..5b9086bdc3 100644 --- a/test/integration/component/test_storage_motion.py +++ b/test/integration/component/test_storage_motion.py @@ -20,9 +20,9 @@ import marvin from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * +from marvin.lib.utils import * +from marvin.lib.base import * +from marvin.lib.common import * from nose.plugins.attrib import attr #Import System modules import time @@ -89,12 +89,13 @@ class TestStorageMotion(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestStorageMotion, cls).getClsTestClient().getApiClient() - cls.services = Services().services + cls.testClient = super(TestStorageMotion, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype template = get_template( @@ -148,7 +149,7 @@ def tearDown(self): cleanup_resources(self.apiclient, self.cleanup) return - @attr(tags = ["advanced", "basic", "multicluster", "storagemotion", "xenserver"]) + @attr(tags=["advanced", "basic", "multicluster", "storagemotion", "xenserver", "provisioning"]) def test_01_migrate_vm_with_volume(self): """Test migrate virtual machine with its volumes """ @@ -226,7 +227,7 @@ def test_01_migrate_vm_with_volume(self): ) return - @attr(tags = ["advanced", "basic", "multipool", "storagemotion", "xenserver"]) + @attr(tags=["advanced", "basic", "multipool", "storagemotion", "xenserver", "selfservice"]) def test_02_migrate_volume(self): """Test migrate volume of a running vm """ diff --git a/test/integration/component/test_tags.py b/test/integration/component/test_tags.py index 2a6e0764f2..fbe64367bf 100644 --- a/test/integration/component/test_tags.py +++ b/test/integration/component/test_tags.py @@ -17,15 +17,31 @@ """ P1 tests for tags """ #Import Local Modules -import marvin from nose.plugins.attrib import attr -from marvin.cloudstackTestCase import * -from marvin.cloudstackAPI import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * -import datetime - +from marvin.cloudstackTestCase import cloudstackTestCase +from marvin.lib.utils import cleanup_resources +from marvin.lib.base import (Tag, + Account, + VirtualMachine, + Iso, + Volume, + Network, + Host, + DiskOffering, + NATRule, + PublicIPAddress, + FireWallRule, + LoadBalancerRule, + Vpn, + Template, + Snapshot, + ServiceOffering, + Project) +from marvin.lib.common import (get_zone, + get_domain, + get_template) +from marvin.codes import FAILED +import time class Services: """Test tags Services @@ -174,30 +190,28 @@ class TestResourceTags(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestResourceTags, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestResourceTags, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services - # Get Zone - cls.zone = get_zone(cls.api_client, cls.services) - # Create domains, account etc. - cls.domain = get_domain(cls.api_client, cls.services) - - cls.account = Account.create( - cls.api_client, - cls.services["account"], - admin=True, - ) - cls.zone = get_zone(cls.api_client, cls.services) + # Get Zone, Domain and templates + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) + cls.domain = get_domain(cls.api_client) cls.template = get_template( cls.api_client, cls.zone.id, cls.services["ostype"] ) + if cls.template == FAILED: + assert False, "get_template() failed to return template with description %s" % cls.services["ostype"] + cls.account = Account.create( + cls.api_client, + cls.services["account"], + admin=True, + ) # Create service offerings, disk offerings etc cls.service_offering = ServiceOffering.create( cls.api_client, @@ -266,7 +280,7 @@ def tearDown(self): return - @attr(tags=["advanced"]) + @attr(tags=["advanced", "selfservice"]) def test_01_lbrule_tag(self): """ Test Create tag on LB rule and remove the LB rule """ @@ -409,7 +423,7 @@ def test_01_lbrule_tag(self): self.fail("failed to delete load balancer rule! - %s" % e) return - @attr(tags=["advanced"]) + @attr(tags=["advanced", "selfservice"]) def test_02_natrule_tag(self): """ Test Create tag on nat rule and remove the nat rule """ @@ -546,7 +560,7 @@ def test_02_natrule_tag(self): self.fail("failed to delete port forwarding rule! - %s" % e) return - @attr(tags=["advanced"]) + @attr(tags=["advanced", "selfservice"]) def test_03_firewallrule_tag(self): """ Test Create tag on firewall rule and remove the firewall rule """ @@ -689,7 +703,7 @@ def test_03_firewallrule_tag(self): self.fail("failed to delete firewall rule! - %s" % e) return - @attr(tags=["advanced"]) + @attr(tags=["advanced", "selfservice"]) def test_04_vpn_tag(self): """ Test Create tag on vpn and remove the vpn """ @@ -841,7 +855,7 @@ def test_04_vpn_tag(self): self.fail("failed to disable VPN! - %s" % e) return - @attr(tags=["advanced", "basic"]) + @attr(tags=["advanced", "basic", "selfservice"]) def test_05_vm_tag(self): """ Test creation, listing and deletion tags on UserVM """ @@ -918,7 +932,7 @@ def test_05_vm_tag(self): ) return - @attr(tags=["advanced", "basic"]) + @attr(tags=["advanced", "basic", "selfservice"]) def test_06_template_tag(self): """ Test creation, listing and deletion tag on templates """ @@ -926,14 +940,14 @@ def test_06_template_tag(self): # 1. Create a tag on template/ISO using createTags API # 2. Delete above created tag using deleteTags API - self.debug("Stopping the virtual machine: %s" % self.vm_1.name) - #Stop virtual machine - self.vm_1.stop(self.apiclient) + try: + self.debug("Stopping the virtual machine: %s" % self.vm_1.name) + #Stop virtual machine + self.vm_1.stop(self.apiclient) + except Exception as e: + self.fail("Failed to stop VM: %s" % e) timeout = self.services["timeout"] - #Wait before server has be successfully stopped - time.sleep(self.services["sleep"]) - while True: list_volume = Volume.list( self.apiclient, @@ -992,11 +1006,11 @@ def test_06_template_tag(self): 'CentOS', 'The tag should have original value' ) - - templates = Template.list( + + Template.list( self.apiclient, templatefilter=\ - self.services["template"]["templatefilter"], + self.services["template"]["templatefilter"], listall=True, key='OS', value='CentOS' @@ -1030,7 +1044,7 @@ def test_06_template_tag(self): ) return - @attr(tags=["advanced", "basic"]) + @attr(tags=["advanced", "basic", "selfservice"]) def test_07_iso_tag(self): """ Test creation, listing and deletion tags on ISO """ @@ -1046,10 +1060,8 @@ def test_07_iso_tag(self): ) self.debug("ISO created with ID: %s" % iso.id) - list_iso_response = list_isos( - self.apiclient, - id=iso.id - ) + list_iso_response = Iso.list(self.apiclient, + id=iso.id) self.assertEqual( isinstance(list_iso_response, list), True, @@ -1127,7 +1139,7 @@ def test_07_iso_tag(self): ) return - @attr(tags=["advanced", "basic"]) + @attr(tags=["advanced", "basic", "selfservice"]) def test_08_volume_tag(self): """ Test creation, listing and deletion tagson volume """ @@ -1216,7 +1228,7 @@ def test_08_volume_tag(self): ) return - @attr(tags=["advanced", "basic"]) + @attr(tags=["advanced", "basic", "selfservice"]) def test_09_snapshot_tag(self): """ Test creation, listing and deletion tag son snapshot """ @@ -1227,12 +1239,10 @@ def test_09_snapshot_tag(self): self.debug("Creating snapshot on ROOT volume for VM: %s " % self.vm_1.name) # Get the Root disk of VM - volumes = list_volumes( - self.apiclient, - virtualmachineid=self.vm_1.id, - type='ROOT', - listall=True - ) + volumes = Volume.list(self.apiclient, + virtualmachineid=self.vm_1.id, + type='ROOT', + listall=True) volume = volumes[0] # Create a snapshot from the ROOTDISK @@ -1240,10 +1250,8 @@ def test_09_snapshot_tag(self): self.debug("Snapshot created: ID - %s" % snapshot.id) self.cleanup.append(snapshot) - snapshots = list_snapshots( - self.apiclient, - id=snapshot.id - ) + snapshots = Snapshot.list(self.apiclient, + id=snapshot.id) self.assertEqual( isinstance(snapshots, list), True, @@ -1277,13 +1285,10 @@ def test_09_snapshot_tag(self): 'manual', 'The tag should have original value' ) - - snapshots = list_snapshots( - self.apiclient, - listall=True, - key='type', - value='manual' - ) + snapshots = Snapshot.list(self.apiclient, + listall=True, + key='type', + value='manual') self.assertEqual( isinstance(snapshots, list), True, @@ -1325,7 +1330,7 @@ def test_09_snapshot_tag(self): return - @attr(tags=["advanced"]) + @attr(tags=["advanced", "selfservice"]) def test_10_network_tag(self): """ Testcreation, listing and deletion tags on guest network """ @@ -1527,7 +1532,7 @@ def test_11_migrate_tagged_vm_del(self): ) return - @attr(tags=["advanced", "basic"]) + @attr(tags=["advanced", "basic", "selfservice"]) def test_13_tag_case_insensitive(self): """ Test to verify that tags are not case sensitive """ @@ -1565,21 +1570,16 @@ def test_13_tag_case_insensitive(self): 'India', 'The tag should have original value' ) - self.debug("Creating the same tag with caps for user VM") - try: - tag_2 = Tag.create( - self.apiclient, - resourceIds=self.vm_1.id, - resourceType='userVM', - tags={'REGION': 'INDIA'} - ) + Tag.create(self.apiclient, + resourceIds=self.vm_1.id, + resourceType='userVM', + tags={'REGION': 'INDIA'}) except Exception as e: pass else: assert("Creating same tag in upper case succeeded") - self.debug("Deleting the created tag..") try: tag_1.delete( self.apiclient, @@ -1608,7 +1608,7 @@ def test_13_tag_case_insensitive(self): return - @attr(tags=["advanced", "basic"]) + @attr(tags=["advanced", "basic", "selfservice"]) def test_14_special_char_mutiple_tags(self): """ Test multiple tags and with special characters on same machine """ @@ -1677,7 +1677,7 @@ def test_14_special_char_mutiple_tags(self): ) return - @attr(tags=["advanced"]) + @attr(tags=["advanced", "selfservice"]) def test_15_project_tag(self): """ Test creation, listing and deletion tags on projects """ @@ -1769,7 +1769,7 @@ def test_15_project_tag(self): ) return - @attr(tags=["advanced", "basic"]) + @attr(tags=["advanced", "basic", "selfservice"]) def test_16_query_tags_other_account(self): """ Test Query the tags from other account """ @@ -1787,14 +1787,14 @@ def test_16_query_tags_other_account(self): domainid=self.domain.id ) self.cleanup.append(user_account) - + other_user_account = Account.create( self.apiclient, self.services["other_user"], domainid=self.domain.id ) self.cleanup.append(other_user_account) - + iso = Iso.create( self.apiclient, self.services["iso"], @@ -1803,10 +1803,8 @@ def test_16_query_tags_other_account(self): ) self.debug("ISO created with ID: %s" % iso.id) - list_iso_response = list_isos( - self.apiclient, - id=iso.id - ) + list_iso_response = Iso.list(self.apiclient, + id=iso.id) self.assertEqual( isinstance(list_iso_response, list), True, @@ -1830,8 +1828,6 @@ def test_16_query_tags_other_account(self): domainid=user_account.domainid, key='region', ) - - self.debug("Verify listTag API using user account") self.assertEqual( isinstance(tags, list), True, @@ -1861,7 +1857,7 @@ def test_16_query_tags_other_account(self): return - @attr(tags=["advanced", "basic"]) + @attr(tags=["advanced", "basic", "selfservice"]) def test_17_query_tags_admin_account(self): """ Test Query the tags from admin account """ @@ -1879,33 +1875,25 @@ def test_17_query_tags_admin_account(self): domainid=self.domain.id ) self.cleanup.append(user_account) - + iso = Iso.create( self.apiclient, self.services["iso"], account=user_account.name, domainid=user_account.domainid ) - self.debug("ISO created with ID: %s" % iso.id) - list_iso_response = list_isos( - self.apiclient, - id=iso.id - ) + list_iso_response = Iso.list(self.apiclient, + id=iso.id) self.assertEqual( isinstance(list_iso_response, list), True, "Check list response returns a valid list" ) - - self.debug("Creating a tag for the ISO") - tag = Tag.create( - self.apiclient, - resourceIds=iso.id, - resourceType='ISO', - tags={'region': 'India'} - ) - self.debug("Tag created: %s" % tag.__dict__) + Tag.create(self.apiclient, + resourceIds=iso.id, + resourceType='ISO', + tags={'region': 'India'}) tags = Tag.list( self.apiclient, @@ -1915,8 +1903,6 @@ def test_17_query_tags_admin_account(self): domainid=user_account.domainid, key='region', ) - - self.debug("Verify listTag API using user account") self.assertEqual( isinstance(tags, list), True, @@ -1948,7 +1934,7 @@ def test_17_query_tags_admin_account(self): return - @attr(tags=["advanced", "basic", "simulator"]) + @attr(tags=["advanced", "basic", "simulator", "selfservice"]) def test_18_invalid_list_parameters(self): """ Test listAPI with invalid tags parameter """ @@ -1987,7 +1973,7 @@ def test_18_invalid_list_parameters(self): return - @attr(tags=["advanced", "basic"]) + @attr(tags=["advanced", "basic", "selfservice"]) def test_19_delete_add_same_tag(self): """ Test deletion and addition of same tag on a resource. """ @@ -2093,7 +2079,7 @@ def test_19_delete_add_same_tag(self): self.fail("Failed to delete the tag - %s" % e) return - @attr(tags=["advanced", "basic"]) + @attr(tags=["advanced", "basic", "selfservice"]) def test_20_create_tags_multiple_resources(self): "Test creation of same tag on multiple resources" @@ -2198,51 +2184,25 @@ def test_20_create_tags_multiple_resources(self): return - @attr(tags=["advanced", "basic"]) + @attr(tags=["advanced", "basic", "selfservice"]) def test_21_create_tag_stopped_vm(self): "Test creation of tag on stopped vm." - self.debug("Stopping the virtual machine: %s" % self.vm_1.name) - #Stop virtual machine - self.vm_1.stop(self.apiclient) - - timeout = self.services["timeout"] - #Wait before server has be successfully stopped - time.sleep(self.services["sleep"]) - - list_vm_response = list_virtual_machines( - self.apiclient, - id=self.vm_1.id - ) - - self.debug( - "Verify listVirtualMachines response for virtual machine: %s" \ - % self.vm_1.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, - "Stopped", - "VM should be in stopped state after deployment" - ) + try: + self.debug("Stopping the virtual machine: %s" % self.vm_1.name) + #Stop virtual machine + self.vm_1.stop(self.apiclient) - self.debug("Creating a tag for user VM") - tag = Tag.create( + self.debug("Creating a tag for user VM") + tag = Tag.create( self.apiclient, resourceIds=self.vm_1.id, resourceType='userVM', tags={'region': 'India'} ) - self.debug("Tag created: %s" % tag.__dict__) + self.debug("Tag created: %s" % tag.__dict__) - tags = Tag.list( + tags = Tag.list( self.apiclient, listall=True, resourceType='userVM', @@ -2251,20 +2211,19 @@ def test_21_create_tag_stopped_vm(self): key='region', value='India' ) - self.assertEqual( + self.assertEqual( isinstance(tags, list), True, "List tags should not return empty response" ) - self.assertEqual( + self.assertEqual( tags[0].value, "India", "Tag created with incorrect value" ) - self.debug("Deleting the created tag..") - try: + self.debug("Deleting the created tag..") tag.delete( self.apiclient, resourceIds=self.vm_1.id, @@ -2272,10 +2231,10 @@ def test_21_create_tag_stopped_vm(self): tags={'region': 'India'} ) except Exception as e: - self.fail("Failed to delete the tag - %s" % e) + self.fail("Exception occured - %s" % e) return - @attr(tags=["advanced", "basic"]) + @attr(tags=["advanced", "basic", "selfservice"]) def test_22_create_tag_destroyed_vm(self): "Test creation of tag on stopped vm." diff --git a/test/integration/component/test_templates.py b/test/integration/component/test_templates.py index 3e836157ac..19852643d6 100644 --- a/test/integration/component/test_templates.py +++ b/test/integration/component/test_templates.py @@ -5,9 +5,9 @@ # 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 @@ -17,15 +17,20 @@ """ P1 tests for Templates """ #Import Local Modules -import marvin from nose.plugins.attrib import attr -from marvin.cloudstackTestCase import * -from marvin.cloudstackAPI import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * -import urllib -from random import random +from marvin.cloudstackTestCase import cloudstackTestCase, unittest +from marvin.cloudstackAPI import listZones +from marvin.lib.utils import (cleanup_resources) +from marvin.lib.base import (Account, + Template, + ServiceOffering, + VirtualMachine, + Snapshot, + Volume) +from marvin.lib.common import (get_domain, + get_zone, + get_template, + get_builtin_template_info) #Import System modules import time @@ -101,8 +106,8 @@ def __init__(self): class TestCreateTemplate(cloudstackTestCase): def setUp(self): - self.apiclient = self.testClient.getApiClient() + self.hypervisor = self.testClient.getHypervisorInfo() self.dbclient = self.testClient.getDbConnection() self.cleanup = [] return @@ -118,12 +123,13 @@ def tearDown(self): @classmethod def setUpClass(cls): - cls.services = Services().services - cls.api_client = super(TestCreateTemplate, cls).getClsTestClient().getApiClient() + cls.testClient = super(TestCreateTemplate, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype cls.services["virtual_machine"]["zoneid"] = cls.zone.id @@ -156,7 +162,7 @@ def tearDownClass(cls): return - @attr(tags = ["advanced", "advancedns"]) + @attr(tags=["advanced", "advancedns", "provisioning"]) def test_01_create_template(self): """Test create public & private template """ @@ -184,7 +190,8 @@ def test_01_create_template(self): self.services["templates"][0], zoneid=self.zone.id, account=self.account.name, - domainid=self.account.domainid + domainid=self.account.domainid, + hypervisor=self.hypervisor ) self.debug( "Registered a template of format: %s with ID: %s" % ( @@ -199,14 +206,13 @@ def test_01_create_template(self): time.sleep(self.services["sleep"]) timeout = self.services["timeout"] while True: - list_template_response = list_templates( - self.apiclient, - templatefilter='all', - id=template.id, - zoneid=self.zone.id, - account=self.account.name, - domainid=self.account.domainid - ) + list_template_response = Template.list( + self.apiclient, + templatefilter='all', + id=template.id, + zoneid=self.zone.id, + account=self.account.name, + domainid=self.account.domainid) if isinstance(list_template_response, list): break elif timeout == 0: @@ -245,12 +251,10 @@ def test_01_create_template(self): mode=self.services["mode"] ) self.debug("creating an instance with template ID: %s" % template.id) - vm_response = list_virtual_machines( - self.apiclient, - id=virtual_machine.id, - account=self.account.name, - domainid=self.account.domainid - ) + vm_response = VirtualMachine.list(self.apiclient, + id=virtual_machine.id, + account=self.account.name, + domainid=self.account.domainid) self.assertEqual( isinstance(vm_response, list), True, @@ -276,12 +280,13 @@ class TestTemplates(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.services = Services().services - cls.api_client = super(TestTemplates, cls).getClsTestClient().getApiClient() + cls.testClient = super(TestTemplates, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() - # Get Zone, templates etc - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.services = Services().services + # 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 #populate second zone id for iso copy cmd = listZones.listZonesCmd() @@ -297,20 +302,24 @@ def setUpClass(cls): cls.services["ostype"] ) cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.account = Account.create( + cls._cleanup = [] + try: + cls.account = Account.create( cls.api_client, cls.services["account"], domainid=cls.domain.id ) + cls._cleanup.append(cls.account) - cls.services["account"] = cls.account.name - cls.service_offering = ServiceOffering.create( + cls.services["account"] = cls.account.name + cls.service_offering = ServiceOffering.create( cls.api_client, cls.services["service_offering"] ) + cls._cleanup.append(cls.service_offering) - # create virtual machine - cls.virtual_machine = VirtualMachine.create( + # create virtual machine + cls.virtual_machine = VirtualMachine.create( cls.api_client, cls.services["virtual_machine"], templateid=template.id, @@ -318,40 +327,36 @@ def setUpClass(cls): domainid=cls.account.domainid, serviceofferingid=cls.service_offering.id, ) - #Stop virtual machine - cls.virtual_machine.stop(cls.api_client) + #Stop virtual machine + cls.virtual_machine.stop(cls.api_client) - timeout = cls.services["timeout"] - #Wait before server has be successfully stopped - time.sleep(cls.services["sleep"]) + timeout = cls.services["timeout"] - while True: - list_volume = list_volumes( - cls.api_client, - virtualmachineid=cls.virtual_machine.id, - type='ROOT', - listall=True - ) - if isinstance(list_volume, list): - break - elif timeout == 0: - raise Exception("List volumes failed.") + while True: + list_volume = Volume.list( + cls.api_client, + virtualmachineid=cls.virtual_machine.id, + type='ROOT', + listall=True) + if isinstance(list_volume, list): + break + elif timeout == 0: + raise Exception("List volumes failed.") - time.sleep(5) - timeout = timeout - 1 + time.sleep(5) + timeout = timeout - 1 - cls.volume = list_volume[0] + cls.volume = list_volume[0] - #Create template from volume - cls.template = Template.create( + #Create template from volume + cls.template = Template.create( cls.api_client, cls.services["template"], cls.volume.id ) - cls._cleanup = [ - cls.service_offering, - cls.account, - ] + except Exception as e: + cls.tearDownClass() + raise unittest.SkipTest("Failure in setUpClass: %s" % e) @classmethod def tearDownClass(cls): @@ -382,7 +387,7 @@ def tearDown(self): return - @attr(tags = ["advanced", "advancedns"]) + @attr(tags=["advanced", "advancedns", "selfservice"]) def test_01_create_template_volume(self): """Test Create template from volume """ @@ -402,12 +407,11 @@ def test_01_create_template_volume(self): self.debug("creating an instance with template ID: %s" % self.template.id) self.cleanup.append(virtual_machine) - vm_response = list_virtual_machines( - self.apiclient, - id=virtual_machine.id, - account=self.account.name, - domainid=self.account.domainid - ) + vm_response = VirtualMachine.list( + self.apiclient, + id=virtual_machine.id, + account=self.account.name, + domainid=self.account.domainid) #Verify VM response to check whether VM deployment was successful self.assertNotEqual( len(vm_response), @@ -422,7 +426,7 @@ def test_01_create_template_volume(self): ) return - @attr(tags = ["advanced", "advancedns"]) + @attr(tags=["advanced", "advancedns", "selfservice"]) def test_03_delete_template(self): """Test Delete template """ @@ -432,13 +436,12 @@ def test_03_delete_template(self): # 2. Delete the created template and again verify list template response # Verify template response for updated attributes - list_template_response = list_templates( + list_template_response = Template.list( self.apiclient, templatefilter=\ self.services["template"]["templatefilter"], id=self.template.id, - zoneid=self.zone.id - ) + zoneid=self.zone.id) self.assertEqual( isinstance(list_template_response, list), True, @@ -464,7 +467,7 @@ def test_03_delete_template(self): self.template.delete(self.apiclient) self.debug("Delete template: %s successful" % self.template) - list_template_response = list_templates( + list_template_response = Template.list( self.apiclient, templatefilter=\ self.services["template"]["templatefilter"], @@ -479,7 +482,7 @@ def test_03_delete_template(self): return @attr(speed = "slow") - @attr(tags = ["advanced", "advancedns"]) + @attr(tags=["advanced", "advancedns", "selfservice"]) def test_04_template_from_snapshot(self): """Create Template from snapshot """ @@ -490,7 +493,7 @@ def test_04_template_from_snapshot(self): # 4. Deploy Virtual machine using this template # 5. VM should be in running state - volumes = list_volumes( + volumes = Volume.list( self.apiclient, virtualmachineid=self.virtual_machine.id, type='ROOT', @@ -515,7 +518,7 @@ def test_04_template_from_snapshot(self): ) self.cleanup.append(template) # Verify created template - templates = list_templates( + templates = Template.list( self.apiclient, templatefilter=\ self.services["template"]["templatefilter"], @@ -544,7 +547,7 @@ def test_04_template_from_snapshot(self): ) self.cleanup.append(virtual_machine) - vm_response = list_virtual_machines( + vm_response = VirtualMachine.list( self.apiclient, id=virtual_machine.id, account=self.account.name, diff --git a/test/integration/component/test_update_vm.py b/test/integration/component/test_update_vm.py index 0786310e19..1c5c236250 100644 --- a/test/integration/component/test_update_vm.py +++ b/test/integration/component/test_update_vm.py @@ -17,9 +17,9 @@ from marvin.cloudstackTestCase import cloudstackTestCase -from marvin.integration.lib.base import Account, VirtualMachine, ServiceOffering -from marvin.integration.lib.utils import cleanup_resources -from marvin.integration.lib.common import get_zone, get_domain, get_template +from marvin.lib.base import Account, VirtualMachine, ServiceOffering +from marvin.lib.utils import cleanup_resources +from marvin.lib.common import get_zone, get_domain, get_template from nose.plugins.attrib import attr class TestData(object): @@ -61,8 +61,8 @@ def setUp(self): self.apiclient = self.testClient.getApiClient() # Get Zone, Domain and Default Built-in template - self.domain = get_domain(self.apiclient, self.testdata) - self.zone = get_zone(self.apiclient, self.testdata) + self.domain = get_domain(self.apiclient) + self.zone = get_zone(self.apiclient, self.testClient.getZoneForTests()) self.testdata["mode"] = self.zone.networktype self.template = get_template(self.apiclient, self.zone.id, self.testdata["ostype"]) @@ -83,7 +83,7 @@ def setUp(self): self.account ] - @attr(tags = ['advanced', 'simulator', 'basic', 'sg']) + @attr(tags=['advanced', 'simulator', 'basic', 'sg', "selfservice"]) def test_update_vm_name(self): """Test Update VirtualMachine Name @@ -156,4 +156,4 @@ def tearDown(self): try: cleanup_resources(self.apiclient, self.cleanup) except Exception as e: - self.debug("Warning! Exception in tearDown: %s" % e) \ No newline at end of file + self.debug("Warning! Exception in tearDown: %s" % e) diff --git a/test/integration/component/test_usage.py b/test/integration/component/test_usage.py index 5979a0a495..4413f43342 100644 --- a/test/integration/component/test_usage.py +++ b/test/integration/component/test_usage.py @@ -5,9 +5,9 @@ # 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 @@ -17,16 +17,27 @@ """ P1 tests for Snapshots """ #Import Local Modules -import marvin from nose.plugins.attrib import attr -from marvin.cloudstackTestCase import * -from marvin.cloudstackAPI import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * -from marvin.sshClient import SshClient -import datetime - +from marvin.cloudstackTestCase import cloudstackTestCase, unittest +from marvin.cloudstackAPI import deleteVolume +from marvin.lib.utils import (cleanup_resources) +from marvin.lib.base import (Account, + ServiceOffering, + NATRule, + VirtualMachine, + Snapshot, + Iso, + ImageStore, + LoadBalancerRule, + PublicIPAddress, + DiskOffering, + Template, + VpnUser, + Vpn, + Volume) +from marvin.lib.common import (get_zone, + get_domain, + get_template) class Services: """Test Snapshots Services @@ -112,11 +123,13 @@ class TestVmUsage(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestVmUsage, cls).getClsTestClient().getApiClient() + cls.testClient = super(TestVmUsage, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype template = get_template( @@ -178,7 +191,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags = ["advanced", "basic", "sg", "eip", "advancedns", "simulator"]) + @attr(tags=["advanced", "basic", "sg", "eip", "advancedns", "simulator", "selfservice"]) def test_01_vm_usage(self): """Test Create/Destroy VM and verify usage calculation """ @@ -191,14 +204,19 @@ def test_01_vm_usage(self): # VM.Destroy and volume .delete Event for the created account # 4. Delete the account - self.debug("Stopping the VM: %s" % self.virtual_machine.id) - # Stop the VM - self.virtual_machine.stop(self.apiclient) + try: + self.debug("Stopping the VM: %s" % self.virtual_machine.id) + # Stop the VM + self.virtual_machine.stop(self.apiclient) + except Exception as e: + self.fail("Failed to stop instance: %s" % e) - time.sleep(self.services["sleep"]) - # Destroy the VM - self.debug("Destroying the VM: %s" % self.virtual_machine.id) - self.virtual_machine.delete(self.apiclient) + try: + # Destroy the VM + self.debug("Destroying the VM: %s" % self.virtual_machine.id) + self.virtual_machine.delete(self.apiclient) + except Exception as e: + self.fail("Failed to destroy VM: %s" % e) # Fetch account ID from account_uuid self.debug("select id from account where uuid = '%s';" \ @@ -296,11 +314,13 @@ class TestPublicIPUsage(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestPublicIPUsage, cls).getClsTestClient().getApiClient() + cls.testClient = super(TestPublicIPUsage, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype template = get_template( @@ -370,7 +390,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags = ["advanced", "eip", "advancedns", "simulator"]) + @attr(tags=["advanced", "eip", "advancedns", "simulator", "selfservice"]) def test_01_public_ip_usage(self): """Test Assign new IP and verify usage calculation """ @@ -448,11 +468,13 @@ class TestVolumeUsage(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestVolumeUsage, cls).getClsTestClient().getApiClient() + cls.testClient = super(TestVolumeUsage, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype cls.disk_offering = DiskOffering.create( cls.api_client, @@ -518,7 +540,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags = ["advanced", "basic", "sg", "eip", "advancedns", "simulator"]) + @attr(tags=["advanced", "basic", "sg", "eip", "advancedns", "simulator", "selfservice"]) def test_01_volume_usage(self): """Test Create/delete a volume and verify correct usage is recorded """ @@ -530,16 +552,18 @@ def test_01_volume_usage(self): # 4. Destroy the Data disk. Volume.delete event is generated for data # disk of the destroyed VM - # Stop VM - self.debug("Stopping VM with ID: %s" % self.virtual_machine.id) - self.virtual_machine.stop(self.apiclient) + try: + # Stop VM + self.debug("Stopping VM with ID: %s" % self.virtual_machine.id) + self.virtual_machine.stop(self.apiclient) + except Exception as e: + self.fail("Failed to stop instance: %s" % e) - volume_response = list_volumes( - self.apiclient, - virtualmachineid=self.virtual_machine.id, - type='DATADISK', - listall=True - ) + volume_response = Volume.list( + self.apiclient, + virtualmachineid=self.virtual_machine.id, + type='DATADISK', + listall=True) self.assertEqual( isinstance(volume_response, list), True, @@ -622,11 +646,13 @@ class TestTemplateUsage(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestTemplateUsage, cls).getClsTestClient().getApiClient() + cls.testClient = super(TestTemplateUsage, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype cls.services["server"]["zoneid"] = cls.zone.id template = get_template( @@ -635,19 +661,22 @@ def setUpClass(cls): cls.services["ostype"] ) cls.services["server"]["zoneid"] = cls.zone.id - cls.account = Account.create( + try: + cls.account = Account.create( cls.api_client, cls.services["account"], domainid=cls.domain.id ) - cls.services["account"] = cls.account.name + cls._cleanup.append(cls.account) + cls.services["account"] = cls.account.name - cls.service_offering = ServiceOffering.create( + cls.service_offering = ServiceOffering.create( cls.api_client, cls.services["service_offering"] ) - #create virtual machine - cls.virtual_machine = VirtualMachine.create( + cls._cleanup.append(cls.service_offering) + #create virtual machine + cls.virtual_machine = VirtualMachine.create( cls.api_client, cls.services["server"], templateid=template.id, @@ -657,24 +686,21 @@ def setUpClass(cls): mode=cls.services["mode"] ) - #Stop virtual machine - cls.virtual_machine.stop(cls.api_client) - - #Wait before server has be successfully stopped - time.sleep(30) - list_volume = list_volumes( - cls.api_client, - virtualmachineid=cls.virtual_machine.id, - type='ROOT', - listall=True - ) - if isinstance(list_volume, list): - cls.volume = list_volume[0] - else: - raise Exception("List Volumes failed!") - cls._cleanup = [ - cls.account, - ] + #Stop virtual machine + cls.virtual_machine.stop(cls.api_client) + + list_volume = Volume.list( + cls.api_client, + virtualmachineid=cls.virtual_machine.id, + type='ROOT', + listall=True) + if isinstance(list_volume, list): + cls.volume = list_volume[0] + else: + raise Exception("List Volumes failed!") + except Exception as e: + cls.tearDownClass() + raise unittest.SkipTest("Exception in setUpClass: %s" % e) return @classmethod @@ -700,7 +726,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags = ["advanced", "basic", "sg", "eip", "advancedns"]) + @attr(tags=["advanced", "basic", "sg", "eip", "advancedns", "selfservice"]) def test_01_template_usage(self): """Test Upload/ delete a template and verify correct usage is generated for the template uploaded @@ -787,11 +813,13 @@ class TestISOUsage(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestISOUsage, cls).getClsTestClient().getApiClient() + cls.testClient = super(TestISOUsage, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype cls.services["server"]["zoneid"] = cls.zone.id cls.services["iso"]["zoneid"] = cls.zone.id @@ -844,7 +872,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags = ["advanced", "basic", "sg", "eip", "advancedns"]) + @attr(tags=["advanced", "basic", "sg", "eip", "advancedns", "selfservice"]) def test_01_ISO_usage(self): """Test Create/Delete a ISO and verify its usage is generated correctly """ @@ -924,11 +952,13 @@ class TestLBRuleUsage(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestLBRuleUsage, cls).getClsTestClient().getApiClient() + cls.testClient = super(TestLBRuleUsage, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype template = get_template( cls.api_client, @@ -996,7 +1026,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags = ["advanced", "eip", "advancedns", "simulator"]) + @attr(tags=["advanced", "eip", "advancedns", "simulator", "selfservice"]) def test_01_lb_usage(self): """Test Create/Delete a LB rule and verify correct usage is recorded """ @@ -1086,11 +1116,13 @@ class TestSnapshotUsage(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestSnapshotUsage, cls).getClsTestClient().getApiClient() + cls.testClient = super(TestSnapshotUsage, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype template = get_template( @@ -1153,7 +1185,7 @@ def tearDown(self): return @attr(speed = "slow") - @attr(tags = ["advanced", "basic", "sg", "eip", "advancedns", "simulator"]) + @attr(tags=["advanced", "basic", "sg", "eip", "advancedns", "simulator", "selfservice"]) def test_01_snapshot_usage(self): """Test Create/Delete a manual snap shot and verify correct usage is recorded @@ -1166,20 +1198,17 @@ def test_01_snapshot_usage(self): # 3. Delete the account # Get the Root disk of VM - volumes = list_volumes( - self.apiclient, - virtualmachineid=self.virtual_machine.id, - type='ROOT', - listall=True - ) + volumes = Volume.list( + self.apiclient, + virtualmachineid=self.virtual_machine.id, + type='ROOT', + listall=True) self.assertEqual( isinstance(volumes, list), True, "Check if list volumes return a valid data" ) - volume = volumes[0] - # Create a snapshot from the ROOTDISK self.debug("Creating snapshot from volume: %s" % volumes[0].id) snapshot = Snapshot.create(self.apiclient, volumes[0].id) @@ -1253,11 +1282,13 @@ class TestNatRuleUsage(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestNatRuleUsage, cls).getClsTestClient().getApiClient() + cls.testClient = super(TestNatRuleUsage, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype template = get_template( cls.api_client, @@ -1325,7 +1356,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags = ["advanced", "advancedns", "simulator"]) + @attr(tags=["advanced", "advancedns", "simulator", "selfservice"]) def test_01_nat_usage(self): """Test Create/Delete a PF rule and verify correct usage is recorded """ @@ -1415,11 +1446,13 @@ class TestVpnUsage(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestVpnUsage, cls).getClsTestClient().getApiClient() + cls.testClient = super(TestVpnUsage, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype template = get_template( cls.api_client, @@ -1429,6 +1462,7 @@ def setUpClass(cls): cls.services["server"]["zoneid"] = cls.zone.id cls.services["template"] = template.id + cls._cleanup = [] # Create Service offerings, VMs etc cls.account = Account.create( @@ -1437,6 +1471,7 @@ def setUpClass(cls): admin=True, domainid=cls.domain.id ) + cls._cleanup.append(cls.account) cls.services["account"] = cls.account.name @@ -1444,6 +1479,7 @@ def setUpClass(cls): cls.api_client, cls.services["service_offering"] ) + cls._cleanup.append(cls.sevice_offering) cls.virtual_machine = VirtualMachine.create( cls.api_client, cls.services["server"], @@ -1459,10 +1495,6 @@ def setUpClass(cls): domainid=cls.virtual_machine.domainid, services=cls.services["server"] ) - cls._cleanup = [ - cls.service_offering, - cls.account, - ] return @classmethod @@ -1488,7 +1520,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags = ["advanced", "advancedns"]) + @attr(tags=["advanced", "advancedns", "selfservice"]) def test_01_vpn_usage(self): """Test Create/Delete a VPN and verify correct usage is recorded """ diff --git a/test/integration/component/test_vm_passwdenabled.py b/test/integration/component/test_vm_passwdenabled.py index 5cfa52556f..2f68257f89 100644 --- a/test/integration/component/test_vm_passwdenabled.py +++ b/test/integration/component/test_vm_passwdenabled.py @@ -18,9 +18,9 @@ from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * from marvin.sshClient import SshClient -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * +from marvin.lib.utils import * +from marvin.lib.base import * +from marvin.lib.common import * from nose.plugins.attrib import attr @@ -92,15 +92,13 @@ class TestVMPasswordEnabled(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestVMPasswordEnabled, - cls - ).getClsTestClient().getApiClient() - cls.services = Services().services + cls.testClient = super(TestVMPasswordEnabled, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - domain = get_domain(cls.api_client, cls.services) - zone = get_zone(cls.api_client, cls.services) + domain = get_domain(cls.api_client) + zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = zone.networktype template = get_template( cls.api_client, diff --git a/test/integration/component/test_vmware_drs.py b/test/integration/component/test_vmware_drs.py index 6a99911184..7d3ab7f5cb 100644 --- a/test/integration/component/test_vmware_drs.py +++ b/test/integration/component/test_vmware_drs.py @@ -23,19 +23,19 @@ from marvin.cloudstackTestCase import cloudstackTestCase, unittest -from marvin.integration.lib.base import (Account, +from marvin.lib.base import (Account, AffinityGroup, Host, VirtualMachine, ServiceOffering) -from marvin.integration.lib.common import (get_zone, +from marvin.lib.common import (get_zone, get_template, get_domain, get_pod ) -from marvin.integration.lib.utils import (validateList, +from marvin.lib.utils import (validateList, cleanup_resources, random_gen) @@ -111,25 +111,16 @@ class TestVMPlacement(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestVMPlacement, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestVMPlacement, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain( - cls.api_client, - cls.services - ) - cls.zone = get_zone( - cls.api_client, - cls.services - ) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.pod = get_pod( cls.api_client, - zoneid=cls.zone.id, - services=cls.services - ) + zone_id=cls.zone.id) cls.template = get_template( cls.api_client, cls.zone.id, @@ -178,7 +169,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags = ["advanced", "vmware", "multihost"]) + @attr(tags=["advanced", "vmware", "multihost", "provisioning"]) def test_vm_creation_in_fully_automated_mode(self): """ Test VM Creation in automation mode = Fully automated This test requires following preconditions: @@ -280,20 +271,13 @@ class TestAntiAffinityRules(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestAntiAffinityRules, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestAntiAffinityRules, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain( - cls.api_client, - cls.services - ) - cls.zone = get_zone( - cls.api_client, - cls.services - ) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, @@ -352,7 +336,7 @@ def create_aff_grp(self, aff_grp=None, except Exception as e: raise Exception("Error: Creation of Affinity Group failed : %s" %e) - @attr(tags = ["advanced", "vmware", "multihost"]) + @attr(tags=["advanced", "vmware", "multihost", "provisioning"]) def test_vmware_anti_affinity(self): """ Test Set up anti-affinity rules @@ -515,20 +499,13 @@ class TestAffinityRules(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestAffinityRules, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestAffinityRules, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain( - cls.api_client, - cls.services - ) - cls.zone = get_zone( - cls.api_client, - cls.services - ) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, @@ -587,7 +564,7 @@ def create_aff_grp(self, aff_grp=None, except Exception as e: raise Exception("Error: Creation of Affinity Group failed : %s" %e) - @attr(tags = ["advanced", "vmware", "multihost"]) + @attr(tags=["advanced", "vmware", "multihost", "provisioning"]) def test_vmware_affinity(self): """ Test Set up affinity rules diff --git a/test/integration/component/test_volumes.py b/test/integration/component/test_volumes.py index ee0f91dd8c..22029b1b30 100644 --- a/test/integration/component/test_volumes.py +++ b/test/integration/component/test_volumes.py @@ -5,9 +5,9 @@ # 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 @@ -18,11 +18,24 @@ """ #Import Local Modules from nose.plugins.attrib import attr -from marvin.cloudstackTestCase import * -from marvin.cloudstackAPI import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * +from marvin.cloudstackTestCase import cloudstackTestCase +from marvin.cloudstackAPI import (listHypervisorCapabilities, + attachIso, + deleteVolume) +from marvin.lib.utils import cleanup_resources +from marvin.lib.base import (Account, + ServiceOffering, + VirtualMachine, + Volume, + Host, + Iso, + Configurations, + DiskOffering, + Domain) +from marvin.lib.common import (get_domain, + get_zone, + get_template, + get_pod) #Import System modules import time @@ -88,13 +101,14 @@ class TestAttachVolume(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestAttachVolume, cls).getClsTestClient().getApiClient() - cls.services = Services().services + cls.testClient = super(TestAttachVolume, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - cls.pod = get_pod(cls.api_client, cls.zone.id, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) + cls.pod = get_pod(cls.api_client, cls.zone.id) cls.services['mode'] = cls.zone.networktype cls.disk_offering = DiskOffering.create( cls.api_client, @@ -185,9 +199,9 @@ def test_01_volume_attach(self): # 5. Start The VM. Start VM should be successful # Create 5 volumes and attach to VM - for i in range(self.max_data_volumes): - self.debug(i) - volume = Volume.create( + try: + for i in range(self.max_data_volumes): + volume = Volume.create( self.apiclient, self.services["volume"], zoneid=self.zone.id, @@ -195,134 +209,99 @@ def test_01_volume_attach(self): domainid=self.account.domainid, diskofferingid=self.disk_offering.id ) - self.debug("Created volume: %s for account: %s" % ( - volume.id, - self.account.name - )) - # Check List Volume response for newly created volume - list_volume_response = list_volumes( + # Check List Volume response for newly created volume + list_volume_response = Volume.list( self.apiclient, id=volume.id ) - self.assertNotEqual( + self.assertNotEqual( list_volume_response, None, "Check if volume exists in ListVolumes" ) - # Attach volume to VM - self.virtual_machine.attach_volume( + # Attach volume to VM + self.virtual_machine.attach_volume( self.apiclient, volume ) - self.debug("Attach volume: %s to VM: %s" % ( - volume.id, - self.virtual_machine.id - )) - # Check all volumes attached to same VM - list_volume_response = list_volumes( + # Check all volumes attached to same VM + list_volume_response = Volume.list( self.apiclient, virtualmachineid=self.virtual_machine.id, type='DATADISK', listall=True ) - self.assertNotEqual( - list_volume_response, - None, - "Check if volume exists in ListVolumes" - ) - self.assertEqual( - isinstance(list_volume_response, list), - True, - "Check list volumes response for valid list" - ) - self.assertEqual( - len(list_volume_response), - self.max_data_volumes, - "Volumes attached to the VM %s. Expected %s" % (len(list_volume_response), self.max_data_volumes) - ) - self.debug("Rebooting the VM: %s" % self.virtual_machine.id) - # Reboot VM - self.virtual_machine.reboot(self.apiclient) - - vm_response = list_virtual_machines( + self.assertNotEqual( + list_volume_response, + None, + "Check if volume exists in ListVolumes") + self.assertEqual( + isinstance(list_volume_response, list), + True, + "Check list volumes response for valid list") + self.assertEqual( + len(list_volume_response), + self.max_data_volumes, + "Volumes attached to the VM %s. Expected %s" % (len(list_volume_response), self.max_data_volumes)) + self.debug("Rebooting the VM: %s" % self.virtual_machine.id) + # Reboot VM + self.virtual_machine.reboot(self.apiclient) + + vm_response = VirtualMachine.list( self.apiclient, id=self.virtual_machine.id, ) - #Verify VM response to check whether VM deployment was successful - self.assertNotEqual( + #Verify VM response to check whether VM deployment was successful + self.assertNotEqual( len(vm_response), 0, "Check VMs available in List VMs response" ) - self.assertEqual( + self.assertEqual( isinstance(vm_response, list), True, "Check list VM response for valid list" ) - vm = vm_response[0] - self.assertEqual( + vm = vm_response[0] + self.assertEqual( vm.state, 'Running', "Check the state of VM" ) - self.debug("Stopping the VM: %s" % self.virtual_machine.id) - # Stop VM - self.virtual_machine.stop(self.apiclient) + # Stop VM + self.virtual_machine.stop(self.apiclient) - vm_response = list_virtual_machines( - self.apiclient, - id=self.virtual_machine.id, - ) - self.assertEqual( - isinstance(vm_response, list), - True, - "Check list VM response for valid list" - ) - - #Verify VM response to check whether VM deployment was successful - self.assertNotEqual( - len(vm_response), - 0, - "Check VMs available in List VMs response" - ) + # Start VM + self.virtual_machine.start(self.apiclient) + # Sleep to ensure that VM is in ready state + time.sleep(self.services["sleep"]) - vm = vm_response[0] - self.assertEqual( - vm.state, - 'Stopped', - "Check the state of VM" - ) - - self.debug("Starting the VM: %s" % self.virtual_machine.id) - # Start VM - self.virtual_machine.start(self.apiclient) - # Sleep to ensure that VM is in ready state - time.sleep(self.services["sleep"]) - - vm_response = list_virtual_machines( + vm_response = VirtualMachine.list( self.apiclient, id=self.virtual_machine.id, ) - self.assertEqual( + self.assertEqual( isinstance(vm_response, list), True, "Check list VM response for valid list" ) - #Verify VM response to check whether VM deployment was successful - self.assertNotEqual( + #Verify VM response to check whether VM deployment was successful + self.assertNotEqual( len(vm_response), 0, "Check VMs available in List VMs response" ) - vm = vm_response[0] - self.assertEqual( + vm = vm_response[0] + self.assertEqual( vm.state, 'Running', "Check the state of VM" ) + except Exception as e: + self.fail("Exception occured: %s" % e) return @attr(tags = ["advanced", "advancedns"]) @@ -348,7 +327,7 @@ def test_02_volume_attach_max(self): self.account.name )) # Check List Volume response for newly created volume - list_volume_response = list_volumes( + list_volume_response = Volume.list( self.apiclient, id=volume.id ) @@ -378,13 +357,14 @@ class TestAttachDetachVolume(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestAttachDetachVolume, cls).getClsTestClient().getApiClient() - cls.services = Services().services + cls.testClient = super(TestAttachDetachVolume, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - cls.pod = get_pod(cls.api_client, cls.zone.id, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) + cls.pod = get_pod(cls.api_client, cls.zone.id) cls.services['mode'] = cls.zone.networktype cls.disk_offering = DiskOffering.create( cls.api_client, @@ -474,10 +454,11 @@ def test_01_volume_attach_detach(self): # 5. Stop the VM. Stop VM should be successful # 6. Start The VM. Start VM should be successful - volumes = [] - # Create 5 volumes and attach to VM - for i in range(self.max_data_volumes): - volume = Volume.create( + try: + volumes = [] + # Create 5 volumes and attach to VM + for i in range(self.max_data_volumes): + volume = Volume.create( self.apiclient, self.services["volume"], zoneid=self.zone.id, @@ -485,155 +466,117 @@ def test_01_volume_attach_detach(self): domainid=self.account.domainid, diskofferingid=self.disk_offering.id ) - self.debug("Created volume: %s for account: %s" % ( - volume.id, - self.account.name - )) - self.cleanup.append(volume) - volumes.append(volume) + self.cleanup.append(volume) + volumes.append(volume) - # Check List Volume response for newly created volume - list_volume_response = list_volumes( + # Check List Volume response for newly created volume + list_volume_response = Volume.list( self.apiclient, id=volume.id ) - self.assertNotEqual( - list_volume_response, - None, - "Check if volume exists in ListVolumes" - ) - self.assertEqual( - isinstance(list_volume_response, list), - True, - "Check list volumes response for valid list" - ) - self.debug("Attach volume: %s to VM: %s" % ( - volume.id, - self.virtual_machine.id - )) - # Attach volume to VM - self.virtual_machine.attach_volume( + self.assertNotEqual( + list_volume_response, + None, + "Check if volume exists in ListVolumes") + self.assertEqual( + isinstance(list_volume_response, list), + True, + "Check list volumes response for valid list") + # Attach volume to VM + self.virtual_machine.attach_volume( self.apiclient, volume ) - # Check all volumes attached to same VM - list_volume_response = list_volumes( + # Check all volumes attached to same VM + list_volume_response = Volume.list( self.apiclient, virtualmachineid=self.virtual_machine.id, type='DATADISK', listall=True ) - self.assertNotEqual( + self.assertNotEqual( list_volume_response, None, "Check if volume exists in ListVolumes" ) - self.assertEqual( + self.assertEqual( isinstance(list_volume_response, list), True, "Check list volumes response for valid list" ) - self.assertEqual( - len(list_volume_response), - self.max_data_volumes, - "Volumes attached to the VM %s. Expected %s" % (len(list_volume_response), self.max_data_volumes) - ) + self.assertEqual( + len(list_volume_response), + self.max_data_volumes, + "Volumes attached to the VM %s. Expected %s" % (len(list_volume_response), self.max_data_volumes) + ) - # Detach all volumes from VM - for volume in volumes: - self.debug("Detach volume: %s to VM: %s" % ( - volume.id, - self.virtual_machine.id - )) - self.virtual_machine.detach_volume( + # Detach all volumes from VM + for volume in volumes: + self.virtual_machine.detach_volume( self.apiclient, volume ) - # Reboot VM - self.debug("Rebooting the VM: %s" % self.virtual_machine.id) - self.virtual_machine.reboot(self.apiclient) - # Sleep to ensure that VM is in ready state - time.sleep(self.services["sleep"]) + # Reboot VM + self.debug("Rebooting the VM: %s" % self.virtual_machine.id) + self.virtual_machine.reboot(self.apiclient) + # Sleep to ensure that VM is in ready state + time.sleep(self.services["sleep"]) - vm_response = list_virtual_machines( + vm_response = VirtualMachine.list( self.apiclient, id=self.virtual_machine.id, ) - #Verify VM response to check whether VM deployment was successful - self.assertEqual( + #Verify VM response to check whether VM deployment was successful + self.assertEqual( isinstance(vm_response, list), True, "Check list VM response for valid list" ) - self.assertNotEqual( + self.assertNotEqual( len(vm_response), 0, "Check VMs available in List VMs response" ) - vm = vm_response[0] - self.assertEqual( + vm = vm_response[0] + self.assertEqual( vm.state, 'Running', "Check the state of VM" ) - # Stop VM - self.debug("Stopping the VM: %s" % self.virtual_machine.id) - self.virtual_machine.stop(self.apiclient) - # Sleep to ensure that VM is in ready state - time.sleep(self.services["sleep"]) + # Stop VM + self.virtual_machine.stop(self.apiclient) - vm_response = list_virtual_machines( - self.apiclient, - id=self.virtual_machine.id, - ) - #Verify VM response to check whether VM deployment was successful - self.assertEqual( - isinstance(vm_response, list), - True, - "Check list VM response for valid list" - ) - self.assertNotEqual( - len(vm_response), - 0, - "Check VMs available in List VMs response" - ) - vm = vm_response[0] - self.assertEqual( - vm.state, - 'Stopped', - "Check the state of VM" - ) + # Start VM + self.virtual_machine.start(self.apiclient) + # Sleep to ensure that VM is in ready state + time.sleep(self.services["sleep"]) - # Start VM - self.debug("Starting the VM: %s" % self.virtual_machine.id) - self.virtual_machine.start(self.apiclient) - # Sleep to ensure that VM is in ready state - time.sleep(self.services["sleep"]) - - vm_response = list_virtual_machines( + vm_response = VirtualMachine.list( self.apiclient, id=self.virtual_machine.id, ) - #Verify VM response to check whether VM deployment was successful - self.assertEqual( + #Verify VM response to check whether VM deployment was successful + self.assertEqual( isinstance(vm_response, list), True, "Check list VM response for valid list" ) - self.assertNotEqual( + self.assertNotEqual( len(vm_response), 0, "Check VMs available in List VMs response" ) - vm = vm_response[0] - self.assertEqual( + vm = vm_response[0] + self.assertEqual( vm.state, 'Running', "Check the state of VM" ) + except Exception as e: + self.fail("Exception occuered: %s" % e) return @@ -641,13 +584,14 @@ class TestAttachVolumeISO(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestAttachVolumeISO, cls).getClsTestClient().getApiClient() - cls.services = Services().services + cls.testClient = super(TestAttachVolumeISO, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - cls.pod = get_pod(cls.api_client, cls.zone.id, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) + cls.pod = get_pod(cls.api_client, cls.zone.id) cls.services['mode'] = cls.zone.networktype cls.disk_offering = DiskOffering.create( cls.api_client, @@ -751,7 +695,7 @@ def test_01_volume_iso_attach(self): self.account.name )) # Check List Volume response for newly created volume - list_volume_response = list_volumes( + list_volume_response = Volume.list( self.apiclient, id=volume.id ) @@ -772,7 +716,7 @@ def test_01_volume_iso_attach(self): ) # Check all volumes attached to same VM - list_volume_response = list_volumes( + list_volume_response = Volume.list( self.apiclient, virtualmachineid=self.virtual_machine.id, type='DATADISK', @@ -823,7 +767,7 @@ def test_01_volume_iso_attach(self): self.apiclient.attachIso(cmd) # Verify ISO is attached to VM - vm_response = list_virtual_machines( + vm_response = VirtualMachine.list( self.apiclient, id=self.virtual_machine.id, ) @@ -852,11 +796,13 @@ class TestVolumes(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestVolumes, cls).getClsTestClient().getApiClient() + cls.testClient = super(TestVolumes, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype cls.disk_offering = DiskOffering.create( cls.api_client, @@ -923,7 +869,7 @@ def tearDown(self): cleanup_resources(self.apiclient, self.cleanup) return - @attr(tags = ["advanced", "advancedns"]) + @attr(tags=["advanced", "advancedns", "selfservice"]) def test_01_attach_volume(self): """Attach a created Volume to a Running VM """ @@ -936,7 +882,7 @@ def test_01_attach_volume(self): # response before volume attach (to VM) # Check the list volumes response for vmname and virtualmachineid - list_volume_response = list_volumes( + list_volume_response = Volume.list( self.apiclient, id=self.volume.id ) @@ -977,7 +923,7 @@ def test_01_attach_volume(self): self.virtual_machine.attach_volume(self.apiclient, self.volume) # Check all volumes attached to same VM - list_volume_response = list_volumes( + list_volume_response = Volume.list( self.apiclient, virtualmachineid=self.virtual_machine.id, type='DATADISK', @@ -1006,7 +952,7 @@ def test_01_attach_volume(self): ) return - @attr(tags = ["advanced", "advancedns"]) + @attr(tags=["advanced", "advancedns", "selfservice"]) def test_02_detach_volume(self): """Detach a Volume attached to a VM """ @@ -1025,7 +971,7 @@ def test_02_detach_volume(self): #Sleep to ensure the current state will reflected in other calls time.sleep(self.services["sleep"]) - list_volume_response = list_volumes( + list_volume_response = Volume.list( self.apiclient, id=self.volume.id ) @@ -1053,7 +999,7 @@ def test_02_detach_volume(self): ) return - @attr(tags = ["advanced", "advancedns"]) + @attr(tags=["advanced", "advancedns", "selfservice"]) def test_03_delete_detached_volume(self): """Delete a Volume unattached to an VM """ @@ -1069,7 +1015,7 @@ def test_03_delete_detached_volume(self): #Sleep to ensure the current state will reflected in other calls time.sleep(self.services["sleep"]) - list_volume_response = list_volumes( + list_volume_response = Volume.list( self.apiclient, id=self.volume.id, ) @@ -1080,7 +1026,7 @@ def test_03_delete_detached_volume(self): ) return - @attr(tags=["advanced", "advancedns", "simulator", "basic", "eip", "sg"]) + @attr(tags=["advanced", "advancedns", "simulator", "basic", "eip", "sg", "selfservice"]) def test_create_volume_under_domain(self): """Create a volume under a non-root domain as non-root-domain user @@ -1095,6 +1041,7 @@ def test_create_volume_under_domain(self): name="NROOT", parentdomainid=self.domain.id ) + self.cleanup.append(dom) self.assertTrue(dom is not None, msg="Domain creation failed") domuser = Account.create( @@ -1103,9 +1050,10 @@ def test_create_volume_under_domain(self): admin=False, domainid=dom.id ) + self.cleanup.insert(-2, domuser) self.assertTrue(domuser is not None) - domapiclient = self.testClient.getUserApiClient(account=domuser.name, domain=dom.name) + domapiclient = self.testClient.getUserApiClient(UserName=domuser.name, DomainName=dom.name) diskoffering = DiskOffering.list(self.apiclient) self.assertTrue(isinstance(diskoffering, list), msg="DiskOffering list is not a list?") @@ -1133,15 +1081,12 @@ class TestDeployVmWithCustomDisk(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestDeployVmWithCustomDisk, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestDeployVmWithCustomDisk, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype cls.disk_offering = DiskOffering.create( cls.api_client, diff --git a/test/integration/component/test_vpc.py b/test/integration/component/test_vpc.py index 1af8d8122e..e9d396e8b8 100644 --- a/test/integration/component/test_vpc.py +++ b/test/integration/component/test_vpc.py @@ -20,11 +20,11 @@ #Import Local Modules from nose.plugins.attrib import attr from marvin.cloudstackTestCase import * -from marvin.cloudstackException import cloudstackAPIException +from marvin.cloudstackException import CloudstackAPIException from marvin.cloudstackAPI import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * +from marvin.lib.utils import * +from marvin.lib.base import * +from marvin.lib.common import * class Services: @@ -175,14 +175,13 @@ class TestVPC(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestVPC, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestVPC, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, @@ -286,7 +285,7 @@ def validate_vpc_network(self, network, state=None): return #list_vpc_apis should be the first case otherwise the vpc counts would be wrong - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "selfservice"]) def test_01_list_vpc_apis(self): """ Test list VPC APIs """ @@ -465,7 +464,7 @@ def test_01_list_vpc_apis(self): ) return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "selfservice"]) def test_02_restart_vpc_no_networks(self): """ Test restart VPC having no networks """ @@ -496,7 +495,7 @@ def test_02_restart_vpc_no_networks(self): self.validate_vpc_network(vpc, state='Enabled') return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "selfservice"]) def test_03_restart_vpc_with_networks(self): """ Test restart VPC having networks """ @@ -581,7 +580,7 @@ def test_03_restart_vpc_with_networks(self): self.validate_vpc_network(vpc, state='Enabled') return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "selfservice"]) def test_04_delete_vpc_no_networks(self): """ Test delete VPC having no networks """ @@ -621,7 +620,7 @@ def test_04_delete_vpc_no_networks(self): ) return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "selfservice"]) def test_05_delete_vpc_with_networks(self): """ Test delete VPC having networks """ @@ -752,7 +751,7 @@ def test_05_delete_vpc_with_networks(self): ) return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "selfservice"]) def test_06_list_vpc_apis_admin(self): """ Test list VPC APIs for different user roles """ @@ -812,7 +811,7 @@ def test_06_list_vpc_apis_admin(self): ) return - @attr(tags=["advanced", "intervlan", "multiple"]) + @attr(tags=["advanced", "intervlan", "multiple", "provisioning"]) def test_07_restart_network_vm_running(self): """ Test Restart VPC when there are multiple networks associated """ @@ -1161,7 +1160,7 @@ def test_07_restart_network_vm_running(self): ) return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "provisioning"]) def test_08_delete_vpc(self): """ Test vpc deletion after account deletion """ @@ -1527,7 +1526,7 @@ def test_08_delete_vpc(self): ) return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "selfservice"]) def test_09_vpc_create(self): """ Test to create vpc and verify VPC state, VR and SourceNatIP """ @@ -1588,7 +1587,7 @@ def test_09_vpc_create(self): "Source Nat IP address was not allocated to VR" ) - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "selfservice"]) def test_10_nonoverlaping_cidrs(self): """ Test creation of multiple VPCs with non-overlapping CIDRs """ @@ -1640,7 +1639,7 @@ def test_10_nonoverlaping_cidrs(self): assert("VPC created with overlapping CIDR") return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "provisioning"]) def test_11_deploy_vm_wo_network_netdomain(self): """ Test deployment of vm in a VPC without network domain """ @@ -1794,7 +1793,7 @@ def validate_vm_netdomain(self, vm, vpc, network, expected_netdomain): (vm_domain, expected_netdomain) ) - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "selfservice"]) def test_12_deploy_vm_with_netdomain(self): """ Test deployment of vm in a VPC with network domain """ @@ -1849,7 +1848,7 @@ def test_12_deploy_vm_with_netdomain(self): networkdomain='test.netdomain' ) - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "provisioning"]) def test_13_deploy_vm_with_vpc_netdomain(self): """ Test deployment of vm in a VPC with network domain """ @@ -1914,7 +1913,7 @@ def test_13_deploy_vm_with_vpc_netdomain(self): self.validate_vm_netdomain(virtual_machine, vpc, network, netdomain) - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "selfservice"]) def test_14_deploy_vm_1(self): """ Test vm deploy in network by a user where VPC was created without account/domain ID """ @@ -1934,10 +1933,10 @@ def test_14_deploy_vm_1(self): self.debug("creating a VPC network in the account: %s" % user.name) - userapiclient = self.testClient.createUserApiClient( + userapiclient = self.testClient.getUserApiClient( UserName=user.name, DomainName=user.domain, - acctType=0) + type=0) vpc = VPC.create( @@ -1990,7 +1989,7 @@ def test_14_deploy_vm_1(self): return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "selfservice"]) def test_15_deploy_vm_2(self): """ Test deployment of vm in a network in a domain admin account where VPC is created without account/domain ID """ @@ -2017,8 +2016,8 @@ def test_15_deploy_vm_2(self): #0 - User, 1 - Root Admin, 2 - Domain Admin userapiclient = self.testClient.getUserApiClient( - account=user.name, - domain=self.services["domain"]["name"], + UserName=user.name, + DomainName=self.services["domain"]["name"], type=2) vpc = VPC.create( @@ -2071,7 +2070,7 @@ def test_15_deploy_vm_2(self): return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "selfservice"]) def test_16_deploy_vm_for_user_by_admin(self): """ Test deployment of vm in a network by root admin for user. """ @@ -2092,8 +2091,8 @@ def test_16_deploy_vm_for_user_by_admin(self): user.name) userapiclient = self.testClient.getUserApiClient( - account=user.name, - domain=user.domain, + UserName=user.name, + DomainName=user.domain, type=0) vpc = VPC.create( @@ -2148,7 +2147,7 @@ def test_16_deploy_vm_for_user_by_admin(self): return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "selfservice"]) def test_17_deploy_vm_for_user_by_domain_admin(self): """ Test deployment of vm in a network by domain admin for user. """ @@ -2171,8 +2170,8 @@ def test_17_deploy_vm_for_user_by_domain_admin(self): self.debug("Created account: %s" % domain_admin.name) self.cleanup.append(domain_admin) da_apiclient = self.testClient.getUserApiClient( - account=domain_admin.name, - domain=domain_admin.domain, + UserName=domain_admin.name, + DomainName=domain_admin.domain, type=2) user = Account.create( @@ -2188,11 +2187,11 @@ def test_17_deploy_vm_for_user_by_domain_admin(self): #0 - User, 1 - Root Admin, 2 - Domain Admin userapiclient = self.testClient.getUserApiClient( - account=user.name, - domain=user.domain, + UserName=user.name, + DomainName=user.domain, type=0) - with self.assertRaises(cloudstackAPIException): + with self.assertRaises(CloudstackAPIException): vpc = VPC.create( da_apiclient, self.services["vpc"], @@ -2202,7 +2201,7 @@ def test_17_deploy_vm_for_user_by_domain_admin(self): zoneid=self.zone.id, ) - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "selfservice"]) def test_18_create_net_for_user_diff_domain_by_doadmin(self): """ Test creation of network by domain admin for user from different domain """ @@ -2222,8 +2221,8 @@ def test_18_create_net_for_user_diff_domain_by_doadmin(self): self.debug("Created account: %s" % domain_admin.name) self.cleanup.append(domain_admin) da_apiclient = self.testClient.getUserApiClient( - account=domain_admin.name, - domain=self.services["domain"]["name"], + UserName=domain_admin.name, + DomainName=self.services["domain"]["name"], type=2) user = Account.create( @@ -2239,8 +2238,8 @@ def test_18_create_net_for_user_diff_domain_by_doadmin(self): #0 - User, 1 - Root Admin, 2 - Domain Admin userapiclient = self.testClient.getUserApiClient( - account=user.name, - domain=user.domain, + UserName=user.name, + DomainName=user.domain, type=0) vpc = VPC.create( @@ -2279,7 +2278,7 @@ def test_18_create_net_for_user_diff_domain_by_doadmin(self): vpcid=vpc.id ) - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "selfservice"]) def test_19_create_vpc_wo_params(self): """ Test creation of VPC without mandatory parameters """ @@ -2339,7 +2338,7 @@ def test_19_create_vpc_wo_params(self): domainid=self.account.domainid ) - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "selfservice"]) def test_20_update_vpc_name_display_text(self): """ Test to verify updation of vpc name and display text """ diff --git a/test/integration/component/test_vpc_distributed_routing_offering.py b/test/integration/component/test_vpc_distributed_routing_offering.py index 0fa7de7934..cc9a19154f 100644 --- a/test/integration/component/test_vpc_distributed_routing_offering.py +++ b/test/integration/component/test_vpc_distributed_routing_offering.py @@ -23,9 +23,9 @@ from nose.plugins.attrib import attr from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * +from marvin.lib.utils import * +from marvin.lib.base import * +from marvin.lib.common import * from marvin.sshClient import SshClient import datetime @@ -154,24 +154,27 @@ class TestVPCDistributedRouterOffering(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestVPCDistributedRouterOffering, - cls - ).getClsTestClient().getApiClient() - cls.services = Services().services + testClient = super(TestVPCDistributedRouterOffering, cls).getClsTestClient() + cls.apiclient = testClient.getApiClient() + cls.services = testClient.getParsedTestDataConfig() + # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.apiclient) + cls.zone = get_zone(cls.apiclient, testClient.getZoneForTests()) + cls.services['mode'] = cls.zone.networktype + cls.template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostype"] - ) + cls.apiclient, + cls.zone.id, + cls.services["ostype"] + ) + if cls.template == FAILED: + assert False, "get_template() failed to return template with description %s" % cls.services["ostype"] cls.services["virtual_machine"]["zoneid"] = cls.zone.id cls.services["virtual_machine"]["template"] = cls.template.id cls.service_offering = ServiceOffering.create( - cls.api_client, + cls.apiclient, cls.services["service_offering"] ) cls._cleanup = [ @@ -183,7 +186,7 @@ def setUpClass(cls): def tearDownClass(cls): try: #Cleanup resources used - cleanup_resources(cls.api_client, cls._cleanup) + cleanup_resources(cls.apiclient, cls._cleanup) except Exception as e: raise Exception("Warning: Exception during cleanup : %s" % e) return diff --git a/test/integration/component/test_vpc_network.py b/test/integration/component/test_vpc_network.py index c393401403..c5d9da6f25 100644 --- a/test/integration/component/test_vpc_network.py +++ b/test/integration/component/test_vpc_network.py @@ -21,8 +21,8 @@ from nose.plugins.attrib import attr from marvin.cloudstackTestCase import cloudstackTestCase, unittest from marvin.cloudstackAPI import startVirtualMachine, stopVirtualMachine -from marvin.integration.lib.utils import cleanup_resources, validateList -from marvin.integration.lib.base import (VirtualMachine, +from marvin.lib.utils import cleanup_resources, validateList +from marvin.lib.base import (VirtualMachine, ServiceOffering, Account, NATRule, @@ -35,7 +35,7 @@ StaticNATRule, NetworkACL, PublicIPAddress) -from marvin.integration.lib.common import (get_zone, +from marvin.lib.common import (get_zone, get_domain, get_template, wait_for_cleanup, @@ -239,17 +239,17 @@ class TestVPCNetwork(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestVPCNetwork, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestVPCNetwork, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services + # Added an attribute to track if Netscaler addition was successful. # Value is checked in tests and if not configured, Netscaler tests will be skipped cls.ns_configured = False # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, @@ -294,8 +294,7 @@ def setUp(self): admin=True, domainid=self.domain.id ) - self.cleanup = [] - self.cleanup.insert(0, self.account) + self.cleanup = [self.account, ] return def tearDown(self): @@ -695,7 +694,7 @@ def test_05_create_network_ext_LB(self): return @unittest.skip("skipped - RvR didn't support VPC currently ") - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "NA"]) def test_06_create_network_with_rvr(self): """ Test create network with redundant router capability """ @@ -769,7 +768,7 @@ def test_06_create_network_with_rvr(self): self.debug("Network creation failed") return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "selfservice"]) def test_07_create_network_unsupported_services(self): """ Test create network services not supported by VPC (Should fail) """ @@ -836,7 +835,7 @@ def test_07_create_network_unsupported_services(self): self.debug("Network creation failed as VPC doesn't have LB service") return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "selfservice"]) def test_08_create_network_without_sourceNAT(self): """ Test create network without sourceNAT service in VPC (should fail) """ @@ -1003,17 +1002,17 @@ class TestVPCNetworkRanges(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestVPCNetworkRanges, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestVPCNetworkRanges, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services + # Added an attribute to track if Netscaler addition was successful. # Value is checked in tests and if not configured, Netscaler tests will be skipped cls.ns_configured = False # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, @@ -1056,8 +1055,7 @@ def setUp(self): admin=True, domainid=self.domain.id ) - self.cleanup = [] - self.cleanup.insert(0, self.account) + self.cleanup = [self.account, ] return def tearDown(self): @@ -1186,7 +1184,7 @@ def test_01_create_network_outside_range(self, value): "Network creation failed as network cidr range is outside of vpc") return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "selfservice"]) def test_02_create_network_outside_range(self): """ Test create network outside cidr range of VPC """ @@ -1516,6 +1514,7 @@ def test_05_create_network_diff_account(self, value): admin=True, domainid=self.domain.id ) + self.cleanup.append(account) # Creating network using the network offering created self.debug("Creating network from diff account than VPC") @@ -1541,14 +1540,14 @@ class TestVPCNetworkUpgrade(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestVPCNetworkUpgrade, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestVPCNetworkUpgrade, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services + # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, @@ -1584,8 +1583,7 @@ def setUp(self): admin=True, domainid=self.domain.id ) - self.cleanup = [] - self.cleanup.insert(0, self.account) + self.cleanup = [self.account, ] return def tearDown(self): @@ -1645,7 +1643,7 @@ def validate_vpc_network(self, network, state=None): self.debug("VPC network validated - %s" % network.name) return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "provisioning"]) def test_01_network_services_upgrade(self): """ Test update Network that is part of a VPC to a network offering that has more services """ @@ -1933,8 +1931,6 @@ def test_01_network_services_upgrade(self): except Exception as e: self.fail("Failed to stop VMs, %s" % e) - wait_for_cleanup(self.apiclient, ["expunge.interval", "expunge.delay"]) - # When all Vms ain network are stopped, network state changes from Implemented --> Shutdown --> Allocated # We can't update the network when it is in Shutodown state, hence we should wait for the state to change to # Allocated and then update the network @@ -2007,7 +2003,7 @@ def test_01_network_services_upgrade(self): ) return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "provisioning"]) def test_02_network_vpcvr2vr_upgrade(self): """ Test update Network that is NOT part of a VPC to a nw offering that has services that are provided by VPCVR and vice versa """ @@ -2108,8 +2104,6 @@ def test_02_network_vpcvr2vr_upgrade(self): except Exception as e: self.fail("Failed to stop VMs, %s" % e) - wait_for_cleanup(self.apiclient, ["expunge.interval", "expunge.delay"]) - self.debug("Upgrading network offering to support PF services") with self.assertRaises(Exception): network_1.update( @@ -2123,14 +2117,14 @@ class TestVPCNetworkGc(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestVPCNetworkGc, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestVPCNetworkGc, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services + # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, @@ -2341,7 +2335,7 @@ def validate_vpc_network(self, network, state=None): self.debug("VPC network validated - %s" % network.name) return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "provisioning"]) def test_01_wait_network_gc(self): """ Test network gc after shutdown of vms in the network """ @@ -2367,7 +2361,7 @@ def test_01_wait_network_gc(self): self.assertEqual(lbrules, None, "LBrules were not cleared after network GC thread is run") return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "provisioning"]) def test_02_start_vm_network_gc(self): """ Test network rules after starting a VpcVr that was shutdown after network.gc """ @@ -2441,7 +2435,7 @@ def test_02_start_vm_network_gc(self): ) return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "provisioning"]) def test_03_restart_vpcvr(self): """ Test Stop all the Vms that are part of the a Network (Wait for network GC).Restart VPCVR. diff --git a/test/integration/component/test_vpc_network_lbrules.py b/test/integration/component/test_vpc_network_lbrules.py index d623fb9bc5..a5625e7216 100644 --- a/test/integration/component/test_vpc_network_lbrules.py +++ b/test/integration/component/test_vpc_network_lbrules.py @@ -20,7 +20,7 @@ #Import Local Modules from nose.plugins.attrib import attr from marvin.cloudstackTestCase import cloudstackTestCase, unittest -from marvin.integration.lib.base import (stopRouter, +from marvin.lib.base import (stopRouter, startRouter, Account, VpcOffering, @@ -34,11 +34,11 @@ VirtualMachine, LoadBalancerRule, StaticNATRule) -from marvin.integration.lib.common import (get_domain, +from marvin.lib.common import (get_domain, get_zone, get_template, list_routers) -from marvin.integration.lib.utils import cleanup_resources +from marvin.lib.utils import cleanup_resources import socket import time @@ -181,14 +181,13 @@ def setUpClass(cls): # We want to fail quicker if it's failure socket.setdefaulttimeout(60) - cls.api_client = super( - TestVPCNetworkLBRules, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestVPCNetworkLBRules, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, @@ -507,7 +506,7 @@ def create_egress_Internet_Rule(self, network): return nwacl_internet_1 - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "selfservice"]) def test_01_VPC_LBRulesListing(self): """ Test case no 210 and 227: List Load Balancing Rules belonging to a VPC """ @@ -555,7 +554,7 @@ def test_01_VPC_LBRulesListing(self): ) return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "provisioning"]) def test_02_VPC_CreateLBRuleInMultipleNetworks(self): """ Test Create LB rules for 1 network which is part of a two/multiple virtual networks of a VPC using a new Public IP Address available with the VPC when the Virtual Router is in Running State @@ -580,7 +579,7 @@ def test_02_VPC_CreateLBRuleInMultipleNetworks(self): self.check_wget_from_vm(vm_1, public_ip_1, testnegative=False) return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "provisioning"]) def test_03_VPC_CreateLBRuleInMultipleNetworksVRStoppedState(self): """ Test case no 222 : Create LB rules for a two/multiple virtual networks of a VPC using a new Public IP Address available with the VPC when the Virtual Router is in Stopped State @@ -616,7 +615,7 @@ def test_03_VPC_CreateLBRuleInMultipleNetworksVRStoppedState(self): self.check_wget_from_vm(vm_1, public_ip_1, testnegative=False) return - @attr(tags=["advanced","advancedns", "intervlan"]) + @attr(tags=["advanced","advancedns", "intervlan", "provisioning"]) def test_04_VPC_CreateLBRuleInMultipleNetworksVRStoppedState(self): """ Test case no 222 : Create LB rules for a two/multiple virtual networks of a VPC using a new Public IP Address available with the VPC when the Virtual Router is in Stopped State @@ -646,7 +645,7 @@ def test_04_VPC_CreateLBRuleInMultipleNetworksVRStoppedState(self): self.check_wget_from_vm(vm_1, public_ip_1, testnegative=False) return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "provisioning"]) def test_05_VPC_CreateAndDeleteLBRule(self): """ Test case no 214 : Delete few(not all) LB rules for a single virtual network of a VPC belonging to a single Public IP Address when the Virtual Router is in Running State @@ -677,7 +676,7 @@ def test_05_VPC_CreateAndDeleteLBRule(self): self.check_ssh_into_vm(vm_1, public_ip_1, testnegative=True) return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "provisioning"]) def test_06_VPC_CreateAndDeleteLBRuleVRStopppedState(self): """ Test Delete few(not all) LB rules for a single virtual network of a VPC belonging to a single Public IP Address when the Virtual Router is in Stopped State @@ -714,7 +713,7 @@ def test_06_VPC_CreateAndDeleteLBRuleVRStopppedState(self): self.check_ssh_into_vm(vm_1, public_ip_1, testnegative=True) return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "provisioning"]) def test_07_VPC_CreateAndDeleteAllLBRule(self): """ Test Delete all LB rules for a single virtual network of a VPC belonging to a single Public IP Address when the Virtual Router is in Running State @@ -747,7 +746,7 @@ def test_07_VPC_CreateAndDeleteAllLBRule(self): self.check_wget_from_vm(vm_1, public_ip_1, testnegative=True) return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "provisioning"]) def test_08_VPC_CreateAndDeleteAllLBRuleVRStoppedState(self): """ Test Delete all LB rules for a single virtual network of a VPC belonging to a single Public IP Address when the Virtual Router is in Stopped State @@ -780,7 +779,7 @@ def test_08_VPC_CreateAndDeleteAllLBRuleVRStoppedState(self): self.check_wget_from_vm(vm_1, public_ip_1, testnegative=True) return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "provisioning"]) def test_09_VPC_LBRuleCreateFailMultipleVPC(self): """ Test User should not be allowed to create a LB rule for a VM that belongs to a different VPC. """ @@ -818,7 +817,7 @@ def test_09_VPC_LBRuleCreateFailMultipleVPC(self): self.debug('Failed to Create LB rule vm_3 and vm_4') return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "selfservice"]) def test_10_VPC_FailedToCreateLBRuleNonVPCNetwork(self): """ Test User should not be allowed to create a LB rule for a VM that does not belong to any VPC. """ @@ -855,7 +854,7 @@ def test_10_VPC_FailedToCreateLBRuleNonVPCNetwork(self): self.debug('Failed to Create LB rule vm_3 and vm_4 in network2') return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "provisioning"]) def test_11_VPC_LBRuleCreateNotAllowed(self): """ Test case no 217 and 236: User should not be allowed to create a LB rule for a VM that does not belong to the same network but belongs to the same VPC. @@ -893,7 +892,7 @@ def test_11_VPC_LBRuleCreateNotAllowed(self): self.debug('Failed to Create LB rule vm_3 and vm_1') return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "selfservice"]) def test_12_VPC_LBRuleCreateFailForRouterIP(self): """ Test User should not be allowed to create a LB rule on an Ipaddress that Source Nat enabled. """ @@ -921,7 +920,7 @@ def test_12_VPC_LBRuleCreateFailForRouterIP(self): self.debug('Failed to Create LB rule vm_2 and vm_1') return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "provisioning"]) def test_13_VPC_LBRuleCreateFailForPFSourceNATIP(self): """ Test User should not be allowed to create a LB rule on an Ipaddress that already has a PF rule. """ @@ -951,7 +950,7 @@ def test_13_VPC_LBRuleCreateFailForPFSourceNATIP(self): self.debug('Failed to Create LB rule vm_2 and vm_1') return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "selfservice"]) def test_14_VPC_LBRuleCreateFailForStaticNatRule(self): """ Test User should not be allowed to create a LB rule on an Ipaddress that already has a Static Nat rule. """ @@ -980,7 +979,7 @@ def test_14_VPC_LBRuleCreateFailForStaticNatRule(self): self.debug('Failed to Create LB rule vm_2 and vm_1') return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "selfservice"]) def test_15_VPC_ReleaseIPForLBRuleCreated(self): """ Test release Ip address that has a LB rule assigned to it. """ diff --git a/test/integration/component/test_vpc_network_pfrules.py b/test/integration/component/test_vpc_network_pfrules.py index c65da4136a..31e7320267 100644 --- a/test/integration/component/test_vpc_network_pfrules.py +++ b/test/integration/component/test_vpc_network_pfrules.py @@ -19,7 +19,7 @@ """ from nose.plugins.attrib import attr from marvin.cloudstackTestCase import cloudstackTestCase, unittest -from marvin.integration.lib.base import (stopRouter, +from marvin.lib.base import (stopRouter, startRouter, Account, VpcOffering, @@ -32,11 +32,11 @@ Network, VirtualMachine, LoadBalancerRule) -from marvin.integration.lib.common import (get_domain, +from marvin.lib.common import (get_domain, get_zone, get_template, list_routers) -from marvin.integration.lib.utils import cleanup_resources +from marvin.lib.utils import cleanup_resources import socket import time @@ -182,14 +182,13 @@ def setUpClass(cls): # We want to fail quicker if it's failure socket.setdefaulttimeout(60) - cls.api_client = super( - TestVPCNetworkPFRules, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestVPCNetworkPFRules, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, @@ -484,7 +483,7 @@ def open_egress_to_world(self, network): return nwacl_internet_1 - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "provisioning"]) def test_01_network_services_VPC_StopCreatePF(self): """ Test : Create VPC PF rules on acquired public ip when VpcVirtualRouter is stopped """ @@ -515,7 +514,7 @@ def test_01_network_services_VPC_StopCreatePF(self): self.check_ssh_into_vm(vm_1, public_ip_1, testnegative=False) return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "provisioning"]) def test_02_network_services_VPC_CreatePF(self): """ Test Create VPC PF rules on acquired public ip when VpcVirtualRouter is Running """ @@ -535,7 +534,7 @@ def test_02_network_services_VPC_CreatePF(self): self.check_ssh_into_vm(vm_1, public_ip_1, testnegative=False) return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "provisioning"]) def test_03_network_services_VPC_StopCreateMultiplePF(self): """ Test Create multiple VPC PF rules on acquired public ip in diff't networks when VpcVirtualRouter is stopped """ @@ -571,7 +570,7 @@ def test_03_network_services_VPC_StopCreateMultiplePF(self): self.check_ssh_into_vm(vm_2, public_ip_2, testnegative=False) return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "provisioning"]) def test_04_network_services_VPC_CreateMultiplePF(self): """ Test Create multiple VPC PF rules on acquired public ip in diff't networks when VpcVirtualRouter is running """ @@ -599,7 +598,7 @@ def test_04_network_services_VPC_CreateMultiplePF(self): self.check_ssh_into_vm(vm_2, public_ip_2, testnegative=False) return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "provisioning"]) def test_05_network_services_VPC_StopDeletePF(self): """ Test delete a PF rule in VPC when VpcVirtualRouter is Stopped """ @@ -630,7 +629,7 @@ def test_05_network_services_VPC_StopDeletePF(self): self.check_wget_from_vm(vm_1, public_ip_1, testnegative=True) return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "provisioning"]) def test_06_network_services_VPC_DeletePF(self): """ Test delete a PF rule in VPC when VpcVirtualRouter is Running """ @@ -657,7 +656,7 @@ def test_06_network_services_VPC_DeletePF(self): self.check_wget_from_vm(vm_1, public_ip_1, testnegative=True) return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "provisioning"]) def test_07_network_services_VPC_StopDeleteAllPF(self): """ Test delete all PF rules in VPC when VpcVirtualRouter is Stopped """ @@ -691,7 +690,7 @@ def test_07_network_services_VPC_StopDeleteAllPF(self): self.check_wget_from_vm(vm_1, public_ip_1, testnegative=True) return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "provisioning"]) def test_08_network_services_VPC_DeleteAllPF(self): """ Test delete all PF rules in VPC when VpcVirtualRouter is Running """ @@ -721,7 +720,7 @@ def test_08_network_services_VPC_DeleteAllPF(self): self.check_wget_from_vm(vm_1, public_ip_1, testnegative=True) return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "provisioning"]) def test_09_network_services_VPC_StopDeleteAllMultiplePF(self): """ Test delete all PF rules in VPC across multiple networks when VpcVirtualRouter is Stopped """ @@ -788,7 +787,7 @@ def test_09_network_services_VPC_StopDeleteAllMultiplePF(self): self.check_wget_from_vm(vm_4, public_ip_4, testnegative=True) return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "provisioning"]) def test_10_network_services_VPC_DeleteAllMultiplePF(self): """ Test delete all PF rules in VPC across multiple networks when VpcVirtualRouter is Running """ diff --git a/test/integration/component/test_vpc_network_staticnatrule.py b/test/integration/component/test_vpc_network_staticnatrule.py index 46e34796f6..65cb044c9a 100644 --- a/test/integration/component/test_vpc_network_staticnatrule.py +++ b/test/integration/component/test_vpc_network_staticnatrule.py @@ -19,7 +19,7 @@ """ from nose.plugins.attrib import attr from marvin.cloudstackTestCase import cloudstackTestCase, unittest -from marvin.integration.lib.base import (Account, +from marvin.lib.base import (Account, VpcOffering, VPC, ServiceOffering, @@ -32,11 +32,11 @@ StaticNATRule) from marvin.cloudstackAPI import (stopRouter, startRouter) -from marvin.integration.lib.common import (get_domain, +from marvin.lib.common import (get_domain, get_zone, get_template, list_routers) -from marvin.integration.lib.utils import cleanup_resources +from marvin.lib.utils import cleanup_resources import socket import time @@ -182,14 +182,13 @@ def setUpClass(cls): # We want to fail quicker if it's failure socket.setdefaulttimeout(60) - cls.api_client = super( - TestVPCNetworkPFRules, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestVPCNetworkPFRules, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, @@ -495,7 +494,7 @@ def create_ingress_rule(self, network, services=None): return nwacl_nat - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "provisioning"]) def test_01_VPC_StaticNatRuleCreateStoppedState(self): """ Test case no extra : """ @@ -523,7 +522,7 @@ def test_01_VPC_StaticNatRuleCreateStoppedState(self): return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "provisioning"]) def test_02_VPC_CreateStaticNatRule(self): """ Test case no 229 : Create Static NAT Rule for a single virtual network of a VPC using a new Public IP Address available with the VPC when the Virtual Router is in Running State @@ -546,7 +545,7 @@ def test_02_VPC_CreateStaticNatRule(self): self.check_ssh_into_vm(vm_1, public_ip_1, testnegative=False) return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "provisioning"]) def test_03_VPC_StopCreateMultipleStaticNatRuleStopppedState(self): """ Test case no extra : Create Static Nat Rule rules for a two/multiple virtual networks of a VPC using a new Public IP Address available with the VPC when Virtual Router is in Stopped State @@ -586,7 +585,7 @@ def test_03_VPC_StopCreateMultipleStaticNatRuleStopppedState(self): self.check_ssh_into_vm(vm_2, public_ip_2, testnegative=False) return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "provisioning"]) def test_04_VPC_CreateMultipleStaticNatRule(self): """ Test case no 230 : Create Static NAT Rules for a two/multiple virtual networks of a VPC using a new Public IP Address available with the VPC when the Virtual Router is in Running State @@ -619,7 +618,7 @@ def test_04_VPC_CreateMultipleStaticNatRule(self): self.check_ssh_into_vm(vm_2, public_ip_2, testnegative=False) return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "provisioning"]) def test_05_network_services_VPC_DeleteAllPF(self): """ Test case no 232: Delete all Static NAT Rules for a single virtual network of a VPC belonging to a single Public IP Address when the Virtual Router is in Running State @@ -651,7 +650,7 @@ def test_05_network_services_VPC_DeleteAllPF(self): self.check_wget_from_vm(vm_1, public_ip_1, testnegative=True) return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "provisioning"]) def test_06_network_services_VPC_DeleteAllMultiplePF(self): """ Test case no 233: Delete all Static NAT rules for two/multiple virtual networks of a VPC. Observe the status of the Public IP Addresses of the rules when the Virtual Router is in Running State. diff --git a/test/integration/component/test_vpc_offerings.py b/test/integration/component/test_vpc_offerings.py index 699cef9d8f..f190773aab 100644 --- a/test/integration/component/test_vpc_offerings.py +++ b/test/integration/component/test_vpc_offerings.py @@ -23,9 +23,9 @@ from nose.plugins.attrib import attr from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * +from marvin.lib.utils import * +from marvin.lib.base import * +from marvin.lib.common import * from marvin.sshClient import SshClient import datetime @@ -137,14 +137,13 @@ class TestVPCOffering(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestVPCOffering, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestVPCOffering, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, @@ -235,7 +234,7 @@ def validate_vpc_network(self, network): self.debug("VPC network created successfully - %s" % network.name) return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "selfservice"]) def test_01_create_vpc_offering(self): """ Test create VPC offering """ @@ -255,7 +254,7 @@ def test_01_create_vpc_offering(self): self.validate_vpc_offering(vpc_off) return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "provisioning"]) def test_02_deploy_vms_in_vpc_nw(self): """Test deploy virtual machines in VPC networks""" @@ -457,7 +456,7 @@ def test_02_deploy_vms_in_vpc_nw(self): # TODO: Remote Access VPN is not yet supported in VPC return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "selfservice"]) def test_03_vpc_off_without_lb(self): """Test VPC offering without load balancing service""" @@ -578,7 +577,7 @@ def test_03_vpc_off_without_lb(self): ) return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "selfservice"]) def test_04_vpc_off_without_static_nat(self): """Test VPC offering without static NAT service""" @@ -697,7 +696,7 @@ def test_04_vpc_off_without_static_nat(self): ) return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "selfservice"]) def test_05_vpc_off_without_pf(self): """Test VPC offering without port forwarding service""" @@ -815,7 +814,7 @@ def test_05_vpc_off_without_pf(self): ) return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "selfservice"]) def test_06_vpc_off_invalid_services(self): """Test VPC offering with invalid services""" @@ -847,7 +846,7 @@ def test_06_vpc_off_invalid_services(self): self.fail("Failed to create the VPC offering - %s" % e) return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "selfservice"]) def test_07_update_vpc_off(self): """Test update VPC offering""" @@ -936,7 +935,7 @@ def test_07_update_vpc_off(self): ) return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "selfservice"]) def test_08_list_vpc_off(self): """Test list VPC offering""" diff --git a/test/integration/component/test_vpc_routers.py b/test/integration/component/test_vpc_routers.py index a83662740d..3cf537ae0b 100644 --- a/test/integration/component/test_vpc_routers.py +++ b/test/integration/component/test_vpc_routers.py @@ -22,9 +22,9 @@ from nose.plugins.attrib import attr from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * +from marvin.lib.utils import * +from marvin.lib.base import * +from marvin.lib.common import * import datetime @@ -169,16 +169,15 @@ class TestVPCRoutersBasic(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.apiclient = super( - TestVPCRoutersBasic, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestVPCRoutersBasic, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.apiclient, cls.services) - cls.zone = get_zone(cls.apiclient, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( - cls.apiclient, + cls.api_client, cls.zone.id, cls.services["ostype"] ) @@ -186,16 +185,16 @@ def setUpClass(cls): cls.services["virtual_machine"]["template"] = cls.template.id cls.service_offering = ServiceOffering.create( - cls.apiclient, + cls.api_client, cls.services["service_offering"] ) cls.vpc_off = VpcOffering.create( - cls.apiclient, + cls.api_client, cls.services["vpc_offering"] ) - cls.vpc_off.update(cls.apiclient, state='Enabled') + cls.vpc_off.update(cls.api_client, state='Enabled') cls.account = Account.create( - cls.apiclient, + cls.api_client, cls.services["account"], admin=True, domainid=cls.domain.id @@ -203,13 +202,13 @@ def setUpClass(cls): cls._cleanup = [cls.account] cls._cleanup.append(cls.vpc_off) #cls.debug("Enabling the VPC offering created") - cls.vpc_off.update(cls.apiclient, state='Enabled') + cls.vpc_off.update(cls.api_client, state='Enabled') #cls.debug("creating a VPC network in the account: %s" % # cls.account.name) cls.services["vpc"]["cidr"] = '10.1.1.1/16' cls.vpc = VPC.create( - cls.apiclient, + cls.api_client, cls.services["vpc"], vpcofferingid=cls.vpc_off.id, zoneid=cls.zone.id, @@ -224,13 +223,13 @@ def setUpClass(cls): def tearDownClass(cls): try: #Cleanup resources used - cleanup_resources(cls.apiclient, cls._cleanup) + cleanup_resources(cls.api_client, cls._cleanup) except Exception as e: raise Exception("Warning: Exception during cleanup : %s" % e) return def setUp(self): - self.apiclient = self.testClient.getApiClient() + self.api_client = self.testClient.getApiClient() return @@ -242,7 +241,7 @@ def validate_vpc_offering(self, vpc_offering): self.debug("Check if the VPC offering is created successfully?") vpc_offs = VpcOffering.list( - self.apiclient, + self.api_client, id=vpc_offering.id ) self.assertEqual( @@ -265,7 +264,7 @@ def validate_vpc_network(self, network, state=None): self.debug("Check if the VPC network is created successfully?") vpc_networks = VPC.list( - self.apiclient, + self.api_client, id=network.id ) self.assertEqual( @@ -291,7 +290,7 @@ def migrate_router(self, router): """ Migrate the router """ self.debug("Checking if the host is available for migration?") - hosts = Host.list(self.apiclient, zoneid=self.zone.id, type='Routing') + hosts = Host.list(self.api_client, zoneid=self.zone.id, type='Routing') self.assertEqual( isinstance(hosts, list), @@ -319,7 +318,7 @@ def migrate_router(self, router): cmd.isAsync = "false" cmd.hostid = host.id cmd.virtualmachineid = router.id - self.apiclient.migrateSystemVm(cmd) + self.api_client.migrateSystemVm(cmd) except Exception as e: self.fail("Failed to migrate instance, %s" % e) @@ -329,7 +328,7 @@ def migrate_router(self, router): #List routers to check state of router router_response = list_routers( - self.apiclient, + self.api_client, id=router.id ) self.assertEqual( @@ -343,7 +342,7 @@ def migrate_router(self, router): " still %s" % (host.id, router.hostid)) return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "selfservice"]) def test_01_stop_start_router_after_creating_vpc(self): """ Test to stop and start router after creation of VPC """ @@ -358,7 +357,7 @@ def test_01_stop_start_router_after_creating_vpc(self): # Stop the VPC Router routers = Router.list( - self.apiclient, + self.api_client, account=self.account.name, domainid=self.account.domainid, listall=True @@ -374,11 +373,11 @@ def test_01_stop_start_router_after_creating_vpc(self): #Stop the router cmd = stopRouter.stopRouterCmd() cmd.id = router.id - self.apiclient.stopRouter(cmd) + self.api_client.stopRouter(cmd) #List routers to check state of router router_response = list_routers( - self.apiclient, + self.api_client, id=router.id ) self.assertEqual( @@ -399,11 +398,11 @@ def test_01_stop_start_router_after_creating_vpc(self): self.debug("Starting the router with ID: %s" % router.id) cmd = startRouter.startRouterCmd() cmd.id = router.id - self.apiclient.startRouter(cmd) + self.api_client.startRouter(cmd) #List routers to check state of router router_response = list_routers( - self.apiclient, + self.api_client, id=router.id ) self.assertEqual( @@ -421,7 +420,7 @@ def test_01_stop_start_router_after_creating_vpc(self): return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "selfservice"]) def test_02_reboot_router_after_creating_vpc(self): """ Test to reboot the router after creating a VPC """ @@ -433,7 +432,7 @@ def test_02_reboot_router_after_creating_vpc(self): self.validate_vpc_offering(self.vpc_off) self.validate_vpc_network(self.vpc) routers = Router.list( - self.apiclient, + self.api_client, account=self.account.name, domainid=self.account.domainid, listall=True @@ -449,11 +448,11 @@ def test_02_reboot_router_after_creating_vpc(self): #Reboot the router cmd = rebootRouter.rebootRouterCmd() cmd.id = router.id - self.apiclient.rebootRouter(cmd) + self.api_client.rebootRouter(cmd) #List routers to check state of router router_response = list_routers( - self.apiclient, + self.api_client, id=router.id ) self.assertEqual( @@ -470,7 +469,7 @@ def test_02_reboot_router_after_creating_vpc(self): return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "provisioning"]) def test_03_migrate_router_after_creating_vpc(self): """ Test migration of router to another host after creating VPC """ @@ -478,7 +477,7 @@ def test_03_migrate_router_after_creating_vpc(self): self.validate_vpc_network(self.vpc) routers = Router.list( - self.apiclient, + self.api_client, account=self.account.name, domainid=self.account.domainid, listall=True @@ -491,7 +490,7 @@ def test_03_migrate_router_after_creating_vpc(self): self.migrate_router(routers[0]) return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "selfservice"]) def test_04_change_service_offerring_vpc(self): """ Tests to change service offering of the Router after creating a vpc @@ -505,7 +504,7 @@ def test_04_change_service_offerring_vpc(self): self.validate_vpc_network(self.vpc) routers = Router.list( - self.apiclient, + self.api_client, account=self.account.name, domainid=self.account.domainid, listall=True @@ -521,15 +520,15 @@ def test_04_change_service_offerring_vpc(self): self.debug("Stopping the router with ID: %s" % router.id) cmd = stopRouter.stopRouterCmd() cmd.id = router.id - self.apiclient.stopRouter(cmd) + self.api_client.stopRouter(cmd) service_offering = ServiceOffering.create( - self.apiclient, + self.api_client, self.services["service_offering_new"] ) self.debug("Changing service offering for the Router %s" % router.id) try: - router = Router.change_service_offering(self.apiclient, + router = Router.change_service_offering(self.api_client, router.id, service_offering.id ) @@ -538,7 +537,7 @@ def test_04_change_service_offerring_vpc(self): self.debug("Router %s" % router) routers = Router.list( - self.apiclient, + self.api_client, account=self.account.name, domainid=self.account.domainid, listall=True @@ -552,7 +551,7 @@ def test_04_change_service_offerring_vpc(self): ) return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "selfservice"]) def test_05_destroy_router_after_creating_vpc(self): """ Test to destroy the router after creating a VPC """ @@ -562,7 +561,7 @@ def test_05_destroy_router_after_creating_vpc(self): self.validate_vpc_offering(self.vpc_off) self.validate_vpc_network(self.vpc) routers = Router.list( - self.apiclient, + self.api_client, account=self.account.name, domainid=self.account.domainid, listall=True @@ -573,12 +572,12 @@ def test_05_destroy_router_after_creating_vpc(self): "List Routers should return a valid list" ) - Router.destroy( self.apiclient, + Router.destroy( self.api_client, id=routers[0].id ) routers = Router.list( - self.apiclient, + self.api_client, account=self.account.name, domainid=self.account.domainid, listall=True @@ -594,17 +593,16 @@ class TestVPCRouterOneNetwork(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.apiclient = super( - TestVPCRouterOneNetwork, - cls - ).getClsTestClient().getApiClient() cls._cleanup = [] + cls.testClient = super(TestVPCRouterOneNetwork, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.apiclient, cls.services) - cls.zone = get_zone(cls.apiclient, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( - cls.apiclient, + cls.api_client, cls.zone.id, cls.services["ostype"] ) @@ -612,19 +610,19 @@ def setUpClass(cls): cls.services["virtual_machine"]["template"] = cls.template.id cls.service_offering = ServiceOffering.create( - cls.apiclient, + cls.api_client, cls.services["service_offering"] ) cls._cleanup.append(cls.service_offering) cls.vpc_off = VpcOffering.create( - cls.apiclient, + cls.api_client, cls.services["vpc_offering"] ) - cls.vpc_off.update(cls.apiclient, state='Enabled') + cls.vpc_off.update(cls.api_client, state='Enabled') cls._cleanup.append(cls.vpc_off) cls.account = Account.create( - cls.apiclient, + cls.api_client, cls.services["account"], admin=True, domainid=cls.domain.id @@ -633,7 +631,7 @@ def setUpClass(cls): cls.services["vpc"]["cidr"] = '10.1.1.1/16' cls.vpc = VPC.create( - cls.apiclient, + cls.api_client, cls.services["vpc"], vpcofferingid=cls.vpc_off.id, zoneid=cls.zone.id, @@ -642,7 +640,7 @@ def setUpClass(cls): ) private_gateway = PrivateGateway.create( - cls.apiclient, + cls.api_client, gateway='10.1.3.1', ipaddress='10.1.3.100', netmask='255.255.255.0', @@ -650,34 +648,34 @@ def setUpClass(cls): vpcid=cls.vpc.id ) cls.gateways = PrivateGateway.list( - cls.apiclient, + cls.api_client, id=private_gateway.id, listall=True ) static_route = StaticRoute.create( - cls.apiclient, + cls.api_client, cidr='11.1.1.1/24', gatewayid=private_gateway.id ) cls.static_routes = StaticRoute.list( - cls.apiclient, + cls.api_client, id=static_route.id, listall=True ) cls.nw_off = NetworkOffering.create( - cls.apiclient, + cls.api_client, cls.services["network_offering"], conservemode=False ) # Enable Network offering - cls.nw_off.update(cls.apiclient, state='Enabled') + cls.nw_off.update(cls.api_client, state='Enabled') cls._cleanup.append(cls.nw_off) # Creating network using the network offering created cls.network_1 = Network.create( - cls.apiclient, + cls.api_client, cls.services["network"], accountid=cls.account.name, domainid=cls.account.domainid, @@ -689,7 +687,7 @@ def setUpClass(cls): # Spawn an instance in that network vm_1 = VirtualMachine.create( - cls.apiclient, + cls.api_client, cls.services["virtual_machine"], accountid=cls.account.name, domainid=cls.account.domainid, @@ -697,7 +695,7 @@ def setUpClass(cls): networkids=[str(cls.network_1.id)] ) vm_2 = VirtualMachine.create( - cls.apiclient, + cls.api_client, cls.services["virtual_machine"], accountid=cls.account.name, domainid=cls.account.domainid, @@ -707,7 +705,7 @@ def setUpClass(cls): # Spawn an instance in that network vm_3 = VirtualMachine.create( - cls.apiclient, + cls.api_client, cls.services["virtual_machine"], accountid=cls.account.name, domainid=cls.account.domainid, @@ -716,14 +714,14 @@ def setUpClass(cls): ) vms = VirtualMachine.list( - cls.apiclient, + cls.api_client, account=cls.account.name, domainid=cls.account.domainid, listall=True ) public_ip_1 = PublicIPAddress.create( - cls.apiclient, + cls.api_client, accountid=cls.account.name, zoneid=cls.zone.id, domainid=cls.account.domainid, @@ -732,7 +730,7 @@ def setUpClass(cls): ) nat_rule = NATRule.create( - cls.apiclient, + cls.api_client, vm_1, cls.services["natrule"], ipaddressid=public_ip_1.ipaddress.id, @@ -742,14 +740,14 @@ def setUpClass(cls): ) nwacl_nat = NetworkACL.create( - cls.apiclient, + cls.api_client, networkid=cls.network_1.id, services=cls.services["natrule"], traffictype='Ingress' ) public_ip_2 = PublicIPAddress.create( - cls.apiclient, + cls.api_client, accountid=cls.account.name, zoneid=cls.zone.id, domainid=cls.account.domainid, @@ -758,7 +756,7 @@ def setUpClass(cls): ) try: StaticNATRule.enable( - cls.apiclient, + cls.api_client, ipaddressid=public_ip_2.ipaddress.id, virtualmachineid=vm_2.id, networkid=cls.network_1.id @@ -768,7 +766,7 @@ def setUpClass(cls): public_ip_2.ipaddress.ipaddress, e)) public_ips = PublicIPAddress.list( - cls.apiclient, + cls.api_client, networkid=cls.network_1.id, listall=True, isstaticnat=True, @@ -776,7 +774,7 @@ def setUpClass(cls): domainid=cls.account.domainid ) public_ip_3 = PublicIPAddress.create( - cls.apiclient, + cls.api_client, accountid=cls.account.name, zoneid=cls.zone.id, domainid=cls.account.domainid, @@ -785,7 +783,7 @@ def setUpClass(cls): ) lb_rule = LoadBalancerRule.create( - cls.apiclient, + cls.api_client, cls.services["lbrule"], ipaddressid=public_ip_3.ipaddress.id, accountid=cls.account.name, @@ -794,17 +792,17 @@ def setUpClass(cls): domainid=cls.account.domainid ) - lb_rule.assign(cls.apiclient, [vm_3]) + lb_rule.assign(cls.api_client, [vm_3]) nwacl_lb = NetworkACL.create( - cls.apiclient, + cls.api_client, networkid=cls.network_1.id, services=cls.services["lbrule"], traffictype='Ingress' ) nwacl_internet_1 = NetworkACL.create( - cls.apiclient, + cls.api_client, networkid=cls.network_1.id, services=cls.services["http_rule"], traffictype='Egress' @@ -814,20 +812,20 @@ def setUpClass(cls): def tearDownClass(cls): try: #Cleanup resources used - cleanup_resources(cls.apiclient, cls._cleanup) + cleanup_resources(cls.api_client, cls._cleanup) except Exception as e: raise Exception("Warning: Exception during cleanup : %s" % e) return def setUp(self): - self.apiclient = self.testClient.getApiClient() + self.api_client = self.testClient.getApiClient() self.cleanup = [] return def tearDown(self): try: #Clean up, terminate the created network offerings - cleanup_resources(self.apiclient, self.cleanup) + cleanup_resources(self.api_client, self.cleanup) except Exception as e: raise Exception("Warning: Exception during cleanup : %s" % e) @@ -838,7 +836,7 @@ def validate_vpc_offering(self, vpc_offering): self.debug("Check if the VPC offering is created successfully?") vpc_offs = VpcOffering.list( - self.apiclient, + self.api_client, id=vpc_offering.id ) self.assertEqual( @@ -861,7 +859,7 @@ def validate_vpc_network(self, network, state=None): self.debug("Check if the VPC network is created successfully?") vpc_networks = VPC.list( - self.apiclient, + self.api_client, id=network.id ) self.assertEqual( @@ -887,13 +885,13 @@ def validate_network_rules(self): """ Validate network rules """ vms = VirtualMachine.list( - self.apiclient, + self.api_client, account=self.account.name, domainid=self.account.domainid, listall=True ) public_ips = PublicIPAddress.list( - self.apiclient, + self.api_client, account=self.account.name, domainid=self.account.domainid, listall=True @@ -927,7 +925,7 @@ def migrate_router(self, router): """ Migrate the router """ self.debug("Checking if the host is available for migration?") - hosts = Host.list(self.apiclient, zoneid=self.zone.id, type='Routing') + hosts = Host.list(self.api_client, zoneid=self.zone.id, type='Routing') self.assertEqual( isinstance(hosts, list), @@ -955,7 +953,7 @@ def migrate_router(self, router): cmd.isAsync = "false" cmd.hostid = host.id cmd.virtualmachineid = router.id - self.apiclient.migrateSystemVm(cmd) + self.api_client.migrateSystemVm(cmd) except Exception as e: self.fail("Failed to migrate instance, %s" % e) @@ -965,7 +963,7 @@ def migrate_router(self, router): #List routers to check state of router router_response = list_routers( - self.apiclient, + self.api_client, id=router.id ) self.assertEqual( @@ -980,7 +978,7 @@ def migrate_router(self, router): return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "provisioining"]) def test_01_start_stop_router_after_addition_of_one_guest_network(self): """ Test start/stop of router after addition of one guest network """ @@ -1012,7 +1010,7 @@ def test_01_start_stop_router_after_addition_of_one_guest_network(self): # Stop the VPC Router routers = Router.list( - self.apiclient, + self.api_client, account=self.account.name, domainid=self.account.domainid, listall=True @@ -1028,11 +1026,11 @@ def test_01_start_stop_router_after_addition_of_one_guest_network(self): #Stop the router cmd = stopRouter.stopRouterCmd() cmd.id = router.id - self.apiclient.stopRouter(cmd) + self.api_client.stopRouter(cmd) #List routers to check state of router router_response = list_routers( - self.apiclient, + self.api_client, id=router.id ) self.assertEqual( @@ -1053,11 +1051,11 @@ def test_01_start_stop_router_after_addition_of_one_guest_network(self): self.debug("Starting the router with ID: %s" % router.id) cmd = startRouter.startRouterCmd() cmd.id = router.id - self.apiclient.startRouter(cmd) + self.api_client.startRouter(cmd) #List routers to check state of router router_response = list_routers( - self.apiclient, + self.api_client, id=router.id ) self.assertEqual( @@ -1075,7 +1073,7 @@ def test_01_start_stop_router_after_addition_of_one_guest_network(self): return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "selfservice"]) def test_02_reboot_router_after_addition_of_one_guest_network(self): """ Test reboot of router after addition of one guest network """ @@ -1106,7 +1104,7 @@ def test_02_reboot_router_after_addition_of_one_guest_network(self): ) routers = Router.list( - self.apiclient, + self.api_client, account=self.account.name, domainid=self.account.domainid, listall=True @@ -1122,11 +1120,11 @@ def test_02_reboot_router_after_addition_of_one_guest_network(self): #Reboot the router cmd = rebootRouter.rebootRouterCmd() cmd.id = router.id - self.apiclient.rebootRouter(cmd) + self.api_client.rebootRouter(cmd) #List routers to check state of router router_response = list_routers( - self.apiclient, + self.api_client, id=router.id ) self.assertEqual( @@ -1142,7 +1140,7 @@ def test_02_reboot_router_after_addition_of_one_guest_network(self): ) return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "provisioning"]) def test_03_migrate_router_after_addition_of_one_guest_network(self): """ Test migrate of router after addition of one guest network """ @@ -1172,7 +1170,7 @@ def test_03_migrate_router_after_addition_of_one_guest_network(self): "List static route should return a valid response" ) routers = Router.list( - self.apiclient, + self.api_client, account=self.account.name, domainid=self.account.domainid, listall=True @@ -1185,7 +1183,7 @@ def test_03_migrate_router_after_addition_of_one_guest_network(self): self.migrate_router(routers[0]) return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "selfservice"]) def test_04_chg_srv_off_router_after_addition_of_one_guest_network(self): """ Test to change service offering of router after addition of one guest network """ @@ -1216,7 +1214,7 @@ def test_04_chg_srv_off_router_after_addition_of_one_guest_network(self): ) routers = Router.list( - self.apiclient, + self.api_client, account=self.account.name, domainid=self.account.domainid, listall=True @@ -1232,15 +1230,15 @@ def test_04_chg_srv_off_router_after_addition_of_one_guest_network(self): self.debug("Stopping the router with ID: %s" % router.id) cmd = stopRouter.stopRouterCmd() cmd.id = router.id - self.apiclient.stopRouter(cmd) + self.api_client.stopRouter(cmd) service_offering = ServiceOffering.create( - self.apiclient, + self.api_client, self.services["service_offering_new"] ) self.debug("Changing service offering for the Router %s" % router.id) try: - router = Router.change_service_offering(self.apiclient, + router = Router.change_service_offering(self.api_client, router.id, service_offering.id ) @@ -1249,7 +1247,7 @@ def test_04_chg_srv_off_router_after_addition_of_one_guest_network(self): self.debug("Router %s" % router) routers = Router.list( - self.apiclient, + self.api_client, account=self.account.name, domainid=self.account.domainid, listall=True @@ -1263,7 +1261,7 @@ def test_04_chg_srv_off_router_after_addition_of_one_guest_network(self): ) return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "selfservice"]) def test_05_destroy_router_after_addition_of_one_guest_network(self): """ Test destroy of router after addition of one guest network """ @@ -1294,7 +1292,7 @@ def test_05_destroy_router_after_addition_of_one_guest_network(self): ) routers = Router.list( - self.apiclient, + self.api_client, account=self.account.name, domainid=self.account.domainid, listall=True @@ -1305,12 +1303,12 @@ def test_05_destroy_router_after_addition_of_one_guest_network(self): "List Routers should return a valid list" ) - Router.destroy( self.apiclient, + Router.destroy( self.api_client, id=routers[0].id ) routers = Router.list( - self.apiclient, + self.api_client, account=self.account.name, domainid=self.account.domainid, listall=True diff --git a/test/integration/component/test_vpc_vm_life_cycle.py b/test/integration/component/test_vpc_vm_life_cycle.py index e40067ea86..fd995cdd5d 100644 --- a/test/integration/component/test_vpc_vm_life_cycle.py +++ b/test/integration/component/test_vpc_vm_life_cycle.py @@ -19,9 +19,9 @@ """ #Import Local Modules from nose.plugins.attrib import attr -from marvin.cloudstackTestCase import cloudstackTestCase, unittest -from marvin.integration.lib.utils import cleanup_resources, validateList -from marvin.integration.lib.base import (VirtualMachine, +from marvin.cloudstackTestCase import cloudstackTestCase +from marvin.lib.utils import cleanup_resources, validateList +from marvin.lib.base import (VirtualMachine, NATRule, LoadBalancerRule, StaticNATRule, @@ -35,7 +35,7 @@ Account, ServiceOffering, Host) -from marvin.integration.lib.common import (get_domain, +from marvin.lib.common import (get_domain, get_zone, get_template, get_free_vlan, @@ -212,14 +212,13 @@ class TestVMLifeCycleVPC(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestVMLifeCycleVPC, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestVMLifeCycleVPC, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, @@ -873,14 +872,13 @@ class TestVMLifeCycleSharedNwVPC(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestVMLifeCycleSharedNwVPC, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestVMLifeCycleSharedNwVPC, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, @@ -1258,24 +1256,6 @@ def test_02_stop_instance_in_network(self): except Exception as e: self.fail("Failed to stop the virtual instances, %s" % e) - self.debug("Check if the instance is in stopped state?") - vms = VirtualMachine.list( - self.apiclient, - id=self.vm_2.id, - listall=True - ) - self.assertEqual( - isinstance(vms, list), - True, - "List virtual machines should return a valid list" - ) - vm = vms[0] - self.assertEqual( - vm.state, - "Stopped", - "Virtual machine should be in stopped state" - ) - self.debug("Validating if network rules are coonfigured properly?") self.validate_network_rules() return @@ -1660,14 +1640,13 @@ class TestVMLifeCycleBothIsolated(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestVMLifeCycleBothIsolated, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestVMLifeCycleBothIsolated, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, @@ -1995,14 +1974,13 @@ class TestVMLifeCycleStoppedVPCVR(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestVMLifeCycleStoppedVPCVR, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestVMLifeCycleStoppedVPCVR, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, @@ -2681,14 +2659,13 @@ class TestVMLifeCycleDiffHosts(cloudstackTestCase): def setUpClass(cls): try: - cls.api_client = super( - TestVMLifeCycleDiffHosts, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestVMLifeCycleDiffHosts, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, @@ -3104,35 +3081,7 @@ def test_02_stop_instance_in_network(self): self.account.name) try: self.vm_1.stop(self.apiclient) - - list_vm_response = list_virtual_machines( - self.apiclient, - id=self.vm_1.id - ) - - vm_response = list_vm_response[0] - - self.assertEqual( - vm_response.state, - 'Stopped', - "VM state should be stopped" - ) - self.vm_2.stop(self.apiclient) - - list_vm_response = list_virtual_machines( - self.apiclient, - id=self.vm_2.id - ) - - vm_response = list_vm_response[0] - - self.assertEqual( - vm_response.state, - 'Stopped', - "VM state should be stopped" - ) - except Exception as e: self.fail("Failed to stop the virtual instances, %s" % e) diff --git a/test/integration/component/test_vpc_vms_deployment.py b/test/integration/component/test_vpc_vms_deployment.py index 0a244ab656..1c1f93d37e 100644 --- a/test/integration/component/test_vpc_vms_deployment.py +++ b/test/integration/component/test_vpc_vms_deployment.py @@ -20,7 +20,7 @@ #Import Local Modules from nose.plugins.attrib import attr from marvin.cloudstackTestCase import cloudstackTestCase, unittest -from marvin.integration.lib.base import (VirtualMachine, +from marvin.lib.base import (VirtualMachine, NetworkOffering, VpcOffering, VPC, @@ -36,13 +36,13 @@ StaticNATRule, Configurations) -from marvin.integration.lib.common import (get_domain, +from marvin.lib.common import (get_domain, get_zone, get_template, wait_for_cleanup, get_free_vlan) -from marvin.integration.lib.utils import cleanup_resources +from marvin.lib.utils import cleanup_resources from marvin.cloudstackAPI import rebootRouter @@ -166,14 +166,13 @@ class TestVMDeployVPC(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestVMDeployVPC, - cls - ).getClsTestClient().getApiClient() + cls.testClient = super(TestVMDeployVPC, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template( cls.api_client, cls.zone.id, @@ -276,7 +275,7 @@ def validate_vpc_network(self, network, state=None): self.debug("VPC network validated - %s" % network.name) return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "selfservice"]) def test_01_deploy_vms_in_network(self): """ Test deploy VMs in VPC networks """ @@ -490,7 +489,7 @@ def test_01_deploy_vms_in_network(self): ) return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "selfservice"]) def test_02_deploy_vms_delete_network(self): """ Test deploy VMs in VPC networks and delete one of the network """ @@ -742,7 +741,7 @@ def test_02_deploy_vms_delete_network(self): ) return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "selfservice"]) def test_03_deploy_vms_delete_add_network(self): """ Test deploy VMs, delete one of the network and add another one """ @@ -1011,7 +1010,7 @@ def test_03_deploy_vms_delete_add_network(self): ) return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "selfservice"]) def test_04_deploy_vms_delete_add_network_noLb(self): """ Test deploy VMs, delete one network without LB and add another one """ @@ -1305,7 +1304,7 @@ def test_04_deploy_vms_delete_add_network_noLb(self): ) return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "selfservice"]) def test_05_create_network_max_limit(self): """ Test create networks in VPC upto maximum limit for hypervisor """ @@ -1476,7 +1475,7 @@ def test_05_create_network_max_limit(self): ) return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "selfservice"]) def test_06_delete_network_vm_running(self): """ Test delete network having running instances in VPC """ @@ -1718,7 +1717,7 @@ def test_06_delete_network_vm_running(self): ) return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "selfservice"]) def test_07_delete_network_with_rules(self): """ Test delete network that has PF/staticNat/LB rules/Network Acl """ diff --git a/test/integration/component/test_vpn_users.py b/test/integration/component/test_vpn_users.py index 02dd02622a..c8b3a2dbac 100644 --- a/test/integration/component/test_vpn_users.py +++ b/test/integration/component/test_vpn_users.py @@ -19,9 +19,9 @@ """ # Import Local Modules from nose.plugins.attrib import attr -from marvin.cloudstackException import cloudstackAPIException +from marvin.cloudstackException import CloudstackAPIException from marvin.cloudstackTestCase import cloudstackTestCase -from marvin.integration.lib.base import ( +from marvin.lib.base import ( Account, ServiceOffering, VirtualMachine, @@ -31,11 +31,11 @@ Configurations, NATRule ) -from marvin.integration.lib.common import (get_domain, +from marvin.lib.common import (get_domain, get_zone, get_template ) -from marvin.integration.lib.utils import cleanup_resources +from marvin.lib.utils import cleanup_resources class Services: @@ -94,12 +94,13 @@ def __init__(self): class TestVPNUsers(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestVPNUsers, - cls).getClsTestClient().getApiClient() + cls.testClient = super(TestVPNUsers, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = Services().services # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services["mode"] = cls.zone.networktype @@ -155,7 +156,7 @@ def setUp(self): services=self.services["virtual_machine"] ) return - except cloudstackAPIException as e: + except CloudstackAPIException as e: self.tearDown() raise e @@ -258,7 +259,7 @@ def test_01_VPN_user_limit(self): self.debug("Limit exceeded exception raised!") return - @attr(tags=["advanced", "advancedns"]) + @attr(tags=["advanced", "advancedns", "selfservice"]) def test_02_use_vpn_port(self): """Test create VPN when L2TP port in use""" @@ -289,7 +290,7 @@ def test_02_use_vpn_port(self): self.debug("Create VPN connection failed! Test successful!") return - @attr(tags=["advanced", "advancedns"]) + @attr(tags=["advanced", "advancedns", "selfservice"]) def test_03_enable_vpn_use_port(self): """Test create NAT rule when VPN when L2TP enabled""" @@ -315,7 +316,7 @@ def test_03_enable_vpn_use_port(self): self.debug("Create NAT rule failed! Test successful!") return - @attr(tags=["advanced", "advancedns"]) + @attr(tags=["advanced", "advancedns", "selfservice"]) def test_04_add_new_users(self): """Test add new users to existing VPN""" @@ -343,7 +344,7 @@ def test_04_add_new_users(self): self.fail("Failed to create new VPN user: %s" % e) return - @attr(tags=["advanced", "advancedns"]) + @attr(tags=["advanced", "advancedns", "selfservice"]) def test_05_add_duplicate_user(self): """Test add duplicate user to existing VPN""" @@ -366,7 +367,7 @@ def test_05_add_duplicate_user(self): self.create_VPN_Users(rand_name=False) return - @attr(tags=["advanced", "advancedns"]) + @attr(tags=["advanced", "advancedns", "selfservice"]) def test_06_add_VPN_user_global_admin(self): """Test as global admin, add a new VPN user to an existing VPN entry that was created by another account.""" @@ -396,7 +397,7 @@ def test_06_add_VPN_user_global_admin(self): domainid=self.account.domainid) self.cleanup.append(admin) self.debug("Creating API client for newly created user") - api_client = self.testClient.createUserApiClient( + api_client = self.testClient.getUserApiClient( UserName=self.account.name, DomainName=self.account.domain) @@ -409,7 +410,7 @@ def test_06_add_VPN_user_global_admin(self): e) return - @attr(tags=["advanced", "advancedns"]) + @attr(tags=["advanced", "advancedns", "selfservice"]) def test_07_add_VPN_user_domain_admin(self): """Test as domain admin, add a new VPN user to an existing VPN entry that was created by another account.""" @@ -438,7 +439,7 @@ def test_07_add_VPN_user_domain_admin(self): domainid=self.account.domainid) self.cleanup.append(admin) self.debug("Creating API client for newly created user") - api_client = self.testClient.createUserApiClient( + api_client = self.testClient.getUserApiClient( UserName=self.account.name, DomainName=self.account.domain) diff --git a/test/integration/smoke/test_affinity_groups.py b/test/integration/smoke/test_affinity_groups.py index c96a580f19..c1c5d5b8e3 100644 --- a/test/integration/smoke/test_affinity_groups.py +++ b/test/integration/smoke/test_affinity_groups.py @@ -16,52 +16,15 @@ # specific language governing permissions and limitations # under the License. +from marvin.codes import FAILED from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * +from marvin.lib.utils import * +from marvin.lib.base import * +from marvin.lib.common import * from marvin.sshClient import SshClient from nose.plugins.attrib import attr -class Services: - """Test Account Services - """ - - def __init__(self): - self.services = { - "domain": { - "name": "Domain", - }, - "account": { - "email": "test@test.com", - "firstname": "Test", - "lastname": "User", - "username": "test", - # Random characters are appended for unique - # username - "password": "password", - }, - "service_offering": { - "name": "Tiny Instance", - "displaytext": "Tiny Instance", - "cpunumber": 1, - "cpuspeed": 100, - # in MHz - "memory": 128, - # In MBs - }, - "ostype": 'CentOS 5.3 (64-bit)', - "virtual_machine" : { - "affinity": { - "name": "webvms", - "type": "host anti-affinity", - }, - "hypervisor" : "XenServer", - } - } - - class TestDeployVmWithAffinityGroup(cloudstackTestCase): """ This test deploys a virtual machine into a user account @@ -70,36 +33,40 @@ class TestDeployVmWithAffinityGroup(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestDeployVmWithAffinityGroup, cls).getClsTestClient().getApiClient() - cls.services = Services().services + cls.testClient = super(TestDeployVmWithAffinityGroup, cls).getClsTestClient() + zone_name = cls.testClient.getZoneForTests() + cls.apiclient = cls.testClient.getApiClient() + cls.domain = get_domain(cls.apiclient) + cls.services = cls.testClient.getParsedTestDataConfig() # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.zone = get_zone(cls.apiclient, cls.testClient.getZoneForTests()) + cls.template = get_template( - cls.api_client, + cls.apiclient, cls.zone.id, cls.services["ostype"] ) + + if cls.template == FAILED: + assert False, "get_template() failed to return template with description %s" % cls.services["ostype"] + cls.services["virtual_machine"]["zoneid"] = cls.zone.id cls.services["template"] = cls.template.id cls.services["zoneid"] = cls.zone.id cls.account = Account.create( - cls.api_client, + cls.apiclient, cls.services["account"], domainid=cls.domain.id ) - - cls.services["account"] = cls.account.name - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] + cls.apiclient, + cls.services["service_offerings"] ) - cls.ag = AffinityGroup.create(cls.api_client, cls.services["virtual_machine"]["affinity"], - account=cls.services["account"], domainid=cls.domain.id) + cls.ag = AffinityGroup.create(cls.apiclient, cls.services["virtual_machine"]["affinity"], + account=cls.account.name, domainid=cls.domain.id) cls._cleanup = [ cls.service_offering, @@ -108,7 +75,7 @@ def setUpClass(cls): ] return - @attr(tags=["simulator", "basic", "advanced", "multihost"]) + @attr(tags=["basic", "advanced", "multihost"], required_hardware="false") def test_DeployVmAntiAffinityGroup(self): """ test DeployVM in anti-affinity groups @@ -118,7 +85,7 @@ def test_DeployVmAntiAffinityGroup(self): """ #deploy VM1 in affinity group created in setUp vm1 = VirtualMachine.create( - self.api_client, + self.apiclient, self.services["virtual_machine"], templateid=self.template.id, accountid=self.account.name, @@ -128,7 +95,7 @@ def test_DeployVmAntiAffinityGroup(self): ) list_vm1 = list_virtual_machines( - self.api_client, + self.apiclient, id=vm1.id ) self.assertEqual( @@ -151,7 +118,7 @@ def test_DeployVmAntiAffinityGroup(self): #deploy VM2 in affinity group created in setUp vm2 = VirtualMachine.create( - self.api_client, + self.apiclient, self.services["virtual_machine"], templateid=self.template.id, accountid=self.account.name, @@ -160,7 +127,7 @@ def test_DeployVmAntiAffinityGroup(self): affinitygroupnames=[self.ag.name] ) list_vm2 = list_virtual_machines( - self.api_client, + self.apiclient, id=vm2.id ) self.assertEqual( @@ -185,10 +152,10 @@ def test_DeployVmAntiAffinityGroup(self): msg="Both VMs of affinity group %s are on the same host" % self.ag.name) - @classmethod - def tearDownClass(cls): - try: - #Clean up, terminate the created templates - cleanup_resources(cls.api_client, cls._cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) + @classmethod + def tearDownClass(cls): + try: + #Clean up, terminate the created templates + cleanup_resources(cls.apiclient, cls._cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) diff --git a/test/integration/smoke/test_deploy_vgpu_enabled_vm.py b/test/integration/smoke/test_deploy_vgpu_enabled_vm.py index a09e87e6f2..2188c7f216 100644 --- a/test/integration/smoke/test_deploy_vgpu_enabled_vm.py +++ b/test/integration/smoke/test_deploy_vgpu_enabled_vm.py @@ -18,127 +18,69 @@ #Test from the Marvin - Testing in Python wiki #All tests inherit from cloudstackTestCase -from marvin.cloudstackTestCase import cloudstackTestCase +from marvin.cloudstackTestCase import cloudstackTestCase, unittest #Import Integration Libraries #base - contains all resources as entities and defines create, delete, list operations on them -from marvin.integration.lib.base import Account, VirtualMachine, ServiceOffering +from marvin.lib.base import Account, VirtualMachine, ServiceOffering #utils - utility classes for common cleanup, external library wrappers etc -from marvin.integration.lib.utils import cleanup_resources +from marvin.lib.utils import cleanup_resources #common - commonly used methods for all tests are listed here -from marvin.integration.lib.common import get_zone, get_domain, get_template +from marvin.lib.common import get_zone, get_domain, get_template, list_hosts -from nose.plugins.attrib import attr - -class Services: - """Test VM Life Cycle Services - """ +from marvin.sshClient import SshClient - def __init__(self): - self.services = { - "disk_offering":{ - "displaytext": "Small", - "name": "Small", - "disksize": 1 - }, - "account": { - "email": "test@test.com", - "firstname": "Test", - "lastname": "User", - "username": "test", - # Random characters are appended in create account to - # ensure unique username generated each time - "password": "password", - }, - "vgpu260q": # Create a virtual machine instance with vgpu type as 260q - { - "displayname": "testserver", - "username": "root", # VM creds for SSH - "password": "password", - "ssh_port": 22, - "hypervisor": 'XenServer', - "privateport": 22, - "publicport": 22, - "protocol": 'TCP', - }, - "vgpu140q": # Create a virtual machine instance with vgpu type as 140q - { - "displayname": "testserver", - "username": "root", - "password": "password", - "ssh_port": 22, - "hypervisor": 'XenServer', - "privateport": 22, - "publicport": 22, - "protocol": 'TCP', - }, - "service_offerings": - { - "vgpu260qwin": - { - "name": "Windows Instance with vGPU260Q", - "displaytext": "Windows Instance with vGPU260Q", - "cpunumber": 2, - "cpuspeed": 1600, # in MHz - "memory": 3072, # In MBs - }, - "vgpu140qwin": - { - # Small service offering ID to for change VM - # service offering from medium to small - "name": "Windows Instance with vGPU140Q", - "displaytext": "Windows Instance with vGPU140Q", - "cpunumber": 2, - "cpuspeed": 1600, - "memory": 3072, - } - }, - "diskdevice": ['/dev/vdc', '/dev/vdb', '/dev/hdb', '/dev/hdc', '/dev/xvdd', '/dev/cdrom', '/dev/sr0', '/dev/cdrom1' ], - # Disk device where ISO is attached to instance - "mount_dir": "/mnt/tmp", - "sleep": 60, - "timeout": 10, - #Migrate VM to hostid - "ostype": 'Windows 7 (32-bit)', - # CentOS 5.3 (64-bit) - } +from marvin.codes import FAILED, XEN_SERVER +from nose.plugins.attrib import attr class TestDeployvGPUenabledVM(cloudstackTestCase): - """Test deploy a vGPU enabled VM into a user account """ + Test deploy a vGPU enabled VM into a user account + """ + @classmethod + def setUpClass(cls): + testClient = super(TestDeployvGPUenabledVM, cls).getClsTestClient() + #Need to add check whether zone containing the xen hypervisor or not as well + hypervisor = testClient.getHypervisorInfo() + if hypervisor.lower() != XEN_SERVER.lower(): + raise unittest.skipTest("GPU feature is supported only on XenServer") + def setUp(self): - self.services = Services().services + self.testdata = self.testClient.getParsedTestDataConfig()["vgpu"] self.apiclient = self.testClient.getApiClient() # Get Zone, Domain and Default Built-in template - self.domain = get_domain(self.apiclient, self.services) - self.zone = get_zone(self.apiclient, self.services) - self.services["mode"] = self.zone.networktype + self.domain = get_domain(self.apiclient) + self.zone = get_zone(self.apiclient, self.testClient.getZoneForTests()) + self.testdata["mode"] = self.zone.networktype # Before running this test, register a windows template with ostype as 'Windows 7 (32-bit)' - self.template = get_template(self.apiclient, self.zone.id, self.services["ostype"], templatetype='USER') + self.template = get_template(self.apiclient, self.zone.id, self.testdata["ostype"]) + if self.template == FAILED: + assert False, "get_template() failed to return template with description %s" % self.testdata["ostype"] #create a user account self.account = Account.create( self.apiclient, - self.services["account"], + self.testdata["account"], domainid=self.domain.id ) - self.services["vgpu260q"]["zoneid"] = self.zone.id - self.services["vgpu260q"]["template"] = self.template.id + self.testdata["vgpu260q"]["zoneid"] = self.zone.id + self.testdata["vgpu260q"]["template"] = self.template.id - self.services["vgpu140q"]["zoneid"] = self.zone.id - self.services["vgpu140q"]["template"] = self.template.id + self.testdata["vgpu140q"]["zoneid"] = self.zone.id + self.testdata["vgpu140q"]["template"] = self.template.id + self.testdata["service_offerings"]["vgpu260qwin"]["serviceofferingdetails"] = [{'pciDevice': 'VGPU'}, + {'vgpuType':'GRID K120Q'}] #create a service offering self.service_offering = ServiceOffering.create( self.apiclient, - self.services["service_offerings"]["vgpu260qwin"], - serviceofferingdetails={'pciDevice': 'VGPU'} + self.testdata["service_offerings"]["vgpu260qwin"], ) #build cleanup list self.cleanup = [ @@ -146,7 +88,7 @@ def setUp(self): self.account ] - @attr(tags = ['advanced', 'simulator', 'basic', 'vgpu']) + @attr(tags = ['advanced', 'basic', 'vgpu'], required_hardware="true", BugId="CLOUDSTACK-6876") def test_deploy_vgpu_enabled_vm(self): """Test Deploy Virtual Machine @@ -157,11 +99,11 @@ def test_deploy_vgpu_enabled_vm(self): """ self.virtual_machine = VirtualMachine.create( self.apiclient, - self.services["vgpu260q"], + self.testdata["vgpu260q"], accountid=self.account.name, domainid=self.account.domainid, serviceofferingid=self.service_offering.id, - mode=self.services['mode'] + mode=self.testdata['mode'] ) list_vms = VirtualMachine.list(self.apiclient, id=self.virtual_machine.id) @@ -198,13 +140,13 @@ def test_deploy_vgpu_enabled_vm(self): "Running", msg="VM is not in Running state" ) - list_hosts = list_hosts( + hosts = list_hosts( self.apiclient, id=vm.hostid ) - hostip = list_hosts[0].ipaddress + hostip = hosts[0].ipaddress try: - sshClient = SshClient(host=hostip, port=22, user='root',passwd=self.services["host_password"]) + sshClient = SshClient(host=hostip, port=22, user='root',passwd=self.testdata["host_password"]) res = sshClient.execute("xe vgpu-list vm-name-label=%s params=type-uuid %s" % ( vm.instancename )) @@ -224,4 +166,4 @@ def tearDown(self): try: cleanup_resources(self.apiclient, self.cleanup) except Exception as e: - self.debug("Warning! Exception in tearDown: %s" % e) \ No newline at end of file + self.debug("Warning! Exception in tearDown: %s" % e) diff --git a/test/integration/smoke/test_deploy_vm.py b/test/integration/smoke/test_deploy_vm.py index fcde2294df..ed5dfaf37e 100644 --- a/test/integration/smoke/test_deploy_vm.py +++ b/test/integration/smoke/test_deploy_vm.py @@ -22,68 +22,35 @@ #Import Integration Libraries +from marvin.codes import FAILED #base - contains all resources as entities and defines create, delete, list operations on them -from marvin.integration.lib.base import Account, VirtualMachine, ServiceOffering +from marvin.lib.base import Account, VirtualMachine, ServiceOffering, SimulatorMock #utils - utility classes for common cleanup, external library wrappers etc -from marvin.integration.lib.utils import cleanup_resources +from marvin.lib.utils import cleanup_resources #common - commonly used methods for all tests are listed here -from marvin.integration.lib.common import get_zone, get_domain, get_template +from marvin.lib.common import get_zone, get_domain, get_template from nose.plugins.attrib import attr -class TestData(object): - """Test data object that is required to create resources - """ - def __init__(self): - self.testdata = { - #data to create an account - "account": { - "email": "test@test.com", - "firstname": "Test", - "lastname": "User", - "username": "test", - "password": "password", - }, - #data reqd for virtual machine creation - "virtual_machine" : { - "name" : "testvm", - "displayname" : "Test VM", - }, - #data reqd for virtual machine creation - "virtual_machine2" : { - "name" : "testvm2", - "displayname" : "Test VM2", - }, - #small service offering - "service_offering": { - "small": { - "name": "Small Instance", - "displaytext": "Small Instance", - "cpunumber": 1, - "cpuspeed": 100, - "memory": 256, - }, - }, - "ostype": 'CentOS 5.3 (64-bit)', - } - - class TestDeployVM(cloudstackTestCase): """Test deploy a VM into a user account """ def setUp(self): - self.testdata = TestData().testdata self.apiclient = self.testClient.getApiClient() + self.testdata = self.testClient.getParsedTestDataConfig() # Get Zone, Domain and Default Built-in template - self.domain = get_domain(self.apiclient, self.testdata) - self.zone = get_zone(self.apiclient, self.testdata) + self.domain = get_domain(self.apiclient) + self.zone = get_zone(self.apiclient, self.testClient.getZoneForTests()) self.testdata["mode"] = self.zone.networktype self.template = get_template(self.apiclient, self.zone.id, self.testdata["ostype"]) + if self.template == FAILED: + self.fail("get_template() failed to return template with description %s" % self.testdata["ostype"]) + #create a user account self.account = Account.create( self.apiclient, @@ -93,7 +60,7 @@ def setUp(self): #create a service offering self.service_offering = ServiceOffering.create( self.apiclient, - self.testdata["service_offering"]["small"] + self.testdata["service_offerings"]["small"] ) #build cleanup list self.cleanup = [ @@ -101,7 +68,7 @@ def setUp(self): self.account ] - @attr(tags = ['advanced', 'simulator', 'basic', 'sg']) + @attr(tags = ['advanced','basic', 'sg'], required_hardware="false") def test_deploy_vm(self): """Test Deploy Virtual Machine @@ -118,24 +85,14 @@ def test_deploy_vm(self): serviceofferingid=self.service_offering.id, templateid=self.template.id ) - + if not self.virtual_machine: + self.fail("Deploying a Virtual Machine Failed") list_vms = 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_vms, list), - True, - "List VM response was not a valid list" - ) - self.assertNotEqual( - len(list_vms), - 0, - "List VM response was empty" - ) + self.assertTrue(isinstance(list_vms, list) and len(list_vms) > 0, msg="List VM response empty") vm = list_vms[0] self.assertEqual( @@ -154,12 +111,12 @@ def test_deploy_vm(self): msg="VM is not in Running state" ) - @attr(tags = ['advanced', 'simulator', 'basic', 'sg']) + @attr(tags = ['advanced', 'basic', 'sg'], required_hardware="false") def test_deploy_vm_multiple(self): """Test Multiple Deploy Virtual Machine # Validate the following: - # 1. deploy 2 virtual machines + # 1. deploy 2 virtual machines # 2. listVirtualMachines using 'ids' parameter returns accurate information """ self.virtual_machine = VirtualMachine.create( @@ -186,7 +143,6 @@ def test_deploy_vm_multiple(self): self.debug( "Verify listVirtualMachines response for virtual machines: %s, %s" % (self.virtual_machine.id, self.virtual_machine2.id) ) - self.assertEqual( isinstance(list_vms, list), True, @@ -204,3 +160,225 @@ def tearDown(self): except Exception as e: self.debug("Warning! Exception in tearDown: %s" % e) +class TestDeployVMVolumeCreationFailure(cloudstackTestCase): + """Test VM deploy into user account with volume creation failure + """ + + def setUp(self): + self.testdata = self.testClient.getParsedTestDataConfig() + self.apiclient = self.testClient.getApiClient() + + # Get Zone, Domain and Default Built-in template + self.domain = get_domain(self.apiclient) + self.zone = get_zone(self.apiclient, self.testClient.getZoneForTests()) + self.testdata["mode"] = self.zone.networktype + self.template = get_template(self.apiclient, self.zone.id, self.testdata["ostype"]) + + #create a user account + self.account = Account.create( + self.apiclient, + self.testdata["account"], + domainid=self.domain.id + ) + #create a service offering + self.service_offering = ServiceOffering.create( + self.apiclient, + self.testdata["service_offerings"]["small"] + ) + #create first VM + self.virtual_machine = VirtualMachine.create( + self.apiclient, + self.testdata["virtual_machine"], + accountid=self.account.name, + zoneid=self.zone.id, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + templateid=self.template.id) + #mock to simulate volume creation failure + self.mock_volume_failure = SimulatorMock.create( + apiclient=self.apiclient, + command="CopyCommand", + count=6) + #build cleanup list + self.cleanup = [ + self.service_offering, + self.account, + self.mock_volume_failure + ] + + @attr(tags = ['advanced'], BugId="CLOUDSTACK-6873", required_hardware="false") + def test_deploy_vm_volume_creation_failure(self): + """Test Deploy Virtual Machine - volume creation failure and retry + + # Validate the following: + # 1. 1st VM creation failed + # 2. Check there were 4 failed volume creation retries (mock count = (6-4) = 2) + # 3. 2nd VM creation succeeded + # 4. Check there were 2 failed volume creation retries (mock count = (2-2) = 0) + # 5. ListVM returns accurate information + """ + self.virtual_machine = None + with self.assertRaises(Exception): + self.virtual_machine = VirtualMachine.create( + self.apiclient, + self.testdata["virtual_machine2"], + accountid=self.account.name, + zoneid=self.zone.id, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + templateid=self.template.id) + + self.mock_volume_failure = self.mock_volume_failure.query(self.apiclient) + self.assertEqual( + self.mock_volume_failure.count, + 2, + msg="Volume failure mock not executed") + + self.virtual_machine = VirtualMachine.create( + self.apiclient, + self.testdata["virtual_machine3"], + accountid=self.account.name, + zoneid=self.zone.id, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + templateid=self.template.id) + list_vms = VirtualMachine.list(self.apiclient, id=self.virtual_machine.id) + self.assertTrue(isinstance(list_vms, list) and len(list_vms) > 0, msg="List VM response empty") + vm = list_vms[0] + self.assertEqual( + vm.id, + self.virtual_machine.id, + "VM ids do not match") + self.assertEqual( + vm.name, + self.virtual_machine.name, + "VM names do not match") + self.assertEqual( + vm.state, + "Running", + msg="VM is not in Running state") + + self.mock_volume_failure = self.mock_volume_failure.query(self.apiclient) + self.assertEqual( + self.mock_volume_failure.count, + 0, + msg="Volume failure mock not executed") + + def tearDown(self): + try: + cleanup_resources(self.apiclient, self.cleanup) + except Exception as e: + self.debug("Warning! Exception in tearDown: %s" % e) + + +class TestDeployVMStartFailure(cloudstackTestCase): + """Test VM deploy into user account with start operation failure + """ + + def setUp(self): + self.testdata = self.testClient.getParsedTestDataConfig() + self.apiclient = self.testClient.getApiClient() + + # Get Zone, Domain and Default Built-in template + self.domain = get_domain(self.apiclient) + self.zone = get_zone(self.apiclient, self.testClient.getZoneForTests()) + self.testdata["mode"] = self.zone.networktype + self.template = get_template(self.apiclient, self.zone.id, self.testdata["ostype"]) + + #create a user account + self.account = Account.create( + self.apiclient, + self.testdata["account"], + domainid=self.domain.id + ) + #create a service offering + self.service_offering = ServiceOffering.create( + self.apiclient, + self.testdata["service_offerings"]["small"] + ) + #create first VM + self.virtual_machine = VirtualMachine.create( + self.apiclient, + self.testdata["virtual_machine"], + accountid=self.account.name, + zoneid=self.zone.id, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + templateid=self.template.id) + #mock to simulate vm start failure + self.mock_start_failure = SimulatorMock.create( + apiclient=self.apiclient, + command="StartCommand", + count=6) + #build cleanup list + self.cleanup = [ + self.service_offering, + self.account, + self.mock_start_failure + ] + + @attr(tags = ['advanced'], BugId="CLOUDSTACK-6873", required_hardware="false") + def test_deploy_vm_start_failure(self): + """Test Deploy Virtual Machine - start operation failure and retry + + # Validate the following: + # 1. 1st VM creation failed + # 2. Check there were 4 failed start operation retries (mock count = (6-4) = 2) + # 3. 2nd VM creation succeeded + # 4. Check there were 2 failed start operation retries (mock count = (2-2) = 0) + # 5. ListVM returns accurate information + """ + self.virtual_machine = None + with self.assertRaises(Exception): + self.virtual_machine = VirtualMachine.create( + self.apiclient, + self.testdata["virtual_machine2"], + accountid=self.account.name, + zoneid=self.zone.id, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + templateid=self.template.id) + + self.mock_start_failure = self.mock_start_failure.query(self.apiclient) + self.assertEqual( + self.mock_start_failure.count, + 2, + msg="Start failure mock not executed") + + self.virtual_machine = VirtualMachine.create( + self.apiclient, + self.testdata["virtual_machine3"], + accountid=self.account.name, + zoneid=self.zone.id, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + templateid=self.template.id) + list_vms = VirtualMachine.list(self.apiclient, id=self.virtual_machine.id) + self.assertTrue(isinstance(list_vms, list) and len(list_vms) > 0, msg="List VM response empty") + vm = list_vms[0] + self.assertEqual( + vm.id, + self.virtual_machine.id, + "VM ids do not match") + self.assertEqual( + vm.name, + self.virtual_machine.name, + "VM names do not match") + self.assertEqual( + vm.state, + "Running", + msg="VM is not in Running state") + + self.mock_start_failure = self.mock_start_failure.query(self.apiclient) + self.assertEqual( + self.mock_start_failure.count, + 0, + msg="Start failure mock not executed") + + def tearDown(self): + try: + cleanup_resources(self.apiclient, self.cleanup) + except Exception as e: + self.debug("Warning! Exception in tearDown: %s" % e) + + diff --git a/test/integration/smoke/test_deploy_vm_root_resize.py b/test/integration/smoke/test_deploy_vm_root_resize.py new file mode 100644 index 0000000000..48cdc02dec --- /dev/null +++ b/test/integration/smoke/test_deploy_vm_root_resize.py @@ -0,0 +1,272 @@ +# 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. + +#Test from the Marvin - Testing in Python wiki + +#All tests inherit from cloudstackTestCase +from marvin.cloudstackTestCase import cloudstackTestCase + +#Import Integration Libraries + +#base - contains all resources as entities and defines create, delete, list operations on them +from marvin.lib.base import Account, VirtualMachine, ServiceOffering + +#utils - utility classes for common cleanup, external library wrappers etc +from marvin.lib.utils import cleanup_resources + +#common - commonly used methods for all tests are listed here +from marvin.lib.common import get_zone, get_domain, get_template, list_volumes + +from marvin.codes import FAILED + +from nose.plugins.attrib import attr + +class TestData(object): + """Test data object that is required to create resources + """ + def __init__(self): + self.testdata = { + #data to create an account + "account": { + "email": "test@test.com", + "firstname": "Test", + "lastname": "User", + "username": "test", + "password": "password", + }, + #data reqd for virtual machine creation + "virtual_machine" : { + "name" : "testvm", + "displayname" : "Test VM", + }, + #small service offering + "service_offering": { + "small": { + "name": "Small Instance", + "displaytext": "Small Instance", + "cpunumber": 1, + "cpuspeed": 100, + "memory": 256, + }, + }, + "ostype": 'CentOS 5.3 (64-bit)', + } + +class TestDeployVM(cloudstackTestCase): + """Test deploy a VM into a user account + """ + + def setUp(self): + self.testdata = TestData().testdata + self.apiclient = self.testClient.getApiClient() + self.hypervisor = self.testClient.getHypervisorInfo() + + # Get Zone, Domain and Default Built-in template + self.domain = get_domain(self.apiclient) + self.zone = get_zone(self.apiclient, self.testClient.getZoneForTests()) + self.testdata["mode"] = self.zone.networktype + self.template = get_template(self.apiclient, self.zone.id, self.testdata["ostype"]) + if self.template == FAILED: + assert False, "get_template() failed to return template " +# for testing with specific template +# self.template = get_template(self.apiclient, self.zone.id, self.testdata["ostype"], templatetype='USER', services = {"template":'31f52a4d-5681-43f7-8651-ad4aaf823618'}) + + + #create a user account + self.account = Account.create( + self.apiclient, + self.testdata["account"], + domainid=self.domain.id + ) + #create a service offering + self.service_offering = ServiceOffering.create( + self.apiclient, + self.testdata["service_offering"]["small"] + ) + #build cleanup list + self.cleanup = [ + self.service_offering, + self.account + ] + + @attr(tags = ['advanced', 'basic', 'sg'], required_hardware="true") + def test_00_deploy_vm_root_resize(self): + """Test deploy virtual machine with root resize + + # Validate the following: + # 1. listVirtualMachines returns accurate information + # 2. root disk has new size per listVolumes + # 3. Rejects non-supported hypervisor types + """ + if(self.hypervisor == 'kvm'): + newrootsize = (self.template.size >> 30) + 2 + self.virtual_machine = VirtualMachine.create( + self.apiclient, + self.testdata["virtual_machine"], + accountid=self.account.name, + zoneid=self.zone.id, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + rootdisksize=newrootsize, + hypervisor=self.hypervisor + ) + + list_vms = 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_vms, list), + True, + "List VM response was not a valid list" + ) + self.assertNotEqual( + len(list_vms), + 0, + "List VM response was empty" + ) + + vm = list_vms[0] + self.assertEqual( + vm.id, + self.virtual_machine.id, + "Virtual Machine ids do not match" + ) + self.assertEqual( + vm.name, + self.virtual_machine.name, + "Virtual Machine names do not match" + ) + self.assertEqual( + vm.state, + "Running", + msg="VM is not in Running state" + ) + + # get root vol from created vm, verify it is correct size + list_volume_response = list_volumes( + self.apiclient, + virtualmachineid=self.virtual_machine.id, + type='ROOT', + listall=True + ) + + rootvolume = list_volume_response[0] + success = False + if rootvolume is not None and rootvolume.size == (newrootsize << 30): + success = True + + self.assertEqual( + success, + True, + "Check if the root volume resized appropriately" + ) + else: + self.debug("hypervisor %s unsupported for test 00, verifying it errors properly" % self.hypervisor) + + newrootsize = (self.template.size >> 30) + 2 + success = False + try: + self.virtual_machine = VirtualMachine.create( + self.apiclient, + self.testdata["virtual_machine"], + accountid=self.account.name, + zoneid=self.zone.id, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + rootdisksize=newrootsize, + hypervisor=self.hypervisor + ) + except Exception as ex: + if "Hypervisor XenServer does not support rootdisksize override" in str(ex): + success = True + else: + self.debug("virtual machine create did not fail appropriately. Error was actually : " + str(ex)); + + self.assertEqual(success, True, "Check if unsupported hypervisor %s fails appropriately" % self.hypervisor) + + @attr(tags = ['advanced', 'basic', 'sg'], required_hardware="true") + def test_01_deploy_vm_root_resize(self): + """Test proper failure to deploy virtual machine with rootdisksize of 0 + """ + if (self.hypervisor == 'kvm'): + newrootsize = 0 + success = False + try: + self.virtual_machine = VirtualMachine.create( + self.apiclient, + self.testdata["virtual_machine"], + accountid=self.account.name, + zoneid=self.zone.id, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + rootdisksize=newrootsize, + hypervisor=self.hypervisor + ) + except Exception as ex: + if "rootdisk size should be a non zero number" in str(ex): + success = True + else: + self.debug("virtual machine create did not fail appropriately. Error was actually : " + str(ex)); + + self.assertEqual(success, True, "Check if passing 0 as rootdisksize fails appropriately") + else: + self.debug("test 01 does not support hypervisor type " + self.hypervisor); + + @attr(tags = ['advanced', 'basic', 'sg'], required_hardware="true", BugId="6984") + def test_02_deploy_vm_root_resize(self): + """Test proper failure to deploy virtual machine with rootdisksize less than template size + """ + if (self.hypervisor == 'kvm'): + newrootsize = (self.template.size >> 30) - 1 + + self.assertEqual(newrootsize > 0, True, "Provided template is less than 1G in size, cannot run test") + + success = False + try: + self.virtual_machine = VirtualMachine.create( + self.apiclient, + self.testdata["virtual_machine"], + accountid=self.account.name, + zoneid=self.zone.id, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + rootdisksize=newrootsize, + hypervisor=self.hypervisor + ) + except Exception as ex: + if "rootdisksize override is smaller than template size" in str(ex): + success = True + else: + self.debug("virtual machine create did not fail appropriately. Error was actually : " + str(ex)); + + self.assertEqual(success, True, "Check if passing rootdisksize < templatesize fails appropriately") + else: + self.debug("test 01 does not support hypervisor type " + self.hypervisor); + + def tearDown(self): + try: + cleanup_resources(self.apiclient, self.cleanup) + except Exception as e: + self.debug("Warning! Exception in tearDown: %s" % e) diff --git a/test/integration/smoke/test_deploy_vm_with_userdata.py b/test/integration/smoke/test_deploy_vm_with_userdata.py index e3788cfbc2..c98b38aac0 100644 --- a/test/integration/smoke/test_deploy_vm_with_userdata.py +++ b/test/integration/smoke/test_deploy_vm_with_userdata.py @@ -16,62 +16,33 @@ # under the License. from marvin.cloudstackTestCase import cloudstackTestCase -from marvin.integration.lib.base import (ServiceOffering, +from marvin.lib.base import (ServiceOffering, VirtualMachine, Account) -from marvin.integration.lib.common import get_template, get_zone, list_virtual_machines -from marvin.integration.lib.utils import cleanup_resources +from marvin.lib.common import get_template, get_zone, list_virtual_machines +from marvin.lib.utils import cleanup_resources from nose.plugins.attrib import attr - +from marvin.codes import FAILED import random import string -class Services: - def __init__(self): - self.services = { - "account": { - "email": "test@test.com", - "firstname": "Test", - "lastname": "User", - "username": "test", - "password": "password", - }, - "virtual_machine": { - "displayname": "Test VM", - "username": "root", - "password": "password", - "ssh_port": 22, - "hypervisor": 'XenServer', - "privateport": 22, - "publicport": 22, - "protocol": 'TCP', - }, - "ostype": 'CentOS 5.3 (64-bit)', - "service_offering": { - "name": "Tiny Instance", - "displaytext": "Tiny Instance", - "cpunumber": 1, - "cpuspeed": 100, - "memory": 256, - }, - } - - class TestDeployVmWithUserData(cloudstackTestCase): """Tests for UserData """ @classmethod def setUpClass(cls): - cls.apiClient = super(TestDeployVmWithUserData, cls).getClsTestClient().getApiClient() - cls.services = Services().services - cls.zone = get_zone(cls.apiClient, cls.services) + testClient = super(TestDeployVmWithUserData, cls).getClsTestClient() + cls.apiClient = testClient.getApiClient() + cls.services = testClient.getParsedTestDataConfig() + + cls.zone = get_zone(cls.apiClient, testClient.getZoneForTests()) if cls.zone.localstorageenabled: #For devcloud since localstroage is enabled - cls.services["service_offering"]["storagetype"] = "local" + cls.services["service_offerings"]["storagetype"] = "local" cls.service_offering = ServiceOffering.create( cls.apiClient, - cls.services["service_offering"] + cls.services["service_offerings"] ) cls.account = Account.create(cls.apiClient, services=cls.services["account"]) cls.cleanup = [cls.account] @@ -80,6 +51,10 @@ def setUpClass(cls): cls.zone.id, cls.services["ostype"] ) + + if cls.template == FAILED: + assert False, "get_template() failed to return template with description %s" % cls.services["ostype"] + cls.debug("Successfully created account: %s, id: \ %s" % (cls.account.name,\ cls.account.id)) @@ -92,7 +67,10 @@ def setUpClass(cls): user_data = ''.join(random.choice(string.ascii_uppercase + string.digits) for x in range(2500)) cls.services["virtual_machine"]["userdata"] = user_data - @attr(tags=["simulator", "devcloud", "basic", "advanced"]) + def setup(self): + self.hypervisor = self.testClient.getHypervisorInfo() + + @attr(tags=["devcloud", "basic", "advanced", "post"], required_hardware="true") def test_deployvm_userdata_post(self): """Test userdata as POST, size > 2k """ @@ -117,7 +95,7 @@ def test_deployvm_userdata_post(self): self.assert_(vm.id == str(deployVmResponse.id), "Vm deployed is different from the test") self.assert_(vm.state == "Running", "VM is not in Running state") - @attr(tags=["simulator", "devcloud", "basic", "advanced"]) + @attr(tags=["devcloud", "basic", "advanced"], required_hardware="true") def test_deployvm_userdata(self): """Test userdata as GET, size > 2k """ diff --git a/test/integration/smoke/test_deploy_vms_with_varied_deploymentplanners.py b/test/integration/smoke/test_deploy_vms_with_varied_deploymentplanners.py index b4d35e0305..9fcb6431c1 100644 --- a/test/integration/smoke/test_deploy_vms_with_varied_deploymentplanners.py +++ b/test/integration/smoke/test_deploy_vms_with_varied_deploymentplanners.py @@ -15,40 +15,13 @@ # specific language governing permissions and limitations # under the License. +from marvin.codes import FAILED from marvin.cloudstackTestCase import cloudstackTestCase -from marvin.integration.lib.base import Account, VirtualMachine, ServiceOffering, Host, Cluster -from marvin.integration.lib.common import get_zone, get_domain, get_template -from marvin.integration.lib.utils import cleanup_resources +from marvin.lib.base import Account, VirtualMachine, ServiceOffering, Host, Cluster +from marvin.lib.common import get_zone, get_domain, get_template +from marvin.lib.utils import cleanup_resources from nose.plugins.attrib import attr -class Services: - def __init__(self): - self.services = { - "account": { - "email": "test@test.com", - "firstname": "Test", - "lastname": "User", - "username": "test", - # Random characters are appended for unique - # username - "password": "password", - }, - "service_offering": { - "name": "Planner Service Offering", - "displaytext": "Planner Service Offering", - "cpunumber": 1, - "cpuspeed": 100, - # in MHz - "memory": 128, - # In MBs - }, - "ostype": 'CentOS 5.3 (64-bit)', - "virtual_machine": { - "hypervisor": "XenServer", - } - } - - class TestDeployVmWithVariedPlanners(cloudstackTestCase): """ Test to create services offerings for deployment planners - firstfit, userdispersing @@ -56,16 +29,22 @@ class TestDeployVmWithVariedPlanners(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.apiclient = super(TestDeployVmWithVariedPlanners, cls).getClsTestClient().getApiClient() - cls.services = Services().services + testClient = super(TestDeployVmWithVariedPlanners, cls).getClsTestClient() + cls.apiclient = testClient.getApiClient() + cls.services = testClient.getParsedTestDataConfig() + # Get Zone, Domain and templates - cls.domain = get_domain(cls.apiclient, cls.services) - cls.zone = get_zone(cls.apiclient, cls.services) + cls.domain = get_domain(cls.apiclient) + cls.zone = get_zone(cls.apiclient, testClient.getZoneForTests()) cls.template = get_template( cls.apiclient, cls.zone.id, cls.services["ostype"] ) + + if cls.template == FAILED: + assert false, "get_template() failed to return template with description %s" % cls.services["ostype"] + cls.services["virtual_machine"]["zoneid"] = cls.zone.id cls.services["template"] = cls.template.id cls.services["zoneid"] = cls.zone.id @@ -75,21 +54,20 @@ def setUpClass(cls): cls.services["account"], domainid=cls.domain.id ) - cls.services["account"] = cls.account.name cls.hosts = Host.list(cls.apiclient, type='Routing') cls.clusters = Cluster.list(cls.apiclient) cls.cleanup = [ cls.account ] - @attr(tags=["simulator", "advanced", "basic", "sg"]) + @attr(tags=["advanced", "basic", "sg"], required_hardware="false") def test_deployvm_firstfit(self): """Test to deploy vm with a first fit offering """ #FIXME: How do we know that first fit actually happened? self.service_offering_firstfit = ServiceOffering.create( self.apiclient, - self.services["service_offering"], + self.services["service_offerings"], deploymentplanner='FirstFitPlanner' ) @@ -126,13 +104,13 @@ def test_deployvm_firstfit(self): msg="VM is not in Running state" ) - @attr(tags=["simulator", "advanced", "basic", "sg"]) + @attr(tags=["advanced", "basic", "sg"], required_hardware="false") def test_deployvm_userdispersing(self): """Test deploy VMs using user dispersion planner """ self.service_offering_userdispersing = ServiceOffering.create( self.apiclient, - self.services["service_offering"], + self.services["service_offerings"], deploymentplanner='UserDispersingPlanner' ) @@ -185,13 +163,13 @@ def test_deployvm_userdispersing(self): self.debug("VMs (%s, %s) meant to be dispersed are deployed in the same cluster %s" % ( vm1.id, vm2.id, vm1clusterid)) - @attr(tags=["simulator", "advanced", "basic", "sg"]) + @attr(tags=["advanced", "basic", "sg"], required_hardware="false") def test_deployvm_userconcentrated(self): """Test deploy VMs using user concentrated planner """ self.service_offering_userconcentrated = ServiceOffering.create( self.apiclient, - self.services["service_offering"], + self.services["service_offerings"], deploymentplanner='UserConcentratedPodPlanner' ) diff --git a/test/integration/smoke/test_disk_offerings.py b/test/integration/smoke/test_disk_offerings.py index 4588a26c8b..69a252b8b2 100644 --- a/test/integration/smoke/test_disk_offerings.py +++ b/test/integration/smoke/test_disk_offerings.py @@ -20,30 +20,17 @@ import marvin from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * +from marvin.lib.utils import * +from marvin.lib.base import * +from marvin.lib.common import * from nose.plugins.attrib import attr _multiprocess_shared_ = True -class Services: - """Test Disk offerings Services - """ - - def __init__(self): - self.services = { - "off": { - "name": "Disk offering", - "displaytext": "Disk offering", - "disksize": 1 # in GB - }, - } - class TestCreateDiskOffering(cloudstackTestCase): def setUp(self): - self.services = Services().services + self.services = self.testClient.getParsedTestDataConfig() self.apiclient = self.testClient.getApiClient() self.dbclient = self.testClient.getDbConnection() self.cleanup = [] @@ -58,17 +45,17 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags = ["advanced", "basic", "eip", "sg", "advancedns", "simulator", "smoke"]) + @attr(tags = ["advanced", "basic", "eip", "sg", "advancedns", "smoke"], required_hardware="false") def test_01_create_disk_offering(self): - """Test to create disk offering""" + """Test to create disk offering # Validate the following: # 1. createDiskOfferings should return valid info for new offering # 2. The Cloud Database contains the valid information - + """ disk_offering = DiskOffering.create( self.apiclient, - self.services["off"] + self.services["disk_offering"] ) self.cleanup.append(disk_offering) @@ -92,17 +79,16 @@ def test_01_create_disk_offering(self): self.assertEqual( disk_response.displaytext, - self.services["off"]["displaytext"], + self.services["disk_offering"]["displaytext"], "Check server id in createServiceOffering" ) self.assertEqual( disk_response.name, - self.services["off"]["name"], + self.services["disk_offering"]["name"], "Check name in createServiceOffering" ) return - class TestDiskOfferings(cloudstackTestCase): def setUp(self): @@ -122,15 +108,17 @@ def tearDown(self): @classmethod def setUpClass(cls): - cls.services = Services().services - cls.api_client = super(TestDiskOfferings, cls).getClsTestClient().getApiClient() + testClient = super(TestDiskOfferings, cls).getClsTestClient() + cls.apiclient = cls.testClient.getApiClient() + cls.services = cls.testClient.getParsedTestDataConfig() + cls.disk_offering_1 = DiskOffering.create( - cls.api_client, - cls.services["off"] + cls.apiclient, + cls.services["disk_offering"] ) cls.disk_offering_2 = DiskOffering.create( - cls.api_client, - cls.services["off"] + cls.apiclient, + cls.services["disk_offering"] ) cls._cleanup = [cls.disk_offering_1] return @@ -138,21 +126,22 @@ def setUpClass(cls): @classmethod def tearDownClass(cls): try: - cls.api_client = super(TestDiskOfferings, cls).getClsTestClient().getApiClient() - cleanup_resources(cls.api_client, cls._cleanup) + cls.apiclient = super(TestDiskOfferings, cls).getClsTestClient().getApiClient() + cleanup_resources(cls.apiclient, cls._cleanup) except Exception as e: raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags = ["advanced", "basic", "eip", "sg", "advancedns", "simulator", "smoke"]) + @attr(tags=["advanced", "basic", "eip", "sg", "advancedns", "smoke"], required_hardware="false") def test_02_edit_disk_offering(self): - """Test to update existing disk offering""" + """Test to update existing disk offering # Validate the following: # 1. updateDiskOffering should return # a valid information for newly created offering #Generate new name & displaytext from random data + """ random_displaytext = random_gen() random_name = random_gen() @@ -195,14 +184,14 @@ def test_02_edit_disk_offering(self): ) return - @attr(tags = ["advanced", "basic", "eip", "sg", "advancedns", "simulator", "smoke"]) + @attr(tags=["advanced", "basic", "eip", "sg", "advancedns", "smoke"], required_hardware="false") def test_03_delete_disk_offering(self): - """Test to delete disk offering""" + """Test to delete disk offering # Validate the following: # 1. deleteDiskOffering should return # a valid information for newly created offering - + """ self.disk_offering_2.delete(self.apiclient) self.debug("Deleted Disk offering with ID: %s" % diff --git a/test/integration/smoke/test_global_settings.py b/test/integration/smoke/test_global_settings.py index 5cd3654b22..4920421adf 100644 --- a/test/integration/smoke/test_global_settings.py +++ b/test/integration/smoke/test_global_settings.py @@ -19,9 +19,9 @@ #Import Local Modules from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * +from marvin.lib.utils import * +from marvin.lib.base import * +from marvin.lib.common import * from nose.plugins.attrib import attr #Import System modules @@ -32,7 +32,7 @@ class TestUpdateConfigWithScope(cloudstackTestCase): def setUp(self): self.apiClient = self.testClient.getApiClient() - @attr(tags=["simulator", "devcloud", "basic", "advanced"]) + @attr(tags=["devcloud", "basic", "advanced"], required_hardware="false") def test_UpdateConfigParamWithScope(self): """ test update configuration setting at zone level scope diff --git a/test/integration/smoke/test_guest_vlan_range.py b/test/integration/smoke/test_guest_vlan_range.py index 07e141d0fe..12ea52ecde 100644 --- a/test/integration/smoke/test_guest_vlan_range.py +++ b/test/integration/smoke/test_guest_vlan_range.py @@ -21,43 +21,22 @@ from nose.plugins.attrib import attr from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * +from marvin.lib.utils import * +from marvin.lib.base import * +from marvin.lib.common import * import datetime - -class Services: - """Test Dedicating Guest Vlan Ranges - """ - - def __init__(self): - self.services = { - "domain": { - "name": "Domain", - }, - "account": { - "email": "test@test.com", - "firstname": "Test", - "lastname": "User", - "username": "test", - "password": "password", - }, - "name": "testphysicalnetwork", - - "vlan": "2118-2120", - } - - class TestDedicateGuestVlanRange(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.apiclient = super(TestDedicateGuestVlanRange, cls).getClsTestClient().getApiClient() - cls.services = Services().services + testClient = super(TestDedicateGuestVlanRange, cls).getClsTestClient() + cls.apiclient = testClient.getApiClient() + cls.services = testClient.getParsedTestDataConfig() + # Get Zone, Domain - cls.domain = get_domain(cls.apiclient, cls.services) - cls.zone = get_zone(cls.apiclient, cls.services) + cls.domain = get_domain(cls.apiclient) + cls.zone = get_zone(cls.apiclient, testClient.getZoneForTests()) # Create Account cls.account = Account.create( @@ -99,13 +78,14 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags=["simulator", "advanced", "guestvlanrange", "dedicate", "release"]) + @attr(tags=["advanced", "guestvlanrange", "dedicate", "release"], required_hardware="false") def test_dedicateGuestVlanRange(self): """Test guest vlan range dedication """ """Assume a physical network is available """ + """ # Validate the following: # 1. List the available physical network using ListPhysicalNetwork # 2. Add a Guest Vlan range to the available physical network using UpdatePhysicalNetwork @@ -114,14 +94,10 @@ def test_dedicateGuestVlanRange(self): # 5. Release the dedicated guest vlan range back to the system # 6. Verify guest vlan range has been released, verify with listDedicatedGuestVlanRanges # 7. Remove the added guest vlan range using UpdatePhysicalNetwork - + """ self.debug("Adding guest vlan range") - - print "existing vlna = %s" %self.physical_network.vlan - print "free vlan = %s" %self.free_vlan new_vlan = self.physical_network.vlan + "," + self.free_vlan["partial_range"][0] - print "new vlan = %s" % new_vlan #new_vlan = self.free_vlan["partial_range"][0] addGuestVlanRangeResponse = self.physical_network.update(self.apiclient, id=self.physical_network.id, vlan=new_vlan) diff --git a/test/integration/smoke/test_hosts.py b/test/integration/smoke/test_hosts.py index 6f7d400eda..952f160094 100644 --- a/test/integration/smoke/test_hosts.py +++ b/test/integration/smoke/test_hosts.py @@ -5,9 +5,9 @@ # 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 @@ -20,9 +20,10 @@ import marvin from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * +from marvin.lib.utils import * +from marvin.lib.base import * +from marvin.lib.common import * +from marvin.lib.utils import (random_gen) from nose.plugins.attrib import attr #Import System modules @@ -30,81 +31,15 @@ _multiprocess_shared_ = True -class Services: - """Test Hosts & Clusters Services - """ - - def __init__(self): - self.services = { - "clusters": { - 0: { - "clustername": "Xen Cluster", - "clustertype": "CloudManaged", - # CloudManaged or ExternalManaged" - "hypervisor": "XenServer", - # Hypervisor type - }, - 1: { - "clustername": "KVM Cluster", - "clustertype": "CloudManaged", - # CloudManaged or ExternalManaged" - "hypervisor": "KVM", - # Hypervisor type - }, - 2: { - "hypervisor": 'VMware', - # Hypervisor type - "clustertype": 'ExternalManaged', - # CloudManaged or ExternalManaged" - "username": 'administrator', - "password": 'fr3sca', - "url": 'http://192.168.100.17/CloudStack-Clogeny-Pune/Pune-1', - # Format:http://vCenter Host/Datacenter/Cluster - "clustername": 'VMWare Cluster', - }, - }, - "hosts": { - "xenserver": { - # Must be name of corresponding Hypervisor type - # in cluster in small letters - "hypervisor": 'XenServer', - # Hypervisor type - "clustertype": 'CloudManaged', - # CloudManaged or ExternalManaged" - "url": 'http://192.168.100.211', - "username": "root", - "password": "fr3sca", - }, - "kvm": { - "hypervisor": 'KVM', - # Hypervisor type - "clustertype": 'CloudManaged', - # CloudManaged or ExternalManaged" - "url": 'http://192.168.100.212', - "username": "root", - "password": "fr3sca", - }, - "vmware": { - "hypervisor": 'VMware', - # Hypervisor type - "clustertype": 'ExternalManaged', - # CloudManaged or ExternalManaged" - "url": 'http://192.168.100.203', - "username": "administrator", - "password": "fr3sca", - }, - }, - } - class TestHosts(cloudstackTestCase): def setUp(self): - self.apiclient = self.testClient.getApiClient() + self.hypervisor = self.testClient.getHypervisorInfo() self.dbclient = self.testClient.getDbConnection() - self.services = Services().services - self.zone = get_zone(self.apiclient, self.services) - self.pod = get_pod(self.apiclient, self.zone.id, self.services) + self.services = self.testClient.getParsedTestDataConfig() + self.zone = get_zone(self.apiclient, self.testClient.getZoneForTests()) + self.pod = get_pod(self.apiclient, self.zone.id) self.cleanup = [] return @@ -118,33 +53,36 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @unittest.skip("skipped - our environments will not add hosts") + #@attr(tags=["selfservice"]) def test_01_clusters(self): - """Test Add clusters & hosts - XEN, KVM, VWARE - """ + """Test Add clusters & hosts - simulator + # Validate the following: - # 1. Verify hypervisortype returned by API is Xen/KVM/VWare + # 1. Verify hypervisortype returned by API is Simulator/Xen/KVM/VWare # 2. Verify that the cluster is in 'Enabled' allocation state # 3. Verify that the host is added successfully and in Up state # with listHosts API response - #Create clusters with Hypervisor type XEN/KVM/VWare + #Create clusters with Hypervisor type Simulator/XEN/KVM/VWare + """ for k, v in self.services["clusters"].items(): + v["clustername"] = v["clustername"] + "-" + random_gen() cluster = Cluster.create( self.apiclient, v, zoneid=self.zone.id, - podid=self.pod.id + podid=self.pod.id, + hypervisor=v["hypervisor"].lower() ) self.debug( "Created Cluster for hypervisor type %s & ID: %s" %( v["hypervisor"], - cluster.id + cluster.id )) self.assertEqual( - cluster.hypervisortype, - v["hypervisor"], + cluster.hypervisortype.lower(), + v["hypervisor"].lower(), "Check hypervisor type is " + v["hypervisor"] + " or not" ) self.assertEqual( @@ -166,16 +104,18 @@ def test_01_clusters(self): cluster, self.services["hosts"][hypervisor_type], zoneid=self.zone.id, - podid=self.pod.id + podid=self.pod.id, + hypervisor=v["hypervisor"].lower() ) + if host == FAILED: + self.fail("Host Creation Failed") self.debug( "Created host (ID: %s) in cluster ID %s" %( host.id, cluster.id )) - - #Cleanup Host & Cluster - self.cleanup.append(host) + #Cleanup Host & Cluster + self.cleanup.append(host) self.cleanup.append(cluster) list_hosts_response = list_hosts( @@ -223,8 +163,8 @@ def test_01_clusters(self): "Check cluster ID with list clusters response" ) self.assertEqual( - cluster_response.hypervisortype, - cluster.hypervisortype, + cluster_response.hypervisortype.lower(), + cluster.hypervisortype.lower(), "Check hypervisor type with is " + v["hypervisor"] + " or not" ) return diff --git a/test/integration/smoke/test_internal_lb.py b/test/integration/smoke/test_internal_lb.py index 7510169921..d2e6364ad2 100644 --- a/test/integration/smoke/test_internal_lb.py +++ b/test/integration/smoke/test_internal_lb.py @@ -17,80 +17,29 @@ """ Tests for configuring Internal Load Balancing Rules. """ #Import Local Modules +from marvin.codes import FAILED from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * +from marvin.lib.utils import * +from marvin.lib.base import * +from marvin.lib.common import * from nose.plugins.attrib import attr - -class Services: - def __init__(self): - self.services = { - "account": { - "email": "test@test.com", - "firstname": "Test", - "lastname": "User", - "username": "test", - "password": "password", - }, - "virtual_machine": { - "displayname": "Test VM", - "username": "root", - "password": "password", - "ssh_port": 22, - "hypervisor": 'XenServer', - "privateport": 22, - "publicport": 22, - "protocol": 'TCP', - }, - "ostype": 'CentOS 5.3 (64-bit)', - "service_offering": { - "name": "Tiny Instance", - "displaytext": "Tiny Instance", - "cpunumber": 1, - "cpuspeed": 100, - "memory": 256, - }, - "network_offering": { - "name": "Network offering for internal lb service", - "displaytext": "Network offering for internal lb service", - "guestiptype": "Isolated", - "traffictype": "Guest", - "supportedservices": "Vpn,Dhcp,Dns,Lb,UserData,SourceNat,StaticNat,PortForwarding,NetworkACL", - "serviceProviderList": { - "Dhcp": "VpcVirtualRouter", - "Dns": "VpcVirtualRouter", - "Vpn": "VpcVirtualRouter", - "UserData": "VpcVirtualRouter", - "Lb": "InternalLbVM", - "SourceNat": "VpcVirtualRouter", - "StaticNat": "VpcVirtualRouter", - "PortForwarding": "VpcVirtualRouter", - "NetworkACL": "VpcVirtualRouter", - }, - "serviceCapabilityList": { - "SourceNat": {"SupportedSourceNatTypes": "peraccount"}, - "Lb": {"lbSchemes": "internal", "SupportedLbIsolation": "dedicated"} - } - } - } - - class TestInternalLb(cloudstackTestCase): """Test Internal LB """ @classmethod def setUpClass(cls): - cls.apiclient = super(TestInternalLb, cls).getClsTestClient().getApiClient() - cls.services = Services().services - cls.zone = get_zone(cls.apiclient, cls.services) + testClient = super(TestInternalLb, cls).getClsTestClient() + cls.apiclient = testClient.getApiClient() + cls.services = testClient.getParsedTestDataConfig() + + cls.zone = get_zone(cls.apiclient, testClient.getZoneForTests()) cls.domain = get_domain(cls.apiclient) cls.service_offering = ServiceOffering.create( cls.apiclient, - cls.services["service_offering"] + cls.services["service_offerings"] ) cls.account = Account.create(cls.apiclient, services=cls.services["account"]) cls.template = get_template( @@ -98,18 +47,22 @@ def setUpClass(cls): cls.zone.id, cls.services["ostype"] ) + + if cls.template == FAILED: + assert False, "get_template() failed to return template with description %s" % cls.services["ostype"] + cls.debug("Successfully created account: %s, id: \ %s" % (cls.account.name,\ cls.account.id)) cls.cleanup = [cls.account] - @attr(tags=["smoke", "advanced"]) + @attr(tags=["smoke", "advanced"], required_hardware="true") def test_internallb(self): """Test create, delete, assign, remove of internal loadbalancer - """ - - #1) Create and enable network offering with Internal Lb vm service - self.networkOffering = NetworkOffering.create(self.apiclient, self.services["network_offering"], conservemode=False) + """ + #1) Create and enable network offering with Internal Lb vm service + self.networkOffering = NetworkOffering.create(self.apiclient, self.services["network_offering_internal_lb"], conservemode=False) + #TODO: SIMENH:modify this test to verify lb rules by sending request from another tier self.networkOffering.update(self.apiclient, state="Enabled") #2) Create VPC and network in it diff --git a/test/integration/smoke/test_iso.py b/test/integration/smoke/test_iso.py index 75289b8fbe..7c4bf0219e 100644 --- a/test/integration/smoke/test_iso.py +++ b/test/integration/smoke/test_iso.py @@ -20,9 +20,9 @@ import marvin from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * +from marvin.lib.utils import * +from marvin.lib.base import * +from marvin.lib.common import * from nose.plugins.attrib import attr import urllib from random import random @@ -31,69 +31,19 @@ _multiprocess_shared_ = True -class Services: - """Test ISO Services - """ - - def __init__(self): - self.services = { - "account": { - "email": "test@test.com", - "firstname": "Test", - "lastname": "User", - "username": "test", - # Random characters are appended in create account to - # ensure unique username generated each time - "password": "password", - }, - "iso_1": - { - "displaytext": "Test ISO 1", - "name": "ISO 1", - "url": "http://people.apache.org/~tsp/dummy.iso", - # Source URL where ISO is located - "isextractable": True, - "isfeatured": True, - "ispublic": True, - "ostype": "CentOS 5.3 (64-bit)", - }, - "iso_2": - { - "displaytext": "Test ISO 2", - "name": "ISO 2", - "url": "http://people.apache.org/~tsp/dummy.iso", - # Source URL where ISO is located - "isextractable": True, - "isfeatured": True, - "ispublic": True, - "ostype": "CentOS 5.3 (64-bit)", - "mode": 'HTTP_DOWNLOAD', - # Used in Extract template, value must be HTTP_DOWNLOAD - }, - "isfeatured": True, - "ispublic": True, - "isextractable": True, - "bootable": True, # For edit template - "passwordenabled": True, - "sleep": 60, - "timeout": 10, - "ostype": "CentOS 5.3 (64-bit)", - # CentOS 5.3 (64 bit) - } - - class TestCreateIso(cloudstackTestCase): - +#TODO: SIMENH: check the existence of registered of ISO in secondary deploy a VM with registered ISO. can be added \ +# as another test def setUp(self): - self.services = Services().services + self.services = self.testClient.getParsedTestDataConfig() self.apiclient = self.testClient.getApiClient() self.dbclient = self.testClient.getDbConnection() # Get Zone, Domain and templates - self.domain = get_domain(self.apiclient, self.services) - self.zone = get_zone(self.apiclient, self.services) + self.domain = get_domain(self.apiclient) + self.zone = get_zone(self.apiclient, self.testClient.getZoneForTests()) self.services['mode'] = self.zone.networktype self.services["domainid"] = self.domain.id - self.services["iso_2"]["zoneid"] = self.zone.id + self.services["iso2"]["zoneid"] = self.zone.id self.account = Account.create( self.apiclient, @@ -108,8 +58,8 @@ def setUp(self): if not isinstance(ostypes, list): raise unittest.SkipTest("OSTypeId for given description not found") - self.services["iso_1"]["ostypeid"] = ostypes[0].id - self.services["iso_2"]["ostypeid"] = ostypes[0].id + self.services["iso1"]["ostypeid"] = ostypes[0].id + self.services["iso2"]["ostypeid"] = ostypes[0].id self.services["ostypeid"] = ostypes[0].id self.cleanup = [self.account] @@ -125,7 +75,7 @@ def tearDown(self): return - @attr(tags = ["advanced", "basic", "eip", "sg", "advancedns", "smoke"]) + @attr(tags = ["advanced", "basic", "eip", "sg", "advancedns", "smoke"], BugId="CLOUDSTACK-6769, CLOUDSTACK-6774", required_hardware="false") def test_01_create_iso(self): """Test create public & private ISO """ @@ -138,7 +88,7 @@ def test_01_create_iso(self): iso = Iso.create( self.apiclient, - self.services["iso_2"], + self.services["iso2"], account=self.account.name, domainid=self.account.domainid ) @@ -169,17 +119,17 @@ def test_01_create_iso(self): self.assertEqual( iso_response.displaytext, - self.services["iso_2"]["displaytext"], + self.services["iso2"]["displaytext"], "Check display text of newly created ISO" ) self.assertEqual( iso_response.name, - self.services["iso_2"]["name"], + self.services["iso2"]["name"], "Check name of newly created ISO" ) self.assertEqual( iso_response.zoneid, - self.services["iso_2"]["zoneid"], + self.services["iso2"]["zoneid"], "Check zone ID of newly created ISO" ) return @@ -188,63 +138,64 @@ def test_01_create_iso(self): class TestISO(cloudstackTestCase): @classmethod + @attr(BugId="CLOUDSTACK-6769, CLOUDSTACK-6774") def setUpClass(cls): - cls.services = Services().services - cls.api_client = super(TestISO, cls).getClsTestClient().getApiClient() + testClient = super(TestISO, cls).getClsTestClient() + cls.apiclient = testClient.getApiClient() + cls.services = testClient.getParsedTestDataConfig() # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.apiclient) + cls.zone = get_zone(cls.apiclient, cls.testClient.getZoneForTests()) cls.services["domainid"] = cls.domain.id - cls.services["iso_1"]["zoneid"] = cls.zone.id - cls.services["iso_2"]["zoneid"] = cls.zone.id + cls.services["iso1"]["zoneid"] = cls.zone.id + cls.services["iso2"]["zoneid"] = cls.zone.id cls.services["sourcezoneid"] = cls.zone.id #populate second zone id for iso copy cmd = listZones.listZonesCmd() - cls.zones = cls.api_client.listZones(cmd) + cls.zones = cls.apiclient.listZones(cmd) if not isinstance(cls.zones, list): raise Exception("Failed to find zones.") #Create an account, ISOs etc. cls.account = Account.create( - cls.api_client, + cls.apiclient, cls.services["account"], domainid=cls.domain.id ) - cls.services["account"] = cls.account.name # Finding the OsTypeId from Ostype ostypes = list_os_types( - cls.api_client, + cls.apiclient, description=cls.services["ostype"] ) if not isinstance(ostypes, list): raise unittest.SkipTest("OSTypeId for given description not found") - cls.services["iso_1"]["ostypeid"] = ostypes[0].id - cls.services["iso_2"]["ostypeid"] = ostypes[0].id + cls.services["iso1"]["ostypeid"] = ostypes[0].id + cls.services["iso2"]["ostypeid"] = ostypes[0].id cls.services["ostypeid"] = ostypes[0].id cls.iso_1 = Iso.create( - cls.api_client, - cls.services["iso_1"], + cls.apiclient, + cls.services["iso1"], account=cls.account.name, domainid=cls.account.domainid ) try: - cls.iso_1.download(cls.api_client) + cls.iso_1.download(cls.apiclient) except Exception as e: raise Exception("Exception while downloading ISO %s: %s"\ % (cls.iso_1.id, e)) cls.iso_2 = Iso.create( - cls.api_client, - cls.services["iso_2"], + cls.apiclient, + cls.services["iso2"], account=cls.account.name, domainid=cls.account.domainid ) try: - cls.iso_2.download(cls.api_client) + cls.iso_2.download(cls.apiclient) except Exception as e: raise Exception("Exception while downloading ISO %s: %s"\ % (cls.iso_2.id, e)) @@ -255,9 +206,9 @@ def setUpClass(cls): @classmethod def tearDownClass(cls): try: - cls.api_client = super(TestISO, cls).getClsTestClient().getApiClient() + cls.apiclient = super(TestISO, cls).getClsTestClient().getApiClient() #Clean up, terminate the created templates - cleanup_resources(cls.api_client, cls._cleanup) + cleanup_resources(cls.apiclient, cls._cleanup) except Exception as e: raise Exception("Warning: Exception during cleanup : %s" % e) @@ -279,7 +230,7 @@ def tearDown(self): return - @attr(tags = ["advanced", "basic", "eip", "sg", "advancedns", "smoke"]) + @attr(tags = ["advanced", "basic", "eip", "sg", "advancedns", "smoke", "selfservice"],BugId="CLOUDSTACK-6769, CLOUDSTACK-6774") def test_02_edit_iso(self): """Test Edit ISO """ @@ -344,7 +295,7 @@ def test_02_edit_iso(self): ) return - @attr(tags = ["advanced", "basic", "eip", "sg", "advancedns", "smoke"]) + @attr(tags = ["advanced", "basic", "eip", "sg", "advancedns", "smoke", "selfservice"], BugId="CLOUDSTACK-6769, CLOUDSTACK-6774") def test_03_delete_iso(self): """Test delete ISO """ @@ -372,7 +323,7 @@ def test_03_delete_iso(self): ) return - @attr(tags = ["advanced", "basic", "eip", "sg", "advancedns", "smoke"]) + @attr(tags = ["advanced", "basic", "eip", "sg", "advancedns", "smoke", "provisioning"], BugId="CLOUDSTACK-6769, CLOUDSTACK-6774") def test_04_extract_Iso(self): "Test for extract ISO" @@ -386,21 +337,9 @@ def test_04_extract_Iso(self): cmd = extractIso.extractIsoCmd() cmd.id = self.iso_2.id - cmd.mode = self.services["iso_2"]["mode"] - cmd.zoneid = self.services["iso_2"]["zoneid"] + cmd.mode = self.services["iso2"]["mode"] + cmd.zoneid = self.services["iso2"]["zoneid"] list_extract_response = self.apiclient.extractIso(cmd) - - try: - #Format URL to ASCII to retrieve response code - formatted_url = urllib.unquote_plus(list_extract_response.url) - url_response = urllib.urlopen(formatted_url) - response_code = url_response.getcode() - except Exception: - self.fail( - "Extract ISO Failed with invalid URL %s (ISO id: %s)" \ - % (formatted_url, self.iso_2.id) - ) - self.assertEqual( list_extract_response.id, self.iso_2.id, @@ -408,14 +347,26 @@ def test_04_extract_Iso(self): ) self.assertEqual( list_extract_response.extractMode, - self.services["iso_2"]["mode"], + self.services["iso2"]["mode"], "Check mode of extraction" ) self.assertEqual( list_extract_response.zoneid, - self.services["iso_2"]["zoneid"], + self.services["iso2"]["zoneid"], "Check zone ID of extraction" ) + + try: + #Format URL to ASCII to retrieve response code + formatted_url = urllib.unquote_plus(list_extract_response.url) + url_response = urllib.urlopen(formatted_url) + response_code = url_response.getcode() + except Exception: + self.fail( + "Extract ISO Failed with invalid URL %s (ISO id: %s)" \ + % (formatted_url, self.iso_2.id) + ) + self.assertEqual( response_code, 200, @@ -423,7 +374,7 @@ def test_04_extract_Iso(self): ) return - @attr(tags = ["advanced", "basic", "eip", "sg", "advancedns", "smoke"]) + @attr(tags = ["advanced", "basic", "eip", "sg", "advancedns", "smoke", "selfservice"], BugId="CLOUDSTACK-6769, CLOUDSTACK-6774") def test_05_iso_permissions(self): """Update & Test for ISO permissions""" @@ -475,7 +426,7 @@ def test_05_iso_permissions(self): ) return - @attr(tags = ["advanced", "basic", "eip", "sg", "advancedns", "smoke", "multizone"]) + @attr(tags = ["advanced", "basic", "eip", "sg", "advancedns", "smoke", "multizone", "provisioning"], BugId="CLOUDSTACK-6769, CLOUDSTACK-6774") def test_06_copy_iso(self): """Test for copy ISO from one zone to another""" diff --git a/test/integration/smoke/test_loadbalance.py b/test/integration/smoke/test_loadbalance.py index 5f80c38303..f662974363 100644 --- a/test/integration/smoke/test_loadbalance.py +++ b/test/integration/smoke/test_loadbalance.py @@ -15,154 +15,86 @@ # specific language governing permissions and limitations # under the License. +from marvin.codes import FAILED from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * from marvin.sshClient import SshClient -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * +from marvin.lib.utils import * +from marvin.lib.base import * +from marvin.lib.common import * from nose.plugins.attrib import attr #Import System modules import time _multiprocess_shared_ = True -class Services: - """Test Network Services - """ - - def __init__(self): - self.services = { - "ostype": "CentOS 5.3 (64-bit)", - # Cent OS 5.3 (64 bit) - "lb_switch_wait": 10, - # Time interval after which LB switches the requests - "sleep": 60, - "timeout":10, - "network_offering": { - "name": 'Test Network offering', - "displaytext": 'Test Network offering', - "guestiptype": 'Isolated', - "supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding', - "traffictype": 'GUEST', - "availability": 'Optional', - "serviceProviderList" : { - "Dhcp": 'VirtualRouter', - "Dns": 'VirtualRouter', - "SourceNat": 'VirtualRouter', - "PortForwarding": 'VirtualRouter', - }, - }, - "network": { - "name": "Test Network", - "displaytext": "Test Network", - }, - "service_offering": { - "name": "Tiny Instance", - "displaytext": "Tiny Instance", - "cpunumber": 1, - "cpuspeed": 100, - # in MHz - "memory": 256, - # In MBs - }, - "account": { - "email": "test@test.com", - "firstname": "Test", - "lastname": "User", - "username": "test", - "password": "password", - }, - "server": - { - "displayname": "Small Instance", - "username": "root", - "password": "password", - "hypervisor": 'XenServer', - "privateport": 22, - "publicport": 22, - "ssh_port": 22, - "protocol": 'TCP', - }, - "natrule": - { - "privateport": 22, - "publicport": 2222, - "protocol": "TCP" - }, - "lbrule": - { - "name": "SSH", - "alg": "roundrobin", - # Algorithm used for load balancing - "privateport": 22, - "publicport": 2222, - "protocol": 'TCP' - } - } - class TestLoadBalance(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestLoadBalance, cls).getClsTestClient().getApiClient() - cls.services = Services().services + testClient = super(TestLoadBalance, cls).getClsTestClient() + cls.apiclient = testClient.getApiClient() + cls.services = testClient.getParsedTestDataConfig() + # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.apiclient) + cls.zone = get_zone(cls.apiclient, testClient.getZoneForTests()) template = get_template( - cls.api_client, + cls.apiclient, cls.zone.id, cls.services["ostype"] ) - cls.services["server"]["zoneid"] = cls.zone.id + if template == FAILED: + assert False, "get_template() failed to return template with description %s" % cls.services["ostype"] + + cls.services["virtual_machine"]["zoneid"] = cls.zone.id #Create an account, network, VM and IP addresses cls.account = Account.create( - cls.api_client, + cls.apiclient, cls.services["account"], admin=True, domainid=cls.domain.id ) cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] + cls.apiclient, + cls.services["service_offerings"] ) cls.vm_1 = VirtualMachine.create( - cls.api_client, - cls.services["server"], + cls.apiclient, + cls.services["virtual_machine"], templateid=template.id, accountid=cls.account.name, domainid=cls.account.domainid, serviceofferingid=cls.service_offering.id ) cls.vm_2 = VirtualMachine.create( - cls.api_client, - cls.services["server"], + cls.apiclient, + cls.services["virtual_machine"], templateid=template.id, accountid=cls.account.name, domainid=cls.account.domainid, serviceofferingid=cls.service_offering.id ) cls.vm_3 = VirtualMachine.create( - cls.api_client, - cls.services["server"], + cls.apiclient, + cls.services["virtual_machine"], templateid=template.id, accountid=cls.account.name, domainid=cls.account.domainid, serviceofferingid=cls.service_offering.id ) cls.non_src_nat_ip = PublicIPAddress.create( - cls.api_client, + cls.apiclient, cls.account.name, cls.zone.id, cls.account.domainid, - cls.services["server"] + cls.services["virtual_machine"] ) # Open up firewall port for SSH cls.fw_rule = FireWallRule.create( - cls.api_client, + cls.apiclient, ipaddressid=cls.non_src_nat_ip.ipaddress.id, protocol=cls.services["lbrule"]["protocol"], cidrlist=['0.0.0.0/0'], @@ -185,7 +117,7 @@ def tearDown(self): @classmethod def tearDownClass(cls): - cleanup_resources(cls.api_client, cls._cleanup) + cleanup_resources(cls.apiclient, cls._cleanup) return def try_ssh(self, ip_addr, hostnames): @@ -208,10 +140,10 @@ def try_ssh(self, ip_addr, hostnames): except Exception as e: self.fail("%s: SSH failed for VM with IP Address: %s" % (e, ip_addr)) - time.sleep(self.services["lb_switch_wait"]) + time.sleep(10) return - @attr(tags = ["advanced", "advancedns", "smoke"]) + @attr(tags = ["advanced", "advancedns", "smoke"], required_hardware="true") def test_01_create_lb_rule_src_nat(self): """Test to create Load balancing rule with source NAT""" @@ -371,7 +303,7 @@ def test_01_create_lb_rule_src_nat(self): self.try_ssh(src_nat_ip_addr.ipaddress, hostnames) return - @attr(tags = ["advanced", "advancedns", "smoke"]) + @attr(tags = ["advanced", "advancedns", "smoke"], required_hardware="true") def test_02_create_lb_rule_non_nat(self): """Test to create Load balancing rule with non source NAT""" @@ -489,7 +421,7 @@ def test_02_create_lb_rule_non_nat(self): self.try_ssh(self.non_src_nat_ip.ipaddress.ipaddress, hostnames) return - @attr(tags = ["advanced", "advancedns", "smoke"]) + @attr(tags = ["advanced", "advancedns", "smoke"], required_hardware="true") def test_assign_and_removal_lb(self): """Test for assign & removing load balancing rule""" diff --git a/test/integration/smoke/test_multipleips_per_nic.py b/test/integration/smoke/test_multipleips_per_nic.py index 7d180641d6..4093356417 100644 --- a/test/integration/smoke/test_multipleips_per_nic.py +++ b/test/integration/smoke/test_multipleips_per_nic.py @@ -16,6 +16,7 @@ # under the License. #Test from the Marvin - Testing in Python wiki +from marvin.codes import FAILED #All tests inherit from cloudstackTestCase from marvin.cloudstackTestCase import cloudstackTestCase @@ -23,13 +24,13 @@ #Import Integration Libraries #base - contains all resources as entities and defines create, delete, list operations on them -from marvin.integration.lib.base import Account, VirtualMachine, ServiceOffering +from marvin.lib.base import Account, VirtualMachine, ServiceOffering #utils - utility classes for common cleanup, external library wrappers etc -from marvin.integration.lib.utils import cleanup_resources +from marvin.lib.utils import cleanup_resources #common - commonly used methods for all tests are listed here -from marvin.integration.lib.common import get_zone, get_domain, get_template +from marvin.lib.common import get_zone, get_domain, get_template from marvin.cloudstackAPI.addIpToNic import addIpToNicCmd from marvin.cloudstackAPI.removeIpFromNic import removeIpFromNicCmd @@ -38,52 +39,23 @@ from nose.plugins.attrib import attr -class TestData(object): - """Test data object that is required to create resources - """ - def __init__(self): - self.testdata = { - #data to create an account - "account": { - "email": "test@test.com", - "firstname": "Test", - "lastname": "User", - "username": "test", - "password": "password", - }, - #data reqd for virtual machine creation - "virtual_machine" : { - "name" : "testvm", - "displayname" : "Test VM", - }, - #small service offering - "service_offering": { - "small": { - "name": "Small Instance", - "displaytext": "Small Instance", - "cpunumber": 1, - "cpuspeed": 100, - "memory": 256, - }, - }, - "ostype": 'CentOS 5.3 (64-bit)', - } - - class TestDeployVM(cloudstackTestCase): """Test deploy a VM into a user account """ def setUp(self): - self.testdata = TestData().testdata + self.testdata = self.testClient.getParsedTestDataConfig() self.apiclient = self.testClient.getApiClient() # Get Zone, Domain and Default Built-in template - self.domain = get_domain(self.apiclient, self.testdata) - self.zone = get_zone(self.apiclient, self.testdata) + self.domain = get_domain(self.apiclient) + self.zone = get_zone(self.apiclient, self.testClient.getZoneForTests()) self.testdata["mode"] = self.zone.networktype self.template = get_template(self.apiclient, self.zone.id, self.testdata["ostype"]) + if self.template == FAILED: + assert False, "get_template() failed to return template with description %s" % self.testdata["ostype"] + #create a user account self.account = Account.create( self.apiclient, @@ -93,7 +65,7 @@ def setUp(self): #create a service offering self.service_offering = ServiceOffering.create( self.apiclient, - self.testdata["service_offering"]["small"] + self.testdata["service_offerings"]["small"] ) #build cleanup list self.cleanup = [ @@ -150,8 +122,9 @@ def setUp(self): msg="VM is not in Running state" ) - @attr(tags = ['advanced', 'simulator', 'basic']) + @attr(tags = ['advanced', 'basic'], required_hardware="false") def test_nic_secondaryip_add_remove(self): + #TODO: SIMENH: add verification list_vms = VirtualMachine.list(self.apiclient, id=self.virtual_machine.id) vm = list_vms[0] nicid = vm.nic[0].id diff --git a/test/integration/smoke/test_network.py b/test/integration/smoke/test_network.py index 732fe15825..988a162971 100644 --- a/test/integration/smoke/test_network.py +++ b/test/integration/smoke/test_network.py @@ -5,9 +5,9 @@ # 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 @@ -18,139 +18,67 @@ """ #Import Local Modules import marvin -from marvin.cloudstackException import cloudstackAPIException +from marvin.codes import FAILED +from marvin.cloudstackException import CloudstackAPIException from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * from marvin.sshClient import SshClient -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * +from marvin.lib.utils import * +from marvin.lib.base import * +from marvin.lib.common import * from nose.plugins.attrib import attr #Import System modules import time _multiprocess_shared_ = True -class Services: - """Test Network Services - """ - - def __init__(self): - self.services = { - "ostype": "CentOS 5.3 (64-bit)", - # Cent OS 5.3 (64 bit) - "lb_switch_wait": 10, - # Time interval after which LB switches the requests - "sleep": 60, - "timeout":10, - "network_offering": { - "name": 'Test Network offering', - "displaytext": 'Test Network offering', - "guestiptype": 'Isolated', - "supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding', - "traffictype": 'GUEST', - "availability": 'Optional', - "serviceProviderList" : { - "Dhcp": 'VirtualRouter', - "Dns": 'VirtualRouter', - "SourceNat": 'VirtualRouter', - "PortForwarding": 'VirtualRouter', - }, - }, - "network": { - "name": "Test Network", - "displaytext": "Test Network", - }, - "service_offering": { - "name": "Tiny Instance", - "displaytext": "Tiny Instance", - "cpunumber": 1, - "cpuspeed": 100, - # in MHz - "memory": 256, - # In MBs - }, - "account": { - "email": "test@test.com", - "firstname": "Test", - "lastname": "User", - "username": "test", - "password": "password", - }, - "server": - { - "displayname": "Small Instance", - "username": "root", - "password": "password", - "hypervisor": 'XenServer', - "privateport": 22, - "publicport": 22, - "ssh_port": 22, - "protocol": 'TCP', - }, - "natrule": - { - "privateport": 22, - "publicport": 22, - "protocol": "TCP" - }, - "lbrule": - { - "name": "SSH", - "alg": "roundrobin", - # Algorithm used for load balancing - "privateport": 22, - "publicport": 2222, - "protocol": 'TCP' - } - } - class TestPublicIP(cloudstackTestCase): def setUp(self): self.apiclient = self.testClient.getApiClient() - self.services = Services().services @classmethod def setUpClass(cls): - cls.api_client = super(TestPublicIP, cls).getClsTestClient().getApiClient() - cls.services = Services().services + testClient = super(TestPublicIP, cls).getClsTestClient() + cls.apiclient = testClient.getApiClient() + cls.services = testClient.getParsedTestDataConfig() + # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.apiclient) + cls.zone = get_zone(cls.apiclient, testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype # Create Accounts & networks cls.account = Account.create( - cls.api_client, + cls.apiclient, cls.services["account"], admin=True, domainid=cls.domain.id ) cls.user = Account.create( - cls.api_client, + cls.apiclient, cls.services["account"], domainid=cls.domain.id ) cls.services["network"]["zoneid"] = cls.zone.id cls.network_offering = NetworkOffering.create( - cls.api_client, + cls.apiclient, cls.services["network_offering"], ) # Enable Network offering - cls.network_offering.update(cls.api_client, state='Enabled') + cls.network_offering.update(cls.apiclient, state='Enabled') cls.services["network"]["networkoffering"] = cls.network_offering.id cls.account_network = Network.create( - cls.api_client, + cls.apiclient, cls.services["network"], cls.account.name, cls.account.domainid ) cls.user_network = Network.create( - cls.api_client, + cls.apiclient, cls.services["network"], cls.user.name, cls.user.domainid @@ -158,13 +86,13 @@ def setUpClass(cls): # Create Source NAT IP addresses account_src_nat_ip = PublicIPAddress.create( - cls.api_client, + cls.apiclient, cls.account.name, cls.zone.id, cls.account.domainid ) user_src_nat_ip = PublicIPAddress.create( - cls.api_client, + cls.apiclient, cls.user.name, cls.zone.id, cls.user.domainid @@ -182,12 +110,12 @@ def setUpClass(cls): def tearDownClass(cls): try: #Cleanup resources used - cleanup_resources(cls.api_client, cls._cleanup) + cleanup_resources(cls.apiclient, cls._cleanup) except Exception as e: raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags = ["advanced", "advancedns", "smoke"]) + @attr(tags = ["advanced", "advancedns", "smoke"], required_hardware="false") def test_public_ip_admin_account(self): """Test for Associate/Disassociate public IP address for admin account""" @@ -223,6 +151,7 @@ def test_public_ip_admin_account(self): ) ip_address.delete(self.apiclient) + time.sleep(30) # Validate the following: # 1.listPublicIpAddresses should no more return the released address @@ -230,14 +159,13 @@ def test_public_ip_admin_account(self): self.apiclient, id=ip_address.ipaddress.id ) - self.assertEqual( - list_pub_ip_addr_resp, - None, - "Check if disassociated IP Address is no longer available" - ) + if list_pub_ip_addr_resp is None: + return + if (list_pub_ip_addr_resp) and (isinstance(list_pub_ip_addr_resp, list)) and (len(list_pub_ip_addr_resp) > 0): + self.fail("list public ip response is not empty") return - @attr(tags = ["advanced", "advancedns", "smoke"]) + @attr(tags = ["advanced", "advancedns", "smoke"], required_hardware="false") def test_public_ip_user_account(self): """Test for Associate/Disassociate public IP address for user account""" @@ -293,32 +221,35 @@ class TestPortForwarding(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestPortForwarding, cls).getClsTestClient().getApiClient() - cls.services = Services().services - + testClient = super(TestPortForwarding, cls).getClsTestClient() + cls.apiclient = testClient.getApiClient() + cls.services = testClient.getParsedTestDataConfig() # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.apiclient) + cls.zone = get_zone(cls.apiclient, testClient.getZoneForTests()) template = get_template( - cls.api_client, + cls.apiclient, cls.zone.id, cls.services["ostype"] ) + if template == FAILED: + assert False, "get_template() failed to return template with description %s" % cls.services["ostype"] + #Create an account, network, VM and IP addresses cls.account = Account.create( - cls.api_client, + cls.apiclient, cls.services["account"], admin=True, domainid=cls.domain.id ) - cls.services["server"]["zoneid"] = cls.zone.id + cls.services["virtual_machine"]["zoneid"] = cls.zone.id cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] + cls.apiclient, + cls.services["service_offerings"] ) cls.virtual_machine = VirtualMachine.create( - cls.api_client, - cls.services["server"], + cls.apiclient, + cls.services["virtual_machine"], templateid=template.id, accountid=cls.account.name, domainid=cls.account.domainid, @@ -338,8 +269,8 @@ def setUp(self): @classmethod def tearDownClass(cls): try: - cls.api_client = super(TestPortForwarding, cls).getClsTestClient().getApiClient() - cleanup_resources(cls.api_client, cls._cleanup) + cls.apiclient = super(TestPortForwarding, cls).getClsTestClient().getApiClient() + cleanup_resources(cls.apiclient, cls._cleanup) except Exception as e: raise Exception("Warning: Exception during cleanup : %s" % e) @@ -347,7 +278,7 @@ def tearDown(self): cleanup_resources(self.apiclient, self.cleanup) return - @attr(tags = ["advanced", "advancedns", "smoke"]) + @attr(tags = ["advanced", "advancedns", "smoke"], required_hardware="true") def test_01_port_fwd_on_src_nat(self): """Test for port forwarding on source NAT""" @@ -390,7 +321,7 @@ def test_01_port_fwd_on_src_nat(self): 'Running', "VM state should be Running before creating a NAT rule." ) - # Open up firewall port for SSH + # Open up firewall port for SSH fw_rule = FireWallRule.create( self.apiclient, ipaddressid=src_nat_ip_addr.id, @@ -437,6 +368,12 @@ def test_01_port_fwd_on_src_nat(self): )) self.virtual_machine.get_ssh_client(src_nat_ip_addr.ipaddress) + vm_response = VirtualMachine.list( + self.apiclient, + id=self.virtual_machine.id + ) + if vm_response[0].state != 'Running': + self.fail("State of VM : %s is not found to be Running" % str(self.virtual_machine.ipaddress)) except Exception as e: self.fail( @@ -444,15 +381,15 @@ def test_01_port_fwd_on_src_nat(self): (self.virtual_machine.ipaddress, e) ) - nat_rule.delete(self.apiclient) - try: - list_nat_rule_response = list_nat_rules( - self.apiclient, - id=nat_rule.id - ) - except cloudstackAPIException: - self.debug("Nat Rule is deleted") + nat_rule.delete(self.apiclient) + except Exception as e: + self.fail("NAT Rule Deletion Failed: %s" % e) + + # NAT rule listing should fail as the nat rule does not exist + with self.assertRaises(Exception): + list_nat_rules(self.apiclient, + id=nat_rule.id) # Check if the Public SSH port is inaccessible with self.assertRaises(Exception): @@ -464,13 +401,11 @@ def test_01_port_fwd_on_src_nat(self): src_nat_ip_addr.ipaddress, self.virtual_machine.ssh_port, self.virtual_machine.username, - self.virtual_machine.password, - retries=2, - delay=0 + self.virtual_machine.password ) return - @attr(tags = ["advanced", "advancedns", "smoke"]) + @attr(tags = ["advanced", "advancedns", "smoke"], required_hardware="true") def test_02_port_fwd_on_non_src_nat(self): """Test for port forwarding on non source NAT""" @@ -483,7 +418,7 @@ def test_02_port_fwd_on_non_src_nat(self): self.account.name, self.zone.id, self.account.domainid, - self.services["server"] + self.services["virtual_machine"] ) self.cleanup.append(ip_address) @@ -509,7 +444,7 @@ def test_02_port_fwd_on_non_src_nat(self): 'Running', "VM state should be Running before creating a NAT rule." ) - # Open up firewall port for SSH + # Open up firewall port for SSH fw_rule = FireWallRule.create( self.apiclient, ipaddressid=ip_address.ipaddress.id, @@ -569,7 +504,7 @@ def test_02_port_fwd_on_non_src_nat(self): self.apiclient, id=nat_rule.id ) - except cloudstackAPIException: + except CloudstackAPIException: self.debug("Nat Rule is deleted") # Check if the Public SSH port is inaccessible @@ -596,17 +531,19 @@ class TestRebootRouter(cloudstackTestCase): def setUp(self): self.apiclient = self.testClient.getApiClient() - self.services = Services().services + self.services = self.testClient.getParsedTestDataConfig() # Get Zone, Domain and templates - self.domain = get_domain(self.apiclient, self.services) - self.zone = get_zone(self.apiclient, self.services) + self.domain = get_domain(self.apiclient) + self.zone = get_zone(self.apiclient, self.testClient.getZoneForTests()) template = get_template( self.apiclient, self.zone.id, self.services["ostype"] ) - self.services["server"]["zoneid"] = self.zone.id + if template == FAILED: + self.fail("get_template() failed to return template with description %s" % self.services["ostype"]) + self.services["virtual_machine"]["zoneid"] = self.zone.id #Create an account, network, VM and IP addresses self.account = Account.create( @@ -617,11 +554,11 @@ def setUp(self): ) self.service_offering = ServiceOffering.create( self.apiclient, - self.services["service_offering"] + self.services["service_offerings"] ) self.vm_1 = VirtualMachine.create( self.apiclient, - self.services["server"], + self.services["virtual_machine"], templateid=template.id, accountid=self.account.name, domainid=self.account.domainid, @@ -646,7 +583,7 @@ def setUp(self): self.vm_1.account, self.vm_1.zoneid, self.vm_1.domainid, - self.services["server"] + self.services["virtual_machine"] ) #Open up firewall port for SSH fw_rule = FireWallRule.create( @@ -680,7 +617,7 @@ def setUp(self): ] return - @attr(tags = ["advanced", "advancedns", "smoke"]) + @attr(tags = ["advanced", "advancedns", "smoke"], required_hardware="true") def test_reboot_router(self): """Test for reboot router""" @@ -696,7 +633,8 @@ def test_reboot_router(self): routers = list_routers( self.apiclient, account=self.account.name, - domainid=self.account.domainid + domainid=self.account.domainid, + listall=True ) self.assertEqual( isinstance(routers, list), @@ -762,17 +700,17 @@ class TestReleaseIP(cloudstackTestCase): def setUp(self): self.apiclient = self.testClient.getApiClient() - self.services = Services().services + self.services = self.testClient.getParsedTestDataConfig() # Get Zone, Domain and templates - self.domain = get_domain(self.apiclient, self.services) - self.zone = get_zone(self.apiclient, self.services) + self.domain = get_domain(self.apiclient) + self.zone = get_zone(self.apiclient, self.testClient.getZoneForTests()) template = get_template( self.apiclient, self.zone.id, self.services["ostype"] ) - self.services["server"]["zoneid"] = self.zone.id + self.services["virtual_machine"]["zoneid"] = self.zone.id #Create an account, network, VM, Port forwarding rule, LB rules self.account = Account.create( @@ -784,12 +722,12 @@ def setUp(self): self.service_offering = ServiceOffering.create( self.apiclient, - self.services["service_offering"] + self.services["service_offerings"] ) self.virtual_machine = VirtualMachine.create( self.apiclient, - self.services["server"], + self.services["virtual_machine"], templateid=template.id, accountid=self.account.name, domainid=self.account.domainid, @@ -806,7 +744,8 @@ def setUp(self): ip_addrs = list_publicIP( self.apiclient, account=self.account.name, - domainid=self.account.domainid + domainid=self.account.domainid, + issourcenat=False ) try: self.ip_addr = ip_addrs[0] @@ -835,7 +774,7 @@ def setUp(self): def tearDown(self): cleanup_resources(self.apiclient, self.cleanup) - @attr(tags = ["advanced", "advancedns", "smoke"]) + @attr(tags = ["advanced", "advancedns", "smoke"], required_hardware="false") def test_releaseIP(self): """Test for release public IP address""" @@ -843,21 +782,22 @@ def test_releaseIP(self): self.ip_address.delete(self.apiclient) - # Sleep to ensure that deleted state is reflected in other calls - time.sleep(self.services["sleep"]) + retriesCount = 10 + isIpAddressDisassociated = False - # ListPublicIpAddresses should not list deleted Public IP address - list_pub_ip_addr_resp = list_publicIP( + while retriesCount > 0: + listResponse = list_publicIP( self.apiclient, id=self.ip_addr.id - ) - self.debug("List Public IP response" + str(list_pub_ip_addr_resp)) + ) + if listResponse is None: + isIpAddressDisassociated = True + break + retriesCount -= 1 + time.sleep(60) + # End while - self.assertEqual( - list_pub_ip_addr_resp, - None, - "Check if disassociated IP Address is no longer available" - ) + self.assertTrue(isIpAddressDisassociated, "Failed to disassociate IP address") # ListPortForwardingRules should not list # associated rules with Public IP address @@ -867,7 +807,7 @@ def test_releaseIP(self): id=self.nat_rule.id ) self.debug("List NAT Rule response" + str(list_nat_rule)) - except cloudstackAPIException: + except CloudstackAPIException: self.debug("Port Forwarding Rule is deleted") # listLoadBalancerRules should not list @@ -878,7 +818,7 @@ def test_releaseIP(self): id=self.lb_rule.id ) self.debug("List LB Rule response" + str(list_lb_rule)) - except cloudstackAPIException: + except CloudstackAPIException: self.debug("Port Forwarding Rule is deleted") # SSH Attempt though public IP should fail @@ -899,17 +839,17 @@ class TestDeleteAccount(cloudstackTestCase): def setUp(self): self.apiclient = self.testClient.getApiClient() - self.services = Services().services + self.services = self.testClient.getParsedTestDataConfig() # Get Zone, Domain and templates - self.domain = get_domain(self.apiclient, self.services) - self.zone = get_zone(self.apiclient, self.services) + self.domain = get_domain(self.apiclient) + self.zone = get_zone(self.apiclient, self.testClient.getZoneForTests()) template = get_template( self.apiclient, self.zone.id, self.services["ostype"] ) - self.services["server"]["zoneid"] = self.zone.id + self.services["virtual_machine"]["zoneid"] = self.zone.id #Create an account, network, VM and IP addresses self.account = Account.create( @@ -920,11 +860,11 @@ def setUp(self): ) self.service_offering = ServiceOffering.create( self.apiclient, - self.services["service_offering"] + self.services["service_offerings"] ) self.vm_1 = VirtualMachine.create( self.apiclient, - self.services["server"], + self.services["virtual_machine"], templateid=template.id, accountid=self.account.name, domainid=self.account.domainid, @@ -960,7 +900,7 @@ def setUp(self): self.cleanup = [] return - @attr(tags = ["advanced", "advancedns", "smoke"]) + @attr(tags = ["advanced", "advancedns", "smoke"], required_hardware="false") def test_delete_account(self): """Test for delete account""" @@ -993,7 +933,7 @@ def test_delete_account(self): account=self.account.name, domainid=self.account.domainid ) - except cloudstackAPIException: + except CloudstackAPIException: self.debug("Port Forwarding Rule is deleted") # ListPortForwardingRules should not @@ -1004,7 +944,7 @@ def test_delete_account(self): account=self.account.name, domainid=self.account.domainid ) - except cloudstackAPIException: + except CloudstackAPIException: self.debug("NATRule is deleted") #Retrieve router for the user account @@ -1012,14 +952,15 @@ def test_delete_account(self): routers = list_routers( self.apiclient, account=self.account.name, - domainid=self.account.domainid + domainid=self.account.domainid, + listall=True ) self.assertEqual( routers, None, "Check routers are properly deleted." ) - except cloudstackAPIException: + except CloudstackAPIException: self.debug("Router is deleted") except Exception as e: diff --git a/test/integration/smoke/test_network_acl.py b/test/integration/smoke/test_network_acl.py index 3363e460dd..015ebabba9 100644 --- a/test/integration/smoke/test_network_acl.py +++ b/test/integration/smoke/test_network_acl.py @@ -17,77 +17,27 @@ """ Tests for Network ACLs in VPC """ #Import Local Modules +from marvin.codes import FAILED from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * +from marvin.lib.utils import * +from marvin.lib.base import * +from marvin.lib.common import * from nose.plugins.attrib import attr -class Services: - def __init__(self): - self.services = { - "account": { - "email": "test@test.com", - "firstname": "Test", - "lastname": "User", - "username": "test", - "password": "password", - }, - "virtual_machine": { - "displayname": "Test VM", - "username": "root", - "password": "password", - "ssh_port": 22, - "hypervisor": 'XenServer', - "privateport": 22, - "publicport": 22, - "protocol": 'TCP', - }, - "ostype": 'CentOS 5.3 (64-bit)', - "service_offering": { - "name": "Tiny Instance", - "displaytext": "Tiny Instance", - "cpunumber": 1, - "cpuspeed": 100, - "memory": 256, - }, - "network_offering": { - "name": "Network offering for internal lb service", - "displaytext": "Network offering for internal lb service", - "guestiptype": "Isolated", - "traffictype": "Guest", - "supportedservices": "Vpn,Dhcp,Dns,Lb,UserData,SourceNat,StaticNat,PortForwarding,NetworkACL", - "serviceProviderList": { - "Dhcp": "VpcVirtualRouter", - "Dns": "VpcVirtualRouter", - "Vpn": "VpcVirtualRouter", - "UserData": "VpcVirtualRouter", - "Lb": "InternalLbVM", - "SourceNat": "VpcVirtualRouter", - "StaticNat": "VpcVirtualRouter", - "PortForwarding": "VpcVirtualRouter", - "NetworkACL": "VpcVirtualRouter", - }, - "serviceCapabilityList": { - "SourceNat": {"SupportedSourceNatTypes": "peraccount"}, - "Lb": {"lbSchemes": "internal", "SupportedLbIsolation": "dedicated"} - } - } - } - - class TestNetworkACL(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.apiclient = super(TestNetworkACL, cls).getClsTestClient().getApiClient() - cls.services = Services().services - cls.zone = get_zone(cls.apiclient, cls.services) + testClient = super(TestNetworkACL, cls).getClsTestClient() + cls.apiclient = testClient.getApiClient() + cls.services = testClient.getParsedTestDataConfig() + + cls.zone = get_zone(cls.apiclient, testClient.getZoneForTests()) cls.domain = get_domain(cls.apiclient) cls.service_offering = ServiceOffering.create( cls.apiclient, - cls.services["service_offering"] + cls.services["service_offerings"] ) cls.account = Account.create(cls.apiclient, services=cls.services["account"]) cls.template = get_template( @@ -95,13 +45,18 @@ def setUpClass(cls): cls.zone.id, cls.services["ostype"] ) + + if cls.template == FAILED: + assert False, "get_template() failed to return template with description %s" % cls.services["ostype"] + cls.debug("Successfully created account: %s, id: \ %s" % (cls.account.name,\ cls.account.id)) cls.cleanup = [cls.account] - @attr(tags=["advanced"]) + @attr(tags=["advanced"], required_hardware="true") def test_network_acl(self): + #TODO: SIMENH: add actual verification Logic for rules. """Test network ACL lists and items in VPC""" # 0) Get the default network offering for VPC diff --git a/test/integration/smoke/test_nic.py b/test/integration/smoke/test_nic.py index ac95685f37..dd6de96233 100644 --- a/test/integration/smoke/test_nic.py +++ b/test/integration/smoke/test_nic.py @@ -16,125 +16,23 @@ # under the License. """ NIC tests for VM """ import marvin +from marvin.codes import FAILED from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * from marvin.sshClient import SshClient -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * +from marvin.lib.utils import * +from marvin.lib.base import * +from marvin.lib.common import * from nose.plugins.attrib import attr import signal import sys import time -class Services: - def __init__(self): - self.services = { - "disk_offering":{ - "displaytext": "Small", - "name": "Small", - "disksize": 1 - }, - "account": { - "email": "test@test.com", - "firstname": "Test", - "lastname": "User", - "username": "test", - # Random characters are appended in create account to - # ensure unique username generated each time - "password": "password", - }, - # Create a small virtual machine instance with disk offering - "small": { - "displayname": "testserver", - "username": "root", # VM creds for SSH - "password": "password", - "ssh_port": 22, - "hypervisor": 'XenServer', - "privateport": 22, - "publicport": 22, - "protocol": 'TCP', - }, - "service_offerings": { - "tiny": { - "name": "Tiny Instance", - "displaytext": "Tiny Instance", - "cpunumber": 1, - "cpuspeed": 100, # in MHz - "memory": 128, # In MBs - }, - }, - "network_offering": { - "name": 'Test Network offering', - "displaytext": 'Test Network offering', - "guestiptype": 'Isolated', - "supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding', - "traffictype": 'GUEST', - "availability": 'Optional', - "serviceProviderList" : { - "Dhcp": 'VirtualRouter', - "Dns": 'VirtualRouter', - "SourceNat": 'VirtualRouter', - "PortForwarding": 'VirtualRouter', - }, - }, - "network_offering_shared": { - "name": 'Test Network offering shared', - "displaytext": 'Test Network offering Shared', - "guestiptype": 'Shared', - "supportedservices": 'Dhcp,Dns,UserData', - "traffictype": 'GUEST', - "specifyVlan" : "True", - "specifyIpRanges" : "True", - "serviceProviderList" : { - "Dhcp": 'VirtualRouter', - "Dns": 'VirtualRouter', - "UserData": 'VirtualRouter', - }, - }, - "network": { - "name": "Test Network", - "displaytext": "Test Network", - "acltype": "Account", - }, - "network2": { - "name": "Test Network Shared", - "displaytext": "Test Network Shared", - "vlan" :1201, - "gateway" :"172.16.15.1", - "netmask" :"255.255.255.0", - "startip" :"172.16.15.21", - "endip" :"172.16.15.41", - "acltype": "Account", - }, - # ISO settings for Attach/Detach ISO tests - "iso": { - "displaytext": "Test ISO", - "name": "testISO", - "url": "http://people.apache.org/~tsp/dummy.iso", - # Source URL where ISO is located - "ostype": 'CentOS 5.3 (64-bit)', - "mode": 'HTTP_DOWNLOAD', # Downloading existing ISO - }, - "template": { - "displaytext": "Cent OS Template", - "name": "Cent OS Template", - "passwordenabled": True, - }, - "sleep": 60, - "timeout": 10, - #Migrate VM to hostid - "ostype": 'CentOS 5.3 (64-bit)', - # CentOS 5.3 (64-bit) - } - class TestNic(cloudstackTestCase): def setUp(self): self.cleanup = [] - self.cleaning_up = 0 - def signal_handler(signal, frame): self.tearDown() sys.exit(0) @@ -145,16 +43,13 @@ def signal_handler(signal, frame): try: self.apiclient = self.testClient.getApiClient() self.dbclient = self.testClient.getDbConnection() - self.services = Services().services + self.services = self.testClient.getParsedTestDataConfig() # Get Zone, Domain and templates - domain = get_domain(self.apiclient, self.services) - zone = get_zone(self.apiclient, self.services) + domain = get_domain(self.apiclient) + zone = get_zone(self.apiclient, self.testClient.getZoneForTests()) self.services['mode'] = zone.networktype - if zone.networktype != 'Advanced': - self.skipTest("Cannot run this test with a basic zone, please use advanced!") - #if local storage is enabled, alter the offerings to use localstorage #this step is needed for devcloud if zone.localstorageenabled == True: @@ -169,7 +64,7 @@ def signal_handler(signal, frame): self.services["small"]["zoneid"] = zone.id self.services["small"]["template"] = template.id - self.services["iso"]["zoneid"] = zone.id + self.services["iso1"]["zoneid"] = zone.id self.services["network"]["zoneid"] = zone.id # Create Account, VMs, NAT Rules etc @@ -224,8 +119,9 @@ def signal_handler(signal, frame): except Exception as ex: self.debug("Exception during NIC test SETUP!: " + str(ex)) - @attr(tags = ["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"]) + @attr(tags = ["devcloud", "smoke", "advanced", "advancedns"], required_hardware="true") def test_01_nic(self): + #TODO: SIMENH: add validation """Test to add and update added nic to a virtual machine""" try: @@ -364,14 +260,6 @@ def test_01_nic(self): self.assertEqual(True, False, "Exception during NIC test!: " + str(ex)) def tearDown(self): - if self.services['mode'] != 'Advanced': - self.debug("Cannot run this test with a basic zone, please use advanced!") - return - - if self.cleaning_up == 1: - return - - self.cleaning_up = 1 try: for obj in self.cleanup: try: @@ -379,8 +267,6 @@ def tearDown(self): time.sleep(10) except Exception as ex: self.debug("Error deleting: " + str(obj) + ", exception: " + str(ex)) - except Exception as e: self.debug("Warning! Exception in tearDown: %s" % e) - self.cleaning_up = 0 diff --git a/test/integration/smoke/test_non_contigiousvlan.py b/test/integration/smoke/test_non_contigiousvlan.py index f1736ae447..e444618068 100644 --- a/test/integration/smoke/test_non_contigiousvlan.py +++ b/test/integration/smoke/test_non_contigiousvlan.py @@ -15,33 +15,30 @@ # specific language governing permissions and limitations # under the License. -from marvin import cloudstackTestCase -from marvin.cloudstackAPI import * +#from marvin.cloudstackAPI import * from marvin.cloudstackTestCase import cloudstackTestCase -from marvin.integration.lib.base import Account -from marvin.integration.lib.base import PhysicalNetwork +from marvin.lib.base import PhysicalNetwork +from marvin.lib.common import setNonContiguousVlanIds, get_zone from nose.plugins.attrib import attr -class Services(): - def __init__(self): - self.services = { - "vlan": { - "part": ["4090-4091", "4092-4095"], - "full": "4090-4095", - } - } - -@attr(tags = ["simulator", "advanced"]) class TestUpdatePhysicalNetwork(cloudstackTestCase): """ Test to extend physical network vlan range """ def setUp(self): - self.vlan = Services().services["vlan"] self.apiClient = self.testClient.getApiClient() + self.zone = get_zone(self.apiClient, self.testClient.getZoneForTests()) + self.physicalnetwork, self.vlan = setNonContiguousVlanIds(self.apiClient, self.zone.id) + + self.physicalnetworkid = self.physicalnetwork.id + self.existing_vlan = self.physicalnetwork.vlan + if self.vlan is None: + raise Exception("Failed to set non contiguous vlan ids to test. Free some ids from \ + from existing physical networks at ends") + @attr(tags = ["advanced"], required_hardware="false") def test_extendPhysicalNetworkVlan(self): """ Test to update a physical network and extend its vlan @@ -53,13 +50,13 @@ def test_extendPhysicalNetworkVlan(self): self.network = phy_networks[0] self.networkid = phy_networks[0].id self.existing_vlan = phy_networks[0].vlan - vlan1 = self.existing_vlan+","+self.vlan["part"][0] + vlan1 = self.existing_vlan+","+self.vlan["partial_range"][0] updatePhysicalNetworkResponse = self.network.update(self.apiClient, id = self.networkid, vlan = vlan1) self.assert_(updatePhysicalNetworkResponse is not None, msg="couldn't extend the physical network with vlan %s"%vlan1) self.assert_(isinstance(self.network, PhysicalNetwork)) - vlan2 = vlan1+","+self.vlan["part"][1] + vlan2 = vlan1+","+self.vlan["partial_range"][1] updatePhysicalNetworkResponse2 = self.network.update(self.apiClient, id = self.networkid, vlan = vlan2) self.assert_(updatePhysicalNetworkResponse2 is not None, msg="couldn't extend the physical network with vlan %s"%vlan2) @@ -68,7 +65,7 @@ def test_extendPhysicalNetworkVlan(self): vlanranges= updatePhysicalNetworkResponse2.vlan self.assert_(vlanranges is not None, "No VLAN ranges found on the deployment") - self.assert_(vlanranges.find(self.vlan["full"]) > 0, "vlan ranges are not extended") + self.assert_(str(vlanranges) == vlan2, "vlan ranges are not extended") def tearDown(self): @@ -82,6 +79,6 @@ def tearDown(self): self.network = phy_networks[0] self.networkid = phy_networks[0].id updateResponse = self.network.update(self.apiClient, id = self.networkid, vlan=self.existing_vlan) - self.assert_(updateResponse.vlan.find(self.vlan["full"]) < 0, + self.assert_(updateResponse.vlan.find(self.vlan["full_range"]) < 0, "VLAN was not removed successfully") diff --git a/test/integration/smoke/test_over_provisioning.py b/test/integration/smoke/test_over_provisioning.py index 28f32b7af9..43d558e671 100644 --- a/test/integration/smoke/test_over_provisioning.py +++ b/test/integration/smoke/test_over_provisioning.py @@ -19,9 +19,9 @@ #Import Local Modules from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * +from marvin.lib.utils import * +from marvin.lib.base import * +from marvin.lib.common import * from nose.plugins.attrib import attr #Import System modules @@ -32,7 +32,7 @@ class TestUpdateOverProvision(cloudstackTestCase): def setUp(self): self.apiClient = self.testClient.getApiClient() - @attr(tags=["simulator", "devcloud", "basic", "advanced"]) + @attr(tags=["devcloud", "basic", "advanced"], required_hardware="false") def test_UpdateStorageOverProvisioningFactor(self): """ test update configuration setting at storage scope @@ -67,7 +67,11 @@ def test_UpdateStorageOverProvisioningFactor(self): self.poolId = pool.id """ list overprovisioning factor for storage pool """ - factorOld = float(pool.overprovisionfactor) + failed = 0 + if pool.overprovisionfactor is None: + failed = 1 + self.assertNotEqual(failed,1,"pool.overprovisionfactor is none") + factorOld = float(str(pool.overprovisionfactor)) factorNew = str(factorOld + 1.0) """ update setting for the pool""" @@ -85,7 +89,11 @@ def test_UpdateStorageOverProvisioningFactor(self): id = self.poolId ) pool = storage_pools[0] - factorNew = float(pool.overprovisionfactor) + failed = 0 + if pool.overprovisionfactor is None: + failed = 1 + self.assertNotEqual(failed,1,"pool.overprovisionfactor is none") + factorNew = float(str(pool.overprovisionfactor)) self.assertNotEqual(int(factorNew), int(factorOld)," Check if overprovision factor of storage pool has changed") self.assertEqual(int(factorNew), int(factorOld + 1.0)," Check if overprovision factor of storage pool has increased by 1") @@ -100,8 +108,11 @@ def tearDown(self): pool = storage_pools[0] updateConfigurationCmd = updateConfiguration.updateConfigurationCmd() updateConfigurationCmd.name = "storage.overprovisioning.factor" - factorOld = float(pool.overprovisionfactor) + factorOld = 0 + if pool.overprovisionfactor is not None: + factorOld = float(str(pool.overprovisionfactor)) factorNew = str(factorOld - 1.0) - updateConfigurationCmd.value = factorNew - updateConfigurationCmd.storageid = pool.id - updateConfigurationResponse = self.apiClient.updateConfiguration(updateConfigurationCmd) + if factorNew > 0: + updateConfigurationCmd.value = factorNew + updateConfigurationCmd.storageid = pool.id + updateConfigurationResponse = self.apiClient.updateConfiguration(updateConfigurationCmd) diff --git a/test/integration/smoke/test_portable_publicip.py b/test/integration/smoke/test_portable_publicip.py index 0faed7163c..be37773484 100644 --- a/test/integration/smoke/test_portable_publicip.py +++ b/test/integration/smoke/test_portable_publicip.py @@ -18,73 +18,11 @@ from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * +from marvin.lib.utils import * +from marvin.lib.base import * +from marvin.lib.common import * from nose.plugins.attrib import attr -class Services: - """Test Data - """ - - def __init__(self): - self.services = { - "domain": { - "name": "Domain", - }, - "account": { - "email": "test@test.com", - "firstname": "Test", - "lastname": "User", - "username": "test", - # Random characters are appended for unique - # username - "password": "password", - }, - "service_offering": { - "name": "Tiny Instance", - "displaytext": "Tiny Instance", - "cpunumber": 1, - "cpuspeed": 100, - # in MHz - "memory": 128, - # In MBs - }, - "network_offering": { - "name": 'Test Network offering', - "displaytext": 'Test Network offering', - "guestiptype": 'Isolated', - "supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding', - "traffictype": 'GUEST', - "availability": 'Optional', - "serviceProviderList" : { - "Dhcp": 'VirtualRouter', - "Dns": 'VirtualRouter', - "SourceNat": 'VirtualRouter', - "PortForwarding": 'VirtualRouter', - }, - }, - "network": { - "name": "Test Network", - "displaytext": "Test Network", - }, - "ostype": 'CentOS 5.3 (64-bit)', - "gateway" : "172.1.1.1", - "netmask" : "255.255.255.0", - "startip" : "172.1.1.10", - "endip" : "172.1.1.20", - "regionid" : "1", - "vlan" :"10", - "isportable" : "true", - "virtual_machine" : { - "affinity": { - "name": "webvms", - "type": "host anti-affinity", - }, - "hypervisor" : "XenServer", - } - } - class TestPortablePublicIPRange(cloudstackTestCase): """ @@ -95,15 +33,17 @@ class TestPortablePublicIPRange(cloudstackTestCase): """ @classmethod def setUpClass(cls): - cls.api_client = super(TestPortablePublicIPRange, cls).getClsTestClient().getApiClient() - cls.services = Services().services + testClient = super(TestPortablePublicIPRange, cls).getClsTestClient() + cls.apiclient = testClient.getApiClient() + cls.services = testClient.getParsedTestDataConfig() + # Get Zone, Domain - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.apiclient) + cls.zone = get_zone(cls.apiclient, cls.testClient.getZoneForTests()) # Create Account cls.account = Account.create( - cls.api_client, + cls.apiclient, cls.services["account"], domainid=cls.domain.id ) @@ -116,7 +56,7 @@ def setUpClass(cls): def tearDownClass(cls): try: # Cleanup resources used - cleanup_resources(cls.api_client, cls._cleanup) + cleanup_resources(cls.apiclient, cls._cleanup) except Exception as e: raise Exception("Warning: Exception during cleanup : %s" % e) return @@ -135,13 +75,13 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags = ["simulator", "basic", "advanced", "portablepublicip"]) + @attr(tags = ["basic", "advanced", "portablepublicip"], required_hardware="false") def test_createPortablePublicIPRange(self): """ Test to create a portable public ip range """ self.debug("attempting to create a portable Public IP range") self.portable_ip_range = PortablePublicIpRange.create( - self.api_client, + self.apiclient, self.services ) self.debug("attempting to verify portable Public IP range is created") @@ -161,29 +101,31 @@ class TestPortablePublicIPAcquire(cloudstackTestCase): """ @classmethod def setUpClass(cls): - cls.api_client = super(TestPortablePublicIPAcquire, cls).getClsTestClient().getApiClient() - cls.services = Services().services + testClient = super(TestPortablePublicIPAcquire, cls).getClsTestClient() + cls.apiclient = testClient.getApiClient() + cls.services = testClient.getParsedTestDataConfig() + # Get Zone, Domain - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.apiclient) + cls.zone = get_zone(cls.apiclient, cls.testClient.getZoneForTests()) # Create Account cls.account = Account.create( - cls.api_client, + cls.apiclient, cls.services["account"], domainid=cls.domain.id ) cls.services["network"]["zoneid"] = cls.zone.id cls.network_offering = NetworkOffering.create( - cls.api_client, + cls.apiclient, cls.services["network_offering"], ) # Enable Network offering - cls.network_offering.update(cls.api_client, state='Enabled') + cls.network_offering.update(cls.apiclient, state='Enabled') cls.services["network"]["networkoffering"] = cls.network_offering.id cls.account_network = Network.create( - cls.api_client, + cls.apiclient, cls.services["network"], cls.account.name, cls.account.domainid @@ -200,7 +142,7 @@ def setUpClass(cls): def tearDownClass(cls): try: # Cleanup resources used - cleanup_resources(cls.api_client, cls._cleanup) + cleanup_resources(cls.apiclient, cls._cleanup) except Exception as e: raise Exception("Warning: Exception during cleanup : %s" % e) return @@ -219,19 +161,19 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags = ["simulator", "advanced", "portablepublicip"]) + @attr(tags = ["advanced", "portablepublicip"], required_hardware="false") def test_createPortablePublicIPAcquire(self): """ Test to acquire a provisioned public ip range """ self.debug("attempting to create a portable Public IP range") self.portable_ip_range = PortablePublicIpRange.create( - self.api_client, + self.apiclient, self.services ) - ip_address = PublicIPAddress.create(self.api_client, self.account.name, + ip_address = PublicIPAddress.create(self.apiclient, self.account.name, self.zone.id, self.account.domainid, isportable=True) - ip_address.delete(self.api_client) + ip_address.delete(self.apiclient) self.portable_ip_range.delete(self.apiclient) return diff --git a/test/integration/smoke/test_primary_storage.py b/test/integration/smoke/test_primary_storage.py index 5cf31b13d8..66aec59b8a 100644 --- a/test/integration/smoke/test_primary_storage.py +++ b/test/integration/smoke/test_primary_storage.py @@ -20,43 +20,24 @@ import marvin from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * +from marvin.lib.utils import * +from marvin.lib.base import * +from marvin.lib.common import * from nose.plugins.attrib import attr #Import System modules import time _multiprocess_shared_ = True -class Services: - """Test Primary storage Services - """ - - def __init__(self): - self.services = { - "nfs": - { - "url": "nfs://10.147.28.7/export/home/talluri/testprimary", - # Format: File_System_Type/Location/Path - "name": "Primary XEN" - }, - "iscsi": { - "url": "iscsi://192.168.100.21/iqn.2012-01.localdomain.clo-cstack-cos6:iser/1", - # Format : iscsi://IP Address/IQN number/LUN# - "name": "Primary iSCSI" - } - } - class TestPrimaryStorageServices(cloudstackTestCase): def setUp(self): self.apiclient = self.testClient.getApiClient() - self.services = Services().services + self.services = self.testClient.getParsedTestDataConfig() self.cleanup = [] # Get Zone and pod - self.zone = get_zone(self.apiclient, self.services) + self.zone = get_zone(self.apiclient, self.testClient.getZoneForTests()) self.pod = get_pod(self.apiclient, self.zone.id) return @@ -70,7 +51,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags = ["advanced", "advancedns", "smoke", "basic", "sg"]) + @attr(tags = ["advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="false") def test_01_primary_storage_nfs(self): """Test primary storage pools - XEN, KVM, VMWare """ @@ -163,7 +144,7 @@ def test_01_primary_storage_nfs(self): return - @attr(tags = ["advanced", "advancedns", "smoke", "basic", "sg"]) + @attr(tags = ["advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="true") def test_01_primary_storage_iscsi(self): """Test primary storage pools - XEN, KVM, VMWare """ @@ -218,7 +199,7 @@ def test_01_primary_storage_iscsi(self): self.assertEqual( storage.type, - 'NetworkFilesystem', + 'IscsiLUN', "Check storage pool type " ) diff --git a/test/integration/smoke/test_privategw_acl.py b/test/integration/smoke/test_privategw_acl.py index 9c37e5e7fc..cf0f8e338c 100644 --- a/test/integration/smoke/test_privategw_acl.py +++ b/test/integration/smoke/test_privategw_acl.py @@ -19,9 +19,9 @@ #Import Local Modules from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * +from marvin.lib.utils import * +from marvin.lib.base import * +from marvin.lib.common import * from nose.plugins.attrib import attr @@ -39,8 +39,9 @@ def setUp(self): self.privateGwId = None - @attr(tags=["advanced"]) + @attr(tags=["advanced"], required_hardware="false") def test_privategw_acl(self): + #TODO: SIMENH: add a new test to verification of ACL rules # 1) Create VPC self.createVPC() @@ -104,25 +105,7 @@ def createNetwork(self): self.assertIsNotNone(createNetworkResponse.id, "Network failed to create") self.networkId = createNetworkResponse.id - def deployVm(self): - deployVirtualMachineCmd = deployVirtualMachine.deployVirtualMachineCmd() - deployVirtualMachineCmd.networkids = self.networkId - deployVirtualMachineCmd.serviceofferingid = self.serviceOfferingId - deployVirtualMachineCmd.zoneid = self.zoneId - deployVirtualMachineCmd.templateid = self.templateId - deployVirtualMachineCmd.hypervisor = "XenServer" - deployVMResponse = self.apiClient.deployVirtualMachine(deployVirtualMachineCmd) - - def deployVm(self): - deployVirtualMachineCmd = deployVirtualMachine.deployVirtualMachineCmd() - deployVirtualMachineCmd.networkids = TestNetworkACL.networkId - deployVirtualMachineCmd.serviceofferingid = TestNetworkACL.serviceOfferingId - deployVirtualMachineCmd.zoneid = TestNetworkACL.zoneId - deployVirtualMachineCmd.templateid = TestNetworkACL.templateId - deployVirtualMachineCmd.hypervisor = "XenServer" - deployVMResponse = self.apiClient.deployVirtualMachine(deployVirtualMachineCmd) - TestNetworkACL.vmId = deployVMResponse.id - self.vmId = deployVMResponse.id + def createPvtGw(self): createPrivateGatewayCmd = createPrivateGateway.createPrivateGatewayCmd() @@ -145,7 +128,4 @@ def replaceacl(self): def tearDown(self): #destroy the vm - if self.vmId is not None: - destroyVirtualMachineCmd = destroyVirtualMachine.destroyVirtualMachineCmd() - destroyVirtualMachineCmd.id = self.vmId - destroyVirtualMachineResponse = self.apiClient.destroyVirtualMachine(destroyVirtualMachineCmd) + return diff --git a/test/integration/smoke/test_public_ip_range.py b/test/integration/smoke/test_public_ip_range.py index e1d78d99d1..e09f7b43b5 100644 --- a/test/integration/smoke/test_public_ip_range.py +++ b/test/integration/smoke/test_public_ip_range.py @@ -21,50 +21,26 @@ from nose.plugins.attrib import attr from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * +from marvin.lib.utils import * +from marvin.lib.base import * +from marvin.lib.common import * import datetime -class Services: - """Test Dedicating Public IP addresses - """ - - def __init__(self): - self.services = { - "domain": { - "name": "Domain", - }, - "account": { - "email": "test@test.com", - "firstname": "Test", - "lastname": "User", - "username": "test", - "password": "password", - }, - "gateway": "10.102.197.1", - "netmask": "255.255.255.0", - "forvirtualnetwork": "true", - "startip": "10.102.197.70", - "endip": "10.102.197.73", - "zoneid": "1", - "podid": "", - "vlan": "4444", - } - class TestDedicatePublicIPRange(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestDedicatePublicIPRange, cls).getClsTestClient().getApiClient() - cls.services = Services().services + cls.testClient = super(TestDedicatePublicIPRange, cls).getClsTestClient() + cls.apiclient = cls.testClient.getApiClient() + cls.services = cls.testClient.getParsedTestDataConfig() # Get Zone, Domain - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - + cls.domain = get_domain(cls.apiclient) + cls.zone = get_zone(cls.apiclient, cls.testClient.getZoneForTests()) + cls.services["zoneid"] = cls.zone.id + cls.pod = get_pod(cls.apiclient, cls.zone.id) # Create Account cls.account = Account.create( - cls.api_client, + cls.apiclient, cls.services["account"], domainid=cls.domain.id ) @@ -77,7 +53,7 @@ def setUpClass(cls): def tearDownClass(cls): try: # Cleanup resources used - cleanup_resources(cls.api_client, cls._cleanup) + cleanup_resources(cls.apiclient, cls._cleanup) except Exception as e: raise Exception("Warning: Exception during cleanup : %s" % e) return @@ -96,7 +72,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags = ["simulator", "advanced", "publiciprange", "dedicate", "release"]) + @attr(tags = ["advanced", "publiciprange", "dedicate", "release"], required_hardware="false") def test_dedicatePublicIpRange(self): """Test public IP range dedication """ @@ -112,7 +88,7 @@ def test_dedicatePublicIpRange(self): self.debug("Creating Public IP range") self.public_ip_range = PublicIpRange.create( - self.api_client, + self.apiclient, self.services ) list_public_ip_range_response = PublicIpRange.list( diff --git a/test/integration/smoke/test_pvlan.py b/test/integration/smoke/test_pvlan.py index aeb47f953c..6e187b99dc 100644 --- a/test/integration/smoke/test_pvlan.py +++ b/test/integration/smoke/test_pvlan.py @@ -21,9 +21,9 @@ from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * from marvin.sshClient import SshClient -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * +from marvin.lib.utils import * +from marvin.lib.base import * +from marvin.lib.common import * from nose.plugins.attrib import attr import telnetlib @@ -38,10 +38,14 @@ class TestPVLAN(cloudstackTestCase): vlan = 1234 isolatedpvlan = 567 - def setUp(self): - self.apiClient = self.testClient.getApiClient() + @classmethod + def setUpClass(cls): + cls.testClient = super(TestPVLAN, cls).getClsTestClient() + cls.apiClient = cls.testClient.getApiClient() + cls.zone = get_zone(cls.apiClient, cls.testClient.getZoneForTests()) + cls.zoneId = cls.zone.id - @attr(tags = ["advanced"]) + @attr(tags = ["advanced"], required_hardware="false") def test_create_pvlan_network(self): self.debug("Test create pvlan network") createNetworkCmd = createNetwork.createNetworkCmd() @@ -76,12 +80,6 @@ def test_create_pvlan_network(self): createNetworkCmd.ip6cidr="fc00:1234::/64" createNetworkCmd.startipv6="fc00:1234::10" createNetworkCmd.endipv6="fc00:1234::20" - err = 0; - try: - createNetworkResponse = self.apiClient.createNetwork(createNetworkCmd) - except Exception as e: - err = 1; - self.debug("Try alloc with ipv6, got:%s" % e) - self.assertEqual(err, 1, "Shouldn't allow create PVLAN network with IPv6"); - - + err = 0 + with self.assertRaises(Exception): + self.apiClient.createNetwork(createNetworkCmd) diff --git a/test/integration/smoke/test_regions.py b/test/integration/smoke/test_regions.py index 5d12e74e8d..7b0dec3c6e 100644 --- a/test/integration/smoke/test_regions.py +++ b/test/integration/smoke/test_regions.py @@ -17,42 +17,33 @@ from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * +from marvin.lib.utils import * +from marvin.lib.base import * +from marvin.lib.common import * from nose.plugins.attrib import attr -class Services: - def __init__(self): - self.services = { - "region": { - "regionid": "2", - "regionname": "Region2", - "regionendpoint": "http://region2:8080/client" - } - } - - class TestRegions(cloudstackTestCase): """Test Regions - basic region creation """ @classmethod def setUpClass(cls): - cls.api_client = super(TestRegions, cls).getClsTestClient().getApiClient() - cls.services = Services().services - cls.domain = get_domain(cls.api_client, cls.services) + testClient = super(TestRegions, cls).getClsTestClient() + cls.apiclient = testClient.getApiClient() + cls.services = testClient.getParsedTestDataConfig() + + cls.domain = get_domain(cls.apiclient) cls.cleanup = [] - @attr(tags=["simulator", "basic", "advanced"]) + @attr(tags=["basic", "advanced"], required_hardware="false") def test_createRegion(self): """ Test for create region """ - region = Region.create(self.api_client, + region = Region.create(self.apiclient, self.services["region"] ) - list_region = Region.list(self.api_client, + list_region = Region.list(self.apiclient, id=self.services["region"]["regionid"] ) @@ -86,8 +77,8 @@ def test_createRegion(self): def tearDownClass(cls): try: #Clean up - cleanup_resources(cls.api_client, cls.cleanup) - list_region = Region.list(cls.api_client, id=cls.services["region"]["regionid"]) + cleanup_resources(cls.apiclient, cls.cleanup) + list_region = Region.list(cls.apiclient, id=cls.services["region"]["regionid"]) assert list_region is None, "Region deletion fails" except Exception as e: - raise Exception("Warning: Region cleanup/delete fails with : %s" % e) \ No newline at end of file + raise Exception("Warning: Region cleanup/delete fails with : %s" % e) diff --git a/test/integration/smoke/test_reset_vm_on_reboot.py b/test/integration/smoke/test_reset_vm_on_reboot.py index 4e52f0fa8d..668c77fa7d 100644 --- a/test/integration/smoke/test_reset_vm_on_reboot.py +++ b/test/integration/smoke/test_reset_vm_on_reboot.py @@ -18,106 +18,56 @@ """ #Import Local Modules import marvin +from marvin.codes import FAILED from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * +from marvin.lib.utils import * +from marvin.lib.base import * +from marvin.lib.common import * from nose.plugins.attrib import attr _multiprocess_shared_ = True -class Services: - """Test VM Life Cycle Services - """ - - def __init__(self): - self.services = { - - "account": { - "email": "test@test.com", - "firstname": "Test", - "lastname": "User", - "username": "test", - # Random characters are appended in create account to - # ensure unique username generated each time - "password": "password", - }, - "small": - # Create a small virtual machine instance with disk offering - { - "displayname": "testserver", - "username": "root", # VM creds for SSH - "password": "password", - "ssh_port": 22, - "hypervisor": 'XenServer', - "privateport": 22, - "publicport": 22, - "protocol": 'TCP', - }, - "service_offerings": - { - "small": - { - # Small service offering ID to for change VM - # service offering from medium to small - "name": "SmallInstance_volatile", - "displaytext": "SmallInstance_volatile", - "cpunumber": 1, - "cpuspeed": 100, - "memory": 256, - }, - }, - #Change this - "template": { - "displaytext": "xs", - "name": "xs", - "passwordenabled": False, - }, - "sleep": 60, - "timeout": 10, - #Migrate VM to hostid - "ostype": 'CentOS 5.3 (64-bit)', - # CentOS 5.3 (64-bit) - } - - class TestResetVmOnReboot(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestResetVmOnReboot, cls).getClsTestClient().getApiClient() - cls.services = Services().services + testClient = super(TestResetVmOnReboot, cls).getClsTestClient() + cls.apiclient = testClient.getApiClient() + cls.services = testClient.getParsedTestDataConfig() # Get Zone, Domain and templates - domain = get_domain(cls.api_client, cls.services) - zone = get_zone(cls.api_client, cls.services) + domain = get_domain(cls.apiclient) + zone = get_zone(cls.apiclient, testClient.getZoneForTests()) cls.services['mode'] = zone.networktype template = get_template( - cls.api_client, + cls.apiclient, zone.id, cls.services["ostype"] ) + if template == FAILED: + assert False, "get_template() failed to return template with description %s" % cls.services["ostype"] + # Set Zones and disk offerings ?? cls.services["small"]["zoneid"] = zone.id cls.services["small"]["template"] = template.id # Create account, service offerings, vm. cls.account = Account.create( - cls.api_client, + cls.apiclient, cls.services["account"], domainid=domain.id ) cls.small_offering = ServiceOffering.create( - cls.api_client, + cls.apiclient, cls.services["service_offerings"]["small"], isvolatile="true" ) #create a virtual machine cls.virtual_machine = VirtualMachine.create( - cls.api_client, + cls.apiclient, cls.services["small"], accountid=cls.account.name, domainid=cls.account.domainid, @@ -131,8 +81,8 @@ def setUpClass(cls): @classmethod def tearDownClass(cls): - cls.api_client = super(TestResetVmOnReboot, cls).getClsTestClient().getApiClient() - cleanup_resources(cls.api_client, cls._cleanup) + cls.apiclient = super(TestResetVmOnReboot, cls).getClsTestClient().getApiClient() + cleanup_resources(cls.apiclient, cls._cleanup) return def setUp(self): @@ -146,8 +96,9 @@ def tearDown(self): return @attr(hypervisor="xenserver") - @attr(tags=["advanced", "basic"]) + @attr(tags=["advanced", "basic"], required_hardware="false") def test_01_reset_vm_on_reboot(self): + #TODO: SIMENH: add new test to check volume contents """Test reset virtual machine on reboot """ # Validate the following diff --git a/test/integration/smoke/test_resource_detail.py b/test/integration/smoke/test_resource_detail.py index 00a7b5c417..7103c65261 100644 --- a/test/integration/smoke/test_resource_detail.py +++ b/test/integration/smoke/test_resource_detail.py @@ -21,113 +21,46 @@ from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * from marvin.sshClient import SshClient -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * +from marvin.lib.utils import * +from marvin.lib.base import * +from marvin.lib.common import * from nose.plugins.attrib import attr #Import System modules import time _multiprocess_shared_ = True -class Services: - """Test VM Life Cycle Services - """ - - def __init__(self): - self.services = { - - "account": { - "email": "test@test.com", - "firstname": "Test", - "lastname": "User", - "username": "test", - # Random characters are appended in create account to - # ensure unique username generated each time - "password": "password", - }, - "small": - # Create a small virtual machine instance with disk offering - { - "displayname": "testserver", - "username": "root", # VM creds for SSH - "password": "password", - "ssh_port": 22, - "hypervisor": 'XenServer', - "privateport": 22, - "publicport": 22, - "protocol": 'TCP', - }, - "disk_offering": { - "displaytext": "Small", - "name": "Small", - "storagetype": "shared", - "disksize": 1 - }, - "service_offerings": - { - "small": - { - # Small service offering ID to for change VM - # service offering from medium to small - "name": "SmallInstance", - "displaytext": "SmallInstance", - "cpunumber": 1, - "cpuspeed": 100, - "memory": 256, - }, - "big": - { - # Big service offering ID to for change VM - "name": "BigInstance", - "displaytext": "BigInstance", - "cpunumber": 1, - "cpuspeed": 100, - "memory": 512, - } - }, - #Change this - "template": { - "displaytext": "xs", - "name": "xs", - "passwordenabled": False, - }, - "sleep": 60, - "timeout": 10, - #Migrate VM to hostid - "ostype": 'CentOS 5.6 (64-bit)', - # CentOS 5.3 (64-bit) - } class TestResourceDetail(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestResourceDetail, cls).getClsTestClient().getApiClient() - cls.services = Services().services + testClient = super(TestResourceDetail, cls).getClsTestClient() + cls.apiclient = testClient.getApiClient() + cls.services = testClient.getParsedTestDataConfig() # Get Zone, Domain and templates - domain = get_domain(cls.api_client, cls.services) - zone = get_zone(cls.api_client, cls.services) + domain = get_domain(cls.apiclient) + zone = get_zone(cls.apiclient, testClient.getZoneForTests()) cls.services['mode'] = zone.networktype # Set Zones and disk offerings ?? # Create account, service offerings, vm. cls.account = Account.create( - cls.api_client, + cls.apiclient, cls.services["account"], domainid=domain.id ) cls.disk_offering = DiskOffering.create( - cls.api_client, + cls.apiclient, cls.services["disk_offering"] ) #create a volume cls.volume = Volume.create( - cls.api_client, + cls.apiclient, { "diskname" : "ndm"}, zoneid=zone.id, account=cls.account.name, @@ -142,8 +75,8 @@ def setUpClass(cls): @classmethod def tearDownClass(cls): - cls.api_client = super(TestResourceDetail, cls).getClsTestClient().getApiClient() - cleanup_resources(cls.api_client, cls._cleanup) + cls.apiclient = super(TestResourceDetail, cls).getClsTestClient().getApiClient() + cleanup_resources(cls.apiclient, cls._cleanup) return def setUp(self): @@ -156,7 +89,7 @@ def tearDown(self): cleanup_resources(self.apiclient, self.cleanup) return - @attr(tags = ["advanced", "xenserver"]) + @attr(tags = ["advanced", "xenserver"], required_hardware="false") def test_01_updatevolumedetail(self): """Test volume detail """ @@ -175,7 +108,7 @@ def test_01_updatevolumedetail(self): listResourceDetailCmd = listResourceDetails.listResourceDetailsCmd() listResourceDetailCmd.resourceid = self.volume.id listResourceDetailCmd.resourcetype = "Volume" - listResourceDetailResponse = self.api_client.listResourceDetails(listResourceDetailCmd) + listResourceDetailResponse = self.apiclient.listResourceDetails(listResourceDetailCmd) self.assertEqual(listResourceDetailResponse, None, "Check if the list API \ returns an empty response") diff --git a/test/integration/smoke/test_routers.py b/test/integration/smoke/test_routers.py index 7d324136e8..cb878a0fdc 100644 --- a/test/integration/smoke/test_routers.py +++ b/test/integration/smoke/test_routers.py @@ -5,9 +5,9 @@ # 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 @@ -18,88 +18,55 @@ """ #Import Local Modules import marvin +from marvin.codes import FAILED from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * from marvin.sshClient import SshClient -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * +from marvin.lib.utils import * +from marvin.lib.base import * +from marvin.lib.common import * from nose.plugins.attrib import attr #Import System modules import time _multiprocess_shared_ = True -class Services: - """Test router Services - """ - - def __init__(self): - self.services = { - "service_offering": { - "name": "Tiny Instance", - "displaytext": "Tiny Instance", - "cpunumber": 1, - "cpuspeed": 100, # in MHz - "memory": 128, # In MBs - }, - "virtual_machine": - { - "displayname": "Test VM", - "username": "root", - "password": "password", - "ssh_port": 22, - "hypervisor": 'XenServer', - "privateport": 22, - "publicport": 22, - "protocol": 'TCP', - }, - "account": { - "email": "test@test.com", - "firstname": "Test", - "lastname": "User", - "username": "testuser", - "password": "password", - }, - "ostype": "CentOS 5.3 (64-bit)", - "sleep": 60, - "timeout": 10, - } - class TestRouterServices(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super( - TestRouterServices, - cls - ).getClsTestClient().getApiClient() - cls.services = Services().services + testClient = super(TestRouterServices, cls).getClsTestClient() + cls.apiclient = testClient.getApiClient() + cls.services = testClient.getParsedTestDataConfig() + # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.apiclient) + cls.zone = get_zone(cls.apiclient, testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype template = get_template( - cls.api_client, + cls.apiclient, cls.zone.id, cls.services["ostype"] ) + if template == FAILED: + cls.fail("get_template() failed to return template with description %s" % cls.services["ostype"]) + cls.services["virtual_machine"]["zoneid"] = cls.zone.id #Create an account, network, VM and IP addresses cls.account = Account.create( - cls.api_client, + cls.apiclient, cls.services["account"], domainid=cls.domain.id ) cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] + cls.apiclient, + cls.services["service_offerings"] ) cls.vm_1 = VirtualMachine.create( - cls.api_client, + cls.apiclient, cls.services["virtual_machine"], templateid=template.id, accountid=cls.account.name, @@ -115,12 +82,12 @@ def setUpClass(cls): @classmethod def tearDownClass(cls): try: - cls.api_client = super( + cls.apiclient = super( TestRouterServices, cls ).getClsTestClient().getApiClient() #Clean up, terminate the created templates - cleanup_resources(cls.api_client, cls.cleanup) + cleanup_resources(cls.apiclient, cls.cleanup) except Exception as e: raise Exception("Warning: Exception during cleanup : %s" % e) @@ -128,9 +95,10 @@ def tearDownClass(cls): def setUp(self): self.apiclient = self.testClient.getApiClient() + self.hypervisor = self.testClient.getHypervisorInfo() return - @attr(tags = ["advanced", "basic", "sg", "smoke"]) + @attr(tags = ["advanced", "basic", "sg", "smoke"], required_hardware="true") def test_01_router_internal_basic(self): """Test router internal basic zone """ @@ -143,13 +111,14 @@ def test_01_router_internal_basic(self): if self.zone.networktype == "Basic": list_router_response = list_routers( self.apiclient, - listall="true" + listall=True ) else: list_router_response = list_routers( self.apiclient, account=self.account.name, - domainid=self.account.domainid + domainid=self.account.domainid, + listall=True ) self.assertEqual( isinstance(list_router_response, list), @@ -180,7 +149,7 @@ def test_01_router_internal_basic(self): "Check list router response for router state" ) - if self.apiclient.hypervisor.lower() == 'vmware': + if self.hypervisor.lower() == 'vmware': result = get_process_status( self.apiclient.connection.mgtSvr, 22, @@ -188,7 +157,7 @@ def test_01_router_internal_basic(self): self.apiclient.connection.passwd, router.linklocalip, "service dnsmasq status", - hypervisor=self.apiclient.hypervisor + hypervisor=self.hypervisor ) else: try: @@ -215,10 +184,7 @@ def test_01_router_internal_basic(self): return - - - - @attr(tags = ["advanced", "smoke"]) + @attr(tags = ["advanced", "smoke"], required_hardware="true") def test_02_router_internal_adv(self): """Test router internal advanced zone """ @@ -231,14 +197,14 @@ def test_02_router_internal_adv(self): list_router_response = list_routers( self.apiclient, account=self.account.name, - domainid=self.account.domainid + domainid=self.account.domainid, + listall=True ) self.assertEqual( isinstance(list_router_response, list), True, "Check list response returns a valid list" ) - router = list_router_response[0] hosts = list_hosts( @@ -262,7 +228,7 @@ def test_02_router_internal_adv(self): "Check list router response for router state" ) - if self.apiclient.hypervisor.lower() == 'vmware': + if self.hypervisor.lower() == 'vmware': result = get_process_status( self.apiclient.connection.mgtSvr, 22, @@ -270,7 +236,7 @@ def test_02_router_internal_adv(self): self.apiclient.connection.passwd, router.linklocalip, "service dnsmasq status", - hypervisor=self.apiclient.hypervisor + hypervisor=self.hypervisor ) else: try: @@ -287,14 +253,13 @@ def test_02_router_internal_adv(self): self.skipTest("Marvin configuration has no host credentials to check router services") res = str(result) self.debug("Dnsmasq process status: %s" % res) - self.assertEqual( res.count("running"), 1, "Check dnsmasq service is running or not" ) - if self.apiclient.hypervisor.lower() == 'vmware': + if self.hypervisor.lower() == 'vmware': result = get_process_status( self.apiclient.connection.mgtSvr, 22, @@ -302,7 +267,7 @@ def test_02_router_internal_adv(self): self.apiclient.connection.passwd, router.linklocalip, "service haproxy status", - hypervisor=self.apiclient.hypervisor + hypervisor=self.hypervisor ) else: try: @@ -326,7 +291,7 @@ def test_02_router_internal_adv(self): self.debug("Haproxy process status: %s" % res) return - @attr(tags = ["advanced", "advancedns", "smoke"]) + @attr(tags = ["advanced", "advancedns", "smoke"], required_hardware="false") def test_03_restart_network_cleanup(self): """Test restart network """ @@ -340,7 +305,8 @@ def test_03_restart_network_cleanup(self): list_router_response = list_routers( self.apiclient, account=self.account.name, - domainid=self.account.domainid + domainid=self.account.domainid, + listall=True ) self.assertEqual( isinstance(list_router_response, list), @@ -388,7 +354,8 @@ def test_03_restart_network_cleanup(self): list_router_response = list_routers( self.apiclient, account=self.account.name, - domainid=self.account.domainid + domainid=self.account.domainid, + listall=True ) self.assertEqual( isinstance(list_router_response, list), @@ -404,7 +371,7 @@ def test_03_restart_network_cleanup(self): ) return - @attr(tags = ["advanced", "advancedns", "smoke"]) + @attr(tags = ["advanced", "advancedns", "smoke"], required_hardware="true") def test_04_restart_network_wo_cleanup(self): """Test restart network without cleanup """ @@ -450,7 +417,8 @@ def test_04_restart_network_wo_cleanup(self): list_router_response = list_routers( self.apiclient, account=self.account.name, - domainid=self.account.domainid + domainid=self.account.domainid, + listall=True ) self.assertEqual( isinstance(list_router_response, list), @@ -473,7 +441,7 @@ def test_04_restart_network_wo_cleanup(self): ) host = hosts[0] - if self.apiclient.hypervisor.lower() == 'vmware': + if self.hypervisor.lower() == 'vmware': res = get_process_status( self.apiclient.connection.mgtSvr, 22, @@ -481,7 +449,7 @@ def test_04_restart_network_wo_cleanup(self): self.apiclient.connection.passwd, router.linklocalip, "uptime", - hypervisor=self.apiclient.hypervisor + hypervisor=self.hypervisor ) else: try: @@ -496,7 +464,6 @@ def test_04_restart_network_wo_cleanup(self): ) except KeyError: self.skipTest("Marvin configuration has no host credentials to check router services") - # res = 12:37:14 up 1 min, 0 users, load average: 0.61, 0.22, 0.08 # Split result to check the uptime result = res[0].split() @@ -520,7 +487,7 @@ def test_04_restart_network_wo_cleanup(self): ) return - @attr(tags = ["advanced", "advancedns", "smoke"]) + @attr(tags = ["advanced", "advancedns", "smoke"], required_hardware="false") def test_05_router_basic(self): """Test router basic setup """ @@ -533,7 +500,8 @@ def test_05_router_basic(self): list_router_response = list_routers( self.apiclient, account=self.account.name, - domainid=self.account.domainid + domainid=self.account.domainid, + listall=True ) self.assertEqual( isinstance(list_router_response, list), @@ -586,7 +554,7 @@ def test_05_router_basic(self): ) return - @attr(tags = ["advanced", "advancedns", "smoke"]) + @attr(tags = ["advanced", "advancedns", "smoke"], required_hardware="false") def test_06_router_advanced(self): """Test router advanced setup """ @@ -599,7 +567,8 @@ def test_06_router_advanced(self): list_router_response = list_routers( self.apiclient, account=self.account.name, - domainid=self.account.domainid + domainid=self.account.domainid, + listall=True ) self.assertEqual( isinstance(list_router_response, list), @@ -669,7 +638,7 @@ def test_06_router_advanced(self): ) return - @attr(tags = ["advanced", "advancedns", "smoke"]) + @attr(tags = ["advanced", "advancedns", "smoke"], required_hardware="false") def test_07_stop_router(self): """Test stop router """ @@ -680,7 +649,8 @@ def test_07_stop_router(self): list_router_response = list_routers( self.apiclient, account=self.account.name, - domainid=self.account.domainid + domainid=self.account.domainid, + listall=True ) self.assertEqual( isinstance(list_router_response, list), @@ -688,7 +658,6 @@ def test_07_stop_router(self): "Check list response returns a valid list" ) router = list_router_response[0] - self.debug("Stopping the router with ID: %s" % router.id) #Stop the router cmd = stopRouter.stopRouterCmd() @@ -698,7 +667,8 @@ def test_07_stop_router(self): #List routers to check state of router router_response = list_routers( self.apiclient, - id=router.id + id=router.id, + listall=True ) self.assertEqual( isinstance(router_response, list), @@ -713,7 +683,7 @@ def test_07_stop_router(self): ) return - @attr(tags = ["advanced", "advancedns", "smoke"]) + @attr(tags = ["advanced", "advancedns", "smoke"], required_hardware="false") def test_08_start_router(self): """Test start router """ @@ -724,7 +694,8 @@ def test_08_start_router(self): list_router_response = list_routers( self.apiclient, account=self.account.name, - domainid=self.account.domainid + domainid=self.account.domainid, + listall=True ) self.assertEqual( isinstance(list_router_response, list), @@ -743,7 +714,8 @@ def test_08_start_router(self): #List routers to check state of router router_response = list_routers( self.apiclient, - id=router.id + id=router.id, + listall=True ) self.assertEqual( isinstance(router_response, list), @@ -758,7 +730,14 @@ def test_08_start_router(self): ) return - @attr(tags = ["advanced", "advancedns", "smoke"]) + def verifyRouterResponse(self,router_response,ip): + if (router_response) and (isinstance(router_response, list)) and \ + (router_response[0].state == "Running") and \ + (router_response[0].publicip == ip): + return True + return False + + @attr(tags = ["advanced", "advancedns", "smoke"], required_hardware="false") def test_09_reboot_router(self): """Test reboot router """ @@ -769,7 +748,8 @@ def test_09_reboot_router(self): list_router_response = list_routers( self.apiclient, account=self.account.name, - domainid=self.account.domainid + domainid=self.account.domainid, + listall=True ) self.assertEqual( isinstance(list_router_response, list), @@ -781,32 +761,23 @@ def test_09_reboot_router(self): public_ip = router.publicip self.debug("Rebooting the router with ID: %s" % router.id) - #Reboot the router cmd = rebootRouter.rebootRouterCmd() cmd.id = router.id self.apiclient.rebootRouter(cmd) #List routers to check state of router - router_response = list_routers( + retries_cnt = 6 + while retries_cnt >= 0: + router_response = list_routers( self.apiclient, - id=router.id + id=router.id, + listall=True ) - self.assertEqual( - isinstance(router_response, list), - True, - "Check list response returns a valid list" - ) - #List router should have router in running state and same public IP - self.assertEqual( - router_response[0].state, - 'Running', - "Check list router response for router state" - ) - - self.assertEqual( - router_response[0].publicip, - public_ip, - "Check list router response for router public IP" - ) + if self.verifyRouterResponse(router_response,public_ip): + self.debug("Router is running successfully after reboot") + return + time.sleep(10) + retries_cnt = retries_cnt - 1 + self.fail("Router response after reboot is either is invalid or in stopped state") return diff --git a/test/integration/smoke/test_scale_vm.py b/test/integration/smoke/test_scale_vm.py index 1d1726dc90..b5c89be453 100644 --- a/test/integration/smoke/test_scale_vm.py +++ b/test/integration/smoke/test_scale_vm.py @@ -18,119 +18,63 @@ """ #Import Local Modules import marvin +from marvin.codes import FAILED from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * +from marvin.lib.utils import * +from marvin.lib.base import * +from marvin.lib.common import * from nose.plugins.attrib import attr _multiprocess_shared_ = True -class Services: - """Test VM Life Cycle Services - """ - - def __init__(self): - self.services = { - - "account": { - "email": "test@test.com", - "firstname": "Test", - "lastname": "User", - "username": "test", - # Random characters are appended in create account to - # ensure unique username generated each time - "password": "password", - }, - "small": - # Create a small virtual machine instance with disk offering - { - "displayname": "testserver", - "username": "root", # VM creds for SSH - "password": "password", - "ssh_port": 22, - "hypervisor": 'XenServer', - "privateport": 22, - "publicport": 22, - "protocol": 'TCP', - }, - "service_offerings": - { - "small": - { - # Small service offering ID to for change VM - # service offering from medium to small - "name": "SmallInstance", - "displaytext": "SmallInstance", - "cpunumber": 1, - "cpuspeed": 100, - "memory": 256, - }, - "big": - { - # Big service offering ID to for change VM - "name": "BigInstance", - "displaytext": "BigInstance", - "cpunumber": 1, - "cpuspeed": 100, - "memory": 512, - } - }, - #Change this - "template": { - "displaytext": "xs", - "name": "xs", - "passwordenabled": False, - }, - "sleep": 60, - "timeout": 10, - #Migrate VM to hostid - "ostype": 'CentOS 5.3 (64-bit)', - # CentOS 5.3 (64-bit) - } - - class TestScaleVm(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestScaleVm, cls).getClsTestClient().getApiClient() - cls.services = Services().services + testClient = super(TestScaleVm, cls).getClsTestClient() + cls.apiclient = testClient.getApiClient() + cls.services = testClient.getParsedTestDataConfig() + cls.hypervisor = cls.testClient.getHypervisorInfo() + if cls.hypervisor.lower() == 'kvm': + raise unittest.SkipTest("ScaleVM is not supported on KVM. Hence, skipping the test") # Get Zone, Domain and templates - domain = get_domain(cls.api_client, cls.services) - zone = get_zone(cls.api_client, cls.services) + domain = get_domain(cls.apiclient) + zone = get_zone(cls.apiclient, testClient.getZoneForTests()) cls.services['mode'] = zone.networktype template = get_template( - cls.api_client, + cls.apiclient, zone.id, cls.services["ostype"] ) + if template == FAILED: + assert False, "get_template() failed to return template with description %s" % cls.services["ostype"] + # Set Zones and disk offerings ?? cls.services["small"]["zoneid"] = zone.id cls.services["small"]["template"] = template.id # Create account, service offerings, vm. cls.account = Account.create( - cls.api_client, + cls.apiclient, cls.services["account"], domainid=domain.id ) cls.small_offering = ServiceOffering.create( - cls.api_client, + cls.apiclient, cls.services["service_offerings"]["small"] ) cls.big_offering = ServiceOffering.create( - cls.api_client, + cls.apiclient, cls.services["service_offerings"]["big"] ) #create a virtual machine cls.virtual_machine = VirtualMachine.create( - cls.api_client, + cls.apiclient, cls.services["small"], accountid=cls.account.name, domainid=cls.account.domainid, @@ -144,8 +88,8 @@ def setUpClass(cls): @classmethod def tearDownClass(cls): - cls.api_client = super(TestScaleVm, cls).getClsTestClient().getApiClient() - cleanup_resources(cls.api_client, cls._cleanup) + cls.apiclient = super(TestScaleVm, cls).getClsTestClient().getApiClient() + cleanup_resources(cls.apiclient, cls._cleanup) return def setUp(self): @@ -159,7 +103,7 @@ def tearDown(self): return @attr(hypervisor="xenserver") - @attr(tags=["advanced", "basic"]) + @attr(tags=["advanced", "basic"], required_hardware="true") def test_01_scale_vm(self): """Test scale virtual machine """ diff --git a/test/integration/smoke/test_secondary_storage.py b/test/integration/smoke/test_secondary_storage.py index ff9692f9c8..2e20421348 100644 --- a/test/integration/smoke/test_secondary_storage.py +++ b/test/integration/smoke/test_secondary_storage.py @@ -20,9 +20,9 @@ import marvin from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * +from marvin.lib.utils import * +from marvin.lib.base import * +from marvin.lib.common import * from nose.plugins.attrib import attr #Import System modules @@ -33,7 +33,7 @@ class TestSecStorageServices(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestSecStorageServices, cls).getClsTestClient().getApiClient() + cls.apiclient = super(TestSecStorageServices, cls).getClsTestClient().getApiClient() cls._cleanup = [] return @@ -41,7 +41,7 @@ def setUpClass(cls): def tearDownClass(cls): try: #Cleanup resources used - cleanup_resources(cls.api_client, cls._cleanup) + cleanup_resources(cls.apiclient, cls._cleanup) except Exception as e: raise Exception("Warning: Exception during cleanup : %s" % e) return @@ -81,7 +81,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags = ["advanced", "advancedns", "smoke", "basic", "eip", "sg"]) + @attr(tags = ["advanced", "advancedns", "smoke", "basic", "eip", "sg"], required_hardware="false",BugId="CLOUDSTACK-6877") def test_01_sys_vm_start(self): """Test system VM start """ @@ -160,7 +160,7 @@ def test_01_sys_vm_start(self): ) return - @attr(tags = ["advanced", "advancedns", "smoke", "basic", "eip", "sg"]) + @attr(tags = ["advanced", "advancedns", "smoke", "basic", "eip", "sg"], BugId="CLOUDSTACK-6773", required_hardware="false") def test_02_sys_template_ready(self): """Test system templates are ready """ @@ -187,6 +187,8 @@ def test_02_sys_template_ready(self): listall=True, account='system' ) + self.assertEqual(validateList(list_template_response)[0], PASS,\ + "templates list validation failed") # Ensure all BUILTIN templates are downloaded templateid = None diff --git a/test/integration/smoke/test_service_offerings.py b/test/integration/smoke/test_service_offerings.py index 968dc5622f..e390f75572 100644 --- a/test/integration/smoke/test_service_offerings.py +++ b/test/integration/smoke/test_service_offerings.py @@ -17,15 +17,16 @@ """ BVT tests for Service offerings""" #Import Local Modules +from marvin.codes import FAILED from marvin.cloudstackTestCase import cloudstackTestCase from marvin.cloudstackAPI import changeServiceForVirtualMachine,updateServiceOffering -from marvin.integration.lib.utils import (isAlmostEqual, +from marvin.lib.utils import (isAlmostEqual, cleanup_resources, random_gen) -from marvin.integration.lib.base import (ServiceOffering, +from marvin.lib.base import (ServiceOffering, Account, VirtualMachine) -from marvin.integration.lib.common import (list_service_offering, +from marvin.lib.common import (list_service_offering, list_virtual_machines, get_domain, get_zone, @@ -35,93 +36,13 @@ _multiprocess_shared_ = True -class Services: - """Test Service offerings Services - """ - - def __init__(self): - self.services = { - "account": { - "email": "test@test.com", - "firstname": "Test", - "lastname": "User", - "username": "test", - # Random characters are appended in create account to - # ensure unique username generated each time - "password": "password", - }, - "off": - { - "name": "Service Offering", - "displaytext": "Service Offering", - "cpunumber": 1, - "cpuspeed": 100, # MHz - "memory": 128, # in MBs - }, - "small": - # Create a small virtual machine instance with disk offering - { - "displayname": "testserver", - "username": "root", # VM creds for SSH - "password": "password", - "ssh_port": 22, - "hypervisor": 'XenServer', - "privateport": 22, - "publicport": 22, - "protocol": 'TCP', - }, - "medium": # Create a medium virtual machine instance - { - "displayname": "testserver", - "username": "root", - "password": "password", - "ssh_port": 22, - "hypervisor": 'XenServer', - "privateport": 22, - "publicport": 22, - "protocol": 'TCP', - }, - "service_offerings": - { - "tiny": - { - "name": "Tiny Instance", - "displaytext": "Tiny Instance", - "cpunumber": 1, - "cpuspeed": 100, # in MHz - "memory": 128, # In MBs - }, - "small": - { - # Small service offering ID to for change VM - # service offering from medium to small - "name": "Small Instance", - "displaytext": "Small Instance", - "cpunumber": 1, - "cpuspeed": 100, - "memory": 128, - }, - "medium": - { - # Medium service offering ID to for - # change VM service offering from small to medium - "name": "Medium Instance", - "displaytext": "Medium Instance", - "cpunumber": 1, - "cpuspeed": 100, - "memory": 256, - } - }, - "ostype": 'CentOS 5.3 (64-bit)', - } - class TestCreateServiceOffering(cloudstackTestCase): def setUp(self): self.apiclient = self.testClient.getApiClient() self.dbclient = self.testClient.getDbConnection() self.cleanup = [] - self.services = Services().services + self.services = self.testClient.getParsedTestDataConfig() def tearDown(self): try: @@ -133,7 +54,7 @@ def tearDown(self): return - @attr(tags=["advanced", "advancedns", "smoke", "basic", "eip", "sg"]) + @attr(tags=["advanced", "advancedns", "smoke", "basic", "eip", "sg"], required_hardware="false") def test_01_create_service_offering(self): """Test to create service offering""" @@ -143,7 +64,7 @@ def test_01_create_service_offering(self): service_offering = ServiceOffering.create( self.apiclient, - self.services["off"] + self.services["service_offerings"] ) self.cleanup.append(service_offering) @@ -164,31 +85,30 @@ def test_01_create_service_offering(self): 0, "Check Service offering is created" ) - service_response = list_service_response[0] self.assertEqual( list_service_response[0].cpunumber, - self.services["off"]["cpunumber"], + self.services["service_offerings"]["cpunumber"], "Check server id in createServiceOffering" ) self.assertEqual( list_service_response[0].cpuspeed, - self.services["off"]["cpuspeed"], + self.services["service_offerings"]["cpuspeed"], "Check cpuspeed in createServiceOffering" ) self.assertEqual( list_service_response[0].displaytext, - self.services["off"]["displaytext"], + self.services["service_offerings"]["displaytext"], "Check server displaytext in createServiceOfferings" ) self.assertEqual( list_service_response[0].memory, - self.services["off"]["memory"], + self.services["service_offerings"]["memory"], "Check memory in createServiceOffering" ) self.assertEqual( list_service_response[0].name, - self.services["off"]["name"], + self.services["service_offerings"]["name"], "Check name in createServiceOffering" ) return @@ -212,25 +132,30 @@ def tearDown(self): @classmethod def setUpClass(cls): - cls.api_client = super(TestServiceOfferings, cls).getClsTestClient().getApiClient() - cls.services = Services().services - domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + testClient = super(TestServiceOfferings, cls).getClsTestClient() + cls.apiclient = testClient.getApiClient() + cls.services = testClient.getParsedTestDataConfig() + + domain = get_domain(cls.apiclient) + cls.zone = get_zone(cls.apiclient, testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype cls.service_offering_1 = ServiceOffering.create( - cls.api_client, - cls.services["off"] + cls.apiclient, + cls.services["service_offerings"] ) cls.service_offering_2 = ServiceOffering.create( - cls.api_client, - cls.services["off"] + cls.apiclient, + cls.services["service_offerings"] ) template = get_template( - cls.api_client, + cls.apiclient, cls.zone.id, cls.services["ostype"] ) + if template == FAILED: + assert False, "get_template() failed to return template with description %s" % cls.services["ostype"] + # Set Zones and disk offerings cls.services["small"]["zoneid"] = cls.zone.id cls.services["small"]["template"] = template.id @@ -240,22 +165,22 @@ def setUpClass(cls): # Create VMs, NAT Rules etc cls.account = Account.create( - cls.api_client, + cls.apiclient, cls.services["account"], domainid=domain.id ) cls.small_offering = ServiceOffering.create( - cls.api_client, + cls.apiclient, cls.services["service_offerings"]["small"] ) cls.medium_offering = ServiceOffering.create( - cls.api_client, + cls.apiclient, cls.services["service_offerings"]["medium"] ) cls.medium_virtual_machine = VirtualMachine.create( - cls.api_client, + cls.apiclient, cls.services["medium"], accountid=cls.account.name, domainid=cls.account.domainid, @@ -272,15 +197,15 @@ def setUpClass(cls): @classmethod def tearDownClass(cls): try: - cls.api_client = super(TestServiceOfferings, cls).getClsTestClient().getApiClient() + cls.apiclient = super(TestServiceOfferings, cls).getClsTestClient().getApiClient() #Clean up, terminate the created templates - cleanup_resources(cls.api_client, cls._cleanup) + cleanup_resources(cls.apiclient, cls._cleanup) except Exception as e: raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags=["advanced", "advancedns", "smoke", "basic", "eip", "sg"]) + @attr(tags=["advanced", "advancedns", "smoke", "basic", "eip", "sg"], required_hardware="false") def test_02_edit_service_offering(self): """Test to update existing service offering""" @@ -331,7 +256,7 @@ def test_02_edit_service_offering(self): return - @attr(tags=["advanced", "advancedns", "smoke", "basic", "eip", "sg"]) + @attr(tags=["advanced", "advancedns", "smoke", "basic", "eip", "sg"], required_hardware="false") def test_03_delete_service_offering(self): """Test to delete service offering""" @@ -357,7 +282,7 @@ def test_03_delete_service_offering(self): return - @attr(tags=["advanced", "advancedns", "smoke"]) + @attr(tags=["advanced", "advancedns", "smoke"], required_hardware="true") def test_04_change_offering_small(self): """Test to change service to a small capacity """ @@ -367,23 +292,10 @@ def test_04_change_offering_small(self): # 2. Using listVM command verify that this Vm # has Small service offering Id. - self.debug("Stopping VM - ID: %s" % self.medium_virtual_machine.id) - self.medium_virtual_machine.stop(self.apiclient) - # Ensure that VM is in stopped state - list_vm_response = list_virtual_machines( - self.apiclient, - id=self.medium_virtual_machine.id - ) - if isinstance(list_vm_response, list): - vm = list_vm_response[0] - if vm.state == 'Stopped': - self.debug("VM state: %s" % vm.state) - else: - raise Exception( - "Failed to stop VM (ID: %s) in change service offering" % vm.id) - - self.debug("Change Service offering VM - ID: %s" % - self.medium_virtual_machine.id) + try: + self.medium_virtual_machine.stop(self.apiclient) + except Exception as e: + self.fail("Failed to stop VM: %s" % e) cmd = changeServiceForVirtualMachine.changeServiceForVirtualMachineCmd() cmd.id = self.medium_virtual_machine.id diff --git a/test/integration/smoke/test_snapshots.py b/test/integration/smoke/test_snapshots.py index 6ee7c6271c..8b6fdd1a0f 100644 --- a/test/integration/smoke/test_snapshots.py +++ b/test/integration/smoke/test_snapshots.py @@ -15,129 +15,35 @@ # specific language governing permissions and limitations # under the License. +from marvin.codes import FAILED from nose.plugins.attrib import attr from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * - -class Services: - """Test Snapshots Services - """ - - def __init__(self): - self.services = { - "account": { - "email": "test@test.com", - "firstname": "Test", - "lastname": "User", - "username": "test", - # Random characters are appended for unique - # username - "password": "password", - }, - "service_offering": { - "name": "Tiny Instance", - "displaytext": "Tiny Instance", - "cpunumber": 1, - "cpuspeed": 200, # in MHz - "memory": 256, # In MBs - }, - "disk_offering": { - "displaytext": "Small Disk", - "name": "Small Disk", - "disksize": 1 - }, - "server_with_disk": - { - "displayname": "Test VM -With Disk", - "username": "root", - "password": "password", - "ssh_port": 22, - "hypervisor": 'XenServer', - "privateport": 22, - "publicport": 22, - "protocol": 'TCP', - }, - - "server_without_disk": - { - "displayname": "Test VM-No Disk", - "username": "root", - "password": "password", - "ssh_port": 22, - "hypervisor": 'XenServer', - "privateport": 22, - # For NAT rule creation - "publicport": 22, - "protocol": 'TCP', - }, - "server": { - "displayname": "TestVM", - "username": "root", - "password": "password", - "ssh_port": 22, - "hypervisor": 'XenServer', - "privateport": 22, - "publicport": 22, - "protocol": 'TCP', - }, - "mgmt_server": { - "ipaddress": '192.168.100.21', - "username": "root", - "password": "password", - "port": 22, - }, - "recurring_snapshot": { - "intervaltype": 'HOURLY', - # Frequency of snapshots - "maxsnaps": 1, # Should be min 2 - "schedule": 1, - "timezone": 'US/Arizona', - # Timezone Formats - http://cloud.mindtouch.us/CloudStack_Documentation/Developer's_Guide%3A_CloudStack - }, - "templates": { - "displaytext": 'Template', - "name": 'Template', - "ostype": "CentOS 5.3 (64-bit)", - "templatefilter": 'self', - }, - "volume": { - "diskname": "APP Data Volume", - "size": 1, # in GBs - "diskdevice": ['/dev/xvdb', '/dev/sdb', '/dev/hdb', '/dev/vdb' ], # Data Disk - }, - "paths": { - "mount_dir": "/mnt/tmp", - "sub_dir": "test", - "sub_lvl_dir1": "test1", - "sub_lvl_dir2": "test2", - "random_data": "random.data", - }, - "ostype": "CentOS 5.3 (64-bit)", - # Cent OS 5.3 (64 bit) - "sleep": 60, - "timeout": 10, - } - +from marvin.lib.utils import * +from marvin.lib.base import * +from marvin.lib.common import * class TestSnapshotRootDisk(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestSnapshotRootDisk, cls).getClsTestClient().getApiClient() - cls.services = Services().services + testClient = super(TestSnapshotRootDisk, cls).getClsTestClient() + cls.apiclient = testClient.getApiClient() + cls.services = testClient.getParsedTestDataConfig() + # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.apiclient) + cls.zone = get_zone(cls.apiclient, testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype template = get_template( - cls.api_client, + cls.apiclient, cls.zone.id, cls.services["ostype"] ) + if template == FAILED: + assert False, "get_template() failed to return template with description %s" % cls.services["ostype"] + cls.services["domainid"] = cls.domain.id cls.services["server_without_disk"]["zoneid"] = cls.zone.id cls.services["templates"]["ostypeid"] = template.ostypeid @@ -145,20 +51,17 @@ def setUpClass(cls): # Create VMs, NAT Rules etc cls.account = Account.create( - cls.api_client, + cls.apiclient, cls.services["account"], domainid=cls.domain.id ) - - cls.services["account"] = cls.account.name - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] + cls.apiclient, + cls.services["service_offerings"] ) cls.virtual_machine = cls.virtual_machine_with_disk = \ VirtualMachine.create( - cls.api_client, + cls.apiclient, cls.services["server_without_disk"], templateid=template.id, accountid=cls.account.name, @@ -176,7 +79,7 @@ def setUpClass(cls): def tearDownClass(cls): try: #Cleanup resources used - cleanup_resources(cls.api_client, cls._cleanup) + cleanup_resources(cls.apiclient, cls._cleanup) except Exception as e: raise Exception("Warning: Exception during cleanup : %s" % e) return @@ -195,8 +98,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(speed = "slow") - @attr(tags = ["advanced", "advancedns", "smoke"]) + @attr(tags = ["advanced", "advancedns", "smoke"], required_hardware="true") def test_01_snapshot_root_disk(self): """Test Snapshot Root Disk """ diff --git a/test/integration/smoke/test_ssvm.py b/test/integration/smoke/test_ssvm.py index a2b9eabc13..9b8d19d024 100644 --- a/test/integration/smoke/test_ssvm.py +++ b/test/integration/smoke/test_ssvm.py @@ -21,9 +21,9 @@ from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * from marvin.sshClient import SshClient -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * +from marvin.lib.utils import * +from marvin.lib.base import * +from marvin.lib.common import * from nose.plugins.attrib import attr import telnetlib @@ -31,24 +31,14 @@ import time _multiprocess_shared_ = True -class Services: - """Test SSVM Services - """ - - def __init__(self): - self.services = { - "sleep": 60, - "timeout": 10, - } - class TestSSVMs(cloudstackTestCase): def setUp(self): - self.apiclient = self.testClient.getApiClient() + self.hypervisor = self.testClient.getHypervisorInfo() self.cleanup = [] - self.services = Services().services - self.zone = get_zone(self.apiclient, self.services) + self.services = self.testClient.getParsedTestDataConfig() + self.zone = get_zone(self.apiclient, self.testClient.getZoneForTests()) return def tearDown(self): @@ -60,7 +50,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags = ["advanced", "advancedns", "smoke", "basic", "sg"]) + @attr(tags = ["advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="false") def test_01_list_sec_storage_vm(self): """Test List secondary storage VMs """ @@ -178,7 +168,7 @@ def test_01_list_sec_storage_vm(self): ) return - @attr(tags = ["advanced", "advancedns", "smoke", "basic", "sg"]) + @attr(tags = ["advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="false") def test_02_list_cpvm_vm(self): """Test List console proxy VMs """ @@ -290,7 +280,7 @@ def test_02_list_cpvm_vm(self): ) return - @attr(tags = ["advanced", "advancedns", "smoke", "basic", "sg"]) + @attr(tags = ["advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="true") def test_03_ssvm_internals(self): """Test SSVM Internals""" @@ -329,7 +319,7 @@ def test_03_ssvm_internals(self): self.debug("Running SSVM check script") - if self.apiclient.hypervisor.lower() == 'vmware': + if self.hypervisor.lower() == 'vmware': #SSH into SSVMs is done via management server for Vmware result = get_process_status( self.apiclient.connection.mgtSvr, @@ -338,7 +328,7 @@ def test_03_ssvm_internals(self): self.apiclient.connection.passwd, ssvm.privateip, "/usr/local/cloud/systemvm/ssvm-check.sh |grep -e ERROR -e WARNING -e FAIL", - hypervisor=self.apiclient.hypervisor + hypervisor=self.hypervisor ) else: try: @@ -369,7 +359,7 @@ def test_03_ssvm_internals(self): ) #Check status of cloud service - if self.apiclient.hypervisor.lower() == 'vmware': + if self.hypervisor.lower() == 'vmware': #SSH into SSVMs is done via management server for Vmware result = get_process_status( self.apiclient.connection.mgtSvr, @@ -378,7 +368,7 @@ def test_03_ssvm_internals(self): self.apiclient.connection.passwd, ssvm.privateip, "service cloud status", - hypervisor=self.apiclient.hypervisor + hypervisor=self.hypervisor ) else: try: @@ -403,7 +393,7 @@ def test_03_ssvm_internals(self): ) return - @attr(tags = ["advanced", "advancedns", "smoke", "basic", "sg"]) + @attr(tags = ["advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="true") def test_04_cpvm_internals(self): """Test CPVM Internals""" @@ -453,7 +443,7 @@ def test_04_cpvm_internals(self): self.debug("Checking cloud process status") - if self.apiclient.hypervisor.lower() == 'vmware': + if self.hypervisor.lower() == 'vmware': #SSH into SSVMs is done via management server for vmware result = get_process_status( self.apiclient.connection.mgtSvr, @@ -462,7 +452,7 @@ def test_04_cpvm_internals(self): self.apiclient.connection.passwd, cpvm.privateip, "service cloud status", - hypervisor=self.apiclient.hypervisor + hypervisor=self.hypervisor ) else: try: @@ -486,7 +476,7 @@ def test_04_cpvm_internals(self): ) return - @attr(tags = ["advanced", "advancedns", "smoke", "basic", "sg"]) + @attr(tags = ["advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="true") def test_05_stop_ssvm(self): """Test stop SSVM """ @@ -562,7 +552,7 @@ def test_05_stop_ssvm(self): self.test_03_ssvm_internals() return - @attr(tags = ["advanced", "advancedns", "smoke", "basic", "sg"]) + @attr(tags = ["advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="true") def test_06_stop_cpvm(self): """Test stop CPVM """ @@ -635,7 +625,7 @@ def test_06_stop_cpvm(self): self.test_04_cpvm_internals() return - @attr(tags = ["advanced", "advancedns", "smoke", "basic", "sg"]) + @attr(tags = ["advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="true") def test_07_reboot_ssvm(self): """Test reboot SSVM """ @@ -721,7 +711,7 @@ def test_07_reboot_ssvm(self): self.test_03_ssvm_internals() return - @attr(tags = ["advanced", "advancedns", "smoke", "basic", "sg"]) + @attr(tags = ["advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="true") def test_08_reboot_cpvm(self): """Test reboot CPVM """ @@ -808,7 +798,7 @@ def test_08_reboot_cpvm(self): self.test_04_cpvm_internals() return - @attr(tags = ["advanced", "advancedns", "smoke", "basic", "sg"]) + @attr(tags = ["advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="true") def test_09_destroy_ssvm(self): """Test destroy SSVM """ @@ -890,7 +880,7 @@ def test_09_destroy_ssvm(self): self.test_03_ssvm_internals() return - @attr(tags = ["advanced", "advancedns", "smoke", "basic", "sg"]) + @attr(tags = ["advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="true") def test_10_destroy_cpvm(self): """Test destroy CPVM """ diff --git a/test/integration/smoke/test_templates.py b/test/integration/smoke/test_templates.py index e371ad436a..a757c2ad1a 100644 --- a/test/integration/smoke/test_templates.py +++ b/test/integration/smoke/test_templates.py @@ -5,9 +5,9 @@ # 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 @@ -17,87 +17,31 @@ """ BVT tests for Templates ISO """ #Import Local Modules -import marvin -from marvin.cloudstackTestCase import * -from marvin.cloudstackAPI import * -from marvin.sshClient import SshClient -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * +from marvin.codes import FAILED +from marvin.cloudstackTestCase import cloudstackTestCase, unittest +from marvin.cloudstackAPI import (updateTemplate, + extractTemplate, + listZones, + updateTemplatePermissions, + deleteTemplate, + copyTemplate) +from marvin.lib.utils import random_gen, cleanup_resources +from marvin.lib.base import (Account, + ServiceOffering, + VirtualMachine, + DiskOffering, + Template, + Volume) +from marvin.lib.common import (get_domain, + get_zone, + get_template) from nose.plugins.attrib import attr import urllib -from random import random #Import System modules -import datetime +import time _multiprocess_shared_ = True -class Services: - """Test Templates Services - """ - - def __init__(self): - self.services = { - "account": { - "email": "test@test.com", - "firstname": "Test", - "lastname": "User", - "username": "test", - # Random characters are appended for unique - # username - "password": "password", - }, - "service_offering": { - "name": "Tiny Instance", - "displaytext": "Tiny Instance", - "cpunumber": 1, - "cpuspeed": 100, # in MHz - "memory": 128, # In MBs - }, - "disk_offering": { - "displaytext": "Small", - "name": "Small", - "disksize": 1 - }, - "virtual_machine": { - "displayname": "testVM", - "hypervisor": 'XenServer', - "protocol": 'TCP', - "ssh_port": 22, - "username": "root", - "password": "password", - "privateport": 22, - "publicport": 22, - }, - "volume": { - "diskname": "Test Volume", - }, - "template_1": { - "displaytext": "Cent OS Template", - "name": "Cent OS Template", - "ostype": "CentOS 5.3 (64-bit)", - }, - "template_2": { - "displaytext": "Public Template", - "name": "Public template", - "ostype": "CentOS 5.3 (64-bit)", - "isfeatured": True, - "ispublic": True, - "isextractable": True, - "mode": "HTTP_DOWNLOAD", - }, - "templatefilter": 'self', - "isfeatured": True, - "ispublic": True, - "isextractable": False, - "bootable": True, - "passwordenabled": True, - "ostype": "CentOS 5.3 (64-bit)", - "sleep": 30, - "timeout": 10, - } - - class TestCreateTemplate(cloudstackTestCase): def setUp(self): @@ -118,45 +62,53 @@ def tearDown(self): @classmethod def setUpClass(cls): - cls.services = Services().services - cls.api_client = super(TestCreateTemplate, cls).getClsTestClient().getApiClient() + + testClient = super(TestCreateTemplate, cls).getClsTestClient() + cls.apiclient = testClient.getApiClient() + cls.services = testClient.getParsedTestDataConfig() # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.apiclient) + cls.zone = get_zone(cls.apiclient, testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype - cls.disk_offering = DiskOffering.create( - cls.api_client, + + cls._cleanup = [] + try: + cls.disk_offering = DiskOffering.create( + cls.apiclient, cls.services["disk_offering"] ) - template = get_template( - cls.api_client, + cls._cleanup.append(cls.disk_offering) + template = get_template( + cls.apiclient, cls.zone.id, cls.services["ostype"] ) - cls.services["template_1"]["ostypeid"] = template.ostypeid - cls.services["template_2"]["ostypeid"] = template.ostypeid - cls.services["ostypeid"] = template.ostypeid - - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["volume"]["diskoffering"] = cls.disk_offering.id - cls.services["volume"]["zoneid"] = cls.zone.id - cls.services["sourcezoneid"] = cls.zone.id - - cls.account = Account.create( - cls.api_client, + if template == FAILED: + assert False, "get_template() failed to return template with description %s" % cls.services["ostype"] + + cls.services["template"]["ostypeid"] = template.ostypeid + cls.services["template_2"]["ostypeid"] = template.ostypeid + cls.services["ostypeid"] = template.ostypeid + + cls.services["virtual_machine"]["zoneid"] = cls.zone.id + cls.services["volume"]["diskoffering"] = cls.disk_offering.id + cls.services["volume"]["zoneid"] = cls.zone.id + cls.services["sourcezoneid"] = cls.zone.id + cls.account = Account.create( + cls.apiclient, cls.services["account"], domainid=cls.domain.id ) - cls.services["account"] = cls.account.name - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] + cls._cleanup.append(cls.account) + cls.service_offering = ServiceOffering.create( + cls.apiclient, + cls.services["service_offerings"] ) - #create virtual machine - cls.virtual_machine = VirtualMachine.create( - cls.api_client, + cls._cleanup.append(cls.service_offering) + #create virtual machine + cls.virtual_machine = VirtualMachine.create( + cls.apiclient, cls.services["virtual_machine"], templateid=template.id, accountid=cls.account.name, @@ -164,62 +116,35 @@ def setUpClass(cls): serviceofferingid=cls.service_offering.id, mode=cls.services["mode"] ) + #Stop virtual machine + cls.virtual_machine.stop(cls.apiclient) - #Stop virtual machine - cls.virtual_machine.stop(cls.api_client) - - # Poll listVM to ensure VM is stopped properly - timeout = cls.services["timeout"] - while True: - time.sleep(cls.services["sleep"]) - - # Ensure that VM is in stopped state - list_vm_response = list_virtual_machines( - cls.api_client, - id=cls.virtual_machine.id - ) - - if isinstance(list_vm_response, list): - - vm = list_vm_response[0] - if vm.state == 'Stopped': - break - - if timeout == 0: - raise Exception( - "Failed to stop VM (ID: %s) in change service offering" % - vm.id) - - timeout = timeout - 1 - - list_volume = list_volumes( - cls.api_client, + list_volume = Volume.list( + cls.apiclient, virtualmachineid=cls.virtual_machine.id, type='ROOT', listall=True ) - cls.volume = list_volume[0] - cls._cleanup = [ - cls.account, - cls.service_offering, - cls.disk_offering, - ] + cls.volume = list_volume[0] + except Exception as e: + cls.tearDownClass() + raise unittest.SkipTest("Exception in setUpClass: %s" % e) return @classmethod def tearDownClass(cls): try: - cls.api_client = super(TestCreateTemplate, cls).getClsTestClient().getApiClient() + cls.apiclient = super(TestCreateTemplate, cls).getClsTestClient().getApiClient() #Cleanup resources used - cleanup_resources(cls.api_client, cls._cleanup) + cleanup_resources(cls.apiclient, cls._cleanup) except Exception as e: raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags = ["advanced", "advancedns", "smoke"]) + @attr(tags = ["advanced", "advancedns", "smoke"], required_hardware="false") def test_01_create_template(self): """Test create public & private template """ @@ -233,7 +158,7 @@ def test_01_create_template(self): #Create template from Virtual machine and Volume ID template = Template.create( self.apiclient, - self.services["template_1"], + self.services["template"], self.volume.id, account=self.account.name, domainid=self.account.domainid @@ -242,7 +167,7 @@ def test_01_create_template(self): self.debug("Created template with ID: %s" % template.id) - list_template_response = list_templates( + list_template_response = Template.list( self.apiclient, templatefilter=\ self.services["templatefilter"], @@ -264,18 +189,18 @@ def test_01_create_template(self): self.assertEqual( template_response.displaytext, - self.services["template_1"]["displaytext"], + self.services["template"]["displaytext"], "Check display text of newly created template" ) name = template_response.name self.assertEqual( - name.count(self.services["template_1"]["name"]), + name.count(self.services["template"]["name"]), 1, "Check name of newly created template" ) self.assertEqual( template_response.ostypeid, - self.services["template_1"]["ostypeid"], + self.services["template"]["ostypeid"], "Check osTypeID of newly created template" ) return @@ -286,60 +211,61 @@ class TestTemplates(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.services = Services().services - cls.api_client = super(TestTemplates, cls).getClsTestClient().getApiClient() + testClient = super(TestTemplates, cls).getClsTestClient() + cls.apiclient = testClient.getApiClient() + cls.services = testClient.getParsedTestDataConfig() # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.apiclient) + cls.zone = get_zone(cls.apiclient, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype #populate second zone id for iso copy cmd = listZones.listZonesCmd() - cls.zones = cls.api_client.listZones(cmd) + cls.zones = cls.apiclient.listZones(cmd) if not isinstance(cls.zones, list): raise Exception("Failed to find zones.") cls.disk_offering = DiskOffering.create( - cls.api_client, + cls.apiclient, cls.services["disk_offering"] ) template = get_template( - cls.api_client, + cls.apiclient, cls.zone.id, cls.services["ostype"] ) + if template == FAILED: + assert False, "get_template() failed to return template with description %s" % cls.services["ostype"] + cls.services["virtual_machine"]["zoneid"] = cls.zone.id cls.services["volume"]["diskoffering"] = cls.disk_offering.id cls.services["volume"]["zoneid"] = cls.zone.id cls.services["template_2"]["zoneid"] = cls.zone.id cls.services["sourcezoneid"] = cls.zone.id - cls.services["template_1"]["ostypeid"] = template.ostypeid + cls.services["template"]["ostypeid"] = template.ostypeid cls.services["template_2"]["ostypeid"] = template.ostypeid cls.services["ostypeid"] = template.ostypeid - + print "Before:",cls.services cls.account = Account.create( - cls.api_client, + cls.apiclient, cls.services["account"], admin=True, domainid=cls.domain.id ) - + print "After:",cls.services cls.user = Account.create( - cls.api_client, + cls.apiclient, cls.services["account"], domainid=cls.domain.id ) - - cls.services["account"] = cls.account.name - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] + cls.apiclient, + cls.services["service_offerings"] ) #create virtual machine cls.virtual_machine = VirtualMachine.create( - cls.api_client, + cls.apiclient, cls.services["virtual_machine"], templateid=template.id, accountid=cls.account.name, @@ -348,34 +274,10 @@ def setUpClass(cls): mode=cls.services["mode"] ) #Stop virtual machine - cls.virtual_machine.stop(cls.api_client) - - # Poll listVM to ensure VM is stopped properly - timeout = cls.services["timeout"] - while True: - time.sleep(cls.services["sleep"]) - - # Ensure that VM is in stopped state - list_vm_response = list_virtual_machines( - cls.api_client, - id=cls.virtual_machine.id - ) - - if isinstance(list_vm_response, list): - - vm = list_vm_response[0] - if vm.state == 'Stopped': - break - - if timeout == 0: - raise Exception( - "Failed to stop VM (ID: %s) in change service offering" % - vm.id) - - timeout = timeout - 1 + cls.virtual_machine.stop(cls.apiclient) - list_volume = list_volumes( - cls.api_client, + list_volume = Volume.list( + cls.apiclient, virtualmachineid=cls.virtual_machine.id, type='ROOT', listall=True @@ -384,19 +286,19 @@ def setUpClass(cls): cls.volume = list_volume[0] except Exception as e: raise Exception( - "Exception: Unable to find root volume foe VM: %s" % - cls.virtual_machine.id) + "Exception: Unable to find root volume foe VM: %s - %s" % + (cls.virtual_machine.id, e)) #Create templates for Edit, Delete & update permissions testcases cls.template_1 = Template.create( - cls.api_client, - cls.services["template_1"], + cls.apiclient, + cls.services["template"], cls.volume.id, account=cls.account.name, domainid=cls.account.domainid ) cls.template_2 = Template.create( - cls.api_client, + cls.apiclient, cls.services["template_2"], cls.volume.id, account=cls.account.name, @@ -412,9 +314,9 @@ def setUpClass(cls): @classmethod def tearDownClass(cls): try: - cls.api_client = super(TestTemplates, cls).getClsTestClient().getApiClient() + cls.apiclient = super(TestTemplates, cls).getClsTestClient().getApiClient() #Cleanup created resources such as templates and VMs - cleanup_resources(cls.api_client, cls._cleanup) + cleanup_resources(cls.apiclient, cls._cleanup) except Exception as e: raise Exception("Warning: Exception during cleanup : %s" % e) @@ -438,7 +340,7 @@ def tearDown(self): return - @attr(tags = ["advanced", "advancedns", "smoke", "basic", "sg"]) + @attr(tags = ["advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="false") def test_02_edit_template(self): """Test Edit template """ @@ -468,7 +370,7 @@ def test_02_edit_template(self): timeout = self.services["timeout"] while True: # Verify template response for updated attributes - list_template_response = list_templates( + list_template_response = Template.list( self.apiclient, templatefilter=\ self.services["templatefilter"], @@ -521,7 +423,7 @@ def test_02_edit_template(self): ) return - @attr(tags = ["advanced", "advancedns", "smoke", "basic", "sg"]) + @attr(tags = ["advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="false") def test_03_delete_template(self): """Test delete template """ @@ -534,7 +436,7 @@ def test_03_delete_template(self): self.template_1.delete(self.apiclient) - list_template_response = list_templates( + list_template_response = Template.list( self.apiclient, templatefilter=\ self.services["templatefilter"], @@ -550,7 +452,7 @@ def test_03_delete_template(self): ) return - @attr(tags = ["advanced", "advancedns", "smoke", "basic", "sg"]) + @attr(tags = ["advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="true") def test_04_extract_template(self): "Test for extract template" @@ -601,7 +503,7 @@ def test_04_extract_template(self): ) return - @attr(tags = ["advanced", "advancedns", "smoke", "basic", "sg"]) + @attr(tags = ["advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="false") def test_05_template_permissions(self): """Update & Test for template permissions""" @@ -621,7 +523,7 @@ def test_05_template_permissions(self): cmd.isextractable = self.services["isextractable"] self.apiclient.updateTemplatePermissions(cmd) - list_template_response = list_templates( + list_template_response = Template.list( self.apiclient, templatefilter='featured', id=self.template_2.id, @@ -654,7 +556,7 @@ def test_05_template_permissions(self): ) return - @attr(tags = ["advanced", "advancedns", "smoke", "basic", "sg", "multizone"]) + @attr(tags = ["advanced", "advancedns", "smoke", "basic", "sg", "multizone"], required_hardware="true") def test_06_copy_template(self): """Test for copy template from one zone to another""" @@ -678,7 +580,7 @@ def test_06_copy_template(self): self.apiclient.copyTemplate(cmd) # Verify template is copied to another zone using ListTemplates - list_template_response = list_templates( + list_template_response = Template.list( self.apiclient, templatefilter=\ self.services["templatefilter"], @@ -712,7 +614,7 @@ def test_06_copy_template(self): timeout = self.services["timeout"] while True: time.sleep(self.services["sleep"]) - list_template_response = list_templates( + list_template_response = Template.list( self.apiclient, templatefilter=\ self.services["templatefilter"], @@ -745,14 +647,14 @@ def test_06_copy_template(self): self.apiclient.deleteTemplate(cmd) return - @attr(tags = ["advanced", "advancedns", "smoke", "basic", "sg"]) + @attr(tags = ["advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="false") def test_07_list_public_templates(self): """Test only public templates are visible to normal user""" # Validate the following # 1. ListTemplates should show only 'public' templates for normal user - list_template_response = list_templates( + list_template_response = Template.list( self.apiclient, templatefilter='featured', account=self.user.name, @@ -777,14 +679,14 @@ def test_07_list_public_templates(self): ) return - @attr(tags = ["advanced", "advancedns", "smoke", "basic", "sg"]) + @attr(tags = ["advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="false") def test_08_list_system_templates(self): """Test System templates are not visible to normal user""" # Validate the following # 1. ListTemplates should not show 'SYSTEM' templates for normal user - list_template_response = list_templates( + list_template_response = Template.list( self.apiclient, templatefilter='featured', account=self.user.name, diff --git a/test/integration/smoke/test_vm_ha.py b/test/integration/smoke/test_vm_ha.py new file mode 100644 index 0000000000..1d9021ce9f --- /dev/null +++ b/test/integration/smoke/test_vm_ha.py @@ -0,0 +1,199 @@ +# 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. + +#Test from the Marvin - Testing in Python wiki + +import time + +#All tests inherit from cloudstackTestCase +from marvin.cloudstackTestCase import cloudstackTestCase + +#Import Integration Libraries + +#base - contains all resources as entities and defines create, delete, list operations on them +from marvin.lib.base import Account, VirtualMachine, Cluster, Host, ServiceOffering, Configurations, SimulatorMock + +#utils - utility classes for common cleanup, external library wrappers etc +from marvin.lib.utils import cleanup_resources + +#common - commonly used methods for all tests are listed here +from marvin.lib.common import get_zone, get_domain, get_template + +from nose.plugins.attrib import attr + +class TestDeployVMHA(cloudstackTestCase): + """Test VM HA + """ + + def setUp(self): + self.testdata = self.testClient.getParsedTestDataConfig() + self.apiclient = self.testClient.getApiClient() + + # Get Zone, Domain and Default Built-in template + self.domain = get_domain(self.apiclient) + self.zone = get_zone(self.apiclient, self.testClient.getZoneForTests()) + + self.testdata["mode"] = self.zone.networktype + self.template = get_template(self.apiclient, self.zone.id, self.testdata["ostype"]) + + self.hosts = [] + suitablecluster = None + clusters = Cluster.list(self.apiclient) + self.assertTrue(isinstance(clusters, list) and len(clusters) > 0, msg = "No clusters found") + for cluster in clusters: + self.hosts = Host.list(self.apiclient, clusterid=cluster.id, type='Routing') + if isinstance(self.hosts, list) and len(self.hosts) >= 2: + suitablecluster = cluster + break + self.assertTrue(isinstance(self.hosts, list) and len(self.hosts) >= 2, msg = "Atleast 2 hosts required in cluster for VM HA test") + #update host tags + for host in self.hosts: + Host.update(self.apiclient, id=host.id, hosttags=self.testdata["service_offerings"]["hasmall"]["hosttags"]) + + #create a user account + self.account = Account.create( + self.apiclient, + self.testdata["account"], + domainid=self.domain.id + ) + #create a service offering + self.service_offering = ServiceOffering.create( + self.apiclient, + self.testdata["service_offerings"]["hasmall"] + ) + #deploy ha vm + self.virtual_machine = VirtualMachine.create( + self.apiclient, + self.testdata["virtual_machine"], + accountid=self.account.name, + zoneid=self.zone.id, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + templateid=self.template.id + ) + list_vms = VirtualMachine.list(self.apiclient, id=self.virtual_machine.id) + self.debug( + "Verify listVirtualMachines response for virtual machine: %s"\ + % self.virtual_machine.id + ) + self.assertTrue(isinstance(list_vms, list) and len(list_vms) == 1, msg = "List VM response was empty") + self.virtual_machine = list_vms[0] + + self.mock_checkhealth = SimulatorMock.create( + apiclient=self.apiclient, + command="CheckHealthCommand", + zoneid=suitablecluster.zoneid, + podid=suitablecluster.podid, + clusterid=suitablecluster.id, + hostid=self.virtual_machine.hostid, + value="result:fail") + self.mock_ping = SimulatorMock.create( + apiclient=self.apiclient, + command="PingCommand", + zoneid=suitablecluster.zoneid, + podid=suitablecluster.podid, + clusterid=suitablecluster.id, + hostid=self.virtual_machine.hostid, + value="result:fail") + self.mock_checkvirtualmachine = SimulatorMock.create( + apiclient=self.apiclient, + command="CheckVirtualMachineCommand", + zoneid=suitablecluster.zoneid, + podid=suitablecluster.podid, + clusterid=suitablecluster.id, + hostid=self.virtual_machine.hostid, + value="result:fail") + self.mock_pingtest = SimulatorMock.create( + apiclient=self.apiclient, + command="PingTestCommand", + zoneid=suitablecluster.zoneid, + podid=suitablecluster.podid, + value="result:fail") + self.mock_checkonhost_list = [] + for host in self.hosts: + if host.id != self.virtual_machine.hostid: + self.mock_checkonhost_list.append(SimulatorMock.create( + apiclient=self.apiclient, + command="CheckOnHostCommand", + zoneid=suitablecluster.zoneid, + podid=suitablecluster.podid, + clusterid=suitablecluster.id, + hostid=host.id, + value="result:fail")) + #build cleanup list + self.cleanup = [ + self.service_offering, + self.account, + self.mock_checkhealth, + self.mock_ping, + self.mock_checkvirtualmachine, + self.mock_pingtest + ] + self.cleanup = self.cleanup + self.mock_checkonhost_list + + @attr(tags = ['advanced'], required_hardware="false", BugId="CLOUDSTACK-6873") + def test_vm_ha(self): + """Test VM HA + + # Validate the following: + # VM started on other host in cluster + """ + + #wait for VM to HA + ping_timeout = Configurations.list(self.apiclient, name="ping.timeout") + ping_interval = Configurations.list(self.apiclient, name="ping.interval") + total_duration = int(float(ping_timeout[0].value) * float(ping_interval[0].value)) + time.sleep(total_duration) + + duration = 0 + vm = None + while duration < total_duration: + list_vms = VirtualMachine.list(self.apiclient, id=self.virtual_machine.id) + self.assertTrue(isinstance(list_vms, list) and len(list_vms) == 1, msg = "List VM response was empty") + vm = list_vms[0] + if vm.hostid != self.virtual_machine.hostid and vm.state == "Running": + break + else: + time.sleep(10) + duration = duration + 10 + + self.assertEqual( + vm.id, + self.virtual_machine.id, + "VM ids do not match") + self.assertEqual( + vm.name, + self.virtual_machine.name, + "VM names do not match") + self.assertEqual( + vm.state, + "Running", + msg="VM is not in Running state") + self.assertNotEqual( + vm.hostid, + self.virtual_machine.hostid, + msg="VM is not started on another host as part of HA") + + def tearDown(self): + try: + for host in self.hosts: + Host.update(self.apiclient, id=host.id, hosttags="") + + cleanup_resources(self.apiclient, self.cleanup) + except Exception as e: + self.debug("Warning! Exception in tearDown: %s" % e) + diff --git a/test/integration/smoke/test_vm_iam.py b/test/integration/smoke/test_vm_iam.py deleted file mode 100644 index 29e587bbd3..0000000000 --- a/test/integration/smoke/test_vm_iam.py +++ /dev/null @@ -1,717 +0,0 @@ -# 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 Virtual Machine IAM effect -""" -#Import Local Modules -import marvin -from marvin.cloudstackTestCase import * -from marvin.cloudstackAPI import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * -from nose.plugins.attrib import attr -#Import System modules -import time - -_multiprocess_shared_ = True -class Services: - """Test VM Life Cycle Services - """ - - def __init__(self): - self.services = { - #data for domains and accounts - "domain1": { - "name": "Domain1", - }, - "account1A": { - "email": "test1A@test.com", - "firstname": "test1A", - "lastname": "User", - "username": "test1A", - "password": "password", - }, - "account1B": { - "email": "test1B@test.com", - "firstname": "test1B", - "lastname": "User", - "username": "test1B", - "password": "password", - }, - "domain2": { - "name": "Domain2", - }, - "account2A": { - "email": "test2A@test.com", - "firstname": "test2A", - "lastname": "User", - "username": "test2A", - "password": "password", - }, - #data reqd for virtual machine creation - "virtual_machine1A" : { - "name" : "test1Avm", - "displayname" : "Test1A VM", - }, - "virtual_machine1B" : { - "name" : "test1Bvm", - "displayname" : "Test1B VM", - }, - "virtual_machine2A" : { - "name" : "test2Avm", - "displayname" : "Test2A VM", - }, - #small service offering - "service_offering": { - "small": { - "name": "Small Instance", - "displaytext": "Small Instance", - "cpunumber": 1, - "cpuspeed": 100, - "memory": 128, - }, - }, - "ostype": 'CentOS 5.6 (64-bit)', - # iam group and policy information - "service_desk_iam_grp" : { - "name" : "Service Desk", - "description" : "Service Desk IAM Group" - }, - "vm_readonly_iam_policy" : { - "name" : "VM Read Only Access", - "description" : "VM read only access iam policy" - }, - } - - - -class TestVMIam(cloudstackTestCase): - - @classmethod - def setUpClass(self): - self.apiclient = super(TestVMIam, self).getClsTestClient().getApiClient() - self.services = Services().services - - # backup default apikey and secretkey - self.default_apikey = self.apiclient.connection.apiKey - self.default_secretkey = self.apiclient.connection.securityKey - - # Create domains and accounts etc - self.domain_1 = Domain.create( - self.apiclient, - self.services["domain1"] - ) - self.domain_2 = Domain.create( - self.apiclient, - self.services["domain2"] - ) - # Create two accounts for doamin_1 - self.account_1A = Account.create( - self.apiclient, - self.services["account1A"], - admin=False, - domainid=self.domain_1.id - ) - - self.account_1B = Account.create( - self.apiclient, - self.services["account1B"], - admin=False, - domainid=self.domain_1.id - ) - - # Create an account for domain_2 - self.account_2A = Account.create( - self.apiclient, - self.services["account2A"], - admin=False, - domainid=self.domain_2.id - ) - - # Fetch user details to register apiKey for them - self.user_1A = User.list( - self.apiclient, - account=self.account_1A.name, - domainid=self.account_1A.domainid - )[0] - - user_1A_key = User.registerUserKeys( - self.apiclient, - self.user_1A.id - ) - self.user_1A_apikey = user_1A_key.apikey - self.user_1A_secretkey = user_1A_key.secretkey - - - self.user_1B = User.list( - self.apiclient, - account=self.account_1B.name, - domainid=self.account_1B.domainid - )[0] - - user_1B_key = User.registerUserKeys( - self.apiclient, - self.user_1B.id - ) - - self.user_1B_apikey = user_1B_key.apikey - self.user_1B_secretkey = user_1B_key.secretkey - - - self.user_2A = User.list( - self.apiclient, - account=self.account_2A.name, - domainid=self.account_2A.domainid - )[0] - - user_2A_key = User.registerUserKeys( - self.apiclient, - self.user_2A.id - ) - self.user_2A_apikey = user_2A_key.apikey - self.user_2A_secretkey = user_2A_key.secretkey - - # create service offering - self.service_offering = ServiceOffering.create( - self.apiclient, - self.services["service_offering"]["small"] - ) - - self.zone = get_zone(self.apiclient, self.services) - self.services['mode'] = self.zone.networktype - self.template = get_template(self.apiclient, self.zone.id, self.services["ostype"]) - - # deploy 3 VMs for three accounts - self.virtual_machine_1A = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine1A"], - accountid=self.account_1A.name, - zoneid=self.zone.id, - domainid=self.account_1A.domainid, - serviceofferingid=self.service_offering.id, - templateid=self.template.id - ) - - self.virtual_machine_1B = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine1B"], - accountid=self.account_1B.name, - zoneid=self.zone.id, - domainid=self.account_1B.domainid, - serviceofferingid=self.service_offering.id, - templateid=self.template.id - ) - - self.virtual_machine_2A = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine2A"], - accountid=self.account_2A.name, - zoneid=self.zone.id, - domainid=self.account_2A.domainid, - serviceofferingid=self.service_offering.id, - templateid=self.template.id - ) - - self.srv_desk_grp = IAMGroup.create( - self.apiclient, - self.services["service_desk_iam_grp"] - ) - - self.vm_read_policy = IAMPolicy.create( - self.apiclient, - self.services["vm_readonly_iam_policy"] - ) - - self.srv_desk_grp.attachPolicy( - self.apiclient, [self.vm_read_policy] - ) - - vm_grant_policy_params = {} - vm_grant_policy_params['name'] = "policyGrantVirtualMachine" + self.virtual_machine_1A.id - vm_grant_policy_params['description'] = "Policy to grant permission to VirtualMachine " + self.virtual_machine_1A.id - self.vm_grant_policy = IAMPolicy.create( - self.apiclient, - vm_grant_policy_params - ) - - self._cleanup = [ - self.account_1A, - self.account_1B, - self.domain_1, - self.account_2A, - self.domain_2, - self.service_offering, - self.vm_read_policy, - self.srv_desk_grp, - self.vm_grant_policy - ] - - @classmethod - def tearDownClass(self): - self.apiclient = super(TestVMIam, self).getClsTestClient().getApiClient() - cleanup_resources(self.apiclient, self._cleanup) - return - - def setUp(self): - self.apiclient = self.testClient.getApiClient() - self.dbclient = self.testClient.getDbConnection() - self.cleanup = [] - - def tearDown(self): - # restore back default apikey and secretkey - self.apiclient.connection.apiKey = self.default_apikey - self.apiclient.connection.securityKey = self.default_secretkey - cleanup_resources(self.apiclient, self.cleanup) - return - - - - @attr(tags = ["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"]) - def test_01_list_own_vm(self): - # listVM command should return owne's VM - - self.debug("Listing VM for account: %s" % self.account_1A.name) - - self.apiclient.connection.apiKey = self.user_1A_apikey - self.apiclient.connection.securityKey = self.user_1A_secretkey - list_vm_response = list_virtual_machines( - self.apiclient - ) - self.assertEqual( - isinstance(list_vm_response, list), - True, - "Check list response returns a valid list" - ) - self.assertEqual( - len(list_vm_response), - 1, - "Check VM available in List Virtual Machines" - ) - - self.assertEqual( - list_vm_response[0].name, - self.virtual_machine_1A.name, - "Virtual Machine names do not match" - ) - - self.debug("Listing VM for account: %s" % self.account_1B.name) - self.apiclient.connection.apiKey = self.user_1B_apikey - self.apiclient.connection.securityKey = self.user_1B_secretkey - list_vm_response = list_virtual_machines( - self.apiclient - ) - self.assertEqual( - isinstance(list_vm_response, list), - True, - "Check list response returns a valid list" - ) - self.assertEqual( - len(list_vm_response), - 1, - "Check VM available in List Virtual Machines" - ) - - self.assertEqual( - list_vm_response[0].name, - self.virtual_machine_1B.name, - "Virtual Machine names do not match" - ) - - self.debug("Listing VM for account: %s" % self.account_2A.name) - - self.apiclient.connection.apiKey = self.user_2A_apikey - self.apiclient.connection.securityKey = self.user_2A_secretkey - list_vm_response = list_virtual_machines( - self.apiclient - ) - self.assertEqual( - isinstance(list_vm_response, list), - True, - "Check list response returns a valid list" - ) - self.assertEqual( - len(list_vm_response), - 1, - "Check VM available in List Virtual Machines" - ) - - self.assertEqual( - list_vm_response[0].name, - self.virtual_machine_2A.name, - "Virtual Machine names do not match" - ) - - return - - @attr(tags = ["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"]) - def test_02_grant_domain_vm(self): - - # Validate the following - # 1. Grant domain2 VM access to account_1B - # 2. listVM command should return account_1B and domain_2 VMs. - - self.debug("Granting Domain %s VM read only access to account: %s" % (self.domain_2.name, self.account_1B.name)) - - self.srv_desk_grp.addAccount(self.apiclient, [self.account_1B]) - domain_permission = {} - domain_permission['action'] = "listVirtualMachines" - domain_permission['entitytype'] = "VirtualMachine" - domain_permission['scope'] = "DOMAIN" - domain_permission['scopeid'] = self.domain_2.id - self.vm_read_policy.addPermission(self.apiclient, domain_permission) - - self.debug("Listing VM for account: %s" % self.account_1B.name) - self.apiclient.connection.apiKey = self.user_1B_apikey - self.apiclient.connection.securityKey = self.user_1B_secretkey - list_vm_response = list_virtual_machines( - self.apiclient - ) - self.assertEqual( - isinstance(list_vm_response, list), - True, - "Check list response returns a valid list" - ) - self.assertEqual( - len(list_vm_response), - 2, - "Check VM available in List Virtual Machines" - ) - - list_vm_names = [list_vm_response[0].name, list_vm_response[1].name] - - self.assertEqual( self.virtual_machine_1B.name in list_vm_names, - True, - "Accessible Virtual Machine names do not match" - ) - - self.assertEqual( self.virtual_machine_2A.name in list_vm_names, - True, - "Accessible Virtual Machine names do not match" - ) - - return - - - @attr(tags = ["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"]) - def test_03_grant_account_vm(self): - - # Validate the following - # 1. Grant account_1A VM access to account_1B - # 2. listVM command should return account_1A and account_1B VMs. - - self.debug("Granting Account %s VM read only access to account: %s" % (self.account_1A.name, self.account_1B.name)) - - account_permission = {} - account_permission['action'] = "listVirtualMachines" - account_permission['entitytype'] = "VirtualMachine" - account_permission['scope'] = "ACCOUNT" - account_permission['scopeid'] = self.account_1A.id - self.vm_read_policy.addPermission(self.apiclient, account_permission) - - self.debug("Listing VM for account: %s" % self.account_1B.name) - self.apiclient.connection.apiKey = self.user_1B_apikey - self.apiclient.connection.securityKey = self.user_1B_secretkey - list_vm_response = list_virtual_machines( - self.apiclient - ) - self.assertEqual( - isinstance(list_vm_response, list), - True, - "Check list response returns a valid list" - ) - self.assertEqual( - len(list_vm_response), - 3, - "Check VM available in List Virtual Machines" - ) - - list_vm_names = [list_vm_response[0].name, list_vm_response[1].name, list_vm_response[2].name] - - self.assertEqual( self.virtual_machine_1B.name in list_vm_names, - True, - "Accessible Virtual Machine names do not match" - ) - - self.assertEqual( self.virtual_machine_1A.name in list_vm_names, - True, - "Accessible Virtual Machine names do not match" - ) - - self.assertEqual( self.virtual_machine_2A.name in list_vm_names, - True, - "Accessible Virtual Machine names do not match" - ) - - return - - - @attr(tags = ["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"]) - def test_04_revoke_account_vm(self): - - # Validate the following - # 1. Revoke account_1A VM access from account_1B - # 2. listVM command should not return account_1A VMs. - - self.debug("Revoking Account %s VM read only access from account: %s" % (self.account_1A.name, self.account_1B.name)) - - account_permission = {} - account_permission['action'] = "listVirtualMachines" - account_permission['entitytype'] = "VirtualMachine" - account_permission['scope'] = "ACCOUNT" - account_permission['scopeid'] = self.account_1A.id - self.vm_read_policy.removePermission(self.apiclient, account_permission) - - self.debug("Listing VM for account: %s" % self.account_1B.name) - self.apiclient.connection.apiKey = self.user_1B_apikey - self.apiclient.connection.securityKey = self.user_1B_secretkey - list_vm_response = list_virtual_machines( - self.apiclient - ) - self.assertEqual( - isinstance(list_vm_response, list), - True, - "Check list response returns a valid list" - ) - self.assertEqual( - len(list_vm_response), - 2, - "Check VM available in List Virtual Machines" - ) - - list_vm_names = [list_vm_response[0].name, list_vm_response[1].name] - - - self.assertEqual( self.virtual_machine_1A.name in list_vm_names, - False, - "Accessible Virtual Machine names do not match" - ) - return - - - @attr(tags = ["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"]) - def test_05_revoke_domain_vm(self): - - # Validate the following - # 1. Revoke account_1A VM access from account_1B - # 2. listVM command should not return account_1A VMs. - - self.debug("Revoking Domain %s VM read only access from account: %s" % (self.domain_1.name, self.account_1B.name)) - - domain_permission = {} - domain_permission['action'] = "listVirtualMachines" - domain_permission['entitytype'] = "VirtualMachine" - domain_permission['scope'] = "DOMAIN" - domain_permission['scopeid'] = self.domain_2.id - self.vm_read_policy.removePermission(self.apiclient, domain_permission) - - self.debug("Listing VM for account: %s" % self.account_1B.name) - self.apiclient.connection.apiKey = self.user_1B_apikey - self.apiclient.connection.securityKey = self.user_1B_secretkey - list_vm_response = list_virtual_machines( - self.apiclient - ) - self.assertEqual( - isinstance(list_vm_response, list), - True, - "Check list response returns a valid list" - ) - self.assertEqual( - len(list_vm_response), - 1, - "Check VM available in List Virtual Machines" - ) - - self.assertEqual( - list_vm_response[0].name, - self.virtual_machine_1B.name, - "Virtual Machine names do not match" - ) - - return - - @attr(tags = ["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"]) - def test_06_grant_resource_vm(self): - - # Validate the following - # 1. Grant a particular vm access to account_1B - # 2. listVM command should return account_1B VMs and granted VM. - - self.debug("Granting VM %s read only access to account: %s" % (self.virtual_machine_1A.name, self.account_1B.name)) - - res_permission = {} - res_permission['action'] = "listVirtualMachines" - res_permission['entitytype'] = "VirtualMachine" - res_permission['scope'] = "RESOURCE" - res_permission['scopeid'] = self.virtual_machine_1A.id - self.vm_read_policy.addPermission(self.apiclient, res_permission) - - self.debug("Listing VM for account: %s" % self.account_1B.name) - self.apiclient.connection.apiKey = self.user_1B_apikey - self.apiclient.connection.securityKey = self.user_1B_secretkey - list_vm_response = list_virtual_machines( - self.apiclient - ) - self.assertEqual( - isinstance(list_vm_response, list), - True, - "Check list response returns a valid list" - ) - self.assertEqual( - len(list_vm_response), - 2, - "Check VM available in List Virtual Machines" - ) - - list_vm_names = [list_vm_response[0].name, list_vm_response[1].name] - - self.assertEqual( self.virtual_machine_1B.name in list_vm_names, - True, - "Accessible Virtual Machine names do not match" - ) - - self.assertEqual( self.virtual_machine_1A.name in list_vm_names, - True, - "Accessible Virtual Machine names do not match" - ) - - return - - @attr(tags = ["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"]) - def test_07_revoke_resource_vm(self): - - # Validate the following - # 1. Grant a particular vm access to account_1B - # 2. listVM command should return account_1B VMs and granted VM. - - self.debug("Revoking VM %s read only access from account: %s" % (self.virtual_machine_1A.name, self.account_1B.name)) - - res_permission = {} - res_permission['action'] = "listVirtualMachines" - res_permission['entitytype'] = "VirtualMachine" - res_permission['scope'] = "RESOURCE" - res_permission['scopeid'] = self.virtual_machine_1A.id - self.vm_read_policy.removePermission(self.apiclient, res_permission) - - self.debug("Listing VM for account: %s" % self.account_1B.id) - self.apiclient.connection.apiKey = self.user_1B_apikey - self.apiclient.connection.securityKey = self.user_1B_secretkey - list_vm_response = list_virtual_machines( - self.apiclient - ) - self.assertEqual( - isinstance(list_vm_response, list), - True, - "Check list response returns a valid list" - ) - self.assertEqual( - len(list_vm_response), - 1, - "Check VM available in List Virtual Machines" - ) - - self.assertEqual( - list_vm_response[0].name, - self.virtual_machine_1B.name, - "Virtual Machine names do not match" - ) - - return - - - @attr(tags = ["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"]) - def test_08_policy_attach_account(self): - - # Validate the following - # 1. Grant a particular vm access to account_1B by directly attaching policy to account - # 2. listVM command should return account_1B VMs and granted VM. - - self.debug("Granting VM %s read only access to account: %s by attaching policy to account" % (self.virtual_machine_1A.name, self.account_1B.name)) - - res_permission = {} - res_permission['action'] = "listVirtualMachines" - res_permission['entitytype'] = "VirtualMachine" - res_permission['scope'] = "RESOURCE" - res_permission['scopeid'] = self.virtual_machine_1A.id - self.vm_grant_policy.addPermission(self.apiclient, res_permission) - self.vm_grant_policy.attachAccount(self.apiclient, [self.account_1B]) - - self.debug("Listing VM for account: %s" % self.account_1B.id) - self.apiclient.connection.apiKey = self.user_1B_apikey - self.apiclient.connection.securityKey = self.user_1B_secretkey - list_vm_response = list_virtual_machines( - self.apiclient - ) - self.assertEqual( - isinstance(list_vm_response, list), - True, - "Check list response returns a valid list" - ) - self.assertEqual( - len(list_vm_response), - 2, - "Check VM available in List Virtual Machines" - ) - - list_vm_names = [list_vm_response[0].name, list_vm_response[1].name] - - self.assertEqual( self.virtual_machine_1B.name in list_vm_names, - True, - "Accessible Virtual Machine names do not match" - ) - - self.assertEqual( self.virtual_machine_1A.name in list_vm_names, - True, - "Accessible Virtual Machine names do not match" - ) - - return - - @attr(tags = ["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"]) - def test_09_policy_detach_account(self): - - # Validate the following - # 1. Revoking a particular vm access from account_1B by detaching policy from account - # 2. listVM command should return account_1B VMs. - - self.debug("Revoking VM %s read only access from account: %s by detaching policy from account" % (self.virtual_machine_1A.name, self.account_1B.name)) - - self.vm_grant_policy.detachAccount(self.apiclient, [self.account_1B]) - - self.debug("Listing VM for account: %s" % self.account_1B.id) - self.apiclient.connection.apiKey = self.user_1B_apikey - self.apiclient.connection.securityKey = self.user_1B_secretkey - list_vm_response = list_virtual_machines( - self.apiclient - ) - self.assertEqual( - isinstance(list_vm_response, list), - True, - "Check list response returns a valid list" - ) - self.assertEqual( - len(list_vm_response), - 1, - "Check VM available in List Virtual Machines" - ) - - self.assertEqual( - list_vm_response[0].name, - self.virtual_machine_1B.name, - "Virtual Machine names do not match" - ) - - return \ No newline at end of file diff --git a/test/integration/smoke/test_vm_life_cycle.py b/test/integration/smoke/test_vm_life_cycle.py index c164f59985..240ab68922 100644 --- a/test/integration/smoke/test_vm_life_cycle.py +++ b/test/integration/smoke/test_vm_life_cycle.py @@ -18,138 +18,40 @@ """ #Import Local Modules from marvin.cloudstackTestCase import cloudstackTestCase -from marvin.cloudstackAPI import (detachIso, +from marvin.cloudstackAPI import (recoverVirtualMachine, + destroyVirtualMachine, attachIso, - recoverVirtualMachine, - destroyVirtualMachine) -from marvin.integration.lib.utils import (cleanup_resources, - validateList, - get_hypervisor_type) -from marvin.integration.lib.base import (Account, - ServiceOffering, - VirtualMachine, - Iso, - Host) -from marvin.integration.lib.common import (get_domain, - get_zone, - get_template, - list_virtual_machines, - list_configurations, - list_routers, - list_isos) -from marvin.codes import PASS + detachIso) +from marvin.lib.utils import (cleanup_resources, + validateList, + get_hypervisor_type) +from marvin.lib.base import (Account, + ServiceOffering, + VirtualMachine, + Host, + Iso, + Router, + Configurations) +from marvin.lib.common import (get_domain, + get_zone, + get_template) +from marvin.codes import FAILED, PASS from nose.plugins.attrib import attr #Import System modules import time _multiprocess_shared_ = True -class Services: - """Test VM Life Cycle Services - """ - - def __init__(self): - self.services = { - "disk_offering":{ - "displaytext": "Small", - "name": "Small", - "disksize": 1 - }, - "account": { - "email": "test@test.com", - "firstname": "Test", - "lastname": "User", - "username": "test", - # Random characters are appended in create account to - # ensure unique username generated each time - "password": "password", - }, - "small": - # Create a small virtual machine instance with disk offering - { - "displayname": "testserver", - "username": "root", # VM creds for SSH - "password": "password", - "ssh_port": 22, - "hypervisor": 'XenServer', - "privateport": 22, - "publicport": 22, - "protocol": 'TCP', - }, - "medium": # Create a medium virtual machine instance - { - "displayname": "testserver", - "username": "root", - "password": "password", - "ssh_port": 22, - "hypervisor": 'XenServer', - "privateport": 22, - "publicport": 22, - "protocol": 'TCP', - }, - "service_offerings": - { - "tiny": - { - "name": "Tiny Instance", - "displaytext": "Tiny Instance", - "cpunumber": 1, - "cpuspeed": 100, # in MHz - "memory": 128, # In MBs - }, - "small": - { - # Small service offering ID to for change VM - # service offering from medium to small - "name": "Small Instance", - "displaytext": "Small Instance", - "cpunumber": 1, - "cpuspeed": 100, - "memory": 256, - }, - "medium": - { - # Medium service offering ID to for - # change VM service offering from small to medium - "name": "Medium Instance", - "displaytext": "Medium Instance", - "cpunumber": 1, - "cpuspeed": 100, - "memory": 256, - } - }, - "iso": # ISO settings for Attach/Detach ISO tests - { - "displaytext": "Test ISO", - "name": "testISO", - "url": "http://people.apache.org/~tsp/dummy.iso", - # Source URL where ISO is located - "ostype": 'CentOS 5.3 (64-bit)', - "mode": 'HTTP_DOWNLOAD', # Downloading existing ISO - }, - "template": { - "displaytext": "Cent OS Template", - "name": "Cent OS Template", - "passwordenabled": True, - }, - "diskdevice": ['/dev/vdc', '/dev/vdb', '/dev/hdb', '/dev/hdc', '/dev/xvdd', '/dev/cdrom', '/dev/sr0', '/dev/cdrom1' ], - # Disk device where ISO is attached to instance - "mount_dir": "/mnt/tmp", - "sleep": 60, - "timeout": 10, - #Migrate VM to hostid - "ostype": 'CentOS 5.3 (64-bit)', - # CentOS 5.3 (64-bit) - } - class TestDeployVM(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.services = Services().services - cls.apiclient = super(TestDeployVM, cls).getClsTestClient().getApiClient() + testClient = super(TestDeployVM, cls).getClsTestClient() + cls.apiclient = testClient.getApiClient() + cls.services = testClient.getParsedTestDataConfig() + # Get Zone, Domain and templates - domain = get_domain(cls.apiclient, cls.services) - cls.zone = get_zone(cls.apiclient, cls.services) + domain = get_domain(cls.apiclient) + cls.zone = get_zone(cls.apiclient, testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype #If local storage is enabled, alter the offerings to use localstorage @@ -164,13 +66,16 @@ def setUpClass(cls): cls.zone.id, cls.services["ostype"] ) + if template == FAILED: + assert False, "get_template() failed to return template with description %s" % cls.services["ostype"] + # Set Zones and disk offerings cls.services["small"]["zoneid"] = cls.zone.id cls.services["small"]["template"] = template.id cls.services["medium"]["zoneid"] = cls.zone.id cls.services["medium"]["template"] = template.id - cls.services["iso"]["zoneid"] = cls.zone.id + cls.services["iso1"]["zoneid"] = cls.zone.id cls.account = Account.create( cls.apiclient, @@ -210,14 +115,14 @@ def setUp(self): self.dbclient = self.testClient.getDbConnection() - @attr(tags = ["simulator", "devcloud", "advanced", "advancedns", "smoke", "basic", "sg"]) + @attr(tags = ["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="false") def test_deploy_vm(self): """Test Deploy Virtual Machine """ # Validate the following: # 1. Virtual Machine is accessible via SSH # 2. listVirtualMachines returns accurate information - list_vm_response = list_virtual_machines( + list_vm_response = VirtualMachine.list( self.apiclient, id=self.virtual_machine.id ) @@ -256,8 +161,9 @@ def test_deploy_vm(self): return - @attr(tags = ["simulator", "advanced"]) + @attr(tags = ["advanced"], required_hardware="false") def test_advZoneVirtualRouter(self): + #TODO: SIMENH: duplicate test, remove it """ Test advanced zone virtual router 1. Is Running @@ -265,7 +171,7 @@ def test_advZoneVirtualRouter(self): 3. Has a linklocalip, publicip and a guestip @return: """ - routers = list_routers(self.apiclient, account=self.account.name) + routers = Router.list(self.apiclient, account=self.account.name, listall=True) self.assertTrue(len(routers) > 0, msg = "No virtual router found") router = routers[0] @@ -277,16 +183,17 @@ def test_advZoneVirtualRouter(self): self.assertIsNotNone(router.publicip, msg="Router has no public ip") self.assertIsNotNone(router.guestipaddress, msg="Router has no guest ip") - @attr(hypervisor = ["simulator"]) - @attr(mode = ["basic"]) + + @attr(mode = ["basic"], required_hardware="false") def test_basicZoneVirtualRouter(self): + #TODO: SIMENH: duplicate test, remove it """ Tests for basic zone virtual router 1. Is Running 2. is in the account the VM was deployed in @return: """ - routers = list_routers(self.apiclient, account=self.account.name) + routers = Router.list(self.apiclient, account=self.account.name, listall=True) self.assertTrue(len(routers) > 0, msg = "No virtual router found") router = routers[0] @@ -301,12 +208,13 @@ class TestVMLifeCycle(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestVMLifeCycle, cls).getClsTestClient().getApiClient() - cls.services = Services().services + testClient = super(TestVMLifeCycle, cls).getClsTestClient() + cls.apiclient = testClient.getApiClient() + cls.services = testClient.getParsedTestDataConfig() # Get Zone, Domain and templates - domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + domain = get_domain(cls.apiclient) + cls.zone = get_zone(cls.apiclient, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype #if local storage is enabled, alter the offerings to use localstorage @@ -317,37 +225,40 @@ def setUpClass(cls): cls.services["service_offerings"]["medium"]["storagetype"] = 'local' template = get_template( - cls.api_client, + cls.apiclient, cls.zone.id, cls.services["ostype"] ) + if template == FAILED: + assert False, "get_template() failed to return template with description %s" % cls.services["ostype"] + # Set Zones and disk offerings cls.services["small"]["zoneid"] = cls.zone.id cls.services["small"]["template"] = template.id cls.services["medium"]["zoneid"] = cls.zone.id cls.services["medium"]["template"] = template.id - cls.services["iso"]["zoneid"] = cls.zone.id + cls.services["iso1"]["zoneid"] = cls.zone.id # Create VMs, NAT Rules etc cls.account = Account.create( - cls.api_client, + cls.apiclient, cls.services["account"], domainid=domain.id ) cls.small_offering = ServiceOffering.create( - cls.api_client, + cls.apiclient, cls.services["service_offerings"]["small"] ) cls.medium_offering = ServiceOffering.create( - cls.api_client, + cls.apiclient, cls.services["service_offerings"]["medium"] ) #create small and large virtual machines cls.small_virtual_machine = VirtualMachine.create( - cls.api_client, + cls.apiclient, cls.services["small"], accountid=cls.account.name, domainid=cls.account.domainid, @@ -355,7 +266,7 @@ def setUpClass(cls): mode=cls.services["mode"] ) cls.medium_virtual_machine = VirtualMachine.create( - cls.api_client, + cls.apiclient, cls.services["medium"], accountid=cls.account.name, domainid=cls.account.domainid, @@ -363,7 +274,7 @@ def setUpClass(cls): mode=cls.services["mode"] ) cls.virtual_machine = VirtualMachine.create( - cls.api_client, + cls.apiclient, cls.services["small"], accountid=cls.account.name, domainid=cls.account.domainid, @@ -378,8 +289,8 @@ def setUpClass(cls): @classmethod def tearDownClass(cls): - cls.api_client = super(TestVMLifeCycle, cls).getClsTestClient().getApiClient() - cleanup_resources(cls.api_client, cls._cleanup) + cls.apiclient = super(TestVMLifeCycle, cls).getClsTestClient().getApiClient() + cleanup_resources(cls.apiclient, cls._cleanup) return def setUp(self): @@ -393,7 +304,7 @@ def tearDown(self): return - @attr(tags = ["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"]) + @attr(tags = ["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="false", BugId="6984") def test_01_stop_vm(self): """Test Stop Virtual Machine """ @@ -402,34 +313,13 @@ def test_01_stop_vm(self): # 1. Should Not be able to login to the VM. # 2. listVM command should return # this VM.State of this VM should be ""Stopped"". - - self.debug("Stopping VM - ID: %s" % self.virtual_machine.id) - self.small_virtual_machine.stop(self.apiclient) - - list_vm_response = list_virtual_machines( - self.apiclient, - id=self.small_virtual_machine.id - ) - - self.assertEqual( - isinstance(list_vm_response, list), - True, - "Check list response returns a valid list" - ) - self.assertNotEqual( - len(list_vm_response), - 0, - "Check VM available in List Virtual Machines" - ) - - self.assertEqual( - list_vm_response[0].state, - "Stopped", - "Check virtual machine is in stopped state" - ) + try: + self.small_virtual_machine.stop(self.apiclient) + except Exception as e: + self.fail("Failed to stop VM: %s" % e) return - @attr(tags = ["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"]) + @attr(tags = ["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="false") def test_02_start_vm(self): """Test Start Virtual Machine """ @@ -440,7 +330,7 @@ def test_02_start_vm(self): self.debug("Starting VM - ID: %s" % self.virtual_machine.id) self.small_virtual_machine.start(self.apiclient) - list_vm_response = list_virtual_machines( + list_vm_response = VirtualMachine.list( self.apiclient, id=self.small_virtual_machine.id ) @@ -467,7 +357,7 @@ def test_02_start_vm(self): ) return - @attr(tags = ["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"]) + @attr(tags = ["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="false") def test_03_reboot_vm(self): """Test Reboot Virtual Machine """ @@ -480,7 +370,7 @@ def test_03_reboot_vm(self): self.debug("Rebooting VM - ID: %s" % self.virtual_machine.id) self.small_virtual_machine.reboot(self.apiclient) - list_vm_response = list_virtual_machines( + list_vm_response = VirtualMachine.list( self.apiclient, id=self.small_virtual_machine.id ) @@ -504,7 +394,7 @@ def test_03_reboot_vm(self): return - @attr(tags = ["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"]) + @attr(tags = ["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="false") def test_06_destroy_vm(self): """Test destroy Virtual Machine """ @@ -517,7 +407,7 @@ def test_06_destroy_vm(self): self.debug("Destroy VM - ID: %s" % self.small_virtual_machine.id) self.small_virtual_machine.delete(self.apiclient) - list_vm_response = list_virtual_machines( + list_vm_response = VirtualMachine.list( self.apiclient, id=self.small_virtual_machine.id ) @@ -540,8 +430,9 @@ def test_06_destroy_vm(self): ) return - @attr(tags = ["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"]) + @attr(tags = ["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="false") def test_07_restore_vm(self): + #TODO: SIMENH: add another test the data on the restored VM. """Test recover Virtual Machine """ @@ -556,7 +447,7 @@ def test_07_restore_vm(self): cmd.id = self.small_virtual_machine.id self.apiclient.recoverVirtualMachine(cmd) - list_vm_response = list_virtual_machines( + list_vm_response = VirtualMachine.list( self.apiclient, id=self.small_virtual_machine.id ) @@ -580,7 +471,7 @@ def test_07_restore_vm(self): return - @attr(tags = ["advanced", "advancedns", "smoke", "basic", "sg", "multihost"]) + @attr(tags = ["advanced", "advancedns", "smoke", "basic", "sg", "multihost"], required_hardware="false") def test_08_migrate_vm(self): """Test migrate VM """ @@ -607,14 +498,14 @@ def test_08_migrate_vm(self): # For XenServer and VMware, migration is possible between hosts belonging to different clusters # with the help of XenMotion and Vmotion respectively. - if hypervisor == "kvm": + if hypervisor.lower() in ["kvm","simulator"]: #identify suitable host clusters = [h.clusterid for h in hosts] #find hosts withe same clusterid clusters = [cluster for index, cluster in enumerate(clusters) if clusters.count(cluster) > 1] if len(clusters) <= 1: - self.skipTest("In KVM, Live Migration needs two hosts within same cluster") + self.skipTest("In " + hypervisor.lower() + " Live Migration needs two hosts within same cluster") suitable_hosts = [host for host in hosts if host.clusterid == clusters[0]] else: @@ -625,7 +516,7 @@ def test_08_migrate_vm(self): #deploy VM on target host self.vm_to_migrate = VirtualMachine.create( - self.api_client, + self.apiclient, self.services["small"], accountid=self.account.name, domainid=self.account.domainid, @@ -638,36 +529,26 @@ def test_08_migrate_vm(self): migrate_host.id )) - self.vm_to_migrate.migrate(self.api_client, migrate_host.id) - - list_vm_response = list_virtual_machines( - self.apiclient, - id=self.vm_to_migrate.id - ) - self.assertNotEqual( - list_vm_response, - None, - "Check virtual machine is listed" - ) - - vm_response = list_vm_response[0] - - self.assertEqual( - vm_response.id, - self.vm_to_migrate.id, - "Check virtual machine ID of migrated VM" - ) - - self.assertEqual( - vm_response.hostid, - migrate_host.id, - "Check destination hostID of migrated VM" - ) + self.vm_to_migrate.migrate(self.apiclient, migrate_host.id) + + retries_cnt = 3 + while retries_cnt >=0: + list_vm_response = VirtualMachine.list(self.apiclient, + id=self.vm_to_migrate.id) + self.assertNotEqual( + list_vm_response, + None, + "Check virtual machine is listed" + ) + vm_response = list_vm_response[0] + self.assertEqual(vm_response.id,self.vm_to_migrate.id,"Check virtual machine ID of migrated VM") + self.assertEqual(vm_response.hostid,migrate_host.id,"Check destination hostID of migrated VM") + retries_cnt = retries_cnt - 1 return @attr(configuration = "expunge.interval") @attr(configuration = "expunge.delay") - @attr(tags = ["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"]) + @attr(tags = ["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"], BugId="CLOUDSTACK-6738", required_hardware="false") def test_09_expunge_vm(self): """Test destroy(expunge) Virtual Machine """ @@ -680,7 +561,7 @@ def test_09_expunge_vm(self): cmd.id = self.small_virtual_machine.id self.apiclient.destroyVirtualMachine(cmd) - config = list_configurations( + config = Configurations.list( self.apiclient, name='expunge.delay' ) @@ -690,33 +571,29 @@ def test_09_expunge_vm(self): #VM should be destroyed unless expunge thread hasn't run #Wait for two cycles of the expunge thread - config = list_configurations( + config = Configurations.list( self.apiclient, name='expunge.interval' ) expunge_cycle = int(config[0].value) - wait_time = expunge_cycle * 2 + wait_time = expunge_cycle * 4 while wait_time >= 0: - list_vm_response = list_virtual_machines( + list_vm_response = VirtualMachine.list( self.apiclient, id=self.small_virtual_machine.id ) - if list_vm_response: - time.sleep(expunge_cycle) - wait_time = wait_time - expunge_cycle - else: + if not list_vm_response: break + self.debug("Waiting for VM to expunge") + time.sleep(expunge_cycle) + wait_time = wait_time - expunge_cycle self.debug("listVirtualMachines response: %s" % list_vm_response) - self.assertEqual( - list_vm_response, - None, - "Check Expunged virtual machine is in listVirtualMachines response" - ) + self.assertEqual(list_vm_response,None,"Check Expunged virtual machine is in listVirtualMachines response") return - @attr(tags = ["advanced", "advancedns", "smoke", "basic", "sg"]) + @attr(tags = ["advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="true", BugId="CLOUDSTACK-6985") def test_10_attachAndDetach_iso(self): """Test for attach and detach ISO to virtual machine""" @@ -730,7 +607,7 @@ def test_10_attachAndDetach_iso(self): iso = Iso.create( self.apiclient, - self.services["iso"], + self.services["iso1"], account=self.account.name, domainid=self.account.domainid ) @@ -758,11 +635,12 @@ def test_10_attachAndDetach_iso(self): self.fail("SSH failed for virtual machine: %s - %s" % (self.virtual_machine.ipaddress, e)) - cmds = "mkdir -p %s" % self.services["mount_dir"] + mount_dir = "/mnt/tmp" + cmds = "mkdir -p %s" % mount_dir self.assert_(ssh_client.execute(cmds) == [], "mkdir failed within guest") for diskdevice in self.services["diskdevice"]: - res = ssh_client.execute("mount -rt iso9660 {} {}".format(diskdevice, self.services["mount_dir"])) + res = ssh_client.execute("mount -rt iso9660 {} {}".format(diskdevice, mount_dir)) if res == []: self.services["mount"] = diskdevice break @@ -775,7 +653,7 @@ def test_10_attachAndDetach_iso(self): self.debug("Found a mount point at %s with size %s" % (res, size)) # Get ISO size - iso_response = list_isos( + iso_response = Iso.list( self.apiclient, id=iso.id ) @@ -787,7 +665,7 @@ def test_10_attachAndDetach_iso(self): try: #Unmount ISO - command = "umount %s" % self.services["mount_dir"] + command = "umount %s" % mount_dir ssh_client.execute(command) except Exception as e: self.fail("SSH failed for virtual machine: %s - %s" % diff --git a/test/integration/smoke/test_vm_snapshots.py b/test/integration/smoke/test_vm_snapshots.py index b49a37c45b..01626f5c1b 100644 --- a/test/integration/smoke/test_vm_snapshots.py +++ b/test/integration/smoke/test_vm_snapshots.py @@ -16,83 +16,45 @@ # under the License. # Import Local Modules -import marvin +from marvin.codes import FAILED, KVM from nose.plugins.attrib import attr -from marvin.cloudstackTestCase import * -from marvin.cloudstackAPI import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * - -class Services: - """Test Snapshots Services - """ - - def __init__(self): - self.services = { - "account": { - "email": "test@test.com", - "firstname": "Test", - "lastname": "User", - "username": "test", - # Random characters are appended for unique - # username - "password": "password", - }, - "service_offering": { - "name": "Tiny Instance", - "displaytext": "Tiny Instance", - "cpunumber": 1, - "cpuspeed": 200, # in MHz - "memory": 256, # In MBs - }, - "server": { - "displayname": "TestVM", - "username": "root", - "password": "password", - "ssh_port": 22, - "hypervisor": 'XenServer', - "privateport": 22, - "publicport": 22, - "protocol": 'TCP', - }, - "mgmt_server": { - "ipaddress": '1.2.2.152', - "username": "root", - "password": "password", - "port": 22, - }, - "templates": { - "displaytext": 'Template', - "name": 'Template', - "ostype": "CentOS 5.3 (64-bit)", - "templatefilter": 'self', - }, - "test_dir": "/tmp", - "random_data": "random.data", - "snapshot_name": "TestSnapshot", - "snapshot_displaytext": "Test", - "ostype": "CentOS 5.3 (64-bit)", - "sleep": 60, - "timeout": 10, - "mode": 'advanced', # Networking mode: Advanced, Basic - } +from marvin.cloudstackTestCase import cloudstackTestCase, unittest +from marvin.cloudstackAPI import startVirtualMachine +from marvin.lib.utils import random_gen, cleanup_resources +from marvin.lib.base import (Account, + ServiceOffering, + VirtualMachine, + VmSnapshot) +from marvin.lib.common import (get_zone, + get_domain, + get_template, + list_virtual_machines) +import time class TestVmSnapshot(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestVmSnapshot, cls).getClsTestClient().getApiClient() - cls.services = Services().services + testClient = super(TestVmSnapshot, cls).getClsTestClient() + + hypervisor = testClient.getHypervisorInfo() + if hypervisor.lower() == KVM.lower(): + raise unittest.SkipTest("VM snapshot feature is not supported on KVM") + + cls.apiclient = testClient.getApiClient() + cls.services = testClient.getParsedTestDataConfig() # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.apiclient) + cls.zone = get_zone(cls.apiclient, testClient.getZoneForTests()) template = get_template( - cls.api_client, + cls.apiclient, cls.zone.id, cls.services["ostype"] ) + if template == FAILED: + assert False, "get_template() failed to return template with description %s" % cls.services["ostype"] + cls.services["domainid"] = cls.domain.id cls.services["server"]["zoneid"] = cls.zone.id cls.services["templates"]["ostypeid"] = template.ostypeid @@ -100,27 +62,27 @@ def setUpClass(cls): # Create VMs, NAT Rules etc cls.account = Account.create( - cls.api_client, + cls.apiclient, cls.services["account"], domainid=cls.domain.id ) - cls.services["account"] = cls.account.name - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] + cls.apiclient, + cls.services["service_offerings"] ) cls.virtual_machine = VirtualMachine.create( - cls.api_client, + cls.apiclient, cls.services["server"], templateid=template.id, accountid=cls.account.name, domainid=cls.account.domainid, serviceofferingid=cls.service_offering.id, - mode=cls.services["mode"] + mode=cls.zone.networktype ) cls.random_data_0 = random_gen(size=100) + cls.test_dir = "/tmp" + cls.random_data = "random.data" cls._cleanup = [ cls.service_offering, cls.account, @@ -131,7 +93,7 @@ def setUpClass(cls): def tearDownClass(cls): try: # Cleanup resources used - cleanup_resources(cls.api_client, cls._cleanup) + cleanup_resources(cls.apiclient, cls._cleanup) except Exception as e: raise Exception("Warning: Exception during cleanup : %s" % e) return @@ -150,7 +112,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags=["advanced", "advancedns", "smoke"]) + @attr(tags=["advanced", "advancedns", "smoke"], required_hardware="true") def test_01_create_vm_snapshots(self): """Test to create VM snapshots """ @@ -160,8 +122,8 @@ def test_01_create_vm_snapshots(self): ssh_client = self.virtual_machine.get_ssh_client() cmds = [ - "echo %s > %s/%s" % (self.random_data_0, self.services["test_dir"], self.services["random_data"]), - "cat %s/%s" % (self.services["test_dir"], self.services["random_data"]) + "echo %s > %s/%s" % (self.random_data_0, self.test_dir, self.random_data), + "cat %s/%s" % (self.test_dir, self.random_data) ] for c in cmds: @@ -184,8 +146,8 @@ def test_01_create_vm_snapshots(self): self.apiclient, self.virtual_machine.id, "false", - self.services["snapshot_name"], - self.services["snapshot_displaytext"] + "TestSnapshot", + "Dsiplay Text" ) self.assertEqual( vm_snapshot.state, @@ -194,7 +156,7 @@ def test_01_create_vm_snapshots(self): ) return - @attr(tags=["advanced", "advancedns", "smoke"]) + @attr(tags=["advanced", "advancedns", "smoke"], required_hardware="true") def test_02_revert_vm_snapshots(self): """Test to revert VM snapshots """ @@ -203,8 +165,8 @@ def test_02_revert_vm_snapshots(self): ssh_client = self.virtual_machine.get_ssh_client() cmds = [ - "rm -rf %s/%s" % (self.services["test_dir"], self.services["random_data"]), - "ls %s/%s" % (self.services["test_dir"], self.services["random_data"]) + "rm -rf %s/%s" % (self.test_dir, self.random_data), + "ls %s/%s" % (self.test_dir, self.random_data) ] for c in cmds: @@ -263,7 +225,7 @@ def test_02_revert_vm_snapshots(self): ssh_client = self.virtual_machine.get_ssh_client(reconnect=True) cmds = [ - "cat %s/%s" % (self.services["test_dir"], self.services["random_data"]) + "cat %s/%s" % (self.test_dir, self.random_data) ] for c in cmds: @@ -281,7 +243,7 @@ def test_02_revert_vm_snapshots(self): "Check the random data is equal with the ramdom file!" ) - @attr(tags=["advanced", "advancedns", "smoke"]) + @attr(tags=["advanced", "advancedns", "smoke"], required_hardware="true") def test_03_delete_vm_snapshots(self): """Test to delete vm snapshots """ diff --git a/test/integration/smoke/test_volumes.py b/test/integration/smoke/test_volumes.py index 8f41803638..70c9114233 100644 --- a/test/integration/smoke/test_volumes.py +++ b/test/integration/smoke/test_volumes.py @@ -17,14 +17,25 @@ """ BVT tests for Volumes """ #Import Local Modules -import marvin -from marvin.cloudstackTestCase import * -from marvin.cloudstackException import * -from marvin.cloudstackAPI import * -from marvin.sshClient import SshClient -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * +from marvin.cloudstackTestCase import cloudstackTestCase +#from marvin.cloudstackException import * +from marvin.cloudstackAPI import (deleteVolume, + extractVolume, + resizeVolume) +#from marvin.sshClient import SshClient +from marvin.lib.utils import (cleanup_resources, + format_volume_to_ext3) +from marvin.lib.base import (ServiceOffering, + VirtualMachine, + Account, + Volume, + Host, + DiskOffering) +from marvin.lib.common import (get_domain, + get_zone, + get_template) +from marvin.lib.utils import checkVolumeSize +from marvin.codes import SUCCESS, FAILED, XEN_SERVER from nose.plugins.attrib import attr #Import System modules import os @@ -34,103 +45,51 @@ _multiprocess_shared_ = True -class Services: - """Test Volume Services - """ - - def __init__(self): - self.services = { - "account": { - "email": "test@test.com", - "firstname": "Test", - "lastname": "User", - "username": "test", - # Random characters are appended for unique - # username - "password": "password", - }, - "service_offering": { - "name": "Tiny Instance", - "displaytext": "Tiny Instance", - "cpunumber": 1, - "cpuspeed": 100, # in MHz - "memory": 260 # In MBs - - }, - "disk_offering": { - "displaytext": "Small", - "name": "Small", - "disksize": 1 - }, - 'resized_disk_offering': { - "displaytext": "Resized", - "name": "Resized", - "disksize": 3 - }, - "volume_offerings": { - 0: { - "diskname": "TestDiskServ", - }, - }, - "customdisksize": 1, # GBs - "username": "root", # Creds for SSH to VM - "password": "password", - "ssh_port": 22, - "diskname": "TestDiskServ", - "hypervisor": 'KVM', - "privateport": 22, - "publicport": 22, - "protocol": 'TCP', - "ostype": 'CentOS 5.5 (64-bit)', - "sleep": 10, - "timeout": 600, - } - - class TestCreateVolume(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestCreateVolume, cls).getClsTestClient().getApiClient() - cls.services = Services().services - + testClient = super(TestCreateVolume, cls).getClsTestClient() + cls.apiclient = testClient.getApiClient() + cls.services = testClient.getParsedTestDataConfig() # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.apiclient) + cls.zone = get_zone(cls.apiclient, testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype cls.disk_offering = DiskOffering.create( - cls.api_client, + cls.apiclient, cls.services["disk_offering"] ) cls.custom_disk_offering = DiskOffering.create( - cls.api_client, + cls.apiclient, cls.services["disk_offering"], custom=True ) template = get_template( - cls.api_client, + cls.apiclient, cls.zone.id, cls.services["ostype"] ) + if template == FAILED: + assert False, "get_template() failed to return template with description %s" % cls.services["ostype"] + cls.services["domainid"] = cls.domain.id cls.services["zoneid"] = cls.zone.id cls.services["template"] = template.id cls.services["customdiskofferingid"] = cls.custom_disk_offering.id - + cls.services["diskname"] = cls.services["volume"]["diskname"] # Create VMs, NAT Rules etc cls.account = Account.create( - cls.api_client, + cls.apiclient, cls.services["account"], domainid=cls.domain.id ) - - cls.services["account"] = cls.account.name cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] + cls.apiclient, + cls.services["service_offerings"] ) cls.virtual_machine = VirtualMachine.create( - cls.api_client, + cls.apiclient, cls.services, accountid=cls.account.name, domainid=cls.account.domainid, @@ -150,7 +109,7 @@ def setUp(self): self.dbclient = self.testClient.getDbConnection() self.cleanup = [] - @attr(tags = ["advanced", "advancedns", "smoke", "basic"]) + @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="true") def test_01_create_volume(self): """Test Volume creation for all Disk Offerings (incl. custom) """ @@ -184,10 +143,9 @@ def test_01_create_volume(self): #Attach a volume with different disk offerings #and check the memory allocated to each of them for volume in self.volumes: - list_volume_response = list_volumes( - self.apiClient, - id=volume.id - ) + list_volume_response = Volume.list( + self.apiClient, + id=volume.id) self.assertEqual( isinstance(list_volume_response, list), True, @@ -221,13 +179,12 @@ def test_01_create_volume(self): time.sleep(self.services["sleep"]) # Ensure that VM is in running state - list_vm_response = list_virtual_machines( + list_vm_response = VirtualMachine.list( self.apiClient, id=self.virtual_machine.id ) if isinstance(list_vm_response, list): - vm = list_vm_response[0] if vm.state == 'Running': self.debug("VM state: %s" % vm.state) @@ -236,31 +193,30 @@ def test_01_create_volume(self): if timeout == 0: raise Exception( "Failed to start VM (ID: %s) " % vm.id) - timeout = timeout - 1 - try: - ssh = self.virtual_machine.get_ssh_client( + vol_sz = str(list_volume_response[0].size) + ssh = self.virtual_machine.get_ssh_client( reconnect=True ) - c = "/sbin/fdisk -l" - res = ssh.execute(c) - - except Exception as e: - self.fail("SSH access failed for VM: %s - %s" % - (self.virtual_machine.ipaddress, e)) - - # Disk /dev/sda doesn't contain a valid partition table - # Disk /dev/sda: 21.5 GB, 21474836480 bytes - result = str(res) - self.debug("fdisk result: %s" % result) - - self.assertEqual( - str(list_volume_response[0].size) in result, - True, - "Check if promised disk size actually available" - ) + # Get the updated volume information + list_volume_response = Volume.list( + self.apiClient, + id=volume.id) + if list_volume_response[0].hypervisor.lower() == XEN_SERVER.lower(): + volume_name = "/dev/xvd" + chr(ord('a') + int(list_volume_response[0].deviceid)) + self.debug(" Using XenServer volume_name: %s" % (volume_name)) + ret = checkVolumeSize(ssh_handle=ssh,volume_name=volume_name,size_to_verify=vol_sz) + elif list_volume_response[0].hypervisor.lower() == "kvm": + volume_name = "/dev/vd" + chr(ord('a') + int(list_volume_response[0].deviceid)) + self.debug(" Using KVM volume_name: %s" % (volume_name)) + ret = checkVolumeSize(ssh_handle=ssh,volume_name=volume_name,size_to_verify=vol_sz) + else: + ret = checkVolumeSize(ssh_handle=ssh,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") + time.sleep(self.services["sleep"]) def tearDown(self): #Clean up, terminate the created volumes @@ -270,8 +226,8 @@ def tearDown(self): @classmethod def tearDownClass(cls): try: - cls.api_client = super(TestCreateVolume, cls).getClsTestClient().getApiClient() - cleanup_resources(cls.api_client, cls._cleanup) + cls.apiclient = super(TestCreateVolume, cls).getClsTestClient().getApiClient() + cleanup_resources(cls.apiclient, cls._cleanup) except Exception as e: raise Exception("Warning: Exception during cleanup : %s" % e) @@ -280,31 +236,36 @@ class TestVolumes(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TestVolumes, cls).getClsTestClient().getApiClient() - cls.services = Services().services + testClient = super(TestVolumes, cls).getClsTestClient() + cls.apiclient = testClient.getApiClient() + cls.services = testClient.getParsedTestDataConfig() + # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.apiclient) + cls.zone = get_zone(cls.apiclient, testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype cls.disk_offering = DiskOffering.create( - cls.api_client, + cls.apiclient, cls.services["disk_offering"] ) cls.resized_disk_offering = DiskOffering.create( - cls.api_client, + cls.apiclient, cls.services["resized_disk_offering"] ) cls.custom_resized_disk_offering = DiskOffering.create( - cls.api_client, + cls.apiclient, cls.services["resized_disk_offering"], custom=True ) template = get_template( - cls.api_client, + cls.apiclient, cls.zone.id, cls.services["ostype"] ) + if template == FAILED: + assert False, "get_template() failed to return template with description %s" % cls.services["ostype"] + cls.services["domainid"] = cls.domain.id cls.services["zoneid"] = cls.zone.id cls.services["template"] = template.id @@ -314,18 +275,16 @@ def setUpClass(cls): # Create VMs, VMs etc cls.account = Account.create( - cls.api_client, + cls.apiclient, cls.services["account"], domainid=cls.domain.id ) - - cls.services["account"] = cls.account.name cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] + cls.apiclient, + cls.services["service_offerings"] ) cls.virtual_machine = VirtualMachine.create( - cls.api_client, + cls.apiclient, cls.services, accountid=cls.account.name, domainid=cls.account.domainid, @@ -334,7 +293,7 @@ def setUpClass(cls): ) cls.volume = Volume.create( - cls.api_client, + cls.apiclient, cls.services, account=cls.account.name, domainid=cls.account.domainid @@ -351,7 +310,7 @@ def setUpClass(cls): @classmethod def tearDownClass(cls): try: - cleanup_resources(cls.api_client, cls._cleanup) + cleanup_resources(cls.apiclient, cls._cleanup) except Exception as e: raise Exception("Warning: Exception during cleanup : %s" % e) @@ -368,7 +327,7 @@ def tearDown(self): cleanup_resources(self.apiClient, self.cleanup) return - @attr(tags = ["advanced", "advancedns", "smoke", "basic"]) + @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="true") def test_02_attach_volume(self): """Attach a created Volume to a Running VM """ @@ -384,7 +343,7 @@ def test_02_attach_volume(self): )) self.virtual_machine.attach_volume(self.apiClient, self.volume) self.attached = True - list_volume_response = list_volumes( + list_volume_response = Volume.list( self.apiClient, id=self.volume.id ) @@ -414,7 +373,7 @@ def test_02_attach_volume(self): (self.virtual_machine.ipaddress, e)) return - @attr(tags = ["advanced", "advancedns", "smoke", "basic"]) + @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="false") def test_03_download_attached_volume(self): """Download a Volume attached to a VM """ @@ -436,7 +395,7 @@ def test_03_download_attached_volume(self): with self.assertRaises(Exception): self.apiClient.extractVolume(cmd) - @attr(tags = ["advanced", "advancedns", "smoke", "basic"]) + @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="false") def test_04_delete_attached_volume(self): """Delete a Volume attached to a VM """ @@ -457,7 +416,7 @@ def test_04_delete_attached_volume(self): with self.assertRaises(Exception): self.apiClient.deleteVolume(cmd) - @attr(tags = ["advanced", "advancedns", "smoke", "basic"]) + @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="false") def test_05_detach_volume(self): """Detach a Volume attached to a VM """ @@ -476,7 +435,7 @@ def test_05_detach_volume(self): self.attached = False #Sleep to ensure the current state will reflected in other calls time.sleep(self.services["sleep"]) - list_volume_response = list_volumes( + list_volume_response = Volume.list( self.apiClient, id=self.volume.id ) @@ -499,7 +458,7 @@ def test_05_detach_volume(self): ) return - @attr(tags = ["advanced", "advancedns", "smoke", "basic"]) + @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="true") def test_06_download_detached_volume(self): """Download a Volume unattached to an VM """ @@ -536,7 +495,7 @@ def test_06_download_detached_volume(self): % (extract_vol.url, self.volume.id) ) - @attr(tags = ["advanced", "advancedns", "smoke", "basic"]) + @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="true") def test_07_resize_fail(self): """Test resize (negative) non-existent volume""" # Verify the size is the new size is what we wanted it to be. @@ -545,10 +504,10 @@ def test_07_resize_fail(self): # first, an invalid id cmd = resizeVolume.resizeVolumeCmd() cmd.id = "invalid id" - cmd.diskofferingid = self.services['resizeddiskofferingid'] + cmd.diskofferingid = self.services['customresizeddiskofferingid'] success = False try: - response = self.apiClient.resizeVolume(cmd) + self.apiClient.resizeVolume(cmd) except Exception as ex: #print str(ex) if "invalid" in str(ex): @@ -563,7 +522,7 @@ def test_07_resize_fail(self): cmd.diskofferingid = "invalid id" success = False try: - response = self.apiClient.resizeVolume(cmd) + self.apiClient.resizeVolume(cmd) except Exception as ex: if "invalid" in str(ex): success = True @@ -571,6 +530,31 @@ def test_07_resize_fail(self): success, True, "ResizeVolume - verify disk offering is handled appropriately") + + # try to resize a root disk with a disk offering, root can only be resized by size= + # get root vol from created vm + list_volume_response = Volume.list( + self.apiClient, + virtualmachineid=self.virtual_machine.id, + type='ROOT', + listall=True + ) + + rootvolume = list_volume_response[0] + + cmd.id = rootvolume.id + cmd.diskofferingid = self.services['diskofferingid'] + success = False + try: + self.apiClient.resizeVolume(cmd) + except Exception as ex: + if "Can only resize Data volumes" in str(ex): + success = True + self.assertEqual( + success, + True, + "ResizeVolume - verify root disks cannot be resized by disk offering id") + # Ok, now let's try and resize a volume that is not custom. cmd.id = self.volume.id cmd.diskofferingid = self.services['diskofferingid'] @@ -600,7 +584,7 @@ def test_07_resize_fail(self): count = 0 success = True while count < 10: - list_volume_response = list_volumes( + list_volume_response = Volume.list( self.apiClient, id=self.volume.id, type='DATADISK' @@ -625,7 +609,7 @@ def test_07_resize_fail(self): return - @attr(tags = ["advanced", "advancedns", "smoke", "basic"]) + @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="true", BugId="CLOUDSTACK-6985") def test_08_resize_volume(self): """Test resize a volume""" # Verify the size is the new size is what we wanted it to be. @@ -647,24 +631,68 @@ def test_08_resize_volume(self): elif hosts[0].hypervisor.lower() == "vmware": self.skipTest("Resize Volume is unsupported on VmWare") + # resize the data disk self.debug("Resize Volume ID: %s" % self.volume.id) + self.services["disk_offering"]["disksize"] = 20 + disk_offering_20_GB = DiskOffering.create( + self.apiclient, + self.services["disk_offering"] + ) + self.cleanup.append(disk_offering_20_GB) + cmd = resizeVolume.resizeVolumeCmd() cmd.id = self.volume.id - cmd.diskofferingid = self.services['resizeddiskofferingid'] + cmd.diskofferingid = disk_offering_20_GB.id self.apiClient.resizeVolume(cmd) count = 0 success = False while count < 3: - list_volume_response = list_volumes( + list_volume_response = Volume.list( self.apiClient, id=self.volume.id, type='DATADISK' ) for vol in list_volume_response: - if vol.id == self.volume.id and vol.size == 3221225472L and vol.state == 'Ready': + if vol.id == self.volume.id and int(vol.size) == (int(disk_offering_20_GB.disksize) * (1024** 3)) and vol.state == 'Ready': + success = True + if success: + break + else: + time.sleep(10) + count += 1 + + self.assertEqual( + success, + True, + "Check if the data volume resized appropriately" + ) + + self.services["disk_offering"]["disksize"] = 10 + disk_offering_10_GB = DiskOffering.create( + self.apiclient, + self.services["disk_offering"] + ) + self.cleanup.append(disk_offering_10_GB) + + cmd = resizeVolume.resizeVolumeCmd() + cmd.id = self.volume.id + cmd.diskofferingid = disk_offering_10_GB.id + cmd.shrinkok = "true" + + self.apiClient.resizeVolume(cmd) + + count = 0 + success = False + while count < 3: + list_volume_response = Volume.list( + self.apiClient, + id=self.volume.id + ) + for vol in list_volume_response: + if vol.id == self.volume.id and int(vol.size) == (int(disk_offering_10_GB.disksize) * (1024 ** 3)) and vol.state == 'Ready': success = True if success: break @@ -675,7 +703,7 @@ def test_08_resize_volume(self): self.assertEqual( success, True, - "Check if the volume resized appropriately" + "Check if the root volume resized appropriately" ) #start the vm if it is on xenserver @@ -685,7 +713,7 @@ def test_08_resize_volume(self): time.sleep(30) return - @attr(tags = ["advanced", "advancedns", "smoke","basic"]) + @attr(tags = ["advanced", "advancedns", "smoke","basic"], required_hardware="false", BugId="CLOUDSTACK-6875") def test_09_delete_detached_volume(self): """Delete a Volume unattached to an VM """ @@ -699,7 +727,7 @@ def test_09_delete_detached_volume(self): self.debug("Delete Volume ID: %s" % self.volume.id) self.volume_1 = Volume.create( - self.api_client, + self.apiclient, self.services, account=self.account.name, domainid=self.account.domainid @@ -712,7 +740,7 @@ def test_09_delete_detached_volume(self): cmd.id = self.volume_1.id self.apiClient.deleteVolume(cmd) - list_volume_response = list_volumes( + list_volume_response = Volume.list( self.apiClient, id=self.volume_1.id, type='DATADISK' diff --git a/test/integration/smoke/test_vpc_vpn.py b/test/integration/smoke/test_vpc_vpn.py index 5e97c79065..f0a2027fe6 100644 --- a/test/integration/smoke/test_vpc_vpn.py +++ b/test/integration/smoke/test_vpc_vpn.py @@ -17,105 +17,29 @@ """ Tests for VPN in VPC """ #Import Local Modules +from marvin.codes import FAILED from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * +from marvin.lib.utils import * +from marvin.lib.base import * +from marvin.lib.common import * from nose.plugins.attrib import attr import time -class Services: - def __init__(self): - self.services = { - "account": { - "email": "test@test.com", - "firstname": "Test", - "lastname": "User", - "username": "test", - "password": "password", - }, - "virtual_machine": { - "displayname": "Test VM", - "username": "root", - "password": "password", - "ssh_port": 22, - "hypervisor": 'XenServer', - "privateport": 22, - "publicport": 22, - "protocol": 'TCP', - }, - "ostype": 'CentOS 5.3 (64-bit)', - "service_offering": { - "name": "Tiny Instance", - "displaytext": "Tiny Instance", - "cpunumber": 1, - "cpuspeed": 100, - "memory": 256, - }, - "network_offering": { - "name": "Network offering for internal vpc", - "displaytext": "Network offering for internal vpc", - "guestiptype": "Isolated", - "traffictype": "Guest", - "supportedservices": "Vpn,Dhcp,Dns,Lb,UserData,SourceNat,StaticNat,PortForwarding,NetworkACL", - "serviceProviderList": { - "Dhcp": "VpcVirtualRouter", - "Dns": "VpcVirtualRouter", - "Vpn": "VpcVirtualRouter", - "UserData": "VpcVirtualRouter", - "Lb": "InternalLbVM", - "SourceNat": "VpcVirtualRouter", - "StaticNat": "VpcVirtualRouter", - "PortForwarding": "VpcVirtualRouter", - "NetworkACL": "VpcVirtualRouter", - }, - "serviceCapabilityList": { - "SourceNat": {"SupportedSourceNatTypes": "peraccount"}, - "Lb": {"lbSchemes": "internal", "SupportedLbIsolation": "dedicated"} - } - }, - "vpn_user": { - "username": "test", - "password": "password", - }, - "vpc": { - "name": "vpc_vpn", - "displaytext": "vpc-vpn", - "cidr": "10.1.1.0/24" - }, - "ntwk": { - "name": "tier1", - "displaytext": "vpc-tier1", - "gateway" : "10.1.1.1", - "netmask" : "255.255.255.192" - }, - "vpc2": { - "name": "vpc2_vpn", - "displaytext": "vpc2-vpn", - "cidr": "10.2.1.0/24" - }, - "ntwk2": { - "name": "tier2", - "displaytext": "vpc-tier2", - "gateway" : "10.2.1.1", - "netmask" : "255.255.255.192" - } - } - - class TestVpcRemoteAccessVpn(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.apiclient = super(TestVpcRemoteAccessVpn, cls).getClsTestClient().getApiClient() - cls.services = Services().services - cls.zone = get_zone(cls.apiclient, cls.services) + testClient = super(TestVpcRemoteAccessVpn, cls).getClsTestClient() + cls.apiclient = testClient.getApiClient() + cls.services = testClient.getParsedTestDataConfig() + + cls.zone = get_zone(cls.apiclient, testClient.getZoneForTests()) cls.domain = get_domain(cls.apiclient) cls.service_offering = ServiceOffering.create( cls.apiclient, - cls.services["service_offering"] + cls.services["service_offerings"] ) cls.account = Account.create(cls.apiclient, services=cls.services["account"]) cls.template = get_template( @@ -123,9 +47,12 @@ def setUpClass(cls): cls.zone.id, cls.services["ostype"] ) + if cls.template == FAILED: + assert False, "get_template() failed to return template with description %s" % cls.services["ostype"] + cls.cleanup = [cls.account] - @attr(tags=["advanced"]) + @attr(tags=["advanced"], required_hardware="false") def test_vpc_remote_access_vpn(self): """Test VPN in VPC""" @@ -211,13 +138,15 @@ class TestVpcSite2SiteVpn(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.apiclient = super(TestVpcSite2SiteVpn, cls).getClsTestClient().getApiClient() - cls.services = Services().services - cls.zone = get_zone(cls.apiclient, cls.services) + testClient = super(TestVpcSite2SiteVpn, cls).getClsTestClient() + cls.apiclient = testClient.getApiClient() + cls.services = testClient.getParsedTestDataConfig() + + cls.zone = get_zone(cls.apiclient, testClient.getZoneForTests()) cls.domain = get_domain(cls.apiclient) cls.service_offering = ServiceOffering.create( cls.apiclient, - cls.services["service_offering"] + cls.services["service_offerings"] ) cls.account = Account.create(cls.apiclient, services=cls.services["account"]) cls.template = get_template( @@ -225,9 +154,12 @@ def setUpClass(cls): cls.zone.id, cls.services["ostype"] ) + if cls.template == FAILED: + assert False, "get_template() failed to return template with description %s" % cls.services["ostype"] + cls.cleanup = [cls.account] - @attr(tags=["advanced"]) + @attr(tags=["advanced"], required_hardware="false",BugId="CLOUDSTACK-6879") def test_vpc_site2site_vpn(self): """Test VPN in VPC""" diff --git a/test/integration/stress/test_multipleremotevpn_vpc.py b/test/integration/stress/test_multipleremotevpn_vpc.py new file mode 100755 index 0000000000..e3ff9b95af --- /dev/null +++ b/test/integration/stress/test_multipleremotevpn_vpc.py @@ -0,0 +1,795 @@ +# 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. + +""" Component tests Multiple Connections for Remote Access VPN on VPC Functionality. +""" +from nose.plugins.attrib import attr +from marvin.cloudstackTestCase import cloudstackTestCase, unittest +from marvin.lib.base import (Vpn, + VpnUser, + VPC, + Account, + User, + VpcOffering, + VPC, + ServiceOffering, + NATRule, + NetworkACL, + PublicIPAddress, + NetworkOffering, + Network, + VirtualMachine, + StaticNATRule, + Template, + Configurations + ) +from marvin.lib.common import (list_publicIP, + get_domain, + get_zone, + get_template, + list_networks, + list_templates, + list_service_offering, + list_vpc_offerings, + list_network_offerings, + list_routers, + list_hosts + ) +from marvin.lib.utils import (cleanup_resources, + random_gen, + get_process_status, + get_host_credentials + ) +import time +import string +from marvin.sshClient import SshClient +import traceback +import thread +import json +from marvin.codes import ( + SUCCESS, FAILED +) + +class TestMultipleVPNAccessonVPC(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + + + cloudstackTestClient = super( + TestMultipleVPNAccessonVPC, + cls + ).getClsTestClient() + + cls.debug("Obtain the Admin's API Client") + cls.api_client = cloudstackTestClient.getApiClient() + cls.debug("Get the dictionary information that will be used during CCP tests, from test_data.py present on the Client") + cls.services = cloudstackTestClient.getParsedTestDataConfig() + + if cls.services is None: + cls.debug("Services Object is None") + raise Exception("Services Object is None") + + cls.debug("Procure the CloudStack Setup configuration Information") + with open(cls.services["config_path"], 'rb') as fp: + cls.pullconfig = json.load(fp) + + cls.debug("Update 'remote.access.vpn.client.iprange','remote.access.vpn.user.limit','max.account.primary.storage','max.account.public.ips','max.account.user.vms','max.account.volumes','max.account.cpus', Global Configuration Parameters") + + update_vpn_client_iprange = Configurations.update( + cls.api_client, + name="remote.access.vpn.client.iprange", + value="10.1.2.1-10.1.2.120") + + cls.debug("'remote.access.vpn.client.iprange' Global Configuration Parameter Updated Successfully") + + update_vpn_user_limit = Configurations.update( + cls.api_client, + name="remote.access.vpn.user.limit", + value=str(int(cls.services["vpnclient_count"]*2)) + ) + + cls.debug("'remote.access.vpn.user.limit' Global Configuration Parameter Updated Successfully") + + update_max_account_primary_stg_limit = Configurations.update( + cls.api_client, + name="max.account.primary.storage", + value=str(int(cls.services["vpnclient_count"]*20 + 100)) + ) + cls.debug("'max.account.primary.storage' Global Configuration Parameter Updated Successfully") + + update_max_account_public_ips_limit = Configurations.update( + cls.api_client, + name="max.account.public.ips", + value=str(int(cls.services["vpnclient_count"]*2 + 10)) + ) + cls.debug("'max.account.public.ips' Global Configuration Parameter Updated Successfully") + + update_max_account_user_vms_limit = Configurations.update( + cls.api_client, + name="max.account.user.vms", + value=str(int(cls.services["vpnclient_count"]*2)) + ) + cls.debug("'max.account.user.vms' Global Configuration Parameter Updated Successfully") + + update_max_account_volumes_limit = Configurations.update( + cls.api_client, + name="max.account.volumes", + value=str(int(cls.services["vpnclient_count"]*2)) + ) + cls.debug("'max.account.volumes' Global Configuration Parameter Updated Successfully") + + update_max_account_cpus_limit = Configurations.update( + cls.api_client, + name="max.account.cpus", + value=str(int(cls.services["vpnclient_count"]*2)) + ) + cls.debug("'max.account.cpus' Global Configuration Parameter Updated Successfully") + + cls.debug("Restart the Management Server") + TestMultipleVPNAccessonVPC.restart_mgmt_server(cls.services["config_path"]) + cls.debug("Completed restarting the Management Server") + + cls.debug("Wait for 120 seconds...") + time.sleep(120) + cls.debug("End of 120 seconds wait time....") + + # Get Zone, Domain and templates + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone( + cls.api_client, + zone_name = cls.services["zone_vpn"]["name"]) + + cls.debug("Use an Existing 'Tiny Instance' Service Offering on the Setup") + list_service_offerings = [] + list_service_offerings = list_service_offering( + cls.api_client, + keyword="Tiny Instance", + ) + + cls._cleanup = [] + + if list_service_offerings is not None: + cls.debug("Found an Existing 'Tiny Instance' Service Offering on the Setup") + cls.service_offering = list_service_offerings[0] + + else: + cls.debug("Create a service offering which will be used for VM deployments in this test") + cls.service_offering = ServiceOffering.create( + cls.api_client, + cls.services["service_offering"] + ) + + cls.debug("Add the created service offering to the _cleanup queue") + cls._cleanup.append(cls.service_offering) + + try: + cls.debug("Create or Use Existing Account to own the VPN Clients, which is used to test Remote VPN Access to VPC") + cls.api_client_vpn_client_reg_user = cloudstackTestClient.getUserApiClient( + UserName="CSRegularVPNClientUser", + DomainName="ROOT" + ) + + list_vpn_client_regular_user = User.list( + cls.api_client, + username="CSRegularVPNClientUser" + ) + + cls.debug("Procure the Account Name and DomainID Information of the Regular Account") + cls.vpn_client_reg_acct_name = list_vpn_client_regular_user[0].account + cls.vpn_client_reg_domain_id = list_vpn_client_regular_user[0].domainid + + list_vpn_client_regular_user_acct = Account.list( + cls.api_client, + name = cls.vpn_client_reg_acct_name, + listall = True + ) + + cls._cleanup.append(Account(list_vpn_client_regular_user_acct[0].__dict__)) + + # Register a Template that already has VPN client installed on it. The template registered here + # has extra scripts to facilitate automated operations to execute Test Cases. + # Template has pre-configured configuration files required for the VPN Client operations. + # The following files are present on the registered template. The location of the files are locations + # on a VM deployed from this template + # 1. "/tmp/ipsec.conf" + # 2. "/tmp/ipsec.secrets" + # 3. "/tmp/options.xl2tpd.client" + # 4. "/tmp/xl2tpd.conf" + # 5 "/tmp/vpnclient_services.sh" + # 6. "/tmp/firstconn_expectscript.exp" + # 7. "/tmp/secondconn_expectscript.exp" + + cls.debug("Use an Existing VPN Client Template on the Setup") + list_vpn_client_templates = list_templates( + cls.api_client_vpn_client_reg_user, + keyword="VPNClient", + templatefilter="featured", + zoneid = cls.zone.id + ) + + if list_vpn_client_templates is not None: + cls.debug("Found an Existing VPN Client Template on the Setup") + cls.template = list_vpn_client_templates[0] + + else: + cls.debug("Register a Template that already has VPN client installed on it") + cls.template = Template.register( + cls.api_client, + cls.services["vpn_template"], + zoneid=cls.zone.id, + hypervisor='XenServer' + ) + + cls._cleanup.append(cls.template) + + cls.debug("Sleep for {0} seconds specified in the dictionary before checking for Template's Availability".format(cls.services["sleep"])) + time.sleep(cls.services["sleep"]) + + cls.debug("Procure Timeout Value from the dictionary") + timeout = cls.services["timeout"] + + while True: + list_template_response = list_templates( + cls.api_client_vpn_client_reg_user, + templatefilter='featured', + id=cls.template.id, + ) + + if isinstance(list_template_response, list): + break + elif timeout == 0: + raise Exception("List template failed!") + + time.sleep(5) + timeout = timeout - 1 + + cls.debug("Verify template response to check whether template is present") + + if list_template_response is None: + raise Exception("Check whether the VPN Client Template is available") + template_response = list_template_response[0] + if template_response.isready == False: + raise Exception("Template state is not ready, it is %r" % template_response.isready) + + # Queue that holds all the VPN Client VMs Information + cls.vpnclientvms = [] + + cls.debug("Deploy {0} VPN Clients in the account".format(int(cls.services["vpnclient_count"]))) + + for vm in xrange(0,int(cls.services["vpnclient_count"])): + + cls.debug("Deploy a new VM {0} in first account. This VM which will be configured as VPN Client".format(int(vm))) + new_vpnclient_vm = VirtualMachine.create( + cls.api_client_vpn_client_reg_user, + cls.services["virtual_machine"], + zoneid=cls.zone.id, + serviceofferingid=cls.service_offering.id, + templateid=cls.template.id, + ) + + cls.debug("Add new VM {0} to the vpnclientvms Queue".format(int(vm))) + cls.vpnclientvms.append(new_vpnclient_vm) + + cls.debug("Allow SSH Access to the new VPN Client VM {0}".format(int(vm))) + new_vpnclient_vm.access_ssh_over_nat( + cls.api_client_vpn_client_reg_user, + cls.services, + new_vpnclient_vm, + allow_egress=True + ) + cls.debug("VM for VPNClient Access Got Created with Public IP Address %s" % new_vpnclient_vm.public_ip) + + cls.debug("Create or Use existing Account in which we deploy VPCs and test remote access to them from the First Account's VMs present on isolated Network") + cls.api_client_vpn_server_reg_user = cloudstackTestClient.getUserApiClient( + UserName="CSRegularVPNServerUser", + DomainName="ROOT" + ) + + list_vpn_server_regular_user = User.list( + cls.api_client, + username="CSRegularVPNServerUser" + ) + + cls.debug("Procure the Account Name and DomainID Information of the Regular Account") + cls.vpn_server_reg_acct_name = list_vpn_server_regular_user[0].account + cls.vpn_server_reg_domain_id = list_vpn_server_regular_user[0].domainid + + list_vpn_server_regular_user_acct = Account.list( + cls.api_client, + name = cls.vpn_server_reg_acct_name, + listall = True + ) + + cls._cleanup.append(Account(list_vpn_server_regular_user_acct[0].__dict__)) + + cls.debug("Use an Existing 'VPC off-' Service Offering on the Setup") + list_available_vpc_offerings = list_vpc_offerings( + cls.api_client, + keyword="VPC off-", + ) + + if list_available_vpc_offerings is not None: + cls.debug("Found an Existing 'VPC off-' Service Offering on the Setup") + cls.vpc_offering = VpcOffering(list_available_vpc_offerings[0].__dict__) + + else: + cls.debug("Creating a VPC offering..") + cls.vpc_offering = VpcOffering.create( + cls.api_client, + cls.services["vpc_offering"] + ) + + # Add the created VPC Offering to __cleanup queue + cls._cleanup.append(cls.vpc_offering) + + # Enable to created VPC Offering inorder to deploy VPCs with it + cls.debug("Enabling the VPC offering created") + cls.vpc_offering.update(cls.api_client, state='Enabled') + cls.debug("Enabled the VPC Offering") + + # Create a VPC for the second account + cls.debug("Creating a VPC in the account: %s" % cls.vpn_server_reg_acct_name) + cls.firstvpc = VPC.create( + cls.api_client_vpn_server_reg_user, + cls.services["vpc_remote_vpn"], + vpcofferingid=cls.vpc_offering.id, + zoneid=cls.zone.id + ) + + cls.debug("Use an Existing 'NET_OFF-RemoteAccessVPNTest-' Network Offering on the Setup") + list_available_network_offerings = list_network_offerings( + cls.api_client, + keyword="NET_OFF-RemoteAccessVPNTest-", + ) + + if list_available_network_offerings is not None: + cls.debug("Found an Existing 'NET_OFF-RemoteAccessVPNTest-' Network Offering on the Setup") + cls.network_off = NetworkOffering(list_available_network_offerings[0].__dict__) + + else: + cls.debug('Create NetworkOffering for Networks in VPC') + cls.services["vpc_network_offering"]["name"] = "NET_OFF-RemoteAccessVPNTest-"+ random_gen() + cls.network_off = NetworkOffering.create( + cls.api_client, + cls.services["vpc_network_offering"], + conservemode=False + ) + + # Add the created Network Offering to __cleanup queue + cls._cleanup.append(cls.network_off) + + # Enable Network offering + cls.network_off.update(cls.api_client, state='Enabled') + + cls.debug('Created and Enabled NetworkOffering') + cls.services["network"]["name"] = "NETWORK-" + random_gen() + + # Create First Network Tier in the First VPC created for second account using the network offering created above. + cls.debug('Adding Network=%s' % cls.services["network"]) + cls.firstnetworktier = Network.create( + cls.api_client_vpn_server_reg_user, + cls.services["network"], + networkofferingid=cls.network_off.id, + zoneid=cls.zone.id, + gateway=cls.services["firstnetwork_tier"]["gateway"], + netmask=cls.services["firstnetwork_tier"]["netmask"], + vpcid=cls.firstvpc.id + ) + + cls.debug("Created network with ID: %s" % cls.firstnetworktier.id) + + # Create Ingress and Egress NetworkACL rules for First Network Tier in the First VPC created for second account. + cls.debug("Adding NetworkACL rules to make Network accessible for all Protocols and all CIDRs ") + NetworkACL.create( + cls.api_client_vpn_server_reg_user, + cls.services["all_rule"], + networkid=cls.firstnetworktier.id, + traffictype='Ingress' + ) + + NetworkACL.create( + cls.api_client_vpn_server_reg_user, + cls.services["all_rule"], + networkid=cls.firstnetworktier.id, + traffictype='Egress' + ) + + listFirstVPC = VPC.list( + cls.api_client_vpn_server_reg_user, + id=cls.firstvpc.id + ) + + cls.debug("Information about the VPC: {0}".format(str(listFirstVPC))) + + cls.debug("Obtain the source nat IP Address of the first VPC.") + cls.listFirstVPCPublicIpAddress = list_publicIP( + cls.api_client_vpn_server_reg_user, + issourcenat="true", + vpcid=listFirstVPC[0].id, + listall="true" + ) + cls.debug("Information about the VPC's Source NAT IP Address: {0}".format(str(cls.listFirstVPCPublicIpAddress))) + + cls.debug("Enable Remote Access VPN on the source nat Public IP Address of the first VPC") + cls.FirstVPNonFirstVPC = Vpn.create( + cls.api_client_vpn_server_reg_user, + cls.listFirstVPCPublicIpAddress[0].id + ) + + cls.debug("Successfully Created First VPN on VPC with preshared key:"+ cls.FirstVPNonFirstVPC.presharedkey) + cls.listfirstNetworkTier = list_networks( + cls.api_client_vpn_server_reg_user, + id=cls.firstnetworktier.id, + listall=True + ) + + + cls.debug("Create a VM using the default template on the First Network Tier in the First VPC of the Second Account") + cls.vm1 = VirtualMachine.create( + cls.api_client_vpn_server_reg_user, + cls.services["virtual_machine"], + zoneid=cls.zone.id, + serviceofferingid=cls.service_offering.id, + templateid=cls.template.id, + networkids=[str(cls.firstnetworktier.id)] + ) + + cls.debug("First VM deployed in the first Network Tier") + + except Exception as e: + cleanup_resources(cls.api_client, cls._cleanup) + printex = traceback.format_exc() + cls.debug("Exception Occurred : {0}".format(printex)) + raise Exception("Warning: Exception during Setting Up the Test Suite Configuration : %s" % e) + + return + + @classmethod + def tearDownClass(cls): + try: + #Cleanup resources used + cleanup_resources(cls.api_client, cls._cleanup) + except Exception as e: + print("Warning: Exception during cleanup : %s" % e) + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + @classmethod + def filecopy(cls,virtual_machine,localfile=None,remotefilelocation=None,permissions="644"): + cls.ssh = SshClient( + host=virtual_machine.public_ip, + port=TestMultipleVPNAccessonVPC.services["virtual_machine"]["ssh_port"], + user='root', + passwd='password') + + cls.ssh.scp(localfile,remotefilelocation) + cls.ssh.runCommand('chmod %s %s' % (permissions,remotefilelocation)) + cls.debug("%s file successfully copied to %s " % (localfile, remotefilelocation)) + + cls.ssh.close() + + @classmethod + def restart_mgmt_server(cls,config): + + cls.ssh = SshClient( + host=cls.pullconfig["mgtSvr"][0]["mgtSvrIp"], + port=22, + user=cls.pullconfig["mgtSvr"][0]["user"], + passwd=cls.pullconfig["mgtSvr"][0]["passwd"] + ) + + result = cls.ssh.runCommand("/etc/init.d/cloudstack-management restart") + + if result["status"] == SUCCESS: + time.sleep(120) + else: + raise Exception("Failure in restarting cloudstack Management Server") + + cls.ssh.close() + + @staticmethod + def char_xrange(firstchar, lastchar): + #Generates a range of Alphabetical Characters, lastchar inclusive + for c in xrange(ord(firstchar),ord(lastchar)+1): + yield chr(c) + + @staticmethod + def get_guest_ip_address(guest_ip_address): + + for ch in ["'","[","]","\\","n"]: + if ch in guest_ip_address: + guest_ip_address = guest_ip_address.replace(ch,"") + + return guest_ip_address + + @staticmethod + def configureVPNClientServicesFile(virtual_machine,vpnclient_services_script,vpnserverip=None,vpnnetworkcidr="192.168.10.0/24",psk=None,vpnuser=None,vpnuserpassword=None): + + ssh = SshClient( + host=virtual_machine.public_ip, + port=TestMultipleVPNAccessonVPC.services["virtual_machine"]["ssh_port"], + user='root', + passwd='password') + + + cidr = "\/".join(vpnnetworkcidr.rsplit("/",1)) + + ssh.execute(''' sed -i "s/VPN_ADDR=.*/VPN_ADDR='%s'/g" %s ''' % (vpnserverip,vpnclient_services_script)) + ssh.execute(''' sed -i "s/CIDR=.*/CIDR='%s'/g" %s ''' % (cidr,vpnclient_services_script)) + ssh.execute(''' sed -i "s/PSK=.*/PSK='%s'/g" %s ''' % (psk,vpnclient_services_script)) + ssh.execute(''' sed -i "s/VPN_USR=.*/VPN_USR='%s'/g" %s ''' % (vpnuser,vpnclient_services_script)) + ssh.execute(''' sed -i "s/VPN_USR_PWD=.*/VPN_USR_PWD='%s'/g" %s ''' % (vpnuserpassword,vpnclient_services_script)) + ssh.execute('echo "VPN Client Services File Ready" >> /tmp/executionoutput.txt') + + ssh.close() + + @staticmethod + def vpnClientServicesInit(virtual_machine,vpnclient_services_script): + + ssh = SshClient( + host=virtual_machine.public_ip, + port=TestMultipleVPNAccessonVPC.services["virtual_machine"]["ssh_port"], + user='root', + passwd='password') + + ssh.execute('%s init >> /tmp/executionoutput.txt' % (vpnclient_services_script)) + ssh.execute('echo "VPN Client Services Configuration Files Initiated" >> /tmp/executionoutput.txt') + + ssh.close() + + @staticmethod + def vpnClientServicesStart(virtual_machine,vpnclient_services_script): + + ssh = SshClient( + host=virtual_machine.public_ip, + port=TestMultipleVPNAccessonVPC.services["virtual_machine"]["ssh_port"], + user='root', + passwd='password') + + ssh.execute('%s start >> /tmp/executionoutput.txt' % (vpnclient_services_script)) + ssh.execute('echo "VPN Client Services Started" >> /tmp/executionoutput.txt') + + ssh.close() + + + def exec_script_on_user_vm(self, virtual_machine,script, exec_cmd_params, expected_result, negative_test=False,public_ip=None): + try: + exec_success = False + + if public_ip is not None: + self.debug("getting SSH client for Vm: %s with ip %s" % (virtual_machine.id,public_ip)) + sshClient = virtual_machine.get_ssh_client(ipaddress=public_ip) + else: + self.debug("getting SSH client for Vm: %s with ip %s" % (virtual_machine.id,virtual_machine.public_ip)) + sshClient = virtual_machine.get_ssh_client(ipaddress=virtual_machine.public_ip) + + result = sshClient.execute(script+exec_cmd_params) + + self.debug("script: %s" % script+exec_cmd_params) + self.debug("result: %s" % result) + + str_result = str(str(result).strip()) + str_expected_result = str(expected_result).strip() + if str_result == str_expected_result: + exec_success = True + + if negative_test: + self.assertEqual(exec_success, + True, + "Script result is %s matching with %s" % (str_result, str_expected_result)) + else: + self.assertEqual(exec_success, + True, + "Script result is %s is not matching with %s" % (str_result, str_expected_result)) + + except Exception as e: + self.debug('Error=%s' % e) + printex = traceback.format_exc() + self.debug("Exception Occurred : {0}".format(printex)) + raise e + + def ping_vm(self, virtual_machine, guest_ip_address, count=1, interval=15, thread_name="Thread-None"): + + try: + self.debug("{4} : Check whether VM with ID: {0} with Public IP: {1} is able to ping Guest VM with IP: {2} - {3} Times !!!".format(virtual_machine.id, virtual_machine.public_ip, guest_ip_address, count, thread_name)) + iteration = 1 + total_times = count + + while count > 0: + self.debug("{4} : Test whether VM with ID: {0} with Public IP: {1} is able to ping Guest VM with IP: {2} for {3} iteration".format(virtual_machine.id, virtual_machine.public_ip, guest_ip_address, iteration, thread_name)) + self.exec_script_on_user_vm( + virtual_machine, + 'ping -c 1 {0}'.format(guest_ip_address), + "| grep -oP \'\d+(?=% packet loss)\'", + "[u'0']", + negative_test=False + ) + self.debug("{4} : Verified Successfully that VM with ID: {0} with Public IP: {1} is able to ping Guest VM with IP: {2} for {3} iteration".format(virtual_machine.id, virtual_machine.public_ip, guest_ip_address, iteration, thread_name)) + count = count-1 + iteration = iteration + 1 + + self.debug("{1} : Wait for {0} seconds before next ping".format(interval,thread_name)) + time.sleep(interval) + self.debug("Still {0} iterations left for Thread {1}".format(count,thread_name)) + + if count == 0: + self.debug("Ping {0} Times is Completed for Thread {1} ".format(total_times,thread_name)) + else: + raise Exception("Count value is still at {0}".format(count)) + + except Exception as e: + + printex = traceback.format_exc() + self.debug("Exception Occurred : {0}".format(printex)) + raise Exception("Warning: Exception during pinging VM : %s" % e) + + + def setUp(self): + self.apiclient = self.testClient.getApiClient() + self.hypervisor = self.testClient.getHypervisorInfo() + self.cleanup=None + return + + def tearDown(self): + try: + #Clean up, terminate the created network offerings + cleanup_resources(self.apiclient, self.cleanup) + except Exception as e: + self.debug("Warning: Exception during cleanup : %s" % e) + return + + @attr(tags=["advanced", "intervlan"],required_hardware="true") + def test_01_Multiple_RemoteAccessVPN_Connections_To_VPC_Ping_Guest_VM_Multiple_Times(self): + """ Test case no : Test Multiple VPN Connections to a VPN Server on VPC + + + # Validate the following for Each VPN VM Client + # 1. Create VPN User on the VPC + # 2. Configure the VPN Client VM with the required Information + # 3. Initialize the VPN Client Services on the VPN Client + # 4. Start the VPN Client Services on the VPN Client + # 5. Wait for 30 seconds before attempting to ping + # 6. Conduct the Ping Test on the VM + + # After the deployment VPN Client VMs and the post deployment steps, do the following steps: + # 7. Wait for 60 seconds + # 8. Check Routers pppX NICs Information + """ + + for vm in xrange(0,int(TestMultipleVPNAccessonVPC.services["vpnclient_count"])): + + vpn_user_name = ''.join((str(vm),"-user")) + vpn_password = ''.join((str(vm),"-pass")) + + self.debug("VPN User Name created with %s " % vpn_user_name) + self.debug("VPN Password created with %s " % vpn_password) + + self.debug("Create new VPN User to use the Remote Access Service enabled on the VPC") + newVPNUser = VpnUser.create( + TestMultipleVPNAccessonVPC.api_client_vpn_server_reg_user, + vpn_user_name, + vpn_password, + rand_name=False + ) + self.debug("VPN User %s got created Successfully " % vpn_user_name) + + self.debug("Configure the VPN Client Services on the VM deployed for VPN client purpose.") + TestMultipleVPNAccessonVPC.configureVPNClientServicesFile( + TestMultipleVPNAccessonVPC.vpnclientvms[vm], + "/tmp/vpnclient_services.sh", + TestMultipleVPNAccessonVPC.listFirstVPCPublicIpAddress[0].ipaddress, + TestMultipleVPNAccessonVPC.listfirstNetworkTier[0].cidr, + TestMultipleVPNAccessonVPC.FirstVPNonFirstVPC.presharedkey, + vpn_user_name, + vpn_password + ) + self.debug("Configuration of VPN Client VM %d Done " % (vm)) + + self.debug("Initialize the VPN Client Services on the VPN Client") + TestMultipleVPNAccessonVPC.vpnClientServicesInit( + TestMultipleVPNAccessonVPC.vpnclientvms[vm], + "/tmp/vpnclient_services.sh" + ) + self.debug("Initiation of VPN Client Services on VM %d Done " % (vm)) + + self.debug("Start the VPN Client Services on the VPN Client") + TestMultipleVPNAccessonVPC.vpnClientServicesStart( + TestMultipleVPNAccessonVPC.vpnclientvms[vm], + "/tmp/vpnclient_services.sh" + ) + self.debug("VPN Client Services on VM %d Started Successfully " % (vm)) + + self.debug("Wait for 30 seconds before attempting to ping") + time.sleep(30) + + self.debug("Conduct the Ping Test on the VM %d" % (vm)) + thread.start_new_thread(self.ping_vm,( + TestMultipleVPNAccessonVPC.vpnclientvms[vm], + TestMultipleVPNAccessonVPC.vm1.nic[0].ipaddress, + 25000, + 15, + "Thread-{0}".format(vm) + )) + + self.debug("Waiting for 60 seconds.........") + time.sleep(60) + self.debug("End of 60 seconds.........") + + # Find router associated with user account + list_router_response = list_routers( + self.apiclient, + vpcid= TestMultipleVPNAccessonVPC.firstvpc.id, + listall=True + ) + + self.assertEqual( + isinstance(list_router_response, list), + True, + "Check list response returns a valid list" + ) + + router = list_router_response[0] + + hosts = list_hosts( + self.apiclient, + zoneid=router.zoneid, + type='Routing', + state='Up', + id=router.hostid + ) + + self.assertEqual( + isinstance(hosts, list), + True, + "Check list response returns a valid list" + ) + + host = hosts[0] + + self.debug("Router ID: %s, state: %s" % (router.id, router.state)) + self.assertEqual( + router.state, + 'Running', + "Check list router response for router state" + ) + + if self.hypervisor.lower() == 'vmware': + result = get_process_status( + self.apiclient.connection.mgtSvr, + 22, + self.apiclient.connection.user, + self.apiclient.connection.passwd, + router.linklocalip, + "ifconfig | grep ppp", + hypervisor=self.hypervisor + ) + else: + try: + host.user, host.passwd = get_host_credentials(self.config, host.ipaddress) + result = get_process_status( + host.ipaddress, + 22, + host.user, + host.passwd, + router.linklocalip, + "ifconfig | grep ppp" + ) + self.debug("Routers pppX NICs Information : %s" % str(result)) + except KeyError: + self.skipTest("Marvin configuration has no host credentials to check router services") + diff --git a/tools/appliance/build.sh b/tools/appliance/build.sh old mode 100644 new mode 100755 index 6d2bd8fec2..db5dcb094b --- a/tools/appliance/build.sh +++ b/tools/appliance/build.sh @@ -28,7 +28,7 @@ fi build_date=`date +%Y-%m-%d` # set fixed or leave empty to use git to determine -branch=master +branch= if [ -z "$branch" ] ; then branch=`git status | grep '# On branch' | awk '{print $4}'` @@ -105,8 +105,8 @@ echo "$appliance exported for VMWare: dist/$appliance-$branch-vmware.vmdk.bz2" vboxmanage export $machine_uuid --output $appliance-$branch-vmware.ovf mv $appliance-$branch-vmware.ovf $appliance-$branch-vmware.ovf-orig java -cp convert Convert convert_ovf_vbox_to_esx.xslt $appliance-$branch-vmware.ovf-orig $appliance-$branch-vmware.ovf -tar -cf $appliance-$branch-vmware.ova $appliance-$branch-vmware.ovf $appliance-$branch-vmware-disk1.vmdk -rm -f $appliance-$branch-vmware.ovf $appliance-$branch-vmware.ovf-orig $appliance-$branch-vmware-disk1.vmdk +tar -cf $appliance-$branch-vmware.ova $appliance-$branch-vmware.ovf $appliance-$branch-vmware-disk[0-9].vmdk +rm -f $appliance-$branch-vmware.ovf $appliance-$branch-vmware.ovf-orig $appliance-$branch-vmware-disk[0-9].vmdk echo "$appliance exported for VMWare: dist/$appliance-$branch-vmware.ova" # Export for HyperV diff --git a/tools/appliance/definitions/systemvm64template/base.sh b/tools/appliance/definitions/systemvm64template/base.sh index bc03ffe9ac..8166081cdc 100644 --- a/tools/appliance/definitions/systemvm64template/base.sh +++ b/tools/appliance/definitions/systemvm64template/base.sh @@ -1,6 +1,10 @@ # Update the box -apt-get -y update -apt-get -y install curl unzip + +export DEBIAN_FRONTEND=noninteractive +export DEBIAN_PRIORITY=critical + +apt-get -q -y --force-yes update +apt-get -q -y --force-yes install curl unzip apt-get clean # Set up sudo, TODO: Check security concerns diff --git a/tools/appliance/definitions/systemvm64template/definition.rb b/tools/appliance/definitions/systemvm64template/definition.rb index bea2fdebbe..f9308a0558 100644 --- a/tools/appliance/definitions/systemvm64template/definition.rb +++ b/tools/appliance/definitions/systemvm64template/definition.rb @@ -4,7 +4,7 @@ :disk_size => '2500', :disk_format => 'VDI', :hostiocache => 'off', :os_type_id => 'Debian_64', :iso_file => "debian-7.4.0-amd64-netinst.iso", - :iso_src => "http://ftp.acc.umu.se/mirror/cdimage/release/7.4.0/amd64/iso-cd/debian-7.4.0-amd64-netinst.iso", + :iso_src => "http://cdimage.debian.org/mirror/cdimage/archive/7.4.0/amd64/iso-cd/debian-7.4.0-amd64-netinst.iso", :iso_md5 => "e7e9433973f082a297793c3c5010b2c5", :iso_download_timeout => "1000", :boot_wait => "10", :boot_cmd_sequence => [ diff --git a/tools/appliance/definitions/systemvm64template/postinstall.sh b/tools/appliance/definitions/systemvm64template/postinstall.sh index cc8ead9d94..b1e4430070 100644 --- a/tools/appliance/definitions/systemvm64template/postinstall.sh +++ b/tools/appliance/definitions/systemvm64template/postinstall.sh @@ -81,7 +81,7 @@ install_packages() { dpkg -i hv-kvp-daemon_3.1_amd64.deb #libraries required for rdp client (Hyper-V) - apt-get --no-install-recommends -q -y --force-yes install libtcnative-1 libssl-dev libapr1-dev + DEBIAN_FRONTEND=noninteractive apt-get --no-install-recommends -qq -y --force-yes install libtcnative-1 libssl-dev libapr1-dev # vmware tools apt-get --no-install-recommends -q -y --force-yes install open-vm-tools @@ -188,6 +188,16 @@ fix_vhdutil() { chmod a+x /bin/vhd-util } +# Preload these module otherwise the sysctl settings will not be set, and pasive ftp will not work. +fix_modules() { + cat >> /etc/modules << EOF +nf_conntrack_ipv4 +nf_conntrack +nf_conntrack_ftp +nf_nat_ftp +EOF +} + do_fixes() { fix_nameserver fix_inittab @@ -195,6 +205,7 @@ do_fixes() { fix_hostname fix_locale fix_vhdutil + fix_modules } configure_apache2() { diff --git a/tools/appliance/definitions/systemvm64template/preseed.cfg b/tools/appliance/definitions/systemvm64template/preseed.cfg index 6996565aaa..635432a6c5 100644 --- a/tools/appliance/definitions/systemvm64template/preseed.cfg +++ b/tools/appliance/definitions/systemvm64template/preseed.cfg @@ -334,6 +334,11 @@ d-i finish-install/reboot_in_progress note # debconf-get-selections --installer > file # debconf-get-selections >> file +libssl1.0.0 libssl1.0.0/restart-services string +libssl1.0.0:amd64 libssl1.0.0/restart-services string + +libssl1.0.0 libssl1.0.0/restart-failed error +libssl1.0.0:amd64 libssl1.0.0/restart-failed error #### Advanced options ### Running custom commands during the installation diff --git a/tools/appliance/definitions/systemvmtemplate/base.sh b/tools/appliance/definitions/systemvmtemplate/base.sh index bc03ffe9ac..8166081cdc 100644 --- a/tools/appliance/definitions/systemvmtemplate/base.sh +++ b/tools/appliance/definitions/systemvmtemplate/base.sh @@ -1,6 +1,10 @@ # Update the box -apt-get -y update -apt-get -y install curl unzip + +export DEBIAN_FRONTEND=noninteractive +export DEBIAN_PRIORITY=critical + +apt-get -q -y --force-yes update +apt-get -q -y --force-yes install curl unzip apt-get clean # Set up sudo, TODO: Check security concerns diff --git a/tools/appliance/definitions/systemvmtemplate/definition.rb b/tools/appliance/definitions/systemvmtemplate/definition.rb index c8b24d6268..fcaab4d0c3 100644 --- a/tools/appliance/definitions/systemvmtemplate/definition.rb +++ b/tools/appliance/definitions/systemvmtemplate/definition.rb @@ -4,7 +4,7 @@ :disk_size => '2500', :disk_format => 'VDI', :hostiocache => 'off', :os_type_id => 'Debian', :iso_file => "debian-7.4.0-i386-netinst.iso", - :iso_src => "http://ftp.acc.umu.se/mirror/cdimage/release/7.4.0/i386/iso-cd/debian-7.4.0-i386-netinst.iso", + :iso_src => "http://cdimage.debian.org/mirror/cdimage/archive/7.4.0/i386/iso-cd/debian-7.4.0-i386-netinst.iso", :iso_md5 => "7339b668a81b417ac023d73739dc6a03", :iso_download_timeout => "1000", :boot_wait => "10", :boot_cmd_sequence => [ diff --git a/tools/appliance/definitions/systemvmtemplate/postinstall.sh b/tools/appliance/definitions/systemvmtemplate/postinstall.sh index 23e66dd288..b3edeb7852 100644 --- a/tools/appliance/definitions/systemvmtemplate/postinstall.sh +++ b/tools/appliance/definitions/systemvmtemplate/postinstall.sh @@ -178,6 +178,16 @@ fix_vhdutil() { chmod a+x /bin/vhd-util } +# Preload these module otherwise the sysctl settings will not be set, and pasive ftp will not work. +fix_modules() { + cat >> /etc/modules << EOF +nf_conntrack_ipv4 +nf_conntrack +nf_conntrack_ftp +nf_nat_ftp +EOF +} + do_fixes() { fix_nameserver fix_inittab @@ -185,6 +195,7 @@ do_fixes() { fix_hostname fix_locale fix_vhdutil + fix_modules } configure_apache2() { diff --git a/tools/appliance/definitions/systemvmtemplate/preseed.cfg b/tools/appliance/definitions/systemvmtemplate/preseed.cfg index 6996565aaa..deb2f94d49 100644 --- a/tools/appliance/definitions/systemvmtemplate/preseed.cfg +++ b/tools/appliance/definitions/systemvmtemplate/preseed.cfg @@ -335,6 +335,12 @@ d-i finish-install/reboot_in_progress note # debconf-get-selections >> file +libssl1.0.0 libssl1.0.0/restart-services string +libssl1.0.0:i386 libssl1.0.0/restart-services string + +libssl1.0.0 libssl1.0.0/restart-failed error +libssl1.0.0:i386 libssl1.0.0/restart-failed error + #### Advanced options ### Running custom commands during the installation # d-i preseeding is inherently not secure. Nothing in the installer checks diff --git a/tools/devcloud-kvm/devcloud-kvm-advanced-fusion.cfg b/tools/devcloud-kvm/devcloud-kvm-advanced-fusion.cfg index 53e1a441b2..2084417cbe 100644 --- a/tools/devcloud-kvm/devcloud-kvm-advanced-fusion.cfg +++ b/tools/devcloud-kvm/devcloud-kvm-advanced-fusion.cfg @@ -120,20 +120,14 @@ "port": 3306, "user": "cloud" }, - "logger": [ - { - "name": "TestClient", - "file": "/var/log/testclient.log" - }, - { - "name": "TestCase", - "file": "/var/log/testcase.log" - } - ], + "logger": { + "LogFolderPath": "/tmp/" + }, "mgtSvr": [ { "mgtSvrIp": "172.17.10.10", - "port": 8096 + "port": 8096, + "hypervisor": "kvm" } ] } diff --git a/tools/devcloud-kvm/devcloud-kvm-advanced.cfg b/tools/devcloud-kvm/devcloud-kvm-advanced.cfg index 53e1a441b2..74c36b718d 100644 --- a/tools/devcloud-kvm/devcloud-kvm-advanced.cfg +++ b/tools/devcloud-kvm/devcloud-kvm-advanced.cfg @@ -133,7 +133,8 @@ "mgtSvr": [ { "mgtSvrIp": "172.17.10.10", - "port": 8096 + "port": 8096, + "hypervisor": "kvm" } ] } diff --git a/tools/devcloud-kvm/devcloud-kvm.cfg b/tools/devcloud-kvm/devcloud-kvm.cfg index 3122e5a979..ab7f9a5276 100644 --- a/tools/devcloud-kvm/devcloud-kvm.cfg +++ b/tools/devcloud-kvm/devcloud-kvm.cfg @@ -104,7 +104,8 @@ "mgtSvr": [ { "mgtSvrIp": "127.0.0.1", - "port": 8096 + "port": 8096, + "hypervisor": "kvm" } ], "dbSvr": diff --git a/tools/devcloud/devcloud-advanced_juniper-contrail.cfg b/tools/devcloud/devcloud-advanced_juniper-contrail.cfg new file mode 100644 index 0000000000..35b551a2aa --- /dev/null +++ b/tools/devcloud/devcloud-advanced_juniper-contrail.cfg @@ -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. +# +# This configuration is meant for running advanced networking , with management server on the laptop, +# It requires that the user run a DNS resolver within devcloud via 'apt-get install dnsmasq' +# +# +{ + "zones": [ + { + "localstorageenabled": "true", + "name": "default", + "dns1": "8.8.8.8", + "physical_networks": [ + { + "broadcastdomainrange": "Zone", + "name": "ip-fabric", + "traffictypes": [ + { + "xen": "Pool-wide network associated with eth0", + "typ": "Management" + }, + { + "xen": "Pool-wide network associated with eth0", + "typ": "Guest" + }, + { + "xen": "Pool-wide network associated with eth1", + "typ": "Public" + } + ], + "providers": [ + { + "broadcastdomainrange": "ZONE", + "name": "JuniperContrailRouter" + } + ], + "isolationmethods": [ + "L3VPN" + ] + } + ], + "ipranges": [ + { + "startip": "10.0.3.100", + "endip": "10.0.3.199", + "netmask": "255.255.255.0", + "vlan": "untagged", + "gateway": "10.0.3.2" + } + ], + "networktype": "Advanced", + "pods": [ + { + "endip": "192.168.56.249", + "name": "a6", + "startip": "192.168.56.200", + "netmask": "255.255.255.0", + "clusters": [ + { + "clustername": "a6-xen", + "hypervisor": "XenServer", + "hosts": [ + { + "username": "root", + "url": "http://192.168.56.10/", + "password": "password" + } + ], + "clustertype": "CloudManaged" + } + ], + "gateway": "192.168.56.1" + } + ], + "internaldns1": "192.168.56.10", + "secondaryStorages": [ + { + "url": "nfs://192.168.56.10:/opt/storage/secondary", + "provider": "NFS", + "details": [ ] + } + ] + } + ], + "dbSvr": { + "dbSvr": "127.0.0.1", + "passwd": "cloud", + "db": "cloud", + "port": 3306, + "user": "cloud" + }, + "logger": [ + { + "name": "TestClient", + "file": "/var/log/testclient.log" + }, + { + "name": "TestCase", + "file": "/var/log/testcase.log" + } + ], + "mgtSvr": [ + { + "mgtSvrIp": "127.0.0.1", + "port": 8096 + } + ] +} diff --git a/tools/marvin/marvin/__init__.py b/tools/marvin/marvin/__init__.py index 7af168e20b..7102e3f310 100644 --- a/tools/marvin/marvin/__init__.py +++ b/tools/marvin/marvin/__init__.py @@ -15,4 +15,4 @@ # specific language governing permissions and limitations # under the License. -#Marvin - The cloudstack test client +# Marvin - The cloudstack test client diff --git a/tools/marvin/marvin/asyncJobMgr.py b/tools/marvin/marvin/asyncJobMgr.py index e24170e18f..00e8c19b3c 100644 --- a/tools/marvin/marvin/asyncJobMgr.py +++ b/tools/marvin/marvin/asyncJobMgr.py @@ -16,7 +16,7 @@ # under the License. import threading -import cloudstackException +from marvin import cloudstackException import time import Queue import copy @@ -26,12 +26,14 @@ class job(object): + def __init__(self): self.id = None self.cmd = None class jobStatus(object): + def __init__(self): self.result = None self.status = None @@ -47,6 +49,7 @@ def __str__(self): class workThread(threading.Thread): + def __init__(self, in_queue, outqueue, apiClient, db=None, lock=None): threading.Thread.__init__(self) self.inqueue = in_queue @@ -62,7 +65,7 @@ def queryAsynJob(self, job): try: self.lock.acquire() result = self.connection.poll(job.jobId, job.responsecls).jobresult - except cloudstackException.cloudstackAPIException, e: + except cloudstackException.CloudstackAPIException as e: result = str(e) finally: self.lock.release() @@ -102,7 +105,7 @@ def executeCmd(self, job): except: pass jobstatus.status = True - except cloudstackException.cloudstackAPIException, e: + except cloudstackException.CloudstackAPIException as e: jobstatus.result = str(e) jobstatus.status = False except: @@ -129,6 +132,7 @@ def run(self): class jobThread(threading.Thread): + def __init__(self, inqueue, interval): threading.Thread.__init__(self) self.inqueue = inqueue @@ -149,12 +153,14 @@ def run(self): class outputDict(object): + def __init__(self): self.lock = threading.Condition() self.dict = {} class asyncJobMgr(object): + def __init__(self, apiClient, db): self.inqueue = Queue.Queue() self.output = outputDict() diff --git a/tools/marvin/marvin/cloudstackConnection.py b/tools/marvin/marvin/cloudstackConnection.py index fb03e3be3a..c49edf3a40 100644 --- a/tools/marvin/marvin/cloudstackConnection.py +++ b/tools/marvin/marvin/cloudstackConnection.py @@ -21,21 +21,28 @@ import hmac import hashlib import time -import cloudstackException -from cloudstackAPI import * +from cloudstackAPI import queryAsyncJobResult import jsonHelper -from requests import ( - ConnectionError, - HTTPError, - Timeout, - RequestException - ) +from marvin.codes import ( + FAILED, + JOB_FAILED, + JOB_CANCELLED, + JOB_SUCCEEDED +) +from marvin.cloudstackException import ( + InvalidParameterException, + GetDetailExceptionInfo) -class cloudConnection(object): +class CSConnection(object): + + ''' + @Desc: Connection Class to make API\Command calls to the + CloudStack Management Server + Sends the GET\POST requests to CS based upon the + information provided and retrieves the parsed response. + ''' - """ Connections to make API calls to the cloudstack management server - """ def __init__(self, mgmtDet, asyncTimeout=3600, logger=None, path='client/api'): self.apiKey = mgmtDet.apiKey @@ -44,238 +51,328 @@ def __init__(self, mgmtDet, asyncTimeout=3600, logger=None, self.port = mgmtDet.port self.user = mgmtDet.user self.passwd = mgmtDet.passwd - self.certCAPath = mgmtDet.certCAPath - self.certPath = mgmtDet.certPath + self.certPath = () + if mgmtDet.certCAPath != "NA" and mgmtDet.certPath != "NA": + self.certPath = (mgmtDet.certCAPath, mgmtDet.certPath) self.logger = logger self.path = path self.retries = 5 + self.__lastError = '' self.mgtDetails = mgmtDet - self.protocol = "http" self.asyncTimeout = asyncTimeout self.auth = True if self.port == 8096 or \ (self.apiKey is None and self.securityKey is None): self.auth = False - if mgmtDet.useHttps == "True": - self.protocol = "https" - self.baseurl = "%s://%s:%d/%s"\ + self.protocol = "https" if mgmtDet.useHttps == "True" else "http" + self.httpsFlag = True if self.protocol == "https" else False + self.baseUrl = "%s://%s:%d/%s"\ % (self.protocol, self.mgtSvr, self.port, self.path) def __copy__(self): - return cloudConnection(self.mgtDetails, - self.asyncTimeout, - self.logger, - self.path) - - def poll(self, jobid, response): - """ - polls the completion of a given jobid - @param jobid: - @param response: - @return: - """ - cmd = queryAsyncJobResult.queryAsyncJobResultCmd() - cmd.jobid = jobid - timeout = self.asyncTimeout - - while timeout > 0: - asyncResonse = self.marvinRequest(cmd, response_type=response) + return CSConnection(self.mgtDetails, + self.asyncTimeout, + self.logger, + self.path) - if asyncResonse.jobstatus == 2: - raise cloudstackException.cloudstackAPIException( - "asyncquery", asyncResonse.jobresult) - elif asyncResonse.jobstatus == 1: - return asyncResonse - - time.sleep(5) - if self.logger is not None: - self.logger.debug("job: %s still processing," - "will timeout in %ds" % (jobid, timeout)) - timeout = timeout - 5 + def __poll(self, jobid, response_cmd): + ''' + @Name : __poll + @Desc: polls for the completion of a given jobid + @Input 1. jobid: Monitor the Jobid for CS + 2. response_cmd:response command for request cmd + @return: FAILED if jobid is cancelled,failed + Else return async_response + ''' + try: + cmd = queryAsyncJobResult.queryAsyncJobResultCmd() + cmd.jobid = jobid + timeout = self.asyncTimeout + start_time = time.time() + end_time = time.time() + async_response = FAILED + self.logger.debug("=== Jobid: %s Started ===" % (str(jobid))) + while timeout > 0: + async_response = self.\ + marvinRequest(cmd, response_type=response_cmd) + if async_response != FAILED: + job_status = async_response.jobstatus + if job_status in [JOB_CANCELLED, + JOB_SUCCEEDED]: + break + elif job_status == JOB_FAILED: + raise Exception("Job failed: %s"\ + % async_response) + time.sleep(5) + timeout -= 5 + self.logger.debug("=== JobId:%s is Still Processing, " + "Will TimeOut in:%s ====" % (str(jobid), + str(timeout))) + end_time = time.time() + tot_time = int(start_time - end_time) + self.logger.debug( + "===Jobid:%s ; StartTime:%s ; EndTime:%s ; " + "TotalTime:%s===" % + (str(jobid), str(time.ctime(start_time)), + str(time.ctime(end_time)), str(tot_time))) + return async_response + except Exception as e: + self.__lastError = e + self.logger.exception("==== __poll: Exception Occurred :%s ====" % + str(self.__lastError)) + return FAILED - raise cloudstackException.cloudstackAPIException( - "asyncquery", "Async job timeout %s" % jobid) + def getLastError(self): + ''' + @Name : getLastError + @Desc : Returns the last error from marvinRequest + ''' + return self.__lastError - def sign(self, payload): + def __sign(self, payload): """ - signs a given request URL when the apiKey and secretKey are known - - @param payload: dict of GET params to be signed - @return: the signature of the payload + @Name : __sign + @Desc:signs a given request URL when the apiKey and + secretKey are known + @Input: payload: dictionary of params be signed + @Output: the signature of the payload """ params = zip(payload.keys(), payload.values()) params.sort(key=lambda k: str.lower(k[0])) - hashStr = "&".join( + hash_str = "&".join( ["=".join( [str.lower(r[0]), str.lower( urllib.quote_plus(str(r[1])) - ).replace("+", "%20")] + ).replace("+", "%20")] ) for r in params] ) signature = base64.encodestring(hmac.new( - self.securityKey, hashStr, hashlib.sha1).digest()).strip() - self.logger.debug("Computed Signature by Marvin: %s" % signature) + self.securityKey, hash_str, hashlib.sha1).digest()).strip() return signature - def request(self, command, auth=True, payload={}, method='GET'): + def __sendPostReqToCS(self, url, payload): + ''' + @Name : __sendPostReqToCS + @Desc : Sends the POST Request to CS + @Input : url: URL to send post req + payload:Payload information as part of request + @Output: Returns response from POST output + else FAILED + ''' + try: + response = requests.post(url, + params=payload, + cert=self.certPath, + verify=self.httpsFlag) + return response + except Exception as e: + self.__lastError = e + self.logger.\ + exception("__sendPostReqToCS : Exception " + "Occurred: %s" % str(self.__lastError)) + return FAILED + + def __sendGetReqToCS(self, url, payload): + ''' + @Name : __sendGetReqToCS + @Desc : Sends the GET Request to CS + @Input : url: URL to send post req + payload:Payload information as part of request + @Output: Returns response from GET output + else FAILED + ''' + try: + response = requests.get(url, + params=payload, + cert=self.certPath, + verify=self.httpsFlag) + return response + except Exception as e: + self.__lastError = e + self.logger.exception("__sendGetReqToCS : Exception Occurred: %s" % + str(self.__lastError)) + return FAILED + + def __sendCmdToCS(self, command, auth=True, payload={}, method='GET'): """ - Makes requests using auth or over integration port - @param command: cloudstack API command name + @Name : __sendCmdToCS + @Desc : Makes requests to CS using the Inputs provided + @Input: command: cloudstack API command name eg: deployVirtualMachineCommand - @param auth: Authentication (apikey,secretKey) => True + auth: Authentication (apikey,secretKey) => True else False for integration.api.port - @param payload: request data composed as a dictionary - @param method: GET/POST via HTTP - @return: + payload: request data composed as a dictionary + method: GET/POST via HTTP + @output: FAILED or else response from CS """ - payload["command"] = command - payload["response"] = "json" - - if auth: - payload["apiKey"] = self.apiKey - signature = self.sign(payload) - payload["signature"] = signature - try: - #https_flag : Signifies whether to verify connection over \ - #http or https, \ - #initialized to False, will be set to true if user provided https - #connection - https_flag = False - cert_path = () - if self.protocol == "https": - https_flag = True - if self.certCAPath != "NA" and self.certPath != "NA": - cert_path = (self.certCAPath, self.certPath) + payload["command"] = command + payload["response"] = "json" + + if auth: + payload["apiKey"] = self.apiKey + payload["signature"] = self.__sign(payload) - #Verify whether protocol is "http", then call the request over http - if self.protocol == "http": + # Verify whether protocol is "http" or "https", then send the + # request + if self.protocol in ["http", "https"]: + self.logger.debug("Payload: %s" % str(payload)) if method == 'POST': - response = requests.post(self.baseurl, params=payload, - verify=https_flag) - else: - response = requests.get(self.baseurl, params=payload, - verify=https_flag) + self.logger.debug("=======Sending POST Cmd : %s=======" + % str(command)) + return self.__sendPostReqToCS(self.baseUrl, payload) + if method == "GET": + self.logger.debug("========Sending GET Cmd : %s=======" + % str(command)) + return self.__sendGetReqToCS(self.baseUrl, payload) else: - ''' - If protocol is https, then create the connection url with \ - user provided certificates \ - provided as part of cert - ''' - try: - if method == 'POST': - response = requests.post(self.baseurl, - params=payload, - cert=cert_path, - verify=https_flag) - else: - response = requests.get(self.baseurl, params=payload, - cert=cert_path, - verify=https_flag) - except Exception, e: - ''' - If an exception occurs with user provided CA certs, \ - then try with default certs, \ - we dont need to mention here the cert path - ''' - self.logger.debug("Creating CS connection over https \ - didnt worked with user provided certs \ - , so trying with no certs %s" % e) - if method == 'POST': - response = requests.post(self.baseurl, - params=payload, - verify=https_flag) - else: - response = requests.get(self.baseurl, - params=payload, - verify=https_flag) - except ConnectionError, c: - self.logger.debug("Connection refused. Reason: %s : %s" % - (self.baseurl, c)) - raise c - except HTTPError, h: - self.logger.debug("Http Error.Server returned error code: %s" % h) - raise h - except Timeout, t: - self.logger.debug("Connection timed out with %s" % t) - raise t - except RequestException, r: - self.logger.debug("RequestException from server %s" % r) - raise r - except Exception, e: - self.logger.debug("Error returned by server %s" % r) - raise e - else: - return response + self.logger.exception("__sendCmdToCS: Invalid Protocol") + return FAILED + except Exception as e: + self.__lastError = e + self.logger.exception("__sendCmdToCS: Exception:%s" % + GetDetailExceptionInfo(e)) + return FAILED - def sanitizeCommand(self, cmd): + def __sanitizeCmd(self, cmd): """ - Removes None values, Validates all required params are present - @param cmd: Cmd object eg: createPhysicalNetwork - @return: + @Name : __sanitizeCmd + @Desc : Removes None values, Validates all required params are present + @Input: cmd: Cmd object eg: createPhysicalNetwork + @Output: Returns command name, asynchronous or not,request payload + FAILED for failed cases """ - requests = {} - required = [] - for attribute in dir(cmd): - if not attribute.startswith('__'): - if attribute == "isAsync": - isAsync = getattr(cmd, attribute) - elif attribute == "required": - required = getattr(cmd, attribute) - else: - requests[attribute] = getattr(cmd, attribute) - - cmdname = cmd.__class__.__name__.replace("Cmd", "") - for requiredPara in required: - if requests[requiredPara] is None: - raise cloudstackException.cloudstackAPIException( - cmdname, "%s is required" % requiredPara) - for param, value in requests.items(): - if value is None: - requests.pop(param) - elif isinstance(value, list): - if len(value) == 0: - requests.pop(param) - else: - if not isinstance(value[0], dict): - requests[param] = ",".join(value) + try: + cmd_name = '' + payload = {} + required = [] + isAsync = "false" + for attribute in dir(cmd): + if not attribute.startswith('__'): + if attribute == "isAsync": + isAsync = getattr(cmd, attribute) + elif attribute == "required": + required = getattr(cmd, attribute) else: - requests.pop(param) - i = 0 - for val in value: - for k, v in val.iteritems(): - requests["%s[%d].%s" % (param, i, k)] = v - i = i + 1 - return cmdname.strip(), isAsync, requests + payload[attribute] = getattr(cmd, attribute) + cmd_name = cmd.__class__.__name__.replace("Cmd", "") + for required_param in required: + if payload[required_param] is None: + self.logger.debug("CmdName: %s Parameter : %s is Required" + % (cmd_name, required_param)) + self.__lastError = InvalidParameterException( + "Invalid Parameters") + return FAILED + for param, value in payload.items(): + if value is None: + payload.pop(param) + elif isinstance(value, list): + if len(value) == 0: + payload.pop(param) + else: + if not isinstance(value[0], dict): + payload[param] = ",".join(value) + else: + payload.pop(param) + i = 0 + for val in value: + for k, v in val.iteritems(): + payload["%s[%d].%s" % (param, i, k)] = v + i += 1 + return cmd_name.strip(), isAsync, payload + except Exception as e: + self.__lastError = e + self.logger.\ + exception("__sanitizeCmd: CmdName : " + "%s : Exception:%s" % (cmd_name, + GetDetailExceptionInfo(e))) + return FAILED + + def __parseAndGetResponse(self, cmd_response, response_cls, is_async): + ''' + @Name : __parseAndGetResponse + @Desc : Verifies the Response(from CS) and returns an + appropriate json parsed Response + @Input: cmd_response: Command Response from cs + response_cls : Mapping class for this Response + is_async: Whether the cmd is async or not. + @Output:Response output from CS + ''' + try: + try: + ret = jsonHelper.getResultObj( + cmd_response.json(), + response_cls) + except TypeError: + ret = jsonHelper.getResultObj(cmd_response.json, response_cls) + + ''' + If the response is asynchronous, poll and return response + else return response as it is + ''' + if is_async == "false": + self.logger.debug("Response : %s" % str(ret)) + return ret + else: + response = self.__poll(ret.jobid, response_cls) + self.logger.debug("Response : %s" % str(response)) + return response.jobresult if response != FAILED else FAILED + except Exception as e: + self.__lastError = e + self.logger.\ + exception("Exception:%s" % GetDetailExceptionInfo(e)) + return FAILED def marvinRequest(self, cmd, response_type=None, method='GET', data=''): """ - Requester for marvin command objects - @param cmd: marvin's command from cloudstackAPI - @param response_type: response type of the command in cmd - @param method: HTTP GET/POST, defaults to GET - @return: + @Name : marvinRequest + @Desc: Handles Marvin Requests + @Input cmd: marvin's command from cloudstackAPI + response_type: response type of the command in cmd + method: HTTP GET/POST, defaults to GET + @Output: Response received from CS + Exception in case of Error\Exception """ - cmdname, isAsync, payload = self.sanitizeCommand(cmd) - self.logger.debug("sending %s request: %s %s" % (method, cmdname, - str(payload))) - response = self.request(cmdname, - self.auth, - payload=payload, - method=method) - if response is None: - return None - self.logger.debug("Request: %s Response: %s" % (response.url, - response.text)) try: - response = jsonHelper.getResultObj(response.json(), response_type) - except TypeError: - response = jsonHelper.getResultObj(response.json, response_type) + ''' + 1. Verify the Inputs Provided + ''' + if (cmd is None or cmd == '')or \ + (response_type is None or response_type == ''): + self.logger.exception("marvinRequest : Invalid Command Input") + raise InvalidParameterException("Invalid Parameter") - if isAsync == "false": - return response - else: - asyncJobId = response.jobid - response = self.poll(asyncJobId, response_type) - return response.jobresult + ''' + 2. Sanitize the Command + ''' + sanitize_cmd_out = self.__sanitizeCmd(cmd) + + if sanitize_cmd_out == FAILED: + raise self.__lastError + + cmd_name, is_async, payload = sanitize_cmd_out + ''' + 3. Send Command to CS + ''' + cmd_response = self.__sendCmdToCS(cmd_name, + self.auth, + payload=payload, + method=method) + if cmd_response == FAILED: + raise self.__lastError + + ''' + 4. Check if the Command Response received above is valid or Not. + If not return Invalid Response + ''' + ret = self.__parseAndGetResponse(cmd_response, + response_type, + is_async) + if ret == FAILED: + raise self.__lastError + return ret + except Exception as e: + self.logger.exception("marvinRequest : CmdName: %s Exception: %s" % + (str(cmd), GetDetailExceptionInfo(e))) + raise e diff --git a/tools/marvin/marvin/cloudstackException.py b/tools/marvin/marvin/cloudstackException.py index 6200003bbc..331ae91192 100644 --- a/tools/marvin/marvin/cloudstackException.py +++ b/tools/marvin/marvin/cloudstackException.py @@ -15,8 +15,13 @@ # specific language governing permissions and limitations # under the License. +import sys +import traceback +from marvin.codes import (INVALID_INPUT, EXCEPTION_OCCURRED) + + +class CloudstackAPIException(Exception): -class cloudstackAPIException(Exception): def __init__(self, cmd="", result=""): self.errorMsg = "Execute cmd: %s failed, due to: %s" % (cmd, result) @@ -25,6 +30,7 @@ def __str__(self): class InvalidParameterException(Exception): + def __init__(self, msg=''): self.errorMsg = msg @@ -33,6 +39,7 @@ def __str__(self): class dbException(Exception): + def __init__(self, msg=''): self.errorMsg = msg @@ -41,8 +48,42 @@ def __str__(self): class internalError(Exception): + def __init__(self, msg=''): self.errorMsg = msg def __str__(self): return self.errorMsg + + +def GetDetailExceptionInfo(e): + if e is not None: + exc_type, exc_value, exc_traceback = sys.exc_info() + return str(repr(traceback.format_exception( + exc_type, exc_value, exc_traceback))) + else: + return EXCEPTION_OCCURRED + +class CloudstackAclException(): + + NO_PERMISSION_TO_OPERATE_DOMAIN = "does not have permission to operate within domain" + UNABLE_TO_USE_NETWORK = "Unable to use network" + NO_PERMISSION_TO_OPERATE_ACCOUNT = "does not have permission to operate with resource Acct" + UNABLE_TO_LIST_NETWORK_ACCOUNT = "Can't create/list resources for account" + NO_PERMISSION_TO_ACCESS_ACCOUNT = "does not have permission to access resource Acct" + + @staticmethod + def verifyMsginException(e,message): + if message in str(e): + return True + else: + return False + + @staticmethod + def verifyErrorCodeinException(e,errorCode): + errorString = " errorCode: " + errorCode + if errorString in str(e): + return True + else: + return False + diff --git a/tools/marvin/marvin/cloudstackTestCase.py b/tools/marvin/marvin/cloudstackTestCase.py index 6456bb1fe6..5cb4a10928 100644 --- a/tools/marvin/marvin/cloudstackTestCase.py +++ b/tools/marvin/marvin/cloudstackTestCase.py @@ -16,7 +16,7 @@ # under the License. import unittest -from marvin.integration.lib.utils import verifyElementInList +from marvin.lib.utils import verifyElementInList from marvin.codes import PASS @@ -37,7 +37,7 @@ def __init__(self, *args, **kws): class cloudstackTestCase(unittest.case.TestCase): clstestclient = None - def assertElementInList(inp, toverify, responsevar=None, pos=0, + def assertElementInList(inp, toverify, responsevar=None, pos=0, assertmsg="TC Failed for reason"): ''' @Name: assertElementInList @@ -46,7 +46,7 @@ def assertElementInList(inp, toverify, responsevar=None, pos=0, Takes one additional argument of what message to assert with when failed ''' - out = verifyElementInList(inp, toverify, responsevar, pos) + out = verifyElementInList(inp, toverify, responsevar, pos) unittest.TestCase.assertEquals(out[0], PASS, "msg:%s" % out[1]) @classmethod diff --git a/tools/marvin/marvin/cloudstackTestClient.py b/tools/marvin/marvin/cloudstackTestClient.py index 4ac510b03a..807ca5de9e 100644 --- a/tools/marvin/marvin/cloudstackTestClient.py +++ b/tools/marvin/marvin/cloudstackTestClient.py @@ -15,201 +15,434 @@ # specific language governing permissions and limitations # under the License. -import cloudstackConnection -import asyncJobMgr -import dbConnection -from cloudstackAPI import * -import random -import string -import hashlib -from configGenerator import ConfigManager -from marvin.integration.lib.utils import random_gen - -''' -@Desc : CloudStackTestClient is encapsulated class for getting various \ - clients viz., apiclient,dbconnection etc -@Input : mgmtDetails : Management Server Details - dbSvrDetails: Database Server details of Management \ +from marvin.cloudstackConnection import CSConnection +from marvin.asyncJobMgr import asyncJobMgr +from marvin.dbConnection import DbConnection +from marvin.cloudstackAPI import * +from marvin.codes import (FAILED, PASS, ADMIN, DOMAIN_ADMIN, + USER, SUCCESS, XEN_SERVER) +from marvin.configGenerator import ConfigManager +from marvin.cloudstackException import GetDetailExceptionInfo +from marvin.lib.utils import (random_gen, validateList) +from marvin.cloudstackAPI.cloudstackAPIClient import CloudStackAPIClient +import copy + + +class CSTestClient(object): + + ''' + @Desc : CloudStackTestClient is encapsulated entity for creating and + getting various clients viz., apiclient, + user api client, dbconnection, test Data parsed + information etc + @Input : + mgmt_details : Management Server Details + dbsvr_details: Database Server details of Management \ Server. Retrieved from configuration file. - asyncTimeout : - defaultWorkerThreads : - logger : provides logging facilities for this library -''' - - -class cloudstackTestClient(object): - def __init__(self, mgmtDetails, - dbSvrDetails, asyncTimeout=3600, - defaultWorkerThreads=10, - logger=None): - self.mgmtDetails = mgmtDetails - self.connection = \ - cloudstackConnection.cloudConnection(self.mgmtDetails, - asyncTimeout, - logger) - self.apiClient =\ - cloudstackAPIClient.CloudStackAPIClient(self.connection) - self.dbConnection = None - if dbSvrDetails is not None: - self.createDbConnection(dbSvrDetails.dbSvr, dbSvrDetails.port, - dbSvrDetails.user, - dbSvrDetails.passwd, dbSvrDetails.db) - ''' - Provides the Configuration Object to users through getConfigParser - The purpose of this object is to parse the config - and provide dictionary of the config so users can - use that configuration.Users can later call getConfig - on this object and it will return the default parsed - config dictionary from default configuration file, - they can overwrite it with providing their own - configuration file as well. - ''' - self.configObj = ConfigManager() - self.asyncJobMgr = None - self.id = None - self.defaultWorkerThreads = defaultWorkerThreads + async_timeout : Timeout for Async queries + default_worker_threads : Number of worker threads + logger : provides logging facilities for this library + zone : The zone on which test suites using this test client will run + ''' + + def __init__(self, mgmt_details, + dbsvr_details, + async_timeout=3600, + logger=None, + test_data_filepath=None, + zone=None, + hypervisor_type=None): + self.__mgmtDetails = mgmt_details + self.__dbSvrDetails = dbsvr_details + self.__csConnection = None + self.__dbConnection = None + self.__testClient = None + self.__asyncTimeOut = async_timeout + self.__logger = logger + self.__apiClient = None + self.__userApiClient = None + self.__asyncJobMgr = None + self.__id = None + self.__hypervisor = hypervisor_type + self.__testDataFilePath = test_data_filepath + self.__parsedTestDataConfig = None + self.__zone = zone + self.__setHypervisorInfo() @property def identifier(self): - return self.id + return self.__id @identifier.setter def identifier(self, id): - self.id = id + self.__id = id + + def getParsedTestDataConfig(self): + ''' + @Name : getParsedTestDataConfig + @Desc : Provides the TestData Config needed for + Tests are to Run + @Output : Returns the Parsed Test Data Dictionary + ''' + return copy.deepcopy(self.__parsedTestDataConfig) + + def getZoneForTests(self): + ''' + @Name : getZoneForTests + @Desc : Provides the Zone against which Tests are to run + If zone name provided to marvin plugin is none + it will get it from Test Data Config File + Even, if it is not available, return None + @Output : Returns the Zone Name + ''' + return self.__zone + + def getHypervisorInfo(self): + ''' + @Name : getHypervisorInfo + @Desc : Provides the hypervisor Information to test users + @Output : Return Hypervisor Information + ''' + return self.__hypervisor + + def __setHypervisorInfo(self): + ''' + @Name : __setHypervisorInfo + @Desc: Set the HyperVisor details; + default to XenServer + ''' + try: + if not self.__hypervisor: + self.__hypervisor = XEN_SERVER + return SUCCESS + except Exception as e: + print "\n Exception Occurred Under __setHypervisorInfo " \ + "%s" % GetDetailExceptionInfo(e) + return FAILED + + def __createApiClient(self): + try: + ''' + Step1 : Create a CS Connection Object + ''' + mgmt_details = self.__mgmtDetails + self.__csConnection = CSConnection(mgmt_details, + self.__asyncTimeOut, + self.__logger) + + ''' + Step2 : Create API Client with earlier created connection object + ''' + self.__apiClient = CloudStackAPIClient(self.__csConnection) + + ''' + Step3: If API Key is not provided as part of Management Details, + then verify and register + ''' + if mgmt_details.apiKey is None: + list_user = listUsers.listUsersCmd() + list_user.account = "admin" + list_user_res = self.__apiClient.listUsers(list_user) + if list_user_res is None or\ + (validateList(list_user_res)[0] != PASS): + self.__logger.error("__createApiClient: API " + "Client Creation Failed") + return FAILED + user_id = list_user_res[0].id + api_key = list_user_res[0].apikey + security_key = list_user_res[0].secretkey + if api_key is None: + ret = self.__getKeys(user_id) + if ret != FAILED: + mgmt_details.apiKey = ret[0] + mgmt_details.securityKey = ret[1] + else: + self.__logger.error("__createApiClient: API Client " + "Creation Failed while " + "Registering User") + return FAILED + else: + mgmt_details.port = 8080 + mgmt_details.apiKey = api_key + mgmt_details.securityKey = security_key + ''' + Now Create the Connection objects and Api Client using + new details + ''' + self.__csConnection = CSConnection(mgmt_details, + self.__asyncTimeOut, + self.__logger) + self.__apiClient = CloudStackAPIClient(self.__csConnection) + return SUCCESS + except Exception as e: + self.__logger.exception(" Exception Occurred Under " + "__createApiClient: %s" % + GetDetailExceptionInfo(e)) + return FAILED + + def __createDbConnection(self): + ''' + @Name : ___createDbConnection + @Desc : Creates the CloudStack DB Connection + ''' + host = "localhost" if self.__dbSvrDetails.dbSvr is None \ + else self.__dbSvrDetails.dbSvr + port = 3306 if self.__dbSvrDetails.port is None \ + else self.__dbSvrDetails.port + user = "cloud" if self.__dbSvrDetails.user is None \ + else self.__dbSvrDetails.user + passwd = 'cloud' if self.__dbSvrDetails.passwd is None \ + else self.__dbSvrDetails.passwd + db = 'cloud' if self.__dbSvrDetails.db is None \ + else self.__dbSvrDetails.db + self.__dbConnection = DbConnection(host, port, user, passwd, db) + + def __getKeys(self, userid): + ''' + @Name : ___getKeys + @Desc : Retrieves the API and Secret Key for the provided Userid + @Input: userid: Userid to register + @Output: FAILED or tuple with apikey and secretkey + ''' + try: + register_user = registerUserKeys.registerUserKeysCmd() + register_user.id = userid + register_user_res = \ + self.__apiClient.registerUserKeys(register_user) + if not register_user_res: + return FAILED + return (register_user_res.apikey, register_user_res.secretkey) + except Exception as e: + self.__logger.exception("Exception Occurred Under __geKeys : " + "%s" % GetDetailExceptionInfo(e)) + return FAILED + + def createTestClient(self): + ''' + @Name : createTestClient + @Desc : Creates the Test Client. + The test Client is used by test suites + Here we create ParsedTestData Config. + Creates a DB Connection. + Creates an API Client + @Output : FAILED In case of an issue\Failure + SUCCESS in case of Success of this function + ''' + try: + ''' + 1. Create Config Object + Provides the Configuration Object to test suites through + getConfigParser. The purpose of this config object is to + parse the default config and provide dictionary of the + config so users can use that configuration. + Users can later call getConfig on this object and it will + return the default parsed config dictionary from default + configuration file. They can overwrite it with + providing their own configuration file as well. + ''' + ''' + 1. Check Config,Zone,Hypervisor Information + ''' + self.__configObj = ConfigManager(self.__testDataFilePath) + + if not self.__configObj or not self.__hypervisor: + self.__logger.error("createTestClient : " + "Either Hypervisor is None or " + "Not able to create " + "ConfigManager Object") + return FAILED - def createDbConnection(self, host="localhost", port=3306, user='cloud', - passwd='cloud', db='cloud'): - self.dbConnection = dbConnection.dbConnection(host, port, user, - passwd, db) + self.__parsedTestDataConfig = self.__configObj.getConfig() + self.__logger.debug("Parsing Test data successful") + + ''' + 2. Create DB Connection + ''' + self.__createDbConnection() + ''' + 3. Creates API Client + ''' + ret = self.__createApiClient() + if ret == FAILED: + self.__logger.\ + error("==== Test Client Creation Failed ====") + else: + self.__logger.\ + debug("==== Test Client Creation Successful ====") + return ret + except Exception as e: + self.__logger.exception("Exception Occurred " + "Under createTestClient " + ": %s" % GetDetailExceptionInfo(e)) + return FAILED def isAdminContext(self): """ - A user is a regular user if he fails to listDomains; + @Name : isAdminContext + @Desc:A user is a regular user if he fails to listDomains; if he is a domain-admin, he can list only domains that are non-ROOT; if he is an admin, he can list the ROOT domain successfully """ try: listdom = listDomains.listDomainsCmd() listdom.name = 'ROOT' - listdomres = self.apiClient.listDomains(listdom) - rootdom = listdomres[0].name - if rootdom == 'ROOT': - return 1 # admin - else: - return 2 # domain-admin + listdomres = self.__apiClient.listDomains(listdom) + if listdomres != FAILED: + rootdom = listdomres[0].name + if rootdom == 'ROOT': + return ADMIN + else: + return DOMAIN_ADMIN + return USER except: - return 0 # user - - def createUserApiClient(self, UserName, DomainName, acctType=0): - if not self.isAdminContext(): - return self.apiClient + return USER - listDomain = listDomains.listDomainsCmd() - listDomain.listall = True - listDomain.name = DomainName - try: - domains = self.apiClient.listDomains(listDomain) - domId = domains[0].id - except: - cdomain = createDomain.createDomainCmd() - cdomain.name = DomainName - domain = self.apiClient.createDomain(cdomain) - domId = domain.id - - cmd = listAccounts.listAccountsCmd() - cmd.name = UserName - cmd.domainid = domId + def __createUserApiClient(self, UserName, DomainName, acctType=0): + ''' + @Name : ___createUserApiClient + @Desc : Creates a User API Client with given + UserName\DomainName Parameters + @Input: UserName: Username to be created in cloudstack + DomainName: Domain under which the above account be created + accType: Type of Account EX: Root,Non Root etc + @Output: Return the API client for the user + ''' try: - accounts = self.apiClient.listAccounts(cmd) - acctId = accounts[0].id - except: - createAcctCmd = createAccount.createAccountCmd() - createAcctCmd.accounttype = acctType - createAcctCmd.domainid = domId - createAcctCmd.email = "test-" + random_gen()\ - + "@cloudstack.org" - createAcctCmd.firstname = UserName - createAcctCmd.lastname = UserName - createAcctCmd.password = 'password' - createAcctCmd.username = UserName - acct = self.apiClient.createAccount(createAcctCmd) - acctId = acct.id - - listuser = listUsers.listUsersCmd() - listuser.username = UserName - - listuserRes = self.apiClient.listUsers(listuser) - userId = listuserRes[0].id - apiKey = listuserRes[0].apikey - securityKey = listuserRes[0].secretkey - - if apiKey is None: - registerUser = registerUserKeys.registerUserKeysCmd() - registerUser.id = userId - registerUserRes = self.apiClient.registerUserKeys(registerUser) - apiKey = registerUserRes.apikey - securityKey = registerUserRes.secretkey - - mgtDetails = self.mgmtDetails - mgtDetails.apiKey = apiKey - mgtDetails.securityKey = securityKey - - newUserConnection =\ - cloudstackConnection.cloudConnection(mgtDetails, - self.connection.asyncTimeout, - self.connection.logger) - self.userApiClient =\ - cloudstackAPIClient.CloudStackAPIClient(newUserConnection) - self.userApiClient.connection = newUserConnection - self.userApiClient.hypervisor = self.apiClient.hypervisor - return self.userApiClient + if not self.isAdminContext(): + return self.__apiClient + mgmt_details = self.__mgmtDetails + listDomain = listDomains.listDomainsCmd() + listDomain.listall = True + listDomain.name = DomainName + try: + domains = self.__apiClient.listDomains(listDomain) + domId = domains[0].id + except: + cdomain = createDomain.createDomainCmd() + cdomain.name = DomainName + domain = self.__apiClient.createDomain(cdomain) + domId = domain.id + + cmd = listAccounts.listAccountsCmd() + cmd.name = UserName + cmd.domainid = domId + cmd.listall = True + try: + accounts = self.__apiClient.listAccounts(cmd) + acctId = accounts[0].id + except: + createAcctCmd = createAccount.createAccountCmd() + createAcctCmd.accounttype = acctType + createAcctCmd.domainid = domId + createAcctCmd.email = "test-" + random_gen()\ + + "@cloudstack.org" + createAcctCmd.firstname = UserName + createAcctCmd.lastname = UserName + createAcctCmd.password = 'password' + createAcctCmd.username = UserName + acct = self.__apiClient.createAccount(createAcctCmd) + acctId = acct.id + + listuser = listUsers.listUsersCmd() + listuser.username = UserName + + listuserRes = self.__apiClient.listUsers(listuser) + userId = listuserRes[0].id + apiKey = listuserRes[0].apikey + securityKey = listuserRes[0].secretkey + + if apiKey is None: + ret = self.__getKeys(userId) + if ret != FAILED: + mgmt_details.apiKey = ret[0] + mgmt_details.securityKey = ret[1] + else: + self.__logger.error("__createUserApiClient: " + "User API Client Creation." + " While Registering User Failed") + return FAILED + else: + mgmt_details.port = 8080 + mgmt_details.apiKey = apiKey + mgmt_details.securityKey = securityKey + + newUserConnection =\ + CSConnection(mgmt_details, + self.__csConnection.asyncTimeout, + self.__csConnection.logger) + self.__userApiClient = CloudStackAPIClient(newUserConnection) + self.__userApiClient.connection = newUserConnection + self.__userApiClient.hypervisor = self.__hypervisor + return self.__userApiClient + except Exception as e: + self.__logger.exception("Exception Occurred " + "Under getUserApiClient : %s" % + GetDetailExceptionInfo(e)) + return FAILED def close(self): - if self.connection is not None: - self.connection.close() + if self.__csConnection is not None: + self.__csConnection.close() def getDbConnection(self): - return self.dbConnection + ''' + @Name : getDbConnection + @Desc : Retrieves the DB Connection Handle + ''' + return self.__dbConnection def getConfigParser(self): - return self.configObj + ''' + @Name : getConfigParser + @Desc : Provides the ConfigManager Interface to TestClients + ''' + return self.__configObj def getApiClient(self): - self.apiClient.id = self.identifier - return self.apiClient + if self.__apiClient: + self.__apiClient.id = self.identifier + return self.__apiClient + return None - def getUserApiClient(self, account, domain, type=0): + def getUserApiClient(self, UserName=None, DomainName=None, type=0): """ - 0 - user - 1 - admin - 2 - domain admin + @Name : getUserApiClient + @Desc : Provides the User API Client to test Users + 0 - user ; 1 - admin;2 - domain admin + @OutPut : FAILED In case of an issue + else User API Client """ - self.createUserApiClient(account, domain, type) - if hasattr(self, "userApiClient"): - return self.userApiClient - return None + if UserName is None or DomainName is None: + return FAILED + return self.__createUserApiClient(UserName, DomainName, type) def submitCmdsAndWait(self, cmds, workers=1): - '''FixME, httplib has issue if more than one thread submitted''' - if self.asyncJobMgr is None: - self.asyncJobMgr = asyncJobMgr.asyncJobMgr(self.apiClient, - self.dbConnection) - return self.asyncJobMgr.submitCmdsAndWait(cmds, workers) + ''' + @Desc : FixME, httplib has issue if more than one thread submitted + ''' + if self.__asyncJobMgr is None: + self.__asyncJobMgr = asyncJobMgr(self.__apiClient, + self.__dbConnection) + return self.__asyncJobMgr.submitCmdsAndWait(cmds, workers) def submitJob(self, job, ntimes=1, nums_threads=10, interval=1): ''' - submit one job and execute the same job ntimes, with nums_threads - of threads + @Desc : submit one job and execute the same job + ntimes, with nums_threads of threads ''' - if self.asyncJobMgr is None: - self.asyncJobMgr = asyncJobMgr.asyncJobMgr(self.apiClient, - self.dbConnection) - self.asyncJobMgr.submitJobExecuteNtimes(job, ntimes, nums_threads, - interval) + if self.__asyncJobMgr is None: + self.__asyncJobMgr = asyncJobMgr(self.__apiClient, + self.__dbConnection) + self.__asyncJobMgr.submitJobExecuteNtimes(job, ntimes, + nums_threads, + interval) def submitJobs(self, jobs, nums_threads=10, interval=1): - '''submit n jobs, execute them with nums_threads of threads''' - if self.asyncJobMgr is None: - self.asyncJobMgr = asyncJobMgr.asyncJobMgr(self.apiClient, - self.dbConnection) - self.asyncJobMgr.submitJobs(jobs, nums_threads, interval) + ''' + @Desc :submit n jobs, execute them with nums_threads + of threads + ''' + if self.__asyncJobMgr is None: + self.__asyncJobMgr = asyncJobMgr(self.__apiClient, + self.__dbConnection) + self.__asyncJobMgr.submitJobs(jobs, nums_threads, interval) diff --git a/tools/marvin/marvin/codegenerator.py b/tools/marvin/marvin/codegenerator.py index e0f056f66a..e5015c6dfd 100644 --- a/tools/marvin/marvin/codegenerator.py +++ b/tools/marvin/marvin/codegenerator.py @@ -25,6 +25,7 @@ class cmdParameterProperty(object): + def __init__(self): self.name = None self.required = False @@ -34,6 +35,7 @@ def __init__(self): class cloudStackCmd(object): + def __init__(self): self.name = "" self.desc = "" @@ -42,7 +44,8 @@ def __init__(self): self.response = [] -class codeGenerator(object): +class CodeGenerator(object): + """ Apache CloudStack- marvin python classes can be generated from the json returned by API discovery or from the xml spec of commands generated by @@ -208,12 +211,12 @@ def finalize(self): body += self.space + '@property' + self.newline body += self.space + 'def id(self):' + self.newline - body += self.space*2 + 'return self._id' + self.newline + body += self.space * 2 + 'return self._id' + self.newline body += self.newline body += self.space + '@id.setter' + self.newline body += self.space + 'def id(self, identifier):' + self.newline - body += self.space*2 + 'self._id = identifier' + self.newline + body += self.space * 2 + 'self._id = identifier' + self.newline body += self.newline for cmdName in self.cmdsName: @@ -340,7 +343,7 @@ def constructResponseFromJSON(self, response): paramProperty.desc = response['description'] if 'type' in response: if response['type'] in ['list', 'map', 'set']: - #Here list becomes a subproperty + # Here list becomes a subproperty if 'response' in response: for innerResponse in response['response']: subProperty =\ @@ -356,9 +359,9 @@ def loadCmdFromJSON(self, apiStream): jsonOut = apiStream.readlines() assert len(jsonOut) > 0 apiDict = json.loads(jsonOut[0]) - if not 'listapisresponse' in apiDict: + if 'listapisresponse' not in apiDict: raise Exception("API discovery plugin response failed") - if not 'count' in apiDict['listapisresponse']: + if 'count' not in apiDict['listapisresponse']: raise Exception("Malformed api response") apilist = apiDict['listapisresponse']['api'] @@ -394,7 +397,8 @@ def loadCmdFromJSON(self, apiStream): csCmd.request.append(paramProperty) for response in cmd['response']: - #FIXME: ExtractImage related APIs return empty dicts in response + # FIXME: ExtractImage related APIs return empty dicts in + # response if len(response) > 0: paramProperty = self.constructResponseFromJSON(response) csCmd.response.append(paramProperty) @@ -409,11 +413,11 @@ def generateCodeFromJSON(self, endpointUrl): @return: The classes in cloudstackAPI/ formed from api discovery json """ if endpointUrl.find('response=json') >= 0: - apiStream = urllib2.urlopen(endpointUrl) - cmds = self.loadCmdFromJSON(apiStream) - for cmd in cmds: - self.generate(cmd) - self.finalize() + apiStream = urllib2.urlopen(endpointUrl) + cmds = self.loadCmdFromJSON(apiStream) + for cmd in cmds: + self.generate(cmd) + self.finalize() def getText(elements): @@ -454,7 +458,7 @@ def getText(elements): print parser.print_help() exit(1) - cg = codeGenerator(folder) + cg = CodeGenerator(folder) if options.spec is not None: cg.generateCodeFromXML(apiSpecFile) elif options.endpoint is not None: diff --git a/tools/marvin/marvin/codes.py b/tools/marvin/marvin/codes.py index e4a0f6a789..a7e8ec8a67 100644 --- a/tools/marvin/marvin/codes.py +++ b/tools/marvin/marvin/codes.py @@ -30,7 +30,28 @@ @DateAdded: 20th October 2013 """ +''' +VM STATES - START +''' RUNNING = "Running" +STOPPED = "Stopped" +STOPPING = "Stopping" +STARTING = "Starting" +DESTROYED = "Destroyed" +EXPUNGING = "Expunging" +''' +VM STATES - END +''' + +''' +Snapshot States - START +''' +BACKED_UP = "backedup" +BACKING_UP = "backingup" +''' +Snapshot States - END +''' + RECURRING = "RECURRING" ENABLED = "Enabled" NETWORK_OFFERING = "network_offering" @@ -47,8 +68,45 @@ FAILED = "FAILED" UNKNOWN_ERROR = "Unknown Error" EXCEPTION = "EXCEPTION" +INVALID_RESPONSE = "Invalid Response" +''' +Async Job Related Codes +''' +JOB_INPROGRESS = 0 +JOB_SUCCEEDED = 1 +JOB_FAILED = 2 +JOB_CANCELLED = 3 +''' +User Related Codes +''' BASIC_ZONE = "basic" ISOLATED_NETWORK = "ISOLATED" SHARED_NETWORK = "SHARED" VPC_NETWORK = "VPC" -ERROR_NO_HOST_FOR_MIGRATION = "Could not find suitable host for migration, please ensure setup has required no. of hosts" +ERROR_NO_HOST_FOR_MIGRATION = \ + "Could not find suitable host for migration, " \ + "please ensure setup has required no. of hosts" +NAT_RULE = "nat rule" +STATIC_NAT_RULE = "static nat rule" +UNKNOWN = "UNKNOWN" +FAULT = "FAULT" +MASTER = "MASTER" +ADMIN = 1 +DOMAIN_ADMIN = 2 +USER = 0 +XEN_SERVER = "XenServer" +ADMIN_ACCOUNT = 'ADMIN_ACCOUNT' +USER_ACCOUNT = 'USER_ACCOUNT' +RESOURCE_CPU = 8 +RESOURCE_MEMORY = 9 +RESOURCE_PRIMARY_STORAGE = 10 +RESOURCE_SECONDARY_STORAGE = 11 +KVM = "kvm" +VMWARE = "vmware" +ROOT_DOMAIN_ADMIN="root domain admin" +CHILD_DOMAIN_ADMIN="child domain admin" + +''' +Network states +''' +ALLOCATED = "Allocated" diff --git a/tools/marvin/marvin/integration/lib/__init__.py b/tools/marvin/marvin/config/__init__.py similarity index 99% rename from tools/marvin/marvin/integration/lib/__init__.py rename to tools/marvin/marvin/config/__init__.py index 978b68af62..13a83393a9 100644 --- a/tools/marvin/marvin/integration/lib/__init__.py +++ b/tools/marvin/marvin/config/__init__.py @@ -5,9 +5,9 @@ # 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 diff --git a/tools/marvin/marvin/config/config.cfg b/tools/marvin/marvin/config/config.cfg deleted file mode 100644 index 356a291191..0000000000 --- a/tools/marvin/marvin/config/config.cfg +++ /dev/null @@ -1,392 +0,0 @@ -# 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. -# -# Use the common configs added such as account, network_offerings, domain, project, -# or add your own data if required separately for any test case -{ - "domain": - { - "name": "domain" - } - , - "project": - { - "name": "Project", - "displaytext": "Test project" - }, - "account": { - "email": "test-account@test.com", - "firstname": "test", - "lastname": "test", - "username": "test-account", - "password": "password" - }, - "service_offering": { - "name": "Tiny Instance", - "displaytext": "Tiny Instance", - "cpunumber": 1, - "cpuspeed": 100, - "memory": 128 - }, - "isolated_network_offering": { - "name": "Isolated Network offering", - "displaytext": "Isolated Network offering", - "guestiptype": "Isolated", - "supportedservices": "Dhcp,Dns,SourceNat,PortForwarding,Vpn,Firewall,Lb,UserData,StaticNat", - "traffictype": "GUEST", - "availability": "Optional'", - "serviceProviderList": { - "Dhcp": "VirtualRouter", - "Dns": "VirtualRouter", - "SourceNat": "VirtualRouter", - "PortForwarding": "VirtualRouter", - "Vpn": "VirtualRouter", - "Firewall": "VirtualRouter", - "Lb": "VirtualRouter", - "UserData": "VirtualRouter", - "StaticNat": "VirtualRouter" - } - }, - "isolated_network": { - "name": "Isolated Network", - "displaytext": "Isolated Network" - }, - "virtual_machine": { - "displayname": "Test VM", - "username": "root", - "password": "password", - "ssh_port": 22, - "privateport": 22, - "publicport": 22, - "protocol": "TCP" - }, - "shared_network": { - "name": "Test Shared Network", - "displaytext": "Test Shared Network", - "vlan" : "", - "gateway" :"", - "netmask" :"", - "startip" :"", - "endip" :"", - "acltype" : "Domain", - "scope":"all" - }, - "shared_network_offering_sg": { - "name": "SharedNwOffering-sg", - "displaytext": "SharedNwOffering-sg", - "guestiptype": "Shared", - "supportedservices": "Dhcp,Dns,UserData,SecurityGroup", - "specifyVlan" : "False", - "specifyIpRanges" : "False", - "traffictype": "GUEST", - "serviceProviderList" : { - "Dhcp": "VirtualRouter", - "Dns": "VirtualRouter", - "UserData": "VirtualRouter", - "SecurityGroup": "SecurityGroupProvider" - } - }, - "shared_network_sg": { - "name": "Shared-Network-SG-Test", - "displaytext": "Shared-Network_SG-Test", - "networkofferingid":"", - "vlan" : "", - "gateway" :"", - "netmask" :"255.255.255.0", - "startip" :"", - "endip" :"", - "acltype" : "Domain", - "scope":"all" - }, - "vpc_offering": { - "name": "VPC off", - "displaytext": "VPC off", - "supportedservices": "Dhcp,Dns,SourceNat,PortForwarding,Vpn,Lb,UserData,StaticNat,NetworkACL" - }, - "vpc": { - "name": "TestVPC", - "displaytext": "TestVPC", - "cidr": "10.0.0.1/24" - }, - "shared_network_offering": { - "name": "SharedNwOffering", - "displaytext": "SharedNwOffering", - "guestiptype": "Shared", - "supportedservices": "Dhcp,Dns,UserData", - "specifyVlan" : "False", - "specifyIpRanges" : "False", - "traffictype": "GUEST", - "serviceProviderList" : { - "Dhcp": "VirtualRouter", - "Dns": "VirtualRouter", - "UserData": "VirtualRouter" - } - }, - "security_group" : { "name": "custom_Sec_Grp" }, - "ingress_rule": { - "protocol": "TCP", - "startport": "22", - "endport": "22", - "cidrlist": "0.0.0.0/0" - }, - "ostype": "CentOS 5.3 (64-bit)", - "sleep": 90, - "timeout": 10, - "netscaler_VPX": { - "ipaddress": "10.223.240.174", - "username": "nsroot", - "password": "nsroot", - "networkdevicetype": "NetscalerVPXLoadBalancer", - "publicinterface": "1/1", - "privateinterface": "1/2", - "numretries": 2, - "lbdevicededicated": "True", - "lbdevicecapacity": 2, - "port": 22 - }, - "nw_offering_shared_persistent": { - "name": "Network offering for Shared Persistent Network", - "displaytext": "Network offering-DA services", - "guestiptype": "Shared", - "supportedservices": "Dhcp,Dns,SourceNat,PortForwarding,Vpn,Firewall,Lb,UserData,StaticNat", - "traffictype": "GUEST", - "availability": "Optional", - "ispersistent": "True", - "serviceProviderList": { - "Dhcp": "VirtualRouter", - "Dns": "VirtualRouter", - "SourceNat": "VirtualRouter", - "PortForwarding": "VirtualRouter", - "Vpn": "VirtualRouter", - "Firewall": "VirtualRouter", - "Lb": "VirtualRouter", - "UserData": "VirtualRouter", - "StaticNat": "VirtualRouter" - } - }, - "nw_off_isolated_persistent": { - "name": "Network offering for Isolated Persistent Network", - "displaytext": "Network Offering for Isolated Persistent Network", - "guestiptype": "Isolated", - "supportedservices": "Dhcp,Dns,SourceNat,PortForwarding,Vpn,Firewall,Lb,UserData,StaticNat", - "traffictype":"GUEST", - "availability":"Optional", - "ispersistent": "True", - "serviceProviderList": { - "Dhcp": "VirtualRouter", - "Dns": "VirtualRouter", - "SourceNat": "VirtualRouter", - "PortForwarding": "VirtualRouter", - "Vpn": "VirtualRouter", - "Firewall": "VirtualRouter", - "Lb": "VirtualRouter", - "UserData": "VirtualRouter", - "StaticNat": "VirtualRouter" - } - }, - "nw_off_isolated_persistent_netscaler": { - "name": "Network offering for Isolated Persistent Network", - "displaytext": "Network Offering for Isolated Persistent Network", - "guestiptype": "Isolated", - "supportedservices": "Dhcp,Dns,SourceNat,PortForwarding,Vpn,Firewall,Lb,UserData,StaticNat", - "traffictype": "GUEST", - "availability": "Optional", - "ispersistent": "True", - "serviceProviderList": { - "Dhcp": "VirtualRouter", - "Dns": "VirtualRouter", - "SourceNat": "VirtualRouter", - "PortForwarding": "VirtualRouter", - "Vpn": "VirtualRouter", - "Firewall": "VirtualRouter", - "Lb": "Netscaler", - "UserData": "VirtualRouter", - "StaticNat": "VirtualRouter" - } - }, - "nw_offering_isolated": { - "name": "Network offering for Isolated Persistent Network", - "displaytext": "Network offering-DA services", - "guestiptype": "Isolated", - "supportedservices": "Dhcp,Dns,SourceNat,PortForwarding,Vpn,Firewall,Lb,UserData,StaticNat", - "traffictype": "GUEST", - "availability": "Optional", - "serviceProviderList": { - "Dhcp": "VirtualRouter", - "Dns": "VirtualRouter", - "SourceNat": "VirtualRouter", - "PortForwarding": "VirtualRouter", - "Vpn": "VirtualRouter", - "Firewall": "VirtualRouter", - "Lb": "VirtualRouter", - "UserData": "VirtualRouter", - "StaticNat": "VirtualRouter" - } - }, - "nw_off_isolated_netscaler": { - "name": "Network offering for Isolated Persistent Network", - "displaytext": "Network offering-DA services", - "guestiptype": "Isolated", - "supportedservices": "Dhcp,Dns,SourceNat,PortForwarding,Vpn,Firewall,Lb,UserData,StaticNat", - "traffictype": "GUEST", - "availability": "Optional", - "serviceProviderList": { - "Dhcp": "VirtualRouter", - "Dns": "VirtualRouter", - "SourceNat": "VirtualRouter", - "PortForwarding": "VirtualRouter", - "Vpn": "VirtualRouter", - "Firewall": "VirtualRouter", - "Lb": "Netscaler", - "UserData": "VirtualRouter", - "StaticNat": "VirtualRouter" - } - }, - "nw_off_persistent_RVR": { - "name": "Network offering-RVR services", - "displaytext": "Network off-RVR services", - "guestiptype": "Isolated", - "supportedservices": "Vpn,Dhcp,Dns,SourceNat,PortForwarding,Firewall,Lb,UserData,StaticNat", - "traffictype": "GUEST", - "availability": "Optional", - "ispersistent": "True", - "serviceProviderList": { - "Vpn": "VirtualRouter", - "Dhcp": "VirtualRouter", - "Dns": "VirtualRouter", - "SourceNat": "VirtualRouter", - "PortForwarding": "VirtualRouter", - "Firewall": "VirtualRouter", - "Lb": "VirtualRouter", - "UserData": "VirtualRouter", - "StaticNat": "VirtualRouter" - }, - "serviceCapabilityList": { - "SourceNat": { - "SupportedSourceNatTypes": "peraccount", - "RedundantRouter": "true" - }, - "lb": { - "SupportedLbIsolation": "dedicated" - } - } - }, - "nw_off_persistent_VPCVR_NoLB": { - "name": "Persistent Network VPC No LB", - "displaytext": "Persistent Network VPC No LB", - "guestiptype": "Isolated", - "supportedservices": "Dhcp,Dns,SourceNat,PortForwarding,Vpn,UserData,StaticNat,NetworkACL", - "traffictype": "GUEST", - "availability": "Optional", - "ispersistent": "False", - "useVpc": "on", - "serviceProviderList": { - "Dhcp": "VpcVirtualRouter", - "Dns": "VpcVirtualRouter", - "SourceNat": "VpcVirtualRouter", - "PortForwarding": "VpcVirtualRouter", - "Vpn": "VpcVirtualRouter", - "UserData": "VpcVirtualRouter", - "StaticNat": "VpcVirtualRouter", - "NetworkACL": "VpcVirtualRouter" - } - }, - "nw_off_persistent_VPCVR_LB": { - "name": "Persistent Network VPC with LB", - "displaytext": "Persistent Network VPC No LB", - "guestiptype": "Isolated", - "supportedservices": "Dhcp,Dns,SourceNat,PortForwarding,Vpn,Lb,UserData,StaticNat,NetworkACL", - "traffictype": "GUEST", - "availability": "Optional", - "ispersistent": "False", - "useVpc": "on", - "serviceProviderList": { - "Dhcp": "VpcVirtualRouter", - "Dns": "VpcVirtualRouter", - "SourceNat": "VpcVirtualRouter", - "PortForwarding": "VpcVirtualRouter", - "Vpn": "VpcVirtualRouter", - "Lb": "VpcVirtualRouter", - "UserData": "VpcVirtualRouter", - "StaticNat": "VpcVirtualRouter", - "NetworkACL": "VpcVirtualRouter" - } - }, - "nw_offering_isolated_vpc": { - "name": "Isolated Network for VPC", - "displaytext": "Isolated Network for VPC", - "guestiptype": "Isolated", - "supportedservices": "Dhcp,Dns,SourceNat,PortForwarding,Vpn,UserData,StaticNat,NetworkACL", - "traffictype": "GUEST", - "availability": "Optional", - "ispersistent": "False", - "useVpc": "on", - "serviceProviderList": { - "Dhcp": "VpcVirtualRouter", - "Dns": "VpcVirtualRouter", - "SourceNat": "VpcVirtualRouter", - "PortForwarding": "VpcVirtualRouter", - "Vpn": "VpcVirtualRouter", - "UserData": "VpcVirtualRouter", - "StaticNat": "VpcVirtualRouter", - "NetworkACL": "VpcVirtualRouter" - } - }, - "natrule": { - "privateport": 22, - "publicport": 22, - "startport": 22, - "endport": 22, - "protocol": "TCP", - "cidrlist": "0.0.0.0/0" - }, - "fwrule": { - "startport": 22, - "endport": 22, - "cidr": "0.0.0.0/0", - "protocol": "TCP" - }, - "lbrule": { - "name": "SSH", - "alg": "leastconn", - # Algorithm used for load balancing - "privateport": 22, - "publicport": 22, - "openfirewall": "False", - "startport": 22, - "endport": 22, - "protocol": "TCP", - "cidrlist": "0.0.0.0/0" - }, - "icmprule": { - "icmptype": -1, - "icmpcode": -1, - "cidrlist": "0.0.0.0/0", - "protocol": "ICMP" - }, - "host_password": "password", - "advanced_sg": { - "zone": { - "name": "", - "dns1": "8.8.8.8", - "internaldns1": "192.168.100.1", - "networktype": "Advanced", - "securitygroupenabled": "true" - }, - "securitygroupenabled": "true" - } -} diff --git a/tools/marvin/marvin/config/test_data.py b/tools/marvin/marvin/config/test_data.py new file mode 100644 index 0000000000..61c133837d --- /dev/null +++ b/tools/marvin/marvin/config/test_data.py @@ -0,0 +1,1161 @@ +# 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. + +test_data = { + "region": { + "regionid": "2", + "regionname": "Region2", + "regionendpoint": "http://region2:8080/client" + }, + "zone": "NA", + "hypervisor": "XenServer", + "deleteDC": True, + "vdomain": { + "name": "domain" + }, + "domain": {"name": "domain"}, + "email": "test@test.com", + "gateway": "172.1.1.1", + "netmask": "255.255.255.0", + "startip": "172.1.1.10", + "endip": "172.1.1.20", + "regionid": "1", + "vlan": "10", + "isportable": "true", + + "project": { + "name": "Project", + "displaytext": "Test project" + }, + "private_gateway": { + "ipaddress": "172.16.1.2", + "gateway": "172.16.1.1", + "netmask": "255.255.255.0", + "vlan":"10", + "name":"test_private_gateway" + + }, + "account": { + "email": "test-account@test.com", + "firstname": "test", + "lastname": "test", + "username": "test-account", + "password": "password" + }, + "small": { + "displayname": "testserver", + "username": "root", + "password": "password", + "ssh_port": 22, + "hypervisor": "XenServer", + "privateport": 22, + "publicport": 22, + "protocol": 'TCP', + }, + "medium": { + "displayname": "testserver", + "username": "root", + "password": "password", + "ssh_port": 22, + "hypervisor": 'XenServer', + "privateport": 22, + "publicport": 22, + "protocol": 'TCP', + }, + "service_offering": { + "name": "Tiny Instance", + "displaytext": "Tiny Instance", + "cpunumber": 1, + "cpuspeed": 100, # in MHz + "memory": 128, # In MBs + }, + "service_offerings": { + "name": "Tiny Instance", + "displaytext": "Tiny Instance", + "cpunumber": 1, + "cpuspeed": 100, + "memory": 128, + + "tiny": { + "name": "Tiny Instance", + "displaytext": "Tiny Instance", + "cpunumber": 1, + "cpuspeed": 100, + "memory": 128, + }, + "small": { + "name": "Small Instance", + "displaytext": "Small Instance", + "cpunumber": 1, + "cpuspeed": 100, + "memory": 256 + }, + "medium": { + "name": "Medium Instance", + "displaytext": "Medium Instance", + "cpunumber": 1, + "cpuspeed": 100, + "memory": 256, + }, + "big": { + "name": "BigInstance", + "displaytext": "BigInstance", + "cpunumber": 1, + "cpuspeed": 100, + "memory": 512, + }, + "hasmall": { + "name": "HA Small Instance", + "displaytext": "HA Small Instance", + "cpunumber": 1, + "cpuspeed": 100, + "memory": 256, + "hosttags": "ha", + "offerha": True, + }, + }, + "disk_offering": { + "name": "Disk offering", + "displaytext": "Disk offering", + "disksize": 1 + }, + 'resized_disk_offering': { + "displaytext": "Resized", + "name": "Resized", + "disksize": 3 + }, + "network": { + "name": "Test Network", + "displaytext": "Test Network", + "acltype": "Account", + }, + "network2": { + "name": "Test Network Shared", + "displaytext": "Test Network Shared", + "vlan": 1201, + "gateway": "172.16.15.1", + "netmask": "255.255.255.0", + "startip": "172.16.15.21", + "endip": "172.16.15.41", + "acltype": "Account", + }, + "network_offering": { + "name": 'Test Network offering', + "displaytext": 'Test Network offering', + "guestiptype": 'Isolated', + "supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding', + "traffictype": 'GUEST', + "availability": 'Optional', + "serviceProviderList": { + "Dhcp": 'VirtualRouter', + "Dns": 'VirtualRouter', + "SourceNat": 'VirtualRouter', + "PortForwarding": 'VirtualRouter', + }, + }, + "nw_off_isolated_netscaler": { + "name": "Network offering-ns services", + "displaytext": "Network offering-ns services", + "guestiptype": "Isolated", + "supportedservices": + "Dhcp,Dns,SourceNat,PortForwarding,Vpn,Firewall,Lb,UserData,StaticNat", + "traffictype": "GUEST", + "availability": "Optional'", + "serviceProviderList": { + "Dhcp": "VirtualRouter", + "Dns": "VirtualRouter", + "SourceNat": "VirtualRouter", + "PortForwarding": "VirtualRouter", + "Vpn": "VirtualRouter", + "Firewall": "VirtualRouter", + "Lb": "NetScaler", + "UserData": "VirtualRouter", + "StaticNat": "VirtualRouter" + } + }, + "nw_off_isolated_persistent": { + "name": 'Test Nw off isolated persistent', + "displaytext": 'Test Nw off isolated persistent', + "guestiptype": 'Isolated', + "supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding', + "traffictype": 'GUEST', + "ispersistent": 'True', + "availability": 'Optional', + "serviceProviderList": { + "Dhcp": 'VirtualRouter', + "Dns": 'VirtualRouter', + "SourceNat": 'VirtualRouter', + "PortForwarding": 'VirtualRouter', + }, + }, + "isolated_network_offering": { + "name": "Network offering-DA services", + "displaytext": "Network offering-DA services", + "guestiptype": "Isolated", + "supportedservices": + "Dhcp,Dns,SourceNat,PortForwarding,Vpn,Firewall,Lb,UserData,StaticNat", + "traffictype": "GUEST", + "availability": "Optional'", + "serviceProviderList": { + "Dhcp": "VirtualRouter", + "Dns": "VirtualRouter", + "SourceNat": "VirtualRouter", + "PortForwarding": "VirtualRouter", + "Vpn": "VirtualRouter", + "Firewall": "VirtualRouter", + "Lb": "VirtualRouter", + "UserData": "VirtualRouter", + "StaticNat": "VirtualRouter" + } + }, + "network_offering_vlan": { + "name": 'Test Network offering', + "displaytext": 'Test Network offering', + "guestiptype": 'Isolated', + "supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding', + "traffictype": 'GUEST', + "specifyvlan": 'False', + "availability": 'Optional', + "serviceProviderList" : { + "Dhcp": 'VirtualRouter', + "Dns": 'VirtualRouter', + "SourceNat": 'VirtualRouter', + "PortForwarding": 'VirtualRouter', + }, + }, + "network_offering_without_sourcenat": { + "name": 'Test Network offering', + "displaytext": 'Test Network offering', + "guestiptype": 'Isolated', + "supportedservices": 'Dhcp,Dns,UserData', + "traffictype": 'GUEST', + "availability": 'Optional', + "serviceProviderList" : { + "Dhcp": 'VirtualRouter', + "Dns": 'VirtualRouter', + "UserData": 'VirtualRouter', + }, + }, + "isolated_network": { + "name": "Isolated Network", + "displaytext": "Isolated Network" + }, + "netscaler_VPX": { + "ipaddress": "10.223.240.174", + "username": "nsroot", + "password": "nsroot", + "networkdevicetype": "NetscalerVPXLoadBalancer", + "publicinterface": "1/1", + "privateinterface": "1/2", + "numretries": 2, + "lbdevicededicated": "True", + "lbdevicecapacity": 2, + "port": 22 + }, + "network_without_acl": { + "name": "TestNetwork", + "displaytext": "TestNetwork", + }, + "virtual_machine": { + "displayname": "Test VM", + "username": "root", + "password": "password", + "ssh_port": 22, + "privateport": 22, + "publicport": 22, + "protocol": "TCP", + "affinity": { + "name": "webvms", + "type": "host anti-affinity", + }, + }, + "virtual_machine2": { + "name": "testvm2", + "displayname": "Test VM2", + }, + "virtual_machine3": { + "name": "testvm3", + "displayname": "Test VM3", + }, + "server_without_disk": { + "displayname": "Test VM-No Disk", + "username": "root", + "password": "password", + "ssh_port": 22, + "hypervisor": 'XenServer', + "privateport": 22, + "publicport": 22, + "protocol": 'TCP', + }, + "shared_network": { + "name": "MySharedNetwork - Test", + "displaytext": "MySharedNetwork", + "vlan": "", + "gateway": "", + "netmask": "", + "startip": "", + "endip": "", + "acltype": "Domain", + "scope": "all" + }, + "shared_network_offering": { + "name": "MySharedOffering-shared", + "displaytext": "MySharedOffering", + "guestiptype": "Shared", + "supportedservices": "Dhcp,Dns,UserData", + "specifyVlan": "False", + "specifyIpRanges": "False", + "traffictype": "GUEST", + "serviceProviderList": { + "Dhcp": "VirtualRouter", + "Dns": "VirtualRouter", + "UserData": "VirtualRouter" + } + }, + "shared_network_offering_all_services": { + "name": "shaared network offering with services enabled", + "displaytext": "Shard network offering", + "guestiptype": "Shared", + "supportedservices": "Dhcp,Dns,SourceNat,PortForwarding,Vpn,Firewall,Lb,UserData,StaticNat", + "specifyVlan": "False", + "specifyIpRanges": "False", + "traffictype": "GUEST", + "serviceProviderList": { + "Dhcp": "VirtualRouter", + "Dns": "VirtualRouter", + "UserData": "VirtualRouter", + "SourceNat": "VirtualRouter", + "PortForwarding": "VirtualRouter", + "Vpn": "VirtualRouter", + "Firewall": "VirtualRouter", + "Lb": "VirtualRouter", + "UserData": "VirtualRouter", + "StaticNat": "VirtualRouter" + } + }, + "shared_network_offering_sg": { + "name": "MySharedOffering-sg", + "displaytext": "MySharedOffering-sg", + "guestiptype": "Shared", + "supportedservices": "Dhcp,Dns,UserData,SecurityGroup", + "specifyVlan": "False", + "specifyIpRanges": "False", + "traffictype": "GUEST", + "serviceProviderList": { + "Dhcp": "VirtualRouter", + "Dns": "VirtualRouter", + "UserData": "VirtualRouter", + "SecurityGroup": "SecurityGroupProvider" + } + }, + "shared_network_sg": { + "name": "Shared-Network-SG-Test", + "displaytext": "Shared-Network_SG-Test", + "networkofferingid": "1", + "vlan": "", + "gateway": "", + "netmask": "255.255.255.0", + "startip": "", + "endip": "", + "acltype": "Domain", + "scope": "all" + }, + "vpc_offering": { + "name": "VPC off", + "displaytext": "VPC off", + "supportedservices": + "Dhcp,Dns,SourceNat,PortForwarding,Vpn,Lb,UserData,StaticNat,NetworkACL" + }, + "vpc": { + "name": "TestVPC", + "displaytext": "TestVPC", + "cidr": "10.0.0.1/24" + }, + "vpc_network_domain": { + "name": "TestVPC", + "displaytext": "TestVPC", + "cidr": '10.0.0.1/24', + "network_domain": "TestVPC" + }, + "clusters": { + 0: { + "clustername": "Xen Cluster", + "clustertype": "CloudManaged", + "hypervisor": "XenServer", + }, + 1: { + "clustername": "KVM Cluster", + "clustertype": "CloudManaged", + "hypervisor": "KVM", + }, + 2: { + "hypervisor": 'VMware', + "clustertype": 'ExternalManaged', + "username": 'administrator', + "password": 'fr3sca', + "url": 'http://192.168.100.17/CloudStack-Clogeny-Pune/Pune-1', + "clustername": 'VMWare Cluster', + }, + }, + "hosts": { + "xenserver": { + "hypervisor": 'XenServer', + "clustertype": 'CloudManaged', + "url": 'http://192.168.100.211', + "username": "root", + "password": "fr3sca", + }, + "kvm": { + "hypervisor": 'KVM', + "clustertype": 'CloudManaged', + "url": 'http://192.168.100.212', + "username": "root", + "password": "fr3sca", + }, + "vmware": { + "hypervisor": 'VMware', + "clustertype": 'ExternalManaged', + "url": 'http://192.168.100.203', + "username": "administrator", + "password": "fr3sca", + }, + }, + "network_offering_shared": { + "name": 'Test Network offering shared', + "displaytext": 'Test Network offering Shared', + "guestiptype": 'Shared', + "supportedservices": 'Dhcp,Dns,UserData', + "traffictype": 'GUEST', + "specifyVlan": "True", + "specifyIpRanges": "True", + "serviceProviderList": { + "Dhcp": 'VirtualRouter', + "Dns": 'VirtualRouter', + "UserData": 'VirtualRouter', + }, + }, + "nw_off_isolated_RVR": { + "name": "Network offering-RVR services", + "displaytext": "Network off-RVR services", + "guestiptype": "Isolated", + "supportedservices": "Vpn,Dhcp,Dns,SourceNat,PortForwarding,Firewall,Lb,UserData,StaticNat", + "traffictype": "GUEST", + "availability": "Optional", + "ispersistent": "False", + "serviceProviderList": { + "Vpn": "VirtualRouter", + "Dhcp": "VirtualRouter", + "Dns": "VirtualRouter", + "SourceNat": "VirtualRouter", + "PortForwarding": "VirtualRouter", + "Firewall": "VirtualRouter", + "Lb": "VirtualRouter", + "UserData": "VirtualRouter", + "StaticNat": "VirtualRouter" + }, + "serviceCapabilityList": { + "SourceNat": { + "SupportedSourceNatTypes": "peraccount", + "RedundantRouter": "true" + }, + "lb": { + "SupportedLbIsolation": "dedicated" + } + } + }, + "nw_off_persistent_RVR": { + "name": 'Network offering-RVR services', + "displaytext": 'Network off-RVR services', + "guestiptype": 'Isolated', + "supportedservices": + 'Vpn,Dhcp,Dns,SourceNat,PortForwarding,Firewall,Lb,UserData,StaticNat', + "traffictype": 'GUEST', + "ispersistent": 'True', + "availability": 'Optional', + "serviceProviderList": { + "Vpn": 'VirtualRouter', + "Dhcp": 'VirtualRouter', + "Dns": 'VirtualRouter', + "SourceNat": 'VirtualRouter', + "PortForwarding": 'VirtualRouter', + "Firewall": 'VirtualRouter', + "Lb": 'VirtualRouter', + "UserData": 'VirtualRouter', + "StaticNat": 'VirtualRouter', + }, + "serviceCapabilityList": { + "SourceNat": { + "SupportedSourceNatTypes": "peraccount", + "RedundantRouter": "true", + }, + "lb": { + "SupportedLbIsolation": "dedicated" + }, + }, + }, + "nw_offering_isolated_vpc": { + "name": "Isolated Network for VPC", + "displaytext": "Isolated Network for VPC", + "guestiptype": "Isolated", + "supportedservices": "Dhcp,Dns,SourceNat,PortForwarding,Vpn,UserData,StaticNat,NetworkACL", + "traffictype": "GUEST", + "availability": "Optional", + "ispersistent": "False", + "useVpc": "on", + "serviceProviderList": { + "Dhcp": "VpcVirtualRouter", + "Dns": "VpcVirtualRouter", + "SourceNat": "VpcVirtualRouter", + "PortForwarding": "VpcVirtualRouter", + "Vpn": "VpcVirtualRouter", + "UserData": "VpcVirtualRouter", + "StaticNat": "VpcVirtualRouter", + "NetworkACL": "VpcVirtualRouter" + } + }, + "nw_off_persistent_VPCVR_LB": { + "name": "Persistent Network VPC with LB", + "displaytext": "Persistent Network VPC No LB", + "guestiptype": "Isolated", + "supportedservices": "Dhcp,Dns,SourceNat,PortForwarding,Vpn,Lb,UserData,StaticNat,NetworkACL", + "traffictype": "GUEST", + "availability": "Optional", + "ispersistent": "False", + "useVpc": "on", + "serviceProviderList": { + "Dhcp": "VpcVirtualRouter", + "Dns": "VpcVirtualRouter", + "SourceNat": "VpcVirtualRouter", + "PortForwarding": "VpcVirtualRouter", + "Vpn": "VpcVirtualRouter", + "Lb": "VpcVirtualRouter", + "UserData": "VpcVirtualRouter", + "StaticNat": "VpcVirtualRouter", + "NetworkACL": "VpcVirtualRouter" + } + }, + "nw_off_persistent_VPCVR_NoLB": { + "name": "Persistent Network VPC No LB", + "displaytext": "Persistent Network VPC No LB", + "guestiptype": "Isolated", + "supportedservices": "Dhcp,Dns,SourceNat,PortForwarding,Vpn,UserData,StaticNat,NetworkACL", + "traffictype": "GUEST", + "availability": "Optional", + "ispersistent": "False", + "useVpc": "on", + "serviceProviderList": { + "Dhcp": "VpcVirtualRouter", + "Dns": "VpcVirtualRouter", + "SourceNat": "VpcVirtualRouter", + "PortForwarding": "VpcVirtualRouter", + "Vpn": "VpcVirtualRouter", + "UserData": "VpcVirtualRouter", + "StaticNat": "VpcVirtualRouter", + "NetworkACL": "VpcVirtualRouter" + } + }, + "nw_offering_shared_persistent": { + "name": "Network offering for Shared Persistent Network", + "displaytext": "Network offering-DA services", + "guestiptype": "Shared", + "supportedservices": "Dhcp,Dns,SourceNat,PortForwarding,Vpn,Firewall,Lb,UserData,StaticNat", + "traffictype": "GUEST", + "availability": "Optional", + "ispersistent": "True", + "serviceProviderList": { + "Dhcp": "VirtualRouter", + "Dns": "VirtualRouter", + "SourceNat": "VirtualRouter", + "PortForwarding": "VirtualRouter", + "Vpn": "VirtualRouter", + "Firewall": "VirtualRouter", + "Lb": "VirtualRouter", + "UserData": "VirtualRouter", + "StaticNat": "VirtualRouter" + } + }, + "fwrule": { + "startport": 22, + "endport": 22, + "cidr": "0.0.0.0/0", + "protocol": "TCP" + }, + "nw_off_isolated_persistent_netscaler": { + "name": 'Netscaler', + "displaytext": 'Netscaler', + "guestiptype": 'Isolated', + "supportedservices": + 'Dhcp,Dns,SourceNat,PortForwarding,Vpn,Firewall,Lb,UserData,StaticNat', + "traffictype": 'GUEST', + "ispersistent": 'True', + "availability": 'Optional', + "serviceProviderList": { + "Dhcp": 'VirtualRouter', + "Dns": 'VirtualRouter', + "SourceNat": 'VirtualRouter', + "PortForwarding": 'VirtualRouter', + "Vpn": 'VirtualRouter', + "Firewall": 'VirtualRouter', + "Lb": 'Netscaler', + "UserData": 'VirtualRouter', + "StaticNat": 'VirtualRouter', + }, + + }, + "nw_off_persistent_VPCVR_NoLB": { + "name": 'VPC Network offering', + "displaytext": 'VPC Network off', + "guestiptype": 'Isolated', + "supportedservices": + 'Vpn,Dhcp,Dns,SourceNat,PortForwarding,UserData,StaticNat,NetworkACL', + "traffictype": 'GUEST', + "availability": 'Optional', + "ispersistent": 'True', + "useVpc": 'on', + "serviceProviderList": { + "Vpn": 'VpcVirtualRouter', + "Dhcp": 'VpcVirtualRouter', + "Dns": 'VpcVirtualRouter', + "SourceNat": 'VpcVirtualRouter', + "PortForwarding": 'VpcVirtualRouter', + "UserData": 'VpcVirtualRouter', + "StaticNat": 'VpcVirtualRouter', + "NetworkACL": 'VpcVirtualRouter' + }, + + }, + "network_acl_rule": { + "protocol":"TCP", + "traffictype":"ingress", + "cidrlist":"0.0.0.0/0", + "startport":"1", + "endport":"1" + }, + "network_offering_internal_lb": { + "name": "Network offering for internal lb service", + "displaytext": "Network offering for internal lb service", + "guestiptype": "Isolated", + "traffictype": "Guest", + "supportedservices": + "Vpn,Dhcp,Dns,Lb,UserData,SourceNat,StaticNat,PortForwarding,NetworkACL", + "serviceProviderList": { + "Dhcp": "VpcVirtualRouter", + "Dns": "VpcVirtualRouter", + "Vpn": "VpcVirtualRouter", + "UserData": "VpcVirtualRouter", + "Lb": "InternalLbVM", + "SourceNat": "VpcVirtualRouter", + "StaticNat": "VpcVirtualRouter", + "PortForwarding": "VpcVirtualRouter", + "NetworkACL": "VpcVirtualRouter", + }, + "serviceCapabilityList": { + "SourceNat": {"SupportedSourceNatTypes": "peraccount"}, + "Lb": {"lbSchemes": "internal", "SupportedLbIsolation": "dedicated"} + } + }, + "natrule": { + "privateport": 22, + "publicport": 22, + "protocol": "TCP" + }, + "lbrule": { + "name": "SSH", + "alg": "roundrobin", + "privateport": 22, + "publicport": 2222, + "protocol": 'TCP' + }, + "icmprule": { + "icmptype": -1, + "icmpcode": -1, + "cidrlist": "0.0.0.0/0", + "protocol": "ICMP" + }, + "iso": { + "displaytext": "Test ISO", + "name": "ISO", + "url": "http://people.apache.org/~tsp/dummy.iso", + "bootable": False, + "ispublic": False, + "ostype": "CentOS 5.6 (64-bit)", + }, + "iso1": { + "displaytext": "Test ISO 1", + "name": "ISO 1", + "url": "http://people.apache.org/~tsp/dummy.iso", + "isextractable": True, + "isfeatured": True, + "ispublic": True, + "ostype": "CentOS 5.6 (64-bit)", + }, + "iso2": { + "displaytext": "Test ISO 2", + "name": "ISO 2", + "url": "http://people.apache.org/~tsp/dummy.iso", + "isextractable": True, + "isfeatured": True, + "ispublic": True, + "ostype": "CentOS 5.6 (64-bit)", + "mode": 'HTTP_DOWNLOAD', + }, + "isfeatured": True, + "ispublic": True, + "isextractable": True, + "bootable": True, + "passwordenabled": True, + + "template": { + "displaytext": "xs", + "name": "xs", + "passwordenabled": False, + }, + "template_2": { + "displaytext": "Public Template", + "name": "Public template", + "ostype": "CentOS 5.6 (64-bit)", + "isfeatured": True, + "ispublic": True, + "isextractable": True, + "mode": "HTTP_DOWNLOAD", + }, + "templatefilter": 'self', + + "templates": { + "displaytext": 'Template', + "name": 'Template', + "ostype": "CentOS 5.3 (64-bit)", + "templatefilter": 'self', + }, + "templateregister": { + "displaytext": "xs", + "name": "xs", + "passwordenabled": False, + "url": "http://10.147.28.7/templates/ttylinux_pv.vhd", + "format": "VHD" + }, + "security_group": {"name": "custom_Sec_Grp"}, + "ingress_rule": { + "protocol": "TCP", + "startport": "22", + "endport": "22", + "cidrlist": "0.0.0.0/0" + }, + "vpncustomergateway": { + "ipsecpsk": "secreatKey", + "ikepolicy": "aes128-sha1", + "ikelifetime": "86400", + "esppolicy": "aes128-sha1", + "epslifetime": "3600", + "dpd": "false" + }, + "ostype": "CentOS 5.6 (64-bit)", + "sleep": 90, + "timeout": 10, + "page": 1, + "pagesize": 2, + "listall": 'true', + "host_password": "password", + "advanced_sg": { + "zone": { + "name": "", + "dns1": "8.8.8.8", + "internaldns1": "192.168.100.1", + "networktype": "Advanced", + "securitygroupenabled": "true" + }, + "securitygroupenabled": "true" + }, + "vlan": "10", + "portableiprange_vlan": { + "part": ["4090-4091", "4092-4095"], + "full": "4090-4095" + }, + "nfs": { + "url": "nfs://nfs/export/automation/1/testprimary", + "name": "Primary XEN" + }, + "iscsi": { + "url": + "iscsi://192.168.100.21/iqn.2012-01.localdomain.clo-cstack-cos6:iser/1", + "name": "Primary iSCSI" + }, + "volume": {"diskname": "Test Volume"}, + "custom_volume": { + "customdisksize": 1, + "diskname": "Custom disk", + }, + "upload_volume": { + "diskname": "UploadVol", + "format": "VHD", + "url": + "http://10.147.28.7/templates/393d3550-05ef-330f-9b8c-745b0e699759.vhd", + "checksum": "", + }, + "recurring_snapshot": { + "maxsnaps": 2, + "timezone": "US/Arizona", + }, + "volume_offerings": { + 0: {"diskname": "TestDiskServ"}, + }, + "diskdevice": ['/dev/vdc', '/dev/vdb', '/dev/hdb', '/dev/hdc', + '/dev/xvdd', '/dev/cdrom', '/dev/sr0', '/dev/cdrom1'], + + # test_vpc_vpn.py + "vpn_user": { + "username": "test", + "password": "password", + }, + "vpc": { + "name": "vpc_vpn", + "displaytext": "vpc-vpn", + "cidr": "10.1.1.0/24" + }, + "ntwk": { + "name": "tier1", + "displaytext": "vpc-tier1", + "gateway": "10.1.1.1", + "netmask": "255.255.255.192" + }, + "vpc2": { + "name": "vpc2_vpn", + "displaytext": "vpc2-vpn", + "cidr": "10.2.1.0/24" + }, + "ntwk2": { + "name": "tier2", + "displaytext": "vpc-tier2", + "gateway": "10.2.1.1", + "netmask": "255.255.255.192" + }, + "server": { + "displayname": "TestVM", + "username": "root", + "password": "password", + "ssh_port": 22, + "hypervisor": 'XenServer', + "privateport": 22, + "publicport": 22, + "protocol": 'TCP' + }, + "privateport": 22, + "publicport": 22, + "protocol": 'TCP', + "forvirtualnetwork": "true", + "customdisksize": 1, + "diskname": "Test Volume", + "portableIpRange": { + "gateway": "10.223.252.195", + "netmask": "255.255.255.192", + "startip": "10.223.252.196", + "endip": "10.223.252.197", + "vlan": "1001" + }, + "sparse": { + "name": "Sparse Type Disk offering", + "displaytext": + "Sparse Type Disk offering", + "disksize": 1, # in GB + "provisioningtype": "sparse" + }, + "fat": { + "name": "Fat Type Disk offering", + "displaytext": + "Fat Type Disk offering", + "disksize": 1, # in GB + "provisioningtype": "fat" + }, + "sparse_disk_offering": { + "displaytext": "Sparse", + "name": "Sparse", + "provisioningtype": "sparse", + "disksize": 1 + }, + "host_anti_affinity": { + "name": "hostantiaffinity", + "type": "host anti-affinity", + }, + "vgpu":{ + "disk_offering":{ + "displaytext": "Small", + "name": "Small", + "disksize": 1 + }, + "account": { + "email": "test@test.com", + "firstname": "Test", + "lastname": "User", + "username": "test", + # Random characters are appended in create account to + # ensure unique username generated each time + "password": "password", + }, + "vgpu260q": # Create a virtual machine instance with vgpu type as 260q + { + "displayname": "testserver", + "username": "root", # VM creds for SSH + "password": "password", + "ssh_port": 22, + "hypervisor": 'XenServer', + "privateport": 22, + "publicport": 22, + "protocol": 'TCP', + }, + "vgpu140q": # Create a virtual machine instance with vgpu type as 140q + { + "displayname": "testserver", + "username": "root", + "password": "password", + "ssh_port": 22, + "hypervisor": 'XenServer', + "privateport": 22, + "publicport": 22, + "protocol": 'TCP', + }, + "service_offerings": + { + "vgpu260qwin": + { + "name": "Windows Instance with vGPU260Q", + "displaytext": "Windows Instance with vGPU260Q", + "cpunumber": 2, + "cpuspeed": 1600, # in MHz + "memory": 3072, # In MBs + }, + "vgpu140qwin": + { + # Small service offering ID to for change VM + # service offering from medium to small + "name": "Windows Instance with vGPU140Q", + "displaytext": "Windows Instance with vGPU140Q", + "cpunumber": 2, + "cpuspeed": 1600, + "memory": 3072, + } + }, + "diskdevice": ['/dev/vdc', '/dev/vdb', '/dev/hdb', '/dev/hdc', '/dev/xvdd', '/dev/cdrom', '/dev/sr0', '/dev/cdrom1' ], + # Disk device where ISO is attached to instance + "mount_dir": "/mnt/tmp", + "sleep": 60, + "timeout": 10, + #Migrate VM to hostid + "ostype": 'Windows 7 (32-bit)', + # CentOS 5.3 (64-bit) + }, + "vpc_remote_vpn": { + + "name": "TestVPC", + "displaytext": "TestVPC", + "cidr": "192.168.1.1/16" + }, + "vpn_template":{ + "name":"VPNClient_Template", + "displaytext":"VPNClient_Template", + "format":"VHD", + "ostype":"CentOS 5.6 (64-bit)", + "url":"http://nfs1.lab.vmops.com/templates/vpnclient-template-xen-centos56-64bit-with-connection-scripts.vhd", + "isfeatured":"True", + "ispublic":"True", + "isextractable":"True" + }, + "all_rule":{ + "protocol":"ALL", + "cidrlist":"0.0.0.0/0" + }, + "vpc_network_offering":{ + "name":"NET_OFF-RemoteAccessVPNTest", + "displaytext":"NET_OFF-RemoteAccessVPNTest", + "guestiptype":"Isolated", + "supportedservices":"Vpn,Dhcp,Dns,SourceNat,PortForwarding,Lb,UserData,StaticNat,NetworkACL", + "traffictype":"GUEST", + "availability":"Optional", + "useVpc":"on", + "serviceProviderList":{ + "Vpn":"VpcVirtualRouter", + "Dhcp":"VpcVirtualRouter", + "Dns":"VpcVirtualRouter", + "SourceNat":"VpcVirtualRouter", + "PortForwarding":"VpcVirtualRouter", + "Lb":"VpcVirtualRouter", + "UserData":"VpcVirtualRouter", + "StaticNat":"VpcVirtualRouter", + "NetworkACL":"VpcVirtualRouter" + } + }, + "firstnetwork_tier":{ + "gateway":"192.168.10.1", + "netmask":"255.255.255.0" + }, + "zone_vpn":{ + "name":"Adv-Xen-Zone1" + }, + "vpnclient_count": 50, + "config_path":"/hudson/scripts3/auto_xen.cfg", + "acl":{ + #data for domains and accounts + "domain1": { + "name": "D1", + }, + "accountD1": { + "email": "testD1@test.com", + "firstname": "testD1", + "lastname": "Admin", + "username": "testD1", + "password": "password", + "accounttype": "1", + }, + "accountD1A": { + "email": "testD1A@test.com", + "firstname": "testD1A", + "lastname": "User", + "username": "testD1A", + "password": "password", + }, + "accountD1B": { + "email": "testD1B@test.com", + "firstname": "testD1B", + "lastname": "User", + "username": "testD1B", + "password": "password", + }, + "domain11": { + "name": "D11", + }, + "accountD11": { + "email": "testD11@test.com", + "firstname": "testD11", + "lastname": "Admin", + "username": "testD11", + "password": "password", + "accounttype": "1", + }, + "accountD11A": { + "email": "testD11A@test.com", + "firstname": "testD11A", + "lastname": "User", + "username": "testD11A", + "password": "password", + }, + "accountD11B": { + "email": "test11B@test.com", + "firstname": "testD11B", + "lastname": "User", + "username": "testD11B", + "password": "password", + }, + "domain111": { + "name": "D111", + }, + "accountD111": { + "email": "testD111@test.com", + "firstname": "testD111", + "lastname": "Admin", + "username": "testD111", + "password": "password", + }, + "accountD111A": { + "email": "testD111A@test.com", + "firstname": "testD111A", + "lastname": "User", + "username": "testD111A", + "password": "password", + }, + "accountD111B": { + "email": "testD111B@test.com", + "firstname": "testD111B", + "lastname": "User", + "username": "testD111B", + "password": "password", + }, + "domain12": { + "name": "D12", + }, + "accountD12A": { + "email": "testD12A@test.com", + "firstname": "testD12A", + "lastname": "User", + "username": "testD12A", + "password": "password", + }, + "accountD12B": { + "email": "testD12B@test.com", + "firstname": "testD12B", + "lastname": "User", + "username": "testD12B", + "password": "password", + }, + + + "domain2": { + "name": "D2", + }, + "accountD2": { + "email": "testD2@test.com", + "firstname": "testD2", + "lastname": "User", + "username": "testD2", + "password": "password", + "accounttype": "1", + }, + "accountD2A": { + "email": "testD2A@test.com", + "firstname": "testD2A", + "lastname": "User", + "username": "testD2A", + "password": "password", + }, + + "accountROOTA": { + "email": "testROOTA@test.com", + "firstname": "testROOTA", + "lastname": "User", + "username": "testROOTA", + "password": "password", + }, + + "accountROOT": { + "email": "testROOTA@test.com", + "firstname": "testROOT", + "lastname": "admin", + "username": "testROOT", + "password": "password", + }, + + #data reqd for Network creation + + "network": { + "name": "Network-", + "displaytext": "Network-", + "gateway" :"10.223.1.1", + "netmask" :"255.255.255.0", + "startip" :"10.223.1.2", + "endip" :"10.223.1.100", + }, + #small service offering + "service_offering": { + "small": { + "name": "Small Instance", + "displaytext": "Small Instance", + "cpunumber": 1, + "cpuspeed": 100, + "memory": 128, + }, + }, + "ostype": 'CentOS 5.6 (64-bit)', + } + } diff --git a/tools/marvin/marvin/configGenerator.py b/tools/marvin/marvin/configGenerator.py index 0b4a0a132b..8daaaa9d59 100644 --- a/tools/marvin/marvin/configGenerator.py +++ b/tools/marvin/marvin/configGenerator.py @@ -20,9 +20,12 @@ from optparse import OptionParser import jsonHelper from marvin.codes import * +from marvin.cloudstackException import GetDetailExceptionInfo +from marvin.config.test_data import test_data class managementServer(object): + def __init__(self): self.mgtSvrIp = None self.port = 8096 @@ -34,6 +37,7 @@ def __init__(self): class dbServer(object): + def __init__(self): self.dbSvr = None self.port = 3306 @@ -43,27 +47,31 @@ def __init__(self): class configuration(object): + def __init__(self): self.name = None self.value = None class logger(object): + def __init__(self): - '''TestCase/TestClient''' - self.logFolderPath = None + self.LogFolderPath = None class cloudstackConfiguration(object): + def __init__(self): self.zones = [] self.mgtSvr = [] self.dbSvr = None self.globalConfig = [] self.logger = None + self.TestData = None class zone(object): + def __init__(self): self.dns1 = None self.internaldns1 = None @@ -83,6 +91,7 @@ def __init__(self): class trafficType(object): + def __init__(self, typ, labeldict=None): self.typ = typ # Guest/Management/Public if labeldict: @@ -95,6 +104,7 @@ def __init__(self, typ, labeldict=None): class pod(object): + def __init__(self): self.gateway = None self.name = None @@ -109,6 +119,7 @@ def __init__(self): class VmwareDc(object): + def __init__(self): self.zoneid = None self.name = None @@ -118,6 +129,7 @@ def __init__(self): class cluster(object): + def __init__(self): self.clustername = None self.clustertype = None @@ -132,6 +144,7 @@ def __init__(self): class host(object): + def __init__(self): self.hypervisor = None self.password = None @@ -141,14 +154,12 @@ def __init__(self): self.podid = None self.clusterid = None self.clustername = None - self.cpunumber = None - self.cpuspeed = None - self.hostmac = None self.hosttags = None - self.memory = None + self.allocationstate = None class physicalNetwork(object): + def __init__(self): self.name = None self.tags = [] @@ -163,6 +174,7 @@ def __init__(self): class provider(object): + def __init__(self, name=None): self.name = name self.state = None @@ -173,6 +185,7 @@ def __init__(self, name=None): class network(object): + def __init__(self): self.displaytext = None self.name = None @@ -185,6 +198,7 @@ def __init__(self): class iprange(object): + def __init__(self): '''tagged/untagged''' self.gateway = None @@ -198,12 +212,15 @@ def __init__(self): class primaryStorage(object): + def __init__(self): self.name = None self.url = None + self.details = None class secondaryStorage(object): + def __init__(self): self.url = None self.provider = None @@ -211,6 +228,7 @@ def __init__(self): class cacheStorage(object): + def __init__(self): self.url = None self.provider = None @@ -218,6 +236,7 @@ def __init__(self): class s3(object): + def __init__(self): self.accesskey = None self.secretkey = None @@ -230,6 +249,7 @@ def __init__(self): class netscaler(object): + def __init__(self, hostname=None, username='nsroot', password='nsroot'): self.hostname = hostname self.username = username @@ -246,11 +266,12 @@ def getUrl(self): def __repr__(self): req = zip(self.__dict__.keys(), self.__dict__.values()) - return self.hostname+"?" + "&".join(["=".join([r[0], r[1]]) - for r in req]) + return self.hostname + "?" + "&".join(["=".join([r[0], r[1]]) + for r in req]) class srx(object): + def __init__(self, hostname=None, username='root', password='admin'): self.hostname = hostname self.username = username @@ -269,11 +290,12 @@ def getUrl(self): def __repr__(self): req = zip(self.__dict__.keys(), self.__dict__.values()) - return self.hostname+"?" + "&".join(["=".join([r[0], r[1]]) - for r in req]) + return self.hostname + "?" + "&".join(["=".join([r[0], r[1]]) + for r in req]) class bigip(object): + def __init__(self, hostname=None, username='root', password='default'): self.hostname = hostname self.username = username @@ -290,14 +312,14 @@ def getUrl(self): def __repr__(self): req = zip(self.__dict__.keys(), self.__dict__.values()) - return self.hostname+"?" + "&".join(["=".join([r[0], r[1]]) - for r in req]) + return self.hostname + "?" + "&".join(["=".join([r[0], r[1]]) + for r in req]) class ConfigManager(object): ''' - @Name: configManager + @Name: ConfigManager @Desc: 1. It provides the basic configuration facilities to marvin. 2. User can just add configuration files for his tests, deployment etc, under one config folder before running their tests. @@ -328,16 +350,21 @@ class ConfigManager(object): "getConfig" API,once configObj is returned. ''' - def __init__(self): - # Joining path with current directory will avoid relative path issue - # It will take correct path irrespective of from where the test case is run - dirPath = os.path.dirname(__file__) - self.filePath = os.path.join(dirPath, 'config/config.cfg') - self.parsedDict = None - if self.__verifyFile(self.filePath) is not False: - self.parsedDict = self.__parseConfig(self.filePath) - - def __parseConfig(self, file): + def __init__(self, cfg_file=None): + self.__filePath = cfg_file + self.__parsedCfgDict = None + ''' + Set the Configuration + ''' + self.__setConfig() + + def __setConfig(self): + if not self.__verifyFile(): + dirPath = os.path.dirname(__file__) + self.__filePath = str(os.path.join(dirPath, "config/test_data.py")) + self.__parsedCfgDict = self.__parseConfig() + + def __parseConfig(self): ''' @Name : __parseConfig @Description: Parses the Input configuration Json file @@ -348,36 +375,38 @@ def __parseConfig(self, file): ''' config_dict = None try: - configlines = [] - with open(file, 'r') as fp: - for line in fp: - if len(line) != 0: + if self.__filePath.endswith(".py"): + config_dict = test_data + else: + configLines = [] + with open(self.__filePath, 'r') as fp: + for line in fp: ws = line.strip() - if ws[0] not in ["#"]: - configlines.append(ws) - config_dict = json.loads("\n".join(configlines)) - except Exception, e: - #Will replace with log once we have logging done - print "\n Exception occurred under __parseConfig", e + if not ws.startswith("#"): + configLines.append(ws) + config = json.loads("\n".join(configLines)) + config_dict = config + except Exception as e: + # Will replace with log once we have logging done + print "\n Exception occurred under ConfigManager:__parseConfig" \ + " :%s", GetDetailExceptionInfo(e) finally: return config_dict - def __verifyFile(self, file): + def __verifyFile(self): ''' @Name : __parseConfig @Description: Parses the Input configuration Json file and returns a dictionary from the file. - @Input : file NA + @Input : NA @Output : True or False based upon file input validity and availability ''' - if file is None or file == '': - return False - if os.path.exists(file) is False: + if self.__filePath is None or self.__filePath == '': return False - return True + return os.path.exists(self.__filePath) - def __getSectionData(self, return_dict, section=None): + def getSectionData(self, section=None): ''' @Name: getSectionData @Desc: Gets the Section data of a particular section @@ -386,43 +415,30 @@ def __getSectionData(self, return_dict, section=None): section to be returned from this dict @Output:Section matching inside the parsed data ''' - if return_dict is not None: - inp = return_dict - elif self.parsedDict is None: + if self.__parsedCfgDict is None or section is None: + print "\nEither Parsed Dictionary is None or Section is None" return INVALID_INPUT - else: - inp = self.parsedDict - if section is not None: - return inp.get(section) - else: - return inp + return self.__parsedCfgDict.get(section) - def getConfig(self, file_path=None, section=None): + def getConfig(self): ''' - @Name: getConfig - @Desc : Parses and converts the given configuration file to dictionary - @Input : file_path: path where the configuration needs to be passed - section: specific section inside the file - @Output: INVALID_INPUT: This value is returned if the input - is invalid or not able to be parsed - Parsed configuration dictionary from json file + @Name : getConfig + @Desc : Returns the Parsed Dictionary of Config Provided + @Input : NA + @Output: ParsedDict if successful if cfg file provided is valid + None if cfg file is invalid or not able to be parsed ''' - ret = None - if file not in [None, '']: - if self.__verifyFile(file_path) is False: - return INVALID_INPUT - else: - ret = self.__parseConfig(file_path) - return self.__getSectionData(ret, section) + out = self.__parsedCfgDict + return out def getDeviceUrl(obj): req = zip(obj.__dict__.keys(), obj.__dict__.values()) if obj.hostname: - return "http://" + obj.hostname+"?" + "&".join(["=".join([r[0], - r[1]]) - for r in req]) + return "http://" + obj.hostname + "?" + "&".join(["=".join([r[0], + r[1]]) + for r in req]) else: return None @@ -437,11 +453,11 @@ def descSetupInBasicMode(): z.dns2 = "8.8.4.4" z.internaldns1 = "192.168.110.254" z.internaldns2 = "192.168.110.253" - z.name = "test"+str(l) + z.name = "test" + str(l) z.networktype = 'Basic' z.securitygroupenabled = 'True' - #If security groups are reqd + # If security groups are reqd sgprovider = provider() sgprovider.broadcastdomainrange = 'Pod' sgprovider.name = 'SecurityGroupProvider' @@ -467,15 +483,15 @@ def descSetupInBasicMode(): ip = iprange() ip.gateway = p.gateway ip.netmask = p.netmask - ip.startip = "192.168.%d.%d" % (i, j*20) - ip.endip = "192.168.%d.%d" % (i, j*20+10) + ip.startip = "192.168.%d.%d" % (i, j * 20) + ip.endip = "192.168.%d.%d" % (i, j * 20 + 10) p.guestIpRanges.append(ip) '''add 10 clusters''' for j in range(2): c = cluster() - c.clustername = "test"+str(l)+str(i) + str(j) + c.clustername = "test" + str(l) + str(i) + str(j) c.clustertype = "CloudManaged" c.hypervisor = "Simulator" @@ -484,15 +500,16 @@ def descSetupInBasicMode(): h = host() h.username = "root" h.password = "password" - memory = 8*1024*1024*1024 - localstorage = 1*1024*1024*1024*1024 + memory = 8 * 1024 * 1024 * 1024 + localstorage = 1 * 1024 * 1024 * 1024 * 1024 h.url = "http://sim/%d%d%d%d" % (l, i, j, k) c.hosts.append(h) '''add 2 primary storages''' for m in range(2): primary = primaryStorage() - primary.name = "primary"+str(l) + str(i) + str(j) + str(m) + primary.name = "primary" + \ + str(l) + str(i) + str(j) + str(m) primary.url = "nfs://localhost/path%s" % (str(l) + str(i) + str(j) + str(m)) c.primaryStorages.append(primary) @@ -504,7 +521,7 @@ def descSetupInBasicMode(): '''add two secondary''' for i in range(5): secondary = secondaryStorage() - secondary.url = "nfs://localhost/path"+str(l) + str(i) + secondary.url = "nfs://localhost/path" + str(l) + str(i) z.secondaryStorages.append(secondary) zs.zones.append(z) @@ -546,7 +563,7 @@ def descSetupInEipMode(): z.dns2 = "8.8.4.4" z.internaldns1 = "192.168.110.254" z.internaldns2 = "192.168.110.253" - z.name = "test"+str(l) + z.name = "test" + str(l) z.networktype = 'Basic' ips = iprange() @@ -557,7 +574,7 @@ def descSetupInEipMode(): ips.netmask = "255.255.255.0" z.ipranges.append(ips) - #If security groups are reqd + # If security groups are reqd sgprovider = provider() sgprovider.broadcastdomainrange = 'Pod' sgprovider.name = 'SecurityGroupProvider' @@ -591,15 +608,15 @@ def descSetupInEipMode(): ip = iprange() ip.gateway = p.gateway ip.netmask = p.netmask - ip.startip = "192.168.%d.%d" % (i, j*20) - ip.endip = "192.168.%d.%d" % (i, j*20+10) + ip.startip = "192.168.%d.%d" % (i, j * 20) + ip.endip = "192.168.%d.%d" % (i, j * 20 + 10) p.guestIpRanges.append(ip) '''add 10 clusters''' for j in range(2): c = cluster() - c.clustername = "test"+str(l)+str(i) + str(j) + c.clustername = "test" + str(l) + str(i) + str(j) c.clustertype = "CloudManaged" c.hypervisor = "Simulator" @@ -614,7 +631,8 @@ def descSetupInEipMode(): '''add 2 primary storages''' for m in range(2): primary = primaryStorage() - primary.name = "primary"+str(l) + str(i) + str(j) + str(m) + primary.name = "primary" + \ + str(l) + str(i) + str(j) + str(m) primary.url = "nfs://localhost/path%s" % (str(l) + str(i) + str(j) + str(m)) @@ -627,7 +645,7 @@ def descSetupInEipMode(): '''add two secondary''' for i in range(5): secondary = secondaryStorage() - secondary.url = "nfs://localhost/path"+str(l) + str(i) + secondary.url = "nfs://localhost/path" + str(l) + str(i) z.secondaryStorages.append(secondary) zs.zones.append(z) @@ -667,7 +685,7 @@ def descSetupInAdvancedMode(): z.dns2 = "8.8.4.4" z.internaldns1 = "192.168.110.254" z.internaldns2 = "192.168.110.253" - z.name = "test"+str(l) + z.name = "test" + str(l) z.networktype = 'Advanced' z.guestcidraddress = "10.1.1.0/24" z.vlan = "100-2000" @@ -703,7 +721,7 @@ def descSetupInAdvancedMode(): '''add 10 clusters''' for j in range(2): c = cluster() - c.clustername = "test"+str(l)+str(i) + str(j) + c.clustername = "test" + str(l) + str(i) + str(j) c.clustertype = "CloudManaged" c.hypervisor = "Simulator" @@ -714,7 +732,7 @@ def descSetupInAdvancedMode(): h.password = "password" memory = 8 * 1024 * 1024 * 1024 localstorage = 1 * 1024 * 1024 * 1024 * 1024 - #h.url = "http://sim/%d%d%d%d/cpucore=1&cpuspeed=8000&\ + # h.url = "http://sim/%d%d%d%d/cpucore=1&cpuspeed=8000&\ # memory=%d&localstorage=%d"%(l, i, j, k, memory, # localstorage) h.url = "http://sim/%d%d%d%d" % (l, i, j, k) @@ -723,8 +741,9 @@ def descSetupInAdvancedMode(): '''add 2 primary storages''' for m in range(2): primary = primaryStorage() - primary.name = "primary"+str(l) + str(i) + str(j) + str(m) - #primary.url = "nfs://localhost/path%s/size=%d" % + primary.name = "primary" + \ + str(l) + str(i) + str(j) + str(m) + # primary.url = "nfs://localhost/path%s/size=%d" % # (str(l) + str(i) + str(j) + str(m), size) primary.url = "nfs://localhost/path%s" % (str(l) + str(i) + str(j) @@ -738,7 +757,7 @@ def descSetupInAdvancedMode(): '''add two secondary''' for i in range(5): secondary = secondaryStorage() - secondary.url = "nfs://localhost/path"+str(l) + str(i) + secondary.url = "nfs://localhost/path" + str(l) + str(i) z.secondaryStorages.append(secondary) '''add default public network''' @@ -788,7 +807,7 @@ def descSetupInAdvancedsgMode(): z.dns2 = "8.8.4.4" z.internaldns1 = "192.168.110.254" z.internaldns2 = "192.168.110.253" - z.name = "test"+str(l) + z.name = "test" + str(l) z.networktype = 'Advanced' z.vlan = "100-2000" z.securitygroupenabled = "true" @@ -797,7 +816,7 @@ def descSetupInAdvancedsgMode(): pn.name = "test-network" pn.traffictypes = [trafficType("Guest"), trafficType("Management")] - #If security groups are reqd + # If security groups are reqd sgprovider = provider() sgprovider.broadcastdomainrange = 'ZONE' sgprovider.name = 'SecurityGroupProvider' @@ -817,7 +836,7 @@ def descSetupInAdvancedsgMode(): '''add 10 clusters''' for j in range(2): c = cluster() - c.clustername = "test"+str(l)+str(i) + str(j) + c.clustername = "test" + str(l) + str(i) + str(j) c.clustertype = "CloudManaged" c.hypervisor = "Simulator" @@ -828,18 +847,17 @@ def descSetupInAdvancedsgMode(): h.password = "password" memory = 8 * 1024 * 1024 * 1024 localstorage = 1 * 1024 * 1024 * 1024 * 1024 - #h.url = "http://sim/%d%d%d%d/cpucore=1&cpuspeed=8000&\ - #memory=%d&localstorage=%d" % (l, i, j, k, memory, - #localstorage) + # h.url = "http://sim/%d%d%d%d/cpucore=1&cpuspeed=8000&\ + # memory=%d&localstorage=%d" % (l, i, j, k, memory, + # localstorage) h.url = "http://sim/%d%d%d%d" % (l, i, j, k) c.hosts.append(h) '''add 2 primary storages''' for m in range(2): primary = primaryStorage() - primary.name = "primary"+str(l) + str(i) + str(j) + str(m) - #primary.url = "nfs://localhost/path%s/size=%d" % \ - #(str(l) + str(i) + str(j) + str(m), size) + primary.name = "primary" + \ + str(l) + str(i) + str(j) + str(m) primary.url = "nfs://localhost/path%s" % \ (str(l) + str(i) + str(j) + str(m)) c.primaryStorages.append(primary) @@ -851,7 +869,7 @@ def descSetupInAdvancedsgMode(): '''add two secondary''' for i in range(5): secondary = secondaryStorage() - secondary.url = "nfs://localhost/path"+str(l) + str(i) + secondary.url = "nfs://localhost/path" + str(l) + str(i) z.secondaryStorages.append(secondary) '''add default guest network''' @@ -901,18 +919,19 @@ def generate_setup_config(config, file=None): def getSetupConfig(file): - if not os.path.exists(file): - raise IOError("config file %s not found. \ - please specify a valid config file" % file) - config = cloudstackConfiguration() - configLines = [] - with open(file, 'r') as fp: - for line in fp: - ws = line.strip() - if not ws.startswith("#"): - configLines.append(ws) - config = json.loads("\n".join(configLines)) - return jsonHelper.jsonLoader(config) + try: + config = cloudstackConfiguration() + configLines = [] + with open(file, 'r') as fp: + for line in fp: + ws = line.strip() + if not ws.startswith("#"): + configLines.append(ws) + config = json.loads("\n".join(configLines)) + return jsonHelper.jsonLoader(config) + except Exception as e: + print "\nException Occurred under getSetupConfig %s" % \ + GetDetailExceptionInfo(e) if __name__ == "__main__": parser = OptionParser() diff --git a/tools/marvin/marvin/dbConnection.py b/tools/marvin/marvin/dbConnection.py index 99014abfa2..66c6cb1773 100644 --- a/tools/marvin/marvin/dbConnection.py +++ b/tools/marvin/marvin/dbConnection.py @@ -20,12 +20,13 @@ from mysql import connector from mysql.connector import errors from contextlib import closing -import cloudstackException +from marvin import cloudstackException import sys import os -class dbConnection(object): +class DbConnection(object): + def __init__(self, host="localhost", port=3306, user='cloud', passwd='cloud', db='cloud'): self.host = host @@ -51,7 +52,7 @@ def execute(self, sql=None, params=None): try: resultRow = cursor.fetchall() except errors.InterfaceError: - #Raised on empty result - DML + # Raised on empty result - DML resultRow = [] return resultRow @@ -68,7 +69,7 @@ def executeSqlFromFile(self, fileName=None): return self.execute(sqls) if __name__ == "__main__": - db = dbConnection() + db = DbConnection() ''' try: diff --git a/tools/marvin/marvin/deployAndRun.py b/tools/marvin/marvin/deployAndRun.py index 56747a7cb2..9f392e5e5a 100644 --- a/tools/marvin/marvin/deployAndRun.py +++ b/tools/marvin/marvin/deployAndRun.py @@ -15,13 +15,13 @@ # specific language governing permissions and limitations # under the License. -from tcExecuteEngine import TestCaseExecuteEngine +from .tcExecuteEngine import TestCaseExecuteEngine import sys import os import traceback import time from argparse import ArgumentParser -from marvinInit import MarvinInit +from .marvinInit import MarvinInit from marvin.codes import (SUCCESS, FAILED, EXCEPTION, @@ -96,9 +96,9 @@ def startMarvin(cfg_file, load_flag): else: print "\nMarvin Initialization Failed" exit(1) - except Exception, e: - print "\n Exception occurred while starting Marvin %s" % str(e) - exit(1) + except Exception as e: + print "\n Exception occurred while starting Marvin %s" % str(e) + exit(1) def runTCs(num_iter, inp1, inp2): diff --git a/tools/marvin/marvin/deployDataCenter.py b/tools/marvin/marvin/deployDataCenter.py index c4f6e1e137..c097238e9d 100644 --- a/tools/marvin/marvin/deployDataCenter.py +++ b/tools/marvin/marvin/deployDataCenter.py @@ -15,462 +15,780 @@ # specific language governing permissions and limitations # under the License. -"""Deploy datacenters according to a json configuration file""" -import configGenerator -import cloudstackException -import cloudstackTestClient -import logging -from cloudstackAPI import * -from os import path -from time import sleep +""" +@Desc : +class DeployDataCenters: Deploys DeleteDataCenters according to a json + configuration file. +class DeleteDataCenters: Deletes a DataCenter based upon the dc cfg + settings provided. + This settings file is the exported + configuration from DeployDataCenters post + its success +""" +from marvin import configGenerator +from marvin.cloudstackException import ( + InvalidParameterException, + GetDetailExceptionInfo) +from marvin.cloudstackAPI import * +from marvin.codes import (FAILED, SUCCESS) +from marvin.lib.utils import (random_gen) +from marvin.config.test_data import test_data +from sys import exit +import os +import pickle +from time import sleep, strftime, localtime from optparse import OptionParser -class deployDataCenters(object): - - def __init__(self, cfg, logger=None): - self.config = cfg - self.tcRunLogger = logger +class DeployDataCenters(object): + + ''' + @Desc : Deploys the Data Center with information provided. + Once the Deployment is successful, it will export + the DataCenter settings to an obj file + ( can be used if wanted to delete the created DC) + ''' + + def __init__(self, + test_client, + cfg, + logger=None, + log_folder_path=None + ): + self.__testClient = test_client + self.__config = cfg + self.__tcRunLogger = logger + self.__logFolderPath = log_folder_path + self.__apiClient = None + self.__cleanUp = {} + + def __persistDcConfig(self): + try: + if self.__logFolderPath: + dc_file_path = self.__logFolderPath + "/dc_entries.obj" + else: + ts = strftime("%b_%d_%Y_%H_%M_%S", localtime()) + dc_file_path = "dc_entries_" + str(ts) + ".obj" + file_to_write = open(dc_file_path, 'w') + if file_to_write: + pickle.dump(self.__cleanUp, file_to_write) + print "\n=== Data Center Settings are dumped to %s===" % \ + dc_file_path + self.__tcRunLogger.debug( + "\n=== Data Center Settings are dumped to %s===" % + dc_file_path) + except Exception as e: + print "Exception Occurred while persisting DC Settings: %s" % \ + GetDetailExceptionInfo(e) + + def __cleanAndExit(self): + try: + print "\n===deploy dc failed, so cleaning the created entries===" + if not test_data.get("deleteDC", None): + print "\n=== Deploy DC Clean Up flag not set. So, exiting ===" + exit(1) + self.__tcRunLogger.debug( + "===Deploy DC Failed, So Cleaning to Exit===") + remove_dc_obj = DeleteDataCenters(self.__testClient, + dc_cfg=self.__cleanUp, + tc_run_logger=self.__tcRunLogger + ) + if remove_dc_obj: + if remove_dc_obj.removeDataCenter() == FAILED: + print "\n===Removing DataCenter Failed===" + self.__tcRunLogger.debug( + "===Removing DataCenter Failed===") + else: + print "\n===Removing DataCenter Successful===" + self.__tcRunLogger.debug( + "===Removing DataCenter Successful===") + exit(1) + except Exception as e: + print "Exception Occurred during DC CleanUp: %s" % \ + GetDetailExceptionInfo(e) + + def __addToCleanUp(self, type, id): + if type not in self.__cleanUp.keys(): + self.__cleanUp[type] = [] + self.__cleanUp[type].append(id) + if "order" not in self.__cleanUp.keys(): + self.__cleanUp["order"] = [] + if type not in self.__cleanUp["order"]: + self.__cleanUp["order"].append(type) def addHosts(self, hosts, zoneId, podId, clusterId, hypervisor): if hosts is None: + print "\n === Invalid Hosts Information ====" return + failed_cnt = 0 for host in hosts: - hostcmd = addHost.addHostCmd() - hostcmd.clusterid = clusterId - hostcmd.cpunumber = host.cpunumer - hostcmd.cpuspeed = host.cpuspeed - hostcmd.hostmac = host.hostmac - hostcmd.hosttags = host.hosttags - hostcmd.hypervisor = host.hypervisor - hostcmd.memory = host.memory - hostcmd.password = host.password - hostcmd.podid = podId - hostcmd.url = host.url - hostcmd.username = host.username - hostcmd.zoneid = zoneId - hostcmd.hypervisor = hypervisor - self.apiClient.addHost(hostcmd) + try: + hostcmd = addHost.addHostCmd() + hostcmd.clusterid = clusterId + hostcmd.hosttags = host.hosttags + hostcmd.hypervisor = host.hypervisor + hostcmd.password = host.password + hostcmd.podid = podId + hostcmd.url = host.url + hostcmd.username = host.username + hostcmd.zoneid = zoneId + hostcmd.hypervisor = hypervisor + ret = self.__apiClient.addHost(hostcmd) + if ret: + self.__tcRunLogger.debug("=== Add Host Successful ===") + self.__addToCleanUp("Host", ret[0].id) + except Exception as e: + failed_cnt = failed_cnt + 1 + print "Exception Occurred :%s" % GetDetailExceptionInfo(e) + self.__tcRunLogger.exception( + "=== Adding Host Failed :%s===" % str( + host.url)) + if failed_cnt == len(hosts): + self.__cleanAndExit() + continue def addVmWareDataCenter(self, vmwareDc): - vdc = addVmwareDc.addVmwareDcCmd() - vdc.zoneid = vmwareDc.zoneid - vdc.name = vmwareDc.name - vdc.vcenter = vmwareDc.vcenter - vdc.username = vmwareDc.username - vdc.password = vmwareDc.password - self.apiClient.addVmwareDc(vdc) + try: + vdc = addVmwareDc.addVmwareDcCmd() + vdc.zoneid = vmwareDc.zoneid + vdc.name = vmwareDc.name + vdc.vcenter = vmwareDc.vcenter + vdc.username = vmwareDc.username + vdc.password = vmwareDc.password + ret = self.__apiClient.addVmwareDc(vdc) + if ret.id: + self.__tcRunLogger.debug("=== Adding VmWare DC Successful===") + self.__addToCleanUp("VmwareDc", ret.id) + except Exception as e: + print "Exception Occurred: %s" % GetDetailExceptionInfo(e) + self.__tcRunLogger.exception("=== Adding VmWare DC Failed===") + self.__cleanAndExit() def createClusters(self, clusters, zoneId, podId, vmwareDc=None): - if clusters is None: - return - - if vmwareDc is not None: - vmwareDc.zoneid = zoneId - self.addVmWareDataCenter(vmwareDc) - - for cluster in clusters: - clustercmd = addCluster.addClusterCmd() - clustercmd.clustername = cluster.clustername - clustercmd.clustertype = cluster.clustertype - clustercmd.hypervisor = cluster.hypervisor - clustercmd.password = cluster.password - clustercmd.podid = podId - clustercmd.url = cluster.url - clustercmd.username = cluster.username - clustercmd.zoneid = zoneId - clusterresponse = self.apiClient.addCluster(clustercmd) - clusterId = clusterresponse[0].id - - if cluster.hypervisor.lower() != "vmware": - self.addHosts(cluster.hosts, zoneId, podId, clusterId, - cluster.hypervisor) - self.waitForHost(zoneId, clusterId) - self.createPrimaryStorages(cluster.primaryStorages, zoneId, podId, - clusterId) + try: + if clusters is None: + return + if vmwareDc is not None: + vmwareDc.zoneid = zoneId + self.addVmWareDataCenter(vmwareDc) + + for cluster in clusters: + clustercmd = addCluster.addClusterCmd() + clustercmd.clustername = cluster.clustername + clustercmd.clustertype = cluster.clustertype + clustercmd.hypervisor = cluster.hypervisor + clustercmd.password = cluster.password + clustercmd.podid = podId + clustercmd.url = cluster.url + clustercmd.username = cluster.username + clustercmd.zoneid = zoneId + clusterresponse = self.__apiClient.addCluster(clustercmd) + if clusterresponse[0].id: + clusterId = clusterresponse[0].id + self.__tcRunLogger.\ + debug("Cluster Name : %s Id : %s Created Successfully" + % (str(cluster.clustername), str(clusterId))) + self.__addToCleanUp("Cluster", clusterId) + if cluster.hypervisor.lower() != "vmware": + self.addHosts(cluster.hosts, zoneId, podId, clusterId, + cluster.hypervisor) + self.waitForHost(zoneId, clusterId) + self.createPrimaryStorages(cluster.primaryStorages, + zoneId, + podId, + clusterId) + except Exception as e: + print "Exception Occurred %s" % GetDetailExceptionInfo(e) + self.__tcRunLogger.exception("====Cluster %s Creation Failed" + "=====" % + str(cluster.clustername)) + self.__cleanAndExit() def waitForHost(self, zoneId, clusterId): """ Wait for the hosts in the zoneid, clusterid to be up - 2 retries with 30s delay """ - retry, timeout = 2, 30 - cmd = listHosts.listHostsCmd() - cmd.clusterid, cmd.zoneid = clusterId, zoneId - hosts = self.apiClient.listHosts(cmd) - while retry != 0: - for host in hosts: - if host.state != 'Up': - break - sleep(timeout) - retry = retry - 1 - - def createPrimaryStorages(self, primaryStorages, zoneId, podId, clusterId): - if primaryStorages is None: - return - for primary in primaryStorages: - primarycmd = createStoragePool.createStoragePoolCmd() - primarycmd.details = primary.details - primarycmd.name = primary.name - primarycmd.podid = podId - primarycmd.tags = primary.tags - primarycmd.url = primary.url - primarycmd.zoneid = zoneId - primarycmd.clusterid = clusterId - self.apiClient.createStoragePool(primarycmd) - - def createPods(self, pods, zoneId, networkId=None): - if pods is None: - return - for pod in pods: - createpod = createPod.createPodCmd() - createpod.name = pod.name - createpod.gateway = pod.gateway - createpod.netmask = pod.netmask - createpod.startip = pod.startip - createpod.endip = pod.endip - createpod.zoneid = zoneId - createpodResponse = self.apiClient.createPod(createpod) - podId = createpodResponse.id - - if pod.guestIpRanges is not None and networkId is not None: - self.createVlanIpRanges("Basic", pod.guestIpRanges, zoneId, - podId, networkId) - - self.createClusters(pod.clusters, zoneId, podId, - vmwareDc=pod.vmwaredc) + try: + retry, timeout = 2, 30 + cmd = listHosts.listHostsCmd() + cmd.clusterid, cmd.zoneid = clusterId, zoneId + hosts = self.__apiClient.listHosts(cmd) + while retry != 0: + for host in hosts: + if host.state != 'Up': + break + sleep(timeout) + retry = retry - 1 + except Exception as e: + print "\nException Occurred:%s" %\ + GetDetailExceptionInfo(e) + self.__tcRunLogger.exception("=== List Hosts Failed===") + self.__cleanAndExit() + + def createPrimaryStorages(self, + primaryStorages, + zoneId, + podId, + clusterId): + try: + if primaryStorages is None: + return + for primary in primaryStorages: + primarycmd = createStoragePool.createStoragePoolCmd() + if primary.details: + for key, value in vars(primary.details).iteritems(): + primarycmd.details.append({ key: value}) + primarycmd.name = primary.name + primarycmd.podid = podId + primarycmd.tags = primary.tags + primarycmd.url = primary.url + primarycmd.zoneid = zoneId + primarycmd.clusterid = clusterId + ret = self.__apiClient.createStoragePool(primarycmd) + if ret.id: + self.__tcRunLogger.debug( + "=== Creating Storage Pool Successful===") + self.__addToCleanUp("StoragePool", ret.id) + except Exception as e: + print "Exception Occurred: %s" % GetDetailExceptionInfo(e) + self.__tcRunLogger.\ + exception("=== Create Storage Pool Failed===") + self.__cleanAndExit() + + def createPods(self, + pods, + zoneId, + networkId=None): + try: + if pods is None: + return + for pod in pods: + createpod = createPod.createPodCmd() + createpod.name = pod.name + createpod.gateway = pod.gateway + createpod.netmask = pod.netmask + createpod.startip = pod.startip + createpod.endip = pod.endip + createpod.zoneid = zoneId + createpodResponse = self.__apiClient.createPod(createpod) + if createpodResponse.id: + podId = createpodResponse.id + self.__tcRunLogger.debug("Pod Name : %s Id : %s " + "Created Successfully" % + (str(pod.name), str(podId))) + self.__addToCleanUp("Pod", podId) + if pod.guestIpRanges is not None and networkId is not None: + self.createVlanIpRanges("Basic", pod.guestIpRanges, zoneId, + podId, networkId) + self.createClusters(pod.clusters, zoneId, podId, + vmwareDc=pod.vmwaredc) + except Exception as e: + print "Exception Occurred: %s" % GetDetailExceptionInfo(e) + self.__tcRunLogger.\ + exception("====Pod: %s Creation " + "Failed=====" % str(pod.name)) + self.__cleanAndExit() def createVlanIpRanges(self, mode, ipranges, zoneId, podId=None, networkId=None, forvirtualnetwork=None): - if ipranges is None: - return - for iprange in ipranges: - vlanipcmd = createVlanIpRange.createVlanIpRangeCmd() - vlanipcmd.account = iprange.account - vlanipcmd.domainid = iprange.domainid - vlanipcmd.endip = iprange.endip - vlanipcmd.gateway = iprange.gateway - vlanipcmd.netmask = iprange.netmask - vlanipcmd.networkid = networkId - vlanipcmd.podid = podId - vlanipcmd.startip = iprange.startip - vlanipcmd.zoneid = zoneId - vlanipcmd.vlan = iprange.vlan - if mode == "Basic": - if forvirtualnetwork: - vlanipcmd.forvirtualnetwork = "true" + try: + if ipranges is None: + return + for iprange in ipranges: + vlanipcmd = createVlanIpRange.createVlanIpRangeCmd() + vlanipcmd.account = iprange.account + vlanipcmd.domainid = iprange.domainid + vlanipcmd.endip = iprange.endip + vlanipcmd.gateway = iprange.gateway + vlanipcmd.netmask = iprange.netmask + vlanipcmd.networkid = networkId + vlanipcmd.podid = podId + vlanipcmd.startip = iprange.startip + vlanipcmd.zoneid = zoneId + vlanipcmd.vlan = iprange.vlan + if mode == "Basic": + if forvirtualnetwork: + vlanipcmd.forvirtualnetwork = "true" + else: + vlanipcmd.forvirtualnetwork = "false" else: - vlanipcmd.forvirtualnetwork = "false" - else: - vlanipcmd.forvirtualnetwork = "true" - self.apiClient.createVlanIpRange(vlanipcmd) + vlanipcmd.forvirtualnetwork = "true" + ret = self.__apiClient.createVlanIpRange(vlanipcmd) + if ret.id: + self.__tcRunLogger.debug( + "=== Creating Vlan Ip Range Successful===") + self.__addToCleanUp("VlanIpRange", ret.id) + except Exception as e: + print "Exception Occurred: %s" % GetDetailExceptionInfo(e) + self.__tcRunLogger.\ + exception("=== Create Vlan Ip Range Failed===") + self.__cleanAndExit() def createSecondaryStorages(self, secondaryStorages, zoneId): - if secondaryStorages is None: - return - for secondary in secondaryStorages: - secondarycmd = addImageStore.addImageStoreCmd() - secondarycmd.url = secondary.url - secondarycmd.provider = secondary.provider - secondarycmd.details = [] - - if secondarycmd.provider == 'S3' \ - or secondarycmd.provider == "Swift": - for key, value in vars(secondary.details).iteritems(): - secondarycmd.details.append({ + try: + if secondaryStorages is None: + return + for secondary in secondaryStorages: + secondarycmd = addImageStore.addImageStoreCmd() + secondarycmd.url = secondary.url + secondarycmd.provider = secondary.provider + secondarycmd.details = [] + + if secondarycmd.provider.lower() in ('s3', "swift", "smb"): + for key, value in vars(secondary.details).iteritems(): + secondarycmd.details.append({ + 'key': key, + 'value': value + }) + if secondarycmd.provider.lower() in ("nfs", "smb"): + secondarycmd.zoneid = zoneId + ret = self.__apiClient.addImageStore(secondarycmd) + if ret.id: + self.__tcRunLogger.debug( + "===Add Image Store Successful===") + self.__addToCleanUp("ImageStore", ret.id) + except Exception as e: + print "Exception Occurred: %s" % GetDetailExceptionInfo(e) + self.__tcRunLogger.\ + exception("=== Add Image Store Failed===") + self.__cleanAndExit() + + def createCacheStorages(self, cacheStorages, zoneId): + try: + if cacheStorages is None: + return + for cache in cacheStorages: + cachecmd = createSecondaryStagingStore.\ + createSecondaryStagingStoreCmd() + cachecmd.url = cache.url + cachecmd.provider = cache.provider + cachecmd.zoneid = zoneId + cachecmd.details = [] + + if cache.details: + for key, value in vars(cache.details).iteritems(): + cachecmd.details.append({ 'key': key, 'value': value }) - if secondarycmd.provider == "NFS": - secondarycmd.zoneid = zoneId - self.apiClient.addImageStore(secondarycmd) - - def createCacheStorages(self, cacheStorages, zoneId): - if cacheStorages is None: - return - for cache in cacheStorages: - cachecmd = createSecondaryStagingStore.\ - createSecondaryStagingStoreCmd() - cachecmd.url = cache.url - cachecmd.provider = cache.provider - cachecmd.zoneid = zoneId - cachecmd.details = [] - - if cache.details: - for key, value in vars(cache.details).iteritems(): - cachecmd.details.append({ - 'key': key, - 'value': value - }) - self.apiClient.createSecondaryStagingStore(cachecmd) + ret = self.__apiClient.createSecondaryStagingStore(cachecmd) + if ret.id: + self.__tcRunLogger.debug( + "===Creating Secondary StagingStore Successful===") + self.__addToCleanUp("SecondaryStagingStore", ret.id) + except Exception as e: + print "Exception Occurred: %s" % GetDetailExceptionInfo(e) + self.__tcRunLogger.\ + exception("=== Creating " + "SecondaryStagingStorage Failed===") + self.__cleanAndExit() def createNetworks(self, networks, zoneId): - if networks is None: - return - for network in networks: - networkcmd = createNetwork.createNetworkCmd() - networkcmd.displaytext = network.displaytext - networkcmd.name = network.name - networkcmd.networkofferingid = network.networkofferingid - networkcmd.zoneid = zoneId - - ipranges = network.ipranges - if ipranges: - iprange = ipranges.pop() - networkcmd.startip = iprange.startip - networkcmd.endip = iprange.endip - networkcmd.gateway = iprange.gateway - networkcmd.netmask = iprange.netmask - - networkcmdresponse = self.apiClient.createNetwork(networkcmd) - networkId = networkcmdresponse.id - return networkId + try: + if networks is None: + return + for network in networks: + networkcmd = createNetwork.createNetworkCmd() + networkcmd.displaytext = network.displaytext + networkcmd.name = network.name + networkcmd.networkofferingid = network.networkofferingid + networkcmd.zoneid = zoneId + + ipranges = network.ipranges + if ipranges: + iprange = ipranges.pop() + networkcmd.startip = iprange.startip + networkcmd.endip = iprange.endip + networkcmd.gateway = iprange.gateway + networkcmd.netmask = iprange.netmask + networkcmdresponse = self.__apiClient.createNetwork(networkcmd) + if networkcmdresponse.id: + networkId = networkcmdresponse.id + self.__tcRunLogger.\ + debug("Creating Network Name : %s Id : %s Successful" + % (str(network.name), str(networkId))) + self.__addToCleanUp("Network", networkId) + return networkId + except Exception as e: + print "Exception Occurred %s" % GetDetailExceptionInfo(e) + self.__tcRunLogger.\ + exception("====Network : %s " + "Creation Failed=====" % str(network.name)) + self.__cleanAndExit() def createPhysicalNetwork(self, net, zoneid): - phynet = createPhysicalNetwork.createPhysicalNetworkCmd() - phynet.zoneid = zoneid - phynet.name = net.name - phynet.isolationmethods = net.isolationmethods - phynetwrk = self.apiClient.createPhysicalNetwork(phynet) - self.addTrafficTypes(phynetwrk.id, net.traffictypes) - return phynetwrk - - def updatePhysicalNetwork(self, networkid, state="Enabled", vlan=None): - upnet = updatePhysicalNetwork.updatePhysicalNetworkCmd() - upnet.id = networkid - upnet.state = state - if vlan: - upnet.vlan = vlan - return self.apiClient.updatePhysicalNetwork(upnet) + try: + phynet = createPhysicalNetwork.createPhysicalNetworkCmd() + phynet.zoneid = zoneid + phynet.name = net.name + phynet.isolationmethods = net.isolationmethods + phynetwrk = self.__apiClient.createPhysicalNetwork(phynet) + if phynetwrk.id: + self.__tcRunLogger.\ + debug("Creating Physical Network Name : " + "%s Id : %s Successful" % (str(phynet.name), + str(phynetwrk.id))) + self.__addToCleanUp("PhysicalNetwork", phynetwrk.id) + self.addTrafficTypes(phynetwrk.id, net.traffictypes) + return phynetwrk + except Exception as e: + print "Exception Occurred: %s" % GetDetailExceptionInfo(e) + self.__tcRunLogger.exception("====Physical Network " + "Creation Failed=====") + self.__cleanAndExit() + + def updatePhysicalNetwork(self, networkid, state="Enabled", + vlan=None): + try: + upnet = updatePhysicalNetwork.updatePhysicalNetworkCmd() + upnet.id = networkid + upnet.state = state + if vlan: + upnet.vlan = vlan + ret = self.__apiClient.updatePhysicalNetwork(upnet) + return ret + except Exception as e: + print "Exception Occurred: %s" % GetDetailExceptionInfo(e) + self.__tcRunLogger.\ + exception("====Update Physical Network Failed=====") + self.__cleanAndExit() def enableProvider(self, provider_id): - upnetprov =\ - updateNetworkServiceProvider.updateNetworkServiceProviderCmd() - upnetprov.id = provider_id - upnetprov.state = "Enabled" - self.apiClient.updateNetworkServiceProvider(upnetprov) + try: + upnetprov =\ + updateNetworkServiceProvider.updateNetworkServiceProviderCmd() + upnetprov.id = provider_id + upnetprov.state = "Enabled" + ret = self.__apiClient.updateNetworkServiceProvider(upnetprov) + if ret.id: + self.__tcRunLogger.debug( + "===Update Network Service Provider Successfull===") + except Exception as e: + print "Exception Occurred: %s" % GetDetailExceptionInfo(e) + self.__tcRunLogger.\ + exception( + "====Update Network Service Provider Failed=====") + self.__cleanAndExit() def configureProviders(self, phynetwrk, providers): """ We will enable the virtualrouter elements for all zones. Other providers like NetScalers, SRX, etc are explicitly added/configured """ - - for provider in providers: - pnetprov = listNetworkServiceProviders.\ - listNetworkServiceProvidersCmd() - pnetprov.physicalnetworkid = phynetwrk.id - pnetprov.state = "Disabled" - pnetprov.name = provider.name - pnetprovres = self.apiClient.listNetworkServiceProviders(pnetprov) - - if pnetprovres and len(pnetprovres) > 0: - if provider.name == 'VirtualRouter'\ - or provider.name == 'VpcVirtualRouter': - vrprov = listVirtualRouterElements.\ - listVirtualRouterElementsCmd() - vrprov.nspid = pnetprovres[0].id - vrprovresponse = self.apiClient.\ - listVirtualRouterElements(vrprov) - vrprovid = vrprovresponse[0].id - - vrconfig = \ - configureVirtualRouterElement.\ - configureVirtualRouterElementCmd() - vrconfig.enabled = "true" - vrconfig.id = vrprovid - self.apiClient.configureVirtualRouterElement(vrconfig) - self.enableProvider(pnetprovres[0].id) - elif provider.name == 'InternalLbVm': - internallbprov = listInternalLoadBalancerElements.\ - listInternalLoadBalancerElementsCmd() - internallbprov.nspid = pnetprovres[0].id - internallbresponse = self.apiClient.\ - listInternalLoadBalancerElements(internallbprov) - internallbid = internallbresponse[0].id - - internallbconfig = \ - configureInternalLoadBalancerElement.\ - configureInternalLoadBalancerElementCmd() - internallbconfig.enabled = "true" - internallbconfig.id = internallbid - self.apiClient.\ - configureInternalLoadBalancerElement(internallbconfig) - self.enableProvider(pnetprovres[0].id) - elif provider.name == 'SecurityGroupProvider': - self.enableProvider(pnetprovres[0].id) - elif provider.name in ['Netscaler', 'JuniperSRX', 'F5BigIp']: - netprov = addNetworkServiceProvider.\ - addNetworkServiceProviderCmd() - netprov.name = provider.name - netprov.physicalnetworkid = phynetwrk.id - result = self.apiClient.addNetworkServiceProvider(netprov) - for device in provider.devices: - if provider.name == 'Netscaler': - dev = addNetscalerLoadBalancer.\ - addNetscalerLoadBalancerCmd() - dev.username = device.username - dev.password = device.password - dev.networkdevicetype = device.networkdevicetype - dev.url = configGenerator.getDeviceUrl(device) - dev.physicalnetworkid = phynetwrk.id - self.apiClient.addNetscalerLoadBalancer(dev) - elif provider.name == 'JuniperSRX': - dev = addSrxFirewall.addSrxFirewallCmd() - dev.username = device.username - dev.password = device.password - dev.networkdevicetype = device.networkdevicetype - dev.url = configGenerator.getDeviceUrl(device) - dev.physicalnetworkid = phynetwrk.id - self.apiClient.addSrxFirewall(dev) - elif provider.name == 'F5BigIp': - dev = addF5LoadBalancer.addF5LoadBalancerCmd() - dev.username = device.username - dev.password = device.password - dev.networkdevicetype = device.networkdevicetype - dev.url = configGenerator.getDeviceUrl(device) - dev.physicalnetworkid = phynetwrk.id - self.apiClient.addF5LoadBalancer(dev) - else: - raise cloudstackException.\ - InvalidParameterException("Device %s doesn't match\ - any know provider type" % device) - self.enableProvider(result.id) + try: + for provider in providers: + pnetprov = listNetworkServiceProviders.\ + listNetworkServiceProvidersCmd() + pnetprov.physicalnetworkid = phynetwrk.id + pnetprov.state = "Disabled" + pnetprov.name = provider.name + pnetprovres = self.__apiClient.listNetworkServiceProviders( + pnetprov) + if pnetprovres and len(pnetprovres) > 0: + if provider.name == 'VirtualRouter'\ + or provider.name == 'VpcVirtualRouter': + vrprov = listVirtualRouterElements.\ + listVirtualRouterElementsCmd() + vrprov.nspid = pnetprovres[0].id + vrprovresponse = self.__apiClient.\ + listVirtualRouterElements(vrprov) + vrprovid = vrprovresponse[0].id + vrconfig = \ + configureVirtualRouterElement.\ + configureVirtualRouterElementCmd() + vrconfig.enabled = "true" + vrconfig.id = vrprovid + self.__apiClient.\ + configureVirtualRouterElement(vrconfig) + self.enableProvider(pnetprovres[0].id) + elif provider.name == 'InternalLbVm': + internallbprov = listInternalLoadBalancerElements.\ + listInternalLoadBalancerElementsCmd() + internallbprov.nspid = pnetprovres[0].id + internallbresponse = self.__apiClient.\ + listInternalLoadBalancerElements(internallbprov) + internallbid = internallbresponse[0].id + internallbconfig = \ + configureInternalLoadBalancerElement.\ + configureInternalLoadBalancerElementCmd() + internallbconfig.enabled = "true" + internallbconfig.id = internallbid + self.__apiClient.\ + configureInternalLoadBalancerElement( + internallbconfig) + self.enableProvider(pnetprovres[0].id) + elif provider.name == 'SecurityGroupProvider': + self.enableProvider(pnetprovres[0].id) + elif provider.name in ['JuniperContrailRouter', + 'JuniperContrailVpcRouter']: + netprov = addNetworkServiceProvider.\ + addNetworkServiceProviderCmd() + netprov.name = provider.name + netprov.physicalnetworkid = phynetwrk.id + result = self.apiClient.addNetworkServiceProvider(netprov) + self.enableProvider(result.id) + elif provider.name in ['Netscaler', 'JuniperSRX', 'F5BigIp']: + netprov = addNetworkServiceProvider.\ + addNetworkServiceProviderCmd() + netprov.name = provider.name + netprov.physicalnetworkid = phynetwrk.id + result = self.__apiClient.addNetworkServiceProvider( + netprov) + if result.id: + self.__tcRunLogger.\ + debug("==== AddNetworkServiceProvider " + "Successful=====") + self.__addToCleanUp( + "NetworkServiceProvider", + result.id) + for device in provider.devices: + if provider.name == 'Netscaler': + dev = addNetscalerLoadBalancer.\ + addNetscalerLoadBalancerCmd() + dev.username = device.username + dev.password = device.password + dev.networkdevicetype = device.networkdevicetype + dev.url = configGenerator.getDeviceUrl(device) + dev.physicalnetworkid = phynetwrk.id + ret = self.__apiClient.addNetscalerLoadBalancer( + dev) + if ret.id: + self.__tcRunLogger.\ + debug("==== AddNetScalerLB " + "Successful=====") + self.__addToCleanUp( + "NetscalerLoadBalancer", + ret.id) + elif provider.name == 'JuniperSRX': + dev = addSrxFirewall.addSrxFirewallCmd() + dev.username = device.username + dev.password = device.password + dev.networkdevicetype = device.networkdevicetype + dev.url = configGenerator.getDeviceUrl(device) + dev.physicalnetworkid = phynetwrk.id + ret = self.__apiClient.addSrxFirewall(dev) + if ret.id: + self.__tcRunLogger.\ + debug("==== AddSrx " + "Successful=====") + self.__addToCleanUp("SrxFirewall", ret.id) + elif provider.name == 'F5BigIp': + dev = addF5LoadBalancer.addF5LoadBalancerCmd() + dev.username = device.username + dev.password = device.password + dev.networkdevicetype = device.networkdevicetype + dev.url = configGenerator.getDeviceUrl(device) + dev.physicalnetworkid = phynetwrk.id + ret = self.__apiClient.addF5LoadBalancer(dev) + if ret.id: + self.__tcRunLogger.\ + debug("==== AddF5 " + "Successful=====") + self.__addToCleanUp("F5LoadBalancer", ret.id) + else: + raise InvalidParameterException( + "Device %s doesn't match " + "any know provider " + "type" % device) + self.enableProvider(result.id) + except Exception as e: + print "Exception Occurred: %s" % GetDetailExceptionInfo(e) + self.__tcRunLogger.\ + exception("====List Network " + "Service Providers Failed=====") + self.__cleanAndExit() def addTrafficTypes(self, physical_network_id, traffictypes): [self.addTrafficType(physical_network_id, traffic_type) for traffic_type in traffictypes] def addTrafficType(self, physical_network_id, traffictype): - traffic_type = addTrafficType.addTrafficTypeCmd() - traffic_type.physicalnetworkid = physical_network_id - traffic_type.traffictype = traffictype.typ - traffic_type.kvmnetworklabel = traffictype.kvm\ - if traffictype.kvm is not None else None - traffic_type.xennetworklabel = traffictype.xen\ - if traffictype.xen is not None else None - traffic_type.vmwarenetworklabel = traffictype.vmware\ - if traffictype.vmware is not None else None - traffic_type.simulatorlabel = traffictype.simulator\ - if traffictype.simulator is not None else None - return self.apiClient.addTrafficType(traffic_type) + try: + traffic_type = addTrafficType.addTrafficTypeCmd() + traffic_type.physicalnetworkid = physical_network_id + traffic_type.traffictype = traffictype.typ + traffic_type.kvmnetworklabel = traffictype.kvm\ + if traffictype.kvm is not None else None + traffic_type.xennetworklabel = traffictype.xen\ + if traffictype.xen is not None else None + traffic_type.vmwarenetworklabel = traffictype.vmware\ + if traffictype.vmware is not None else None + traffic_type.simulatorlabel = traffictype.simulator\ + if traffictype.simulator is not None else None + ret = self.__apiClient.addTrafficType(traffic_type) + if ret.id: + self.__tcRunLogger.debug("===Add TrafficType Successful====") + self.__addToCleanUp("TrafficType", ret.id) + return ret + except Exception as e: + print "Exception Occurred: %s" % GetDetailExceptionInfo(e) + self.__tcRunLogger.\ + exception("==== Add TrafficType Failed=====") + self.__cleanAndExit() def enableZone(self, zoneid, allocation_state="Enabled"): - zoneCmd = updateZone.updateZoneCmd() - zoneCmd.id = zoneid - zoneCmd.allocationstate = allocation_state - return self.apiClient.updateZone(zoneCmd) + try: + zoneCmd = updateZone.updateZoneCmd() + zoneCmd.id = zoneid + zoneCmd.allocationstate = allocation_state + ret = self.__apiClient.updateZone(zoneCmd) + if ret.id: + self.__tcRunLogger.debug("==== Enable Zone SuccessFul=====") + return ret + except Exception as e: + print "Exception Occurred: %s" % GetDetailExceptionInfo(e) + self.__tcRunLogger.exception("==== Enable Zone Failed=====") + self.__cleanAndExit() def updateZoneDetails(self, zoneid, details): - zoneCmd = updateZone.updateZoneCmd() - zoneCmd.id = zoneid - zoneCmd.details = details - return self.apiClient.updateZone(zoneCmd) + try: + zoneCmd = updateZone.updateZoneCmd() + zoneCmd.id = zoneid + zoneCmd.details = details + ret = self.__apiClient.updateZone(zoneCmd) + if ret.id: + self.__tcRunLogger.debug("=== Update Zone SuccessFul===") + return ret + except Exception as e: + print "Exception Occurred: %s" % GetDetailExceptionInfo(e) + self.__tcRunLogger.exception("==== Update Zone Failed=====") + self.__cleanAndExit() + + def createZone(self, zone, rec=0): + try: + zoneresponse = self.__apiClient.createZone(zone) + if zoneresponse.id: + self.__addToCleanUp("Zone", zoneresponse.id) + self.__tcRunLogger.\ + debug("Zone Name : %s Id : %s Created Successfully" % + (str(zone.name), str(zoneresponse.id))) + return zoneresponse.id + else: + self.__tcRunLogger.\ + exception("====Zone : %s Creation Failed=====" % + str(zone.name)) + print "\n====Zone : %s Creation Failed=====" % str(zone.name) + if not rec: + zone.name = zone.name + "_" + random_gen() + self.__tcRunLogger.\ + debug("====Recreating Zone With New Name : " + "%s" % zone.name) + print "\n====Recreating Zone With New Name ====", \ + str(zone.name) + return self.createZone(zone, 1) + except Exception as e: + print "\nException Occurred under createZone : %s" % \ + GetDetailExceptionInfo(e) + self.__tcRunLogger.exception("====Create Zone Failed ===") + return FAILED def createZones(self, zones): - for zone in zones: - createzone = createZone.createZoneCmd() - createzone.dns1 = zone.dns1 - createzone.dns2 = zone.dns2 - createzone.internaldns1 = zone.internaldns1 - createzone.internaldns2 = zone.internaldns2 - createzone.name = zone.name - createzone.securitygroupenabled = zone.securitygroupenabled - createzone.localstorageenabled = zone.localstorageenabled - createzone.networktype = zone.networktype - if zone.securitygroupenabled != "true": - createzone.guestcidraddress = zone.guestcidraddress - - zoneresponse = self.apiClient.createZone(createzone) - zoneId = zoneresponse.id - - for pnet in zone.physical_networks: - phynetwrk = self.createPhysicalNetwork(pnet, zoneId) - self.configureProviders(phynetwrk, pnet.providers) - self.updatePhysicalNetwork(phynetwrk.id, "Enabled", - vlan=pnet.vlan) - - if zone.networktype == "Basic": - listnetworkoffering =\ - listNetworkOfferings.listNetworkOfferingsCmd() - listnetworkoffering.name =\ - "DefaultSharedNetscalerEIPandELBNetworkOffering" \ - if len(filter(lambda x: - x.typ == 'Public', - zone.physical_networks[0]. - traffictypes)) > 0 \ - else "DefaultSharedNetworkOfferingWithSGService" - if zone.networkofferingname is not None: - listnetworkoffering.name = zone.networkofferingname - - listnetworkofferingresponse = \ - self.apiClient.listNetworkOfferings(listnetworkoffering) - - guestntwrk = configGenerator.network() - guestntwrk.displaytext = "guestNetworkForBasicZone" - guestntwrk.name = "guestNetworkForBasicZone" - guestntwrk.zoneid = zoneId - guestntwrk.networkofferingid = \ - listnetworkofferingresponse[0].id - - networkid = self.createNetworks([guestntwrk], zoneId) - self.createPods(zone.pods, zoneId, networkid) - if self.isEipElbZone(zone): + try: + for zone in zones: + zonecmd = createZone.createZoneCmd() + zonecmd.dns1 = zone.dns1 + zonecmd.dns2 = zone.dns2 + zonecmd.internaldns1 = zone.internaldns1 + zonecmd.internaldns2 = zone.internaldns2 + zonecmd.name = zone.name + zonecmd.securitygroupenabled = zone.securitygroupenabled + zonecmd.localstorageenabled = zone.localstorageenabled + zonecmd.networktype = zone.networktype + if zone.securitygroupenabled != "true": + zonecmd.guestcidraddress = zone.guestcidraddress + zoneId = self.createZone(zonecmd) + if zoneId == FAILED: + self.__tcRunLogger.\ + exception( + "====Zone: %s Creation Failed. So Exiting=====" % + str(zone.name)) + self.__cleanAndExit() + for pnet in zone.physical_networks: + phynetwrk = self.createPhysicalNetwork(pnet, zoneId) + self.configureProviders(phynetwrk, pnet.providers) + self.updatePhysicalNetwork(phynetwrk.id, "Enabled", + vlan=pnet.vlan) + if zone.networktype == "Basic": + listnetworkoffering =\ + listNetworkOfferings.listNetworkOfferingsCmd() + listnetworkoffering.name =\ + "DefaultSharedNetscalerEIPandELBNetworkOffering" \ + if len(filter(lambda x: + x.typ == 'Public', + zone.physical_networks[0]. + traffictypes)) > 0 \ + else "DefaultSharedNetworkOfferingWithSGService" + if zone.networkofferingname is not None: + listnetworkoffering.name = zone.networkofferingname + listnetworkofferingresponse = \ + self.__apiClient.listNetworkOfferings( + listnetworkoffering) + guestntwrk = configGenerator.network() + guestntwrk.displaytext = "guestNetworkForBasicZone" + guestntwrk.name = "guestNetworkForBasicZone" + guestntwrk.zoneid = zoneId + guestntwrk.networkofferingid = \ + listnetworkofferingresponse[0].id + networkid = self.createNetworks([guestntwrk], zoneId) + self.createPods(zone.pods, zoneId, networkid) + if self.isEipElbZone(zone): + self.createVlanIpRanges( + zone.networktype, zone.ipranges, + zoneId, forvirtualnetwork=True) + isPureAdvancedZone = (zone.networktype == "Advanced" + and zone.securitygroupenabled != "true") + if isPureAdvancedZone: + self.createPods(zone.pods, zoneId) self.createVlanIpRanges(zone.networktype, zone.ipranges, - zoneId, forvirtualnetwork=True) - - isPureAdvancedZone = (zone.networktype == "Advanced" - and zone.securitygroupenabled != "true") - if isPureAdvancedZone: - self.createPods(zone.pods, zoneId) - self.createVlanIpRanges(zone.networktype, zone.ipranges, - zoneId) - elif (zone.networktype == "Advanced" - and zone.securitygroupenabled == "true"): - listnetworkoffering =\ - listNetworkOfferings.listNetworkOfferingsCmd() - listnetworkoffering.name =\ - "DefaultSharedNetworkOfferingWithSGService" - if zone.networkofferingname is not None: - listnetworkoffering.name = zone.networkofferingname - - listnetworkofferingresponse = \ - self.apiClient.listNetworkOfferings(listnetworkoffering) - - networkcmd = createNetwork.createNetworkCmd() - networkcmd.displaytext = "Shared SG enabled network" - networkcmd.name = "Shared SG enabled network" - networkcmd.networkofferingid =\ - listnetworkofferingresponse[0].id - networkcmd.zoneid = zoneId - - ipranges = zone.ipranges - if ipranges: - iprange = ipranges.pop() - networkcmd.startip = iprange.startip - networkcmd.endip = iprange.endip - networkcmd.gateway = iprange.gateway - networkcmd.netmask = iprange.netmask - networkcmd.vlan = iprange.vlan - - networkcmdresponse = self.apiClient.createNetwork(networkcmd) - networkId = networkcmdresponse.id - self.createPods(zone.pods, zoneId, networkId) - - '''Note: Swift needs cache storage first''' - self.createCacheStorages(zone.cacheStorages, zoneId) - self.createSecondaryStorages(zone.secondaryStorages, zoneId) - - enabled = getattr(zone, 'enabled', 'True') - if enabled == 'True' or enabled is None: - self.enableZone(zoneId, "Enabled") - details = getattr(zone, 'details') - if details is not None: - det = [d.__dict__ for d in details] - self.updateZoneDetails(zoneId, det) - - return + zoneId) + elif (zone.networktype == "Advanced" + and zone.securitygroupenabled == "true"): + listnetworkoffering =\ + listNetworkOfferings.listNetworkOfferingsCmd() + listnetworkoffering.name =\ + "DefaultSharedNetworkOfferingWithSGService" + if zone.networkofferingname is not None: + listnetworkoffering.name = zone.networkofferingname + listnetworkofferingresponse = \ + self.__apiClient.listNetworkOfferings( + listnetworkoffering) + networkcmd = createNetwork.createNetworkCmd() + networkcmd.displaytext = "Shared SG enabled network" + networkcmd.name = "Shared SG enabled network" + networkcmd.networkofferingid =\ + listnetworkofferingresponse[0].id + networkcmd.zoneid = zoneId + ipranges = zone.ipranges + if ipranges: + iprange = ipranges.pop() + networkcmd.startip = iprange.startip + networkcmd.endip = iprange.endip + networkcmd.gateway = iprange.gateway + networkcmd.netmask = iprange.netmask + networkcmd.vlan = iprange.vlan + networkcmdresponse = self.__apiClient.createNetwork( + networkcmd) + if networkcmdresponse.id: + self.__addToCleanUp("Network", networkcmdresponse.id) + self.__tcRunLogger.\ + debug("create Network Successful. NetworkId : %s " + % str(networkcmdresponse.id)) + self.createPods(zone.pods, zoneId, networkcmdresponse.id) + '''Note: Swift needs cache storage first''' + self.createCacheStorages(zone.cacheStorages, zoneId) + self.createSecondaryStorages(zone.secondaryStorages, zoneId) + enabled = getattr(zone, 'enabled', 'True') + if enabled == 'True' or enabled is None: + self.enableZone(zoneId, "Enabled") + details = getattr(zone, 'details') + if details is not None: + det = [d.__dict__ for d in details] + self.updateZoneDetails(zoneId, det) + return + except Exception as e: + print "\nException Occurred %s" % GetDetailExceptionInfo(e) + self.__tcRunLogger.exception("==== Create Zones Failed ===") def isEipElbZone(self, zone): if (zone.networktype == "Basic" @@ -479,64 +797,30 @@ def isEipElbZone(self, zone): return True return False - def registerApiKey(self): - listuser = listUsers.listUsersCmd() - listuser.account = "admin" - listuserRes = self.testClient.getApiClient().listUsers(listuser) - userId = listuserRes[0].id - apiKey = listuserRes[0].apikey - securityKey = listuserRes[0].secretkey - if apiKey is None: - registerUser = registerUserKeys.registerUserKeysCmd() - registerUser.id = userId - registerUserRes = \ - self.testClient.getApiClient().registerUserKeys(registerUser) - - apiKey = registerUserRes.apikey - securityKey = registerUserRes.secretkey - - self.config.mgtSvr[0].port = 8080 - self.config.mgtSvr[0].apiKey = apiKey - self.config.mgtSvr[0].securityKey = securityKey - return apiKey, securityKey - - def loadCfg(self): - ''' Retrieving Management Server Connection Details ''' - mgtDetails = self.config.mgtSvr[0] - ''' Retrieving Database Connection Details''' - dbSvrDetails = self.config.dbSvr - - self.testClient = \ - cloudstackTestClient.\ - cloudstackTestClient(mgtDetails, - dbSvrDetails, - logger=self.tcRunLogger) - - if mgtDetails.apiKey is None: - mgtDetails.apiKey, mgtDetails.securityKey = self.registerApiKey() - mgtDetails.port = 8080 - self.testClient = \ - cloudstackTestClient.cloudstackTestClient( - mgtDetails, - dbSvrDetails, - logger=self.tcRunLogger) - - self.apiClient = self.testClient.getApiClient() - """set hypervisor""" - if mgtDetails.hypervisor: - self.apiClient.hypervisor = mgtDetails.hypervisor - else: - self.apiClient.hypervisor = "XenServer" # Defaults to Xenserver + def setClient(self): + ''' + @Name : setClient + @Desc : Sets the API Client retrieved from test client + ''' + self.__apiClient = self.__testClient.getApiClient() def updateConfiguration(self, globalCfg): - if globalCfg is None: - return None - - for config in globalCfg: - updateCfg = updateConfiguration.updateConfigurationCmd() - updateCfg.name = config.name - updateCfg.value = config.value - self.apiClient.updateConfiguration(updateCfg) + try: + if globalCfg is None or self.__apiClient is None: + return None + for config in globalCfg: + updateCfg = updateConfiguration.updateConfigurationCmd() + updateCfg.name = config.name + updateCfg.value = config.value + ret = self.__apiClient.updateConfiguration(updateCfg) + if ret.id: + self.__tcRunLogger.debug( + "==UpdateConfiguration Successfull===") + except Exception as e: + print "Exception Occurred %s" % GetDetailExceptionInfo(e) + self.__tcRunLogger.\ + exception("===UpdateConfiguration Failed===") + self.__cleanAndExit() def copyAttributesToCommand(self, source, command): map(lambda attr: setattr(command, attr, getattr(source, attr, None)), @@ -544,42 +828,311 @@ def copyAttributesToCommand(self, source, command): ["required", "isAsync"], dir(command))) def configureS3(self, s3): - if s3 is None: - return - command = addS3.addS3Cmd() - self.copyAttributesToCommand(s3, command) - self.apiClient.addS3(command) + try: + if s3 is None: + return + command = addS3.addS3Cmd() + self.copyAttributesToCommand(s3, command) + ret = self.__apiClient.addS3(command) + if ret.id: + self.__tcRunLogger.debug("===AddS3 Successfull===") + self.__addToCleanUp("s3", ret.id) + except Exception as e: + self.__tcRunLogger.exception("====AddS3 Failed===") + self.__cleanAndExit() def deploy(self): - self.loadCfg() - self.updateConfiguration(self.config.globalConfig) - self.createZones(self.config.zones) - self.configureS3(self.config.s3) + try: + print "\n==== Deploy DC Started ====" + self.__tcRunLogger.debug("\n==== Deploy DC Started ====") + ''' + Step1 : Set the Client + ''' + self.setClient() + ''' + Step2: Update the Configuration + ''' + self.updateConfiguration(self.__config.globalConfig) + ''' + Step3 :Deploy the Zone + ''' + self.createZones(self.__config.zones) + self.configureS3(self.__config.s3) + ''' + Persist the Configuration to an external file post DC creation + ''' + self.__persistDcConfig() + print "\n====Deploy DC Successful=====" + self.__tcRunLogger.debug("\n====Deploy DC Successful====") + return SUCCESS + except Exception as e: + print "\nException Occurred Under deploy :%s" % \ + GetDetailExceptionInfo(e) + self.__tcRunLogger.debug("\n====Deploy DC Failed====") + print "\n====Deploy DC Failed====" + self.__cleanAndExit() + return FAILED + + +class DeleteDataCenters: + + ''' + @Desc : Deletes the Data Center using the settings provided. + tc_client :Client for deleting the DC. + dc_cfg_file : obj file exported by DeployDataCenter + when successfully created DC. + This file is serialized one containing + entries with successful DC. + dc_cfg: If dc_cfg_file, is not available, we can use + the dictionary of elements to delete. + tc_run_logger: Logger to dump log messages. + ''' + + def __init__(self, + tc_client, + dc_cfg_file=None, + dc_cfg=None, + tc_run_logger=None + ): + self.__dcCfgFile = dc_cfg_file + self.__dcCfg = dc_cfg + self.__tcRunLogger = tc_run_logger + self.__apiClient = None + self.__testClient = tc_client + + def __deleteCmds(self, cmd_name, cmd_obj): + ''' + @Name : __deleteCmds + @Desc : Deletes the entities provided by cmd + ''' + if cmd_name.lower() == "deletehostcmd": + cmd_obj.forcedestroylocalstorage = "true" + cmd_obj.force = "true" + ''' + Step1 : Prepare Host For Maintenance + ''' + host_maint_cmd = prepareHostForMaintenance.\ + prepareHostForMaintenanceCmd() + host_maint_cmd.id = cmd_obj.id + host_maint_resp = self.__apiClient.prepareHostForMaintenance( + host_maint_cmd) + if host_maint_resp: + ''' + Step2 : List Hosts for Resource State + ''' + list_host_cmd = listHosts.listHostsCmd() + list_host_cmd.id = cmd_obj.id + retries = 3 + for i in xrange(retries): + list_host_resp = self.__apiClient.\ + listHosts(list_host_cmd) + if (list_host_resp) and\ + (list_host_resp[0].resourcestate == 'Maintenance'): + break + sleep(30) + if cmd_name.lower() == "deletestoragepoolcmd": + cmd_obj.forced = "true" + store_maint_cmd = enableStorageMaintenance.\ + enableStorageMaintenanceCmd() + store_maint_cmd.id = cmd_obj.id + store_maint_resp = self.__apiClient.\ + enableStorageMaintenance(store_maint_cmd) + if store_maint_resp: + list_store_cmd = listStoragePools.listStoragePoolsCmd() + list_store_cmd.id = cmd_obj.id + retries = 3 + for i in xrange(retries): + store_maint_resp = self.__apiClient.\ + listStoragePools(list_store_cmd) + if (store_maint_resp) and \ + (store_maint_resp[0].state == 'Maintenance'): + break + sleep(30) + return cmd_obj + + def __setClient(self): + ''' + @Name : setClient + @Desc : Sets the API Client retrieved from test client + ''' + self.__apiClient = self.__testClient.getApiClient() + + def __cleanEntries(self): + ''' + @Name : __cleanAndEntries + @Description: Cleans up the created DC in order of creation + ''' + try: + ret = FAILED + if "order" in self.__dcCfg.keys() and len(self.__dcCfg["order"]): + self.__dcCfg["order"].reverse() + print "\n====Clean Up Entries===", self.__dcCfg + for type in self.__dcCfg["order"]: + self.__tcRunLogger.debug( + "====CleanUp Started For Type: %s====" % + type) + if type: + temp_ids = self.__dcCfg[type] + ids = [items for items in temp_ids if items] + for id in ids: + del_mod = "delete" + type + del_cmd = getattr( + globals()[del_mod], + del_mod + "Cmd") + del_cmd_obj = del_cmd() + del_cmd_resp = getattr( + globals()[del_mod], + del_mod + "Response") + del_cmd_obj.id = id + del_cmd_obj = self.__deleteCmds( + del_mod + + "Cmd", + del_cmd_obj) + del_func = getattr(self.__apiClient, del_mod) + del_cmd_resp = del_func(del_cmd_obj) + if del_cmd_resp: + self.__tcRunLogger.debug( + "====%s CleanUp Failed. ID: %s ===" % + (type, id)) + else: + self.__tcRunLogger.debug( + "====%s CleanUp Successful. ID : %s===" % + (type, id)) + ret = SUCCESS + except Exception as e: + print "\n==== Exception Under __cleanEntries: %s ==== % " \ + % GetDetailExceptionInfo(e) + self.__tcRunLogger.exception( + "\n==== Exception Under __cleanEntries: %s ==== % " % + GetDetailExceptionInfo(e)) + finally: + return ret + + def removeDataCenter(self): + ''' + @Name : removeDataCenter + @Desc : Removes the Data Center provided by Configuration + If Input dc file configuration is None, uses the cfg provided + else uses the dc file to get the configuration + ''' + try: + self.__setClient() + self.__tcRunLogger.debug("====DeployDC: CleanUp Started====") + print "\n====DeployDC: CleanUp Started====" + ret = FAILED + if self.__dcCfgFile: + file_to_read = open(self.__dcCfgFile, 'r') + if file_to_read: + self.__dcCfg = pickle.load(file_to_read) + if self.__dcCfg: + ret = self.__cleanEntries() + except Exception as e: + print "\n==== Exception Under removeDataCenter: %s ====" % \ + GetDetailExceptionInfo(e) + self.__tcRunLogger.exception( + "===DeployDC CleanUp FAILED: %s ====" % + GetDetailExceptionInfo(e)) + finally: + return ret + if __name__ == "__main__": + ''' + @Desc : This module facilitates the following: + 1. Deploying DataCenter by using the input provided + configuration. + EX: python deployDataCenter.py -i + 2. Removes a created DataCenter by providing + the input configuration file and data center settings file + EX: python deployDataCenter.py -i + -r + ''' parser = OptionParser() parser.add_option("-i", "--input", action="store", - default="./datacenterCfg", dest="input", help="the path \ - where the json config file generated, by default is \ - ./datacenterCfg") - + default=None, dest="input", + help="the path \ + where the json config file generated") + + parser.add_option("-r", "--remove", action="store", + default=None, dest="remove", + help="path to file\ + where the created dc entries are kept") (options, args) = parser.parse_args() + + ''' + Verify the input validity + ''' + if options.input is None and options.remove is None: + print "\n==== For DeployDataCenter: Please Specify a " \ + "Valid Input Configuration File====" + print "\n==== For DeleteDataCenters: Please Specify a " \ + "Valid Input Configuration File and DC Settings====" + exit(1) + + ''' + Imports the Modules Required + ''' from marvin.marvinLog import MarvinLog - cfg = configGenerator.getSetupConfig(options.input) + from marvin.cloudstackTestClient import CSTestClient + + ''' + Step1: Create the Logger + ''' + if (options.input) and not (os.path.isfile(options.input)): + print "\n=== Invalid Input Config File Path, Please Check ===" + exit(1) + log_obj = MarvinLog("CSLog") - tcRunLogger = log_obj.setLogHandler("/tmp/debug.log") - deploy = deployDataCenters(cfg, tcRunLogger) - deploy.deploy() - - """ - create = createStoragePool.createStoragePoolCmd() - create.clusterid = 1 - create.podid = 2 - create.name = "fdffdf" - create.url = "nfs://jfkdjf/fdkjfkd" - create.zoneid = 2 - - deploy = deployDataCenters("./datacenterCfg") - deploy.loadCfg() - deploy.apiClient.createStoragePool(create) - """ + cfg = configGenerator.getSetupConfig(options.input) + log = cfg.logger + + ret = log_obj.createLogs("DeployDataCenter", + log) + if ret != FAILED: + log_folder_path = log_obj.getLogFolderPath() + tc_run_logger = log_obj.getLogger() + else: + print "\n===Log Creation Failed. Please Check===" + exit(1) + + ''' + Step2 : Create Test Client + ''' + obj_tc_client = CSTestClient(cfg.mgtSvr[0], cfg.dbSvr, + logger=tc_run_logger) + if obj_tc_client and obj_tc_client.createTestClient() == FAILED: + print "\n=== TestClient Creation Failed===" + exit(1) + + ''' + Step3: Verify and continue whether to deploy a DC or remove a DC + ''' + + if (options.input) and (os.path.isfile(options.input)) and \ + (options.remove is None): + ''' + @Desc : Deploys a Data Center with provided Config + ''' + deploy = DeployDataCenters(obj_tc_client, + cfg, + tc_run_logger, + log_folder_path=log_folder_path) + deploy.deploy() + exit(1) + + if options.remove and os.path.isfile(options.remove) and options.input: + ''' + @Desc : Removes a Data Center with provided Config + ''' + remove_dc_obj = DeleteDataCenters(obj_tc_client, + dc_cfg_file=options.remove, + tc_run_logger=tc_run_logger + ) + if remove_dc_obj: + if remove_dc_obj.removeDataCenter() == FAILED: + print "\n===Removing DataCenter Failed===" + tc_run_logger.debug("\n===Removing DataCenter Failed===") + else: + print "\n===Removing DataCenter Successful===" + tc_run_logger.debug("\n===Removing DataCenter Successful===") + exit(1) diff --git a/tools/marvin/marvin/integration/lib/common.py b/tools/marvin/marvin/integration/lib/common.py deleted file mode 100644 index 3b292bf920..0000000000 --- a/tools/marvin/marvin/integration/lib/common.py +++ /dev/null @@ -1,1001 +0,0 @@ -# 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. -"""Common functions -""" - -#Import Local Modules -from marvin.cloudstackAPI import (listConfigurations, - listPhysicalNetworks, - listRegions, - addNetworkServiceProvider, - updateNetworkServiceProvider, - listDomains, - listZones, - listPods, - listOsTypes, - listTemplates, - updateResourceLimit, - listRouters, - listNetworks, - listClusters, - listSystemVms, - listStoragePools, - listVirtualMachines, - listLoadBalancerRuleInstances, - listFirewallRules, - listVolumes, - listIsos, - listAccounts, - listSnapshotPolicies, - listDiskOfferings, - listVlanIpRanges, - listUsageRecords, - listNetworkServiceProviders, - listHosts, - listPublicIpAddresses, - listPortForwardingRules, - listLoadBalancerRules, - listSnapshots, - listUsers, - listEvents, - listServiceOfferings, - listVirtualRouterElements, - listNetworkOfferings, - listResourceLimits, - listVPCOfferings) -from marvin.integration.lib.base import (Configurations, - NetScaler, - Template, - Resources, - PhysicalNetwork, - Host, - PublicIPAddress, - NetworkOffering, - Network) -from marvin.integration.lib.utils import (get_process_status, - xsplit, - validateList) - -from marvin.sshClient import SshClient -from marvin.codes import PASS, ISOLATED_NETWORK, VPC_NETWORK, BASIC_ZONE, FAIL -import random - -#Import System modules -import time - - -def is_config_suitable(apiclient, name, value): - """ - Ensure if the deployment has the expected `value` for the global setting `name' - @return: true if value is set, else false - """ - configs = Configurations.list(apiclient, name=name) - assert(configs is not None and isinstance(configs, list) and len(configs) > 0) - return configs[0].value == value - -def wait_for_cleanup(apiclient, configs=None): - """Sleeps till the cleanup configs passed""" - - # Configs list consists of the list of global configs - if not isinstance(configs, list): - return - for config in configs: - cmd = listConfigurations.listConfigurationsCmd() - cmd.name = config - cmd.listall = True - try: - config_descs = apiclient.listConfigurations(cmd) - except Exception as e: - raise Exception("Failed to fetch configurations: %s" % e) - - if not isinstance(config_descs, list): - raise Exception("List configs didn't returned a valid data") - - config_desc = config_descs[0] - # Sleep for the config_desc.value time - time.sleep(int(config_desc.value)) - return - -def add_netscaler(apiclient, zoneid, NSservice): - """ Adds Netscaler device and enables NS provider""" - - cmd = listPhysicalNetworks.listPhysicalNetworksCmd() - cmd.zoneid = zoneid - physical_networks = apiclient.listPhysicalNetworks(cmd) - if isinstance(physical_networks, list): - physical_network = physical_networks[0] - - cmd = listNetworkServiceProviders.listNetworkServiceProvidersCmd() - cmd.name = 'Netscaler' - cmd.physicalnetworkid=physical_network.id - nw_service_providers = apiclient.listNetworkServiceProviders(cmd) - - if isinstance(nw_service_providers, list): - netscaler_provider = nw_service_providers[0] - else: - cmd1 = addNetworkServiceProvider.addNetworkServiceProviderCmd() - cmd1.name = 'Netscaler' - cmd1.physicalnetworkid = physical_network.id - netscaler_provider = apiclient.addNetworkServiceProvider(cmd1) - - netscaler = NetScaler.add( - apiclient, - NSservice, - physicalnetworkid=physical_network.id - ) - if netscaler_provider.state != 'Enabled': - cmd = updateNetworkServiceProvider.updateNetworkServiceProviderCmd() - cmd.id = netscaler_provider.id - cmd.state = 'Enabled' - apiclient.updateNetworkServiceProvider(cmd) - - return netscaler - -def get_region(apiclient, services=None): - "Returns a default region" - - cmd = listRegions.listRegionsCmd() - if services: - if "regionid" in services: - cmd.id = services["regionid"] - - regions = apiclient.listRegions(cmd) - - if isinstance(regions, list): - assert len(regions) > 0 - return regions[0] - else: - raise Exception("Failed to find specified region.") - -def get_domain(apiclient, services=None): - "Returns a default domain" - - cmd = listDomains.listDomainsCmd() - if services: - if "domainid" in services: - cmd.id = services["domainid"] - - domains = apiclient.listDomains(cmd) - - if isinstance(domains, list): - assert len(domains) > 0 - return domains[0] - else: - raise Exception("Failed to find specified domain.") - - -def get_zone(apiclient, services=None): - "Returns a default zone" - - cmd = listZones.listZonesCmd() - if services: - if "zoneid" in services: - cmd.id = services["zoneid"] - - zones = apiclient.listZones(cmd) - - if isinstance(zones, list): - assert len(zones) > 0, "There are no available zones in the deployment" - return zones[0] - else: - raise Exception("Failed to find specified zone.") - - -def get_pod(apiclient, zoneid, services=None): - "Returns a default pod for specified zone" - - cmd = listPods.listPodsCmd() - cmd.zoneid = zoneid - - if services: - if "podid" in services: - cmd.id = services["podid"] - - pods = apiclient.listPods(cmd) - - if isinstance(pods, list): - assert len(pods) > 0, "No pods found for zone %s"%zoneid - return pods[0] - else: - raise Exception("Exception: Failed to find specified pod.") - - -def get_template(apiclient, zoneid, ostype, services=None, - templatefilter='featured', - templatetype='BUILTIN'): - "Returns a featured built in template in given zone" - - cmd = listTemplates.listTemplatesCmd() - cmd.templatefilter = templatefilter - cmd.zoneid = zoneid - - if services: - if "template" in services: - cmd.id = services["template"] - - list_templates = apiclient.listTemplates(cmd) - - if isinstance(list_templates, list): - assert len(list_templates) > 0, "received empty response on featured templates" - for template in list_templates: - if template.isready and template.templatetype == templatetype: - return template - - raise Exception("Exception: Failed to find built in template which is in " - "ready state: %s" % templatetype) - return - - -def download_systemplates_sec_storage(server, services): - """Download System templates on sec storage""" - - try: - # Login to management server - ssh = SshClient( - server["ipaddress"], - server["port"], - server["username"], - server["password"] - ) - except Exception: - raise Exception("SSH access failted for server with IP address: %s" % - server["ipaddess"]) - # Mount Secondary Storage on Management Server - cmds = [ - "mkdir -p %s" % services["mnt_dir"], - "mount -t nfs %s:/%s %s" % ( - services["sec_storage"], - services["path"], - services["mnt_dir"] - ), - "%s -m %s -u %s -h %s -F" % ( - services["command"], - services["mnt_dir"], - services["download_url"], - services["hypervisor"] - ) - ] - for c in cmds: - result = ssh.execute(c) - - res = str(result) - - # Unmount the Secondary storage - ssh.execute("umount %s" % (services["mnt_dir"])) - - if res.count("Successfully installed system VM template") == 1: - return - else: - raise Exception("Failed to download System Templates on Sec Storage") - return - - -def wait_for_ssvms(apiclient, zoneid, podid, interval=60): - """After setup wait for SSVMs to come Up""" - - time.sleep(interval) - timeout = 40 - while True: - list_ssvm_response = list_ssvms( - apiclient, - systemvmtype='secondarystoragevm', - zoneid=zoneid, - podid=podid - ) - ssvm = list_ssvm_response[0] - if ssvm.state != 'Running': - # Sleep to ensure SSVMs are Up and Running - time.sleep(interval) - timeout = timeout - 1 - elif ssvm.state == 'Running': - break - elif timeout == 0: - raise Exception("SSVM failed to come up") - break - - timeout = 40 - while True: - list_ssvm_response = list_ssvms( - apiclient, - systemvmtype='consoleproxy', - zoneid=zoneid, - podid=podid - ) - cpvm = list_ssvm_response[0] - if cpvm.state != 'Running': - # Sleep to ensure SSVMs are Up and Running - time.sleep(interval) - timeout = timeout - 1 - elif cpvm.state == 'Running': - break - elif timeout == 0: - raise Exception("CPVM failed to come up") - break - return - -def get_builtin_template_info(apiclient, zoneid): - """Returns hypervisor specific infor for templates""" - - list_template_response = Template.list( - apiclient, - templatefilter='featured', - zoneid=zoneid, - ) - - for b_template in list_template_response: - if b_template.templatetype == 'BUILTIN': - break - - extract_response = Template.extract(apiclient, - b_template.id, - 'HTTP_DOWNLOAD', - zoneid) - - return extract_response.url, b_template.hypervisor, b_template.format - -def download_builtin_templates(apiclient, zoneid, hypervisor, host, - linklocalip, interval=60): - """After setup wait till builtin templates are downloaded""" - - # Change IPTABLES Rules - get_process_status( - host["ipaddress"], - host["port"], - host["username"], - host["password"], - linklocalip, - "iptables -P INPUT ACCEPT" - ) - time.sleep(interval) - # Find the BUILTIN Templates for given Zone, Hypervisor - list_template_response = list_templates( - apiclient, - hypervisor=hypervisor, - zoneid=zoneid, - templatefilter='self' - ) - - if not isinstance(list_template_response, list): - raise Exception("Failed to download BUILTIN templates") - - # Ensure all BUILTIN templates are downloaded - templateid = None - for template in list_template_response: - if template.templatetype == "BUILTIN": - templateid = template.id - - # Sleep to ensure that template is in downloading state after adding - # Sec storage - time.sleep(interval) - while True: - template_response = list_templates( - apiclient, - id=templateid, - zoneid=zoneid, - templatefilter='self' - ) - template = template_response[0] - # If template is ready, - # template.status = Download Complete - # Downloading - x% Downloaded - # Error - Any other string - if template.status == 'Download Complete': - break - - elif 'Downloaded' in template.status: - time.sleep(interval) - - elif 'Installing' not in template.status: - raise Exception("ErrorInDownload") - - return - - -def update_resource_limit(apiclient, resourcetype, account=None, - domainid=None, max=None, projectid=None): - """Updates the resource limit to 'max' for given account""" - - cmd = updateResourceLimit.updateResourceLimitCmd() - cmd.resourcetype = resourcetype - if account: - cmd.account = account - if domainid: - cmd.domainid = domainid - if max: - cmd.max = max - if projectid: - cmd.projectid = projectid - apiclient.updateResourceLimit(cmd) - return - - -def list_os_types(apiclient, **kwargs): - """List all os types matching criteria""" - - cmd = listOsTypes.listOsTypesCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listOsTypes(cmd)) - - -def list_routers(apiclient, **kwargs): - """List all Routers matching criteria""" - - cmd = listRouters.listRoutersCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listRouters(cmd)) - - -def list_zones(apiclient, **kwargs): - """List all Zones matching criteria""" - - cmd = listZones.listZonesCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listZones(cmd)) - - -def list_networks(apiclient, **kwargs): - """List all Networks matching criteria""" - - cmd = listNetworks.listNetworksCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listNetworks(cmd)) - - -def list_clusters(apiclient, **kwargs): - """List all Clusters matching criteria""" - - cmd = listClusters.listClustersCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listClusters(cmd)) - - -def list_ssvms(apiclient, **kwargs): - """List all SSVMs matching criteria""" - - cmd = listSystemVms.listSystemVmsCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listSystemVms(cmd)) - - -def list_storage_pools(apiclient, **kwargs): - """List all storage pools matching criteria""" - - cmd = listStoragePools.listStoragePoolsCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listStoragePools(cmd)) - - -def list_virtual_machines(apiclient, **kwargs): - """List all VMs matching criteria""" - - cmd = listVirtualMachines.listVirtualMachinesCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listVirtualMachines(cmd)) - - -def list_hosts(apiclient, **kwargs): - """List all Hosts matching criteria""" - - cmd = listHosts.listHostsCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listHosts(cmd)) - - -def list_configurations(apiclient, **kwargs): - """List configuration with specified name""" - - cmd = listConfigurations.listConfigurationsCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listConfigurations(cmd)) - - -def list_publicIP(apiclient, **kwargs): - """List all Public IPs matching criteria""" - - cmd = listPublicIpAddresses.listPublicIpAddressesCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listPublicIpAddresses(cmd)) - - -def list_nat_rules(apiclient, **kwargs): - """List all NAT rules matching criteria""" - - cmd = listPortForwardingRules.listPortForwardingRulesCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listPortForwardingRules(cmd)) - - -def list_lb_rules(apiclient, **kwargs): - """List all Load balancing rules matching criteria""" - - cmd = listLoadBalancerRules.listLoadBalancerRulesCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listLoadBalancerRules(cmd)) - - -def list_lb_instances(apiclient, **kwargs): - """List all Load balancing instances matching criteria""" - - cmd = listLoadBalancerRuleInstances.listLoadBalancerRuleInstancesCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listLoadBalancerRuleInstances(cmd)) - - -def list_firewall_rules(apiclient, **kwargs): - """List all Firewall Rules matching criteria""" - - cmd = listFirewallRules.listFirewallRulesCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listFirewallRules(cmd)) - - -def list_volumes(apiclient, **kwargs): - """List all volumes matching criteria""" - - cmd = listVolumes.listVolumesCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listVolumes(cmd)) - - -def list_isos(apiclient, **kwargs): - """Lists all available ISO files.""" - - cmd = listIsos.listIsosCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listIsos(cmd)) - - -def list_snapshots(apiclient, **kwargs): - """List all snapshots matching criteria""" - - cmd = listSnapshots.listSnapshotsCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listSnapshots(cmd)) - - -def list_templates(apiclient, **kwargs): - """List all templates matching criteria""" - - cmd = listTemplates.listTemplatesCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listTemplates(cmd)) - - -def list_domains(apiclient, **kwargs): - """Lists domains""" - - cmd = listDomains.listDomainsCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listDomains(cmd)) - - -def list_accounts(apiclient, **kwargs): - """Lists accounts and provides detailed account information for - listed accounts""" - - cmd = listAccounts.listAccountsCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listAccounts(cmd)) - - -def list_users(apiclient, **kwargs): - """Lists users and provides detailed account information for - listed users""" - - cmd = listUsers.listUsersCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listUsers(cmd)) - - -def list_snapshot_policy(apiclient, **kwargs): - """Lists snapshot policies.""" - - cmd = listSnapshotPolicies.listSnapshotPoliciesCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listSnapshotPolicies(cmd)) - - -def list_events(apiclient, **kwargs): - """Lists events""" - - cmd = listEvents.listEventsCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listEvents(cmd)) - - -def list_disk_offering(apiclient, **kwargs): - """Lists all available disk offerings.""" - - cmd = listDiskOfferings.listDiskOfferingsCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listDiskOfferings(cmd)) - - -def list_service_offering(apiclient, **kwargs): - """Lists all available service offerings.""" - - cmd = listServiceOfferings.listServiceOfferingsCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listServiceOfferings(cmd)) - - -def list_vlan_ipranges(apiclient, **kwargs): - """Lists all VLAN IP ranges.""" - - cmd = listVlanIpRanges.listVlanIpRangesCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listVlanIpRanges(cmd)) - - -def list_usage_records(apiclient, **kwargs): - """Lists usage records for accounts""" - - cmd = listUsageRecords.listUsageRecordsCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listUsageRecords(cmd)) - - -def list_nw_service_prividers(apiclient, **kwargs): - """Lists Network service providers""" - - cmd = listNetworkServiceProviders.listNetworkServiceProvidersCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listNetworkServiceProviders(cmd)) - - -def list_virtual_router_elements(apiclient, **kwargs): - """Lists Virtual Router elements""" - - cmd = listVirtualRouterElements.listVirtualRouterElementsCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listVirtualRouterElements(cmd)) - - -def list_network_offerings(apiclient, **kwargs): - """Lists network offerings""" - - cmd = listNetworkOfferings.listNetworkOfferingsCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listNetworkOfferings(cmd)) - - -def list_resource_limits(apiclient, **kwargs): - """Lists resource limits""" - - cmd = listResourceLimits.listResourceLimitsCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listResourceLimits(cmd)) - -def list_vpc_offerings(apiclient, **kwargs): - """ Lists VPC offerings """ - - cmd = listVPCOfferings.listVPCOfferingsCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listVPCOfferings(cmd)) - -def update_resource_count(apiclient, domainid, accountid=None, - projectid=None, rtype=None): - """updates the resource count - 0 - VM - 1 - Public IP - 2 - Volume - 3 - Snapshot - 4 - Template - 5 - Projects - 6 - Network - 7 - VPC - 8 - CPUs - 9 - RAM - 10 - Primary (shared) storage (Volumes) - 11 - Secondary storage (Snapshots, Templates & ISOs) - """ - - Resources.updateCount(apiclient, - domainid=domainid, - account=accountid if accountid else None, - projectid=projectid if projectid else None, - resourcetype=rtype if rtype else None - ) - return - -def findSuitableHostForMigration(apiclient, vmid): - """Returns a suitable host for VM migration""" - suitableHost = None - try: - hosts = Host.listForMigration(apiclient, virtualmachineid=vmid, - ) - except Exception as e: - raise Exception("Exception while getting hosts list suitable for migration: %s" % e) - - suitablehosts = [] - if isinstance(hosts, list) and len(hosts) > 0: - suitablehosts = [host for host in hosts if (str(host.resourcestate).lower() == "enabled"\ - and str(host.state).lower() == "up")] - if len(suitablehosts)>0: - suitableHost = suitablehosts[0] - - return suitableHost - -def get_resource_type(resource_id): - """Returns resource type""" - - lookup = { 0: "VM", - 1: "Public IP", - 2: "Volume", - 3: "Snapshot", - 4: "Template", - 5: "Projects", - 6: "Network", - 7: "VPC", - 8: "CPUs", - 9: "RAM", - 10: "Primary (shared) storage (Volumes)", - 11: "Secondary storage (Snapshots, Templates & ISOs)" - } - - return lookup[resource_id] - -def get_portable_ip_range_services(config): - """ Reads config values related to portable ip and fills up - services accordingly""" - - services = {} - attributeError = False - - if config.portableIpRange.startip: - services["startip"] = config.portableIpRange.startip - else: - attributeError = True - - if config.portableIpRange.endip: - services["endip"] = config.portableIpRange.endip - else: - attributeError = True - - if config.portableIpRange.netmask: - services["netmask"] = config.portableIpRange.netmask - else: - attributeError = True - - if config.portableIpRange.gateway: - services["gateway"] = config.portableIpRange.gateway - else: - attributeError = True - - if config.portableIpRange.vlan: - services["vlan"] = config.portableIpRange.vlan - - if attributeError: - services = None - - return services - -def get_free_vlan(apiclient, zoneid): - """ - Find an unallocated VLAN outside the range allocated to the physical network. - - @note: This does not guarantee that the VLAN is available for use in - the deployment's network gear - @return: physical_network, shared_vlan_tag - """ - list_physical_networks_response = PhysicalNetwork.list( - apiclient, - zoneid=zoneid - ) - assert isinstance(list_physical_networks_response, list) - assert len(list_physical_networks_response) > 0, "No physical networks found in zone %s" % zoneid - - physical_network = list_physical_networks_response[0] - - networks = list_networks(apiclient, zoneid= zoneid, type='Shared') - usedVlanIds = [] - - if isinstance(networks, list) and len(networks) > 0: - usedVlanIds = [int(nw.vlan) for nw in networks if nw.vlan!="untagged"] - - if hasattr(physical_network, "vlan") is False: - while True: - shared_ntwk_vlan = random.randrange(1,4095) - if shared_ntwk_vlan in usedVlanIds: - continue - else: - break - else: - vlans = xsplit(physical_network.vlan, ['-', ',']) - - assert len(vlans) > 0 - assert int(vlans[0]) < int(vlans[-1]), "VLAN range %s was improperly split" % physical_network.vlan - - retriesCount = 20 #Assuming random function will give different integer each time - - shared_ntwk_vlan = None - - while True: - - if retriesCount == 0: - break - - free_vlan = int(vlans[-1]) + random.randrange(1, 20) - - if free_vlan > 4095: - free_vlan = int(vlans[0]) - random.randrange(1, 20) - if free_vlan < 0 or (free_vlan in usedVlanIds): - retriesCount -= 1 - continue - else: - shared_ntwk_vlan = free_vlan - break - - return physical_network, shared_ntwk_vlan - -def setNonContiguousVlanIds(apiclient, zoneid): - """ - Form the non contiguous ranges based on currently assigned range in physical network - """ - - NonContigVlanIdsAcquired = False - - list_physical_networks_response = PhysicalNetwork.list( - apiclient, - zoneid=zoneid - ) - assert isinstance(list_physical_networks_response, list) - assert len(list_physical_networks_response) > 0, "No physical networks found in zone %s" % zoneid - - for physical_network in list_physical_networks_response: - - vlans = xsplit(physical_network.vlan, ['-', ',']) - - assert len(vlans) > 0 - assert int(vlans[0]) < int(vlans[-1]), "VLAN range %s was improperly split" % physical_network.vlan - - # Keep some gap between existing vlan and the new vlans which we are going to add - # So that they are non contiguous - - non_contig_end_vlan_id = int(vlans[-1]) + 6 - non_contig_start_vlan_id = int(vlans[0]) - 6 - - # Form ranges which are consecutive to existing ranges but not immediately contiguous - # There should be gap in between existing range and new non contiguous ranage - - # If you can't add range after existing range, because it's crossing 4095, then - # select VLAN ids before the existing range such that they are greater than 0, and - # then add this non contiguoud range - vlan = { "partial_range": ["",""], "full_range": ""} - - if non_contig_end_vlan_id < 4095: - vlan["partial_range"][0] = str(non_contig_end_vlan_id - 4) + '-' + str(non_contig_end_vlan_id - 3) - vlan["partial_range"][1] = str(non_contig_end_vlan_id - 1) + '-' + str(non_contig_end_vlan_id) - vlan["full_range"] = str(non_contig_end_vlan_id - 4) + '-' + str(non_contig_end_vlan_id) - NonContigVlanIdsAcquired = True - - elif non_contig_start_vlan_id > 0: - vlan["partial_range"][0] = str(non_contig_start_vlan_id) + '-' + str(non_contig_start_vlan_id + 1) - vlan["partial_range"][1] = str(non_contig_start_vlan_id + 3) + '-' + str(non_contig_start_vlan_id + 4) - vlan["full_range"] = str(non_contig_start_vlan_id) + '-' + str(non_contig_start_vlan_id + 4) - NonContigVlanIdsAcquired = True - - else: - NonContigVlanIdsAcquired = False - - # If failed to get relevant vlan ids, continue to next physical network - # else break from loop as we have hot the non contiguous vlan ids for the test purpose - - if not NonContigVlanIdsAcquired: - continue - else: - break - - # If even through looping from all existing physical networks, failed to get relevant non - # contiguous vlan ids, then fail the test case - - if not NonContigVlanIdsAcquired: - return None, None - - return physical_network, vlan - -def is_public_ip_in_correct_state(apiclient, ipaddressid, state): - """ Check if the given IP is in the correct state (given) - and return True/False accordingly""" - retriesCount = 10 - while True: - portableips = PublicIPAddress.list(apiclient, id=ipaddressid) - assert validateList(portableips)[0] == PASS, "IPs list validation failed" - if str(portableips[0].state).lower() == state: - break - elif retriesCount == 0: - return False - else: - retriesCount -= 1 - time.sleep(60) - continue - return True - -def setSharedNetworkParams(networkServices, range=20): - """Fill up the services dictionary for shared network using random subnet""" - - # @range: range decides the endip. Pass the range as "x" if you want the difference between the startip - # and endip as "x" - # Set the subnet number of shared networks randomly prior to execution - # of each test case to avoid overlapping of ip addresses - shared_network_subnet_number = random.randrange(1,254) - - networkServices["gateway"] = "172.16."+str(shared_network_subnet_number)+".1" - networkServices["startip"] = "172.16."+str(shared_network_subnet_number)+".2" - networkServices["endip"] = "172.16."+str(shared_network_subnet_number)+"."+str(range+1) - networkServices["netmask"] = "255.255.255.0" - return networkServices - -def createEnabledNetworkOffering(apiclient, networkServices): - """Create and enable network offering according to the type - - @output: List, containing [ Result,Network Offering,Reason ] - Ist Argument('Result') : FAIL : If exception or assertion error occurs - PASS : If network offering - is created and enabled successfully - IInd Argument(Net Off) : Enabled network offering - In case of exception or - assertion error, it will be None - IIIrd Argument(Reason) : Reason for failure, - default to None - """ - try: - resultSet = [FAIL, None, None] - # Create network offering - network_offering = NetworkOffering.create(apiclient, networkServices, conservemode=False) - - # Update network offering state from disabled to enabled. - NetworkOffering.update(network_offering, apiclient, id=network_offering.id, - state="enabled") - except Exception as e: - resultSet[2] = e - return resultSet - return [PASS, network_offering, None] - -def shouldTestBeSkipped(networkType, zoneType): - """Decide which test to skip, according to type of network and zone type""" - - # If network type is isolated or vpc and zone type is basic, then test should be skipped - skipIt = False - if ((networkType.lower() == str(ISOLATED_NETWORK).lower() or networkType.lower() == str(VPC_NETWORK).lower()) - and (zoneType.lower() == BASIC_ZONE)): - skipIt = True - return skipIt - -def verifyNetworkState(apiclient, networkid, state): - """List networks and check if the network state matches the given state""" - try: - networks = Network.list(apiclient, id=networkid) - except Exception as e: - raise Exception("Failed while fetching network list with error: %s" % e) - assert validateList(networks)[0] == PASS, "Networks list validation failed, list is %s" % networks - assert str(networks[0].state).lower() == state, "network state should be %s, it is %s" % (state, networks[0].state) - return - -def verifyComputeOfferingCreation(apiclient, computeofferingid): - """List Compute offerings by ID and verify that the offering exists""" - - cmd = listServiceOfferings.listServiceOfferingsCmd() - cmd.id = computeofferingid - serviceOfferings = None - try: - serviceOfferings = apiclient.listServiceOfferings(cmd) - except Exception as e: - return FAIL - if not (isinstance(serviceOfferings, list) and len(serviceOfferings) > 0): - return FAIL - return PASS diff --git a/tools/marvin/marvin/jsonHelper.py b/tools/marvin/marvin/jsonHelper.py index ae40b8dabf..3f48a00ba6 100644 --- a/tools/marvin/marvin/jsonHelper.py +++ b/tools/marvin/marvin/jsonHelper.py @@ -18,11 +18,13 @@ import cloudstackException import json import inspect -from cloudstackAPI import * +from marvin.cloudstackAPI import * class jsonLoader(object): + '''The recursive class for building and representing objects with.''' + def __init__(self, obj): for k in obj: v = obj[k] @@ -52,6 +54,7 @@ def __str__(self): class jsonDump(object): + @staticmethod def __serialize(obj): """Recursively walk object's hierarchy.""" @@ -145,7 +148,7 @@ def getResultObj(returnObj, responsecls=None): errMsg = "errorCode: %s, errorText:%s" % (result.errorcode, result.errortext) respname = responseName.replace("response", "") - raise cloudstackException.cloudstackAPIException(respname, errMsg) + raise cloudstackException.CloudstackAPIException(respname, errMsg) if result.count is not None: for key in result.__dict__.iterkeys(): @@ -247,7 +250,7 @@ def getResultObj(returnObj, responsecls=None): }''' try: asynJob = getResultObj(result) - except cloudstackException.cloudstackAPIException, e: + except cloudstackException.CloudstackAPIException as e: print e result = '{ "queryasyncjobresultresponse" : {} }' diff --git a/tools/marvin/marvin/integration/__init__.py b/tools/marvin/marvin/lib/__init__.py similarity index 98% rename from tools/marvin/marvin/integration/__init__.py rename to tools/marvin/marvin/lib/__init__.py index 57823fcc16..13a83393a9 100644 --- a/tools/marvin/marvin/integration/__init__.py +++ b/tools/marvin/marvin/lib/__init__.py @@ -5,14 +5,12 @@ # 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. - - diff --git a/tools/marvin/marvin/integration/lib/base.py b/tools/marvin/marvin/lib/base.py old mode 100755 new mode 100644 similarity index 74% rename from tools/marvin/marvin/integration/lib/base.py rename to tools/marvin/marvin/lib/base.py index b7e2be4755..5d750375fb --- a/tools/marvin/marvin/integration/lib/base.py +++ b/tools/marvin/marvin/lib/base.py @@ -20,8 +20,12 @@ """ import marvin -from utils import is_server_ssh_ready, random_gen from marvin.cloudstackAPI import * +from marvin.codes import (FAILED, FAIL, PASS, RUNNING, STOPPED, + STARTING, DESTROYED, EXPUNGING, + STOPPING, BACKED_UP, BACKING_UP) +from marvin.cloudstackException import GetDetailExceptionInfo +from marvin.lib.utils import validateList, is_server_ssh_ready, random_gen # Import System modules import time import hashlib @@ -29,7 +33,9 @@ class Domain: + """ Domain Life Cycle """ + def __init__(self, items): self.__dict__.update(items) @@ -77,11 +83,15 @@ def list(cls, apiclient, **kwargs): """Lists domains""" cmd = listDomains.listDomainsCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True return(apiclient.listDomains(cmd)) class Account: + """ Account Life Cycle """ + def __init__(self, items): self.__dict__.update(items) @@ -99,16 +109,16 @@ def create(cls, apiclient, services, admin=False, domainid=None): cmd.password = services["password"] - username = "-".join([services["username"], random_gen(id=apiclient.id)]) + username = "-".join([services["username"], + random_gen(id=apiclient.id)]) # Trim username to 99 characters to prevent failure cmd.username = username[:99] if len(username) > 99 else username if "accountUUID" in services: - cmd.accountid = "-".join([services["accountUUID"],random_gen()]) + cmd.accountid = "-".join([services["accountUUID"], random_gen()]) if "userUUID" in services: - cmd.userid = "-".join([services["userUUID"],random_gen()]) - + cmd.userid = "-".join([services["userUUID"], random_gen()]) if domainid: cmd.domainid = domainid @@ -129,6 +139,8 @@ def list(cls, apiclient, **kwargs): cmd = listAccounts.listAccountsCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True return(apiclient.listAccounts(cmd)) def disable(self, apiclient, lock=False): @@ -140,7 +152,9 @@ def disable(self, apiclient, lock=False): class User: + """ User Life Cycle """ + def __init__(self, items): self.__dict__.update(items) @@ -156,7 +170,7 @@ def create(cls, apiclient, services, account, domainid): cmd.lastname = services["lastname"] if "userUUID" in services: - cmd.userid = "-".join([services["userUUID"],random_gen()]) + cmd.userid = "-".join([services["userUUID"], random_gen()]) cmd.password = services["password"] cmd.username = "-".join([services["username"], random_gen()]) @@ -177,6 +191,8 @@ def list(cls, apiclient, **kwargs): cmd = listUsers.listUsersCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True return(apiclient.listUsers(cmd)) @classmethod @@ -217,8 +233,19 @@ def login(cls, apiclient, username, password, domain=None, domainid=None): class VirtualMachine: + """Manage virtual machine lifecycle""" + '''Class level variables''' + # Variables denoting VM state - start + STOPPED = STOPPED + RUNNING = RUNNING + DESTROYED = DESTROYED + EXPUNGING = EXPUNGING + STOPPING = STOPPING + STARTING = STARTING + # Varibles denoting VM state - end + def __init__(self, items, services): self.__dict__.update(items) if "username" in services: @@ -240,7 +267,8 @@ def __init__(self, items, services): @classmethod def ssh_access_group(cls, apiclient, cmd): """ - Programs the security group with SSH access before deploying virtualmachine + Programs the security group with SSH + access before deploying virtualmachine @return: """ zone_list = Zone.list( @@ -249,12 +277,13 @@ def ssh_access_group(cls, apiclient, cmd): domainid=cmd.domainid if cmd.domainid else None ) zone = zone_list[0] - #check if security groups settings is enabled for the zone + # check if security groups settings is enabled for the zone if zone.securitygroupsenabled: list_security_groups = SecurityGroup.list( apiclient, account=cmd.account, domainid=cmd.domainid, + listall=True, securitygroupname="basic_sec_grp" ) @@ -271,9 +300,11 @@ def ssh_access_group(cls, apiclient, cmd): "endport": 22, "cidrlist": "0.0.0.0/0" } - #Authorize security group for above ingress rule - basic_mode_security_group.authorize(apiclient, sec_grp_services, account=cmd.account, - domainid=cmd.domainid) + # Authorize security group for above ingress rule + basic_mode_security_group.authorize(apiclient, + sec_grp_services, + account=cmd.account, + domainid=cmd.domainid) else: basic_mode_security_group = list_security_groups[0] @@ -283,7 +314,9 @@ def ssh_access_group(cls, apiclient, cmd): cmd.securitygroupids = [basic_mode_security_group.id] @classmethod - def access_ssh_over_nat(cls, apiclient, services, virtual_machine, allow_egress=False): + def access_ssh_over_nat( + cls, apiclient, services, virtual_machine, allow_egress=False, + networkid=None): """ Program NAT and PF rules to open up ssh access to deployed guest @return: @@ -293,7 +326,8 @@ def access_ssh_over_nat(cls, apiclient, services, virtual_machine, allow_egress= accountid=virtual_machine.account, zoneid=virtual_machine.zoneid, domainid=virtual_machine.domainid, - services=services + services=services, + networkid=networkid ) FireWallRule.create( apiclient=apiclient, @@ -321,11 +355,13 @@ def access_ssh_over_nat(cls, apiclient, services, virtual_machine, allow_egress= @classmethod def create(cls, apiclient, services, templateid=None, accountid=None, - domainid=None, zoneid=None, networkids=None, serviceofferingid=None, - securitygroupids=None, projectid=None, startvm=None, - diskofferingid=None, affinitygroupnames=None, affinitygroupids=None, group=None, - hostid=None, keypair=None, ipaddress=None, mode='default', method='GET', - customcpunumber=None, customcpuspeed=None, custommemory=None): + domainid=None, zoneid=None, networkids=None, + serviceofferingid=None, securitygroupids=None, + projectid=None, startvm=None, diskofferingid=None, + affinitygroupnames=None, affinitygroupids=None, group=None, + hostid=None, keypair=None, ipaddress=None, mode='default', + method='GET', hypervisor="XenServer", customcpunumber=None, + customcpuspeed=None, custommemory=None, rootdisksize=None): """Create the instance""" cmd = deployVirtualMachine.deployVirtualMachineCmd() @@ -339,7 +375,7 @@ def create(cls, apiclient, services, templateid=None, accountid=None, cmd.zoneid = zoneid elif "zoneid" in services: cmd.zoneid = services["zoneid"] - cmd.hypervisor = apiclient.hypervisor + cmd.hypervisor = hypervisor if "displayname" in services: cmd.displayname = services["displayname"] @@ -394,12 +430,12 @@ def create(cls, apiclient, services, templateid=None, accountid=None, cmd.securitygroupids = [str(sg_id) for sg_id in securitygroupids] if "affinitygroupnames" in services: - cmd.affinitygroupnames = services["affinitygroupnames"] + cmd.affinitygroupnames = services["affinitygroupnames"] elif affinitygroupnames: - cmd.affinitygroupnames = affinitygroupnames + cmd.affinitygroupnames = affinitygroupnames if affinitygroupids: - cmd.affinitygroupids = affinitygroupids + cmd.affinitygroupids = affinitygroupids if projectid: cmd.projectid = projectid @@ -413,7 +449,7 @@ def create(cls, apiclient, services, templateid=None, accountid=None, if "userdata" in services: cmd.userdata = base64.urlsafe_b64encode(services["userdata"]) - cmd.details = [{"cpuNumber": "","cpuSpeed":"","memory":""}] + cmd.details = [{}] if customcpunumber: cmd.details[0]["cpuNumber"] = customcpunumber @@ -424,28 +460,38 @@ def create(cls, apiclient, services, templateid=None, accountid=None, if custommemory: cmd.details[0]["memory"] = custommemory + if rootdisksize >= 0: + cmd.details[0]["rootdisksize"] = rootdisksize + if group: cmd.group = group - #program default access to ssh + # program default access to ssh if mode.lower() == 'basic': cls.ssh_access_group(apiclient, cmd) virtual_machine = apiclient.deployVirtualMachine(cmd, method=method) virtual_machine.ssh_ip = virtual_machine.nic[0].ipaddress - if startvm == False: + if startvm is False: virtual_machine.public_ip = virtual_machine.nic[0].ipaddress return VirtualMachine(virtual_machine.__dict__, services) - #program ssh access over NAT via PF + # program ssh access over NAT via PF if mode.lower() == 'advanced': - cls.access_ssh_over_nat(apiclient, services, virtual_machine, allow_egress=allow_egress) + cls.access_ssh_over_nat( + apiclient, + services, + virtual_machine, + allow_egress=allow_egress, + networkid=cmd.networkids[0] if cmd.networkids else None) elif mode.lower() == 'basic': if virtual_machine.publicip is not None: - vm_ssh_ip = virtual_machine.publicip #EIP/ELB (netscaler) enabled zone + # EIP/ELB (netscaler) enabled zone + vm_ssh_ip = virtual_machine.publicip else: - vm_ssh_ip = virtual_machine.nic[0].ipaddress #regular basic zone with security group + # regular basic zone with security group + vm_ssh_ip = virtual_machine.nic[0].ipaddress virtual_machine.ssh_ip = vm_ssh_ip virtual_machine.public_ip = vm_ssh_ip @@ -456,12 +502,22 @@ def start(self, apiclient): cmd = startVirtualMachine.startVirtualMachineCmd() cmd.id = self.id apiclient.startVirtualMachine(cmd) + response = self.getState(apiclient, VirtualMachine.RUNNING) + if response[0] == FAIL: + raise Exception(response[1]) + return - def stop(self, apiclient): + def stop(self, apiclient, forced=None): """Stop the instance""" cmd = stopVirtualMachine.stopVirtualMachineCmd() cmd.id = self.id + if forced: + cmd.forced = forced apiclient.stopVirtualMachine(cmd) + response = self.getState(apiclient, VirtualMachine.STOPPED) + if response[0] == FAIL: + raise Exception(response[1]) + return def reboot(self, apiclient): """Reboot the instance""" @@ -483,12 +539,14 @@ def restore(self, apiclient, templateid=None): cmd.templateid = templateid return apiclient.restoreVirtualMachine(cmd) - def get_ssh_client(self, ipaddress=None, reconnect=False, port=None, keyPairFileLocation=None): + def get_ssh_client( + self, ipaddress=None, reconnect=False, port=None, + keyPairFileLocation=None): """Get SSH object of VM""" # If NAT Rules are not created while VM deployment in Advanced mode # then, IP address must be passed - if ipaddress != None: + if ipaddress is not None: self.ssh_ip = ipaddress if port: self.ssh_port = port @@ -498,21 +556,52 @@ def get_ssh_client(self, ipaddress=None, reconnect=False, port=None, keyPairFile if reconnect: self.ssh_client = is_server_ssh_ready( - self.ssh_ip, - self.ssh_port, - self.username, - self.password, - keyPairFileLocation=keyPairFileLocation - ) + self.ssh_ip, + self.ssh_port, + self.username, + self.password, + keyPairFileLocation=keyPairFileLocation + ) self.ssh_client = self.ssh_client or is_server_ssh_ready( - self.ssh_ip, - self.ssh_port, - self.username, - self.password, - keyPairFileLocation=keyPairFileLocation - ) + self.ssh_ip, + self.ssh_port, + self.username, + self.password, + keyPairFileLocation=keyPairFileLocation + ) return self.ssh_client + def getState(self, apiclient, state, timeout=600): + """List VM and check if its state is as expected + @returnValue - List[Result, Reason] + 1) Result - FAIL if there is any exception + in the operation or VM state does not change + to expected state in given time else PASS + 2) Reason - Reason for failure""" + + returnValue = [FAIL, "VM state not trasited to %s,\ + operation timed out" % state] + + while timeout>0: + try: + projectid = None + if hasattr(self, "projectid"): + projectid = self.projectid + vms = VirtualMachine.list(apiclient, projectid=projectid, + id=self.id, listAll=True) + validationresult = validateList(vms) + if validationresult[0] == FAIL: + raise Exception("VM list validation failed: %s" % validationresult[2]) + elif str(vms[0].state).lower().decode("string_escape") == str(state).lower(): + returnValue = [PASS, None] + break + except Exception as e: + returnValue = [FAIL, e] + break + time.sleep(60) + timeout -= 60 + return returnValue + def resetSshKey(self, apiclient, **kwargs): """Resets SSH key""" @@ -535,6 +624,12 @@ def delete(self, apiclient): cmd.id = self.id apiclient.destroyVirtualMachine(cmd) + def expung(self, apiclient): + """Expung an Instance""" + cmd = expungeVirtualMachine.expungeVirtualMachineCmd() + cmd.id = self.id + apiclient.expungeVirtualMachine(cmd) + def migrate(self, apiclient, hostid=None): """migrate an Instance""" cmd = migrateVirtualMachine.migrateVirtualMachineCmd() @@ -576,7 +671,8 @@ def remove_nic(self, apiclient, nicId): def update_default_nic(self, apiclient, nicId): """Set a NIC to be the default network adapter for a VM""" - cmd = updateDefaultNicForVirtualMachine.updateDefaultNicForVirtualMachineCmd() + cmd = updateDefaultNicForVirtualMachine.\ + updateDefaultNicForVirtualMachineCmd() cmd.nicid = nicId cmd.virtualmachineid = self.id return apiclient.updateDefaultNicForVirtualMachine(cmd) @@ -591,12 +687,20 @@ def attach_iso(self, apiclient, iso): def detach_iso(self, apiclient): """Detach ISO to instance""" cmd = detachIso.detachIsoCmd() - cmd.id = self.id + cmd.virtualmachineid = self.id return apiclient.detachIso(cmd) + def scale_virtualmachine(self, apiclient, serviceOfferingId): + """ Scale up of service offering for the Instance""" + cmd = scaleVirtualMachine.scaleVirtualMachineCmd() + cmd.id = self.id + cmd.serviceofferingid = serviceOfferingId + return apiclient.scaleVirtualMachine(cmd) + def change_service_offering(self, apiclient, serviceOfferingId): """Change service offering of the instance""" - cmd = changeServiceForVirtualMachine.changeServiceForVirtualMachineCmd() + cmd = changeServiceForVirtualMachine.\ + changeServiceForVirtualMachineCmd() cmd.id = self.id cmd.serviceofferingid = serviceOfferingId return apiclient.changeServiceForVirtualMachine(cmd) @@ -607,12 +711,15 @@ def list(cls, apiclient, **kwargs): cmd = listVirtualMachines.listVirtualMachinesCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True return(apiclient.listVirtualMachines(cmd)) def resetPassword(self, apiclient): """Resets VM password if VM created using password enabled template""" - cmd = resetPasswordForVirtualMachine.resetPasswordForVirtualMachineCmd() + cmd = resetPasswordForVirtualMachine.\ + resetPasswordForVirtualMachineCmd() cmd.id = self.id try: response = apiclient.resetPasswordForVirtualMachine(cmd) @@ -624,15 +731,15 @@ def resetPassword(self, apiclient): def assign_virtual_machine(self, apiclient, account, domainid): """Move a user VM to another user under same domain.""" - cmd = assignVirtualMachine.assignVirtualMachineCmd() + cmd = assignVirtualMachine.assignVirtualMachineCmd() cmd.virtualmachineid = self.id - cmd.account = account - cmd.domainid = domainid + cmd.account = account + cmd.domainid = domainid try: response = apiclient.assignVirtualMachine(cmd) return response except Exception as e: - raise Exception("assignVirtualMachine failed - %s" %e) + raise Exception("assignVirtualMachine failed - %s" % e) def update_affinity_group(self, apiclient, affinitygroupids=None, affinitygroupnames=None): @@ -649,12 +756,12 @@ def update_affinity_group(self, apiclient, affinitygroupids=None, return apiclient.updateVMAffinityGroup(cmd) def scale(self, apiclient, serviceOfferingId, - customcpunumber=None, customcpuspeed=None, custommemory=None): + customcpunumber=None, customcpuspeed=None, custommemory=None): """Change service offering of the instance""" cmd = scaleVirtualMachine.scaleVirtualMachineCmd() cmd.id = self.id cmd.serviceofferingid = serviceOfferingId - cmd.details = [{"cpuNumber": "","cpuSpeed":"","memory":""}] + cmd.details = [{"cpuNumber": "", "cpuSpeed": "", "memory": ""}] if customcpunumber: cmd.details[0]["cpuNumber"] = customcpunumber if customcpuspeed: @@ -665,8 +772,10 @@ def scale(self, apiclient, serviceOfferingId, class Volume: + """Manage Volume Life cycle """ + def __init__(self, items): self.__dict__.update(items) @@ -703,7 +812,7 @@ def create(cls, apiclient, services, zoneid=None, account=None, @classmethod def create_custom_disk(cls, apiclient, services, account=None, - domainid=None, diskofferingid=None): + domainid=None, diskofferingid=None): """Create Volume from Custom disk offering""" cmd = createVolume.createVolumeCmd() cmd.name = services["diskname"] @@ -759,6 +868,8 @@ def list(cls, apiclient, **kwargs): cmd = listVolumes.listVolumesCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True return(apiclient.listVolumes(cmd)) def resize(self, apiclient, **kwargs): @@ -769,7 +880,8 @@ def resize(self, apiclient, **kwargs): return(apiclient.resizeVolume(cmd)) @classmethod - def upload(cls, apiclient, services, zoneid=None, account=None, domainid=None, url=None): + def upload(cls, apiclient, services, zoneid=None, + account=None, domainid=None, url=None): """Uploads the volume to specified account""" cmd = uploadVolume.uploadVolumeCmd() @@ -794,10 +906,10 @@ def wait_for_upload(self, apiclient, timeout=10, interval=60): while True: volume_response = Volume.list( - apiclient, - id=self.id, - zoneid=self.zoneid, - ) + apiclient, + id=self.id, + zoneid=self.zoneid, + ) if isinstance(volume_response, list): volume = volume_response[0] @@ -812,7 +924,7 @@ def wait_for_upload(self, apiclient, timeout=10, interval=60): elif 'Installing' not in volume.state: raise Exception( "Error in uploading volume: status - %s" % - volume.state) + volume.state) elif timeout == 0: break @@ -821,6 +933,16 @@ def wait_for_upload(self, apiclient, timeout=10, interval=60): timeout = timeout - 1 return + @classmethod + def extract(cls, apiclient, volume_id, zoneid, mode): + """Extracts the volume""" + + cmd = extractVolume.extractVolumeCmd() + cmd.id = volume_id + cmd.zoneid = zoneid + cmd.mode = mode + return Volume(apiclient.extractVolume(cmd).__dict__) + @classmethod def migrate(cls, apiclient, **kwargs): """Migrate a volume""" @@ -828,15 +950,24 @@ def migrate(cls, apiclient, **kwargs): [setattr(cmd, k, v) for k, v in kwargs.items()] return(apiclient.migrateVolume(cmd)) + class Snapshot: + """Manage Snapshot Lifecycle """ + + '''Class level variables''' + # Variables denoting possible Snapshot states - start + BACKED_UP = BACKED_UP + BACKING_UP = BACKING_UP + # Variables denoting possible Snapshot states - end + def __init__(self, items): self.__dict__.update(items) @classmethod def create(cls, apiclient, volume_id, account=None, - domainid=None, projectid=None): + domainid=None, projectid=None): """Create Snapshot""" cmd = createSnapshot.createSnapshotCmd() cmd.volumeid = volume_id @@ -860,10 +991,40 @@ def list(cls, apiclient, **kwargs): cmd = listSnapshots.listSnapshotsCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True return(apiclient.listSnapshots(cmd)) + def validateState(self, apiclient, snapshotstate, timeout=600): + """Check if snapshot is in required state + returnValue: List[Result, Reason] + @Result: PASS if snapshot is in required state, + else FAIL + @Reason: Reason for failure in case Result is FAIL + """ + isSnapshotInRequiredState = False + try: + while timeout >= 0: + snapshots = Snapshot.list(apiclient, id=self.id) + assert validateList(snapshots)[0] == PASS, "snapshots list\ + validation failed" + if str(snapshots[0].state).lower() == snapshotstate: + isSnapshotInRequiredState = True + break + timeout -= 60 + time.sleep(60) + #end while + if isSnapshotInRequiredState: + return[PASS, None] + else: + raise Exception("Snapshot not in required state") + except Exception as e: + return [FAIL, e] + + class Template: + """Manage template life cycle""" def __init__(self, items): @@ -888,16 +1049,20 @@ def create(cls, apiclient, services, volumeid=None, if not isinstance(ostypes, list): raise Exception( "Unable to find Ostype id with desc: %s" % - services["ostype"]) + services["ostype"]) cmd.ostypeid = ostypes[0].id else: raise Exception( - "Unable to find Ostype is required for creating template") + "Unable to find Ostype is required for creating template") - cmd.isfeatured = services["isfeatured"] if "isfeatured" in services else False - cmd.ispublic = services["ispublic"] if "ispublic" in services else False - cmd.isextractable = services["isextractable"] if "isextractable" in services else False - cmd.passwordenabled = services["passwordenabled"] if "passwordenabled" in services else False + cmd.isfeatured = services[ + "isfeatured"] if "isfeatured" in services else False + cmd.ispublic = services[ + "ispublic"] if "ispublic" in services else False + cmd.isextractable = services[ + "isextractable"] if "isextractable" in services else False + cmd.passwordenabled = services[ + "passwordenabled"] if "passwordenabled" in services else False if volumeid: cmd.volumeid = volumeid @@ -914,7 +1079,7 @@ def create(cls, apiclient, services, volumeid=None, @classmethod def register(cls, apiclient, services, zoneid=None, - account=None, domainid=None): + account=None, domainid=None, hypervisor=None): """Create template from URL""" # Create template from Virtual machine and Volume ID @@ -922,7 +1087,7 @@ def register(cls, apiclient, services, zoneid=None, cmd.displaytext = services["displaytext"] cmd.name = "-".join([services["name"], random_gen()]) cmd.format = services["format"] - cmd.hypervisor = apiclient.hypervisor + cmd.hypervisor = hypervisor if "ostypeid" in services: cmd.ostypeid = services["ostypeid"] @@ -935,11 +1100,11 @@ def register(cls, apiclient, services, zoneid=None, if not isinstance(ostypes, list): raise Exception( "Unable to find Ostype id with desc: %s" % - services["ostype"]) + services["ostype"]) cmd.ostypeid = ostypes[0].id else: raise Exception( - "Unable to find Ostype is required for registering template") + "Unable to find Ostype is required for registering template") cmd.url = services["url"] @@ -948,10 +1113,14 @@ def register(cls, apiclient, services, zoneid=None, else: cmd.zoneid = services["zoneid"] - cmd.isfeatured = services["isfeatured"] if "isfeatured" in services else False - cmd.ispublic = services["ispublic"] if "ispublic" in services else False - cmd.isextractable = services["isextractable"] if "isextractable" in services else False - cmd.passwordenabled = services["passwordenabled"] if "passwordenabled" in services else False + cmd.isfeatured = services[ + "isfeatured"] if "isfeatured" in services else False + cmd.ispublic = services[ + "ispublic"] if "ispublic" in services else False + cmd.isextractable = services[ + "isextractable"] if "isextractable" in services else False + cmd.passwordenabled = services[ + "passwordenabled"] if "passwordenabled" in services else False if account: cmd.account = account @@ -978,15 +1147,15 @@ def extract(cls, apiclient, id, mode, zoneid=None): @classmethod def create_from_snapshot(cls, apiclient, snapshot, services, - random_name=True): + random_name=True): """Create Template from snapshot""" # Create template from Virtual machine and Snapshot ID cmd = createTemplate.createTemplateCmd() cmd.displaytext = services["displaytext"] cmd.name = "-".join([ - services["name"], - random_gen() - ]) if random_name else services["name"] + services["name"], + random_gen() + ]) if random_name else services["name"] if "ostypeid" in services: cmd.ostypeid = services["ostypeid"] @@ -999,11 +1168,11 @@ def create_from_snapshot(cls, apiclient, snapshot, services, if not isinstance(ostypes, list): raise Exception( "Unable to find Ostype id with desc: %s" % - services["ostype"]) + services["ostype"]) cmd.ostypeid = ostypes[0].id else: raise Exception( - "Unable to find Ostype is required for creating template") + "Unable to find Ostype is required for creating template") cmd.snapshotid = snapshot.id return Template(apiclient.createTemplate(cmd).__dict__) @@ -1022,11 +1191,11 @@ def download(self, apiclient, timeout=5, interval=60): while True: template_response = Template.list( - apiclient, - id=self.id, - zoneid=self.zoneid, - templatefilter='self' - ) + apiclient, + id=self.id, + zoneid=self.zoneid, + templatefilter='self' + ) if isinstance(template_response, list): template = template_response[0] @@ -1043,7 +1212,7 @@ def download(self, apiclient, timeout=5, interval=60): elif 'Installing' not in template.status: raise Exception( "Error in downloading template: status - %s" % - template.status) + template.status) elif timeout == 0: break @@ -1061,16 +1230,38 @@ def updatePermissions(self, apiclient, **kwargs): [setattr(cmd, k, v) for k, v in kwargs.items()] return(apiclient.updateTemplatePermissions(cmd)) + def update(self, apiclient, **kwargs): + """Updates the template details""" + + cmd = updateTemplate.updateTemplateCmd() + cmd.id = self.id + [setattr(cmd, k, v) for k, v in kwargs.items()] + return(apiclient.updateTemplate(cmd)) + + @classmethod + def copy(cls, apiclient, id, sourcezoneid, destzoneid): + "Copy Template from source Zone to Destination Zone" + + cmd = copyTemplate.copyTemplateCmd() + cmd.id = id + cmd.sourcezoneid = sourcezoneid + cmd.destzoneid = destzoneid + + return apiclient.copyTemplate(cmd) + @classmethod def list(cls, apiclient, **kwargs): """List all templates matching criteria""" cmd = listTemplates.listTemplatesCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True return(apiclient.listTemplates(cmd)) class Iso: + """Manage ISO life cycle""" def __init__(self, items): @@ -1078,7 +1269,7 @@ def __init__(self, items): @classmethod def create(cls, apiclient, services, account=None, domainid=None, - projectid=None): + projectid=None): """Create an ISO""" # Create ISO from URL cmd = registerIso.registerIsoCmd() @@ -1095,11 +1286,11 @@ def create(cls, apiclient, services, account=None, domainid=None, if not isinstance(ostypes, list): raise Exception( "Unable to find Ostype id with desc: %s" % - services["ostype"]) + services["ostype"]) cmd.ostypeid = ostypes[0].id else: raise Exception( - "Unable to find Ostype is required for creating ISO") + "Unable to find Ostype is required for creating ISO") cmd.url = services["url"] cmd.zoneid = services["zoneid"] @@ -1149,10 +1340,10 @@ def download(self, apiclient, timeout=5, interval=60): if response.status == 'Successfully Installed': return elif 'Downloaded' not in response.status and \ - 'Installing' not in response.status: + 'Installing' not in response.status: raise Exception( "Error In Downloading ISO: ISO Status - %s" % - response.status) + response.status) elif timeout == 0: raise Exception("ISO download Timeout Exception") @@ -1160,24 +1351,58 @@ def download(self, apiclient, timeout=5, interval=60): timeout = timeout - 1 return + @classmethod + def extract(cls, apiclient, id, mode, zoneid=None): + "Extract ISO " + + cmd = extractIso.extractIsoCmd() + cmd.id = id + cmd.mode = mode + cmd.zoneid = zoneid + + return apiclient.extractIso(cmd) + + def update(self, apiclient, **kwargs): + """Updates the ISO details""" + + cmd = updateIso.updateIsoCmd() + cmd.id = self.id + [setattr(cmd, k, v) for k, v in kwargs.items()] + return(apiclient.updateIso(cmd)) + + @classmethod + def copy(cls, apiclient, id, sourcezoneid, destzoneid): + "Copy ISO from source Zone to Destination Zone" + + cmd = copyIso.copyIsoCmd() + cmd.id = id + cmd.sourcezoneid = sourcezoneid + cmd.destzoneid = destzoneid + + return apiclient.copyIso(cmd) + @classmethod def list(cls, apiclient, **kwargs): """Lists all available ISO files.""" cmd = listIsos.listIsosCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True return(apiclient.listIsos(cmd)) class PublicIPAddress: + """Manage Public IP Addresses""" def __init__(self, items): self.__dict__.update(items) @classmethod - def create(cls, apiclient, accountid=None, zoneid=None, domainid=None, services=None, - networkid=None, projectid=None, vpcid=None, isportable=False): + def create(cls, apiclient, accountid=None, zoneid=None, domainid=None, + services=None, networkid=None, projectid=None, vpcid=None, + isportable=False): """Associate Public IP address""" cmd = associateIpAddress.associateIpAddressCmd() @@ -1222,10 +1447,12 @@ def list(cls, apiclient, **kwargs): cmd = listPublicIpAddresses.listPublicIpAddressesCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] + cmd.listall=True return(apiclient.listPublicIpAddresses(cmd)) class NATRule: + """Manage port forwarding rule""" def __init__(self, items): @@ -1233,7 +1460,8 @@ def __init__(self, items): @classmethod def create(cls, apiclient, virtual_machine, services, ipaddressid=None, - projectid=None, openfirewall=False, networkid=None, vpcid=None): + projectid=None, openfirewall=False, networkid=None, vpcid=None, + vmguestip=None): """Create Port forwarding rule""" cmd = createPortForwardingRule.createPortForwardingRuleCmd() @@ -1262,6 +1490,10 @@ def create(cls, apiclient, virtual_machine, services, ipaddressid=None, if vpcid: cmd.vpcid = vpcid + + if vmguestip: + cmd.vmguestip = vmguestip + return NATRule(apiclient.createPortForwardingRule(cmd).__dict__) def delete(self, apiclient): @@ -1277,17 +1509,21 @@ def list(cls, apiclient, **kwargs): cmd = listPortForwardingRules.listPortForwardingRulesCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True return(apiclient.listPortForwardingRules(cmd)) class StaticNATRule: + """Manage Static NAT rule""" def __init__(self, items): self.__dict__.update(items) @classmethod - def create(cls, apiclient, services, ipaddressid=None, networkid=None, vpcid=None): + def create(cls, apiclient, services, ipaddressid=None, + networkid=None, vpcid=None): """Creates static ip forwarding rule""" cmd = createFirewallRule.createFirewallRuleCmd() @@ -1312,6 +1548,18 @@ def create(cls, apiclient, services, ipaddressid=None, networkid=None, vpcid=Non cmd.vpcid = vpcid return StaticNATRule(apiclient.createFirewallRule(cmd).__dict__) + @classmethod + def createIpForwardingRule(cls, apiclient, startport, endport, protocol, ipaddressid, openfirewall): + """Creates static ip forwarding rule""" + + cmd = createIpForwardingRule.createIpForwardingRuleCmd() + cmd.startport = startport + cmd.endport = endport + cmd.protocol = protocol + cmd.openfirewall = openfirewall + cmd.ipaddressid = ipaddressid + return StaticNATRule(apiclient.createIpForwardingRule(cmd).__dict__) + def delete(self, apiclient): """Delete IP forwarding rule""" cmd = deleteIpForwardingRule.deleteIpForwardingRuleCmd() @@ -1325,10 +1573,13 @@ def list(cls, apiclient, **kwargs): cmd = listIpForwardingRules.listIpForwardingRulesCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True return(apiclient.listIpForwardingRules(cmd)) @classmethod - def enable(cls, apiclient, ipaddressid, virtualmachineid, networkid=None): + def enable(cls, apiclient, ipaddressid, virtualmachineid, networkid=None, + vmguestip=None): """Enables Static NAT rule""" cmd = enableStaticNat.enableStaticNatCmd() @@ -1336,11 +1587,14 @@ def enable(cls, apiclient, ipaddressid, virtualmachineid, networkid=None): cmd.virtualmachineid = virtualmachineid if networkid: cmd.networkid = networkid + + if vmguestip: + cmd.vmguestip = vmguestip apiclient.enableStaticNat(cmd) return @classmethod - def disable(cls, apiclient, ipaddressid, virtualmachineid): + def disable(cls, apiclient, ipaddressid, virtualmachineid=None): """Disables Static NAT rule""" cmd = disableStaticNat.disableStaticNatCmd() @@ -1350,6 +1604,7 @@ def disable(cls, apiclient, ipaddressid, virtualmachineid): class EgressFireWallRule: + """Manage Egress Firewall rule""" def __init__(self, items): @@ -1369,7 +1624,8 @@ def create(cls, apiclient, networkid, protocol, cidrlist=None, if endport: cmd.endport = endport - return EgressFireWallRule(apiclient.createEgressFirewallRule(cmd).__dict__) + return EgressFireWallRule( + apiclient.createEgressFirewallRule(cmd).__dict__) def delete(self, apiclient): """Delete Egress Firewall rule""" @@ -1384,11 +1640,13 @@ def list(cls, apiclient, **kwargs): cmd = listEgressFirewallRules.listEgressFirewallRulesCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True return(apiclient.listEgressFirewallRules(cmd)) - class FireWallRule: + """Manage Firewall rule""" def __init__(self, items): @@ -1429,10 +1687,169 @@ def list(cls, apiclient, **kwargs): cmd = listFirewallRules.listFirewallRulesCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True return(apiclient.listFirewallRules(cmd)) +class Autoscale: + + """Manage Auto scale""" + + def __init__(self, items): + self.__dict__.update(items) + + @classmethod + def listCounters(cls, apiclient, **kwargs): + """Lists all available Counters.""" + + cmd = listCounters.listCountersCmd() + [setattr(cmd, k, v) for k, v in kwargs.items()] + return(apiclient.listCounters(cmd)) + + @classmethod + def createCondition(cls, apiclient, counterid, relationaloperator, threshold): + """creates condition.""" + + cmd = createCondition.createConditionCmd() + cmd.counterid = counterid + cmd.relationaloperator = relationaloperator + cmd.threshold = threshold + return(apiclient.createCondition(cmd)) + + @classmethod + def listConditions(cls, apiclient, **kwargs): + """Lists all available Conditions.""" + + cmd = listConditions.listConditionsCmd() + [setattr(cmd, k, v) for k, v in kwargs.items()] + return(apiclient.listConditions(cmd)) + + @classmethod + def listAutoscalePolicies(cls, apiclient, **kwargs): + """Lists all available Autoscale Policies.""" + + cmd = listAutoScalePolicies.listAutoScalePoliciesCmd() + [setattr(cmd, k, v) for k, v in kwargs.items()] + return(apiclient.listAutoScalePolicies(cmd)) + + @classmethod + def createAutoscalePolicy(cls, apiclient, action, conditionids, duration, quiettime=None): + """creates condition.""" + + cmd = createAutoScalePolicy.createAutoScalePolicyCmd() + cmd.action = action + cmd.conditionids = conditionids + cmd.duration = duration + if quiettime: + cmd.quiettime = quiettime + + return(apiclient.createAutoScalePolicy(cmd)) + + @classmethod + def updateAutoscalePolicy(cls, apiclient, id, **kwargs): + """Updates Autoscale Policy.""" + + cmd = updateAutoScalePolicy.updateAutoScalePolicyCmd() + cmd.id = id + [setattr(cmd, k, v) for k, v in kwargs.items()] + return(apiclient.updateAutoScalePolicy(cmd)) + + @classmethod + def listAutoscaleVmPofiles(cls, apiclient, **kwargs): + """Lists all available AutoscaleVM Profiles.""" + + cmd = listAutoScaleVmProfiles.listAutoScaleVmProfilesCmd() + [setattr(cmd, k, v) for k, v in kwargs.items()] + return(apiclient.listAutoScaleVmProfiles(cmd)) + + @classmethod + def createAutoscaleVmProfile(cls, apiclient, serviceofferingid, zoneid, templateid, + autoscaleuserid=None, destroyvmgraceperiod=None, counterparam=None): + """creates Autoscale VM Profile.""" + + cmd = createAutoScaleVmProfile.createAutoScaleVmProfileCmd() + cmd.serviceofferingid = serviceofferingid + cmd.zoneid = zoneid + cmd.templateid = templateid + if autoscaleuserid: + cmd.autoscaleuserid = autoscaleuserid + + if destroyvmgraceperiod: + cmd.destroyvmgraceperiod = destroyvmgraceperiod + + if counterparam: + for name, value in counterparam.items(): + cmd.counterparam.append({ + 'name': name, + 'value': value + }) + + return(apiclient.createAutoScaleVmProfile(cmd)) + + @classmethod + def updateAutoscaleVMProfile(cls, apiclient, id, **kwargs): + """Updates Autoscale Policy.""" + + cmd = updateAutoScaleVmProfile.updateAutoScaleVmProfileCmd() + cmd.id = id + [setattr(cmd, k, v) for k, v in kwargs.items()] + return(apiclient.updateAutoScaleVmProfile(cmd)) + + @classmethod + def createAutoscaleVmGroup(cls, apiclient, lbruleid, minmembers, maxmembers, + scaledownpolicyids, scaleuppolicyids, vmprofileid, interval=None): + """creates Autoscale VM Group.""" + + cmd = createAutoScaleVmGroup.createAutoScaleVmGroupCmd() + cmd.lbruleid = lbruleid + cmd.minmembers = minmembers + cmd.maxmembers = maxmembers + cmd.scaledownpolicyids = scaledownpolicyids + cmd.scaleuppolicyids = scaleuppolicyids + cmd.vmprofileid = vmprofileid + if interval: + cmd.interval = interval + + return(apiclient.createAutoScaleVmGroup(cmd)) + + @classmethod + def listAutoscaleVmGroup(cls, apiclient, **kwargs): + """Lists all available AutoscaleVM Group.""" + + cmd = listAutoScaleVmGroups.listAutoScaleVmGroupsCmd() + [setattr(cmd, k, v) for k, v in kwargs.items()] + return(apiclient.listAutoScaleVmGroups(cmd)) + + @classmethod + def enableAutoscaleVmGroup(cls, apiclient, id, **kwargs): + """Enables AutoscaleVM Group.""" + + cmd = enableAutoScaleVmGroup.enableAutoScaleVmGroupCmd() + cmd.id = id + [setattr(cmd, k, v) for k, v in kwargs.items()] + return(apiclient.enableAutoScaleVmGroup(cmd)) + + @classmethod + def disableAutoscaleVmGroup(cls, apiclient, id, **kwargs): + """Disables AutoscaleVM Group.""" + + cmd = disableAutoScaleVmGroup.disableAutoScaleVmGroupCmd() + cmd.id = id + [setattr(cmd, k, v) for k, v in kwargs.items()] + return(apiclient.disableAutoScaleVmGroup(cmd)) + + @classmethod + def updateAutoscaleVMGroup(cls, apiclient, id, **kwargs): + """Updates Autoscale VM Group.""" + + cmd = updateAutoScaleVmGroup.updateAutoScaleVmGroupCmd() + cmd.id = id + [setattr(cmd, k, v) for k, v in kwargs.items()] + return(apiclient.updateAutoScaleVmGroup(cmd)) + class ServiceOffering: + """Manage service offerings cycle""" def __init__(self, items): @@ -1459,15 +1876,26 @@ def create(cls, apiclient, services, domainid=None, **kwargs): if "tags" in services: cmd.tags = services["tags"] + if "hosttags" in services: + cmd.hosttags = services["hosttags"] + if "deploymentplanner" in services: cmd.deploymentplanner = services["deploymentplanner"] if "serviceofferingdetails" in services: - cmd.serviceofferingdetails.append({services['serviceofferingdetails']}) + count = 1 + for i in services["serviceofferingdetails"]: + for key, value in i.items(): + setattr(cmd, "serviceofferingdetails[%d].key" % count, key) + setattr(cmd, "serviceofferingdetails[%d].value" % count, value) + count = count + 1 if "isvolatile" in services: cmd.isvolatile = services["isvolatile"] + if "offerha" in services: + cmd.offerha = services["offerha"] + # Service Offering private to that domain if domainid: cmd.domainid = domainid @@ -1488,10 +1916,13 @@ def list(cls, apiclient, **kwargs): cmd = listServiceOfferings.listServiceOfferingsCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True return(apiclient.listServiceOfferings(cmd)) class DiskOffering: + """Manage disk offerings cycle""" def __init__(self, items): @@ -1529,10 +1960,13 @@ def list(cls, apiclient, **kwargs): cmd = listDiskOfferings.listDiskOfferingsCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True return(apiclient.listDiskOfferings(cmd)) class NetworkOffering: + """Manage network offerings cycle""" def __init__(self, items): @@ -1557,18 +1991,19 @@ def create(cls, apiclient, services, **kwargs): if "serviceProviderList" in services: for service, provider in services["serviceProviderList"].items(): cmd.serviceproviderlist.append({ - 'service': service, - 'provider': provider - }) + 'service': service, + 'provider': provider + }) if "serviceCapabilityList" in services: cmd.servicecapabilitylist = [] - for service, capability in services["serviceCapabilityList"].items(): + for service, capability in services["serviceCapabilityList"].\ + items(): for ctype, value in capability.items(): cmd.servicecapabilitylist.append({ - 'service': service, - 'capabilitytype': ctype, - 'capabilityvalue': value - }) + 'service': service, + 'capabilitytype': ctype, + 'capabilityvalue': value + }) if "specifyVlan" in services: cmd.specifyVlan = services["specifyVlan"] if "specifyIpRanges" in services: @@ -1605,10 +2040,13 @@ def list(cls, apiclient, **kwargs): cmd = listNetworkOfferings.listNetworkOfferingsCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True return(apiclient.listNetworkOfferings(cmd)) class SnapshotPolicy: + """Manage snapshot policies""" def __init__(self, items): @@ -1638,10 +2076,31 @@ def list(cls, apiclient, **kwargs): cmd = listSnapshotPolicies.listSnapshotPoliciesCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True return(apiclient.listSnapshotPolicies(cmd)) +class Hypervisor: + + """Manage Hypervisor""" + + def __init__(self, items): + self.__dict__.update(items) + + @classmethod + def list(cls, apiclient, **kwargs): + """Lists hypervisors""" + + cmd = listHypervisors.listHypervisorsCmd() + [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True + return(apiclient.listHypervisors(cmd)) + + class LoadBalancerRule: + """Manage Load Balancer rule""" def __init__(self, items): @@ -1707,7 +2166,8 @@ def remove(self, apiclient, vms): apiclient.removeFromLoadBalancerRule(cmd) return - def update(self, apiclient, algorithm=None, description=None, name=None, **kwargs): + def update(self, apiclient, algorithm=None, + description=None, name=None, **kwargs): """Updates the load balancing rule""" cmd = updateLoadBalancerRule.updateLoadBalancerRuleCmd() cmd.id = self.id @@ -1721,7 +2181,8 @@ def update(self, apiclient, algorithm=None, description=None, name=None, **kwarg [setattr(cmd, k, v) for k, v in kwargs.items()] return apiclient.updateLoadBalancerRule(cmd) - def createSticky(self, apiclient, methodname, name, description=None, param=None): + def createSticky( + self, apiclient, methodname, name, description=None, param=None): """Creates a sticky policy for the LB rule""" cmd = createLBStickinessPolicy.createLBStickinessPolicyCmd() @@ -1750,6 +2211,8 @@ def listStickyPolicies(cls, apiclient, lbruleid, **kwargs): cmd = listLBStickinessPolicies.listLBStickinessPoliciesCmd() cmd.lbruleid = lbruleid [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True return apiclient.listLBStickinessPolicies(cmd) @classmethod @@ -1758,21 +2221,37 @@ def list(cls, apiclient, **kwargs): cmd = listLoadBalancerRules.listLoadBalancerRulesCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True return(apiclient.listLoadBalancerRules(cmd)) + @classmethod + def listLoadBalancerRuleInstances(cls, apiclient, id, applied=None, **kwargs): + """Lists load balancing rule Instances""" + + cmd = listLoadBalancerRuleInstances.listLoadBalancerRuleInstancesCmd() + cmd.id = id + if applied: + cmd.applied = applied + + [setattr(cmd, k, v) for k, v in kwargs.items()] + return apiclient.listLoadBalancerRuleInstances(cmd) + class Cluster: + """Manage Cluster life cycle""" def __init__(self, items): self.__dict__.update(items) @classmethod - def create(cls, apiclient, services, zoneid=None, podid=None): + def create(cls, apiclient, services, zoneid=None, podid=None, + hypervisor=None): """Create Cluster""" cmd = addCluster.addClusterCmd() cmd.clustertype = services["clustertype"] - cmd.hypervisor = apiclient.hypervisor + cmd.hypervisor = hypervisor if zoneid: cmd.zoneid = zoneid @@ -1808,46 +2287,75 @@ def list(cls, apiclient, **kwargs): cmd = listClusters.listClustersCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True return(apiclient.listClusters(cmd)) class Host: + """Manage Host life cycle""" def __init__(self, items): self.__dict__.update(items) @classmethod - def create(cls, apiclient, cluster, services, zoneid=None, podid=None): - """Create Host in cluster""" - - cmd = addHost.addHostCmd() - cmd.hypervisor = apiclient.hypervisor - cmd.url = services["url"] - cmd.clusterid = cluster.id - - if zoneid: - cmd.zoneid = zoneid - else: - cmd.zoneid = services["zoneid"] - - if podid: - cmd.podid = podid - else: - cmd.podid = services["podid"] - - if "clustertype" in services: - cmd.clustertype = services["clustertype"] - if "username" in services: - cmd.username = services["username"] - if "password" in services: - cmd.password = services["password"] + def create(cls, apiclient, cluster, services, + zoneid=None, podid=None, hypervisor=None): + """ + 1. Creates the host based upon the information provided. + 2. Verifies the output of the adding host and its state post addition + Returns FAILED in case of an issue, else an instance of Host + """ + try: + cmd = addHost.addHostCmd() + cmd.hypervisor = hypervisor + cmd.url = services["url"] + cmd.clusterid = cluster.id - # Add host - host = apiclient.addHost(cmd) + if zoneid: + cmd.zoneid = zoneid + else: + cmd.zoneid = services["zoneid"] - if isinstance(host, list): - return Host(host[0].__dict__) + if podid: + cmd.podid = podid + else: + cmd.podid = services["podid"] + + if "clustertype" in services: + cmd.clustertype = services["clustertype"] + if "username" in services: + cmd.username = services["username"] + if "password" in services: + cmd.password = services["password"] + + ''' + Adds a Host, + If response is valid and host is up return + an instance of Host. + If response is invalid, returns FAILED. + If host state is not up, verify through listHosts call + till host status is up and return accordingly. Max 3 retries + ''' + host = apiclient.addHost(cmd) + ret = validateList(host) + if ret[0] == PASS: + if str(host[0].state).lower() == 'up': + return Host(host[0].__dict__) + retries = 3 + while retries: + lh_resp = apiclient.listHosts(host[0].id) + ret = validateList(lh_resp) + if (ret[0] == PASS) and \ + (str(ret[1].state).lower() == 'up'): + return Host(host[0].__dict__) + retries += -1 + return FAILED + except Exception as e: + print "Exception Occurred Under Host.create : %s" % \ + GetDetailExceptionInfo(e) + return FAILED def delete(self, apiclient): """Delete Host""" @@ -1898,6 +2406,8 @@ def list(cls, apiclient, **kwargs): cmd = listHosts.listHostsCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True return(apiclient.listHosts(cmd)) @classmethod @@ -1906,6 +2416,8 @@ def listForMigration(cls, apiclient, **kwargs): cmd = findHostsForMigration.findHostsForMigrationCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True return(apiclient.findHostsForMigration(cmd)) @classmethod @@ -1918,6 +2430,7 @@ def update(cls, apiclient, **kwargs): class StoragePool: + """Manage Storage pools (Primary Storage)""" def __init__(self, items): @@ -1925,7 +2438,7 @@ def __init__(self, items): @classmethod def create(cls, apiclient, services, clusterid=None, - zoneid=None, podid=None): + zoneid=None, podid=None): """Create Storage pool (Primary Storage)""" cmd = createStoragePool.createStoragePoolCmd() @@ -1975,6 +2488,8 @@ def list(cls, apiclient, **kwargs): cmd = listStoragePools.listStoragePoolsCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True return(apiclient.listStoragePools(cmd)) @classmethod @@ -1983,9 +2498,13 @@ def listForMigration(cls, apiclient, **kwargs): cmd = findStoragePoolsForMigration.findStoragePoolsForMigrationCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True return(apiclient.findStoragePoolsForMigration(cmd)) + class Network: + """Manage Network pools""" def __init__(self, items): @@ -2073,10 +2592,13 @@ def list(cls, apiclient, **kwargs): cmd = listNetworks.listNetworksCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True return(apiclient.listNetworks(cmd)) class NetworkACL: + """Manage Network ACL lifecycle""" def __init__(self, items): @@ -2084,7 +2606,8 @@ def __init__(self, items): @classmethod def create(cls, apiclient, services, networkid=None, protocol=None, - number=None, aclid=None, action='Allow', traffictype=None, cidrlist=[]): + number=None, aclid=None, action='Allow', + traffictype=None, cidrlist=[]): """Create network ACL rules(Ingress/Egress)""" cmd = createNetworkACL.createNetworkACLCmd() @@ -2147,17 +2670,21 @@ def list(cls, apiclient, **kwargs): cmd = listNetworkACLs.listNetworkACLsCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True return(apiclient.listNetworkACLs(cmd)) class NetworkACLList: + """Manage Network ACL lists lifecycle""" def __init__(self, items): self.__dict__.update(items) @classmethod - def create(cls, apiclient, services, name=None, description=None, vpcid=None): + def create( + cls, apiclient, services, name=None, description=None, vpcid=None): """Create network ACL container list""" cmd = createNetworkACLList.createNetworkACLListCmd() @@ -2191,10 +2718,13 @@ def list(cls, apiclient, **kwargs): cmd = listNetworkACLLists.listNetworkACLListsCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True return(apiclient.listNetworkACLLists(cmd)) class Vpn: + """Manage VPN life cycle""" def __init__(self, items): @@ -2202,7 +2732,7 @@ def __init__(self, items): @classmethod def create(cls, apiclient, publicipid, account=None, domainid=None, - projectid=None, networkid=None, vpcid=None): + projectid=None, networkid=None, vpcid=None, openfirewall=None): """Create VPN for Public IP address""" cmd = createRemoteAccessVpn.createRemoteAccessVpnCmd() cmd.publicipid = publicipid @@ -2216,7 +2746,55 @@ def create(cls, apiclient, publicipid, account=None, domainid=None, cmd.networkid = networkid if vpcid: cmd.vpcid = vpcid + if openfirewall: + cmd.openfirewall = openfirewall return Vpn(apiclient.createRemoteAccessVpn(cmd).__dict__) + + @classmethod + def createVpnGateway(cls, apiclient, vpcid): + """Create VPN Gateway """ + cmd = createVpnGateway.createVpnGatewayCmd() + cmd.vpcid = vpcid + return (apiclient.createVpnGateway(cmd).__dict__) + + @classmethod + def createVpnConnection(cls, apiclient, s2scustomergatewayid,s2svpngatewayid): + """Create VPN Connection """ + cmd = createVpnConnection.createVpnConnectionCmd() + cmd.s2scustomergatewayid = s2scustomergatewayid + cmd.s2svpngatewayid = s2svpngatewayid + return (apiclient.createVpnGateway(cmd).__dict__) + + @classmethod + def resetVpnConnection(cls, apiclient,id): + """Reset VPN Connection """ + cmd = resetVpnConnection.resetVpnConnectionCmd() + cmd.id = id + return (apiclient.resetVpnConnection(cmd).__dict__) + + @classmethod + def deleteVpnConnection(cls, apiclient,id): + """Delete VPN Connection """ + cmd = deleteVpnConnection.deleteVpnConnectionCmd() + cmd.id = id + return (apiclient.deleteVpnConnection(cmd).__dict__) + + @classmethod + def listVpnGateway(cls, apiclient, **kwargs): + """List all VPN Gateways matching criteria""" + + cmd = listVpnGateways.listVpnGatewaysCmd() + [setattr(cmd, k, v) for k, v in kwargs.items()] + return(apiclient.listVpnGateways(cmd)) + + @classmethod + def listVpnConnection(cls, apiclient, **kwargs): + """List all VPN Connections matching criteria""" + + cmd = listVpnConnections.listVpnConnectionsCmd() + [setattr(cmd, k, v) for k, v in kwargs.items()] + return(apiclient.listVpnConnections(cmd)) + def delete(self, apiclient): """Delete remote VPN access""" @@ -2231,10 +2809,13 @@ def list(cls, apiclient, **kwargs): cmd = listRemoteAccessVpns.listRemoteAccessVpnsCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True return(apiclient.listRemoteAccessVpns(cmd)) class VpnUser: + """Manage VPN user""" def __init__(self, items): @@ -2275,10 +2856,13 @@ def list(cls, apiclient, **kwargs): cmd = listVpnUsers.listVpnUsersCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True return(apiclient.listVpnUsers(cmd)) class Zone: + """Manage Zone""" def __init__(self, items): @@ -2325,10 +2909,13 @@ def list(cls, apiclient, **kwargs): cmd = listZones.listZonesCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True return(apiclient.listZones(cmd)) class Pod: + """Manage Pod""" def __init__(self, items): @@ -2360,10 +2947,13 @@ def list(cls, apiclient, **kwargs): cmd = listPods.listPodsCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True return apiclient.listPods(cmd) class PublicIpRange: + """Manage VlanIpRange""" def __init__(self, items): @@ -2380,7 +2970,8 @@ def create(cls, apiclient, services): cmd.startip = services["startip"] cmd.endip = services["endip"] cmd.zoneid = services["zoneid"] - cmd.podid = services["podid"] + if "podid" in services: + cmd.podid = services["podid"] cmd.vlan = services["vlan"] return PublicIpRange(apiclient.createVlanIpRange(cmd).__dict__) @@ -2398,10 +2989,13 @@ def list(cls, apiclient, **kwargs): cmd = listVlanIpRanges.listVlanIpRangesCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True return(apiclient.listVlanIpRanges(cmd)) @classmethod - def dedicate(cls, apiclient, id, account=None, domainid=None, projectid=None): + def dedicate( + cls, apiclient, id, account=None, domainid=None, projectid=None): """Dedicate VLAN IP range""" cmd = dedicatePublicIpRange.dedicatePublicIpRangeCmd() @@ -2420,6 +3014,7 @@ def release(self, apiclient): class PortablePublicIpRange: + """Manage portable public Ip Range""" def __init__(self, items): @@ -2439,7 +3034,8 @@ def create(cls, apiclient, services): if "vlan" in services: cmd.vlan = services["vlan"] - return PortablePublicIpRange(apiclient.createPortableIpRange(cmd).__dict__) + return PortablePublicIpRange( + apiclient.createPortableIpRange(cmd).__dict__) def delete(self, apiclient): """Delete portable IpRange""" @@ -2454,9 +3050,13 @@ def list(cls, apiclient, **kwargs): cmd = listPortableIpRanges.listPortableIpRangesCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True return(apiclient.listPortableIpRanges(cmd)) + class SecondaryStagingStore: + """Manage Staging Store""" def __init__(self, items): @@ -2476,7 +3076,8 @@ def create(cls, apiclient, url, provider, services=None): if "scope" in services: cmd.scope = services["scope"] - return SecondaryStagingStore(apiclient.createSecondaryStagingStore(cmd).__dict__) + return SecondaryStagingStore( + apiclient.createSecondaryStagingStore(cmd).__dict__) def delete(self, apiclient): """Delete Staging Storage""" @@ -2488,10 +3089,13 @@ def delete(self, apiclient): def list(cls, apiclient, **kwargs): cmd = listSecondaryStagingStores.listSecondaryStagingStoresCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True return(apiclient.listSecondaryStagingStores(cmd)) class ImageStore: + """Manage image stores""" def __init__(self, items): @@ -2523,10 +3127,13 @@ def delete(self, apiclient): def list(cls, apiclient, **kwargs): cmd = listImageStores.listImageStoresCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True return(apiclient.listImageStores(cmd)) class PhysicalNetwork: + """Manage physical network storage""" def __init__(self, items): @@ -2567,7 +3174,8 @@ def addTrafficType(self, apiclient, type): return apiclient.addTrafficType(cmd) @classmethod - def dedicate(cls, apiclient, vlanrange, physicalnetworkid, account=None, domainid=None, projectid=None): + def dedicate(cls, apiclient, vlanrange, physicalnetworkid, + account=None, domainid=None, projectid=None): """Dedicate guest vlan range""" cmd = dedicateGuestVlanRange.dedicateGuestVlanRangeCmd() @@ -2581,7 +3189,8 @@ def dedicate(cls, apiclient, vlanrange, physicalnetworkid, account=None, domaini def release(self, apiclient): """Release guest vlan range""" - cmd = releaseDedicatedGuestVlanRange.releaseDedicatedGuestVlanRangeCmd() + cmd = releaseDedicatedGuestVlanRange.\ + releaseDedicatedGuestVlanRangeCmd() cmd.id = self.id return apiclient.releaseDedicatedGuestVlanRange(cmd) @@ -2591,6 +3200,8 @@ def listDedicated(cls, apiclient, **kwargs): cmd = listDedicatedGuestVlanRanges.listDedicatedGuestVlanRangesCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True return apiclient.listDedicatedGuestVlanRanges(cmd) @classmethod @@ -2599,10 +3210,14 @@ def list(cls, apiclient, **kwargs): cmd = listPhysicalNetworks.listPhysicalNetworksCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] - return map(lambda pn : PhysicalNetwork(pn.__dict__), apiclient.listPhysicalNetworks(cmd)) + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True + return map(lambda pn: PhysicalNetwork( + pn.__dict__), apiclient.listPhysicalNetworks(cmd)) class SecurityGroup: + """Manage Security Groups""" def __init__(self, items): @@ -2614,7 +3229,7 @@ def create(cls, apiclient, services, account=None, domainid=None, """Create security group""" cmd = createSecurityGroup.createSecurityGroupCmd() - cmd.name = services["name"] + cmd.name = "-".join([services["name"], random_gen()]) if account: cmd.account = account if domainid: @@ -2694,9 +3309,9 @@ def authorizeEgress(self, apiclient, services, account=None, domainid=None, cmd.usersecuritygrouplist = [] for account, group in user_secgrp_list.items(): cmd.usersecuritygrouplist.append({ - 'account': account, - 'group': group - }) + 'account': account, + 'group': group + }) return (apiclient.authorizeSecurityGroupEgress(cmd).__dict__) @@ -2713,10 +3328,87 @@ def list(cls, apiclient, **kwargs): cmd = listSecurityGroups.listSecurityGroupsCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True return(apiclient.listSecurityGroups(cmd)) +class VpnCustomerGateway: + + """Manage VPN Customer Gateway""" + + def __init__(self, items): + self.__dict__.update(items) + + @classmethod + def create(cls, apiclient, services, name, gateway, cidrlist, + account=None, domainid=None): + """Create VPN Customer Gateway""" + cmd = createVpnCustomerGateway.createVpnCustomerGatewayCmd() + cmd.name = name + cmd.gateway = gateway + cmd.cidrlist = cidrlist + if "ipsecpsk" in services: + cmd.ipsecpsk = services["ipsecpsk"] + if "ikepolicy" in services: + cmd.ikepolicy = services["ikepolicy"] + if "ikelifetime" in services: + cmd.ikelifetime = services["ikelifetime"] + if "esppolicy" in services: + cmd.esppolicy = services["esppolicy"] + if "esplifetime" in services: + cmd.esplifetime = services["esplifetime"] + if "dpd" in services: + cmd.dpd = services["dpd"] + if account: + cmd.account = account + if domainid: + cmd.domainid = domainid + return VpnCustomerGateway( + apiclient.createVpnCustomerGateway(cmd).__dict__) + + def update(self, apiclient, services, name, gateway, cidrlist): + """Updates VPN Customer Gateway""" + + cmd = updateVpnCustomerGateway.updateVpnCustomerGatewayCmd() + cmd.id = self.id + cmd.name = name + cmd.gateway = gateway + cmd.cidrlist = cidrlist + if "ipsecpsk" in services: + cmd.ipsecpsk = services["ipsecpsk"] + if "ikepolicy" in services: + cmd.ikepolicy = services["ikepolicy"] + if "ikelifetime" in services: + cmd.ikelifetime = services["ikelifetime"] + if "esppolicy" in services: + cmd.esppolicy = services["esppolicy"] + if "esplifetime" in services: + cmd.esplifetime = services["esplifetime"] + if "dpd" in services: + cmd.dpd = services["dpd"] + return(apiclient.updateVpnCustomerGateway(cmd)) + + def delete(self, apiclient): + """Delete VPN Customer Gateway""" + + cmd = deleteVpnCustomerGateway.deleteVpnCustomerGatewayCmd() + cmd.id = self.id + apiclient.deleteVpnCustomerGateway(cmd) + + @classmethod + def list(cls, apiclient, **kwargs): + """List all VPN customer Gateway""" + + cmd = listVpnCustomerGateways.listVpnCustomerGatewaysCmd() + [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True + return(apiclient.listVpnCustomerGateways(cmd)) + + class Project: + """Manage Project life cycle""" def __init__(self, items): @@ -2790,6 +3482,8 @@ def listAccounts(cls, apiclient, **kwargs): cmd = listProjectAccounts.listProjectAccountsCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True return(apiclient.listProjectAccounts(cmd)) @classmethod @@ -2798,10 +3492,13 @@ def list(cls, apiclient, **kwargs): cmd = listProjects.listProjectsCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True return(apiclient.listProjects(cmd)) class ProjectInvitation: + """Manage project invitations""" def __init__(self, items): @@ -2834,10 +3531,13 @@ def list(cls, apiclient, **kwargs): cmd = listProjectInvitations.listProjectInvitationsCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True return(apiclient.listProjectInvitations(cmd)) class Configurations: + """Manage Configuration""" @classmethod @@ -2855,17 +3555,28 @@ def list(cls, apiclient, **kwargs): cmd = listConfigurations.listConfigurationsCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True return(apiclient.listConfigurations(cmd)) + + @classmethod + def listCapabilities(cls, apiclient, **kwargs): + """Lists capabilities""" + cmd = listCapabilities.listCapabilitiesCmd() + [setattr(cmd, k, v) for k, v in kwargs.items()] + return(apiclient.listCapabilities(cmd)) class NetScaler: + """Manage external netscaler device""" def __init__(self, items): self.__dict__.update(items) @classmethod - def add(cls, apiclient, services, physicalnetworkid, username=None, password=None): + def add(cls, apiclient, services, physicalnetworkid, + username=None, password=None): """Add external netscaler device to cloudstack""" cmd = addNetscalerLoadBalancer.addNetscalerLoadBalancerCmd() @@ -2885,11 +3596,14 @@ def add(cls, apiclient, services, physicalnetworkid, username=None, password=Non # Generate the URL url = 'https://' + str(services["ipaddress"]) + '?' url = url + 'publicinterface=' + str(services["publicinterface"]) + '&' - url = url + 'privateinterface=' + str(services["privateinterface"]) + '&' + url = url + 'privateinterface=' + \ + str(services["privateinterface"]) + '&' url = url + 'numretries=' + str(services["numretries"]) + '&' - if not services["lbdevicededicated"] and "lbdevicecapacity" in services: - url = url + 'lbdevicecapacity=' + str(services["lbdevicecapacity"]) + '&' + if not services["lbdevicededicated"] and \ + "lbdevicecapacity" in services: + url = url + 'lbdevicecapacity=' + \ + str(services["lbdevicecapacity"]) + '&' url = url + 'lbdevicededicated=' + str(services["lbdevicededicated"]) @@ -2907,7 +3621,8 @@ def delete(self, apiclient): def configure(self, apiclient, **kwargs): """List already registered netscaler devices""" - cmd = configureNetscalerLoadBalancer.configureNetscalerLoadBalancerCmd() + cmd = configureNetscalerLoadBalancer.\ + configureNetscalerLoadBalancerCmd() cmd.lbdeviceid = self.lbdeviceid [setattr(cmd, k, v) for k, v in kwargs.items()] return(apiclient.configureNetscalerLoadBalancer(cmd)) @@ -2918,10 +3633,13 @@ def list(cls, apiclient, **kwargs): cmd = listNetscalerLoadBalancers.listNetscalerLoadBalancersCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True return(apiclient.listNetscalerLoadBalancers(cmd)) class NetworkServiceProvider: + """Manage network serivce providers for CloudStack""" def __init__(self, items): @@ -2935,7 +3653,8 @@ def add(cls, apiclient, name, physicalnetworkid, servicelist): cmd.name = name cmd.physicalnetworkid = physicalnetworkid cmd.servicelist = servicelist - return NetworkServiceProvider(apiclient.addNetworkServiceProvider(cmd).__dict__) + return NetworkServiceProvider( + apiclient.addNetworkServiceProvider(cmd).__dict__) def delete(self, apiclient): """Deletes network service provider""" @@ -2967,10 +3686,13 @@ def list(cls, apiclient, **kwargs): cmd = listNetworkServiceProviders.listNetworkServiceProvidersCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True return(apiclient.listNetworkServiceProviders(cmd)) class Router: + """Manage router life cycle""" def __init__(self, items): @@ -3020,10 +3742,13 @@ def list(cls, apiclient, **kwargs): cmd = listRouters.listRoutersCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True return(apiclient.listRouters(cmd)) class Tag: + """Manage tags""" def __init__(self, items): @@ -3039,9 +3764,9 @@ def create(cls, apiclient, resourceIds, resourceType, tags): cmd.tags = [] for key, value in tags.items(): cmd.tags.append({ - 'key': key, - 'value': value - }) + 'key': key, + 'value': value + }) return Tag(apiclient.createTags(cmd).__dict__) def delete(self, apiclient, resourceIds, resourceType, tags): @@ -3053,9 +3778,9 @@ def delete(self, apiclient, resourceIds, resourceType, tags): cmd.tags = [] for key, value in tags.items(): cmd.tags.append({ - 'key': key, - 'value': value - }) + 'key': key, + 'value': value + }) apiclient.deleteTags(cmd) @classmethod @@ -3064,10 +3789,13 @@ def list(cls, apiclient, **kwargs): cmd = listTags.listTagsCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True return(apiclient.listTags(cmd)) class VpcOffering: + """Manage VPC offerings""" def __init__(self, items): @@ -3084,18 +3812,19 @@ def create(cls, apiclient, services): if "serviceProviderList" in services: for service, provider in services["serviceProviderList"].items(): cmd.serviceproviderlist.append({ - 'service': service, - 'provider': provider - }) + 'service': service, + 'provider': provider + }) if "serviceCapabilityList" in services: cmd.servicecapabilitylist = [] - for service, capability in services["serviceCapabilityList"].items(): + for service, capability in \ + services["serviceCapabilityList"].items(): for ctype, value in capability.items(): cmd.servicecapabilitylist.append({ - 'service': service, - 'capabilitytype': ctype, - 'capabilityvalue': value - }) + 'service': service, + 'capabilitytype': ctype, + 'capabilityvalue': value + }) return VpcOffering(apiclient.createVPCOffering(cmd).__dict__) def update(self, apiclient, name=None, displaytext=None, state=None): @@ -3117,6 +3846,8 @@ def list(cls, apiclient, **kwargs): cmd = listVPCOfferings.listVPCOfferingsCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True return(apiclient.listVPCOfferings(cmd)) def delete(self, apiclient): @@ -3128,6 +3859,7 @@ def delete(self, apiclient): class VPC: + """Manage Virtual Private Connection""" def __init__(self, items): @@ -3135,7 +3867,8 @@ def __init__(self, items): @classmethod def create(cls, apiclient, services, vpcofferingid, - zoneid, networkDomain=None, account=None, domainid=None, **kwargs): + zoneid, networkDomain=None, account=None, + domainid=None, **kwargs): """Creates the virtual private connection (VPC)""" cmd = createVPC.createVPCCmd() @@ -3185,10 +3918,13 @@ def list(cls, apiclient, **kwargs): cmd = listVPCs.listVPCsCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True return(apiclient.listVPCs(cmd)) class PrivateGateway: + """Manage private gateway lifecycle""" def __init__(self, items): @@ -3196,7 +3932,7 @@ def __init__(self, items): @classmethod def create(cls, apiclient, gateway, ipaddress, netmask, vlan, vpcid, - physicalnetworkid=None): + physicalnetworkid=None, aclid=None): """Create private gateway""" cmd = createPrivateGateway.createPrivateGatewayCmd() @@ -3207,6 +3943,8 @@ def create(cls, apiclient, gateway, ipaddress, netmask, vlan, vpcid, cmd.vpcid = vpcid if physicalnetworkid: cmd.physicalnetworkid = physicalnetworkid + if aclid: + cmd.aclid = aclid return PrivateGateway(apiclient.createPrivateGateway(cmd).__dict__) @@ -3223,10 +3961,13 @@ def list(cls, apiclient, **kwargs): cmd = listPrivateGateways.listPrivateGatewaysCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True return(apiclient.listPrivateGateways(cmd)) class AffinityGroup: + def __init__(self, items): self.__dict__.update(items) @@ -3254,10 +3995,15 @@ def delete(self, apiclient): def list(cls, apiclient, **kwargs): cmd = listAffinityGroups.listAffinityGroupsCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True return apiclient.listAffinityGroups(cmd) + class StaticRoute: + """Manage static route lifecycle""" + def __init__(self, items): self.__dict__.update(items) @@ -3283,15 +4029,20 @@ def list(cls, apiclient, **kwargs): cmd = listStaticRoutes.listStaticRoutesCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True return(apiclient.listStaticRoutes(cmd)) class VNMC: + """Manage VNMC lifecycle""" + def __init__(self, items): self.__dict__.update(items) - def create(cls, apiclient, hostname, username, password, physicalnetworkid): + def create(cls, apiclient, hostname, username, password, + physicalnetworkid): """Registers VNMC appliance""" cmd = addCiscoVnmcResource.addCiscoVnmcResourceCmd() @@ -3314,10 +4065,13 @@ def list(cls, apiclient, **kwargs): cmd = listCiscoVnmcResources.listCiscoVnmcResourcesCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True return(apiclient.listCiscoVnmcResources(cmd)) class SSHKeyPair: + """Manage SSH Key pairs""" def __init__(self, items, services): @@ -3325,7 +4079,7 @@ def __init__(self, items, services): @classmethod def create(cls, apiclient, name=None, account=None, - domainid=None, projectid=None): + domainid=None, projectid=None): """Creates SSH keypair""" cmd = createSSHKeyPair.createSSHKeyPairCmd() cmd.name = name @@ -3337,6 +4091,14 @@ def create(cls, apiclient, name=None, account=None, cmd.projectid = projectid return (apiclient.createSSHKeyPair(cmd)) + @classmethod + def register(cls, apiclient, name, publickey): + """Registers SSH keypair""" + cmd = registerSSHKeyPair.registerSSHKeyPairCmd() + cmd.name = name + cmd.publickey = publickey + return (apiclient.registerSSHKeyPair(cmd)) + def delete(self, apiclient): """Delete SSH key pair""" cmd = deleteSSHKeyPair.deleteSSHKeyPairCmd() @@ -3348,10 +4110,13 @@ def list(cls, apiclient, **kwargs): """List all SSH key pairs""" cmd = listSSHKeyPairs.listSSHKeyPairsCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True return(apiclient.listSSHKeyPairs(cmd)) class Capacities: + """Manage Capacities""" @classmethod @@ -3360,10 +4125,13 @@ def list(cls, apiclient, **kwargs): cmd = listCapacity.listCapacityCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True return(apiclient.listCapacity(cmd)) class Alert: + """Manage alerts""" @classmethod @@ -3372,10 +4140,13 @@ def list(cls, apiclient, **kwargs): cmd = listAlerts.listAlertsCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True return(apiclient.listAlerts(cmd)) class InstanceGroup: + """Manage VM instance groups""" def __init__(self, items): @@ -3416,6 +4187,8 @@ def list(cls, apiclient, **kwargs): """List all instance groups""" cmd = listInstanceGroups.listInstanceGroupsCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True return (apiclient.listInstanceGroups(cmd)) def startInstances(self, apiclient): @@ -3449,7 +4222,8 @@ def deleteInstances(self, apiclient): def changeServiceOffering(self, apiclient, serviceOfferingId): """Change service offering of the vm tier""" - cmd = changeServiceForVirtualMachine.changeServiceForVirtualMachineCmd() + cmd = changeServiceForVirtualMachine.\ + changeServiceForVirtualMachineCmd() cmd.group = self.id cmd.serviceofferingid = serviceOfferingId return apiclient.changeServiceForVirtualMachine(cmd) @@ -3462,8 +4236,10 @@ def recoverInstances(self, apiclient): class ASA1000V: + """Manage ASA 1000v lifecycle""" - def create(cls, apiclient, hostname, insideportprofile, clusterid, physicalnetworkid): + def create(cls, apiclient, hostname, insideportprofile, + clusterid, physicalnetworkid): """Registers ASA 1000v appliance""" cmd = addCiscoAsa1000vResource.addCiscoAsa1000vResourceCmd() @@ -3486,14 +4262,21 @@ def list(cls, apiclient, **kwargs): cmd = listCiscoAsa1000vResources.listCiscoAsa1000vResourcesCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True return(apiclient.listCiscoAsa1000vResources(cmd)) + class VmSnapshot: + """Manage VM Snapshot life cycle""" + def __init__(self, items): self.__dict__.update(items) + @classmethod - def create(cls,apiclient,vmid,snapshotmemory="false",name=None,description=None): + def create(cls, apiclient, vmid, snapshotmemory="false", + name=None, description=None): cmd = createVMSnapshot.createVMSnapshotCmd() cmd.virtualmachineid = vmid @@ -3504,29 +4287,34 @@ def create(cls,apiclient,vmid,snapshotmemory="false",name=None,description=None) if description: cmd.description = description return VmSnapshot(apiclient.createVMSnapshot(cmd).__dict__) - + @classmethod def list(cls, apiclient, **kwargs): cmd = listVMSnapshot.listVMSnapshotCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True return(apiclient.listVMSnapshot(cmd)) - + @classmethod - def revertToSnapshot(cls, apiclient,vmsnapshotid): + def revertToSnapshot(cls, apiclient, vmsnapshotid): cmd = revertToVMSnapshot.revertToVMSnapshotCmd() cmd.vmsnapshotid = vmsnapshotid - + return apiclient.revertToVMSnapshot(cmd) - + @classmethod - def deleteVMSnapshot(cls,apiclient,vmsnapshotid): + def deleteVMSnapshot(cls, apiclient, vmsnapshotid): cmd = deleteVMSnapshot.deleteVMSnapshotCmd() cmd.vmsnapshotid = vmsnapshotid - + return apiclient.deleteVMSnapshot(cmd) + class Region: + """ Regions related Api """ + def __init__(self, items): self.__dict__.update(items) @@ -3547,6 +4335,8 @@ def create(cls, apiclient, services): def list(cls, apiclient, **kwargs): cmd = listRegions.listRegionsCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True region = apiclient.listRegions(cmd) return region @@ -3568,14 +4358,16 @@ def delete(self, apiclient): class ApplicationLoadBalancer: + """Manage Application Load Balancers in VPC""" def __init__(self, items): self.__dict__.update(items) @classmethod - def create(cls, apiclient, services, name=None, sourceport=None, instanceport=22, - algorithm="roundrobin", scheme="internal", sourcenetworkid=None, networkid=None): + def create(cls, apiclient, services, name=None, sourceport=None, + instanceport=22, algorithm="roundrobin", scheme="internal", + sourcenetworkid=None, networkid=None): """Create Application Load Balancer""" cmd = createLoadBalancer.createLoadBalancerCmd() @@ -3644,9 +4436,13 @@ def list(cls, apiclient, **kwargs): """List all appln load balancers""" cmd = listLoadBalancers.listLoadBalancersCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True return(apiclient.listLoadBalancerRules(cmd)) + class Resources: + """Manage resource limits""" def __init__(self, items, services): @@ -3658,6 +4454,8 @@ def list(cls, apiclient, **kwargs): cmd = listResourceLimits.listResourceLimitsCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True return(apiclient.listResourceLimits(cmd)) @classmethod @@ -3675,9 +4473,12 @@ def updateCount(cls, apiclient, **kwargs): cmd = updateResourceCount.updateResourceCountCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] return(apiclient.updateResourceCount(cmd)) - + + class NIC: + """NIC related API""" + def __init__(self, items): self.__dict__.update(items) @@ -3691,7 +4492,7 @@ def addIp(cls, apiclient, id, ipaddress=None): return(apiclient.addIpToNic(cmd)) @classmethod - def removeIp(cls,apiclient,ipaddressid): + def removeIp(cls, apiclient, ipaddressid): """Remove secondary Ip from NIC""" cmd = removeIpFromNic.removeIpFromNicCmd() cmd.id = ipaddressid @@ -3703,9 +4504,13 @@ def list(cls, apiclient, **kwargs): cmd = listNics.listNicsCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True return(apiclient.listNics(cmd)) - + + class IAMGroup: + def __init__(self, items): self.__dict__.update(items) @@ -3732,15 +4537,17 @@ def delete(self, apiclient): def list(cls, apiclient, **kwargs): cmd = listIAMGroups.listIAMGroupsCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] - return apiclient.listIAMGroupsCmd(cmd) - + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True + return apiclient.listIAMGroups(cmd) + def addAccount(self, apiclient, accts): """Add accounts to iam group""" cmd = addAccountToIAMGroup.addAccountToIAMGroupCmd() cmd.id = self.id cmd.accounts = [str(acct.id) for acct in accts] apiclient.addAccountToIAMGroup(cmd) - return + return def removeAccount(self, apiclient, accts): """ Remove accounts from iam group""" @@ -3748,25 +4555,26 @@ def removeAccount(self, apiclient, accts): cmd.id = self.id cmd.accounts = [str(acct.id) for acct in accts] apiclient.removeAccountFromIAMGroup(cmd) - return - + return + def attachPolicy(self, apiclient, policies): """Add policies to iam group""" cmd = attachIAMPolicyToIAMGroup.attachIAMPolicyToIAMGroupCmd() cmd.id = self.id cmd.policies = [str(policy.id) for policy in policies] apiclient.attachIAMPolicyToIAMGroup(cmd) - return - + return + def detachPolicy(self, apiclient, policies): """Remove policies from iam group""" cmd = removeIAMPolicyFromIAMGroup.removeIAMPolicyFromIAMGroupCmd() cmd.id = self.id cmd.policies = [str(policy.id) for policy in policies] apiclient.removeIAMPolicyFromIAMGroup(cmd) - return - + return + class IAMPolicy: + def __init__(self, items): self.__dict__.update(items) @@ -3793,7 +4601,9 @@ def delete(self, apiclient): def list(cls, apiclient, **kwargs): cmd = listIAMPolicies.listIAMPoliciesCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] - return apiclient.listIAMPoliciesCmd(cmd) + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True + return apiclient.listIAMPolicies(cmd) def addPermission(self, apiclient, permission): """Add permission to iam policy""" @@ -3804,31 +4614,81 @@ def addPermission(self, apiclient, permission): cmd.scope = permission['scope'] cmd.scopeid = permission['scopeid'] apiclient.addIAMPermissionToIAMPolicy(cmd) - return + return def removePermission(self, apiclient, permission): """Remove permission from iam policy""" - cmd = removeIAMPermissionFromIAMPolicy.removeIAMPermissionFromIAMPolicyCmd() + cmd = removeIAMPermissionFromIAMPolicy.\ + removeIAMPermissionFromIAMPolicyCmd() cmd.id = self.id cmd.action = permission['action'] cmd.entitytype = permission['entitytype'] cmd.scope = permission['scope'] cmd.scopeid = permission['scopeid'] apiclient.removeIAMPermissionFromIAMPolicy(cmd) - return - + return + def attachAccount(self, apiclient, accts): """Attach iam policy to accounts""" cmd = attachIAMPolicyToAccount.attachIAMPolicyToAccountCmd() cmd.id = self.id cmd.accounts = [str(acct.id) for acct in accts] apiclient.attachIAMPolicyToAccount(cmd) - return - + return + def detachAccount(self, apiclient, accts): """Detach iam policy from accounts""" cmd = removeIAMPolicyFromAccount.removeIAMPolicyFromAccountCmd() cmd.id = self.id cmd.accounts = [str(acct.id) for acct in accts] apiclient.removeIAMPolicyFromAccount(cmd) - return + return + + +class SimulatorMock: + + """Manage simulator mock lifecycle""" + + def __init__(self, items): + self.__dict__.update(items) + + @classmethod + def create(cls, apiclient, command, zoneid=None, podid=None, + clusterid=None, hostid=None, value="result:fail", + count=None, jsonresponse=None): + """Creates simulator mock""" + + cmd = configureSimulator.configureSimulatorCmd() + cmd.zoneid = zoneid + cmd.podid = podid + cmd.clusterid = clusterid + cmd.hostid = hostid + cmd.name = command + cmd.value = value + cmd.count = count + cmd.jsonresponse = jsonresponse + try: + simulatormock = apiclient.configureSimulator(cmd) + if simulatormock is not None: + return SimulatorMock(simulatormock.__dict__) + except Exception as e: + raise e + + def delete(self, apiclient): + """Removes simulator mock""" + + cmd = cleanupSimulatorMock.cleanupSimulatorMockCmd() + cmd.id = self.id + return apiclient.cleanupSimulatorMock(cmd) + + def query(self, apiclient): + """Queries simulator mock""" + + cmd = querySimulatorMock.querySimulatorMockCmd() + cmd.id = self.id + try: + simulatormock = apiclient.querySimulatorMock(cmd) + if simulatormock is not None: + return SimulatorMock(simulatormock.__dict__) + except Exception as e: + raise e diff --git a/tools/marvin/marvin/lib/common.py b/tools/marvin/marvin/lib/common.py new file mode 100644 index 0000000000..7b0c7ad445 --- /dev/null +++ b/tools/marvin/marvin/lib/common.py @@ -0,0 +1,1349 @@ +# 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. +"""Common functions +""" + +# Import Local Modules +from marvin.cloudstackAPI import (listConfigurations, + listPhysicalNetworks, + listRegions, + addNetworkServiceProvider, + updateNetworkServiceProvider, + listDomains, + listZones, + listPods, + listOsTypes, + listTemplates, + updateResourceLimit, + listRouters, + listNetworks, + listClusters, + listSystemVms, + listStoragePools, + listVirtualMachines, + listLoadBalancerRuleInstances, + listFirewallRules, + listVolumes, + listIsos, + listAccounts, + listSnapshotPolicies, + listDiskOfferings, + listVlanIpRanges, + listUsageRecords, + listNetworkServiceProviders, + listHosts, + listPublicIpAddresses, + listPortForwardingRules, + listLoadBalancerRules, + listSnapshots, + listUsers, + listEvents, + listServiceOfferings, + listVirtualRouterElements, + listNetworkOfferings, + listResourceLimits, + listVPCOfferings) + + +from marvin.sshClient import SshClient +from marvin.codes import (PASS, FAILED, ISOLATED_NETWORK, VPC_NETWORK, + BASIC_ZONE, FAIL, NAT_RULE, STATIC_NAT_RULE, + RESOURCE_PRIMARY_STORAGE, RESOURCE_SECONDARY_STORAGE, + RESOURCE_CPU, RESOURCE_MEMORY) +from marvin.lib.utils import (validateList, xsplit, get_process_status) +from marvin.lib.base import (PhysicalNetwork, + PublicIPAddress, + NetworkOffering, + NATRule, + StaticNATRule, + Volume, + Account, + Project, + Snapshot, + NetScaler, + VirtualMachine, + FireWallRule, + Template, + Network, + Host, + Resources, + Configurations) +import random + + +# Import System modules +import time + + +def is_config_suitable(apiclient, name, value): + """ + Ensure if the deployment has the expected + `value` for the global setting `name' + @return: true if value is set, else false + """ + configs = Configurations.list(apiclient, name=name) + assert( + configs is not None and isinstance( + configs, + list) and len( + configs) > 0) + return configs[0].value == value + + +def wait_for_cleanup(apiclient, configs=None): + """Sleeps till the cleanup configs passed""" + + # Configs list consists of the list of global configs + if not isinstance(configs, list): + return + for config in configs: + cmd = listConfigurations.listConfigurationsCmd() + cmd.name = config + cmd.listall = True + try: + config_descs = apiclient.listConfigurations(cmd) + except Exception as e: + raise Exception("Failed to fetch configurations: %s" % e) + + if not isinstance(config_descs, list): + raise Exception("List configs didn't returned a valid data") + + config_desc = config_descs[0] + # Sleep for the config_desc.value time + time.sleep(int(config_desc.value)) + return + + +def add_netscaler(apiclient, zoneid, NSservice): + """ Adds Netscaler device and enables NS provider""" + + cmd = listPhysicalNetworks.listPhysicalNetworksCmd() + cmd.zoneid = zoneid + physical_networks = apiclient.listPhysicalNetworks(cmd) + if isinstance(physical_networks, list): + physical_network = physical_networks[0] + + cmd = listNetworkServiceProviders.listNetworkServiceProvidersCmd() + cmd.name = 'Netscaler' + cmd.physicalnetworkid = physical_network.id + nw_service_providers = apiclient.listNetworkServiceProviders(cmd) + + if isinstance(nw_service_providers, list): + netscaler_provider = nw_service_providers[0] + else: + cmd1 = addNetworkServiceProvider.addNetworkServiceProviderCmd() + cmd1.name = 'Netscaler' + cmd1.physicalnetworkid = physical_network.id + netscaler_provider = apiclient.addNetworkServiceProvider(cmd1) + + netscaler = NetScaler.add( + apiclient, + NSservice, + physicalnetworkid=physical_network.id + ) + if netscaler_provider.state != 'Enabled': + cmd = updateNetworkServiceProvider.updateNetworkServiceProviderCmd() + cmd.id = netscaler_provider.id + cmd.state = 'Enabled' + apiclient.updateNetworkServiceProvider(cmd) + + return netscaler + + +def get_region(apiclient, region_id=None, region_name=None): + ''' + @name : get_region + @Desc : Returns the Region Information for a given + region id or region name + @Input : region_name: Name of the Region + region_id : Id of the region + @Output : 1. Region Information for the passed inputs else first Region + 2. FAILED In case the cmd failed + ''' + cmd = listRegions.listRegionsCmd() + if region_name is not None: + cmd.name = region_name + if region_id is not None: + cmd.id = region_id + cmd_out = apiclient.listRegions(cmd) + return FAILED if validateList(cmd_out)[0] != PASS else cmd_out[0] + + +def get_domain(apiclient, domain_id=None, domain_name=None): + ''' + @name : get_domain + @Desc : Returns the Domain Information for a given domain id or domain name + @Input : domain id : Id of the Domain + domain_name : Name of the Domain + @Output : 1. Domain Information for the passed inputs else first Domain + 2. FAILED In case the cmd failed + ''' + cmd = listDomains.listDomainsCmd() + + if domain_name is not None: + cmd.name = domain_name + if domain_id is not None: + cmd.id = domain_id + cmd_out = apiclient.listDomains(cmd) + if validateList(cmd_out)[0] != PASS: + return FAILED + return cmd_out[0] + + +def get_zone(apiclient, zone_name=None, zone_id=None): + ''' + @name : get_zone + @Desc :Returns the Zone Information for a given zone id or Zone Name + @Input : zone_name: Name of the Zone + zone_id : Id of the zone + @Output : 1. Zone Information for the passed inputs else first zone + 2. FAILED In case the cmd failed + ''' + cmd = listZones.listZonesCmd() + if zone_name is not None: + cmd.name = zone_name + if zone_id is not None: + cmd.id = zone_id + + cmd_out = apiclient.listZones(cmd) + + if validateList(cmd_out)[0] != PASS: + return FAILED + ''' + Check if input zone name and zone id is None, + then return first element of List Zones command + ''' + return cmd_out[0] + + +def get_pod(apiclient, zone_id=None, pod_id=None, pod_name=None): + ''' + @name : get_pod + @Desc : Returns the Pod Information for a given zone id or Zone Name + @Input : zone_id: Id of the Zone + pod_name : Name of the Pod + pod_id : Id of the Pod + @Output : 1. Pod Information for the pod + 2. FAILED In case the cmd failed + ''' + cmd = listPods.listPodsCmd() + + if pod_name is not None: + cmd.name = pod_name + if pod_id is not None: + cmd.id = pod_id + if zone_id is not None: + cmd.zoneid = zone_id + + cmd_out = apiclient.listPods(cmd) + + if validateList(cmd_out)[0] != PASS: + return FAILED + return cmd_out[0] + + +def get_template( + apiclient, zone_id=None, ostype_desc=None, template_filter="featured", + template_type='BUILTIN', template_id=None, template_name=None, + account=None, domain_id=None, project_id=None, hypervisor=None): + ''' + @Name : get_template + @Desc : Retrieves the template Information based upon inputs provided + Template is retrieved based upon either of the inputs matched + condition + @Input : returns a template" + @Output : FAILED in case of any failure + template Information matching the inputs + ''' + cmd = listTemplates.listTemplatesCmd() + cmd.templatefilter = template_filter + if domain_id is not None: + cmd.domainid = domain_id + if zone_id is not None: + cmd.zoneid = zone_id + if template_id is not None: + cmd.id = template_id + if template_name is not None: + cmd.name = template_name + if hypervisor is not None: + cmd.hypervisor = hypervisor + if project_id is not None: + cmd.projectid = project_id + if account is not None: + cmd.account = account + + ''' + Get the Templates pertaining to the inputs provided + ''' + list_templatesout = apiclient.listTemplates(cmd) + if validateList(list_templatesout)[0] != PASS: + return FAILED + + for template in list_templatesout: + if template.isready and template.templatetype == template_type: + return template + ''' + Return default first template, if no template matched + ''' + return list_templatesout[0] + + +def download_systemplates_sec_storage(server, services): + """Download System templates on sec storage""" + + try: + # Login to management server + ssh = SshClient( + server["ipaddress"], + server["port"], + server["username"], + server["password"] + ) + except Exception: + raise Exception("SSH access failed for server with IP address: %s" % + server["ipaddess"]) + # Mount Secondary Storage on Management Server + cmds = [ + "mkdir -p %s" % services["mnt_dir"], + "mount -t nfs %s:/%s %s" % ( + services["sec_storage"], + services["path"], + services["mnt_dir"] + ), + "%s -m %s -u %s -h %s -F" % ( + services["command"], + services["mnt_dir"], + services["download_url"], + services["hypervisor"] + ) + ] + for c in cmds: + result = ssh.execute(c) + + res = str(result) + + # Unmount the Secondary storage + ssh.execute("umount %s" % (services["mnt_dir"])) + + if res.count("Successfully installed system VM template") == 1: + return + else: + raise Exception("Failed to download System Templates on Sec Storage") + return + + +def wait_for_ssvms(apiclient, zoneid, podid, interval=60): + """After setup wait for SSVMs to come Up""" + + time.sleep(interval) + timeout = 40 + while True: + list_ssvm_response = list_ssvms( + apiclient, + systemvmtype='secondarystoragevm', + zoneid=zoneid, + podid=podid + ) + ssvm = list_ssvm_response[0] + if ssvm.state != 'Running': + # Sleep to ensure SSVMs are Up and Running + time.sleep(interval) + timeout = timeout - 1 + elif ssvm.state == 'Running': + break + elif timeout == 0: + raise Exception("SSVM failed to come up") + break + + timeout = 40 + while True: + list_ssvm_response = list_ssvms( + apiclient, + systemvmtype='consoleproxy', + zoneid=zoneid, + podid=podid + ) + cpvm = list_ssvm_response[0] + if cpvm.state != 'Running': + # Sleep to ensure SSVMs are Up and Running + time.sleep(interval) + timeout = timeout - 1 + elif cpvm.state == 'Running': + break + elif timeout == 0: + raise Exception("CPVM failed to come up") + break + return + + +def get_builtin_template_info(apiclient, zoneid): + """Returns hypervisor specific infor for templates""" + + list_template_response = Template.list( + apiclient, + templatefilter='featured', + zoneid=zoneid, + ) + + for b_template in list_template_response: + if b_template.templatetype == 'BUILTIN': + break + + extract_response = Template.extract(apiclient, + b_template.id, + 'HTTP_DOWNLOAD', + zoneid) + + return extract_response.url, b_template.hypervisor, b_template.format + + +def download_builtin_templates(apiclient, zoneid, hypervisor, host, + linklocalip, interval=60): + """After setup wait till builtin templates are downloaded""" + + # Change IPTABLES Rules + get_process_status( + host["ipaddress"], + host["port"], + host["username"], + host["password"], + linklocalip, + "iptables -P INPUT ACCEPT" + ) + time.sleep(interval) + # Find the BUILTIN Templates for given Zone, Hypervisor + list_template_response = list_templates( + apiclient, + hypervisor=hypervisor, + zoneid=zoneid, + templatefilter='self' + ) + + if not isinstance(list_template_response, list): + raise Exception("Failed to download BUILTIN templates") + + # Ensure all BUILTIN templates are downloaded + templateid = None + for template in list_template_response: + if template.templatetype == "BUILTIN": + templateid = template.id + + # Sleep to ensure that template is in downloading state after adding + # Sec storage + time.sleep(interval) + while True: + template_response = list_templates( + apiclient, + id=templateid, + zoneid=zoneid, + templatefilter='self' + ) + template = template_response[0] + # If template is ready, + # template.status = Download Complete + # Downloading - x% Downloaded + # Error - Any other string + if template.status == 'Download Complete': + break + + elif 'Downloaded' in template.status: + time.sleep(interval) + + elif 'Installing' not in template.status: + raise Exception("ErrorInDownload") + + return + + +def update_resource_limit(apiclient, resourcetype, account=None, + domainid=None, max=None, projectid=None): + """Updates the resource limit to 'max' for given account""" + + cmd = updateResourceLimit.updateResourceLimitCmd() + cmd.resourcetype = resourcetype + if account: + cmd.account = account + if domainid: + cmd.domainid = domainid + if max: + cmd.max = max + if projectid: + cmd.projectid = projectid + apiclient.updateResourceLimit(cmd) + return + + +def list_os_types(apiclient, **kwargs): + """List all os types matching criteria""" + + cmd = listOsTypes.listOsTypesCmd() + [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True + return(apiclient.listOsTypes(cmd)) + + +def list_routers(apiclient, **kwargs): + """List all Routers matching criteria""" + + cmd = listRouters.listRoutersCmd() + [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True + return(apiclient.listRouters(cmd)) + + +def list_zones(apiclient, **kwargs): + """List all Zones matching criteria""" + + cmd = listZones.listZonesCmd() + [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True + return(apiclient.listZones(cmd)) + + +def list_networks(apiclient, **kwargs): + """List all Networks matching criteria""" + + cmd = listNetworks.listNetworksCmd() + [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True + return(apiclient.listNetworks(cmd)) + + +def list_clusters(apiclient, **kwargs): + """List all Clusters matching criteria""" + + cmd = listClusters.listClustersCmd() + [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True + return(apiclient.listClusters(cmd)) + + +def list_ssvms(apiclient, **kwargs): + """List all SSVMs matching criteria""" + + cmd = listSystemVms.listSystemVmsCmd() + [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True + return(apiclient.listSystemVms(cmd)) + + +def list_storage_pools(apiclient, **kwargs): + """List all storage pools matching criteria""" + + cmd = listStoragePools.listStoragePoolsCmd() + [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True + return(apiclient.listStoragePools(cmd)) + + +def list_virtual_machines(apiclient, **kwargs): + """List all VMs matching criteria""" + + cmd = listVirtualMachines.listVirtualMachinesCmd() + [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True + return(apiclient.listVirtualMachines(cmd)) + + +def list_hosts(apiclient, **kwargs): + """List all Hosts matching criteria""" + + cmd = listHosts.listHostsCmd() + [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True + return(apiclient.listHosts(cmd)) + + +def list_configurations(apiclient, **kwargs): + """List configuration with specified name""" + + cmd = listConfigurations.listConfigurationsCmd() + [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True + return(apiclient.listConfigurations(cmd)) + + +def list_publicIP(apiclient, **kwargs): + """List all Public IPs matching criteria""" + + cmd = listPublicIpAddresses.listPublicIpAddressesCmd() + [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True + return(apiclient.listPublicIpAddresses(cmd)) + + +def list_nat_rules(apiclient, **kwargs): + """List all NAT rules matching criteria""" + + cmd = listPortForwardingRules.listPortForwardingRulesCmd() + [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True + return(apiclient.listPortForwardingRules(cmd)) + + +def list_lb_rules(apiclient, **kwargs): + """List all Load balancing rules matching criteria""" + + cmd = listLoadBalancerRules.listLoadBalancerRulesCmd() + [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True + return(apiclient.listLoadBalancerRules(cmd)) + + +def list_lb_instances(apiclient, **kwargs): + """List all Load balancing instances matching criteria""" + + cmd = listLoadBalancerRuleInstances.listLoadBalancerRuleInstancesCmd() + [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True + return(apiclient.listLoadBalancerRuleInstances(cmd)) + + +def list_firewall_rules(apiclient, **kwargs): + """List all Firewall Rules matching criteria""" + + cmd = listFirewallRules.listFirewallRulesCmd() + [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True + return(apiclient.listFirewallRules(cmd)) + + +def list_volumes(apiclient, **kwargs): + """List all volumes matching criteria""" + + cmd = listVolumes.listVolumesCmd() + [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True + return(apiclient.listVolumes(cmd)) + + +def list_isos(apiclient, **kwargs): + """Lists all available ISO files.""" + + cmd = listIsos.listIsosCmd() + [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True + return(apiclient.listIsos(cmd)) + + +def list_snapshots(apiclient, **kwargs): + """List all snapshots matching criteria""" + + cmd = listSnapshots.listSnapshotsCmd() + [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True + return(apiclient.listSnapshots(cmd)) + + +def list_templates(apiclient, **kwargs): + """List all templates matching criteria""" + + cmd = listTemplates.listTemplatesCmd() + [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True + return(apiclient.listTemplates(cmd)) + + +def list_domains(apiclient, **kwargs): + """Lists domains""" + + cmd = listDomains.listDomainsCmd() + [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True + return(apiclient.listDomains(cmd)) + + +def list_accounts(apiclient, **kwargs): + """Lists accounts and provides detailed account information for + listed accounts""" + + cmd = listAccounts.listAccountsCmd() + [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True + return(apiclient.listAccounts(cmd)) + + +def list_users(apiclient, **kwargs): + """Lists users and provides detailed account information for + listed users""" + + cmd = listUsers.listUsersCmd() + [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True + return(apiclient.listUsers(cmd)) + + +def list_snapshot_policy(apiclient, **kwargs): + """Lists snapshot policies.""" + + cmd = listSnapshotPolicies.listSnapshotPoliciesCmd() + [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True + return(apiclient.listSnapshotPolicies(cmd)) + + +def list_events(apiclient, **kwargs): + """Lists events""" + + cmd = listEvents.listEventsCmd() + [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True + return(apiclient.listEvents(cmd)) + + +def list_disk_offering(apiclient, **kwargs): + """Lists all available disk offerings.""" + + cmd = listDiskOfferings.listDiskOfferingsCmd() + [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True + return(apiclient.listDiskOfferings(cmd)) + + +def list_service_offering(apiclient, **kwargs): + """Lists all available service offerings.""" + + cmd = listServiceOfferings.listServiceOfferingsCmd() + [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True + return(apiclient.listServiceOfferings(cmd)) + + +def list_vlan_ipranges(apiclient, **kwargs): + """Lists all VLAN IP ranges.""" + + cmd = listVlanIpRanges.listVlanIpRangesCmd() + [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True + return(apiclient.listVlanIpRanges(cmd)) + + +def list_usage_records(apiclient, **kwargs): + """Lists usage records for accounts""" + + cmd = listUsageRecords.listUsageRecordsCmd() + [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True + return(apiclient.listUsageRecords(cmd)) + + +def list_nw_service_prividers(apiclient, **kwargs): + """Lists Network service providers""" + + cmd = listNetworkServiceProviders.listNetworkServiceProvidersCmd() + [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True + return(apiclient.listNetworkServiceProviders(cmd)) + + +def list_virtual_router_elements(apiclient, **kwargs): + """Lists Virtual Router elements""" + + cmd = listVirtualRouterElements.listVirtualRouterElementsCmd() + [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True + return(apiclient.listVirtualRouterElements(cmd)) + + +def list_network_offerings(apiclient, **kwargs): + """Lists network offerings""" + + cmd = listNetworkOfferings.listNetworkOfferingsCmd() + [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True + return(apiclient.listNetworkOfferings(cmd)) + + +def list_resource_limits(apiclient, **kwargs): + """Lists resource limits""" + + cmd = listResourceLimits.listResourceLimitsCmd() + [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True + return(apiclient.listResourceLimits(cmd)) + + +def list_vpc_offerings(apiclient, **kwargs): + """ Lists VPC offerings """ + + cmd = listVPCOfferings.listVPCOfferingsCmd() + [setattr(cmd, k, v) for k, v in kwargs.items()] + if 'account' in kwargs.keys() and 'domainid' in kwargs.keys(): + cmd.listall=True + return(apiclient.listVPCOfferings(cmd)) + + +def update_resource_count(apiclient, domainid, accountid=None, + projectid=None, rtype=None): + """updates the resource count + 0 - VM + 1 - Public IP + 2 - Volume + 3 - Snapshot + 4 - Template + 5 - Projects + 6 - Network + 7 - VPC + 8 - CPUs + 9 - RAM + 10 - Primary (shared) storage (Volumes) + 11 - Secondary storage (Snapshots, Templates & ISOs) + """ + + Resources.updateCount(apiclient, + domainid=domainid, + account=accountid if accountid else None, + projectid=projectid if projectid else None, + resourcetype=rtype if rtype else None + ) + return + + +def findSuitableHostForMigration(apiclient, vmid): + """Returns a suitable host for VM migration""" + suitableHost = None + try: + hosts = Host.listForMigration(apiclient, virtualmachineid=vmid, + ) + except Exception as e: + raise Exception( + "Exception while getting hosts list suitable for migration: %s" % + e) + + suitablehosts = [] + if isinstance(hosts, list) and len(hosts) > 0: + suitablehosts = [host for host in hosts + if (str(host.resourcestate).lower() == "enabled" + and str(host.state).lower() == "up")] + if len(suitablehosts) > 0: + suitableHost = suitablehosts[0] + + return suitableHost + + +def get_resource_type(resource_id): + """Returns resource type""" + + lookup = {0: "VM", + 1: "Public IP", + 2: "Volume", + 3: "Snapshot", + 4: "Template", + 5: "Projects", + 6: "Network", + 7: "VPC", + 8: "CPUs", + 9: "RAM", + 10: "Primary (shared) storage (Volumes)", + 11: "Secondary storage (Snapshots, Templates & ISOs)" + } + + return lookup[resource_id] + + +def get_free_vlan(apiclient, zoneid): + """ + Find an unallocated VLAN outside the range + allocated to the physical network. + + @note: This does not guarantee that the VLAN is available for use in + the deployment's network gear + @return: physical_network, shared_vlan_tag + """ + list_physical_networks_response = PhysicalNetwork.list( + apiclient, + zoneid=zoneid + ) + assert isinstance(list_physical_networks_response, list) + assert len( + list_physical_networks_response) > 0,\ + "No physical networks found in zone %s" % zoneid + + physical_network = list_physical_networks_response[0] + + networks = list_networks(apiclient, zoneid=zoneid, type='Shared') + usedVlanIds = [] + + if isinstance(networks, list) and len(networks) > 0: + usedVlanIds = [int(nw.vlan) + for nw in networks if nw.vlan != "untagged"] + + if hasattr(physical_network, "vlan") is False: + while True: + shared_ntwk_vlan = random.randrange(1, 4095) + if shared_ntwk_vlan in usedVlanIds: + continue + else: + break + else: + vlans = xsplit(physical_network.vlan, ['-', ',']) + + assert len(vlans) > 0 + assert int(vlans[0]) < int( + vlans[-1]), "VLAN range %s was improperly split"\ + % physical_network.vlan + + # Assuming random function will give different integer each time + retriesCount = 20 + + shared_ntwk_vlan = None + + while True: + + if retriesCount == 0: + break + + free_vlan = int(vlans[-1]) + random.randrange(1, 20) + + if free_vlan > 4095: + free_vlan = int(vlans[0]) - random.randrange(1, 20) + if free_vlan < 0 or (free_vlan in usedVlanIds): + retriesCount -= 1 + continue + else: + shared_ntwk_vlan = free_vlan + break + + return physical_network, shared_ntwk_vlan + + +def setNonContiguousVlanIds(apiclient, zoneid): + """ + Form the non contiguous ranges based on currently + assigned range in physical network + """ + + NonContigVlanIdsAcquired = False + + list_physical_networks_response = PhysicalNetwork.list( + apiclient, + zoneid=zoneid + ) + assert isinstance(list_physical_networks_response, list) + assert len( + list_physical_networks_response) > 0, \ + "No physical networks found in zone %s" % zoneid + + for physical_network in list_physical_networks_response: + + vlans = xsplit(physical_network.vlan, ['-', ',']) + + assert len(vlans) > 0 + assert int(vlans[0]) < int( + vlans[-1]), "VLAN range %s was improperly split"\ + % physical_network.vlan + + # Keep some gap between existing vlan and the new vlans + # which we are going to add + # So that they are non contiguous + + non_contig_end_vlan_id = int(vlans[-1]) + 6 + non_contig_start_vlan_id = int(vlans[0]) - 6 + + # Form ranges which are consecutive to existing ranges but + # not immediately contiguous + # There should be gap in between existing range + # and new non contiguous range + # If you can't add range after existing range, + # because it's crossing 4095, then select VLAN ids before + # the existing range such that they are greater than 0, and + # then add this non contiguoud range + vlan = {"partial_range": ["", ""], "full_range": ""} + + if non_contig_end_vlan_id < 4095: + vlan["partial_range"][0] = str( + non_contig_end_vlan_id - 4) + '-' + str(non_contig_end_vlan_id + - 3) + vlan["partial_range"][1] = str( + non_contig_end_vlan_id - 1) + '-' + str(non_contig_end_vlan_id) + vlan["full_range"] = str( + non_contig_end_vlan_id - 4) + '-' + str(non_contig_end_vlan_id) + NonContigVlanIdsAcquired = True + + elif non_contig_start_vlan_id > 0: + vlan["partial_range"][0] = \ + str(non_contig_start_vlan_id) \ + + '-' + str(non_contig_start_vlan_id + 1) + vlan["partial_range"][1] = \ + str(non_contig_start_vlan_id + 3) \ + + '-' + str(non_contig_start_vlan_id + 4) + vlan["full_range"] = \ + str(non_contig_start_vlan_id) \ + + '-' + str(non_contig_start_vlan_id + 4) + NonContigVlanIdsAcquired = True + + else: + NonContigVlanIdsAcquired = False + + # If failed to get relevant vlan ids, continue to next physical network + # else break from loop as we have hot the non contiguous vlan ids for + # the test purpose + + if not NonContigVlanIdsAcquired: + continue + else: + break + + # If even through looping from all existing physical networks, + # failed to get relevant non + # contiguous vlan ids, then fail the test case + + if not NonContigVlanIdsAcquired: + return None, None + + return physical_network, vlan + +def isIpInDesiredState(apiclient, ipaddressid, state): + """ Check if the given IP is in the correct state (given) + and return True/False accordingly""" + retriesCount = 10 + ipInDesiredState = False + exceptionOccured = False + exceptionMessage = "" + try: + while retriesCount >= 0: + portableips = PublicIPAddress.list(apiclient, id=ipaddressid) + assert validateList( + portableips)[0] == PASS, "IPs list validation failed" + if str(portableips[0].state).lower() == state: + ipInDesiredState = True + break + retriesCount -= 1 + time.sleep(60) + except Exception as e: + exceptionOccured = True + exceptionMessage = e + return [exceptionOccured, ipInDesiredState, e] + if not ipInDesiredState: + exceptionMessage = "Ip should be in %s state, it is in %s" %\ + (state, portableips[0].state) + return [False, ipInDesiredState, exceptionMessage] + + +def setSharedNetworkParams(networkServices, range=20): + """Fill up the services dictionary for shared network + using random subnet + """ + + # @range: range decides the endip. Pass the range as "x" + # if you want the difference between the startip + # and endip as "x" + # Set the subnet number of shared networks randomly prior to execution + # of each test case to avoid overlapping of ip addresses + shared_network_subnet_number = random.randrange(1, 254) + + networkServices["gateway"] = "172.16." + \ + str(shared_network_subnet_number) + ".1" + networkServices["startip"] = "172.16." + \ + str(shared_network_subnet_number) + ".2" + networkServices["endip"] = "172.16." + \ + str(shared_network_subnet_number) + "." + str(range + 1) + networkServices["netmask"] = "255.255.255.0" + return networkServices + + +def createEnabledNetworkOffering(apiclient, networkServices): + """Create and enable network offering according to the type + + @output: List, containing [ Result,Network Offering,Reason ] + Ist Argument('Result') : FAIL : If exception or assertion + error occurs + PASS : If network offering + is created and enabled successfully + IInd Argument(Net Off) : Enabled network offering + In case of exception or + assertion error, it will be + None + IIIrd Argument(Reason) : Reason for failure, + default to None + """ + try: + resultSet = [FAIL, None, None] + # Create network offering + network_offering = NetworkOffering.create( + apiclient, + networkServices, + conservemode=False) + + # Update network offering state from disabled to enabled. + NetworkOffering.update(network_offering, + apiclient, id=network_offering.id, + state="enabled") + except Exception as e: + resultSet[2] = e + return resultSet + return [PASS, network_offering, None] + + +def shouldTestBeSkipped(networkType, zoneType): + """Decide which test to skip, according to type of network and zone type""" + + # If network type is isolated or vpc and zone type is basic, then test + # should be skipped + skipIt = False + if (networkType.lower() == str(ISOLATED_NETWORK).lower() or + networkType.lower() == str(VPC_NETWORK).lower()) and\ + (zoneType.lower() == BASIC_ZONE): + skipIt = True + return skipIt + + +def verifyNetworkState(apiclient, networkid, state): + """List networks and check if the network state matches the given state""" + retriesCount = 10 + isNetworkInDesiredState = False + exceptionOccured = False + exceptionMessage = "" + try: + while retriesCount >= 0: + networks = Network.list(apiclient, id=networkid) + assert validateList( + networks)[0] == PASS, "Networks list validation failed" + if str(networks[0].state).lower() == state: + isNetworkInDesiredState = True + break + retriesCount -= 1 + time.sleep(60) + except Exception as e: + exceptionOccured = True + exceptionMessage = e + return [exceptionOccured, isNetworkInDesiredState, exceptionMessage] + return [exceptionOccured, isNetworkInDesiredState, exceptionMessage] + + +def verifyComputeOfferingCreation(apiclient, computeofferingid): + """List Compute offerings by ID and verify that the offering exists""" + + cmd = listServiceOfferings.listServiceOfferingsCmd() + cmd.id = computeofferingid + serviceOfferings = None + try: + serviceOfferings = apiclient.listServiceOfferings(cmd) + except Exception: + return FAIL + if not (isinstance(serviceOfferings, list) and len(serviceOfferings) > 0): + return FAIL + return PASS + + +def createNetworkRulesForVM(apiclient, virtualmachine, ruletype, + account, networkruledata): + """Acquire IP, create Firewall and NAT/StaticNAT rule + (associating it with given vm) for that IP""" + + try: + public_ip = PublicIPAddress.create( + apiclient, accountid=account.name, + zoneid=virtualmachine.zoneid, domainid=account.domainid, + networkid=virtualmachine.nic[0].networkid) + + FireWallRule.create( + apiclient, ipaddressid=public_ip.ipaddress.id, + protocol='TCP', cidrlist=[networkruledata["fwrule"]["cidr"]], + startport=networkruledata["fwrule"]["startport"], + endport=networkruledata["fwrule"]["endport"] + ) + + if ruletype == NAT_RULE: + # Create NAT rule + NATRule.create(apiclient, virtualmachine, + networkruledata[ + "natrule"], ipaddressid=public_ip.ipaddress.id, + networkid=virtualmachine.nic[0].networkid) + elif ruletype == STATIC_NAT_RULE: + # Enable Static NAT for VM + StaticNATRule.enable(apiclient, public_ip.ipaddress.id, + virtualmachine.id, + networkid=virtualmachine.nic[0].networkid) + except Exception as e: + [FAIL, e] + return [PASS, public_ip] + +def getPortableIpRangeServices(config): + """ Reads config values related to portable ip and fills up + services accordingly""" + + services = {} + attributeError = False + + if config.portableIpRange.startip: + services["startip"] = config.portableIpRange.startip + else: + attributeError = True + + if config.portableIpRange.endip: + services["endip"] = config.portableIpRange.endip + else: + attributeError = True + + if config.portableIpRange.netmask: + services["netmask"] = config.portableIpRange.netmask + else: + attributeError = True + + if config.portableIpRange.gateway: + services["gateway"] = config.portableIpRange.gateway + else: + attributeError = True + + if config.portableIpRange.vlan: + services["vlan"] = config.portableIpRange.vlan + + if attributeError: + services = FAILED + + return services + + +def uploadVolume(apiclient, zoneid, account, services): + try: + # Upload the volume + volume = Volume.upload(apiclient, services["volume"], + zoneid=zoneid, account=account.name, + domainid=account.domainid, url=services["url"]) + + volume.wait_for_upload(apiclient) + + # Check List Volume response for newly created volume + volumes = Volume.list(apiclient, id=volume.id, + zoneid=zoneid, listall=True) + validationresult = validateList(volumes) + assert validationresult[0] == PASS,\ + "volumes list validation failed: %s" % validationresult[2] + assert str(volumes[0].state).lower() == "uploaded",\ + "Volume state should be 'uploaded' but it is %s" % volumes[0].state + except Exception as e: + return [FAIL, e] + return [PASS, volume] + +def matchResourceCount(apiclient, expectedCount, resourceType, + accountid=None, projectid=None): + """Match the resource count of account/project with the expected + resource count""" + try: + resourceholderlist = None + if accountid: + resourceholderlist = Account.list(apiclient, id=accountid) + elif projectid: + resourceholderlist = Project.list(apiclient, id=projectid, listall=True) + validationresult = validateList(resourceholderlist) + assert validationresult[0] == PASS,\ + "accounts list validation failed" + if resourceType == RESOURCE_PRIMARY_STORAGE: + resourceCount = resourceholderlist[0].primarystoragetotal + elif resourceType == RESOURCE_SECONDARY_STORAGE: + resourceCount = resourceholderlist[0].secondarystoragetotal + elif resourceType == RESOURCE_CPU: + resourceCount = resourceholderlist[0].cputotal + elif resourceType == RESOURCE_MEMORY: + resourceCount = resourceholderlist[0].memorytotal + assert str(resourceCount) == str(expectedCount),\ + "Resource count %s should match with the expected resource count %s" %\ + (resourceCount, expectedCount) + except Exception as e: + return [FAIL, e] + return [PASS, None] + +def createSnapshotFromVirtualMachineVolume(apiclient, account, vmid): + """Create snapshot from volume""" + + try: + volumes = Volume.list(apiclient, account=account.name, + domainid=account.domainid, virtualmachineid=vmid) + validationresult = validateList(volumes) + assert validateList(volumes)[0] == PASS,\ + "List volumes should return a valid response" + snapshot = Snapshot.create(apiclient, volume_id=volumes[0].id, + account=account.name, domainid=account.domainid) + snapshots = Snapshot.list(apiclient, id=snapshot.id, + listall=True) + validationresult = validateList(snapshots) + assert validationresult[0] == PASS,\ + "List snapshot should return a valid list" + except Exception as e: + return[FAIL, e] + return [PASS, snapshot] + +def isVmExpunged(apiclient, vmid, projectid=None, timeout=600): + """Verify if VM is expunged or not""" + vmExpunged= False + while timeout>=0: + try: + vms = VirtualMachine.list(apiclient, id=vmid, projectid=projectid) + if vms is None: + vmExpunged = True + break + timeout -= 60 + time.sleep(60) + except Exception: + vmExpunged = True + break + #end while + return vmExpunged + +def isDomainResourceCountEqualToExpectedCount(apiclient, domainid, expectedcount, + resourcetype): + """Get the resource count of specific domain and match + it with the expected count + Return list [isExceptionOccured, reasonForException, isResourceCountEqual]""" + isResourceCountEqual = False + isExceptionOccured = False + reasonForException = None + try: + response = Resources.updateCount(apiclient, domainid=domainid, + resourcetype=resourcetype) + except Exception as e: + reasonForException = "Failed while updating resource count: %s" % e + isExceptionOccured = True + return [isExceptionOccured, reasonForException, isResourceCountEqual] + + resourcecount = (response[0].resourcecount / (1024**3)) + if resourcecount == expectedcount: + isResourceCountEqual = True + return [isExceptionOccured, reasonForException, isResourceCountEqual] diff --git a/tools/marvin/marvin/integration/lib/utils.py b/tools/marvin/marvin/lib/utils.py similarity index 62% rename from tools/marvin/marvin/integration/lib/utils.py rename to tools/marvin/marvin/lib/utils.py index 709fddebe7..c94afd5d06 100644 --- a/tools/marvin/marvin/integration/lib/utils.py +++ b/tools/marvin/marvin/lib/utils.py @@ -28,13 +28,19 @@ import socket import urlparse import datetime -from marvin.cloudstackAPI import cloudstackAPIClient, listHosts +from marvin.cloudstackAPI import cloudstackAPIClient, listHosts, listRouters +from platform import system +from marvin.cloudstackException import GetDetailExceptionInfo from marvin.sshClient import SshClient -from marvin.codes import (FAIL, - PASS, - MATCH_NOT_FOUND, - INVALID_INPUT, - EMPTY_LIST) +from marvin.codes import ( + SUCCESS, + FAIL, + PASS, + MATCH_NOT_FOUND, + INVALID_INPUT, + EMPTY_LIST, + FAILED) + def restart_mgmt_server(server): """Restarts the management server""" @@ -116,7 +122,9 @@ def cleanup_resources(api_client, resources): obj.delete(api_client) -def is_server_ssh_ready(ipaddress, port, username, password, retries=20, retryinterv=30, timeout=10.0, keyPairFileLocation=None): +def is_server_ssh_ready(ipaddress, port, username, password, + retries=20, retryinterv=30, + timeout=10.0, keyPairFileLocation=None): ''' @Name: is_server_ssh_ready @Input: timeout: tcp connection timeout flag, @@ -136,8 +144,10 @@ def is_server_ssh_ready(ipaddress, port, username, password, retries=20, retryin retries=retries, delay=retryinterv, timeout=timeout) - except Exception, e: - raise Exception("SSH connection has Failed. Waited %ss. Error is %s" % (retries * retryinterv, str(e))) + except Exception as e: + raise Exception( + "SSH connection has Failed. Waited %ss. Error is %s" % + (retries * retryinterv, str(e))) else: return ssh @@ -166,6 +176,7 @@ def fetch_api_client(config_file='datacenterCfg'): ) ) + def get_host_credentials(config, hostip): """Get login information for a host `hostip` (ipv4) from marvin's `config` @@ -181,26 +192,35 @@ def get_host_credentials(config, hostip): try: if socket.getfqdn(hostip) == socket.getfqdn(hostname): return host.username, host.password - except socket.error, e: - raise Exception("Unresolvable host %s error is %s" % (hostip, e)) - raise KeyError("Please provide the marvin configuration file with credentials to your hosts") - - -def get_process_status(hostip, port, username, password, linklocalip, process, hypervisor=None): + except socket.error as e: + raise Exception( + "Unresolvable host %s error is %s" % + (hostip, e)) + raise KeyError( + "Please provide the marvin configuration file " + "with credentials to your hosts") + + +def get_process_status( + hostip, port, username, password, + linklocalip, process, hypervisor=None): """Double hop and returns a process status""" - #SSH to the machine + # SSH to the machine ssh = SshClient(hostip, port, username, password) if (str(hypervisor).lower() == 'vmware' - or str(hypervisor).lower() == 'hyperv'): - ssh_command = "ssh -i /var/cloudstack/management/.ssh/id_rsa -ostricthostkeychecking=no " + or str(hypervisor).lower() == 'hyperv'): + ssh_command =\ + "ssh -i /var/cloudstack/management/" \ + ".ssh/id_rsa -ostricthostkeychecking=no " else: - ssh_command = "ssh -i ~/.ssh/id_rsa.cloud -ostricthostkeychecking=no " + ssh_command = "ssh -i ~/.ssh/id_rsa.cloud " \ + "-ostricthostkeychecking=no " ssh_command = ssh_command +\ - "-oUserKnownHostsFile=/dev/null -p 3922 %s %s" % ( - linklocalip, - process) + "-oUserKnownHostsFile=/dev/null -p 3922 %s %s" % ( + linklocalip, + process) # Double hop into router timeout = 5 @@ -237,12 +257,13 @@ def xsplit(txt, seps): @return: list of split units """ default_sep = seps[0] - for sep in seps[1:]: # we skip seps[0] because that's the default separator + # we skip seps[0] because that's the default separator + for sep in seps[1:]: txt = txt.replace(sep, default_sep) return [i.strip() for i in txt.split(default_sep)] -def get_hypervisor_type(apiclient): +def get_hypervisor_type(apiclient): """Return the hypervisor type of the hosts in setup""" cmd = listHosts.listHostsCmd() @@ -250,70 +271,91 @@ def get_hypervisor_type(apiclient): cmd.listall = True hosts = apiclient.listHosts(cmd) hosts_list_validation_result = validateList(hosts) - assert hosts_list_validation_result[0] == PASS, "host list validation failed" + assert hosts_list_validation_result[ + 0] == PASS, "host list validation failed" return hosts_list_validation_result[1].hypervisor + def is_snapshot_on_nfs(apiclient, dbconn, config, zoneid, snapshotid): """ - Checks whether a snapshot with id (not UUID) `snapshotid` is present on the nfs storage + Checks whether a snapshot with id + (not UUID) `snapshotid` is present on the nfs storage @param apiclient: api client connection @param @dbconn: connection to the cloudstack db @param config: marvin configuration file - @param zoneid: uuid of the zone on which the secondary nfs storage pool is mounted + @param zoneid: uuid of the zone on which the + secondary nfs storage pool is mounted @param snapshotid: uuid of the snapshot @return: True if snapshot is found, False otherwise """ # snapshot extension to be appended to the snapshot path obtained from db snapshot_extensions = {"vmware": ".ovf", - "kvm": "", - "xenserver": ".vhd"} + "kvm": "", + "xenserver": ".vhd", + "simulator": ""} qresultset = dbconn.execute( - "select id from snapshots where uuid = '%s';" \ - % str(snapshotid) - ) + "select id from snapshots where uuid = '%s';" + % str(snapshotid) + ) if len(qresultset) == 0: raise Exception( "No snapshot found in cloudstack with id %s" % snapshotid) - snapshotid = qresultset[0][0] qresultset = dbconn.execute( - "select install_path,store_id from snapshot_store_ref where snapshot_id='%s' and store_role='Image';" % snapshotid + "select install_path,store_id from snapshot_store_ref" + " where snapshot_id='%s' and " + "store_role='Image';" % snapshotid ) - assert isinstance(qresultset, list), "Invalid db query response for snapshot %s" % snapshotid + assert isinstance( + qresultset, list), "Invalid db query " \ + "response for snapshot " \ + "%s" % snapshotid if len(qresultset) == 0: - #Snapshot does not exist + # Snapshot does not exist return False from base import ImageStore - #pass store_id to get the exact storage pool where snapshot is stored - secondaryStores = ImageStore.list(apiclient, zoneid=zoneid, id=int(qresultset[0][1])) - - assert isinstance(secondaryStores, list), "Not a valid response for listImageStores" - assert len(secondaryStores) != 0, "No image stores found in zone %s" % zoneid + # pass store_id to get the exact storage pool where snapshot is stored + secondaryStores = ImageStore.list( + apiclient, + zoneid=zoneid, + id=int( + qresultset[0][1])) + + assert isinstance( + secondaryStores, list), "Not a valid response for listImageStores" + assert len( + secondaryStores) != 0, "No image stores found in zone %s" % zoneid secondaryStore = secondaryStores[0] if str(secondaryStore.providername).lower() != "nfs": raise Exception( - "is_snapshot_on_nfs works only against nfs secondary storage. found %s" % str(secondaryStore.providername)) + "is_snapshot_on_nfs works only " + "against nfs secondary storage." + " found %s" % str(secondaryStore.providername)) hypervisor = get_hypervisor_type(apiclient) # append snapshot extension based on hypervisor, to the snapshot path - snapshotPath = str(qresultset[0][0]) + snapshot_extensions[str(hypervisor).lower()] + snapshotPath = str(qresultset[0][0]) + \ + snapshot_extensions[str(hypervisor).lower()] nfsurl = secondaryStore.url from urllib2 import urlparse parse_url = urlparse.urlsplit(nfsurl, scheme='nfs') - host, path = parse_url.netloc, parse_url.path + host, path = str(parse_url.netloc), str(parse_url.path) if not config.mgtSvr: - raise Exception("Your marvin configuration does not contain mgmt server credentials") - mgtSvr, user, passwd = config.mgtSvr[0].mgtSvrIp, config.mgtSvr[0].user, config.mgtSvr[0].passwd + raise Exception( + "Your marvin configuration does " + "not contain mgmt server credentials") + mgtSvr, user, passwd = config.mgtSvr[ + 0].mgtSvrIp, config.mgtSvr[0].user, config.mgtSvr[0].passwd try: ssh_client = SshClient( @@ -322,33 +364,40 @@ def is_snapshot_on_nfs(apiclient, dbconn, config, zoneid, snapshotid): user, passwd ) + + pathSeparator = "" #used to form host:dir format + if not host.endswith(':'): + pathSeparator= ":" + cmds = [ - "mkdir -p %s /mnt/tmp", - "mount -t %s %s%s /mnt/tmp" % ( - 'nfs', - host, - path, - ), - "test -f %s && echo 'snapshot exists'" % ( - os.path.join("/mnt/tmp", snapshotPath) - ), - ] + "mkdir -p %s /mnt/tmp", + "mount -t %s %s%s%s /mnt/tmp" % ( + 'nfs', + host, + pathSeparator, + path, + ), + "test -f %s && echo 'snapshot exists'" % ( + os.path.join("/mnt/tmp", snapshotPath) + ), + ] for c in cmds: result = ssh_client.execute(c) # Unmount the Sec Storage cmds = [ - "cd", - "umount /mnt/tmp", - ] + "cd", + "umount /mnt/tmp", + ] for c in cmds: ssh_client.execute(c) except Exception as e: raise Exception("SSH failed for management server: %s - %s" % - (config.mgtSvr[0].mgtSvrIp, e)) + (config.mgtSvr[0].mgtSvrIp, e)) return 'snapshot exists' in result + def validateList(inp): """ @name: validateList @@ -382,7 +431,8 @@ def validateList(inp): return ret return [PASS, inp[0], None] -def verifyElementInList(inp, toverify, responsevar=None, pos=0): + +def verifyElementInList(inp, toverify, responsevar=None, pos=0): ''' @name: verifyElementInList @Description: @@ -394,9 +444,9 @@ def verifyElementInList(inp, toverify, responsevar=None, pos=0): at a given pos @Input: I : Input to be verified whether its a list or not - II : Element to verify whether it exists in the list - III : variable name in response object to verify - default to None, if None, we will verify for the complete + II : Element to verify whether it exists in the list + III : variable name in response object to verify + default to None, if None, we will verify for the complete first element EX: state of response object object IV : Position in the list at which the input element to verify default to 0 @@ -419,13 +469,77 @@ def verifyElementInList(inp, toverify, responsevar=None, pos=0): return [FAIL, out[2]] if len(inp) > pos: if responsevar is None: - if inp[pos] == toverify: - return [PASS, None] + if inp[pos] == toverify: + return [PASS, None] else: - if responsevar in inp[pos].__dict__ and getattr(inp[pos], responsevar) == toverify: - return [PASS, None] - else: - return [FAIL, MATCH_NOT_FOUND] + if responsevar in inp[pos].\ + __dict__ and getattr(inp[pos], responsevar) == toverify: + return [PASS, None] + else: + return [FAIL, MATCH_NOT_FOUND] else: return [FAIL, MATCH_NOT_FOUND] + +def checkVolumeSize(ssh_handle=None, + volume_name="/dev/sda", + cmd_inp="/sbin/fdisk -l | grep Disk", + size_to_verify=0): + ''' + @Name : getDiskUsage + @Desc : provides facility to verify the + volume size against the size to verify + @Input: 1. ssh_handle : machine against which to execute the disk size cmd + 2. volume_name : The name of the volume + against which to verify the size + 3. cmd_inp : Input command used to veify the size + 4. size_to_verify: size against which to compare. + @Output: Returns FAILED in case of an issue, else SUCCESS + ''' + try: + if ssh_handle is None or cmd_inp is None or volume_name is None: + return INVALID_INPUT + + cmd = cmd_inp + ''' + Retrieve the cmd output + ''' + if system().lower() != "windows": + fdisk_output = ssh_handle.runCommand(cmd_inp) + if fdisk_output["status"] != SUCCESS: + return FAILED + for line in fdisk_output["stdout"]: + if volume_name in line: + parts = line.strip().split() + if str(parts[-2]) == str(size_to_verify): + return [SUCCESS, str(parts[-2])] + return [FAILED, "Volume Not Found"] + except Exception as e: + print "\n Exception Occurred under getDiskUsage: " \ + "%s" % GetDetailExceptionInfo(e) + return [FAILED, GetDetailExceptionInfo(e)] + + +def verifyRouterState(apiclient, routerid, allowedstates): + """List the router and verify that its state is in allowed states + @output: List, containing [Result, Reason] + Ist Argument ('Result'): FAIL: If router state is not + in allowed states + PASS: If router state is in + allowed states""" + + try: + cmd = listRouters.listRoutersCmd() + cmd.id = routerid + cmd.listall = True + routers = apiclient.listRouters(cmd) + except Exception as e: + return [FAIL, e] + listvalidationresult = validateList(routers) + if listvalidationresult[0] == FAIL: + return [FAIL, listvalidationresult[2]] + if routers[0].redundantstate not in allowedstates: + return [FAIL, "Redundant state of the" + " router should be in %s but is %s" % + (allowedstates, routers[0].redundantstate)] + return [PASS, None] diff --git a/tools/marvin/marvin/marvinInit.py b/tools/marvin/marvin/marvinInit.py index f722058a9f..ce9b43f1ad 100644 --- a/tools/marvin/marvin/marvinInit.py +++ b/tools/marvin/marvin/marvinInit.py @@ -15,56 +15,67 @@ # specific language governing permissions and limitations # under the License. ''' -@Desc: Initializes the marvin and does required prerequisites +Initializes the marvin and does required prerequisites for starting it. -1. Parses the configuration file passed to marvin and creates a - parsed config + 1. Parses the configuration file passed to marvin and creates a + parsed config. 2. Initializes the logging required for marvin.All logs are now made available under a single timestamped folder. - 3. Deploys the Data Center based upon input + 3. Deploys the Data Center based upon input. ''' - -from marvin import configGenerator -from marvin import cloudstackException +from marvin.configGenerator import getSetupConfig from marvin.marvinLog import MarvinLog -from marvin.deployDataCenter import deployDataCenters +from marvin.deployDataCenter import DeployDataCenters +from marvin.cloudstackTestClient import CSTestClient +from marvin.cloudstackException import GetDetailExceptionInfo from marvin.codes import( - YES, - NO, + XEN_SERVER, SUCCESS, FAILED - ) -import sys -import time +) import os -import logging -import string -import random class MarvinInit: - def __init__(self, config_file, load_flag, log_folder_path=None): + + def __init__(self, config_file, + deploy_dc_flag=None, + test_mod_name="deploydc", + zone=None, + hypervisor_type=None, + user_logfolder_path=None): self.__configFile = config_file - self.__loadFlag = load_flag - self.__parsedConfig = None - self.__logFolderPath = log_folder_path + self.__deployFlag = deploy_dc_flag + self.__logFolderPath = None self.__tcRunLogger = None + self.__testModName = test_mod_name self.__testClient = None - self.__tcRunDebugFile = None + self.__tcResultFile = None + self.__testDataFilePath = None + self.__zoneForTests = zone + self.__parsedConfig = None + self.__hypervisorType = hypervisor_type + self.__userLogFolderPath = user_logfolder_path def __parseConfig(self): ''' + @Name: __parseConfig @Desc : Parses the configuration file passed and assigns the parsed configuration + @Output : SUCCESS or FAILED ''' try: - self.__parsedConfig = configGenerator.\ - getSetupConfig(self.__configFile) + if not os.path.isfile(self.__configFile): + print "\n=== Marvin Parse Config Init Failed ===" + return FAILED + self.__parsedConfig = getSetupConfig(self.__configFile) + print "\n=== Marvin Parse Config Successful ===" return SUCCESS - except Exception, e: - print "\n Exception Occurred Under __parseConfig : %s" % str(e) - return None + except Exception as e: + print "\nException Occurred Under __parseConfig : " \ + "%s" % GetDetailExceptionInfo(e) + return FAILED def getParsedConfig(self): return self.__parsedConfig @@ -78,33 +89,67 @@ def getTestClient(self): def getLogger(self): return self.__tcRunLogger - def getDebugFile(self): - return self.__tcRunDebugFile + def getResultFile(self): + ''' + @Name : getDebugFile + @Desc : Creates the result file at a given path. + @Output : Returns the Result file to be used for writing + test outputs + ''' + if self.__logFolderPath is not None: + self.__tcResultFile = open(self.__logFolderPath + + "/results.txt", "w") + return self.__tcResultFile + + def __setHypervisorAndZoneInfo(self): + ''' + @Name : __setHypervisorAndZoneInfo + @Desc: Set the HyperVisor and Zone details; + default to XenServer + ''' + try: + if not self.__hypervisorType: + self.__hypervisorType = XEN_SERVER + if not self.__zoneForTests: + if self.__parsedConfig: + for zone in self.__parsedConfig.zones: + self.__zoneForTests = zone.name + break + return SUCCESS + except Exception as e: + print "\n Exception Occurred Under init " \ + "%s" % GetDetailExceptionInfo(e) + return FAILED def init(self): ''' + @Name : init @Desc :Initializes the marvin by 1. Parsing the configuration and creating a parsed config structure 2. Creates a timestamped log folder and provides all logs to be dumped there 3. Creates the DataCenter based upon configuration provided + @Output : SUCCESS or FAILED ''' try: - if ((self.__parseConfig() is not None) and - (self.__initLogging() is not None) and - (self.__deployDC() is not None)): + if ((self.__parseConfig() != FAILED) and + (self.__setHypervisorAndZoneInfo())and + (self.__setTestDataPath() != FAILED) and + (self.__initLogging() != FAILED) and + (self.__createTestClient() != FAILED) and + (self.__deployDC() != FAILED)): return SUCCESS - else: - return FAILED - except Exception, e: - print "\n Exception Occurred Under init %s" % str(e) + return FAILED + except Exception as e: + print "\n Exception Occurred Under init " \ + "%s" % GetDetailExceptionInfo(e) return FAILED def __initLogging(self): - try: - ''' - @Desc : 1. Initializes the logging for marvin and so provides + ''' + @Name : __initLogging + @Desc : 1. Initializes the logging for marvin and so provides various log features for automation run. 2. Initializes all logs to be available under given Folder Path,where all test run logs @@ -112,58 +157,87 @@ def __initLogging(self): 3. All logging like exception log,results, run info etc for a given test run are available under a given timestamped folder - ''' - temp_path = "".join(str(time.time()).split(".")) - if self.__logFolderPath is None: - log_config = self.__parsedConfig.logger - if log_config is not None: - if log_config.LogFolderPath is not None: - self.logFolderPath = log_config.LogFolderPath + '/' \ - + temp_path - else: - self.logFolderPath = temp_path - else: - self.logFolderPath = temp_path - else: - self.logFolderPath = self.__logFolderPath + '/' + temp_path - if os.path.exists(self.logFolderPath): - self.logFolderPath += ''.join(random.choice( - string.ascii_uppercase + - string.digits for x in range(3))) - os.makedirs(self.logFolderPath) - ''' - Log File Paths - ''' - tc_failed_exceptionlog = self.logFolderPath + "/failed_" \ - "plus_" \ - "exceptions.txt" - tc_run_log = self.logFolderPath + "/runinfo.txt" - self.__tcRunDebugFile = open(self.logFolderPath + - "/results.txt", "w") - + @Output : SUCCESS or FAILED + ''' + try: log_obj = MarvinLog("CSLog") - self.__tcRunLogger = log_obj.setLogHandler(tc_run_log) - log_obj.setLogHandler(tc_failed_exceptionlog, - log_level=logging.FATAL) + if log_obj: + ret = log_obj.\ + createLogs(self.__testModName, + self.__parsedConfig.logger, + self.__userLogFolderPath) + if ret != FAILED: + self.__logFolderPath = log_obj.getLogFolderPath() + self.__tcRunLogger = log_obj.getLogger() + print "\n=== Marvin Init Logging Successful===" + return SUCCESS + return FAILED + except Exception as e: + print "\n Exception Occurred Under __initLogging " \ + ":%s" % GetDetailExceptionInfo(e) + return FAILED + + def __createTestClient(self): + ''' + @Name : __createTestClient + @Desc : Creates the TestClient during init + based upon the parameters provided + @Output: Returns SUCCESS or FAILED + ''' + try: + mgt_details = self.__parsedConfig.mgtSvr[0] + dbsvr_details = self.__parsedConfig.dbSvr + self.__testClient = CSTestClient( + mgt_details, + dbsvr_details, + logger=self.__tcRunLogger, + test_data_filepath=self.__testDataFilePath, + zone=self.__zoneForTests, + hypervisor_type=self.__hypervisorType) + if self.__testClient: + return self.__testClient.createTestClient() + return FAILED + except Exception as e: + print "\n Exception Occurred Under __createTestClient : %s" % \ + GetDetailExceptionInfo(e) + return FAILED + + def __setTestDataPath(self): + ''' + @Name : __setTestDataPath + @Desc : Sets the TestData Path for tests to run + @Output:Returns SUCCESS or FAILED + ''' + try: + if ((self.__parsedConfig.TestData is not None) and + (self.__parsedConfig.TestData.Path is not None)): + self.__testDataFilePath = self.__parsedConfig.TestData.Path + print "\n=== Marvin Setting TestData Successful===" return SUCCESS - except Exception, e: - print "\n Exception Occurred Under __initLogging :%s" % str(e) - return None + except Exception as e: + print "\nException Occurred Under __setTestDataPath : %s" % \ + GetDetailExceptionInfo(e) + return FAILED def __deployDC(self): + ''' + @Name : __deployDC + @Desc : Deploy the DataCenter and returns accordingly. + @Output: SUCCESS or FAILED + ''' try: - ''' - Deploy the DataCenter and retrieves test client. - ''' - deploy_obj = deployDataCenters(self.__parsedConfig, - self.__tcRunLogger) - if self.__loadFlag: - deploy_obj.loadCfg() - else: - deploy_obj.deploy() - - self.__testClient = deploy_obj.testClient - return SUCCESS - except Exception, e: - print "\n Exception Occurred Under __deployDC : %s" % str(e) - return None + ret = SUCCESS + if self.__deployFlag: + deploy_obj = DeployDataCenters(self.__testClient, + self.__parsedConfig, + self.__tcRunLogger) + ret = deploy_obj.deploy() + if ret == SUCCESS: + print "Deploy DC Successful" + else: + print "Deploy DC Failed" + return ret + except Exception as e: + print "\n Exception Occurred Under __deployDC : %s" % \ + GetDetailExceptionInfo(e) + return FAILED diff --git a/tools/marvin/marvin/marvinLog.py b/tools/marvin/marvin/marvinLog.py index 76de185421..ea8eaee7df 100644 --- a/tools/marvin/marvin/marvinLog.py +++ b/tools/marvin/marvin/marvinLog.py @@ -20,17 +20,22 @@ import logging import sys import time -from marvin.codes import (NO, - YES +import os +from marvin.codes import (SUCCESS, + FAILED ) +from marvin.cloudstackException import GetDetailExceptionInfo +from marvin.lib.utils import random_gen class MarvinLog: + ''' + @Name : MarvinLog @Desc : provides interface for logging to marvin @Input : logger_name : name for logger ''' - logFormat = logging.Formatter("%(asctime)s - %(levelname)s - %(name)s - %(message)s") + logFormat = logging.Formatter("%(asctime)s - %(levelname)s - %(message)s") _instance = None def __new__(cls, logger_name): @@ -39,21 +44,39 @@ def __new__(cls, logger_name): return cls._instance def __init__(self, logger_name): - self.loggerName = logger_name - self.logger = None + ''' + @Name: __init__ + @Input: logger_name for logger + ''' + self.__loggerName = logger_name + ''' + Logger for Logging Info + ''' + self.__logger = None + ''' + Log Folder Directory + ''' + self.__logFolderDir = None self.__setLogger() def __setLogger(self): - self.logger = logging.getLogger(self.loggerName) - self.logger.setLevel(logging.DEBUG) + ''' + @Name : __setLogger + @Desc : Sets the Logger and Level + ''' + self.__logger = logging.getLogger(self.__loggerName) + self.__logger.setLevel(logging.DEBUG) - def setLogHandler(self, log_file_path, log_format=None, - log_level=logging.DEBUG): + def __setLogHandler(self, log_file_path, + log_format=None, + log_level=logging.DEBUG): ''' + @Name : __setLogHandler @Desc: Adds the given Log handler to the current logger @Input: log_file_path: Log File Path as where to store the logs log_format : Format of log messages to be dumped log_level : Determines the level of logging for this logger + @Output: SUCCESS if no issues else FAILED ''' try: if log_file_path is not None: @@ -66,8 +89,98 @@ def setLogHandler(self, log_file_path, log_format=None, else: stream.setFormatter(self.__class__.logFormat) stream.setLevel(log_level) - self.logger.addHandler(stream) - except Exception, e: - print "\n Exception Occurred Under setLogHandler %s" % str(e) - finally: - return self.logger + self.__logger.addHandler(stream) + return SUCCESS + except Exception as e: + print "\nException Occurred Under " \ + "__setLogHandler %s" % GetDetailExceptionInfo(e) + return FAILED + + def __cleanPreviousLogs(self, logfolder_to_remove): + ''' + @Name : __cleanPreviousLogs + @Desc : Removes the Previous Logs + @Return: N\A + @Input: logfolder_to_remove: Path of Log to remove + ''' + try: + if os.path.isdir(logfolder_to_remove): + os.rmdir(logfolder_to_remove) + except Exception as e: + print "\n Exception Occurred Under __cleanPreviousLogs :%s" % \ + GetDetailExceptionInfo(e) + return FAILED + + def getLogger(self): + ''' + @Name:getLogger + @Desc : Returns the Logger + ''' + return self.__logger + + def getLogFolderPath(self): + ''' + @Name : getLogFolderPath + @Desc : Returns the final log directory path for marvin run + ''' + return self.__logFolderDir + + def createLogs(self, + test_module_name=None, + log_cfg=None, + user_provided_logpath=None): + ''' + @Name : createLogs + @Desc : Gets the Logger with file paths initialized and created + @Inputs :test_module_name: Test Module Name to use for logs while + creating log folder path + log_cfg: Log Configuration provided inside of + Configuration + user_provided_logpath:LogPath provided by user + If user provided log path + is available, then one in cfg + will not be picked up. + @Output : SUCCESS\FAILED + ''' + try: + temp_ts = time.strftime("%b_%d_%Y_%H_%M_%S", + time.localtime()) + if test_module_name is None: + temp_path = temp_ts + "_" + random_gen() + else: + temp_path = str(test_module_name) + \ + "__" + str(temp_ts) + "_" + random_gen() + + if user_provided_logpath: + temp_dir = user_provided_logpath + "/MarvinLogs" + elif ((log_cfg is not None) and + ('LogFolderPath' in log_cfg.__dict__.keys()) and + (log_cfg.__dict__.get('LogFolderPath') is not None)): + temp_dir = \ + log_cfg.__dict__.get('LogFolderPath') + "/MarvinLogs" + + self.__logFolderDir = temp_dir + "//" + temp_path + print "\n==== Log Folder Path: %s. " \ + "All logs will be available here ====" \ + % str(self.__logFolderDir) + os.makedirs(self.__logFolderDir) + + ''' + Log File Paths + 1. FailedExceptionLog + 2. RunLog contains the complete Run Information for Test Run + 3. ResultFile contains the TC result information for Test Run + ''' + tc_failed_exception_log = \ + self.__logFolderDir + "/failed_plus_exceptions.txt" + tc_run_log = self.__logFolderDir + "/runinfo.txt" + if self.__setLogHandler(tc_run_log, + log_level=logging.DEBUG) != FAILED: + self.__setLogHandler(tc_failed_exception_log, + log_level=logging.FATAL) + return SUCCESS + return FAILED + except Exception as e: + print "\n Exception Occurred Under createLogs :%s" % \ + GetDetailExceptionInfo(e) + return FAILED diff --git a/tools/marvin/marvin/marvinPlugin.py b/tools/marvin/marvin/marvinPlugin.py index df7d7a3123..52a2cdea3d 100644 --- a/tools/marvin/marvin/marvinPlugin.py +++ b/tools/marvin/marvin/marvinPlugin.py @@ -14,25 +14,24 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. - import marvin -import sys +from sys import stdout, exit import logging +import time +import os import nose.core from marvin.cloudstackTestCase import cloudstackTestCase from marvin.marvinInit import MarvinInit from nose.plugins.base import Plugin from marvin.codes import (SUCCESS, FAILED, - EXCEPTION, - UNKNOWN_ERROR - ) -import traceback -import time -import os + EXCEPTION) +from marvin.lib.utils import random_gen +from marvin.cloudstackException import GetDetailExceptionInfo class MarvinPlugin(Plugin): + """ Custom plugin for the cloudstackTestCases to be run using nose """ @@ -40,18 +39,35 @@ class MarvinPlugin(Plugin): name = "marvin" def __init__(self): - self.identifier = None - self.testClient = None - self.parsedConfig = None - self.configFile = None - self.loadFlag = None + self.__identifier = None + self.__testClient = None + self.__logFolderPath = None + self.__parsedConfig = None + ''' + Contains Config File + ''' + self.__configFile = None + ''' + Signifies the Zone against which all tests will be Run + ''' + self.__zoneForTests = None + ''' + Signifies the flag whether to deploy the New DC or Not + ''' + self.__deployDcFlag = None self.conf = None - self.debugStream = sys.stdout - self.testRunner = None - self.testResult = SUCCESS - self.startTime = None - self.testName = None - self.tcRunLogger = None + self.__resultStream = stdout + self.__testRunner = None + self.__testResult = SUCCESS + self.__startTime = None + self.__testName = None + self.__tcRunLogger = None + self.__testModName = '' + self.__hypervisorType = None + ''' + The Log Path provided by user where all logs are routed to + ''' + self.__userLogPath = None Plugin.__init__(self) def configure(self, options, conf): @@ -60,20 +76,20 @@ def configure(self, options, conf): self.enabled (True|False) determines whether marvin's tests will run. By default non-default plugins like marvin will be disabled """ + self.enabled = True if hasattr(options, self.enableOpt): if not getattr(options, self.enableOpt): self.enabled = False return - else: - self.enabled = True - self.configFile = options.config_file - self.loadFlag = options.load - self.logFolderPath = options.log_folder_path + self.__configFile = options.configFile + self.__deployDcFlag = options.deployDc + self.__zoneForTests = options.zone + self.__hypervisorType = options.hypervisor_type + self.__userLogPath = options.logFolder self.conf = conf - ''' - Initializes the marvin with required settings - ''' - self.startMarvin() + if self.startMarvin() == FAILED: + print "\nStarting Marvin Failed, exiting. Please Check" + exit(1) def options(self, parser, env): """ @@ -82,20 +98,31 @@ def options(self, parser, env): parser.add_option("--marvin-config", action="store", default=env.get('MARVIN_CONFIG', './datacenter.cfg'), - dest="config_file", - help="Marvin's configuration file where the " + - "datacenter information is specified" + - " [MARVIN_CONFIG]") - parser.add_option("--load", action="store_true", + dest="configFile", + help="Marvin's configuration file is required." + "The config file containing the datacenter and " + "other management server " + "information is specified") + parser.add_option("--deploy", action="store_true", default=False, - dest="load", - help="Only load the deployment configuration given") - parser.add_option("--log-folder-path", - action="store", + dest="deployDc", + help="Deploys the DC with Given Configuration." + "Requires only when DC needs to be deployed") + parser.add_option("--zone", action="store", + default=None, + dest="zone", + help="Runs all tests against this specified zone") + parser.add_option("--hypervisor", action="store", + default=None, + dest="hypervisor_type", + help="Runs all tests against the specified " + "zone and hypervisor Type") + parser.add_option("--log-folder-path", action="store", default=None, - dest="log_folder_path", - help="Path to the folder " - "where log files will be stored") + dest="logFolder", + help="Collects all logs under the user specified" + "folder" + ) Plugin.options(self, parser, env) def wantClass(self, cls): @@ -105,93 +132,124 @@ def wantClass(self, cls): return True return None - def wantFile(self, filename): + def __checkImport(self, filename): ''' - Only python files will be used as test modules + @Name : __checkImport + @Desc : Verifies to run the available test module for any Import + Errors before running and check + whether if it is importable. + This will check for test modules which has some issues to be + getting imported. + Returns False or True based upon the result. ''' - parts = filename.split(os.path.sep) - base, ext = os.path.splitext(parts[-1]) - if ext == '.py': - return True - else: + try: + if os.path.isfile(filename): + ret = os.path.splitext(filename) + if ret[1] == ".py": + os.system("python " + filename) + return True + return False + except ImportError as e: + print "FileName :%s : Error : %s" % \ + (filename, GetDetailExceptionInfo(e)) return False + def wantFile(self, filename): + ''' + @Desc : Only python files will be used as test modules + ''' + return self.__checkImport(filename) + def loadTestsFromTestCase(self, cls): if cls.__name__ != 'cloudstackTestCase': - self.identifier = cls.__name__ + self.__identifier = cls.__name__ self._injectClients(cls) def beforeTest(self, test): - self.testName = test.__str__().split()[0] - self.testClient.identifier = '-'.join([self.identifier, self.testName]) - self.tcRunLogger.name = test.__str__() - - def prepareTestRunner(self, runner): - return self.testRunner + self.__testModName = test.__str__() + self.__testName = test.__str__().split()[0] + self.__testClient.identifier = '-'.\ + join([self.__identifier, self.__testName]) + if self.__tcRunLogger: + self.__tcRunLogger.name = test.__str__() def startTest(self, test): """ Currently used to record start time for tests Dump Start Msg of TestCase to Log """ - self.tcRunLogger.debug("::::::::::::STARTED : TC: " + - str(self.testName) + " :::::::::::") - self.startTime = time.time() + if self.__tcRunLogger: + self.__tcRunLogger.debug("::::::::::::STARTED : TC: " + + str(self.__testName) + " :::::::::::") + self.__startTime = time.time() + + def printMsg(self, status, tname, err): + if status in [FAILED, EXCEPTION] and self.__tcRunLogger: + self.__tcRunLogger.\ + fatal("%s: %s: %s" % (status, + tname, + GetDetailExceptionInfo(err))) + write_str = "=== TestName: %s | Status : %s ===\n" % (tname, status) + self.__resultStream.write(write_str) + print write_str - def getErrorInfo(self, err): + def addSuccess(self, test, capt): ''' - Extracts and returns the sanitized error message + Adds the Success Messages to logs ''' - if err is not None: - return str(traceback.format_exc()) - else: - return UNKNOWN_ERROR + self.printMsg(SUCCESS, self.__testName, "Test Case Passed") + self.__testresult = SUCCESS def handleError(self, test, err): ''' Adds Exception throwing test cases and information to log. ''' - err_msg = self.getErrorInfo(err) - self.tcRunLogger.fatal("%s: %s: %s" % - (EXCEPTION, self.testName, err_msg)) - self.testResult = EXCEPTION + self.printMsg(EXCEPTION, self.__testName, GetDetailExceptionInfo(err)) + self.__testResult = EXCEPTION + + def prepareTestRunner(self, runner): + if self.__testRunner: + return self.__testRunner def handleFailure(self, test, err): ''' Adds Failing test cases and information to log. ''' - err_msg = self.getErrorInfo(err) - self.tcRunLogger.fatal("%s: %s: %s" % - (FAILED, self.testName, err_msg)) - self.testResult = FAILED + self.printMsg(FAILED, self.__testName, GetDetailExceptionInfo(err)) + self.__testResult = FAILED def startMarvin(self): ''' - Initializes the Marvin - creates the test Client - creates the runlogger for logging - Parses the config and creates a parsedconfig - Creates a debugstream for tc debug log + @Name : startMarvin + @Desc : Initializes the Marvin + creates the test Client + creates the runlogger for logging + Parses the config and creates a parsedconfig + Creates a debugstream for tc debug log ''' try: - obj_marvininit = MarvinInit(self.configFile, - self.loadFlag, - self.logFolderPath) - if obj_marvininit.init() == SUCCESS: - self.testClient = obj_marvininit.getTestClient() - self.tcRunLogger = obj_marvininit.getLogger() - self.parsedConfig = obj_marvininit.getParsedConfig() - self.debugStream = obj_marvininit.getDebugFile() - self.testRunner = nose.core.TextTestRunner(stream= - self.debugStream, - descriptions=True, - verbosity=2, - config=self.conf) + obj_marvininit = MarvinInit(self.__configFile, + self.__deployDcFlag, + None, + self.__zoneForTests, + self.__hypervisorType, + self.__userLogPath) + if obj_marvininit and obj_marvininit.init() == SUCCESS: + self.__testClient = obj_marvininit.getTestClient() + self.__tcRunLogger = obj_marvininit.getLogger() + self.__parsedConfig = obj_marvininit.getParsedConfig() + self.__resultStream = obj_marvininit.getResultFile() + self.__logFolderPath = obj_marvininit.getLogFolderPath() + self.__testRunner = nose.core.\ + TextTestRunner(stream=self.__resultStream, + descriptions=True, + verbosity=2, + config=self.conf) return SUCCESS - else: - return FAILED - except Exception, e: - print "Exception Occurred under startMarvin: %s" % str(e) + return FAILED + except Exception as e: + print "Exception Occurred under startMarvin: %s" % \ + GetDetailExceptionInfo(e) return FAILED def stopTest(self, test): @@ -199,27 +257,53 @@ def stopTest(self, test): Currently used to record end time for tests """ endTime = time.time() - if self.startTime is not None: - totTime = int(endTime - self.startTime) - self.tcRunLogger.debug("TestCaseName: %s; Time Taken: " - "%s Seconds; " - "StartTime: %s; EndTime: %s; Result: %s" - % (self.testName, str(totTime), - str(time.ctime(self.startTime)), - str(time.ctime(endTime)), - self.testResult)) + if self.__startTime: + totTime = int(endTime - self.__startTime) + if self.__tcRunLogger: + self.__tcRunLogger.\ + debug("TestCaseName: %s; " + "Time Taken: %s Seconds; StartTime: %s; " + "EndTime: %s; Result: %s" % + (self.__testName, str(totTime), + str(time.ctime(self.__startTime)), + str(time.ctime(endTime)), + self.__testResult)) def _injectClients(self, test): - setattr(test, "debug", self.tcRunLogger.debug) - setattr(test, "info", self.tcRunLogger.info) - setattr(test, "warn", self.tcRunLogger.warning) - setattr(test, "error", self.tcRunLogger.error) - setattr(test, "testClient", self.testClient) - setattr(test, "config", self.parsedConfig) - if self.testClient.identifier is None: - self.testClient.identifier = self.identifier - setattr(test, "clstestclient", self.testClient) + setattr(test, "debug", self.__tcRunLogger.debug) + setattr(test, "info", self.__tcRunLogger.info) + setattr(test, "warn", self.__tcRunLogger.warning) + setattr(test, "error", self.__tcRunLogger.error) + setattr(test, "testClient", self.__testClient) + setattr(test, "config", self.__parsedConfig) + if self.__testClient.identifier is None: + self.__testClient.identifier = self.__identifier + setattr(test, "clstestclient", self.__testClient) if hasattr(test, "user"): # when the class-level attr applied. all test runs as 'user' - self.testClient.createUserApiClient(test.UserName, test.DomainName, - test.AcctType) + self.__testClient.getUserApiClient(test.UserName, + test.DomainName, + test.AcctType) + + def finalize(self, result): + try: + src = self.__logFolderPath + if not self.__userLogPath: + log_cfg = self.__parsedConfig.logger + tmp = log_cfg.__dict__.get('LogFolderPath') + "/MarvinLogs" + else: + tmp = self.__userLogPath + "/MarvinLogs" + dst = tmp + "//" + random_gen() + mod_name = "test_suite" + if self.__testModName: + mod_name = self.__testModName.split(".") + if len(mod_name) > 2: + mod_name = mod_name[-2] + if mod_name: + dst = tmp + "/" + mod_name + "_" + random_gen() + cmd = "mv " + src + " " + dst + os.system(cmd) + print "===final results are now copied to: %s===" % str(dst) + except Exception as e: + print "=== Exception occurred under finalize :%s ===" % \ + str(GetDetailExceptionInfo(e)) diff --git a/tools/marvin/marvin/src/__init__.py b/tools/marvin/marvin/src/__init__.py new file mode 100644 index 0000000000..13a83393a9 --- /dev/null +++ b/tools/marvin/marvin/src/__init__.py @@ -0,0 +1,16 @@ +# 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. diff --git a/tools/marvin/marvin/sshClient.py b/tools/marvin/marvin/sshClient.py index fd8726cee3..df2eeee1d4 100644 --- a/tools/marvin/marvin/sshClient.py +++ b/tools/marvin/marvin/sshClient.py @@ -15,30 +15,48 @@ # specific language governing permissions and limitations # under the License. -import paramiko +from paramiko import (BadHostKeyException, + AuthenticationException, + SSHException, + SSHClient, + AutoAddPolicy, + Transport, + SFTPClient) +import socket import time -import cloudstackException +from marvin.cloudstackException import ( + internalError, + GetDetailExceptionInfo +) import contextlib import logging from marvin.codes import ( - SUCCESS, FAIL, INVALID_INPUT, EXCEPTION_OCCURRED - ) -from contextlib import closing + SUCCESS, FAILED, INVALID_INPUT +) class SshClient(object): + ''' - Added timeout flag for ssh connect calls.Default to 3.0 seconds + @Desc : SSH Library for Marvin. + Facilitates SSH,SCP services to marvin users + @Input: host: Host to connect + port: port on host to connect + user: Username to be used for connecting + passwd: Password for connection + retries and delay applies for establishing connection + timeout : Applies while executing command ''' - def __init__(self, host, port, user, passwd, retries=20, delay=30, - log_lvl=logging.INFO, keyPairFiles=None, timeout=10.0): + + def __init__(self, host, port, user, passwd, retries=60, delay=10, + log_lvl=logging.DEBUG, keyPairFiles=None, timeout=10.0): self.host = None self.port = 22 self.user = user self.passwd = passwd self.keyPairFiles = keyPairFiles - self.ssh = paramiko.SSHClient() - self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) + self.ssh = SSHClient() + self.ssh.set_missing_host_key_policy(AutoAddPolicy()) self.logger = logging.getLogger('sshClient') self.retryCnt = 0 self.delay = 0 @@ -47,8 +65,8 @@ def __init__(self, host, port, user, passwd, retries=20, delay=30, ch.setLevel(log_lvl) self.logger.addHandler(ch) - #Check invalid host value and raise exception - #Atleast host is required for connection + # Check invalid host value and raise exception + # Atleast host is required for connection if host is not None and host != '': self.host = host if retries is not None and retries > 0: @@ -57,11 +75,10 @@ def __init__(self, host, port, user, passwd, retries=20, delay=30, self.delay = delay if timeout is not None and timeout > 0: self.timeout = timeout - if port is not None or port >= 0: + if port is not None and port >= 0: self.port = port - if self.createConnection() == FAIL: - raise cloudstackException.\ - internalError("Connection Failed") + if self.createConnection() == FAILED: + raise internalError("SSH Connection Failed") def execute(self, command): stdin, stdout, stderr = self.ssh.exec_command(command) @@ -86,15 +103,16 @@ def createConnection(self): @Desc: Creates an ssh connection for retries mentioned,along with sleep mentioned @Output: SUCCESS on successful connection - FAIL If connection through ssh failed + FAILED If connection through ssh failed ''' - ret = FAIL + ret = FAILED + except_msg = '' while self.retryCnt >= 0: try: - self.logger.debug("SSH Connection: Host:%s User:%s\ - Port:%s" % - (self.host, self.user, str(self.port) - )) + self.logger.debug("====Trying SSH Connection: Host:%s User:%s\ + Port:%s RetryCnt:%s===" % + (self.host, self.user, str(self.port), + str(self.retryCnt))) if self.keyPairFiles is None: self.ssh.connect(hostname=self.host, port=self.port, @@ -102,20 +120,37 @@ def createConnection(self): password=self.passwd, timeout=self.timeout) else: + self.ssh.load_host_keys(self.keyPairFiles) self.ssh.connect(hostname=self.host, port=self.port, username=self.user, password=self.passwd, key_filename=self.keyPairFiles, timeout=self.timeout, - look_for_keys=False + look_for_keys=True ) + self.logger.debug("===SSH to Host %s port : %s SUCCESSFUL===" + % (str(self.host), str(self.port))) ret = SUCCESS break - except Exception as se: - self.retryCnt = self.retryCnt - 1 - if self.retryCnt == 0: + except BadHostKeyException as e: + except_msg = GetDetailExceptionInfo(e) + except AuthenticationException as e: + except_msg = GetDetailExceptionInfo(e) + except SSHException as e: + except_msg = GetDetailExceptionInfo(e) + except socket.error as e: + except_msg = GetDetailExceptionInfo(e) + except Exception as e: + except_msg = GetDetailExceptionInfo(e) + finally: + if self.retryCnt == 0 or ret == SUCCESS: break + if except_msg != '': + self.logger.\ + exception("SshClient: Exception under " + "createConnection: %s" % except_msg) + self.retryCnt -= 1 time.sleep(self.delay) return ret @@ -126,57 +161,54 @@ def runCommand(self, command): returns the result along with status code @Input: command to execute @Output: 1: status of command executed. - Default to None SUCCESS : If command execution is successful - FAIL : If command execution has failed - EXCEPTION_OCCURRED: Exception occurred while executing - command - INVALID_INPUT : If invalid value for command is passed + FAILED : If command execution has failed 2: stdin,stdout,stderr values of command output ''' - excep_msg = '' - ret = {"status": None, "stdin": None, "stdout": None, "stderr": None} + ret = {"status": FAILED, "stdin": None, "stdout": None, + "stderr": INVALID_INPUT} if command is None or command == '': - ret["status"] = INVALID_INPUT return ret try: status_check = 1 - stdin, stdout, stderr = self.ssh.exec_command(command) - output = stdout.readlines() - errors = stderr.readlines() - inp = stdin.readlines() - ret["stdin"] = inp - ret["stdout"] = output - ret["stderr"] = errors + stdin, stdout, stderr = self.ssh.\ + exec_command(command, timeout=self.timeout) if stdout is not None: status_check = stdout.channel.recv_exit_status() - if status_check == 0: - ret["status"] = SUCCESS - else: - ret["status"] = FAIL + if status_check == 0: + ret["status"] = SUCCESS + ret["stdout"] = stdout.readlines() + if stderr is not None: + ret["stderr"] = stderr.readlines() except Exception as e: - excep_msg = str(e) - ret["status"] = EXCEPTION_OCCURRED + ret["stderr"] = GetDetailExceptionInfo(e) + self.logger.exception("SshClient: Exception under runCommand :%s" % + GetDetailExceptionInfo(e)) finally: - self.logger.debug(" Host: %s Cmd: %s Output:%s Exception: %s" % - (self.host, command, str(ret), excep_msg)) + self.logger.debug(" Host: %s Cmd: %s Output:%s" % + (self.host, command, str(ret))) return ret def scp(self, srcFile, destPath): - transport = paramiko.Transport((self.host, int(self.port))) + transport = Transport((self.host, int(self.port))) transport.connect(username=self.user, password=self.passwd) - sftp = paramiko.SFTPClient.from_transport(transport) + sftp = SFTPClient.from_transport(transport) try: sftp.put(srcFile, destPath) - except IOError, e: + except IOError as e: raise e + def __del__(self): + self.close() + def close(self): - if self.ssh is not None: - self.ssh.close() + if self.ssh is not None: + self.ssh.close() + self.ssh = None if __name__ == "__main__": - with contextlib.closing(SshClient("10.223.75.10", 22, "root", - "password")) as ssh: - print ssh.execute("ls -l") + with contextlib.closing(SshClient("127.0.0.1", 22, "root", + "asdf!@34")) as ssh: + ret = ssh.runCommand("ls -l") + print ret diff --git a/tools/marvin/marvin/tcExecuteEngine.py b/tools/marvin/marvin/tcExecuteEngine.py index f959e7e935..e2f4d114b7 100644 --- a/tools/marvin/marvin/tcExecuteEngine.py +++ b/tools/marvin/marvin/tcExecuteEngine.py @@ -23,6 +23,7 @@ class TestCaseExecuteEngine(object): + def __init__(self, testclient, config, tc_logger=None, debug_stream=None): """ Initialize the testcase execution engine, just the basics here @@ -53,7 +54,7 @@ def injectTestCase(self, testSuites): if isinstance(test, unittest.BaseTestSuite): self.injectTestCase(test) else: - #inject testclient and logger into each unittest + # inject testclient and logger into each unittest self.tcRunLogger.name = test.__str__() setattr(test, "testClient", self.testclient) setattr(test, "config", self.config) @@ -61,9 +62,10 @@ def injectTestCase(self, testSuites): setattr(test.__class__, "clstestclient", self.testclient) if hasattr(test, "user"): # attribute when test is entirely executed as user - self.testclient.createUserApiClient(test.UserName, - test.DomainName, - test.AcctType) + self.testclient.\ + getUserApiClient(test.UserName, + test.DomainName, + test.AcctType) def run(self): if self.suite: diff --git a/tools/marvin/marvin/testSetupSuccess.py b/tools/marvin/marvin/testSetupSuccess.py index 1701626a82..8b000f9e97 100644 --- a/tools/marvin/marvin/testSetupSuccess.py +++ b/tools/marvin/marvin/testSetupSuccess.py @@ -23,6 +23,7 @@ class TestSetupSuccess(cloudstackTestCase): + """ Test to verify if the cloudstack is ready to launch tests upon 1. Verify that system VMs are up and running in all zones diff --git a/tools/marvin/setup.py b/tools/marvin/setup.py index 9ce3951fde..b7a927e081 100644 --- a/tools/marvin/setup.py +++ b/tools/marvin/setup.py @@ -6,9 +6,9 @@ # 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 @@ -30,33 +30,37 @@ VERSION = '0.1.0' import os + + def read(fname): return open(os.path.join(os.path.dirname(__file__), fname)).read().strip() setup(name="Marvin", - version=VERSION, - description="Marvin - Python client for Apache CloudStack", - author="Edison Su", - author_email="Edison.Su@citrix.com", - maintainer="Prasanna Santhanam", - maintainer_email="tsp@apache.org", - long_description="Marvin is the Apache CloudStack python client written around the unittest framework", - platforms=("Any",), - url="https://builds.apache.org/job/cloudstack-marvin/", - packages=["marvin", "marvin.cloudstackAPI", "marvin.integration", - "marvin.integration.lib", "marvin.sandbox", - "marvin.sandbox.advanced", "marvin.sandbox.advancedsg", "marvin.sandbox.basic"], - license="LICENSE.txt", - install_requires=[ - "mysql-connector-python", - "requests", - "paramiko", - "nose", - "ddt >= 0.4.0" - ], - py_modules=['marvin.marvinPlugin'], - zip_safe=False, - entry_points={ - 'nose.plugins': ['marvinPlugin = marvin.marvinPlugin:MarvinPlugin'] - }, -) + version=VERSION, + description="Marvin - Python client for Apache CloudStack", + author="Edison Su", + author_email="Edison.Su@citrix.com", + maintainer="Prasanna Santhanam", + maintainer_email="tsp@apache.org", + long_description="Marvin is the Apache CloudStack python " + "client written around the unittest framework", + platforms=("Any",), + url="https://builds.apache.org/job/cloudstack-marvin/", + packages=["marvin", "marvin.cloudstackAPI", + "marvin.lib", "marvin.config", "marvin.sandbox", + "marvin.sandbox.advanced", "marvin.sandbox.advancedsg", + "marvin.sandbox.basic"], + license="LICENSE.txt", + install_requires=[ + "mysql-connector-python >= 1.1.6", + "requests >= 2.2.1", + "paramiko >= 1.13.0", + "nose >= 1.3.3", + "ddt >= 0.4.0" + ], + py_modules=['marvin.marvinPlugin'], + zip_safe=False, + entry_points={ + 'nose.plugins': ['marvinPlugin = marvin.marvinPlugin:MarvinPlugin'] + }, + ) diff --git a/tools/transifex/.tx/config b/tools/transifex/.tx/config index 5e83db3ef0..a2c1e26289 100644 --- a/tools/transifex/.tx/config +++ b/tools/transifex/.tx/config @@ -15,23 +15,14 @@ source_lang = en [CloudStack_UI.42xmessagesproperties] file_filter = translations/CloudStack_UI.42xmessagesproperties/.properties -source_file = work-dir/messages.properties source_lang = en -trans.ar = work-dir/messages_ar.properties -trans.ca = work-dir/messages_ca.properties -trans.de_DE = work-dir/messages_de_DE.properties -trans.es = work-dir/messages_es.properties -trans.fr_FR = work-dir/messages_fr_FR.properties -trans.it_IT = work-dir/messages_it_IT.properties -trans.ja = work-dir/messages_ja.properties -trans.ko_KR = work-dir/messages_ko_KR.properties -trans.nb_NO = work-dir/messages_nb_NO.properties -trans.pt_BR = work-dir/messages_pt_BR.properties -trans.ru_RU = work-dir/messages_ru_RU.properties -trans.zh_CN = work-dir/messages_zh_CN.properties [CloudStack_UI.43xmessagesproperties] -source_file = work-dir/messages.properties +file_filter = translations/CloudStack_UI.43xmessagesproperties/.properties +source_lang = en + +[CloudStack_UI.44xmessagesproperties] +file_filter = translations/CloudStack_UI.44xmessagesproperties/.properties source_lang = en trans.ar = work-dir/messages_ar.properties trans.ca = work-dir/messages_ca.properties diff --git a/ui/css/cloudstack3.css b/ui/css/cloudstack3.css index 2b88e03366..17441c49a1 100644 --- a/ui/css/cloudstack3.css +++ b/ui/css/cloudstack3.css @@ -173,6 +173,13 @@ table tbody td.truncated > span { text-overflow: ellipsis; } +.list-view-select table th.name, +.list-view-select table td.name { + width: 170px; + min-width: 170px; + max-width: 170px; +} + /** Multiselect*/ table thead th.multiselect, table tbody td.multiselect { @@ -210,6 +217,23 @@ table tbody td.actions input { margin: 11px 0 0px; } +.list-view-select table tbody td.actions { + width: 40px !important; + min-width: 40px !important; + max-width: 40px !important; +} + +.list-view-select table tbody td.actions input { + margin: 0 0 0 -7px; +} + +.list-view-select table thead th.actions { + width: 40px !important; + min-width: 40px !important; + max-width: 40px !important; + text-indent: 5px; +} + /** Quick view table cell*/ table tbody td.quick-view, table thead th.quick-view { @@ -1293,6 +1317,10 @@ div.panel div.list-view div.fixed-header { background: #FFFFFF; } +.detail-view div#details-tab-zones div.fixed-header { + left: 25px !important; +} + .detail-view div.list-view div.fixed-header table { width: 100% !important; } @@ -1333,7 +1361,7 @@ div.list-view td.first { cursor: pointer; } -div.list-view td.first:hover { +div.list-view tr:not(.multi-edit-selected) td.first:hover { color: #3A82CD; } @@ -1836,6 +1864,58 @@ div.list-view td.state.off span { width: 245px; } +.detail-group .main-groups table td.value > span.copypasteenabledvalue { + text-overflow: ellipsis; + -o-text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; +} + +.detail-group .main-groups table td.value > .copypasteactive { + display: auto; + white-space: nowrap; + overflow: none; +} + +div.copypasteicon { + background: url("../images/sprites.png") no-repeat -271px -65px; + float: left; + height: 21px; + margin-left: 6px; + margin-top: 0px; + width: 18px; +} + +div.copypasteicon:hover { + background: url("../images/sprites.png") no-repeat -271px -646px; +} + +.detail-group .main-groups table td.value > span.copypasteenabledvalue { + text-overflow: ellipsis; + -o-text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; +} + +.detail-group .main-groups table td.value > .copypasteactive { + display: auto; + white-space: nowrap; + overflow: none; +} + +div.copypasteicon { + background: url("../images/sprites.png") no-repeat -271px -65px; + float: left; + height: 21px; + margin-left: 6px; + margin-top: 0px; + width: 18px; +} + +div.copypasteicon:hover { + background: url("../images/sprites.png") no-repeat -271px -646px; +} + .detail-group .main-groups table td.value > span select { width: 100% !important; } @@ -1926,6 +2006,11 @@ div.list-view td.state.off span { margin: 4px 0 0 12px; } +.list-view .subselect span.info { + font-size: 10px; + white-space: nowrap; +} + .list-view .subselect select { width: 85%; margin: 5px 0 4px; @@ -3893,7 +3978,7 @@ Dialogs*/ } .ui-dialog.confirm .ui-dialog-title { - background: url(../images/icons.png) no-repeat 0px -225px; + background: url(../images/icons.png) no-repeat 0px -224px; } .ui-dialog.create-form .ui-dialog-title { @@ -5988,7 +6073,7 @@ label.error { } .multi-wizard.instance-wizard .data-disk-offering .select-container { - height: 280px; + height: 300px; margin: -7px 6px 0 8px; /*+border-radius:6px;*/ -moz-border-radius: 6px; @@ -5998,6 +6083,94 @@ label.error { border-radius: 6px 6px 6px 6px; } +.multi-wizard.instance-wizard .data-disk-offering .disk-select-group { + float: left; + margin-top: 12px; + width: 100%; +} + +.multi-wizard.instance-wizard .data-disk-offering .disk-select-header { + border-bottom: 1px solid #D4D4D4; + /*+border-radius:4px;*/ + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + -khtml-border-radius: 4px; + border-radius: 4px; + background: #C2C2C2 0px 4px; + padding: 6px; + height: 17px; +} + +.multi-wizard.instance-wizard .disk-select-group.selected .disk-select-header { + background: #505050; + /*+border-radius:4px 4px 0 0;*/ + -moz-border-radius: 4px 4px 0 0; + -webkit-border-radius: 4px 4px 0 0; + -khtml-border-radius: 4px 4px 0 0; + border-radius: 4px 4px 0 0; +} + +.multi-wizard.instance-wizard .data-disk-offering .disk-select-header input { + float: left; +} + +.multi-wizard.instance-wizard .data-disk-offering .disk-select-header .title { + float: left; + font-size: 14px; + padding: 2px; +} + +.multi-wizard.instance-wizard .disk-select-group.selected .disk-select-header .title { + color: #FFFFFF; + /*+text-shadow:0px -1px #000000;*/ + -moz-text-shadow: 0px -1px #000000; + -webkit-text-shadow: 0px -1px #000000; + -o-text-shadow: 0px -1px #000000; + text-shadow: 0px -1px #000000; +} + +.multi-wizard.instance-wizard .data-disk-offering .multi-disk-select-container { + max-height: 257px; + overflow: auto; + border: 1px solid #DDDBDB; + padding: 13px; + background: #E4E4E4; +} + +.multi-wizard.instance-wizard .data-disk-offering .disk-select-group .select-container { + max-height: 114px; + float: left; + margin: 0; + border: none; + /*+border-radius:0;*/ + -moz-border-radius: 0; + -webkit-border-radius: 0; + -khtml-border-radius: 0; + border-radius: 0; + display: none; +} + +.multi-wizard.instance-wizard .data-disk-offering .disk-select-group.selected .select-container { + display: block; +} + +.multi-wizard.instance-wizard .data-disk-offering .disk-select-group .select { + padding: 0 0 17px; + height: 0; +} + +.multi-wizard.instance-wizard .data-disk-offering .disk-select-group.custom-size .section.custom-size { + display: block !important; +} + +.multi-wizard.instance-wizard .data-disk-offering .disk-select-group .select input { + margin: 13px 12px 12px; +} + +.multi-wizard.instance-wizard .data-disk-offering .disk-select-group .select-desc { + margin: 13px 0 0; +} + .multi-wizard.instance-wizard .data-disk-offering.required .select-container { height: 344px; position: relative; @@ -6057,6 +6230,13 @@ label.error { border-radius: 4px; } +.multi-wizard.instance-wizard .section.custom-iops-do { + position: relative; + background: #F4F4F4; + padding: 7px; + border-radius: 4px; +} + .multi-wizard.instance-wizard .section.custom-size input[type=radio] { float: left; } @@ -6073,6 +6253,12 @@ label.error { margin: 6px -1px 0 8px; } +.multi-wizard.instance-wizard .section.custom-iops-do input[type=text] { + float: left; + width: 28px; + margin: 6px -1px 0 8px; +} + .multi-wizard.instance-wizard .section.custom-size label.error { position: absolute; top: 29px; @@ -6080,6 +6266,53 @@ label.error { font-size: 10px; } +.instance-wizard .step.data-disk-offering.custom-disk-size .select-container { + height: 272px; +} + +.instance-wizard .step.data-disk-offering.custom-iops-do .select-container { + height: 240px; +} + +.instance-wizard .step.data-disk-offering.custom-disk-size.custom-iops-do .select-container { + height: 176px; +} + +.instance-wizard .step.data-disk-offering.required.custom-disk-size .select-container { + height: 315px; +} + +.instance-wizard .step.data-disk-offering.required.custom-iops-do .select-container { + height: 295px; +} + +.instance-wizard .step.data-disk-offering.required.custom-disk-size.custom-iops-do .select-container { + height: 223px; +} + +.instance-wizard .step.data-disk-offering .custom-iops-do { + display: none; +} + +.instance-wizard .step.data-disk-offering.custom-iops-do .custom-iops-do { + display: block; +} + +.instance-wizard .step.data-disk-offering .custom-iops-do .field { + width: 30%; + float: left; + margin-bottom: 5px; +} + +.instance-wizard .step.data-disk-offering .custom-iops-do .field label { + text-indent: 20px; +} + +.instance-wizard .step.data-disk-offering .custom-iops-do .field input { + width: 88%; + margin-left: 26px; +} + /*** Compute offering*/ .instance-wizard .step.service-offering { } @@ -7739,28 +7972,42 @@ div.panel.ui-dialog div.list-view div.fixed-header { /*List-view: subselect dropdown*/ .list-view .subselect { - width: 116px; + width: 173px; + cursor: default; display: block; float: left; - background: url(../images/bg-gradients.png) 0px -42px; + background: #E8E8E8; padding: 0; - margin: 8px 0 1px 7px; + margin: 0 0 0 -3px; clear: both; border: 1px solid #A8A7A7; - /*+border-radius:4px;*/ - -moz-border-radius: 4px; - -webkit-border-radius: 4px; - -khtml-border-radius: 4px; - border-radius: 4px; + /*+border-radius:2px;*/ + -moz-border-radius: 2px; + -webkit-border-radius: 2px; + -khtml-border-radius: 2px; + border-radius: 2px; +} + +.list-view .subselect:hover span { + color: initial; } .list-view .subselect span { margin: 4px 0 0 12px; + cursor: default; +} + +.list-view .subselect span.info { + background: none; +} + +.list-view .subselect span:hover { + color: initial; } .list-view .subselect select { - width: 85%; - margin: 5px 0 4px; + width: 175px; + margin: 0 0 0 -11px; font-size: 10px; } @@ -12374,11 +12621,13 @@ div.ui-dialog div.autoscaler div.field-group div.form-container form div.form-it } .restoreVM .icon, -.restore .icon { +.restore .icon, +.recover .icon { background-position: -168px -31px; } -.reset .icon { +.reset .icon, +.reinstall .icon { background-position: -168px -31px; } @@ -12687,3 +12936,50 @@ div.ui-dialog div.autoscaler div.field-group div.form-container form div.form-it display: inline-block; } +/*GPU*/ +div.gpugroups div.list-view div.fixed-header { + position: relative; + left: 12px !important; + top: 0px !important; +} + +div.gpugroups div.list-view div.fixed-header table { + width: auto; +} + +div.gpugroups div.list-view div.data-table table { + margin-top: 0; +} + +div.gpugroups div.list-view { + position: relative; + height: auto !important; + margin-top: 0 !important; + border: none !important; +} + +.gpugroups { + float: left; + height: 100%; + width: 100%; + overflow-x: hidden; + overflow-y: auto; +} + +.gpugroups .gpugroup-container { + border: 1px solid #C8C2C2; + border-radius: 3px; + height: auto !important; + margin: 12px; + padding: 0; + position: relative; + float: left; + width: auto; +} + +.gpugroups .gpugroup-container .title { + font-size: 13px; + font-weight: 100; + padding: 12px 12px 5px; +} + diff --git a/ui/dictionary.jsp b/ui/dictionary.jsp index 074db7f061..b668bb5645 100644 --- a/ui/dictionary.jsp +++ b/ui/dictionary.jsp @@ -25,6 +25,12 @@ under the License. <% long now = System.currentTimeMillis(); %> diff --git a/ui/images/sprites.png b/ui/images/sprites.png old mode 100644 new mode 100755 index ab396700f3..1a6eaa577f Binary files a/ui/images/sprites.png and b/ui/images/sprites.png differ diff --git a/ui/index.jsp b/ui/index.jsp index d46c395cd8..5840e7171d 100644 --- a/ui/index.jsp +++ b/ui/index.jsp @@ -206,6 +206,7 @@

@@ -1065,7 +1077,7 @@
-
+
 
diff --git a/ui/scripts/accounts.js b/ui/scripts/accounts.js index aff780ef48..2ebfe82c42 100644 --- a/ui/scripts/accounts.js +++ b/ui/scripts/accounts.js @@ -17,8 +17,7 @@ (function(cloudStack) { var domainObjs; - var rootDomainId; - + cloudStack.sections.accounts = { title: 'label.accounts', id: 'accounts', @@ -97,6 +96,7 @@ label: 'Add LDAP Account', isHeader: true, preFilter: function(args) { + //if ((isAdmin() || isDomainAdmin()) && true) { //for testing only if ((isAdmin() || isDomainAdmin()) && isLdapEnabled()) { return true; } else { @@ -1374,12 +1374,6 @@ state: { label: 'label.state' }, - apikey: { - label: 'label.api.key' - }, - secretkey: { - label: 'label.secret.key' - }, account: { label: 'label.account.name' }, @@ -1392,6 +1386,14 @@ domain: { label: 'label.domain' }, + apikey: { + label: 'label.api.key', + isCopyPaste: true + }, + secretkey: { + label: 'label.secret.key', + isCopyPaste: true + }, email: { label: 'label.email', isEditable: true, @@ -1525,19 +1527,21 @@ allowedActions.push("enable"); allowedActions.push("remove"); } - } else { - if (isSelfOrChildDomainUser(jsonObj.username, jsonObj.accounttype, jsonObj.domainid, jsonObj.iscallerchilddomain)) { - if (isDomainAdmin() && jsonObj.username != g_username) { - allowedActions.push("edit"); - if (jsonObj.state == "enabled") - allowedActions.push("disable"); - if (jsonObj.state == "disabled") - allowedActions.push("enable"); - allowedActions.push("remove"); - } + } else { //domain-admin, regular-user + if (jsonObj.username == g_username) { //selected user is self + allowedActions.push("changePassword"); + allowedActions.push("generateKeys"); + } else if (isDomainAdmin()) { //if selected user is not self, and the current login is domain-admin + allowedActions.push("edit"); + if (jsonObj.state == "enabled") + allowedActions.push("disable"); + if (jsonObj.state == "disabled") + allowedActions.push("enable"); + allowedActions.push("remove"); + allowedActions.push("changePassword"); allowedActions.push("generateKeys"); - } + } } return allowedActions; } diff --git a/ui/scripts/accountsWizard.js b/ui/scripts/accountsWizard.js index 6b4907c1cb..f022193270 100644 --- a/ui/scripts/accountsWizard.js +++ b/ui/scripts/accountsWizard.js @@ -16,6 +16,8 @@ // under the License. (function(cloudStack, $) { + var rootDomainId; + cloudStack.accountsWizard = { informationWithinLdap: { @@ -75,20 +77,9 @@ validation: { required: true }, - select: function(args) { - var data = {}; - - if (args.context.users) { // In accounts section - data.listAll = true; - } else if (args.context.domains) { // In domain section (use specific domain) - data.id = args.context.domains[0].id; - } - + select: function(args) { $.ajax({ - url: createURL("listDomains"), - data: data, - dataType: "json", - async: false, + url: createURL("listDomains"), success: function(json) { var items = []; domainObjs = json.listdomainsresponse.domain; @@ -191,6 +182,8 @@ password = args.data.password; if (md5Hashed) { password = $.md5(password); + } else { + password = todb(password); } array1.push("&password=" + password); } @@ -198,14 +191,16 @@ array1.push("&domainid=" + args.data.domainid); var account = args.data.account; - if (account === null || account.length === 0) { - account = args.username; + + if (account !== null && account.length > 0) { + array1.push("&account=" + account); } - array1.push("&account=" + account); var accountType = args.data.accounttype; - if (args.data.accounttype == "1" && args.data.domainid != rootDomainId) { //if account type is admin, but domain is not Root domain - accountType = "2"; // Change accounttype from root-domain("1") to domain-admin("2") + if (accountType == "1") { //if "admin" is selected in account type dropdown + if (rootDomainId == undefined || args.data.domainid != rootDomainId ) { //but current login has no visibility to root domain object, or the selected domain is not root domain + accountType = "2"; // change accountType from root-domain("1") to domain-admin("2") + } } array1.push("&accounttype=" + accountType); @@ -225,6 +220,7 @@ $.ajax({ url: createURL('importLdapUsers' + array1.join("")), dataType: "json", + type: "POST", async: false, success: function(json) { var count = json.ldapuserresponse.count; @@ -240,6 +236,7 @@ $.ajax({ url: createURL('ldapCreateAccount' + array1.join("")), dataType: "json", + type: "POST", async: false, success: function(json) { var item = json.createaccountresponse.account; @@ -256,6 +253,7 @@ $.ajax({ url: createURL('createAccount' + array1.join("")), dataType: "json", + type: "POST", async: false, success: function(json) { var item = json.createaccountresponse.account; @@ -268,48 +266,6 @@ } }); } - } - /* - action: function(args) { - var array1 = []; - - var username = args.data.username; - - array1.push("&domainid=" + args.data.domainid); - - if (args.data.account != null && args.data.account.length != 0) { - array1.push("&account=" + args.data.account); - } - - if (args.data.accounttype == "1" && args.data.domainid != rootDomainId) { - args.data.accounttype = "2"; - } - array1.push("&accountType=" + args.data.accounttype); - - if (args.data.timezone != null && args.data.timezone.length != 0) { - array1.push("&timezone=" + args.data.timezone); - } - if (args.data.networkdomain != null && args.data.networkdomain != 0) { - array1.push("&networkDomain=" + args.data.networkdomain); - } - - for (var i = 0; i < username.length; i++) { - $.ajax({ - url: createURL("ldapCreateAccount&username=" + username[i] + array1.join("")), - dataType: "json", - async: false, - success: function(json) { - var item = json.createaccountresponse.account; - args.response.success({ - data: item - }); - }, - error: function(XMLHttpResponse) { - args.response.error(parseXMLHttpResponse(XMLHttpResponse)); - } - }); - } - } - */ + } }; }(cloudStack, jQuery)); \ No newline at end of file diff --git a/ui/scripts/cloudStack.js b/ui/scripts/cloudStack.js index be7692de09..2285276272 100644 --- a/ui/scripts/cloudStack.js +++ b/ui/scripts/cloudStack.js @@ -489,6 +489,6 @@ }; } - document.title = _l('label.app.name'); + document.title = _l('label.app.name'); }); })(cloudStack, jQuery); diff --git a/ui/scripts/configuration.js b/ui/scripts/configuration.js index 7b2f4e9219..f56f4e2a2b 100644 --- a/ui/scripts/configuration.js +++ b/ui/scripts/configuration.js @@ -331,8 +331,15 @@ args.response.success({ data: items }); - - + args.$select.change(function() { + var $form = $(this).closest('form'); + var $fields = $form.find('.field'); + if ($(this).val() == "ImplicitDedicationPlanner") { + $form.find('[rel=plannerMode]').css('display', 'block'); + } else { + $form.find('[rel=plannerMode]').hide(); + } + }); } }); } @@ -362,7 +369,7 @@ }, pciDevice: { - label: 'GPU Type', + label: 'GPU', select: function(args) { var items = []; items.push({ @@ -370,40 +377,71 @@ description: '' }); items.push({ - id: 'GPU_Passthrough', - description: 'GPU-Passthrough' + id: 'Group of NVIDIA Corporation GK107GL [GRID K1] GPUs', + description: 'NVIDIA GRID K1' }); items.push({ - id: 'VGPU', - description: 'VGPU' + id: 'Group of NVIDIA Corporation GK104GL [GRID K2] GPUs', + description: 'NVIDIA GRID K2' }); args.response.success({ data: items }); + + var vGpuMap = {}; + vGpuMap['Group of NVIDIA Corporation GK107GL [GRID K1] GPUs'] = ['passthrough', 'GRID K100', 'GRID K120Q', 'GRID K140Q']; + vGpuMap['Group of NVIDIA Corporation GK104GL [GRID K2] GPUs'] = ['passthrough', 'GRID K200', 'GRID K220Q', 'GRID K240Q', 'GRID K260Q']; + args.$select.change(function() { - var $form = $(this).closest('form'); - var $fields = $form.find('.field'); - if (($(this).val() == "") || $(this).val() == "GPU-Passthrough") { - $form.find('[rel=vgpuType]').hide(); - } else if ($(this).val() == "VGPU") { - $form.find('[rel=vgpuType]').css('display', 'block'); + var gpu = $(this).val(); + + if (gpu == '') { + $(this).closest('form').find('.form-item[rel=\"vgpuType\"]').hide(); + } + else { + $(this).closest('form').find('.form-item[rel=\"vgpuType\"]').css('display', 'inline-block'); + + // enable/disable vGPU type options, depending on selected GPU + var $vGpuTypeSelect = $(this).closest('form').find('select[name=vgpuType]'); + var $vGpuTypeOptions = $vGpuTypeSelect.find('option'); + $vGpuTypeOptions.each(function(index) { + var vGpuTypeOption = $(this).val(); + if (vGpuTypeOption == '' || (gpu in vGpuMap && $.inArray(vGpuTypeOption, vGpuMap[gpu]) > -1)) + $(this).attr('disabled', false); + else + $(this).attr('disabled', true); + }); + + //if selected option is disabled, select the first enabled option instead + if ($vGpuTypeSelect.find('option:selected:disabled').length > 0) { + $vGpuTypeSelect.val($vGpuTypeSelect.find('option:enabled:first').val()); + } } }); } }, vgpuType: { - label: 'VGPU Type', + label: 'vGPU Type', + isHidden: true, select: function(args) { var items = []; items.push({ id: '', description: '' }); + items.push({ + id: 'passthrough', + description: 'passthrough' + }); items.push({ id: 'GRID K100', description: 'GRID K100' }); + items.push({ + id: 'GRID K120Q', + description: 'GRID K120Q' + }); items.push({ id: 'GRID K140Q', description: 'GRID K140Q' @@ -412,6 +450,10 @@ id: 'GRID K200', description: 'GRID K200' }); + items.push({ + id: 'GRID K220Q', + description: 'GRID K220Q' + }); items.push({ id: 'GRID K240Q', description: 'GRID K240Q' @@ -465,21 +507,17 @@ }; //custom fields (begin) - if (args.$form.find('.form-item[rel=cpuNumber]').css("display") != "none") { + if (args.data.isCustomized != "on") { $.extend(data, { - cpuNumber: args.data.cpuNumber + cpuNumber: args.data.cpuNumber }); - } - if (args.$form.find('.form-item[rel=cpuSpeed]').css("display") != "none") { $.extend(data, { - cpuSpeed: args.data.cpuSpeed + cpuSpeed: args.data.cpuSpeed }); - } - if (args.$form.find('.form-item[rel=memory]').css("display") != "none") { $.extend(data, { - memory: args.data.memory + memory: args.data.memory }); - } + } //custom fields (end) if (args.data.deploymentPlanner != null && args.data.deploymentPlanner.length > 0) { @@ -499,7 +537,7 @@ array1.push("&serviceofferingdetails[1].value" + "=" + args.data.pciDevice); } - if (args.data.pciDevice == "VGPU") { + if (args.data.vgpuType != "") { array1.push("&serviceofferingdetails[2].key" + "=" + "vgpuType"); array1.push("&serviceofferingdetails[2].value" + "=" + args.data.vgpuType); } @@ -586,7 +624,7 @@ isvolatile: (args.data.isVolatile == "on") }); - if (args.$form.find('.form-item[rel=domainId]').css("display") != "none") { + if (args.data.isPublic != "on") { $.extend(data, { domainid: args.data.domainId }); @@ -738,9 +776,9 @@ memory: { label: 'label.memory.mb', converter: function(args) { - if (args == undefined) - return ''; - else + if (args == undefined) + return ''; + else return cloudStack.converters.convertBytes(args * 1024 * 1024); } }, @@ -808,6 +846,12 @@ plannerMode: { label: 'Planner Mode' }, + pciDevice: { + label: 'GPU' + }, + vgpuType: { + label: 'vGPU type' + }, tags: { label: 'label.storage.tags' }, @@ -836,11 +880,16 @@ var item = json.listserviceofferingsresponse.serviceoffering[0]; if (item.deploymentplanner != null && item.serviceofferingdetails != null) { - if (item.deploymentplanner == 'ImplicitDedicationPlanner' && item.serviceofferingdetails.ImplicitDedicationMode != null) { - item.plannerMode = item.serviceofferingdetails.ImplicitDedicationMode; - } + if (item.deploymentplanner == 'ImplicitDedicationPlanner' && item.serviceofferingdetails.ImplicitDedicationMode != null) { + item.plannerMode = item.serviceofferingdetails.ImplicitDedicationMode; + } } + if (item.serviceofferingdetails != null) { + item.pciDevice = item.serviceofferingdetails.pciDevice; + item.vgpuType = item.serviceofferingdetails.vgpuType; + } + args.response.success({ actionFitler: serviceOfferingActionfilter, data: item @@ -1120,7 +1169,7 @@ limitcpuuse: (args.data.cpuCap == "on") }); - if (args.$form.find('.form-item[rel=domainId]').css("display") != "none") { + if (args.data.isPublic != "on") { $.extend(data, { domainid: args.data.domainId }); @@ -1288,9 +1337,9 @@ memory: { label: 'label.memory.mb', converter: function(args) { - if (args == undefined) - return ''; - else + if (args == undefined) + return ''; + else return cloudStack.converters.convertBytes(args * 1024 * 1024); } }, @@ -1679,7 +1728,7 @@ customized: (args.data.isCustomized == "on") }; - if (args.$form.find('.form-item[rel=disksize]').css("display") != "none") { + if (args.data.isCustomized != "on") { $.extend(data, { disksize: args.data.disksize }); @@ -1743,7 +1792,7 @@ }); } - if (args.$form.find('.form-item[rel=domainId]').css("display") != "none") { + if (args.data.isPublic != "on") { $.extend(data, { domainid: args.data.domainId }); @@ -2006,6 +2055,7 @@ var $lbType = args.$form.find('.form-item[rel=lbType]'); var $serviceofferingid = args.$form.find('.form-item[rel=serviceofferingid]'); var $conservemode = args.$form.find('.form-item[rel=conservemode]'); + var $supportsstrechedl2subnet = args.$form.find('.form-item[rel=supportsstrechedl2subnet]'); var $serviceSourceNatRedundantRouterCapabilityCheckbox = args.$form.find('.form-item[rel="service.SourceNat.redundantRouterCapabilityCheckbox"]'); var hasAdvancedZones = false; @@ -2043,7 +2093,7 @@ } else { //Isolated network offering $useVpc.css('display', 'inline-block'); } - var $providers = $useVpcCb.closest('form').find('.dynamic-input select'); + var $providers = $useVpcCb.closest('form').find('.dynamic-input select[name!="service.Connectivity.provider"]'); var $optionsOfProviders = $providers.find('option'); //p.s. Netscaler is supported in both vpc and non-vpc if ($useVpc.is(':visible') && $useVpcCb.is(':checked')) { //*** vpc *** @@ -2153,7 +2203,7 @@ /* - when service(s) has VPC Virtual Router as provider: + when service(s) has VPC Virtual Router as provider: (1) conserve mode is set to unchecked and grayed out. (2) redundant router capability checkbox is set to unchecked and grayed out. (3) remove Firewall service, SecurityGroup service. @@ -2185,43 +2235,43 @@ //CS-16612 show all services regardless of guestIpType(Shared/Isolated) /* - //hide/show service fields ***** (begin) ***** - var serviceFieldsToHide = []; - if($guestTypeField.val() == 'Shared') { //Shared network offering - serviceFieldsToHide = [ - 'service.SourceNat.isEnabled', - 'service.PortForwarding.isEnabled', - 'service.Firewall.isEnabled', - 'service.Vpn.isEnabled' - ]; - if(havingVpcVirtualRouterForAtLeastOneService == true) { //add SecurityGroup to to-hide-list - serviceFieldsToHide.push('service.SecurityGroup.isEnabled'); - } - else { //remove SecurityGroup from to-hide-list - var temp = $.map(serviceFieldsToHide, function(item) { - if (item != 'service.SecurityGroup.isEnabled') { - return item; - } - }); - serviceFieldsToHide = temp; - } - } - else { //Isolated network offering - serviceFieldsToHide = [ - 'service.SecurityGroup.isEnabled' - ]; - if(havingVpcVirtualRouterForAtLeastOneService == true) { //add firewall to to-hide-list - serviceFieldsToHide.push('service.Firewall.isEnabled'); - } - else { //remove firewall from to-hide-list - var temp = $.map(serviceFieldsToHide, function(item) { - if (item != 'service.Firewall.isEnabled') { - return item; - } - }); - serviceFieldsToHide = temp; - } - } + //hide/show service fields ***** (begin) ***** + var serviceFieldsToHide = []; + if($guestTypeField.val() == 'Shared') { //Shared network offering + serviceFieldsToHide = [ + 'service.SourceNat.isEnabled', + 'service.PortForwarding.isEnabled', + 'service.Firewall.isEnabled', + 'service.Vpn.isEnabled' + ]; + if(havingVpcVirtualRouterForAtLeastOneService == true) { //add SecurityGroup to to-hide-list + serviceFieldsToHide.push('service.SecurityGroup.isEnabled'); + } + else { //remove SecurityGroup from to-hide-list + var temp = $.map(serviceFieldsToHide, function(item) { + if (item != 'service.SecurityGroup.isEnabled') { + return item; + } + }); + serviceFieldsToHide = temp; + } + } + else { //Isolated network offering + serviceFieldsToHide = [ + 'service.SecurityGroup.isEnabled' + ]; + if(havingVpcVirtualRouterForAtLeastOneService == true) { //add firewall to to-hide-list + serviceFieldsToHide.push('service.Firewall.isEnabled'); + } + else { //remove firewall from to-hide-list + var temp = $.map(serviceFieldsToHide, function(item) { + if (item != 'service.Firewall.isEnabled') { + return item; + } + }); + serviceFieldsToHide = temp; + } + } */ @@ -2274,9 +2324,9 @@ } if (args.$form.find('.form-item[rel=\"service.Firewall.isEnabled\"] input[type=checkbox]').is(':checked') == true) { - args.$form.find('.form-item[rel=\"egresspolicy\"]').css('display', 'inline-block'); + args.$form.find('.form-item[rel=\"egressdefaultpolicy\"]').css('display', 'inline-block'); } else { - args.$form.find('.form-item[rel=\"egresspolicy\"]').css('display', 'none'); + 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 @@ -2309,6 +2359,13 @@ args.$form.find('.form-item[rel=\"service.StaticNat.associatePublicIP\"]').hide(); args.$form.find('.form-item[rel=\"service.StaticNat.associatePublicIP\"]').find('input[type=checkbox]').attr('checked', false); } + + //StretchedL2Subnet checkbox should be displayed only when 'Connectivity' service is checked + if (args.$form.find('.form-item[rel=\"service.Connectivity.isEnabled\"]').find('input[type=checkbox]').is(':checked')) { + $supportsstrechedl2subnet.css('display', 'inline-block'); + } else { + $supportsstrechedl2subnet.hide(); + } }); args.$form.change(); @@ -2346,7 +2403,7 @@ }); } }, - */ + */ guestIpType: { label: 'label.guest.type', @@ -2682,10 +2739,17 @@ }, //show or hide upon checked services and selected providers above (end) + supportsstrechedl2subnet: { + label: 'label.supportsstrechedl2subnet', + isBoolean: true, + isChecked: false, + isHidden: true + }, conservemode: { label: 'label.conserve.mode', isBoolean: true, + isChecked: true, docID: 'helpNetworkOfferingConserveMode' }, @@ -2710,7 +2774,7 @@ } }, - egresspolicy: { + egressdefaultpolicy: { label: 'label.default.egress.policy', isHidden: true, select: function(args) { @@ -2784,15 +2848,17 @@ inputData['servicecapabilitylist[' + serviceCapabilityIndex + '].capabilitytype'] = 'lbSchemes'; inputData['servicecapabilitylist[' + serviceCapabilityIndex + '].capabilityvalue'] = 'internal'; serviceCapabilityIndex++; - } - } else if (value != '') { // Normal data - inputData[key] = value; + } + } else if (value != '') { // normal data (serviceData.length ==1), e.g. "name", "displayText", "networkRate", "guestIpType", "lbType" (unwanted), "availability" (unwated when value is "Optional"), "egressdefaultpolicy", "state" (unwanted), "status" (unwanted), "allocationstate" (unwanted) + if (!(key == "lbType" || (key == "availability" && value == "Optional") || key == "state" || key == "status" || key == "allocationstate" || key == "useVpc" )) { + inputData[key] = value; + } } }); for (var key1 in inputData) { /* When capability ElasticIp=true is passed to API, if capability associatePublicIP is not passed to API, cloudStack API will assume associatePublicIP=true. - So, UI has to explicitly pass associatePublicIP=false to API if its checkbox is unchecked. */ + So, UI has to explicitly pass associatePublicIP=false to API if its checkbox is unchecked. */ if (inputData[key1] == 'ElasticIp') { //ElasticIp checkbox is checked var associatePublicIPExists = false; for (var key2 in inputData) { @@ -2806,11 +2872,25 @@ inputData['servicecapabilitylist[' + serviceCapabilityIndex + '].service'] = 'StaticNat'; inputData['servicecapabilitylist[' + serviceCapabilityIndex + '].capabilitytype'] = 'associatePublicIP'; inputData['servicecapabilitylist[' + serviceCapabilityIndex + '].capabilityvalue'] = false; //associatePublicIP checkbox is unchecked + serviceCapabilityIndex++; } break; //break key1 for loop } } + //passing supportsstrechedl2subnet's value as capability + for (var k in inputData) { + if (k == 'supportsstrechedl2subnet' && ("Connectivity" in serviceProviderMap)) { + inputData['servicecapabilitylist[' + serviceCapabilityIndex + '].service'] = 'Connectivity'; + inputData['servicecapabilitylist[' + serviceCapabilityIndex + '].capabilitytype'] = 'StretchedL2Subnet'; + inputData['servicecapabilitylist[' + serviceCapabilityIndex + '].capabilityvalue'] = true; + serviceCapabilityIndex++; + break; + } + } + //removing supportsstrechedl2subnet from parameters, it has been set as capability + delete inputData['supportsstrechedl2subnet']; + // Make supported services list inputData['supportedServices'] = $.map(serviceProviderMap, function(value, key) { return key; @@ -2819,28 +2899,28 @@ if (inputData['guestIpType'] == "Shared") { //specifyVlan checkbox is disabled, so inputData won't include specifyVlan inputData['specifyVlan'] = true; //hardcode inputData['specifyVlan'] - inputData['specifyIpRanges'] = true; - inputData['isPersistent'] = false; + inputData['specifyIpRanges'] = true; + delete inputData.isPersistent; //if Persistent checkbox is unchecked, do not pass isPersistent parameter to API call since we need to keep API call's size as small as possible (p.s. isPersistent is defaulted as false at server-side) } else if (inputData['guestIpType'] == "Isolated") { //specifyVlan checkbox is shown - inputData['specifyIpRanges'] = false; - + //inputData['specifyIpRanges'] = false; + delete inputData.specifyIpRanges; //if specifyIpRanges should be false, do not pass specifyIpRanges parameter to API call since we need to keep API call's size as small as possible (p.s. specifyIpRanges is defaulted as false at server-side) + if (inputData['specifyVlan'] == 'on') { //specifyVlan checkbox is checked inputData['specifyVlan'] = true; - } else { //specifyVlan checkbox is unchecked - inputData['specifyVlan'] = false; - + } else { //specifyVlan checkbox is unchecked + delete inputData.specifyVlan; //if specifyVlan checkbox is unchecked, do not pass specifyVlan parameter to API call since we need to keep API call's size as small as possible (p.s. specifyVlan is defaulted as false at server-side) } if (inputData['isPersistent'] == 'on') { //It is a persistent network inputData['isPersistent'] = true; } else { //Isolated Network with Non-persistent network - inputData['isPersistent'] = false; + delete inputData.isPersistent; //if Persistent checkbox is unchecked, do not pass isPersistent parameter to API call since we need to keep API call's size as small as possible (p.s. isPersistent is defaulted as false at server-side) } } if (inputData['conservemode'] == 'on') { - inputData['conservemode'] = true; + delete inputData.conservemode; //if ConserveMode checkbox is checked, do not pass conservemode parameter to API call since we need to keep API call's size as small as possible (p.s. conservemode is defaulted as true at server-side) } else { inputData['conservemode'] = false; } @@ -2852,14 +2932,15 @@ inputData['serviceProviderList[' + serviceProviderIndex + '].provider'] = value; serviceProviderIndex++; }); - - if (args.$form.find('.form-item[rel=availability]').css("display") == "none") - inputData['availability'] = 'Optional'; - - if (args.$form.find('.form-item[rel=egresspolicy]').is(':visible')) { - inputData['egressdefaultpolicy'] = formData.egresspolicy === 'ALLOW' ? true : false; + + if (args.$form.find('.form-item[rel=egressdefaultpolicy]').is(':visible')) { + if (formData.egressdefaultpolicy === 'ALLOW') { + delete inputData.egressdefaultpolicy; //do not pass egressdefaultpolicy to API call since we need to keep API call's size as small as possible (p.s. egressdefaultpolicy is defaulted as true at server-side) + } else { + inputData['egressdefaultpolicy'] = false; + } } else { - delete inputData.egresspolicy; + delete inputData.egressdefaultpolicy; } if (args.$form.find('.form-item[rel=serviceofferingid]').css("display") == "none") @@ -2870,8 +2951,7 @@ $.ajax({ url: createURL('createNetworkOffering'), data: inputData, - dataType: 'json', - async: true, + type: "POST", //use POST instead of GET since the API call might be overlong and exceed size limit success: function(data) { var item = data.createnetworkofferingresponse.networkoffering; @@ -3145,6 +3225,10 @@ traffictype: { label: 'label.traffic.type' }, + supportsstrechedl2subnet: { + label: 'label.supportsstrechedl2subnet', + converter: cloudStack.converters.toBooleanText + }, supportedServices: { label: 'label.supported.services' }, @@ -3170,6 +3254,561 @@ return service.name; }).join(', '), + serviceCapabilities: $.map(item.service, function(service) { + return service.provider ? $.map(service.provider, function(capability) { + return service.name + ': ' + capability.name; + }).join(', ') : null; + }).join(', ') + }) + }); + } + }); + } + } + } + } + } + }, + + vpcOfferings: { + type: 'select', + title: 'label.menu.vpc.offerings', + listView: { + id: 'vpcOfferings', + label: 'label.menu.vpc.offerings', + fields: { + name: { + label: 'label.name' + }, + state: { + label: 'label.state', + indicator: { + 'Enabled': 'on', + 'Disabled': 'off', + 'Destroyed': 'off' + } + } + }, + + dataProvider: function(args) { + var data = {}; + listViewDataProvider(args, data); + + $.ajax({ + url: createURL('listVPCOfferings'), + data: data, + success: function(json) { + var items = json.listvpcofferingsresponse.vpcoffering; + args.response.success({ + actionFilter: vpcOfferingActionfilter, + data: items + }); + }, + error: function(data) { + args.response.error(parseXMLHttpResponse(data)); + } + }); + }, + + actions: { + add: { + label: 'label.add.vpc.offering', + + createForm: { + title: 'label.add.vpc.offering', + + preFilter: function(args) { + var hasAdvancedZones = false; + + // Check whether there are any advanced zones + $.ajax({ + url: createURL('listZones'), + data: { + listAll: true + }, + async: false, + success: function(json) { + var zones = json.listzonesresponse.zone; + if (zones != null && zones.length > 0) { + for (var i = 0; i < zones.length; i++) { + if (zones[i].networktype == "Advanced") + hasAdvancedZones = true; + } + } + } + }); + + args.$form.bind('change', function() { //when any field in the dialog is changed + + var $providers = args.$form.find('.dynamic-input select'); + var $optionsOfProviders = $providers.find('option'); + + $providers.each(function() { + //if selected option is disabled, select the first enabled option instead + if ($(this).find('option:selected:disabled').length > 0) { + $(this).val($(this).find('option:first')); + } + }); + }); + + args.$form.change(); + }, + + fields: { + name: { + label: 'label.name', + validation: { + required: true + }, + docID: 'helpVpcOfferingName' + }, + + displayText: { + label: 'label.description', + validation: { + required: true + }, + docID: 'helpVpcOfferingDescription' + }, + + supportedServices: { + label: 'label.supported.services', + + dynamic: function(args) { + var networkServiceObjs = []; + networkServiceObjs.push({ + name: 'Dhcp', + provider: [{name: 'VpcVirtualRouter'}] + }); + networkServiceObjs.push({ + name: 'Dns', + provider: [{name: 'VpcVirtualRouter'}] + }); + networkServiceObjs.push({ + name: 'Lb', + provider: [{name: 'VpcVirtualRouter'}] + }); + networkServiceObjs.push({ + name: 'Gateway', + provider: [{name: 'VpcVirtualRouter'}] + }); + networkServiceObjs.push({ + name: 'StaticNat', + provider: [{name: 'VpcVirtualRouter'}] + }); + networkServiceObjs.push({ + name: 'SourceNat', + provider: [{name: 'VpcVirtualRouter'}] + }); + networkServiceObjs.push({ + name: 'NetworkACL', + provider: [{name: 'VpcVirtualRouter'}] + }); + networkServiceObjs.push({ + name: 'PortForwarding', + provider: [{name: 'VpcVirtualRouter'}] + }); + networkServiceObjs.push({ + name: 'UserData', + provider: [{name: 'VpcVirtualRouter'}] + }); + networkServiceObjs.push({ + name: 'Vpn', + provider: [{name: 'VpcVirtualRouter'}] + }); + + networkServiceObjs.push({ + name: 'Connectivity', + provider: [ + {name: 'NiciraNvp'}, + {name: 'Ovs'}, + {name: 'JuniperContrailVpcRouter'} + ] + }); + + serviceFields = []; + var fields = {}; + $(networkServiceObjs).each(function() { + var serviceName = this.name; + var providerObjs = this.provider; + var serviceDisplayName; + + // Sanitize names + switch (serviceName) { + case 'Vpn': + serviceDisplayName = dictionary['label.vpn']; + break; + case 'Dhcp': + serviceDisplayName = dictionary['label.dhcp']; + break; + case 'Dns': + serviceDisplayName = dictionary['label.dns']; + break; + case 'Lb': + serviceDisplayName = dictionary['label.load.balancer']; + break; + case 'SourceNat': + serviceDisplayName = dictionary['label.source.nat']; + break; + case 'StaticNat': + serviceDisplayName = dictionary['label.static.nat']; + break; + case 'PortForwarding': + serviceDisplayName = dictionary['label.port.forwarding']; + break; + case 'UserData': + serviceDisplayName = dictionary['label.user.data']; + break; + default: + serviceDisplayName = serviceName; + break; + } + + var id = { + isEnabled: 'service' + '.' + serviceName + '.' + 'isEnabled', + capabilities: 'service' + '.' + serviceName + '.' + 'capabilities', + provider: 'service' + '.' + serviceName + '.' + 'provider' + }; + + serviceCheckboxNames.push(id.isEnabled); + + fields[id.isEnabled] = { + label: serviceDisplayName, + isBoolean: true, + }; + + serviceFields.push(id.isEnabled); + + fields[id.provider] = { + label: serviceDisplayName + ' Provider', + isHidden: true, + dependsOn: id.isEnabled, + select: function(args) { + var items = []; + $(providerObjs).each(function() { + items.push({ + id: this.name, + description: this.name + }); + }); + args.response.success({ + data: items + }); + } + } + }); + + args.response.success({ + fields: fields + }); + } + }, //end of supportedservices field + + "service.Connectivity.regionLevelVpcCapabilityCheckbox": { + label: 'label.regionlevelvpc', + isHidden: true, + dependsOn: 'service.Connectivity.isEnabled', + isBoolean: true + }, + + "service.Connectivity.distributedRouterCapabilityCheckbox": { + label: 'label.distributedrouter', + isHidden: true, + dependsOn: 'service.Connectivity.isEnabled', + isBoolean: true + } + },//end of fields + }, //end of createForm + + action: function(args) { + var formData = args.data; + var inputData = {}; + var serviceProviderMap = {}; + var serviceCapabilityIndex = 0; + + $.each(formData, function(key, value) { + var serviceData = key.split('.'); + + if (serviceData.length > 1) { + if (serviceData[0] == 'service' && + serviceData[2] == 'isEnabled' && + value == 'on') { // Services field + + serviceProviderMap[serviceData[1]] = formData[ + 'service.' + serviceData[1] + '.provider' + ]; + } else if ((key == 'service.Connectivity.regionLevelVpcCapabilityCheckbox') && ("Connectivity" in serviceProviderMap)) { + inputData['serviceCapabilityList[' + serviceCapabilityIndex + '].service'] = 'Connectivity'; + inputData['serviceCapabilityList[' + serviceCapabilityIndex + '].capabilitytype'] = "RegionLevelVpc"; + inputData['serviceCapabilityList[' + serviceCapabilityIndex + '].capabilityvalue'] = true; + serviceCapabilityIndex++; + } else if ((key == 'service.Connectivity.distributedRouterCapabilityCheckbox') && ("Connectivity" in serviceProviderMap)) { + inputData['servicecapabilitylist[' + serviceCapabilityIndex + '].service'] = 'Connectivity'; + inputData['servicecapabilitylist[' + serviceCapabilityIndex + '].capabilitytype'] = 'DistributedRouter'; + inputData['servicecapabilitylist[' + serviceCapabilityIndex + '].capabilityvalue'] = true; + serviceCapabilityIndex++; + } + } else if (value != '') { // Normal data + inputData[key] = value; + } + }); + + // Make supported services list + inputData['supportedServices'] = $.map(serviceProviderMap, function(value, key) { + return key; + }).join(','); + + + // Make service provider map + var serviceProviderIndex = 0; + $.each(serviceProviderMap, function(key, value) { + inputData['serviceProviderList[' + serviceProviderIndex + '].service'] = key; + inputData['serviceProviderList[' + serviceProviderIndex + '].provider'] = value; + serviceProviderIndex++; + }); + + $.ajax({ + url: createURL('createVPCOffering'), + data: inputData, + dataType: 'json', + async: true, + success: function(data) { + var item = data.createvpcofferingresponse; + + args.response.success({ + data: item, + actionFilter: vpcOfferingActionfilter + }); + }, + + error: function(data) { + args.response.error(parseXMLHttpResponse(data)); + } + }); + }, + + notification: { + poll: function(args) { + args.complete({ + actionFilter: vpcOfferingActionfilter + }); + } + }, + + messages: { + notification: function(args) { + return 'Added VPC offering'; + } + } + } + }, + + reorder: cloudStack.api.actions.sort('updateVPCOffering', 'vpcOfferings'), + + detailView: { + name: 'label.vpc.offering.details', + actions: { + edit: { + label: 'label.edit', + action: function(args) { + var data = { + id: args.context.vpcOfferings[0].id, + name: args.data.name, + displaytext: args.data.displaytext, + availability: args.data.availability + }; + + $.ajax({ + url: createURL('updateVPCOffering'), + data: data, + success: function(json) { + var item = json.updatevpcofferingresponse.vpcoffering; + args.response.success({ + data: item + }); + }, + error: function(data) { + args.response.error(parseXMLHttpResponse(data)); + } + }); + } + }, + + enable: { + label: 'label.enable.vpc.offering', + messages: { + confirm: function(args) { + return 'message.confirm.enable.vpc.offering'; + }, + notification: function(args) { + return 'message.enabling.vpc.offering'; + } + }, + action: function(args) { + $.ajax({ + url: createURL("updateVPCOffering&id=" + args.context.vpcOfferings[0].id + "&state=Enabled"), + dataType: "json", + async: true, + success: function(json) { + var item = json.updatevpcofferingresponse.vpcoffering; + args.response.success(); + }, + error: function(data) { + args.response.error(parseXMLHttpResponse(data)); + } + }); + }, + notification: { + poll: function(args) { + args.complete({ + data: { + state: 'Enabled' + } + }); + } + } + }, + + disable: { + label: 'label.disable.vpc.offering', + messages: { + confirm: function(args) { + return 'message.confirm.disable.vpc.offering'; + }, + notification: function(args) { + return 'message.disabling.vpc.offering'; + } + }, + action: function(args) { + $.ajax({ + url: createURL("updateVPCOffering&id=" + args.context.vpcOfferings[0].id + "&state=Disabled"), + dataType: "json", + async: true, + success: function(json) { + var item = json.updatevpcofferingresponse.vpcoffering; + args.response.success(); + }, + error: function(data) { + args.response.error(parseXMLHttpResponse(data)); + } + }); + }, + notification: { + poll: function(args) { + args.complete({ + data: { + state: 'Disabled' + } + }); + } + } + }, + + remove: { + label: 'label.remove.vpc.offering', + action: function(args) { + $.ajax({ + url: createURL('deleteVPCOffering'), + data: { + id: args.context.vpcOfferings[0].id + }, + success: function(json) { + args.response.success(); + }, + error: function(data) { + args.response.error(parseXMLHttpResponse(data)); + } + }); + }, + messages: { + confirm: function() { + return 'message.confirm.remove.vpc.offering'; + }, + notification: function() { + return 'label.remove.vpc.offering'; + } + }, + notification: { + poll: function(args) { + args.complete({ + data: { + state: 'Destroyed' + }, + actionFilter: vpcOfferingActionfilter + }); + } + } + } + }, + tabs: { + details: { + title: 'label.details', + + fields: [{ + name: { + label: 'label.name', + isEditable: true, + validation: { + required: true + } + } + }, { + id: { + label: 'label.id' + }, + displaytext: { + label: 'label.description', + isEditable: true, + validation: { + required: true + } + }, + state: { + label: 'label.state' + }, + + isdefault: { //created by system by default + label: 'label.created.by.system', + converter: cloudStack.converters.toBooleanText + }, + + supportedServices: { + label: 'label.supported.services' + }, + serviceCapabilities: { + label: 'label.service.capabilities' + }, + distributedvpcrouter: { + label: 'label.vpc.distributedvpcrouter', + converter: cloudStack.converters.toBooleanText + }, + supportsregionLevelvpc: { + label: 'label.vpc.supportsregionlevelvpc', + converter: cloudStack.converters.toBooleanText + }, + serviceCapabilities: { + label: 'label.service.capabilities' + }, + tags: { + label: 'label.tags' + } + + }], + + dataProvider: function(args) { + $.ajax({ + url: createURL('listVPCOfferings&id=' + args.context.vpcOfferings[0].id), + dataType: "json", + async: true, + success: function(json) { + var item = json.listvpcofferingsresponse.vpcoffering[0]; + args.response.success({ + actionFilter: vpcOfferingActionfilter, + data: $.extend(item, { + supportedServices: $.map(item.service, function(service) { + return service.name; + }).join(', '), + serviceCapabilities: $.map(item.service, function(service) { return service.provider ? $.map(service.provider, function(capability) { return service.name + ': ' + capability.name; @@ -3186,7 +3825,8 @@ } } } - }; +} + var serviceOfferingActionfilter = function(args) { var jsonObj = args.context.item; @@ -3232,4 +3872,24 @@ return allowedActions; }; + var vpcOfferingActionfilter = function(args) { + var jsonObj = args.context.item; + + if (jsonObj.state == 'Destroyed') + return []; + + var allowedActions = []; + allowedActions.push("edit"); + + if (jsonObj.state == "Enabled") + allowedActions.push("disable"); + else if (jsonObj.state == "Disabled") + allowedActions.push("enable"); + + if (jsonObj.isdefault == false) + allowedActions.push("remove"); + + return allowedActions; + }; + })(cloudStack, jQuery); diff --git a/ui/scripts/docs.js b/ui/scripts/docs.js index 32237f318e..c90252737c 100755 --- a/ui/scripts/docs.js +++ b/ui/scripts/docs.js @@ -627,7 +627,7 @@ cloudStack.docs = { externalLink: '' }, helpPrimaryStorageProtocol: { - desc: 'For XenServer, choose NFS, iSCSI, or PreSetup. For KVM, choose NFS or SharedMountPoint. For vSphere, choose VMFS (iSCSI or FiberChannel) or NFS.', + desc: 'For XenServer, choose NFS, iSCSI, or PreSetup. For KVM, choose NFS or SharedMountPoint. For vSphere, choose VMFS (iSCSI or FiberChannel) or NFS. For Hyper-V, choose SMB/CIFS or PreSetup', externalLink: '' }, helpPrimaryStorageServer: { @@ -1197,7 +1197,7 @@ cloudStack.docs = { externalLink: '' }, helpUploadVolumeFormat: { - desc: 'The disk image format of the volume. XenServer is VHD, VMware is OVA, and KVM is QCOW2.', + desc: 'The disk image format of the volume. XenServer is VHD, VMware is OVA, and KVM is QCOW2. Hyper-V is VHD.', externalLink: '' }, helpUploadVolumeURL: { @@ -1211,5 +1211,13 @@ cloudStack.docs = { helpLdapGroupName: { desc: 'The group name from which you want to import LDAP users', externalLink: '' + }, + helpVpcOfferingName: { + desc: 'Any desired name for the VPC offering', + externalLink: '' + }, + helpVpcOfferingDescription: { + desc: 'A short description of the offering that can be displayed to users', + externalLink: '' } }; diff --git a/ui/scripts/instanceWizard.js b/ui/scripts/instanceWizard.js index 5c04d0e145..9df6eccdff 100644 --- a/ui/scripts/instanceWizard.js +++ b/ui/scripts/instanceWizard.js @@ -22,6 +22,12 @@ var step6ContainerType = 'nothing-to-select'; //'nothing-to-select', 'select-network', 'select-security-group', 'select-advanced-sg'(advanced sg-enabled zone) cloudStack.instanceWizard = { + //min disk offering size when custom disk size is used + minDiskOfferingSize: function() { + return g_capabilities.customdiskofferingminsize; + }, + + //max disk offering size when custom disk size is used maxDiskOfferingSize: function() { return g_capabilities.customdiskofferingmaxsize; }, @@ -292,6 +298,9 @@ selectedHypervisor = args.currentData.hypervisorid; } + // if the user is leveraging a template, then we can show custom IOPS, if applicable + var canShowCustomIopsForServiceOffering = (args.currentData["select-template"] != "select-iso" ? true : false); + $.ajax({ url: createURL("listServiceOfferings&issystem=false"), dataType: "json", @@ -299,6 +308,7 @@ success: function(json) { serviceOfferingObjs = json.listserviceofferingsresponse.serviceoffering; args.response.success({ + canShowCustomIops: canShowCustomIopsForServiceOffering, customFlag: 'iscustomized', //customFlag: 'offerha', //for testing only customIopsFlag: 'iscustomizediops', @@ -322,9 +332,11 @@ args.response.success({ required: isRequred, customFlag: 'iscustomized', // Field determines if custom slider is shown + customIopsDoFlag: 'iscustomizediops', data: { diskOfferings: diskOfferingObjs - } + }, + multiDisk: false }); } }); @@ -657,6 +669,20 @@ size : args.data.size }); } + + if (selectedDiskOfferingObj.iscustomizediops == true) { + if (args.$wizard.find('input[name=disk-min-iops-do]').val().length > 0) { + $.extend(deployVmData, { + 'details[0].minIopsDo' : args.$wizard.find('input[name=disk-min-iops-do]').val() + }); + } + + if (args.$wizard.find('input[name=disk-max-iops-do]').val().length > 0) { + $.extend(deployVmData, { + 'details[0].maxIopsDo' : args.$wizard.find('input[name=disk-max-iops-do]').val() + }); + } + } } //step 5: select an affinity group diff --git a/ui/scripts/instances.js b/ui/scripts/instances.js index 10d25917f9..93a40fc097 100644 --- a/ui/scripts/instances.js +++ b/ui/scripts/instances.js @@ -148,13 +148,15 @@ }, fields: { name: { - label: 'label.name' + label: 'label.name', + truncate: true }, instancename: { label: 'label.internal.name' }, displayname: { - label: 'label.display.name' + label: 'label.display.name', + truncate: true }, zonename: { label: 'label.zone.name' @@ -660,15 +662,15 @@ poll: pollAsyncJobResult } }, - restore: { - label: 'label.action.restore.instance', - compactLabel: 'label.restore', + recover: { + label: 'label.recover.vm', + compactLabel: 'label.recover.vm', messages: { confirm: function(args) { - return 'message.action.restore.instance'; + return 'message.recover.vm'; }, notification: function(args) { - return 'label.action.restore.instance'; + return 'label.recover.vm'; } }, action: function(args) { @@ -694,15 +696,14 @@ } } }, - reset: { - label: 'label.resetVM', - textLabel: 'label.resetVM', + reinstall: { + label: 'label.reinstall.vm', messages: { confirm: function(args) { - return 'message.restoreVM'; + return 'message.reinstall.vm'; }, notification: function(args) { - return 'label.resetVM'; + return 'label.reinstall.vm'; }, complete: function(args) { if (args.password != null && args.password.length > 0) @@ -1876,7 +1877,11 @@ else jsonObj.xenserverToolsVersion61plus = false; } - + + if (isModuleIncluded("dr")) { + cloudStack.dr.sharedFunctions.addExtraProperties(jsonObj, "UserVM"); + } + args.response.success({ actionFilter: vmActionfilter, data: jsonObj @@ -2198,7 +2203,7 @@ if (jsonObj.state == 'Destroyed') { if (isAdmin() || isDomainAdmin()) { - allowedActions.push("restore"); + allowedActions.push("recover"); } if (isAdmin() || isDomainAdmin()) allowedActions.push("expunge"); @@ -2208,7 +2213,7 @@ if (jsonObj.hypervisor != 'KVM' || g_kvmsnapshotenabled == true) allowedActions.push("snapshot"); allowedActions.push("destroy"); - allowedActions.push("reset"); + allowedActions.push("reinstall"); //when userVm is running, scaleUp is not supported for KVM if (jsonObj.hypervisor != 'KVM') { @@ -2234,7 +2239,7 @@ allowedActions.push("edit"); allowedActions.push("start"); allowedActions.push("destroy"); - allowedActions.push("reset"); + allowedActions.push("reinstall"); if (jsonObj.hypervisor != 'KVM' || g_kvmsnapshotenabled == true) allowedActions.push("snapshot"); allowedActions.push("scaleUp"); //when vm is stopped, scaleUp is supported for all hypervisors diff --git a/ui/scripts/network.js b/ui/scripts/network.js index f82a295aee..2039aa047e 100755 --- a/ui/scripts/network.js +++ b/ui/scripts/network.js @@ -40,7 +40,7 @@ var instance = args.context.instances[0]; var network = args.context.networks[0]; - if (args.context.ipAddresses[0].isportable) { + if (args.context.ipAddresses[0].isportable) { //portable IP which has multiple NICs. Each NIC has a different network ID. $.ajax({ url: createURL('listNics'), data: { @@ -49,72 +49,73 @@ success: function(json) { var nics = json.listnicsresponse.nic; var ipSelection = []; - - $(nics).map(function(index, nic) { - var ips = nic.secondaryip ? nic.secondaryip : []; + + $(nics).map(function(index, nic) { + var primaryIp = nic.ipaddress; + var secondaryIps = nic.secondaryip ? nic.secondaryip : []; var prefix = '[NIC ' + (index + 1) + '] '; // Add primary IP as default ipSelection.push({ id: nic.networkid + ',-1', - description: prefix + nic.ipaddress + ' (Primary)' + description: prefix + primaryIp + ' (Primary)' }); // Add secondary IPs - $(ips).map(function(index, ip) { + $(secondaryIps).map(function(index, secondaryIp) { ipSelection.push({ - id: nic.networkid + ',' + ip.ipaddress, - description: prefix + ip.ipaddress + id: nic.networkid + ',' + secondaryIp.ipaddress, + description: prefix + secondaryIp.ipaddress }); }); }); - args.response.success({ data: ipSelection }); } }); - - return; + + } else { //non-portable IP which has only one NIC + /* + var nic = $.grep(instance.nic, function(nic) { + return nic.networkid == network.id; + })[0]; + */ + + // Get NIC IPs + $.ajax({ + url: createURL('listNics'), + data: { + virtualmachineid: instance.id, + nicId: instance.nic[0].id + }, + success: function(json) { + var nic = json.listnicsresponse.nic[0]; + var primaryIp = nic.ipaddress; + var secondaryIps = nic.secondaryip ? nic.secondaryip : []; + var ipSelection = []; + + // Add primary IP as default + ipSelection.push({ + id: -1, + description: primaryIp + ' (Primary)' + }); + + // Add secondary IPs + $(secondaryIps).map(function(index, secondaryIp) { + ipSelection.push({ + id: secondaryIp.ipaddress, + description: secondaryIp.ipaddress + }); + }); + + args.response.success({ + data: ipSelection + }); + } + }); } - - var nic = $.grep(instance.nic, function(nic) { - return nic.networkid == network.id; - })[0]; - - // Get NIC IPs - $.ajax({ - url: createURL('listNics'), - data: { - virtualmachineid: instance.id, - nicId: nic.id - }, - success: function(json) { - var nic = json.listnicsresponse.nic[0]; - var ips = nic.secondaryip ? nic.secondaryip : []; - var ipSelection = []; - - // Add primary IP as default - ipSelection.push({ - id: -1, - description: nic.ipaddress + ' (Primary)' - }); - - // Add secondary IPs - $(ips).map(function(index, ip) { - ipSelection.push({ - id: ip.ipaddress, - description: ip.ipaddress - }); - }); - - - args.response.success({ - data: ipSelection - }); - } - }) }; //value of Primary IP in subselect dropdown is itself (not -1), for multiple VM selection (API parameter vmidipmap), e.g. assignToLoadBalancerRule API. @@ -122,7 +123,7 @@ var instance = args.context.instances[0]; var network = args.context.networks[0]; - if (args.context.ipAddresses[0].isportable) { + if (args.context.ipAddresses[0].isportable) { //portable IP which has multiple NICs. Each NIC has a different network ID. $.ajax({ url: createURL('listNics'), data: { @@ -132,71 +133,80 @@ var nics = json.listnicsresponse.nic; var ipSelection = []; + //portable IP has multiple NICs. Each NIC has a different network ID. $(nics).map(function(index, nic) { - var ips = nic.secondaryip ? nic.secondaryip : []; + var primaryIp = nic.ipaddress; + var secondaryIps = nic.secondaryip ? nic.secondaryip : []; var prefix = '[NIC ' + (index + 1) + '] '; // Add primary IP as default ipSelection.push({ - id: nic.networkid + ',' + nic.ipaddress, - description: prefix + nic.ipaddress + ' (Primary)' + id: nic.networkid + ',' + primaryIp, + description: prefix + primaryIp + ' (Primary)' }); // Add secondary IPs - $(ips).map(function(index, ip) { + $(secondaryIps).map(function(index, secondaryIp) { ipSelection.push({ - id: nic.networkid + ',' + ip.ipaddress, - description: prefix + ip.ipaddress + id: nic.networkid + ',' + secondaryIp.ipaddress, + description: prefix + secondaryIp.ipaddress }); }); - }); - - + }); + args.response.success({ data: ipSelection }); } - }); + }); - return; - } - - var nic = $.grep(instance.nic, function(nic) { - return nic.networkid == network.id; - })[0]; - - // Get NIC IPs - $.ajax({ - url: createURL('listNics'), - data: { - virtualmachineid: instance.id, - nicId: nic.id - }, - success: function(json) { - var nic = json.listnicsresponse.nic[0]; - var ips = nic.secondaryip ? nic.secondaryip : []; - var ipSelection = []; - - // Add primary IP as default - ipSelection.push({ - id: nic.ipaddress, - description: nic.ipaddress + ' (Primary)' - }); + } else { //non-portable IP which has only one NIC + /* + var nic = $.grep(instance.nic, function(nic) { + return nic.networkid == network.id; + })[0]; + */ + + // Get NIC IPs + $.ajax({ + url: createURL('listNics'), + data: { + virtualmachineid: instance.id, + nicId: instance.nic[0].id + }, + success: function(json) { + var nic = json.listnicsresponse.nic[0]; + var primaryIp = nic.ipaddress; + var secondaryIps = nic.secondaryip ? nic.secondaryip : []; + var ipSelection = []; + var existingIps = $(args.context.subItemData).map( + function(index, item) { return item.itemIp; } + ); - // Add secondary IPs - $(ips).map(function(index, ip) { - ipSelection.push({ - id: ip.ipaddress, - description: ip.ipaddress - }); - }); + // Add primary IP as default + if ($.inArray(primaryIp, existingIps) == -1) { + ipSelection.push({ + id: primaryIp, + description: primaryIp + ' (Primary)' + }); + } + // Add secondary IPs + $(secondaryIps).map(function(index, secondaryIp) { + if ($.inArray(secondaryIp.ipaddress, existingIps) == -1) { + ipSelection.push({ + id: secondaryIp.ipaddress, + description: secondaryIp.ipaddress + }); + } + }); - args.response.success({ - data: ipSelection - }); - } - }) + args.response.success({ + data: ipSelection + }); + } + }); + } }; var ipChangeNotice = function() { @@ -1373,6 +1383,11 @@ success: function(json) { var jsonObj = json.listnetworksresponse.network[0]; addExtraPropertiesToGuestNetworkObject(jsonObj); + + if (isModuleIncluded("dr")) { + cloudStack.dr.sharedFunctions.addExtraProperties(jsonObj, "Network"); + } + args.response.success({ actionFilter: cloudStack.actionFilter.guestNetwork, data: jsonObj @@ -2131,12 +2146,15 @@ $.ajax({ url: createURL('listRegions'), success: function(json) { + var selectedRegionName = $(".region-switcher .title").text(); + if ( selectedRegionName == undefined || selectedRegionName.length == 0) { + selectedRegionName = "Local"; + } var items = json.listregionsresponse.region; if(items != null) { - for(var i = 0; i < items.length; i++) { - var region = items[0]; - if(region.name == 'Local') { - if(region.portableipserviceenabled == true) { + for(var i = 0; i < items.length; i++) { + if(items[i].name == selectedRegionName) { + if(items[i].portableipserviceenabled == true) { args.$form.find('.form-item[rel=isportable]').css('display', 'inline-block'); } else { args.$form.find('.form-item[rel=isportable]').hide(); @@ -3317,16 +3335,14 @@ filters: false, //when server-side change of adding new parameter "vmidipmap" to assignToLoadBalancerRule API is in, uncomment the following commented 4 lines. - /* subselect: { - label: 'label.use.vm.ip', + isMultiple: true, + label: 'label.use.vm.ips', dataProvider: multipleVmSecondaryIPSubselect }, - */ - + dataProvider: function(args) { - var itemData = $.isArray(args.context.multiRule) && args.context.multiRule[0]['_itemData'] ? - args.context.multiRule[0]['_itemData'] : []; + var itemData = $.isArray(args.context.multiRule) && args.context.subItemData ? args.context.subItemData : []; var networkid; if ('vpc' in args.context) @@ -3375,6 +3391,42 @@ return item.id == instance.id; }).length; + // Check if there are any remaining IPs + if (!notExisting) { + $.ajax({ + url: createURL('listNics'), + async: false, + data: { + virtualmachineid: instance.id + }, + success: function(json) { + var nics = json.listnicsresponse.nic; + + $(nics).map(function (index, nic) { + if (nic.secondaryip) { + var targetIPs = $(nic.secondaryip).map(function (index, sip) { + return sip.ipaddress; + }); + + var lbIPs = $(itemData).map(function(index, item) { return item.itemIp; }); + + targetIPs.push(nic.ipaddress); + + var matchingIPs = $.grep(targetIPs, function(item) { + return $.inArray(item, lbIPs) > -1; + }); + + if (targetIPs.length - matchingIPs.length) { + notExisting = true; + + return false; + } + } + }); + } + }) + } + return nonAutoScale && isActiveState && notExisting; } ); @@ -3578,6 +3630,7 @@ var stickyData = $.extend(true, {}, args.data.sticky); + //***** create new LB rule > Add VMs ***** $.ajax({ url: createURL('createLoadBalancerRule'), data: data, @@ -3588,40 +3641,48 @@ var jobID = data.createloadbalancerruleresponse.jobid; 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(',') }; - //when server-side change of adding new parameter "vmidipmap" to assignToLoadBalancerRule API is in, remove the above 6 lines and uncomment the commented section below. + */ + //virtualmachineids parameter has been replaced with vmidipmap parameter, so comment out the 6 lines above. - /* - var inputData = { - id: data.createloadbalancerruleresponse.id - }; - if (args.context.ipAddresses[0].isportable) { - if (args.itemData != null) { - for (var k = 0; k < args.itemData.length; k++) { - inputData['vmidipmap[' + k + '].vmid'] = args.itemData[k].id; - inputData['vmidipmap[' + k + '].ip'] = args.itemData[k]._subselect.split(',')[1]; - } - } - - } else { - if (args.itemData != null) { - for (var k = 0; k < args.itemData.length; k++) { - inputData['vmidipmap[' + k + '].vmid'] = args.itemData[k].id; - inputData['vmidipmap[' + k + '].ip'] = args.itemData[k]._subselect; - } - } - } - */ - //http://localhost:8080/client/api?command=assignToLoadBalancerRule&response=json&sessionkey=M6I8h6gBXuEMeBMb4pjSDTjYprc=&id=da97bae5-9389-4bbb-aef3-ccca8408a852&vmidipmap[0].vmid=667d1450-3cd9-4670-b22e-aebb77f521a3&vmidipmap[0].ip=10.1.1.23&vmidipmap[1].vmid=5128d30b-7747-4a05-bdbc-6262191d7642&vmidipmap[1].ip=10.1.1.82&vmidipmap[2].vmid=48c61d00-28d2-4048-aed5-774289470804&vmidipmap[2].ip=10.1.1.5&_=1393451067671 - - + /* + * 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 + */ + 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; + + 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('assignToLoadBalancerRule'), data: inputData, @@ -3731,17 +3792,44 @@ }, itemActions: { - add: { + //***** update existing LB rule > Add VMs ***** + add: { label: 'label.add.vms.to.lb', action: function(args) { + var inputData = { + id: args.multiRule.id + }; + + /* + * 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 + */ + var selectedVMs = args.data; + 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; + + 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('assignToLoadBalancerRule'), - data: { - id: args.multiRule.id, - virtualmachineids: $.map(args.data, function(elem) { - return elem.id; - }).join(',') - }, + data: inputData, success: function(json) { args.response.success({ notification: { @@ -3764,13 +3852,24 @@ }, destroy: { label: 'label.remove.vm.from.lb', - action: function(args) { - $.ajax({ - url: createURL('removeFromLoadBalancerRule'), - data: { + action: function(args) { + var inputData; + if (args.item.itemIp == undefined) { + inputData = { id: args.multiRule.id, virtualmachineids: args.item.id - }, + }; + } else { + inputData = { + id: args.multiRule.id, + "vmidipmap[0].vmid": args.item.id, + "vmidipmap[0].vmip": args.item.itemIp + }; + } + + $.ajax({ + url: createURL('removeFromLoadBalancerRule'), + data: inputData, success: function(json) { args.response.success({ notification: { @@ -3804,31 +3903,30 @@ dataType: 'json', async: true, success: function(data) { - var loadBalancerData = data.listloadbalancerrulesresponse.loadbalancerrule; - var loadVMTotal = loadBalancerData ? loadBalancerData.length : 0; - var loadVMCurrent = 0; - - $(loadBalancerData).each(function() { - loadVMCurrent++; - var item = this; + var loadbalancerrules = data.listloadbalancerrulesresponse.loadbalancerrule; + + $(loadbalancerrules).each(function() { + var lbRule = this; var stickyData = {}; - var lbInstances = []; + + //var lbInstances = []; + var itemData = []; // Passing _hideFields array will disable specified fields for this row - //item._hideFields = ['autoScale']; + //lbRule._hideFields = ['autoScale']; $.ajax({ url: createURL('listAutoScaleVmGroups'), data: { listAll: true, - lbruleid: item.id + lbruleid: lbRule.id }, async: false, success: function(json) { if (json.listautoscalevmgroupsresponse.autoscalevmgroup != null && json.listautoscalevmgroupsresponse.autoscalevmgroup.length > 0) { //from 'autoScale' button - item._hideFields = ['add-vm']; + lbRule._hideFields = ['add-vm']; } else { //from 'add-vm' button - item._hideFields = ['autoScale']; + lbRule._hideFields = ['autoScale']; } } }); @@ -3839,7 +3937,7 @@ async: false, data: { listAll: true, - lbruleid: item.id + lbruleid: lbRule.id }, success: function(json) { var stickyPolicy = json.listlbstickinesspoliciesresponse.stickinesspolicies ? @@ -3855,12 +3953,12 @@ methodname: stickyPolicy.methodname, stickyName: stickyPolicy.name, id: stickyPolicy.id, - lbRuleID: item.id + lbRuleID: lbRule.id }; $.extend(stickyData, stickyPolicy.params); } else { stickyData = { - lbRuleID: item.id + lbRuleID: lbRule.id }; } }, @@ -3878,42 +3976,62 @@ async: false, data: { listAll: true, - id: item.id + lbvmips: true, + id: lbRule.id }, success: function(data) { - lbInstances = data.listloadbalancerruleinstancesresponse.loadbalancerruleinstance ? - data.listloadbalancerruleinstancesresponse.loadbalancerruleinstance : []; - - $(lbInstances).each(function() { - if (this.displayname.indexOf('AutoScale-LB-') > -1) //autoscale VM is not allowed to be deleted manually. So, hide destroy button - this._hideActions = ['destroy']; - - if (this.servicestate) { - this._itemStateLabel = 'label.service.state'; - this._itemState = this.servicestate; - } - }); + //when "lbvmips: true" is not passed to API + //lbVMs = data.listloadbalancerruleinstancesresponse.loadbalancerruleinstance; + + //when "lbvmips: true" is passed to API + lbrulevmidips = data.listloadbalancerruleinstancesresponse.lbrulevmidip; + + if (lbrulevmidips != null) { + for (var k = 0; k < lbrulevmidips.length; k++) { + var lbrulevmidip = lbrulevmidips[k]; + var lbVM = lbrulevmidip.loadbalancerruleinstance; + if (lbVM.displayname.indexOf('AutoScale-LB-') > -1) //autoscale VM is not allowed to be deleted manually. So, hide destroy button + lbVM._hideActions = ['destroy']; + + if (lbVM.servicestate) { + lbVM._itemStateLabel = 'label.service.state'; + lbVM._itemState = lbVM.servicestate; + } + + if (lbrulevmidip.lbvmipaddresses != null) { + for (var m = 0 ; m < lbrulevmidip.lbvmipaddresses.length; m++) { + var ip = lbrulevmidip.lbvmipaddresses[m]; + itemData.push($.extend({}, lbVM, { + itemIp: ip + })); + } + } else { + itemData.push(lbVM); + } + } + } }, error: function(data) { args.response.error(parseXMLHttpResponse(data)); } - }); + }); - $.extend(item, { + $.extend(lbRule, { _itemName: 'name', - _itemData: lbInstances, + _itemIp: 'itemIp', + _itemData: itemData, _maxLength: { name: 7 }, sticky: stickyData, autoScale: { - lbRuleID: item.id + lbRuleID: lbRule.id } }); }); args.response.success({ - data: loadBalancerData + data: loadbalancerrules }); } }); @@ -5107,7 +5225,16 @@ url: createURL('listVPCs'), data: data, success: function(json) { - var items = json.listvpcsresponse.vpc; + var items = json.listvpcsresponse.vpc ? json.listvpcsresponse.vpc : { }; + + //If we are coming from Home > Regions, show only regional vpcs + if (args.context.regions) + items = $.grep( + items, + function (vpc, i) { + return vpc.regionlevelvpc; + }); + args.response.success({ data: items }); @@ -5201,30 +5328,49 @@ data: items }); } + }, + vpcoffering: { + label: 'label.vpc.offering', + validation: { + required: true + }, + + select: function(args) { + var data = { + listAll: true + }; + $.ajax({ + url: createURL('listVPCOfferings'), + data: { + listAll: true + }, + success: function(json) { + var offerings = json.listvpcofferingsresponse.vpcoffering ? json.listvpcofferingsresponse.vpcoffering : []; + var filteredofferings = $.grep(offerings, function(offering) { + return offering.state == 'Enabled'; + }); + args.response.success({ + data: $.map(filteredofferings, function(vpco) { + return { + id: vpco.id, + description: vpco.name + }; + }) + }); + } + }); + } } } }, action: function(args) { - var vpcOfferingName; - if (args.data.publicLoadBalancerProvider == 'VpcVirtualRouter') - vpcOfferingName = 'Default VPC offering'; - else if (args.data.publicLoadBalancerProvider == 'Netscaler') - vpcOfferingName = 'Default VPC offering with Netscaler'; - - $.ajax({ - url: createURL('listVPCOfferings'), - data: { - name: vpcOfferingName - }, - success: function(json) { - var vpcofferingid = json.listvpcofferingsresponse.vpcoffering[0].id; - + var vpcOfferingName = args.data.vpcoffering var dataObj = { name: args.data.name, displaytext: args.data.displaytext, zoneid: args.data.zoneid, cidr: args.data.cidr, - vpcofferingid: vpcofferingid + vpcofferingid: args.data.vpcoffering }; if (args.data.networkdomain != null && args.data.networkdomain.length > 0) @@ -5252,8 +5398,6 @@ args.response.error(parseXMLHttpResponse(data)); } }); - } - }); }, notification: { diff --git a/ui/scripts/regions.js b/ui/scripts/regions.js index 66dae8c1a1..368c1bfb2f 100644 --- a/ui/scripts/regions.js +++ b/ui/scripts/regions.js @@ -147,6 +147,9 @@ viewAll: [{ path: 'regions.GSLB', label: 'GSLB' + }, { + path: 'network.vpc', + label: 'label.regionlevelvpc' }, { path: 'regions.portableIpRanges', label: 'Portable IP', diff --git a/ui/scripts/sharedFunctions.js b/ui/scripts/sharedFunctions.js index 9c24f40489..f58fdd2176 100644 --- a/ui/scripts/sharedFunctions.js +++ b/ui/scripts/sharedFunctions.js @@ -18,6 +18,7 @@ var g_mySession = null; var g_sessionKey = null; var g_role = null; // roles - root, domain-admin, ro-admin, user var g_username = null; +var g_userid = null; var g_account = null; var g_domainid = null; var g_loginCmdText = null; @@ -48,8 +49,6 @@ var md5HashedLogin = false; var pageSize = 20; //var pageSize = 1; //for testing only -var rootAccountId = 1; - //async action var pollAsyncJobResult = function(args) { $.ajax({ @@ -764,18 +763,6 @@ var addGuestNetworkDialog = { return (g_role == 0); } - function isSelfOrChildDomainUser(username, useraccounttype, userdomainid, iscallerchilddomain) { - if (username == g_username) { //is self - return true; - } else if (isDomainAdmin() && !iscallerchilddomain && (useraccounttype == 0)) { //domain admin to user - return true; - } else if (isDomainAdmin() && iscallerchilddomain && (userdomainid != g_domainid)) { //domain admin to subdomain admin and user - return true; - } else { - return false; - } - } - // FUNCTION: Handles AJAX error callbacks. You can pass in an optional function to // handle errors that are not already handled by this method. @@ -919,11 +906,18 @@ cloudStack.converters = { var disconnected = new Date(); disconnected.setISO8601(UtcDate); - if (g_timezoneoffset != null) + if (g_timezoneoffset != null) { localDate = disconnected.getTimePlusTimezoneOffset(g_timezoneoffset); - else - localDate = disconnected.toUTCString(); - // localDate = disconnected.getTimePlusTimezoneOffset(0); + } else { + var browserDate = new Date(); + var browserTimezoneoffset = browserDate.getTimezoneOffset(); + if (browserTimezoneoffset == undefined || isNaN(browserTimezoneoffset) ) { + localDate = disconnected.toUTCString(); + } else { + g_timezoneoffset = (browserTimezoneoffset/60) * (-1); + localDate = disconnected.getTimePlusTimezoneOffset(g_timezoneoffset); + } + } } return localDate; }, @@ -1096,6 +1090,8 @@ cloudStack.converters = { return "VLAN"; case 18: return "Secondary Storage VM"; + case 19: + return "GPU"; } }, @@ -1121,6 +1117,16 @@ cloudStack.converters = { } } +function isModuleIncluded(moduleName) { + for(var moduleIndex = 0; moduleIndex < cloudStack.modules.length; moduleIndex++) { + if (cloudStack.modules[moduleIndex] == moduleName) { + return true; + break; + } + } + return false; +} + //data parameter passed to API call in listView function listViewDataProvider(args, data, options) { @@ -1173,10 +1179,7 @@ var addExtraPropertiesToGuestNetworkObject = function(jsonObj) { jsonObj.networkofferingidText = jsonObj.networkofferingid; if (jsonObj.acltype == "Domain") { - if (jsonObj.domainid == rootAccountId) - jsonObj.scope = "All"; - else - jsonObj.scope = "Domain (" + jsonObj.domain + ")"; + jsonObj.scope = "Domain (" + jsonObj.domain + ")"; } else if (jsonObj.acltype == "Account") { if (jsonObj.project != null) jsonObj.scope = "Account (" + jsonObj.domain + ", " + jsonObj.project + ")"; diff --git a/ui/scripts/storage.js b/ui/scripts/storage.js index e69a07e115..260f5212e5 100644 --- a/ui/scripts/storage.js +++ b/ui/scripts/storage.js @@ -305,6 +305,10 @@ id: 'VHD', description: 'VHD' }); + items.push({ + id: 'VHDX', + description: 'VHDX' + }); items.push({ id: 'OVA', description: 'OVA' @@ -900,7 +904,12 @@ hypervisor: args.context.volumes[0].hypervisor }); } - + + var volumeDrEnabled = false; + if (isModuleIncluded("dr")) { + volumeDrEnabled = cloudStack.dr.sharedFunctions.isVolumeDrEnabled(args.context.volumes[0]); + } + $(['Running', 'Stopped']).each(function() { $.ajax({ url: createURL('listVirtualMachines'), @@ -910,11 +919,21 @@ async: false, success: function(json) { var instanceObjs = json.listvirtualmachinesresponse.virtualmachine; - $(instanceObjs).each(function() { - items.push({ - id: this.id, - description: this.displayname ? this.displayname : this.name - }); + $(instanceObjs).each(function() { + if (isModuleIncluded("dr")) { + var vmDrEnabled = cloudStack.dr.sharedFunctions.isVmDrEnabled(this); + if (vmDrEnabled == volumeDrEnabled) { + items.push({ + id: this.id, + description: this.displayname ? this.displayname : this.name + }); + } + } else { + items.push({ + id: this.id, + description: this.displayname ? this.displayname : this.name + }); + } }); } }); @@ -975,7 +994,7 @@ getUpdatedItem: function(json) { return { virtualmachineid: null, - vmname: null + vmdisplayname: null }; }, getActionFilter: function() { @@ -1479,6 +1498,11 @@ async: true, success: function(json) { var jsonObj = json.listvolumesresponse.volume[0]; + + if (isModuleIncluded("dr")) { + cloudStack.dr.sharedFunctions.addExtraProperties(jsonObj, "Volume"); + } + args.response.success({ actionFilter: volumeActionfilter, data: jsonObj @@ -1989,7 +2013,7 @@ } if (jsonObj.state != "Creating") { - if (jsonObj.type == "ROOT") { + if (jsonObj.type == "ROOT") { if (jsonObj.vmstate == "Stopped") { allowedActions.push("createTemplate"); } diff --git a/ui/scripts/system.js b/ui/scripts/system.js index cdd02b29fd..96b98fb05e 100644 --- a/ui/scripts/system.js +++ b/ui/scripts/system.js @@ -1954,6 +1954,11 @@ success: function (json) { selectedGuestNetworkObj = json.listnetworksresponse.network[0]; addExtraPropertiesToGuestNetworkObject(selectedGuestNetworkObj); + + if (isModuleIncluded("dr")) { + cloudStack.dr.sharedFunctions.addExtraProperties(selectedGuestNetworkObj, "Network"); + } + args.response.success({ actionFilter: cloudStack.actionFilter.guestNetwork, data: selectedGuestNetworkObj @@ -6172,7 +6177,7 @@ args.response.success({ actionFilter: virtualRouterProviderActionFilter, data: $.extend(nspMap[ "Ovs"], { - supportedServices: nspMap[ "Ovs"].servicelist.join(', ') + supportedServices: nspMap["Ovs"] == undefined? "": nspMap["Ovs"].servicelist.join(', ') }) }); } @@ -7590,6 +7595,10 @@ } //override default error handling: cloudStack.dialog.notice({ message: parseXMLHttpResponse(XMLHttpResponse)}); }); + + if (isModuleIncluded("dr")) { + cloudStack.dr.sharedFunctions.addExtraProperties(selectedZoneObj, "Zone"); + } args.response.success({ actionFilter: zoneActionfilter, @@ -14755,6 +14764,74 @@ } }, + enable: { + label: 'Enable Host', + action: function (args) { + var data = { + id: args.context.hosts[0].id, + allocationstate: "Enable" + }; + $.ajax({ + url: createURL("updateHost"), + data: data, + success: function (json) { + var item = json.updatehostresponse.host; + args.response.success({ + actionFilter: hostActionfilter, + data: item + }); + } + }); + }, + messages: { + confirm: function (args) { + return 'Please confirm that you want to enable the host'; + }, + notification: function (args) { + return 'Enable Host'; + } + }, + notification: { + poll: function (args) { + args.complete(); + } + } + }, + + disable: { + label: 'Disable Host', + action: function (args) { + var data = { + id: args.context.hosts[0].id, + allocationstate: "Disable" + }; + $.ajax({ + url: createURL("updateHost"), + data: data, + success: function (json) { + var item = json.updatehostresponse.host; + args.response.success({ + actionFilter: hostActionfilter, + data: item + }); + } + }); + }, + messages: { + confirm: function (args) { + return 'Please confirm that you want to disable the host'; + }, + notification: function (args) { + return 'Disable Host'; + } + }, + notification: { + poll: function (args) { + args.complete(); + } + } + }, + 'remove': { label: 'label.action.remove.host', messages: { @@ -14811,6 +14888,13 @@ } } }, + tabFilter: function (args) { + var hiddenTabs =[]; + if (args.context.hosts[0].gpugroup == null) { + hiddenTabs.push("gpu"); + } + return hiddenTabs; + }, tabs: { details: { title: 'label.details', @@ -15004,6 +15088,81 @@ } }); } + }, + gpu: { + title: 'label.gpu', + custom: function (args) { + var gpugroups = null; + $.ajax({ + url: createURL("listHosts&id=" + args.context.hosts[0].id), + dataType: "json", + async: false, + success: function (json) { + var item = json.listhostsresponse.host[0]; + if (item != null && item.gpugroup != null) + gpugroups = item.gpugroup; + } + }); + + var $tabcontent = $('
').addClass('gpugroups'); + + $(gpugroups).each(function() { + var gpugroupObj = this; + + var $groupcontainer = $('
').addClass('gpugroup-container'); + + //group name + $groupcontainer.append($('
').addClass('title') + .append($('').html(gpugroupObj.gpugroupname))); + //vgpu details + var $groupdetails = $('
').listView({ + context: args.context, + listView: { + id: 'gputypes', + hideToolbar: true, + fields: { + vgputype: { + label: 'label.vgpu.type' + }, + maxvgpuperpgpu: { + label: 'label.vgpu.max.vgpu.per.gpu', + converter: function (args) { + return (args == null || args == 0) ? "" : args; + } + }, + videoram: { + label: 'label.vgpu.video.ram', + converter: function (args) { + return (args == null || args == 0) ? "" : cloudStack.converters.convertBytes(args); + } + }, + maxresolution: { + label: 'label.vgpu.max.resolution' + }, + remainingcapacity: { + label: 'label.vgpu.remaining.capacity' + } + }, + dataProvider: function (args) { + var items = gpugroupObj.vgpu.sort(function(a, b) { + return a.maxvgpuperpgpu >= b.maxvgpuperpgpu; + }); + $(items).each(function () { + this.maxresolution = (this.maxresolutionx == null || this.maxresolutionx == 0 + || this.maxresolutiony == null || this.maxresolutiony == 0) + ? "" : this.maxresolutionx + " x " + this.maxresolutiony; + }); + args.response.success({ + data: items + }); + } + } + }); + $groupcontainer.append($groupdetails); + $tabcontent.append($groupcontainer); + }); + return $tabcontent; + } } } } @@ -15131,7 +15290,11 @@ id: 'VMware', description: _l('VMware') }); - + items.push({ + id: 'Hyperv', + description: _l('Hyperv') + }); + args.response.success({ data: items }); @@ -15273,17 +15436,19 @@ dependsOn: 'clusterId', select: function (args) { var clusterId = args.clusterId; - if (clusterId == null) + if (clusterId == null || clusterId.length == 0) { + args.response.success({ + data: [] + }); return; - var items =[]; + } + $(clusterObjs).each(function () { if (this.id == clusterId) { selectedClusterObj = this; return false; //break the $.each() loop } }); - if (selectedClusterObj == null) - return; if (selectedClusterObj.hypervisortype == "KVM") { var items =[]; @@ -15346,6 +15511,10 @@ id: "SMB", description: "SMB/CIFS" }); + items.push({ + id: "PreSetup", + description: "PreSetup" + }); args.response.success({ data: items }); @@ -15395,7 +15564,7 @@ $form.find('.form-item[rel=path]').css('display', 'inline-block'); var $required = $form.find('.form-item[rel=path]').find(".name").find("label span"); - $form.find('.form-item[rel=path]').find(".name").find("label").text('label.path'+":").prepend($required); + $form.find('.form-item[rel=path]').find(".name").find("label").text("Path:").prepend($required); $form.find('.form-item[rel=smbUsername]').hide(); $form.find('.form-item[rel=smbPassword]').hide(); @@ -15422,7 +15591,7 @@ $form.find('.form-item[rel=path]').css('display', 'inline-block'); var $required = $form.find('.form-item[rel=path]').find(".name").find("label span"); - $form.find('.form-item[rel=path]').find(".name").find("label").text('label.path'+":").prepend($required); + $form.find('.form-item[rel=path]').find(".name").find("label").text("Path:").prepend($required); $form.find('.form-item[rel=smbUsername]').css('display', 'inline-block'); $form.find('.form-item[rel=smbPassword]').css('display', 'inline-block'); @@ -15449,7 +15618,7 @@ $form.find('.form-item[rel=path]').css('display', 'inline-block'); var $required = $form.find('.form-item[rel=path]').find(".name").find("label span"); - $form.find('.form-item[rel=path]').find(".name").find("label").text('label.path'+":").prepend($required); + $form.find('.form-item[rel=path]').find(".name").find("label").text("Path:").prepend($required); $form.find('.form-item[rel=smbUsername]').hide(); $form.find('.form-item[rel=smbPassword]').hide(); @@ -15475,7 +15644,7 @@ $form.find('.form-item[rel=path]').css('display', 'inline-block'); var $required = $form.find('.form-item[rel=path]').find(".name").find("label span"); - $form.find('.form-item[rel=path]').find(".name").find("label").text('label.SR.name'+":").prepend($required); + $form.find('.form-item[rel=path]').find(".name").find("label").text("SR Name-Label:").prepend($required); $form.find('.form-item[rel=smbUsername]').hide(); $form.find('.form-item[rel=smbPassword]').hide(); @@ -15574,7 +15743,7 @@ $form.find('.form-item[rel=path]').css('display', 'inline-block'); var $required = $form.find('.form-item[rel=path]').find(".name").find("label span"); - $form.find('.form-item[rel=path]').find(".name").find("label").text('label.path'+":").prepend($required); + $form.find('.form-item[rel=path]').find(".name").find("label").text("Path:").prepend($required); $form.find('.form-item[rel=smbUsername]').hide(); $form.find('.form-item[rel=smbPassword]').hide(); @@ -18907,6 +19076,7 @@ if (jsonObj.resourcestate == "Enabled") { allowedActions.push("edit"); allowedActions.push("enableMaintenanceMode"); + allowedActions.push("disable"); if (jsonObj.state != "Disconnected") allowedActions.push("forceReconnect"); @@ -18923,6 +19093,7 @@ allowedActions.push("remove"); } else if (jsonObj.resourcestate == "Disabled") { allowedActions.push("edit"); + allowedActions.push("enable"); allowedActions.push("remove"); } @@ -19267,11 +19438,14 @@ }); } + if ($.grep(nspHardcodingArray, function(e) { return e.id == 'Ovs'; }).length == 0 ) { nspHardcodingArray.push({ - id: 'OVS', - name: 'OVS', + id: 'Ovs', + name: 'Ovs', state: nspMap.Ovs ? nspMap.Ovs.state : 'Disabled' }); + } + }; cloudStack.actionFilter.physicalNetwork = function (args) { diff --git a/ui/scripts/templates.js b/ui/scripts/templates.js index 7a45463d8a..e5b8bd6569 100644 --- a/ui/scripts/templates.js +++ b/ui/scripts/templates.js @@ -53,9 +53,6 @@ name: { label: 'label.name' }, - zonename: { - label: 'label.zone' - }, hypervisor: { label: 'label.hypervisor' } @@ -396,6 +393,10 @@ id: 'VHD', description: 'VHD' }); + items.push({ + id: 'VHDX', + description: 'VHDX' + }); } args.response.success({ data: items @@ -597,9 +598,32 @@ data: data, success: function(json) { var items = json.listtemplatesresponse.template; + var itemsView = []; + + $(items).each(function(index, item) { + var existing = $.grep(itemsView, function(it){ + return it != null && it.id !=null && it.id == item.id; + }); + + if (existing.length == 0) { + itemsView.push({ + id: item.id, + name: item.name, + description: item.description, + hypervisor: item.hypervisor, + zones: item.zonename, + zoneids: [item.zoneid] + }); + } + else { + existing[0].zones = 'label.multiplezones'; + existing[0].zoneids.push(item.zoneid); + } + }); + args.response.success({ actionFilter: templateActionfilter, - data: items + data: itemsView }); } }); @@ -745,91 +769,6 @@ } }, - copyTemplate: { - label: 'label.action.copy.template', - messages: { - confirm: function(args) { - return 'message.copy.template.confirm'; - }, - success: function(args) { - return 'message.template.copying'; - }, - notification: function(args) { - return 'label.action.copy.template'; - } - }, - createForm: { - title: 'label.action.copy.template', - desc: '', - fields: { - destinationZoneId: { - label: 'label.destination.zone', - docID: 'helpCopyTemplateDestination', - validation: { - required: true - }, - select: function(args) { - $.ajax({ - url: createURL("listZones&available=true"), - dataType: "json", - async: true, - success: function(json) { - var zoneObjs = []; - var items = json.listzonesresponse.zone; - if (items != null) { - for (var i = 0; i < items.length; i++) { - if (items[i].id != args.context.templates[0].zoneid) { //destination zone must be different from source zone - zoneObjs.push({ - id: items[i].id, - description: items[i].name - }); - } - } - } - args.response.success({ - data: zoneObjs - }); - } - }); - } - } - } - }, - action: function(args) { - var data = { - id: args.context.templates[0].id, - destzoneid: args.data.destinationZoneId - }; - if (args.context.templates[0].zoneid != undefined) { - $.extend(data, { - sourcezoneid: args.context.templates[0].zoneid - }); - } - - $.ajax({ - url: createURL('copyTemplate'), - data: data, - success: function(json) { - var jid = json.copytemplateresponse.jobid; - args.response.success({ - _custom: { - jobId: jid, - getUpdatedItem: function(json) { - return {}; //nothing in this template needs to be updated - }, - getActionFilter: function() { - return templateActionfilter; - } - } - }); - } - }); - }, - notification: { - poll: pollAsyncJobResult - } - }, - downloadTemplate: { label: 'label.action.download.template', messages: { @@ -876,40 +815,6 @@ } }, - remove: { - label: 'label.action.delete.template', - messages: { - confirm: function(args) { - return 'message.action.delete.template'; - }, - notification: function(args) { - return 'label.action.delete.template'; - } - }, - action: function(args) { - var array1 = []; - if (args.context.templates[0].zoneid != null) - array1.push("&zoneid=" + args.context.templates[0].zoneid); - - $.ajax({ - url: createURL("deleteTemplate&id=" + args.context.templates[0].id + array1.join("")), - dataType: "json", - async: true, - success: function(json) { - var jid = json.deletetemplateresponse.jobid; - args.response.success({ - _custom: { - jobId: jid - } - }); - } - }); - }, - notification: { - poll: pollAsyncJobResult - } - } - }, tabs: { details: { @@ -939,14 +844,6 @@ } } }, { - isready: { - label: 'state.ready', - converter: cloudStack.converters.toBooleanText - }, - status: { - label: 'label.status' - }, - hypervisor: { label: 'label.hypervisor' }, @@ -1046,9 +943,6 @@ } }, - zonename: { - label: 'label.zone.name' - }, crossZones: { label: 'label.cross.zones', converter: cloudStack.converters.toBooleanText @@ -1078,9 +972,6 @@ id: { label: 'label.id' - }, - zoneid: { - label: 'label.zone.id' } }], @@ -1116,6 +1007,367 @@ } }); } + }, + + zones: { + title: 'label.zones', + listView: { + id: 'zones', + fields: { + zonename: { + label: 'label.name' + }, + status: { + label: 'label.status' + }, + isready: { + label: 'state.ready', + converter: cloudStack.converters.toBooleanText + } + }, + hideSearchBar: true, + + + dataProvider: function(args) { + var jsonObj = args.context.templates[0]; + var apiCmd = "listTemplates&templatefilter=self&id=" + jsonObj.id; + + $.ajax({ + url: createURL(apiCmd), + dataType: "json", + success: function(json) { + var templates = json.listtemplatesresponse.template; + var zones = []; + zones = templates; + + args.response.success({ + actionFilter: templateActionfilter, + data: zones + }); + } + }); + }, + + detailView: { + actions: { + remove: { + label: 'label.action.delete.template', + messages: { + confirm: function(args) { + return 'message.action.delete.template'; + }, + notification: function(args) { + return 'label.action.delete.template'; + } + }, + action: function(args) { + $.ajax({ + url: createURL("deleteTemplate&id=" + args.context.templates[0].id + "&zoneid=" + args.context.zones[0].zoneid), + dataType: "json", + async: true, + success: function(json) { + var jid = json.deletetemplateresponse.jobid; + args.response.success({ + _custom: { + jobId: jid + } + }); + } + }); + }, + notification: { + poll: pollAsyncJobResult + } + }, + copyTemplate: { + label: 'label.action.copy.template', + messages: { + confirm: function(args) { + return 'message.copy.template.confirm'; + }, + success: function(args) { + return 'message.template.copying'; + }, + notification: function(args) { + return 'label.action.copy.template'; + } + }, + createForm: { + title: 'label.action.copy.template', + desc: '', + fields: { + destinationZoneId: { + label: 'label.destination.zone', + docID: 'helpCopyTemplateDestination', + validation: { + required: true + }, + select: function(args) { + $.ajax({ + url: createURL("listZones&available=true"), + dataType: "json", + async: true, + success: function(json) { + var zoneObjs = []; + var items = json.listzonesresponse.zone; + if (items != null) { + for (var i = 0; i < items.length; i++) { + if (args.context.zones[0].zoneid != items[i].id) { + zoneObjs.push({ + id: items[i].id, + description: items[i].name + }); + } + } + } + args.response.success({ + data: zoneObjs + }); + } + }); + } + } + } + }, + action: function(args) { + var data = { + id: args.context.templates[0].id, + destzoneid: args.data.destinationZoneId + }; + $.extend(data, { + sourcezoneid: args.context.zones[0].zoneid + }); + + $.ajax({ + url: createURL('copyTemplate'), + data: data, + success: function(json) { + var jid = json.copytemplateresponse.jobid; + args.response.success({ + _custom: { + jobId: jid, + getUpdatedItem: function(json) { + return {}; //nothing in this template needs to be updated + }, + getActionFilter: function() { + return templateActionfilter; + } + } + }); + } + }); + }, + notification: { + poll: pollAsyncJobResult + } + } + }, + + tabs: { + details: { + title: 'label.details', + preFilter: function(args) { + var hiddenFields; + if (isAdmin()) { + hiddenFields = []; + } else { + hiddenFields = ["hypervisor", 'xenserverToolsVersion61plus']; + } + + if ('templates' in args.context && args.context.templates[0].hypervisor != 'XenServer') { + hiddenFields.push('xenserverToolsVersion61plus'); + } + + return hiddenFields; + }, + + fields: [{ + name: { + label: 'label.name', + isEditable: true, + validation: { + required: true + } + } + }, { + id: { + label: 'label.id' + }, + zonename: { + label: 'label.zone.name' + }, + zoneid: { + label: 'label.zone.id' + }, + isready: { + label: 'state.ready', + converter: cloudStack.converters.toBooleanText + }, + status: { + label: 'label.status' + } + }, { + hypervisor: { + label: 'label.hypervisor' + }, + xenserverToolsVersion61plus: { + label: 'label.xenserver.tools.version.61.plus', + isBoolean: true, + isEditable: function () { + if (isAdmin()) + return true; + else + return false; + }, + converter: cloudStack.converters.toBooleanText + }, + + size: { + label: 'label.size', + converter: function(args) { + if (args == null || args == 0) + return ""; + else + return cloudStack.converters.convertBytes(args); + } + }, + isextractable: { + label: 'extractable', + isBoolean: true, + isEditable: function() { + if (isAdmin()) + return true; + else + return false; + }, + converter: cloudStack.converters.toBooleanText + }, + passwordenabled: { + label: 'label.password.enabled', + isBoolean: true, + isEditable: true, + converter: cloudStack.converters.toBooleanText + }, + isdynamicallyscalable: { + label: 'Dynamically Scalable', + isBoolean: true, + isEditable: true, + converter: cloudStack.converters.toBooleanText + }, + ispublic: { + label: 'label.public', + isBoolean: true, + isEditable: function() { + if (isAdmin()) { + return true; + } else { + if (g_userPublicTemplateEnabled == "true") + return true; + else + return false; + } + }, + converter: cloudStack.converters.toBooleanText + }, + isfeatured: { + label: 'label.featured', + isBoolean: true, + isEditable: function() { + if (isAdmin()) + return true; + else + return false; + }, + converter: cloudStack.converters.toBooleanText + }, + + ostypeid: { + label: 'label.os.type', + isEditable: true, + select: function(args) { + $.ajax({ + url: createURL("listOsTypes"), + dataType: "json", + async: true, + success: function(json) { + var ostypes = json.listostypesresponse.ostype; + var items = []; + $(ostypes).each(function() { + items.push({ + id: this.id, + description: this.description + }); + }); + args.response.success({ + data: items + }); + } + }); + } + }, + + + displaytext: { + label: 'label.description', + isEditable: true, + validation: { + required: true + } + }, + + domain: { + label: 'label.domain' + }, + account: { + label: 'label.account' + }, + created: { + label: 'label.created', + converter: cloudStack.converters.toLocalDate + }, + + templatetype: { + label: 'label.type' + }, + + + }], + + tags: cloudStack.api.tags({ + resourceType: 'Template', + contextId: 'templates' + }), + + + dataProvider: function(args) { + var jsonObj = args.context.templates[0]; + var apiCmd = "listTemplates&templatefilter=self&id=" + jsonObj.id; + if (jsonObj.zoneid != null) + apiCmd = apiCmd + "&zoneid=" + jsonObj.zoneid; + + $.ajax({ + url: createURL(apiCmd), + dataType: "json", + success: function(json) { + var jsonObj = json.listtemplatesresponse.template[0]; + + if ('details' in jsonObj && 'hypervisortoolsversion' in jsonObj.details) { + if (jsonObj.details.hypervisortoolsversion == 'xenserver61') + jsonObj.xenserverToolsVersion61plus = true; + else + jsonObj.xenserverToolsVersion61plus = false; + } + + args.response.success({ + actionFilter: templateActionfilter, + data: jsonObj + }); + } + }); + } + } + }} + } } } } @@ -1149,9 +1401,6 @@ fields: { name: { label: 'label.name' - }, - zonename: { - label: 'label.zone' } }, @@ -1430,9 +1679,30 @@ data: data, success: function(json) { var items = json.listisosresponse.iso; + + var itemsView = []; + $(items).each(function(index, item) { + var existing = $.grep(itemsView, function(it){ + return it != null && it.id !=null && it.id == item.id; + }); + if (existing.length == 0) { + itemsView.push({ + id: item.id, + name: item.name, + description: item.description, + zones: item.zonename, + zoneids: [item.zoneid] + }); + } + else { + existing[0].zones = 'Multiple Zones'; + existing[0].zoneids.push(item.zoneid); + } + } +); args.response.success({ actionFilter: isoActionfilter, - data: items + data: itemsView }); } }); @@ -1527,85 +1797,6 @@ }); } }, - - copyISO: { - label: 'label.action.copy.ISO', - messages: { - notification: function(args) { - return 'Copying ISO'; - } - }, - createForm: { - title: 'label.action.copy.ISO', - desc: 'label.action.copy.ISO', - fields: { - destinationZoneId: { - label: 'label.destination.zone', - validation: { - required: true - }, - select: function(args) { - $.ajax({ - url: createURL("listZones&available=true"), - dataType: "json", - async: true, - success: function(json) { - var zoneObjs = []; - var items = json.listzonesresponse.zone; - if (items != null) { - for (var i = 0; i < items.length; i++) { - if (items[i].id != args.context.isos[0].zoneid) { //destination zone must be different from source zone - zoneObjs.push({ - id: items[i].id, - description: items[i].name - }); - } - } - } - args.response.success({ - data: zoneObjs - }); - } - }); - } - } - } - }, - action: function(args) { - var data = { - id: args.context.isos[0].id, - destzoneid: args.data.destinationZoneId - }; - if (args.context.isos[0].zoneid != undefined) { - $.extend(data, { - sourcezoneid: args.context.isos[0].zoneid - }); - } - - $.ajax({ - url: createURL('copyIso'), - data: data, - success: function(json) { - var jid = json.copytemplateresponse.jobid; - args.response.success({ - _custom: { - jobId: jid, - getUpdatedItem: function(json) { - return {}; //nothing in this ISO needs to be updated - }, - getActionFilter: function() { - return isoActionfilter; - } - } - }); - } - }); - }, - notification: { - poll: pollAsyncJobResult - } - }, - downloadISO: { label: 'label.action.download.ISO', messages: { @@ -1650,42 +1841,7 @@ notification: { poll: pollAsyncJobResult } - }, - - remove: { - label: 'label.action.delete.ISO', - messages: { - confirm: function(args) { - return 'message.action.delete.ISO'; - }, - notification: function(args) { - return 'label.action.delete.ISO'; - } - }, - action: function(args) { - var array1 = []; - if (args.context.isos[0].zoneid != null) - array1.push("&zoneid=" + args.context.isos[0].zoneid); - - $.ajax({ - url: createURL("deleteIso&id=" + args.context.isos[0].id + array1.join("")), - dataType: "json", - async: true, - success: function(json) { - var jid = json.deleteisosresponse.jobid; - args.response.success({ - _custom: { - jobId: jid - } - }); - } - }); - }, - notification: { - poll: pollAsyncJobResult - } } - }, tabs: { @@ -1704,12 +1860,6 @@ id: { label: 'ID' }, - zonename: { - label: 'label.zone.name' - }, - zoneid: { - label: 'label.zone.id' - }, displaytext: { label: 'label.description', isEditable: true, @@ -1717,13 +1867,6 @@ required: true } }, - isready: { - label: 'state.Ready', - converter: cloudStack.converters.toBooleanText - }, - status: { - label: 'label.status' - }, size: { label: 'label.size', converter: function(args) { @@ -1830,6 +1973,301 @@ }); } + }, + zones: { + title: 'label.zones', + listView: { + id: 'zones', + fields: { + zonename: { + label: 'label.name' + }, + status: { + label: 'label.status' + }, + isready: { + label: 'state.ready', + converter: cloudStack.converters.toBooleanText + } + }, + hideSearchBar: true, + + dataProvider: function(args) { + var jsonObj = args.context.isos[0]; + var apiCmd = "listIsos&isofilter=self&id=" + jsonObj.id; + + $.ajax({ + url: createURL(apiCmd), + dataType: "json", + success: function(json) { + var isos = json.listisosresponse.iso; + var zones = []; + zones = isos; + + args.response.success({ + actionFilter: isoActionfilter, + data: zones + }); + } + }); + }, + + detailView: { + actions: { + copyISO: { + label: 'label.action.copy.ISO', + messages: { + notification: function(args) { + return 'Copying ISO'; + } + }, + createForm: { + title: 'label.action.copy.ISO', + desc: 'label.action.copy.ISO', + fields: { + destinationZoneId: { + label: 'label.destination.zone', + validation: { + required: true + }, + select: function(args) { + $.ajax({ + url: createURL("listZones&available=true"), + dataType: "json", + async: true, + success: function(json) { + var zoneObjs = []; + var items = json.listzonesresponse.zone; + if (items != null) { + for (var i = 0; i < items.length; i++) { + if (items[i].id != args.context.zones[0].zoneid) { + zoneObjs.push({ + id: items[i].id, + description: items[i].name + }); + } + } + } + args.response.success({ + data: zoneObjs + }); + } + }); + } + } + } + }, + action: function(args) { + var data = { + id: args.context.isos[0].id, + destzoneid: args.data.destinationZoneId + }; + if (args.context.zones[0].zoneid != undefined) { + $.extend(data, { + sourcezoneid: args.context.zones[0].zoneid + }); + } + + $.ajax({ + url: createURL('copyIso'), + data: data, + success: function(json) { + var jid = json.copytemplateresponse.jobid; + args.response.success({ + _custom: { + jobId: jid, + getUpdatedItem: function(json) { + return {}; //nothing in this ISO needs to be updated + }, + getActionFilter: function() { + return isoActionfilter; + } + } + }); + } + }); + }, + notification: { + poll: pollAsyncJobResult + } + }, + + remove: { + label: 'label.action.delete.ISO', + messages: { + confirm: function(args) { + return 'message.action.delete.ISO'; + }, + notification: function(args) { + return 'label.action.delete.ISO'; + } + }, + action: function(args) { + var array1 = []; + if (args.context.zones[0].zoneid != null) + array1.push("&zoneid=" + args.context.zones[0].zoneid); + + $.ajax({ + url: createURL("deleteIso&id=" + args.context.isos[0].id + "&zoneid=" + args.context.zones[0].zoneid), + dataType: "json", + async: true, + success: function(json) { + var jid = json.deleteisosresponse.jobid; + args.response.success({ + _custom: { + jobId: jid + } + }); + } + }); + }, + notification: { + poll: pollAsyncJobResult + } + } + }, + tabs: { + details: { + title: 'label.details', + + fields: [{ + name: { + label: 'label.name', + isEditable: true, + validation: { + required: true + } + } + }, { + id: { + label: 'ID' + }, + zonename: { + label: 'label.zone.name' + }, + zoneid: { + label: 'label.zone.id' + }, + isready: { + label: 'state.Ready', + converter: cloudStack.converters.toBooleanText + }, + status: { + label: 'label.status' + } + },{ + displaytext: { + label: 'label.description', + isEditable: true, + validation: { + required: true + } + }, + size: { + label: 'label.size', + converter: function(args) { + if (args == null || args == 0) + return ""; + else + return cloudStack.converters.convertBytes(args); + } + }, + isextractable: { + label: 'extractable', + isBoolean: true, + isEditable: function() { + if (isAdmin()) + return true; + else + return false; + }, + converter: cloudStack.converters.toBooleanText + }, + bootable: { + label: 'label.bootable', + converter: cloudStack.converters.toBooleanText + }, + ispublic: { + label: 'label.public', + isBoolean: true, + isEditable: true, + converter: cloudStack.converters.toBooleanText + }, + isfeatured: { + label: 'label.featured', + isBoolean: true, + isEditable: function() { + if (isAdmin()) + return true; + else + return false; + }, + converter: cloudStack.converters.toBooleanText + }, + + ostypeid: { + label: 'label.os.type', + isEditable: true, + select: function(args) { + $.ajax({ + url: createURL("listOsTypes"), + dataType: "json", + async: true, + success: function(json) { + var ostypes = json.listostypesresponse.ostype; + var items = []; + $(ostypes).each(function() { + items.push({ + id: this.id, + description: this.description + }); + }); + args.response.success({ + data: items + }); + } + }); + } + }, + + domain: { + label: 'label.domain' + }, + account: { + label: 'label.account' + }, + created: { + label: 'label.created', + converter: cloudStack.converters.toLocalDate + } + }], + + tags: cloudStack.api.tags({ + resourceType: 'ISO', + contextId: 'isos' + }), + + dataProvider: function(args) { + var jsonObj = args.context.isos[0]; + var apiCmd = "listIsos&isofilter=self&id=" + jsonObj.id; + if (jsonObj.zoneid != null) + apiCmd = apiCmd + "&zoneid=" + args.context.zones[0].zoneid; + + $.ajax({ + url: createURL(apiCmd), + dataType: "json", + success: function(json) { + args.response.success({ + actionFilter: isoActionfilter, + data: json.listisosresponse.iso[0] + }); + } + }); + + } + } + } + }} } } } diff --git a/ui/scripts/ui-custom/accountsWizard.js b/ui/scripts/ui-custom/accountsWizard.js index 5ef0fa96b3..3259227d13 100644 --- a/ui/scripts/ui-custom/accountsWizard.js +++ b/ui/scripts/ui-custom/accountsWizard.js @@ -130,6 +130,89 @@ dataType: "json", async: false, success: function(json) { + //for testing only (begin) + /* + json = { + "ldapuserresponse": { + "count": 11, + "LdapUser": [ + { + "email": "test@test.com", + "principal": "CN=Administrator,CN=Users,DC=hyd-qa,DC=com", + "username": "Administrator", + "domain": "CN=Administrator" + }, + { + "email": "test@test.com", + "principal": "CN=Guest,CN=Users,DC=hyd-qa,DC=com", + "username": "Guest", + "domain": "CN=Guest" + }, + { + "email": "test@test.com", + "principal": "CN=IUSR_HYD-QA12,CN=Users,DC=hyd-qa,DC=com", + "username": "IUSR_HYD-QA12", + "domain": "CN=IUSR_HYD-QA12" + }, + { + "email": "test@test.com", + "principal": "CN=IWAM_HYD-QA12,CN=Users,DC=hyd-qa,DC=com", + "username": "IWAM_HYD-QA12", + "domain": "CN=IWAM_HYD-QA12" + }, + { + "email": "test@test.com", + "principal": "CN=SUPPORT_388945a0,CN=Users,DC=hyd-qa,DC=com", + "username": "SUPPORT_388945a0", + "domain": "CN=SUPPORT_388945a0" + }, + { + "principal": "CN=jessica j,CN=Users,DC=hyd-qa,DC=com", + "firstname": "jessica", + "lastname": "j", + "username": "jessica", + "domain": "CN=jessica j" + }, + { + "principal": "CN=krbtgt,CN=Users,DC=hyd-qa,DC=com", + "username": "krbtgt", + "domain": "CN=krbtgt" + }, + { + "email": "sadhu@sadhu.com", + "principal": "CN=sadhu,CN=Users,DC=hyd-qa,DC=com", + "firstname": "sadhu", + "username": "sadhu", + "domain": "CN=sadhu" + }, + { + "email": "test@test.com", + "principal": "CN=sangee1 hariharan,CN=Users,DC=hyd-qa,DC=com", + "firstname": "sangee1", + "lastname": "hariharan", + "username": "sangee1", + "domain": "CN=sangee1 hariharan" + }, + { + "email": "test@test.com", + "principal": "CN=sanjeev n.,CN=Users,DC=hyd-qa,DC=com", + "firstname": "sanjeev", + "username": "sanjeev", + "domain": "CN=sanjeev n." + }, + { + "email": "test@test.com", + "principal": "CN=test1dddd,CN=Users,DC=hyd-qa,DC=com", + "firstname": "test1", + "username": "test1dddd", + "domain": "CN=test1dddd" + } + ] + } + }; + */ + //for testing only (end) + if (json.ldapuserresponse.count > 0) { $(json.ldapuserresponse.LdapUser).each(function() { var $result = $(''); @@ -137,15 +220,15 @@ $result.append( $('').addClass('select').append( $('').attr({ - type: 'checkbox', name: 'username', value: this.username + type: 'checkbox', name: 'username', value: _s(this.username) }) ), - $('').addClass('name').html(this.firstname + ' ' + this.lastname) - .attr('title', this.firstname + ' ' + this.lastname), - $('').addClass('username').html(this.username) + $('').addClass('name').html(_s(this.firstname) + ' ' + _s(this.lastname)) + .attr('title', _s(this.firstname) + ' ' + _s(this.lastname)), + $('').addClass('username').html(_s(this.username)) .attr('title', this.username), - $('').addClass('email').html(this.email) - .attr('title', this.email) + $('').addClass('email').html(_s(this.email)) + .attr('title', _s(this.email)) ) $table.append($result); diff --git a/ui/scripts/ui-custom/instanceWizard.js b/ui/scripts/ui-custom/instanceWizard.js index f5f7b10cfa..527dc10547 100644 --- a/ui/scripts/ui-custom/instanceWizard.js +++ b/ui/scripts/ui-custom/instanceWizard.js @@ -59,6 +59,24 @@ }); data['new-network-ip'] = $form.find('.new-network .select.advanced .specify-ip input[type=text]').val(); + // Handle multi-disk service offerings + if ($form.find('.multi-disk-select-container').size()) { + data['disk-offerings-multi'] = []; + + var $diskGroups = $form.find('.disk-select-group'); + var $selectedDisks = $.grep($diskGroups, function (diskGroup) { + return $(diskGroup).find('input[type=checkbox]:checked').size(); + }); + + $selectedDisks.map(function (disk) { + data['disk-offerings-multi'].push( + $.extend($(disk).data('json-obj'), { + _diskOfferingId: $(disk).find('input[type=radio]:checked').val() + }) + ); + }); + } + args.action({ // Populate data context: context, @@ -460,7 +478,7 @@ var customIops = item[args.customIopsFlag]; - if (customIops) { + if (customIops && args.canShowCustomIops) { $step.addClass('custom-iops'); } else { $step.removeClass('custom-iops'); @@ -491,7 +509,11 @@ return { response: { success: function(args) { + var multiDisk = args.multiDisk; + + $step.find('.multi-disk-select-container').remove(); $step.removeClass('custom-disk-size'); + if (args.required) { $step.find('.section.no-thanks').hide(); $step.addClass('required'); @@ -500,15 +522,68 @@ $step.removeClass('required'); } - $step.find('.content .select-container').append( - makeSelects('diskofferingid', args.data.diskOfferings, { - id: 'id', - name: 'name', - desc: 'displaytext' - }, { - 'wizard-field': 'disk-offering' - }) - ); + var $selectContainer = $step.find('.content .select-container:not(.multi-disk)'); + + if (multiDisk) { // Render as multiple groups for each disk + var $multiDiskSelect = $('
').addClass('multi-disk-select-container'); + + $(multiDisk).map(function(index, disk) { + var $group = $('
').addClass('disk-select-group'); + var $header = $('
').addClass('disk-select-header').append( + $('
').addClass('title').html(disk.label) + ).appendTo($group); + var $checkbox = $('').addClass('multi-disk-select') + .attr({ + type: 'checkbox', + 'disk-id': disk.id + }) + .prependTo($header); + var $multiSelectContainer = $selectContainer.clone().append( + makeSelects('diskofferingid.' + disk.id, args.data.diskOfferings, { + id: 'id', + name: 'name', + desc: 'displaytext' + }, { + 'wizard-field': 'disk-offering' + }) + ).appendTo($group).addClass('multi-disk'); + + $group.appendTo($multiDiskSelect); + $group.data('json-obj', disk); + + // Show-hide disk group selects + $checkbox.click(function() { + $group.toggleClass('selected'); + $group.find('.select:first input[type=radio]').click(); + + if (!$multiDiskSelect.find('input[type=checkbox]:checked').size()) { + $step.find('.no-thanks input[type=radio]').click(); + } else { + $step.find('.no-thanks input[type=radio]').attr('checked', false); + } + }); + + // Add custom disk size box + $step.find('.section.custom-size').clone().hide().appendTo($group); + }); + + $multiDiskSelect.insertAfter($selectContainer); + $selectContainer.hide(); + + // Fix issue with containers always showing after reload + $multiDiskSelect.find('.select-container').attr('style', null); + } else { + $selectContainer.show(); + $step.find('.content .select-container').append( + makeSelects('diskofferingid', args.data.diskOfferings, { + id: 'id', + name: 'name', + desc: 'displaytext' + }, { + 'wizard-field': 'disk-offering' + }) + ); + } $step.find('input[type=radio]').bind('change', function() { var $target = $(this); @@ -516,44 +591,81 @@ var item = $.grep(args.data.diskOfferings, function(elem) { return elem.id == val; })[0]; + var isMultiDisk = $step.find('.multi-disk-select').size(); - if (!item) return true; + // Uncheck any multi-select groups + if ($target.closest('.no-thanks').size() && isMultiDisk) { + $step.find('.disk-select-group input[type=checkbox]:checked').click(); + $(this).attr('checked', true); + + return true; + } + + if (!item) { + if (isMultiDisk) { + $(this).closest('.disk-select-group .section.custom-size').hide(); + $(this).closest('.disk-select-group').removeClass('custom-size'); + } else { + // handle removal of custom size controls + $step.find('.section.custom-size').hide(); + $step.removeClass('custom-disk-size'); + + // handle removal of custom IOPS controls + $step.removeClass('custom-iops-do'); + } + + return true; + } var custom = item[args.customFlag]; - $step.find('.custom-size-label').remove(); + if (!isMultiDisk) $step.find('.custom-size-label').remove(); - if (custom) { + if (custom && !isMultiDisk) { $target.parent().find('.name') + .append( + $('').addClass('custom-size-label') + .append(': ') .append( - $('').addClass('custom-size-label') - .append(': ') - .append( - $('').addClass('custom-disk-size').html( - $step.find('.custom-size input[name=size]').val() - ) - ) - .append(' GB') + $('').addClass('custom-disk-size').html( + $step.find('.custom-size input[name=size]').val() + ) + ) + .append(' GB') ); $target.parent().find('.select-desc .desc') + .append( + $('').addClass('custom-size-label') + .append(', ') .append( - $('').addClass('custom-size-label') - .append(', ') - .append( - $('').addClass('custom-disk-size').html( - $step.find('.custom-size input[name=size]').val() - ) - ) - .append(' GB') + $('').addClass('custom-disk-size').html( + $step.find('.custom-size input[name=size]').val() + ) + ) + .append(' GB') ); $step.find('.section.custom-size').show(); $step.addClass('custom-disk-size'); $target.closest('.select-container').scrollTop( $target.position().top ); + } else if (custom && isMultiDisk) { + $(this).closest('.disk-select-group').addClass('custom-size'); } else { - $step.find('.section.custom-size').hide(); - $step.removeClass('custom-disk-size'); + if (isMultiDisk) { + $(this).closest('.disk-select-group').removeClass('custom-size'); + } else { + $step.find('.section.custom-size').hide(); + $step.removeClass('custom-disk-size'); + } + } + + var customIops = item[args.customIopsDoFlag]; + + if (customIops) { + $step.addClass('custom-iops-do'); + } else { + $step.removeClass('custom-iops-do'); } return true; @@ -1088,17 +1200,22 @@ $futureSteps.removeClass('loaded'); }); + var minCustomDiskSize = args.minDiskOfferingSize ? + args.minDiskOfferingSize() : 1; + var maxCustomDiskSize = args.maxDiskOfferingSize ? args.maxDiskOfferingSize() : 100; // Setup tabs and slider + $wizard.find('.section.custom-size .size.min span').html(minCustomDiskSize); + $wizard.find('.section.custom-size input[type=text]').val(minCustomDiskSize); $wizard.find('.section.custom-size .size.max span').html(maxCustomDiskSize); $wizard.find('.tab-view').tabs(); $wizard.find('.slider').each(function() { var $slider = $(this); - + $slider.slider({ - min: 1, + min: minCustomDiskSize, max: maxCustomDiskSize, start: function(event) { $slider.closest('.section.custom-size').find('input[type=radio]').click(); diff --git a/ui/scripts/ui-custom/physicalResources.js b/ui/scripts/ui-custom/physicalResources.js index fcc2f6ab5b..ac379b462f 100644 --- a/ui/scripts/ui-custom/physicalResources.js +++ b/ui/scripts/ui-custom/physicalResources.js @@ -117,8 +117,8 @@ type: "POST", url: createURL('uploadCustomCertificate'), data: { - certificate: encodeURIComponent(args.data.certificate), - privatekey: encodeURIComponent(args.data.privatekey), + certificate: args.data.certificate, + privatekey: args.data.privatekey, domainsuffix: args.data.domainsuffix }, dataType: 'json', @@ -136,7 +136,7 @@ clearInterval(uploadCustomCertificateIntervalID); if (result.jobstatus == 1) { cloudStack.dialog.notice({ - message: 'Update SSL Certiciate succeeded' + message: 'Update SSL Certificate succeeded' }); } else if (result.jobstatus == 2) { cloudStack.dialog.notice({ diff --git a/ui/scripts/ui-custom/zoneChart.js b/ui/scripts/ui-custom/zoneChart.js index bc30d51053..ac3c0e475a 100644 --- a/ui/scripts/ui-custom/zoneChart.js +++ b/ui/scripts/ui-custom/zoneChart.js @@ -24,7 +24,7 @@ */ var viewAllButton = function(args) { var $viewAll = $('
').addClass('button view-all'); - var $label = $('').addClass('view-all-label').html(args.label ? args.label : 'label.view.all'); + var $label = $('').addClass('view-all-label').html(args.label ? args.label : _l('label.view.all')); var $browser = args.$browser; var action = args.action; // Launch a list view @@ -166,13 +166,13 @@ var $label = $('').addClass('label'); $li.addClass(id); - $label.html(resource.label); + $label.html(_l(resource.label)); $label.appendTo($li); // View all if (resource.viewAll) { viewAllButton($.extend(resource.viewAll, { - title: resource.label, + title: _l(resource.label), $browser: $browser, context: context })).appendTo($li); @@ -383,6 +383,9 @@ }, 7: { name: _l('label.vlan') + }, + 19: { + name: _l('GPU') } }; diff --git a/ui/scripts/ui/dialog.js b/ui/scripts/ui/dialog.js index 82e7fd428c..0fddcf70b2 100644 --- a/ui/scripts/ui/dialog.js +++ b/ui/scripts/ui/dialog.js @@ -223,7 +223,10 @@ }); if ($dependsOn.is('[type=checkbox]')) { - var isReverse = args.form.fields[dependsOn].isReverse; + + var isReverse = false; + if (args.form.fields[dependsOn]) + isReverse = args.form.fields[dependsOn].isReverse; // Checkbox $dependsOn.bind('click', function(event) { @@ -268,24 +271,31 @@ context: args.context, response: { success: function(args) { + if (args.data == undefined || args.data.length == 0) { + var $option = $('