diff --git a/api/src/org/apache/cloudstack/api/command/admin/host/ListHostsCmd.java b/api/src/org/apache/cloudstack/api/command/admin/host/ListHostsCmd.java index 69c69802bfe..eaaec3091a7 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/host/ListHostsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/host/ListHostsCmd.java @@ -74,9 +74,6 @@ public class ListHostsCmd extends BaseListCmd { @Parameter(name=ApiConstants.ZONE_ID, type=CommandType.UUID, entityType = ZoneResponse.class, description="the Zone ID for the host") private Long zoneId; - - @Parameter(name=ApiConstants.ZONE_TYPE, type=CommandType.STRING, description="the network type of the zone that the virtual machine belongs to") - private String zoneType; @Parameter(name=ApiConstants.VIRTUAL_MACHINE_ID, type=CommandType.UUID, entityType = UserVmResponse.class, required=false, description="lists hosts in the same cluster as this VM and flag hosts with enough CPU/RAm to host this VM") @@ -126,10 +123,6 @@ public class ListHostsCmd extends BaseListCmd { public Long getZoneId() { return zoneId; } - - public String getZoneType() { - return zoneType; - } public Long getVirtualMachineId() { return virtualMachineId; diff --git a/api/src/org/apache/cloudstack/api/command/admin/ldap/LDAPConfigCmd.java b/api/src/org/apache/cloudstack/api/command/admin/ldap/LDAPConfigCmd.java index 2976de4bf28..2726f84163d 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/ldap/LDAPConfigCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/ldap/LDAPConfigCmd.java @@ -43,10 +43,9 @@ public class LDAPConfigCmd extends BaseCmd { ///////////////////////////////////////////////////// //////////////// API parameters ///////////////////// ///////////////////////////////////////////////////// - - @Parameter(name=ApiConstants.LIST_ALL, type=CommandType.STRING, description="Hostname or ip address of the ldap server eg: my.ldap.com") - private String listall; - + @Parameter(name=ApiConstants.LIST_ALL, type=CommandType.BOOLEAN, description="If true return current LDAP configuration") + private Boolean listAll; + @Parameter(name=ApiConstants.HOST_NAME, type=CommandType.STRING, description="Hostname or ip address of the ldap server eg: my.ldap.com") private String hostname; @@ -78,10 +77,10 @@ public class LDAPConfigCmd extends BaseCmd { /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// - public String getListAll() { - return listall == null ? "false" : listall; + public Boolean getListAll() { + return listAll == null ? Boolean.FALSE : listAll; } - + public String getBindPassword() { return bindPassword; } @@ -156,16 +155,15 @@ public class LDAPConfigCmd extends BaseCmd { InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException { try { - if ("true".equalsIgnoreCase(getListAll())){ + if (getListAll()){ // return the existing conf LDAPConfigCmd cmd = _configService.listLDAPConfig(this); - LDAPConfigResponse lr = _responseGenerator.createLDAPConfigResponse(cmd.getHostname(), cmd.getPort(), cmd.getUseSSL(), - cmd.getQueryFilter(), cmd.getSearchBase(), cmd.getBindDN()); + LDAPConfigResponse lr = _responseGenerator.createLDAPConfigResponse(cmd.getHostname(), cmd.getPort(), cmd.getUseSSL(), cmd.getQueryFilter(), cmd.getSearchBase(), cmd.getBindDN()); lr.setResponseName(getCommandName()); this.setResponseObject(lr); } else if (getHostname()==null || getSearchBase() == null || getQueryFilter() == null) { - throw new InvalidParameterValueException("You need to provide hostname, serachbase and queryfilter to configure your LDAP server"); + throw new InvalidParameterValueException("You need to provide hostname, searchbase and queryfilter to configure your LDAP server"); } else { boolean result = _configService.updateLDAP(this); diff --git a/api/src/org/apache/cloudstack/api/command/admin/storage/ListStoragePoolsCmd.java b/api/src/org/apache/cloudstack/api/command/admin/storage/ListStoragePoolsCmd.java index 17adb18ecc8..85a3c22a3e2 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/storage/ListStoragePoolsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/storage/ListStoragePoolsCmd.java @@ -59,9 +59,6 @@ public class ListStoragePoolsCmd extends BaseListCmd { @Parameter(name=ApiConstants.ZONE_ID, type=CommandType.UUID, entityType = ZoneResponse.class, description="the Zone ID for the storage pool") private Long zoneId; - - @Parameter(name=ApiConstants.ZONE_TYPE, type=CommandType.STRING, description="the network type of the zone that the virtual machine belongs to") - private String zoneType; @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType = StoragePoolResponse.class, description="the ID of the storage pool") @@ -95,10 +92,6 @@ public class ListStoragePoolsCmd extends BaseListCmd { return zoneId; } - public String getZoneType() { - return zoneType; - } - public Long getId() { return id; } 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 b2a2ce071f1..d3b29db2801 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 @@ -78,9 +78,6 @@ public class ListVMsCmd extends BaseListTaggedResourcesCmd { @Parameter(name=ApiConstants.ZONE_ID, type=CommandType.UUID, entityType=ZoneResponse.class, description="the availability zone ID") private Long zoneId; - @Parameter(name=ApiConstants.ZONE_TYPE, type=CommandType.STRING, description="the network type of the zone that the virtual machine belongs to") - private String zoneType; - @Parameter(name=ApiConstants.FOR_VIRTUAL_NETWORK, type=CommandType.BOOLEAN, description="list by network type; true if need to list vms using Virtual Network, false otherwise") private Boolean forVirtualNetwork; @@ -149,10 +146,6 @@ public class ListVMsCmd extends BaseListTaggedResourcesCmd { return zoneId; } - public String getZoneType() { - return zoneType; - } - public Boolean getForVirtualNetwork() { return forVirtualNetwork; } 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 91316b02167..0bced56918b 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 @@ -67,8 +67,6 @@ public class ListVolumesCmd extends BaseListTaggedResourcesCmd { description="the ID of the availability zone") private Long zoneId; - @Parameter(name=ApiConstants.ZONE_TYPE, type=CommandType.STRING, description="the network type of the zone that the virtual machine belongs to") - private String zoneType; ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// @@ -103,9 +101,6 @@ public class ListVolumesCmd extends BaseListTaggedResourcesCmd { return zoneId; } - public String getZoneType() { - return zoneType; - } ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// diff --git a/client/tomcatconf/nonossComponentContext.xml.in b/client/tomcatconf/nonossComponentContext.xml.in index 16fd88337fb..143aa220cfc 100644 --- a/client/tomcatconf/nonossComponentContext.xml.in +++ b/client/tomcatconf/nonossComponentContext.xml.in @@ -370,6 +370,7 @@ + diff --git a/docs/en-US/CloudStack_GSoC_Guide.xml b/docs/en-US/CloudStack_GSoC_Guide.xml index 1f435931363..cd8205d34ba 100644 --- a/docs/en-US/CloudStack_GSoC_Guide.xml +++ b/docs/en-US/CloudStack_GSoC_Guide.xml @@ -50,5 +50,6 @@ + diff --git a/docs/en-US/add-loadbalancer-rule-vpc.xml b/docs/en-US/add-loadbalancer-rule-vpc.xml index b7b9e3e7613..82e870243d1 100644 --- a/docs/en-US/add-loadbalancer-rule-vpc.xml +++ b/docs/en-US/add-loadbalancer-rule-vpc.xml @@ -25,16 +25,16 @@ External LB is nothing but a LB rule created to redirect the traffic received at a public IP of the VPC virtual router. The traffic is load balanced within a tier based on your configuration. Citrix NetScaler and VPC virtual router are supported for external LB. When you use internal LB - service, traffic received at a tier is load balanced across different tiers within the VPC. For - example, traffic reached at Web tier is redirected to Application tier. External load balancing - devices are not supported for internal LB. The service is provided by a internal LB VM + service, traffic received at a tier is load balanced across different VMs within that tier. For + example, traffic reached at Web tier is redirected to another VM in that tier. External load + balancing devices are not supported for internal LB. The service is provided by a internal LB VM configured on the target tier.
Load Balancing Within a Tier (External LB) A &PRODUCT; user or administrator may create load balancing rules that balance traffic received at a public IP to one or more VMs that belong to a network tier that provides load balancing service in a VPC. A user creates a rule, specifies an algorithm, and assigns the - rule to a set of VMs within a VPC. + rule to a set of VMs within a tier. Log in to the &PRODUCT; UI as an administrator or end user. diff --git a/docs/en-US/create-vpn-connection-vpc.xml b/docs/en-US/create-vpn-connection-vpc.xml index 1fba09e18fb..88a058c9f89 100644 --- a/docs/en-US/create-vpn-connection-vpc.xml +++ b/docs/en-US/create-vpn-connection-vpc.xml @@ -20,6 +20,7 @@ -->
Creating a VPN Connection + &PRODUCT; supports creating up to 8 VPN connections. Log in to the &PRODUCT; UI as an administrator or end user. @@ -38,19 +39,37 @@ Click the Settings icon. - The following options are displayed. + For each tier, the following options are displayed: - IP Addresses + Internal LB - Gateways + Public LB IP - Site-to-Site VPN + Static NAT - Network ASLs + Virtual Machines + + + CIDR + + + The following router information is displayed: + + + Private Gateways + + + Public IP Addresses + + + Site-to-Site VPNs + + + Network ACL Lists @@ -100,4 +119,4 @@ -
\ No newline at end of file +
diff --git a/docs/en-US/create-vpn-gateway-for-vpc.xml b/docs/en-US/create-vpn-gateway-for-vpc.xml index 396a7d9d174..0f8a0dcc03b 100644 --- a/docs/en-US/create-vpn-gateway-for-vpc.xml +++ b/docs/en-US/create-vpn-gateway-for-vpc.xml @@ -38,19 +38,37 @@ Click the Settings icon. - The following options are displayed. + For each tier, the following options are displayed: - IP Addresses + Internal LB - Gateways + Public LB IP - Site-to-Site VPN + Static NAT - Network ACLs + Virtual Machines + + + CIDR + + + The following router information is displayed: + + + Private Gateways + + + Public IP Addresses + + + Site-to-Site VPNs + + + Network ACL Lists @@ -77,4 +95,4 @@ - \ No newline at end of file + diff --git a/docs/en-US/delete-reset-vpn.xml b/docs/en-US/delete-reset-vpn.xml index 318e5fe321e..2fe85d279b6 100644 --- a/docs/en-US/delete-reset-vpn.xml +++ b/docs/en-US/delete-reset-vpn.xml @@ -38,19 +38,37 @@ Click the Settings icon. - The following options are displayed. + For each tier, the following options are displayed: - IP Addresses + Internal LB - Gateways + Public LB IP - Site-to-Site VPN + Static NAT - Network ASLs + Virtual Machines + + + CIDR + + + The following router information is displayed: + + + Private Gateways + + + Public IP Addresses + + + Site-to-Site VPNs + + + Network ACL Lists diff --git a/docs/en-US/gsoc-shiva.xml b/docs/en-US/gsoc-shiva.xml new file mode 100644 index 00000000000..400af3c82f6 --- /dev/null +++ b/docs/en-US/gsoc-shiva.xml @@ -0,0 +1,70 @@ + + +%BOOK_ENTITIES; +]> + + + + + Shiva Teja's 2013 GSoC Proposal + This chapter describes Shiva Teja's 2013 Google Summer of Code project within the &PRODUCT; ASF project. It is a copy paste of the submitted proposal. +
+ Abstract + + The aim of this project is to create a new modular UI for Apache CloudStack using Bootstrap by Twitter and Backbone.js. To achieve this easily, I'll be creating a RESTful wrapper API on top of the current CloudStack API. I hope this project will make custom UIs for CloudStack very easy. + + Why does CloudStack need a new UI? + + The current UI cannot be reused easliy to make a custom UI. The UI I will be making using backbone.js can be reused very easily to make custom UIs. The models, views, routers etc can remain the same in all the UIs. The user interface can be changed just by changing the templates. Check the implementation details below for further details. + + Why does it need a RESTful wrapper API ? + + Backbone.js heavily depends on RESTful architecture. Making a new UI with backbone.js using a query based API might not be easy. +
+
+ List of deliverables + + A new UI for CloudStack(with almost all features in the current UI and new ones, if any). + A RESTful wrapper API on top of the CloudStack API + Some documentation about using this UI to make a custom UI. + +
+
+ Approach + Wrapper API: Backbone.js, by default, uses four HTTP methods(GET, PUT, POST, DELETE) for communicating with the server. It uses GET to fetch a resource from the server, POST to create a resource, PUT to update the resource and DELETE to delete the resource. A query based API can probably be used to make the UI by overriding backbone's default sync function. But it makes more sense to have an API which supports the above mentioned method and is resource based. This RESTful API works on top of the CloudStack API. The main task is to map the combinations of these HTTP methods and the resources to appropriate CloudStack API command. The other task is to decide on how the URLs should look like. Say for starting a virtual machine, for it to be RESTful, we have to use POST as we are creating a resource, or a PUT as we are changing the state of a virtual machine. So the possible options on the URL could be to do a POST /runningvirtualmachines and respond with 201 Created code or a PUT on /virtualmachines/id and respond with 200 OK. If these are decided, the wrapper can be generated or be written manually, which can use defined patters to map to appropriate CloudStack API commands(Similar to what cloudmonkey does. See this prototype. I can use cloudmonkey's code to generate the required API entity verb relationships. Each verb will have a set of rules saying what method should be used in the RESTful API and how should it look like in the URL. Another possible way could be to group entities first manually and write the wrapper manually(something like zone/pods/cluster). Some possibilities have been discussed in this thread. + + UI: It will be a single page app. It'll use client side templating for rendering. This makes it very easy to make a custom UI because it can be achieved just by changing the templates. Backbone views will make use of these templates to render the appropriate models/collections. A completely new interface can be written just by changing the templates. Javascript code can completely remain the same. The views will take care of appropriate DOM events. Such event will correspond to appropriate model/collection chages, thus causing appropriate API calls. +
+
+ Approximate Schedle + Till June 17 - Decide on how the RESTful API should look like and design algorithms to generate the wrapper. + July 5(soft deadline), July 10(hard deadline) : Wrapper API will be ready. + July 12(soft) - July 15(hard): Make basic wireframes and designs for the website and get them approved. + July 29(mid term evaluation) : All the basic models, views, routes of the UI should be ready along with a few templates. + August 15(hard deadline, shouldn't take much time actually) - A basic usable UI where users can just list all the entities which are present in the current UI's main navigation( Like Instances, Templates, Accounts etc) + September 1(hard) - From this UI, users should be able to launch instances, edit settings of most of the entities. + September 16(Pencil down!) - Fix some design tweaks and finish a completely usable interface with functions similar to current UI. + September 23 - Finish the documentation on how to use this UI to make custom UIs. +
+
+ About Me + I am a 2nd year computer science undergrad studying at IIT Mandi, India. I've been using Python for an year and a half now. I've used Django, Flask and Tornado for my small projects. Along with Python, I use C++ for competitive programming. Recently, I fell in love with Haskell. I've always been fascinated about web technologies. +
+
diff --git a/docs/en-US/pvlan.xml b/docs/en-US/pvlan.xml index c4d8f921c87..d569507f973 100644 --- a/docs/en-US/pvlan.xml +++ b/docs/en-US/pvlan.xml @@ -32,14 +32,10 @@ Isolate VMs in a shared networks by using Private VLANs. - Supported in both VPC and non-VPC deployments. + Supported on KVM, XenServer, and VMware hypervisors - Supported on all hypervisors. - - - Allow end users to deploy VMs in an isolated networks, or a VPC, or a Private - VLAN-enabled shared network. + PVLAN-enabled shared network can be a part of multiple networks of a guest VM.
@@ -121,55 +117,16 @@ switch, connect the switch to upper switch by using cables. The number of cables should be greater than the number of PVLANs used. - - If your Catalyst switch supports PVLAN, but not PVLAN promiscuous trunk mode, perform - the following: - - - Configure one of the switch port as trunk for management network (management - VLAN). - - - For each PVLAN, perform the following: - - - Connect a port of the Catalyst switch to the upper switch. - - - Set the port in the Catalyst Switch in promiscuous mode for one pair of - PVLAN. - - - Set the port in the upper switch to access mode, and allow only the traffic of - the primary VLAN of the PVLAN pair. - - - - - Configure private VLAN on your physical switches out-of-band. - Open vSwitch (OVS) used by XenServer and KVM does not support PVLAN. Therefore, - simulate PVLAN on OVS for XenServer and KVM by modifying the flow table to achieve the - following: - - - For every traffic leaving user VMs, tag with the secondary isolated VLAN - ID. - - - Change the VLAN ID to primary VLAN ID. - This allows the traffic which is tagged with the secondary isolated VLAN ID reach - the DHCP server. - - - The gateway is PVLAN-unaware; therefore, the switch connected to the gateway - should translate all the secondary VLAN to primary VLAN for communicating with the - gateway. - - + Before you use PVLAN on XenServer and KVM, enable Open vSwitch (OVS) . + + OVS on XenServer and KVM does not support PVLAN. Therefore, simulate PVLAN on OVS + for XenServer and KVM by modifying the flow table and tagging every traffic leaving + guest VMs with the secondary VLAN ID. +
@@ -208,41 +165,83 @@ Specify the following: - Name: + Name: The name of the network. This will be + visible to the user. - Description: + Description: The short description of the network + that can be displayed to users. - VLAN ID: + VLAN ID: The unique ID of the VLAN. - Private VLAN ID: + Isolated VLAN ID: The unique ID of the Secondary + Isolated VLAN. + For the description on Secondary Isolated VLAN, see . - Scope: + Scope: The available scopes are Domain, Account, + Project, and All. + + + Domain: Selecting Domain limits the scope of + this guest network to the domain you specify. The network will not be available + for other domains. If you select Subdomain Access, the guest network is available + to all the sub domains within the selected domain. + + + Account: The account for which the guest + network is being created for. You must specify the domain the account belongs + to. + + + Project: The project for which the guest + network is being created for. You must specify the domain the project belongs + to. + + + All: The guest network is available for all + the domains, account, projects within the selected zone. + + - Network Offering: + Network Offering: If the administrator has + configured multiple network offerings, select the one you want to use for this + network. - Gateway: + Gateway: The gateway that the guests should + use. - Netmask: + Netmask: The netmask in use on the subnet the + guests will use. - IP Range: + IP Range: A range of IP addresses that are + accessible from the Internet and are assigned to the guest VMs. + If one NIC is used, these IPs should be in the same CIDR in the case of + IPv6. - IPv6 CIDR: + IPv6 CIDR: The network prefix that defines the + guest network subnet. This is the CIDR that describes the IPv6 addresses in use in the + guest networks in this zone. To allot IP addresses from within a particular address + block, enter a CIDR. - Network Domain: + Network Domain: A custom DNS suffix at the level + of a network. If you want to assign a special domain name to the guest VM network, + specify a DNS suffix. - Click OK to confirm. + + Click OK to confirm. + diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java index 817da0f85db..ec4f14fe981 100755 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java @@ -3310,7 +3310,9 @@ ServerResource { ConsoleDef console = new ConsoleDef("pty", null, null, (short) 0); devices.addDevice(console); - GraphicDef grap = new GraphicDef("vnc", (short) 0, true, null, null, + //add the VNC port passwd here, get the passwd from the vmInstance. + String passwd = vmTO.getVncPassword(); + GraphicDef grap = new GraphicDef("vnc", (short) 0, true, null, passwd, null); devices.addDevice(grap); diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java index da554b051a7..0aa0e148dd1 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java @@ -991,7 +991,7 @@ public class LibvirtVMDef { if (_listenAddr != null) { graphicBuilder.append(" listen='" + _listenAddr + "'"); } else { - graphicBuilder.append(" listen='' "); + graphicBuilder.append(" listen=''"); } if (_passwd != null) { graphicBuilder.append(" passwd='" + _passwd + "'"); diff --git a/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtComputingResourceTest.java b/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtComputingResourceTest.java index 0bafd073f68..c82c31fc510 100644 --- a/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtComputingResourceTest.java +++ b/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtComputingResourceTest.java @@ -80,7 +80,7 @@ public class LibvirtComputingResourceTest { vmStr += "\n"; vmStr += "\n"; vmStr += "\n"; - vmStr += "\n"; + vmStr += "\n"; vmStr += "\n"; vmStr += "\n"; vmStr += "\n"; @@ -156,7 +156,7 @@ public class LibvirtComputingResourceTest { vmStr += "\n"; vmStr += "\n"; vmStr += "\n"; - vmStr += "\n"; + vmStr += "\n"; vmStr += "\n"; vmStr += "\n"; vmStr += "\n"; diff --git a/server/src/com/cloud/api/query/QueryManagerImpl.java b/server/src/com/cloud/api/query/QueryManagerImpl.java index beda75e863c..f70f5aef599 100644 --- a/server/src/com/cloud/api/query/QueryManagerImpl.java +++ b/server/src/com/cloud/api/query/QueryManagerImpl.java @@ -636,8 +636,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { c.addCriteria(Criteria.ID, cmd.getId()); c.addCriteria(Criteria.NAME, cmd.getInstanceName()); c.addCriteria(Criteria.STATE, cmd.getState()); - c.addCriteria(Criteria.DATACENTERID, cmd.getZoneId()); - c.addCriteria(Criteria.DATACENTERTYPE, cmd.getZoneType()); + c.addCriteria(Criteria.DATACENTERID, cmd.getZoneId()); c.addCriteria(Criteria.GROUPID, cmd.getGroupId()); c.addCriteria(Criteria.FOR_VIRTUAL_NETWORK, cmd.getForVirtualNetwork()); c.addCriteria(Criteria.NETWORKID, cmd.getNetworkId()); @@ -686,8 +685,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { Object name = c.getCriteria(Criteria.NAME); Object state = c.getCriteria(Criteria.STATE); Object notState = c.getCriteria(Criteria.NOTSTATE); - Object zoneId = c.getCriteria(Criteria.DATACENTERID); - Object zoneType = c.getCriteria(Criteria.DATACENTERTYPE); + Object zoneId = c.getCriteria(Criteria.DATACENTERID); Object pod = c.getCriteria(Criteria.PODID); Object hostId = c.getCriteria(Criteria.HOSTID); Object hostName = c.getCriteria(Criteria.HOSTNAME); @@ -709,8 +707,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { sb.and("stateEQ", sb.entity().getState(), SearchCriteria.Op.EQ); sb.and("stateNEQ", sb.entity().getState(), SearchCriteria.Op.NEQ); sb.and("stateNIN", sb.entity().getState(), SearchCriteria.Op.NIN); - sb.and("dataCenterId", sb.entity().getDataCenterId(), SearchCriteria.Op.EQ); - sb.and("dataCenterType", sb.entity().getDataCenterType(), SearchCriteria.Op.EQ); + sb.and("dataCenterId", sb.entity().getDataCenterId(), SearchCriteria.Op.EQ); sb.and("podId", sb.entity().getPodId(), SearchCriteria.Op.EQ); sb.and("hypervisorType", sb.entity().getHypervisorType(), SearchCriteria.Op.EQ); sb.and("hostIdEQ", sb.entity().getHostId(), SearchCriteria.Op.EQ); @@ -824,11 +821,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { sc.setParameters("stateNEQ", "Destroyed"); } } - - if (zoneType != null) { - sc.setParameters("dataCenterType", zoneType); - } - + if (pod != null) { sc.setParameters("podId", pod); @@ -1422,8 +1415,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { public Pair, Integer> searchForServersInternal(ListHostsCmd cmd) { - Long zoneId = _accountMgr.checkAccessAndSpecifyAuthority(UserContext.current().getCaller(), cmd.getZoneId()); - String zoneType = cmd.getZoneType(); + Long zoneId = _accountMgr.checkAccessAndSpecifyAuthority(UserContext.current().getCaller(), cmd.getZoneId()); Object name = cmd.getHostName(); Object type = cmd.getType(); Object state = cmd.getState(); @@ -1444,8 +1436,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { sb.and("name", sb.entity().getName(), SearchCriteria.Op.LIKE); sb.and("type", sb.entity().getType(), SearchCriteria.Op.LIKE); sb.and("status", sb.entity().getStatus(), SearchCriteria.Op.EQ); - sb.and("dataCenterId", sb.entity().getZoneId(), SearchCriteria.Op.EQ); - sb.and("dataCenterType", sb.entity().getZoneType(), SearchCriteria.Op.EQ); + sb.and("dataCenterId", sb.entity().getZoneId(), SearchCriteria.Op.EQ); sb.and("podId", sb.entity().getPodId(), SearchCriteria.Op.EQ); sb.and("clusterId", sb.entity().getClusterId(), SearchCriteria.Op.EQ); sb.and("resourceState", sb.entity().getResourceState(), SearchCriteria.Op.EQ); @@ -1489,10 +1480,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { } if (zoneId != null) { sc.setParameters("dataCenterId", zoneId); - } - if (zoneType != null) { - sc.setParameters("dataCenterType", zoneType); - } + } if (pod != null) { sc.setParameters("podId", pod); } @@ -1549,8 +1537,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { String type = cmd.getType(); Map tags = cmd.getTags(); - Long zoneId = cmd.getZoneId(); - String zoneType = cmd.getZoneType(); + Long zoneId = cmd.getZoneId(); Long podId = null; if (_accountMgr.isAdmin(caller.getType())) { podId = cmd.getPodId(); @@ -1577,8 +1564,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); sb.and("volumeType", sb.entity().getVolumeType(), SearchCriteria.Op.LIKE); sb.and("instanceId", sb.entity().getVmId(), SearchCriteria.Op.EQ); - sb.and("dataCenterId", sb.entity().getDataCenterId(), SearchCriteria.Op.EQ); - sb.and("dataCenterType", sb.entity().getDataCenterType(), SearchCriteria.Op.EQ); + sb.and("dataCenterId", sb.entity().getDataCenterId(), SearchCriteria.Op.EQ); sb.and("podId", sb.entity().getPodId(), SearchCriteria.Op.EQ); // Only return volumes that are not destroyed sb.and("state", sb.entity().getState(), SearchCriteria.Op.NEQ); @@ -1637,10 +1623,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { } if (zoneId != null) { sc.setParameters("dataCenterId", zoneId); - } - if (zoneType != null) { - sc.setParameters("dataCenterType", zoneType); - } + } if (podId != null) { sc.setParameters("podId", podId); } @@ -1886,8 +1869,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { private Pair, Integer> searchForStoragePoolsInternal(ListStoragePoolsCmd cmd) { - Long zoneId = _accountMgr.checkAccessAndSpecifyAuthority(UserContext.current().getCaller(), cmd.getZoneId()); - String zoneType = cmd.getZoneType(); + Long zoneId = _accountMgr.checkAccessAndSpecifyAuthority(UserContext.current().getCaller(), cmd.getZoneId()); Object id = cmd.getId(); Object name = cmd.getStoragePoolName(); Object path = cmd.getPath(); @@ -1906,8 +1888,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); sb.and("name", sb.entity().getName(), SearchCriteria.Op.LIKE); sb.and("path", sb.entity().getPath(), SearchCriteria.Op.EQ); - sb.and("dataCenterId", sb.entity().getZoneId(), SearchCriteria.Op.EQ); - sb.and("dataCenterType", sb.entity().getZoneType(), SearchCriteria.Op.EQ); + sb.and("dataCenterId", sb.entity().getZoneId(), SearchCriteria.Op.EQ); sb.and("podId", sb.entity().getPodId(), SearchCriteria.Op.EQ); sb.and("clusterId", sb.entity().getClusterId(), SearchCriteria.Op.EQ); sb.and("hostAddress", sb.entity().getHostAddress(), SearchCriteria.Op.EQ); @@ -1937,10 +1918,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { } if (zoneId != null) { sc.setParameters("dataCenterId", zoneId); - } - if (zoneType != null) { - sc.setParameters("dataCenterType", zoneType); - } + } if (pod != null) { sc.setParameters("podId", pod); } diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java index 940ad4af76f..47ece3ee6a5 100755 --- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java +++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java @@ -4187,8 +4187,11 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati sc.addAnd("isDefault", SearchCriteria.Op.EQ, isDefault); } - if (specifyVlan != null) { + // only root admin can list network offering with specifyVlan = true + if (specifyVlan != null && caller.getType() == Account.ACCOUNT_TYPE_ADMIN) { sc.addAnd("specifyVlan", SearchCriteria.Op.EQ, specifyVlan); + }else{ + specifyVlan = false; } if (availability != null) { diff --git a/server/src/com/cloud/network/NetworkServiceImpl.java b/server/src/com/cloud/network/NetworkServiceImpl.java index 024c969a043..f026dbc2a32 100755 --- a/server/src/com/cloud/network/NetworkServiceImpl.java +++ b/server/src/com/cloud/network/NetworkServiceImpl.java @@ -1202,9 +1202,9 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { + Network.GuestType.Isolated + " with a service " + Service.SourceNat.getName() + " enabled"); } - // Don't allow to specify vlan if the caller is a regular user - if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL && (ntwkOff.getSpecifyVlan() || vlanId != null)) { - throw new InvalidParameterValueException("Regular user is not allowed to specify vlanId"); + // Don't allow to specify vlan if the caller is not ROOT admin + if (caller.getType() != Account.ACCOUNT_TYPE_ADMIN && (ntwkOff.getSpecifyVlan() || vlanId != null)) { + throw new InvalidParameterValueException("Only ROOT admin is allowed to specify vlanId"); } if (ipv4) { diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java index db4786a7c7e..8da51763982 100755 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -3144,6 +3144,16 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V vlanIpMap.put(vlanTag, ipList); } + List nics = _nicDao.listByVmId(router.getId()); + String baseMac = null; + for (NicVO nic : nics) { + NetworkVO nw = _networkDao.findById(nic.getNetworkId()); + if (nw.getTrafficType() == TrafficType.Public) { + baseMac = nic.getMacAddress(); + break; + } + } + for (Map.Entry> vlanAndIp : vlanIpMap.entrySet()) { List ipAddrList = vlanAndIp.getValue(); // Source nat ip address should always be sent first @@ -3175,7 +3185,14 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V String vlanId = ipAddr.getVlanTag(); String vlanGateway = ipAddr.getGateway(); String vlanNetmask = ipAddr.getNetmask(); - String vifMacAddress = ipAddr.getMacAddress(); + String vifMacAddress = null; + // For non-source nat IP, set the mac to be something based on first public nic's MAC + // We cannot depends on first ip because we need to deal with first ip of other nics + if (!ipAddr.isSourceNat() && ipAddr.getVlanId() != 0) { + vifMacAddress = NetUtils.generateMacOnIncrease(baseMac, ipAddr.getVlanId()); + } else { + vifMacAddress = ipAddr.getMacAddress(); + } IpAddressTO ip = new IpAddressTO(ipAddr.getAccountId(), ipAddr.getAddress().addr(), add, firstIP, sourceNat, vlanId, vlanGateway, vlanNetmask, vifMacAddress, networkRate, ipAddr.isOneToOneNat()); @@ -3336,7 +3353,12 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V // password should be set only on default network element if (password != null && nic.isDefaultNic()) { - final String encodedPassword = PasswordGenerator.rot13(password); + String encodedPassword = PasswordGenerator.rot13(password); + // We would unset password for BACKUP router in the RvR, to prevent user from accidently reset the + // password again after BACKUP become MASTER + if (router.getIsRedundantRouter() && router.getRedundantState() != RedundantState.MASTER) { + encodedPassword = PasswordGenerator.rot13("saved_password"); + } SavePasswordCommand cmd = new SavePasswordCommand(encodedPassword, nic.getIp4Address(), profile.getVirtualMachine().getHostName()); cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(nic.getNetworkId(), router.getId())); diff --git a/server/src/com/cloud/network/vpc/NetworkACLServiceImpl.java b/server/src/com/cloud/network/vpc/NetworkACLServiceImpl.java index 4ad22d90770..a28657b4a81 100644 --- a/server/src/com/cloud/network/vpc/NetworkACLServiceImpl.java +++ b/server/src/com/cloud/network/vpc/NetworkACLServiceImpl.java @@ -294,6 +294,10 @@ public class NetworkACLServiceImpl extends ManagerBase implements NetworkACLServ throw new InvalidParameterValueException("Start port can't be bigger than end port"); } + // start port and end port must be null for protocol = 'all' + if ((portStart != null || portEnd != null ) && protocol != null && protocol.equalsIgnoreCase("all")) + throw new InvalidParameterValueException("start port and end port must be null if protocol = 'all'"); + if (sourceCidrList != null) { for (String cidr: sourceCidrList){ if (!NetUtils.isValidCIDR(cidr)){ diff --git a/services/console-proxy/server/js/ajaxkeys.js b/services/console-proxy/server/js/ajaxkeys.js index 5f497bbb785..677962be192 100644 --- a/services/console-proxy/server/js/ajaxkeys.js +++ b/services/console-proxy/server/js/ajaxkeys.js @@ -146,6 +146,17 @@ X11_KEY_TILDE = 0x7e; // ~ X11_KEY_CIRCUMFLEX_ACCENT = 0x5e; // ^ X11_KEY_YEN_MARK = 0xa5; // Japanese YEN mark X11_KEY_ASTERISK = 0x2a; +X11_KEY_KP_0 = 0xFFB0; +X11_KEY_KP_1 = 0xFFB1; +X11_KEY_KP_2 = 0xFFB2; +X11_KEY_KP_3 = 0xFFB3; +X11_KEY_KP_4 = 0xFFB4; +X11_KEY_KP_5 = 0xFFB5; +X11_KEY_KP_6 = 0xFFB6; +X11_KEY_KP_7 = 0xFFB7; +X11_KEY_KP_8 = 0xFFB8; +X11_KEY_KP_9 = 0xFFB9; +X11_KEY_KP_Decimal = 0xFFAE; KEY_DOWN = 5; KEY_UP = 6; @@ -248,17 +259,17 @@ var keyboardTables = [ {keycode: JS_KEY_FORWARD_SLASH, entry : X11_KEY_FORWARD_SLASH}, {keycode: JS_KEY_DASH, entry : X11_KEY_DASH}, {keycode: JS_KEY_SEMI_COLON, entry : X11_KEY_SEMI_COLON}, - {keycode: JS_KEY_NUMPAD0, entry : X11_KEY_NUMPAD0}, - {keycode: JS_KEY_NUMPAD1, entry : X11_KEY_NUMPAD1}, - {keycode: JS_KEY_NUMPAD2, entry : X11_KEY_NUMPAD2}, - {keycode: JS_KEY_NUMPAD3, entry : X11_KEY_NUMPAD3}, - {keycode: JS_KEY_NUMPAD4, entry : X11_KEY_NUMPAD4}, - {keycode: JS_KEY_NUMPAD5, entry : X11_KEY_NUMPAD5}, - {keycode: JS_KEY_NUMPAD6, entry : X11_KEY_NUMPAD6}, - {keycode: JS_KEY_NUMPAD7, entry : X11_KEY_NUMPAD7}, - {keycode: JS_KEY_NUMPAD8, entry : X11_KEY_NUMPAD8}, - {keycode: JS_KEY_NUMPAD9, entry : X11_KEY_NUMPAD9}, - {keycode: JS_KEY_DECIMAL_POINT, entry : X11_KEY_DECIMAL_POINT}, + {keycode: JS_KEY_NUMPAD0, entry : X11_KEY_KP_0}, + {keycode: JS_KEY_NUMPAD1, entry : X11_KEY_KP_1}, + {keycode: JS_KEY_NUMPAD2, entry : X11_KEY_KP_2}, + {keycode: JS_KEY_NUMPAD3, entry : X11_KEY_KP_3}, + {keycode: JS_KEY_NUMPAD4, entry : X11_KEY_KP_4}, + {keycode: JS_KEY_NUMPAD5, entry : X11_KEY_KP_5}, + {keycode: JS_KEY_NUMPAD6, entry : X11_KEY_KP_6}, + {keycode: JS_KEY_NUMPAD7, entry : X11_KEY_KP_7}, + {keycode: JS_KEY_NUMPAD8, entry : X11_KEY_KP_8}, + {keycode: JS_KEY_NUMPAD9, entry : X11_KEY_KP_9}, + {keycode: JS_KEY_DECIMAL_POINT, entry : X11_KEY_KP_Decimal}, {keycode: JS_KEY_DIVIDE, entry : 0xffaf}, {keycode: JS_KEY_MULTIPLY, entry : 0xffaa}, {keycode: JS_KEY_ADD, entry : 0xffab}, @@ -289,9 +300,12 @@ var keyboardTables = [ ] } }, {tindex: 2, keyboardType: KEYBOARD_TYPE_UK, mappingTable: - {X11: [], - keyPress: [ - //[34 = "] + {X11: [ + //[223 = `¬¦] + {keycode: 223, entry : 0x60, browser: "IE"}, + ], + keyPress: [ + //[34 = "] {keycode: 34, entry: [{type : KEY_DOWN, code : 0x40, modifiers : 64, shift : true}] }, diff --git a/services/console-proxy/server/scripts/ssvm-check.sh b/services/console-proxy/server/scripts/ssvm-check.sh deleted file mode 100644 index a4011647f07..00000000000 --- a/services/console-proxy/server/scripts/ssvm-check.sh +++ /dev/null @@ -1,136 +0,0 @@ -#!/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. - - -# Health check script for the Secondary Storage VM - -# DNS server is specified. - - -CMDLINE=/var/cache/cloud/cmdline -for i in `cat $CMDLINE` -do - key=`echo $i | cut -d= -f1` - value=`echo $i | cut -d= -f2` - case $key in - host) - MGMTSERVER=$value - ;; - esac -done - - -# ping dns server -echo ================================================ -DNSSERVER=`egrep '^nameserver' /etc/resolv.conf | awk '{print $2}'| head -1` -echo "First DNS server is " $DNSSERVER -ping -c 2 $DNSSERVER -if [ $? -eq 0 ] -then - echo "Good: Can ping DNS server" -else - echo "WARNING: cannot ping DNS server" - echo "route follows" - route -n -fi - - -# check dns resolve -echo ================================================ -nslookup download.cloud.com 1> /tmp/dns 2>&1 -grep 'no servers could' /tmp/dns 1> /dev/null 2>&1 -if [ $? -eq 0 ] -then - echo "ERROR: DNS not resolving download.cloud.com" - echo resolv.conf follows - cat /etc/resolv.conf - exit 2 -else - echo "Good: DNS resolves download.cloud.com" -fi - - -# check to see if we have the NFS volume mounted -echo ================================================ -mount|grep -v sunrpc|grep nfs 1> /dev/null 2>&1 -if [ $? -eq 0 ] -then - echo "NFS is currently mounted" - # check for write access - for MOUNTPT in `mount|grep -v sunrpc|grep nfs| awk '{print $3}'` - do - if [ $MOUNTPT != "/proc/xen" ] # mounted by xen - then - echo Mount point is $MOUNTPT - touch $MOUNTPT/foo - if [ $? -eq 0 ] - then - echo "Good: Can write to mount point" - rm $MOUNTPT/foo - else - echo "ERROR: Cannot write to mount point" - echo "You need to export with norootsquash" - fi - fi - done -else - echo "ERROR: NFS is not currently mounted" - echo "Try manually mounting from inside the VM" - NFSSERVER=`awk '{print $17}' $CMDLINE|awk -F= '{print $2}'|awk -F: '{print $1}'` - echo "NFS server is " $NFSSERVER - ping -c 2 $NFSSERVER - if [ $? -eq 0 ] - then - echo "Good: Can ping NFS server" - else - echo "WARNING: cannot ping NFS server" - echo routing table follows - route -n - fi -fi - - -# check for connectivity to the management server -echo ================================================ -echo Management server is $MGMTSERVER. Checking connectivity. -socatout=$(echo | socat - TCP:$MGMTSERVER:8250,connect-timeout=3 2>&1) -if [ $? -eq 0 ] -then - echo "Good: Can connect to management server port 8250" -else - echo "ERROR: Cannot connect to $MGMTSERVER port 8250" - echo $socatout - exit 4 -fi - - -# check for the java process running -echo ================================================ -ps -eaf|grep -v grep|grep java 1> /dev/null 2>&1 -if [ $? -eq 0 ] -then - echo "Good: Java process is running" -else - echo "ERROR: Java process not running. Try restarting the SSVM." - exit 3 -fi - -echo ================================================ -echo Tests Complete. Look for ERROR or WARNING above. - -exit 0 diff --git a/services/console-proxy/server/systemvm-descriptor.xml b/services/console-proxy/server/systemvm-descriptor.xml index e34026bc3a6..6c98d2d3eb0 100644 --- a/services/console-proxy/server/systemvm-descriptor.xml +++ b/services/console-proxy/server/systemvm-descriptor.xml @@ -36,6 +36,15 @@ 555 555 + + ../../secondary-storage/scripts/ + + 555 + 555 + + ssvm-check.sh + + ../../../scripts/storage/secondary/ scripts/storage/secondary diff --git a/setup/db/db/schema-2214to30.sql b/setup/db/db/schema-2214to30.sql index e288b0fd4f9..326e9a71cb6 100755 --- a/setup/db/db/schema-2214to30.sql +++ b/setup/db/db/schema-2214to30.sql @@ -665,6 +665,7 @@ ALTER TABLE `cloud`.`dc_storage_network_ip_range` ADD COLUMN `gateway` varchar(1 ALTER TABLE `cloud`.`volumes` ADD COLUMN `last_pool_id` bigint unsigned; UPDATE `cloud`.`volumes` SET `last_pool_id` = `pool_id`; UPDATE `cloud`.`volumes` SET `path` = SUBSTRING_INDEX(`path`, '/', -1); +UPDATE `cloud`.`template_spool_ref` SET `local_path` = SUBSTRING_INDEX(`local_path`, '/', -1); ALTER TABLE `cloud`.`user_ip_address` ADD COLUMN `is_system` int(1) unsigned NOT NULL default '0'; ALTER TABLE `cloud`.`volumes` ADD COLUMN `update_count` bigint unsigned NOT NULL DEFAULT 0; diff --git a/test/integration/component/maint/__init__.py b/test/integration/component/maint/__init__.py new file mode 100644 index 00000000000..f044f8bcd9a --- /dev/null +++ b/test/integration/component/maint/__init__.py @@ -0,0 +1,21 @@ +# 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 that put hosts, zones, resources in to maintenance mode are here. +These will have to be run sequentiall when resources are available so as not disrupt other tests +""" \ No newline at end of file diff --git a/test/integration/component/test_high_availability.py b/test/integration/component/maint/test_high_availability.py similarity index 100% rename from test/integration/component/test_high_availability.py rename to test/integration/component/maint/test_high_availability.py diff --git a/test/integration/component/test_host_high_availability.py b/test/integration/component/maint/test_host_high_availability.py similarity index 99% rename from test/integration/component/test_host_high_availability.py rename to test/integration/component/maint/test_host_high_availability.py index 57eb5edede9..5fb047ba6cb 100644 --- a/test/integration/component/test_host_high_availability.py +++ b/test/integration/component/maint/test_host_high_availability.py @@ -15,7 +15,7 @@ # specific language governing permissions and limitations # under the License. -""" P1 tests for dedicated Host high availability +""" P1 tests for dedicated Host high availability """ #Import Local Modules from nose.plugins.attrib import attr @@ -142,7 +142,6 @@ class TestHostHighAvailability(cloudstackTestCase): try: #Clean up, terminate the created accounts, domains etc cleanup_resources(self.apiclient, self.cleanup) - self.testClient.close() except Exception as e: raise Exception("Warning: Exception during cleanup : %s" % e) return @@ -158,7 +157,7 @@ class TestHostHighAvailability(cloudstackTestCase): # Validations, #1. Ensure that the offering is created and that in the UI the 'Offer HA' field is enabled (Yes) #The listServiceOffering API should list 'offerha' as true. - #2. Select the newly created VM and ensure that the Compute offering field value lists the compute service offering that was selected. + #2. Select the newly created VM and ensure that the Compute offering field value lists the compute service offering that was selected. # Also, check that the HA Enabled field is enabled 'Yes'. #list and validate above created service offering with Ha enabled @@ -258,7 +257,7 @@ class TestHostHighAvailability(cloudstackTestCase): self.debug("Deployed VM on host: %s" % vm.hostid) - #validate the virtual machine created is host Ha enabled + #validate the virtual machine created is host Ha enabled list_hosts_response = list_hosts( self.apiclient, id=vm.hostid @@ -594,7 +593,7 @@ class TestHostHighAvailability(cloudstackTestCase): vm_with_ha_enabled = vms[0] - #Verify the virtual machine got created on non HA host + #Verify the virtual machine got created on non HA host list_hosts_response = list_hosts( self.apiclient, id=vm_with_ha_enabled.hostid @@ -726,7 +725,7 @@ class TestHostHighAvailability(cloudstackTestCase): vm_with_ha_disabled = vms[0] - #Verify the virtual machine got created on non HA host + #Verify the virtual machine got created on non HA host list_hosts_response = list_hosts( self.apiclient, id=vm_with_ha_disabled.hostid diff --git a/test/integration/component/test_vpc_host_maintenance.py b/test/integration/component/maint/test_vpc_host_maintenance.py similarity index 63% rename from test/integration/component/test_vpc_host_maintenance.py rename to test/integration/component/maint/test_vpc_host_maintenance.py index d28b7985b9b..8fc427abd36 100644 --- a/test/integration/component/test_vpc_host_maintenance.py +++ b/test/integration/component/maint/test_vpc_host_maintenance.py @@ -558,332 +558,4 @@ class TestVMLifeCycleHostmaintenance(cloudstackTestCase): "Router state should be running" ) # TODO: Check for the network connectivity - return - - -class TestVPCNetworkRules(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super( - TestVPCNetworkRules, - 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.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.service_offering_1 = ServiceOffering.create( - cls.api_client, - cls.services["service_offering_1"] - ) - cls.service_offering_2 = ServiceOffering.create( - cls.api_client, - cls.services["service_offering_2"] - ) - cls.vpc_off = VpcOffering.create( - cls.api_client, - cls.services["vpc_offering"] - ) - cls.vpc_off.update(cls.api_client, state='Enabled') - - cls.account = Account.create( - cls.api_client, - cls.services["account"], - admin=True, - domainid=cls.domain.id - ) - - cls.vpc_off = VpcOffering.create( - cls.api_client, - cls.services["vpc_offering"] - ) - - cls.vpc_off.update(cls.api_client, state='Enabled') - - cls.services["vpc"]["cidr"] = '10.1.1.1/16' - cls.vpc = VPC.create( - cls.api_client, - cls.services["vpc"], - vpcofferingid=cls.vpc_off.id, - zoneid=cls.zone.id, - account=cls.account.name, - domainid=cls.account.domainid - ) - - cls.nw_off = NetworkOffering.create( - cls.api_client, - cls.services["network_offering"], - conservemode=False - ) - # Enable Network offering - cls.nw_off.update(cls.api_client, state='Enabled') - - # Creating network using the network offering created - cls.network_1 = Network.create( - cls.api_client, - cls.services["network"], - accountid=cls.account.name, - domainid=cls.account.domainid, - networkofferingid=cls.nw_off.id, - zoneid=cls.zone.id, - gateway='10.1.1.1', - vpcid=cls.vpc.id - ) - cls.nw_off_no_lb = NetworkOffering.create( - cls.api_client, - cls.services["network_offering_no_lb"], - conservemode=False - ) - # Enable Network offering - cls.nw_off_no_lb.update(cls.api_client, state='Enabled') - - # Creating network using the network offering created - cls.network_2 = Network.create( - cls.api_client, - cls.services["network"], - accountid=cls.account.name, - domainid=cls.account.domainid, - networkofferingid=cls.nw_off_no_lb.id, - zoneid=cls.zone.id, - gateway='10.1.2.1', - vpcid=cls.vpc.id - ) - # Spawn an instance in that network - cls.vm_1 = VirtualMachine.create( - cls.api_client, - cls.services["virtual_machine"], - accountid=cls.account.name, - domainid=cls.account.domainid, - serviceofferingid=cls.service_offering_1.id, - networkids=[str(cls.network_1.id)] - ) - # Spawn an instance in that network - cls.vm_2 = VirtualMachine.create( - cls.api_client, - cls.services["virtual_machine"], - accountid=cls.account.name, - domainid=cls.account.domainid, - serviceofferingid=cls.service_offering_2.id, - networkids=[str(cls.network_1.id)] - ) - cls.vm_3 = VirtualMachine.create( - cls.api_client, - cls.services["virtual_machine"], - accountid=cls.account.name, - domainid=cls.account.domainid, - serviceofferingid=cls.service_offering_1.id, - networkids=[str(cls.network_2.id)] - ) - cls.vm_4 = VirtualMachine.create( - cls.api_client, - cls.services["virtual_machine"], - accountid=cls.account.name, - domainid=cls.account.domainid, - serviceofferingid=cls.service_offering_2.id, - networkids=[str(cls.network_2.id)] - ) - - cls._cleanup = [ - cls.service_offering_1, - cls.service_offering_2, - cls.nw_off, - cls.nw_off_no_lb, - ] - return - - @classmethod - def tearDownClass(cls): - try: - cls.account.delete(cls.api_client) - wait_for_cleanup(cls.api_client, ["account.cleanup.interval"]) - #Cleanup resources used - cleanup_resources(cls.api_client, cls._cleanup) - - # Waiting for network cleanup to delete vpc offering - wait_for_cleanup(cls.api_client, ["network.gc.wait", - "network.gc.interval"]) - cls.vpc_off.delete(cls.api_client) - 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 network offerings - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def validate_vm_deployment(self): - """Validates VM deployment on different hosts""" - - vms = VirtualMachine.list( - self.apiclient, - account=self.account.name, - domainid=self.account.domainid, - networkid=self.network_1.id, - listall=True - ) - self.assertEqual( - isinstance(vms, list), - True, - "List VMs shall return a valid response" - ) - host_1 = vms[0].hostid - self.debug("Host for network 1: %s" % vms[0].hostid) - - vms = VirtualMachine.list( - self.apiclient, - account=self.account.name, - domainid=self.account.domainid, - networkid=self.network_2.id, - listall=True - ) - self.assertEqual( - isinstance(vms, list), - True, - "List VMs shall return a valid response" - ) - host_2 = vms[0].hostid - self.debug("Host for network 2: %s" % vms[0].hostid) - - self.assertNotEqual( - host_1, - host_2, - "Both the virtual machines should be deployed on diff hosts " - ) - return - - @attr(tags=["advanced", "intervlan"]) - def test_list_pf_rules_for_vpc(self): - """ Test List Port Forwarding Rules & vms belonging to a VPC - """ - - # Validate the following - # 1. Create a VPC with cidr - 10.1.1.1/16 - # 2. Add network1(10.1.1.1/24) and network2(10.1.2.1/24) to this VPC. - # 3. Deploy vm1 and vm2 in network1 and vm3 and vm4 in network2. - # Make sure vm1 and vm3 are deployed on one host in the cluster - # while vm2 and vm4 are deployed on the other host in the cluster. - # This can be done using host's tags and service offerings with - # host tags. - # 4. Create a PF rule for vms in network1. - # 5. Create a PF rule for vms in network2. - # Steps: - # 1. List all the Port Forwarding Rules belonging to a VPC - # 2. Successfully List the Port Forwarding Rules belonging to the VPC - # 3. List the VMs on network1 for selection for the PF Rule - # 4. Successfully list the VMs for Port Forwarding Rule creation - - self.debug("Associating public IP for network: %s" % - self.network_1.name) - public_ip_1 = PublicIPAddress.create( - self.apiclient, - accountid=self.account.name, - zoneid=self.zone.id, - domainid=self.account.domainid, - networkid=self.network_1.id, - vpcid=self.vpc.id - ) - self.debug("Associated %s with network %s" % ( - public_ip_1.ipaddress.ipaddress, - self.network_1.id - )) - - nat_rule_1 = NATRule.create( - self.apiclient, - self.vm_1, - self.services["natrule"], - ipaddressid=public_ip_1.ipaddress.id, - openfirewall=False, - networkid=self.network_1.id, - vpcid=self.vpc.id - ) - - self.debug("Associating public IP for network: %s" % - self.network_2.name) - public_ip_2 = PublicIPAddress.create( - self.apiclient, - accountid=self.account.name, - zoneid=self.zone.id, - domainid=self.account.domainid, - networkid=self.network_2.id, - vpcid=self.vpc.id - ) - self.debug("Associated %s with network %s" % ( - public_ip_2.ipaddress.ipaddress, - self.network_2.id - )) - - nat_rule_2 = NATRule.create( - self.apiclient, - self.vm_3, - self.services["natrule"], - ipaddressid=public_ip_2.ipaddress.id, - openfirewall=False, - networkid=self.network_2.id, - vpcid=self.vpc.id - ) - - self.debug("Listing all the PF rules belonging to VPC") - nat_rules = NATRule.list( - self.apiclient, - vpcid=self.vpc.id, - listall=True - ) - self.assertEqual( - isinstance(nat_rules, list), - True, - "List NAT rules should return the valid list" - ) - self.assertEqual( - len(nat_rules), - 2, - "List NAT for VPC shall return all NAT rules belonging to VPC" - ) - for nat_rule in nat_rules: - self.assertEqual( - nat_rule.vpcid, - self.vpc.id, - "NAT rules should belong to VPC" - ) - - self.debug( - "Listing all the VMs belonging to VPC for network: %s" % - self.network_1.name) - vms = VirtualMachine.list( - self.apiclient, - networkid=self.network_1.id, - vpcid=self.vpc.id, - listall=True - ) - self.assertEqual( - isinstance(vms, list), - True, - "List virtual machines should return the valid list" - ) - for vm in vms: - self.assertEqual( - vm.networkid, - self.network_1.id, - "List VMs should return vms belonging to network_1" - ) - return - + return \ No newline at end of file diff --git a/test/integration/component/maint/test_vpc_on_host_maintenance.py b/test/integration/component/maint/test_vpc_on_host_maintenance.py new file mode 100644 index 00000000000..6630ee61e0a --- /dev/null +++ b/test/integration/component/maint/test_vpc_on_host_maintenance.py @@ -0,0 +1,323 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +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 VPC 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, + }, + "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' + }, + "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 TestVPCHostMaintenance(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + cls.api_client = super( + TestVPCHostMaintenance, + 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.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["mode"] = cls.zone.networktype + + cls.service_offering = ServiceOffering.create( + cls.api_client, + cls.services["service_offering"] + ) + cls.vpc_off = VpcOffering.create( + cls.api_client, + cls.services["vpc_offering"] + ) + cls.vpc_off.update(cls.api_client, state='Enabled') + hosts = Host.list( + cls.api_client, + zoneid=cls.zone.id, + listall=True, + type='Routing' + ) + + if isinstance(hosts, list): + for host in hosts: + Host.enableMaintenance( + cls.api_client, + id=host.id + ) + + timeout = cls.services["timeout"] + while True: + time.sleep(cls.services["sleep"]) + hosts_states = Host.list( + cls.api_client, + id=host.id, + listall=True + ) + if hosts_states[0].resourcestate == 'PrepareForMaintenance': + # Wait for sometimetill host goes in maintenance state + time.sleep(cls.services["sleep"]) + elif hosts_states[0].resourcestate == 'Maintenance': + time.sleep(cls.services["sleep"]) + break + elif timeout == 0: + raise unittest.SkipTest( + "Failed to enable maintenance mode on %s" % host.name) + timeout = timeout - 1 + + cls._cleanup = [ + cls.service_offering, + cls.vpc_off + ] + return + + @classmethod + def tearDownClass(cls): + try: + #Cleanup resources used + cleanup_resources(cls.api_client, cls._cleanup) + hosts = Host.list( + cls.api_client, + zoneid=cls.zone.id, + listall=True, + type='Routing' + ) + if isinstance(hosts, list): + for host in hosts: + Host.cancelMaintenance( + cls.api_client, + id=host.id + ) + hosts_states = Host.list( + cls.api_client, + id=host.id, + listall=True + ) + if hosts_states[0].resourcestate != 'Enabled': + raise Exception( + "Failed to cancel maintenance mode on %s" % (host.name)) + 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.account] + return + + def tearDown(self): + try: + #Clean up, terminate the created network offerings + cleanup_resources(self.apiclient, self.cleanup) + interval = list_configurations( + self.apiclient, + name='network.gc.interval' + ) + wait = list_configurations( + self.apiclient, + name='network.gc.wait' + ) + # Sleep to ensure that all resources are deleted + time.sleep(int(interval[0].value) + int(wait[0].value)) + 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.debug( + "VPC offering is created successfully - %s" % + vpc_offering.name) + return + + def validate_vpc_network(self, network, state=None): + """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" + ) + if state: + self.assertEqual( + vpc_networks[0].state, + state, + "VPC state should be '%s'" % state + ) + self.debug("VPC network validated - %s" % network.name) + return + + @attr(tags=["advanced", "intervlan"]) + def test_01_create_vpc_host_maintenance(self): + """ Test VPC when host is in maintenance mode + """ + + # Validate the following + # 1. Put the host in maintenance mode. + # 2. Attempt to Create a VPC with cidr - 10.1.1.1/16 + # 3. VPC will be created but will be in "Disabled" state + + self.debug("creating a VPC network in the account: %s" % + self.account.name) + 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=self.account.name, + domainid=self.account.domainid + ) + self.validate_vpc_network(vpc, state='Disabled') + return + + @attr(tags=["advanced", "intervlan"]) + def test_02_create_vpc_wait_gc(self): + """ Test VPC when host is in maintenance mode and wait till nw gc + """ + + # Validate the following + # 1. Put the host in maintenance mode. + # 2. Attempt to Create a VPC with cidr - 10.1.1.1/16 + # 3. Wait for the VPC GC thread to run. + # 3. VPC will be created but will be in "Disabled" state and should + # get deleted + + self.debug("creating a VPC network in the account: %s" % + self.account.name) + 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=self.account.name, + domainid=self.account.domainid + ) + self.validate_vpc_network(vpc, state='Disabled') + interval = list_configurations( + self.apiclient, + name='network.gc.interval' + ) + wait = list_configurations( + self.apiclient, + name='network.gc.wait' + ) + self.debug("Sleep till network gc thread runs..") + # Sleep to ensure that all resources are deleted + time.sleep(int(interval[0].value) + int(wait[0].value)) + vpcs = VPC.list( + self.apiclient, + id=vpc.id, + listall=True + ) + self.assertEqual( + vpcs, + None, + "List VPC should not return anything after network gc" + ) + return diff --git a/test/integration/component/test_accounts.py b/test/integration/component/test_accounts.py index 3f106c3b048..ec135b1de4f 100644 --- a/test/integration/component/test_accounts.py +++ b/test/integration/component/test_accounts.py @@ -84,6 +84,7 @@ class Services: "isfeatured": True, "ispublic": True, "isextractable": True, + "ostype": 'CentOS 5.3 (64-bit)', }, "natrule": { "publicport": 22, diff --git a/test/integration/component/test_custom_hostname.py b/test/integration/component/test_custom_hostname.py index c9db2154a94..e569215980c 100644 --- a/test/integration/component/test_custom_hostname.py +++ b/test/integration/component/test_custom_hostname.py @@ -300,7 +300,7 @@ class TestInstanceNameFlagTrue(cloudstackTestCase): "Running", "Vm state should be running after deployment" ) - self.assertEqual( + self.assertNotEqual( vm.displayname, vm.id, "Vm display name should not match the given name" diff --git a/test/integration/component/test_vpc.py b/test/integration/component/test_vpc.py index 3fc0cc5a7e2..acf7a8eb2e3 100644 --- a/test/integration/component/test_vpc.py +++ b/test/integration/component/test_vpc.py @@ -18,16 +18,12 @@ """ Component tests for VPC functionality """ #Import Local Modules -import marvin -import unittest 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.remoteSSHClient import remoteSSHClient -import datetime class Services: @@ -331,7 +327,7 @@ class TestVPC(cloudstackTestCase): @attr(tags=["advanced", "intervlan"]) def test_02_restart_vpc_with_networks(self): - """ Test restart VPC having with networks + """ Test restart VPC having networks """ # Validate the following @@ -2474,250 +2470,4 @@ class TestVPC(cloudstackTestCase): "Updation of VPC display text failed.") -class TestVPCHostMaintenance(cloudstackTestCase): - @classmethod - def setUpClass(cls): - cls.api_client = super( - TestVPCHostMaintenance, - 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.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.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.vpc_off = VpcOffering.create( - cls.api_client, - cls.services["vpc_offering"] - ) - cls.vpc_off.update(cls.api_client, state='Enabled') - hosts = Host.list( - cls.api_client, - zoneid=cls.zone.id, - listall=True, - type='Routing' - ) - - if isinstance(hosts, list): - for host in hosts: - Host.enableMaintenance( - cls.api_client, - id=host.id - ) - - timeout = cls.services["timeout"] - while True: - time.sleep(cls.services["sleep"]) - hosts_states = Host.list( - cls.api_client, - id=host.id, - listall=True - ) - if hosts_states[0].resourcestate == 'PrepareForMaintenance': - # Wait for sometimetill host goes in maintenance state - time.sleep(cls.services["sleep"]) - elif hosts_states[0].resourcestate == 'Maintenance': - time.sleep(cls.services["sleep"]) - break - elif timeout == 0: - raise unittest.SkipTest( - "Failed to enable maintenance mode on %s" % host.name) - timeout = timeout - 1 - - cls._cleanup = [ - cls.service_offering, - cls.vpc_off - ] - return - - @classmethod - def tearDownClass(cls): - try: - #Cleanup resources used - cleanup_resources(cls.api_client, cls._cleanup) - hosts = Host.list( - cls.api_client, - zoneid=cls.zone.id, - listall=True, - type='Routing' - ) - if isinstance(hosts, list): - for host in hosts: - Host.cancelMaintenance( - cls.api_client, - id=host.id - ) - hosts_states = Host.list( - cls.api_client, - id=host.id, - listall=True - ) - if hosts_states[0].resourcestate != 'Enabled': - raise Exception( - "Failed to cancel maintenance mode on %s" % (host.name)) - 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.account] - return - - def tearDown(self): - try: - #Clean up, terminate the created network offerings - cleanup_resources(self.apiclient, self.cleanup) - interval = list_configurations( - self.apiclient, - name='network.gc.interval' - ) - wait = list_configurations( - self.apiclient, - name='network.gc.wait' - ) - # Sleep to ensure that all resources are deleted - time.sleep(int(interval[0].value) + int(wait[0].value)) - 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.debug( - "VPC offering is created successfully - %s" % - vpc_offering.name) - return - - def validate_vpc_network(self, network, state=None): - """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" - ) - if state: - self.assertEqual( - vpc_networks[0].state, - state, - "VPC state should be '%s'" % state - ) - self.debug("VPC network validated - %s" % network.name) - return - - @attr(tags=["advanced", "intervlan"]) - def test_01_create_vpc_host_maintenance(self): - """ Test VPC when host is in maintenance mode - """ - - # Validate the following - # 1. Put the host in maintenance mode. - # 2. Attempt to Create a VPC with cidr - 10.1.1.1/16 - # 3. VPC will be created but will be in "Disabled" state - - self.debug("creating a VPC network in the account: %s" % - self.account.name) - 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=self.account.name, - domainid=self.account.domainid - ) - self.validate_vpc_network(vpc, state='Disabled') - return - - @attr(tags=["advanced", "intervlan"]) - def test_02_create_vpc_wait_gc(self): - """ Test VPC when host is in maintenance mode and wait till nw gc - """ - - # Validate the following - # 1. Put the host in maintenance mode. - # 2. Attempt to Create a VPC with cidr - 10.1.1.1/16 - # 3. Wait for the VPC GC thread to run. - # 3. VPC will be created but will be in "Disabled" state and should - # get deleted - - self.debug("creating a VPC network in the account: %s" % - self.account.name) - 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=self.account.name, - domainid=self.account.domainid - ) - self.validate_vpc_network(vpc, state='Disabled') - interval = list_configurations( - self.apiclient, - name='network.gc.interval' - ) - wait = list_configurations( - self.apiclient, - name='network.gc.wait' - ) - self.debug("Sleep till network gc thread runs..") - # Sleep to ensure that all resources are deleted - time.sleep(int(interval[0].value) + int(wait[0].value)) - vpcs = VPC.list( - self.apiclient, - id=vpc.id, - listall=True - ) - self.assertEqual( - vpcs, - None, - "List VPC should not return anything after network gc" - ) - return diff --git a/test/integration/smoke/test_network.py b/test/integration/smoke/test_network.py index 1c867fa0422..a75ffeb8953 100644 --- a/test/integration/smoke/test_network.py +++ b/test/integration/smoke/test_network.py @@ -664,6 +664,32 @@ class TestLoadBalancingRule(cloudstackTestCase): cleanup_resources(cls.api_client, cls._cleanup) return + def try_ssh(self, src_nat_ip_addr, hostnames): + try: + self.debug( + "SSH into VM (IPaddress: %s) & NAT Rule (Public IP: %s)" % + (self.vm_1.ipaddress, src_nat_ip_addr.ipaddress) + ) + + ssh_1 = remoteSSHClient( + src_nat_ip_addr.ipaddress, + self.services['lbrule']["publicport"], + self.vm_1.username, + self.vm_1.password + ) + + # If Round Robin Algorithm is chosen, + # each ssh command should alternate between VMs + # hostnames = [ssh_1.execute("hostname")[0]] + hostnames.append(ssh_1.execute("hostname")[0]) + + except Exception as e: + self.fail("%s: SSH failed for VM with IP Address: %s" % + (e, src_nat_ip_addr.ipaddress)) + + time.sleep(self.services["lb_switch_wait"]) + return + @attr(tags = ["advanced", "advancedns", "smoke"]) def test_01_create_lb_rule_src_nat(self): """Test to create Load balancing rule with source NAT""" @@ -776,62 +802,33 @@ class TestLoadBalancingRule(cloudstackTestCase): [self.vm_1.id, self.vm_2.id], "Check List Load Balancer instances Rules returns valid VM ID" ) - try: - self.debug( - "SSH into VM (IPaddress: %s) & NAT Rule (Public IP: %s)" % - (self.vm_1.ipaddress, src_nat_ip_addr.ipaddress) - ) - ssh_1 = remoteSSHClient( - src_nat_ip_addr.ipaddress, - self.services['lbrule']["publicport"], - self.vm_1.username, - self.vm_1.password - ) - # If Round Robin Algorithm is chosen, - # each ssh command should alternate between VMs - hostnames = [ssh_1.execute("hostname")[0]] - except Exception as e: - self.fail("%s: SSH failed for VM with IP Address: %s" % - (e, src_nat_ip_addr.ipaddress)) + hostnames = [] + self.try_ssh(src_nat_ip_addr, hostnames) + self.try_ssh(src_nat_ip_addr, hostnames) + self.try_ssh(src_nat_ip_addr, hostnames) + self.try_ssh(src_nat_ip_addr, hostnames) + self.try_ssh(src_nat_ip_addr, hostnames) - time.sleep(self.services["lb_switch_wait"]) - - try: - self.debug("SSHing into IP address: %s after adding VMs (ID: %s , %s)" % - ( - src_nat_ip_addr.ipaddress, - self.vm_1.id, - self.vm_2.id - )) - - ssh_2 = remoteSSHClient( - src_nat_ip_addr.ipaddress, - self.services['lbrule']["publicport"], - self.vm_1.username, - self.vm_1.password - ) - hostnames.append(ssh_2.execute("hostname")[0]) - - except Exception as e: - self.fail("%s: SSH failed for VM with IP Address: %s" % - (e, src_nat_ip_addr.ipaddress)) - - self.debug("Hostnames: %s" % str(hostnames)) - self.assertIn( - self.vm_1.name, - hostnames, - "Check if ssh succeeded for server1" - ) - self.assertIn( - self.vm_2.name, - hostnames, - "Check if ssh succeeded for server2" - ) + self.debug("Hostnames: %s" % str(hostnames)) + self.assertIn( + self.vm_1.name, + hostnames, + "Check if ssh succeeded for server1" + ) + self.assertIn( + self.vm_2.name, + hostnames, + "Check if ssh succeeded for server2" + ) #SSH should pass till there is a last VM associated with LB rule lb_rule.remove(self.apiclient, [self.vm_2]) + + # making hostnames list empty + hostnames[:] = [] + try: self.debug("SSHing into IP address: %s after removing VM (ID: %s)" % ( @@ -839,25 +836,18 @@ class TestLoadBalancingRule(cloudstackTestCase): self.vm_2.id )) - ssh_1 = remoteSSHClient( - src_nat_ip_addr.ipaddress, - self.services['lbrule']["publicport"], - self.vm_1.username, - self.vm_1.password - ) + self.try_ssh(src_nat_ip_addr, hostnames) - hostnames.append(ssh_1.execute("hostname")[0]) - - except Exception as e: - self.fail("%s: SSH failed for VM with IP Address: %s" % - (e, src_nat_ip_addr.ipaddress)) - - self.assertIn( + self.assertIn( self.vm_1.name, hostnames, "Check if ssh succeeded for server1" ) + except Exception as e: + self.fail("%s: SSH failed for VM with IP Address: %s" % + (e, src_nat_ip_addr.ipaddress)) + lb_rule.remove(self.apiclient, [self.vm_1]) with self.assertRaises(Exception): @@ -967,50 +957,24 @@ class TestLoadBalancingRule(cloudstackTestCase): "Check List Load Balancer instances Rules returns valid VM ID" ) try: - self.debug("SSHing into IP address: %s after adding VMs (ID: %s , %s)" % - ( - self.non_src_nat_ip.ipaddress.ipaddress, - self.vm_1.id, - self.vm_2.id - )) - ssh_1 = remoteSSHClient( - self.non_src_nat_ip.ipaddress.ipaddress, - self.services['lbrule']["publicport"], - self.vm_1.username, - self.vm_1.password - ) + hostnames = [] + self.try_ssh(self.non_src_nat_ip, hostnames) + self.try_ssh(self.non_src_nat_ip, hostnames) + self.try_ssh(self.non_src_nat_ip, hostnames) + self.try_ssh(self.non_src_nat_ip, hostnames) + self.try_ssh(self.non_src_nat_ip, hostnames) - # If Round Robin Algorithm is chosen, - # each ssh command should alternate between VMs - hostnames = [ssh_1.execute("hostname")[0]] - - time.sleep(self.services["lb_switch_wait"]) - - self.debug("SSHing again into IP address: %s with VMs (ID: %s , %s) added to LB rule" % - ( - self.non_src_nat_ip.ipaddress.ipaddress, - self.vm_1.id, - self.vm_2.id - )) - ssh_2 = remoteSSHClient( - self.non_src_nat_ip.ipaddress.ipaddress, - self.services['lbrule']["publicport"], - self.vm_1.username, - self.vm_1.password - ) - - hostnames.append(ssh_2.execute("hostname")[0]) - self.debug("Hostnames after adding 2 VMs to LB rule: %s" % str(hostnames)) - self.assertIn( + self.debug("Hostnames: %s" % str(hostnames)) + self.assertIn( self.vm_1.name, hostnames, "Check if ssh succeeded for server1" - ) - self.assertIn( + ) + self.assertIn( self.vm_2.name, hostnames, "Check if ssh succeeded for server2" - ) + ) #SSH should pass till there is a last VM associated with LB rule lb_rule.remove(self.apiclient, [self.vm_2]) @@ -1020,25 +984,23 @@ class TestLoadBalancingRule(cloudstackTestCase): self.non_src_nat_ip.ipaddress.ipaddress, self.vm_2.id )) - ssh_1 = remoteSSHClient( - self.non_src_nat_ip.ipaddress.ipaddress, - self.services['lbrule']["publicport"], - self.vm_1.username, - self.vm_1.password - ) + # Making host list empty + hostnames[:] = [] + + self.try_ssh(self.non_src_nat_ip, hostnames) + + self.assertIn( + self.vm_1.name, + hostnames, + "Check if ssh succeeded for server1" + ) - hostnames.append(ssh_1.execute("hostname")[0]) self.debug("Hostnames after removing VM2: %s" % str(hostnames)) + except Exception as e: self.fail("%s: SSH failed for VM with IP Address: %s" % (e, self.non_src_nat_ip.ipaddress.ipaddress)) - self.assertIn( - self.vm_1.name, - hostnames, - "Check if ssh succeeded for server1" - ) - lb_rule.remove(self.apiclient, [self.vm_1]) with self.assertRaises(Exception): self.debug("SSHing into IP address: %s after removing VM (ID: %s) from LB rule" % @@ -1209,7 +1171,7 @@ class TestRebootRouter(cloudstackTestCase): except Exception as e: self.fail( "SSH Access failed for %s: %s" % \ - (self.nat_rule.ipaddress.ipaddress, e)) + (self.vm_1.ipaddress, e)) return def tearDown(self): @@ -1277,6 +1239,36 @@ class TestAssignRemoveLB(cloudstackTestCase): ] return + def tearDown(self): + cleanup_resources(self.apiclient, self.cleanup) + return + + def try_ssh(self, src_nat_ip_addr, hostnames): + try: + self.debug( + "SSH into VM (IPaddress: %s) & NAT Rule (Public IP: %s)" % + (self.vm_1.ipaddress, src_nat_ip_addr.ipaddress) + ) + + ssh_1 = remoteSSHClient( + src_nat_ip_addr.ipaddress, + self.services['lbrule']["publicport"], + self.vm_1.username, + self.vm_1.password + ) + + # If Round Robin Algorithm is chosen, + # each ssh command should alternate between VMs + # hostnames = [ssh_1.execute("hostname")[0]] + hostnames.append(ssh_1.execute("hostname")[0]) + + except Exception as e: + self.fail("%s: SSH failed for VM with IP Address: %s" % + (e, src_nat_ip_addr.ipaddress)) + + time.sleep(self.services["lb_switch_wait"]) + return + @attr(tags = ["advanced", "advancedns", "smoke"]) def test_assign_and_removal_lb(self): """Test for assign & removing load balancing rule""" @@ -1344,137 +1336,74 @@ class TestAssignRemoveLB(cloudstackTestCase): ) lb_rule.assign(self.apiclient, [self.vm_1, self.vm_2]) - try: - self.debug("SSHing into IP address: %s with VMs (ID: %s , %s) added to LB rule" % - ( - self.non_src_nat_ip.ipaddress, - self.vm_1.id, - self.vm_2.id - )) - #Create SSH client for each VM - ssh_1 = remoteSSHClient( - self.non_src_nat_ip.ipaddress, - self.services["lbrule"]["publicport"], - self.vm_1.username, - self.vm_1.password - ) - except Exception as e: - self.fail("SSH failed for VM with IP: %s" % - self.non_src_nat_ip.ipaddress) + hostnames = [] + self.try_ssh(self.non_src_nat_ip, hostnames) + self.try_ssh(self.non_src_nat_ip, hostnames) + self.try_ssh(self.non_src_nat_ip, hostnames) + self.try_ssh(self.non_src_nat_ip, hostnames) + self.try_ssh(self.non_src_nat_ip, hostnames) - try: - self.debug("SSHing again into IP address: %s with VMs (ID: %s , %s) added to LB rule" % - ( - self.non_src_nat_ip.ipaddress, - self.vm_1.id, - self.vm_2.id - )) - ssh_2 = remoteSSHClient( - self.non_src_nat_ip.ipaddress, - self.services["lbrule"]["publicport"], - self.vm_2.username, - self.vm_2.password - ) + self.debug("Hostnames: %s" % str(hostnames)) + self.assertIn( + self.vm_1.name, + hostnames, + "Check if ssh succeeded for server1" + ) + self.assertIn( + self.vm_2.name, + hostnames, + "Check if ssh succeeded for server2" + ) - # If Round Robin Algorithm is chosen, - # each ssh command should alternate between VMs - res_1 = ssh_1.execute("hostname")[0] - self.debug(res_1) - - time.sleep(self.services["lb_switch_wait"]) - - res_2 = ssh_2.execute("hostname")[0] - self.debug(res_2) - - except Exception as e: - self.fail("SSH failed for VM with IP: %s" % - self.non_src_nat_ip.ipaddress) - - self.assertIn( - self.vm_1.name, - res_1, - "Check if ssh succeeded for server1" - ) - self.assertIn( - self.vm_2.name, - res_2, - "Check if ssh succeeded for server2" - ) #Removing VM and assigning another VM to LB rule lb_rule.remove(self.apiclient, [self.vm_2]) + # making hostnames list empty + hostnames[:] = [] + try: self.debug("SSHing again into IP address: %s with VM (ID: %s) added to LB rule" % ( self.non_src_nat_ip.ipaddress, self.vm_1.id, )) - # Again make a SSH connection, as previous is not used after LB remove - ssh_1 = remoteSSHClient( - self.non_src_nat_ip.ipaddress, - self.services["lbrule"]["publicport"], - self.vm_1.username, - self.vm_1.password - ) - res_1 = ssh_1.execute("hostname")[0] - self.debug(res_1) + self.try_ssh(self.non_src_nat_ip, hostnames) + + self.assertIn( + self.vm_1.name, + hostnames, + "Check if ssh succeeded for server1" + ) except Exception as e: self.fail("SSH failed for VM with IP: %s" % self.non_src_nat_ip.ipaddress) - self.assertIn( - self.vm_1.name, - res_1, - "Check if ssh succeeded for server1" - ) - lb_rule.assign(self.apiclient, [self.vm_3]) - try: - ssh_1 = remoteSSHClient( - self.non_src_nat_ip.ipaddress, - self.services["lbrule"]["publicport"], - self.vm_1.username, - self.vm_1.password - ) - ssh_3 = remoteSSHClient( - self.non_src_nat_ip.ipaddress, - self.services["lbrule"]["publicport"], - self.vm_3.username, - self.vm_3.password - ) + # Making hostnames list empty + hostnames[:] = [] - res_1 = ssh_1.execute("hostname")[0] - self.debug(res_1) + self.try_ssh(self.non_src_nat_ip, hostnames) + self.try_ssh(self.non_src_nat_ip, hostnames) + self.try_ssh(self.non_src_nat_ip, hostnames) + self.try_ssh(self.non_src_nat_ip, hostnames) + self.try_ssh(self.non_src_nat_ip, hostnames) - time.sleep(self.services["lb_switch_wait"]) - - res_3 = ssh_3.execute("hostname")[0] - self.debug(res_3) - - except Exception as e: - self.fail("SSH failed for VM with IP: %s" % - self.non_src_nat_ip.ipaddress) - - self.assertIn( - self.vm_1.name, - res_1, - "Check if ssh succeeded for server1" - ) - self.assertIn( - self.vm_3.name, - res_3, - "Check if ssh succeeded for server3" - ) + self.debug("Hostnames: %s" % str(hostnames)) + self.assertIn( + self.vm_1.name, + hostnames, + "Check if ssh succeeded for server1" + ) + self.assertIn( + self.vm_3.name, + hostnames, + "Check if ssh succeeded for server3" + ) return - def tearDown(self): - cleanup_resources(self.apiclient, self.cleanup) - return - - class TestReleaseIP(cloudstackTestCase): def setUp(self): diff --git a/tools/apidoc/generateadmincommands.xsl b/tools/apidoc/generateadmincommands.xsl index a33e7baf20d..9abec10a4fb 100644 --- a/tools/apidoc/generateadmincommands.xsl +++ b/tools/apidoc/generateadmincommands.xsl @@ -150,10 +150,10 @@ version="1.0"> + Apache, CloudStack, Apache CloudStack, the Apache CloudStack logo, the CloudMonkey logo and the Apache feather logo are trademarks of The Apache Software Foundation.

+ diff --git a/tools/apidoc/generatecommand.xsl b/tools/apidoc/generatecommand.xsl index b665cf36f7d..965a3a334d1 100644 --- a/tools/apidoc/generatecommand.xsl +++ b/tools/apidoc/generatecommand.xsl @@ -179,9 +179,9 @@ version="1.0">
  • Contacts
  • -

    Copyright © 2012 The Apache Software Foundation, Licensed under the +

    Copyright © 2013 The Apache Software Foundation, Licensed under the Apache License, Version 2.0.
    - Apache and the Apache feather logo are trademarks of The Apache Software Foundation.

    + Apache, CloudStack, Apache CloudStack, the Apache CloudStack logo, the CloudMonkey logo and the Apache feather logo are trademarks of The Apache Software Foundation.

    diff --git a/tools/apidoc/generatedomainadmincommands.xsl b/tools/apidoc/generatedomainadmincommands.xsl index 7f5321cc06e..7238f05369f 100644 --- a/tools/apidoc/generatedomainadmincommands.xsl +++ b/tools/apidoc/generatedomainadmincommands.xsl @@ -144,9 +144,9 @@ version="1.0"> diff --git a/tools/apidoc/generatetoc_footer.xsl b/tools/apidoc/generatetoc_footer.xsl index cf6dbc4c7b3..93a86671084 100644 --- a/tools/apidoc/generatetoc_footer.xsl +++ b/tools/apidoc/generatetoc_footer.xsl @@ -26,9 +26,9 @@ under the License. diff --git a/tools/apidoc/generateusercommands.xsl b/tools/apidoc/generateusercommands.xsl index e884ab13ac3..4fa1f867fe5 100644 --- a/tools/apidoc/generateusercommands.xsl +++ b/tools/apidoc/generateusercommands.xsl @@ -142,9 +142,9 @@ version="1.0"> diff --git a/tools/apidoc/images/cloudstack.png b/tools/apidoc/images/cloudstack.png index cc3c9d7d342..2f3d899701a 100644 Binary files a/tools/apidoc/images/cloudstack.png and b/tools/apidoc/images/cloudstack.png differ diff --git a/tools/apidoc/images/ins_buttonshadow.gif b/tools/apidoc/images/ins_buttonshadow.gif deleted file mode 100644 index ac34ec859c9..00000000000 Binary files a/tools/apidoc/images/ins_buttonshadow.gif and /dev/null differ diff --git a/tools/apidoc/images/insdownload_button.gif b/tools/apidoc/images/insdownload_button.gif deleted file mode 100644 index eb5cb5e700f..00000000000 Binary files a/tools/apidoc/images/insdownload_button.gif and /dev/null differ diff --git a/tools/apidoc/images/insdownload_button_hover.gif b/tools/apidoc/images/insdownload_button_hover.gif deleted file mode 100644 index 424ab461f52..00000000000 Binary files a/tools/apidoc/images/insdownload_button_hover.gif and /dev/null differ diff --git a/tools/apidoc/images/insjoincomm_button.gif b/tools/apidoc/images/insjoincomm_button.gif deleted file mode 100644 index f149c8506c1..00000000000 Binary files a/tools/apidoc/images/insjoincomm_button.gif and /dev/null differ diff --git a/tools/apidoc/images/insjoincomm_button_hover.gif b/tools/apidoc/images/insjoincomm_button_hover.gif deleted file mode 100644 index 74df0a60e64..00000000000 Binary files a/tools/apidoc/images/insjoincomm_button_hover.gif and /dev/null differ diff --git a/tools/apidoc/includes/main.css b/tools/apidoc/includes/main.css index a8fa348065b..1c3baa871db 100644 --- a/tools/apidoc/includes/main.css +++ b/tools/apidoc/includes/main.css @@ -239,7 +239,7 @@ a:hover.insdownload_button { a.cloud_logo { - width:300px; + width:373px; height:51px; float:left; background:url(../images/cloudstack.png) no-repeat top left; diff --git a/tools/cli/cloudmonkey/config.py b/tools/cli/cloudmonkey/config.py index aaf97ebd25d..36f7e77ed82 100644 --- a/tools/cli/cloudmonkey/config.py +++ b/tools/cli/cloudmonkey/config.py @@ -18,7 +18,7 @@ # Use following rules for versioning: # - -__version__ = "4.1.0-0" +__version__ = "4.2.0-0" __description__ = "Command Line Interface for Apache CloudStack" __maintainer__ = "Rohit Yadav" __maintaineremail__ = "bhaisaab@apache.org" diff --git a/tools/cli/cloudmonkey/requester.py b/tools/cli/cloudmonkey/requester.py index d2dae6dfc3f..b06e1fc99e3 100644 --- a/tools/cli/cloudmonkey/requester.py +++ b/tools/cli/cloudmonkey/requester.py @@ -125,61 +125,36 @@ def monkeyrequest(command, args, isasync, asyncblock, logger, host, port, command = "queryAsyncJobResult" request = {'jobid': jobid} timeout = int(timeout) - pollperiod = 3 + pollperiod = 2 progress = 1 while timeout > 0: print '\r' + '.' * progress, sys.stdout.flush() - progress += 1 + time.sleep(pollperiod) timeout = timeout - pollperiod + progress += 1 logger_debug(logger, "Job %s to timeout in %ds" % (jobid, timeout)) - sys.stdout.flush() - if re.match("queryAsyncJobResult", command): - time.sleep(pollperiod) - else: - response, error = monkeyrequest(command, request, isasync, - asyncblock, logger, - host, port, apikey, secretkey, - timeout, protocol, path) + response, error = make_request(command, request, logger, + host, port, apikey, secretkey, + protocol, path) + if error is not None: + return response, error + response = process_json(response) responsekeys = filter(lambda x: 'response' in x, response.keys()) if len(responsekeys) < 1: - time.sleep(pollperiod) continue result = response[responsekeys[0]] jobstatus = result['jobstatus'] - jobresultcode = result['jobresultcode'] - try: - jobresult = result["jobresult"] - logger_debug(logger, "jobresult %s" % (jobresult)) - sys.stdout.flush() - return response, None - except KeyError: - logger_debug(logger, "No jobresult yet %s" % (result)) - sys.stdout.flush() - - if jobresultcode != 0: - error = "Error: resultcode %d for jobid %s" % (jobresultcode, - jobid) - logger_debug(logger, "%s" % (error)) - return response, error - else: - # if we get a valid respons resultcode give back results - response, error = monkeyrequest(command, request, isasync, - asyncblock, logger, - host, port, apikey, secretkey, - timeout, protocol, path) - logger_debug(logger, "Ok: %s" % (jobid)) - return response, error - if jobstatus == 2: + jobresult = result["jobresult"] error = "\rAsync job %s failed\nError %s, %s" % (jobid, jobresult["errorcode"], jobresult["errortext"]) return response, error elif jobstatus == 1: - print '\r', + print "\r" + " " * progress, return response, error else: logger_debug(logger, "We should not arrive here!") diff --git a/ui/index.jsp b/ui/index.jsp index 2992afb5c31..34f0c54175b 100644 --- a/ui/index.jsp +++ b/ui/index.jsp @@ -1698,7 +1698,6 @@ under the License. - diff --git a/ui/scripts/configuration.js b/ui/scripts/configuration.js index e813c66721d..150f244ff3c 100644 --- a/ui/scripts/configuration.js +++ b/ui/scripts/configuration.js @@ -1411,8 +1411,11 @@ } }); } - $providers.each(function() { - $(this).val($(this).find('option:first')); + $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')); + } }); diff --git a/ui/scripts/system.js b/ui/scripts/system.js index f853ed53f7e..df37f31d5fe 100644 --- a/ui/scripts/system.js +++ b/ui/scripts/system.js @@ -1340,7 +1340,7 @@ docID: 'helpGuestNetworkZoneVLANID' }, isolatedpvlanId: { - label: 'Private VLAN ID' + label: 'Secondary Isolated VLAN ID' }, scope: { @@ -7899,7 +7899,13 @@ lbdevicededicated: { label: 'label.dedicated', converter: cloudStack.converters.toBooleanText - } + }, + gslbprovider: { + label: 'GSLB service', + converter: cloudStack.converters.toBooleanText + }, + gslbproviderpublicip: { label: 'GSLB service Public IP' }, + gslbproviderprivateip: { label: 'GSLB service Private IP' } } ], dataProvider: function(args) { diff --git a/ui/scripts/ui/widgets/listView.js b/ui/scripts/ui/widgets/listView.js index ba4d2881580..8dbc2f6ffbc 100644 --- a/ui/scripts/ui/widgets/listView.js +++ b/ui/scripts/ui/widgets/listView.js @@ -1327,6 +1327,12 @@ }); $table.dataTable(null, { noSelect: uiCustom }); + if(args.data && + args.data.length < pageSize && + options.setEndTable) { + options.setEndTable(); + } + setTimeout(function() { $table.dataTable('refresh'); }); @@ -1467,6 +1473,12 @@ var page = 1; var actions = listViewData.actions; var reorder = listViewData.reorder; + var tableHeight = $table.height(); + var endTable = false; + var setEndTable = function() { + endTable = true; + } + var $switcher; if (args.sections) { @@ -1572,7 +1584,8 @@ { context: args.context, reorder: reorder, - detailView: listViewData.detailView + detailView: listViewData.detailView, + setEndTable: setEndTable } ); @@ -1625,7 +1638,8 @@ { context: $listView.data('view-args').context, reorder: listViewData.reorder, - detailView: listViewData.detailView + detailView: listViewData.detailView, + setEndTable: setEndTable } ); }; @@ -1675,7 +1689,8 @@ { context: $listView.data('view-args').context, reorder: listViewData.reorder, - detailView: listViewData.detailView + detailView: listViewData.detailView, + setEndTable: setEndTable } ); }; @@ -1728,8 +1743,6 @@ return false; }); - var tableHeight = $table.height(); - var endTable = false; // Infinite scrolling event $listView.bind('scroll', function(event) { @@ -1767,7 +1780,8 @@ filterBy: filterBy }, actions, { reorder: listViewData.reorder, - detailView: listViewData.detailView + detailView: listViewData.detailView, + setEndTable: setEndTable }); $table.height() == tableHeight ? endTable = true : tableHeight = $table.height(); } diff --git a/ui/scripts/vpc.js b/ui/scripts/vpc.js index 399699d3948..759364ded1a 100644 --- a/ui/scripts/vpc.js +++ b/ui/scripts/vpc.js @@ -97,6 +97,13 @@ name != 'icmpcode' && name != 'cidrlist'; }); + var $portFields = $inputs.filter(function() { + var name = $(this).attr('name'); + return $.inArray(name, [ + 'startport', + 'endport' + ]) > -1; + }); var $protocolinput = args.$form.find('td input'); var $protocolFields = $protocolinput.filter(function(){ @@ -124,6 +131,10 @@ $icmpFields.hide(); $icmpFields.parent().find('label.error').hide(); $protocolFields.hide().removeClass('required'); + if ($(this).val() == 'all'){ + $portFields.attr('disabled', 'disabled'); + $portFields.hide(); + } } }); @@ -216,11 +227,11 @@ - if((args.data.protocol == 'tcp' || args.data.protocol == 'udp' || args.data.protocol == 'all') && (args.data.startport=="" || args.data.startport == undefined)){ + if((args.data.protocol == 'tcp' || args.data.protocol == 'udp') && (args.data.startport=="" || args.data.startport == undefined)){ cloudStack.dialog.notice({message:_l('Start Port or End Port value should not be blank')}); $(window).trigger('cloudStack.fullRefresh'); } - else if((args.data.protocol == 'tcp' || args.data.protocol == 'udp' || args.data.protocol == 'all') && (args.data.endport=="" || args.data.endport == undefined)){ + else if((args.data.protocol == 'tcp' || args.data.protocol == 'udp') && (args.data.endport=="" || args.data.endport == undefined)){ cloudStack.dialog.notice({message:_l('Start Port or End Port value should not be blank')}); $(window).trigger('cloudStack.fullRefresh'); } @@ -761,7 +772,7 @@ } }); }, - notificaton: { + notification: { poll: pollAsyncJobResult } } diff --git a/utils/src/com/cloud/utils/net/NetUtils.java b/utils/src/com/cloud/utils/net/NetUtils.java index ec0ff05fce8..5c13454da79 100755 --- a/utils/src/com/cloud/utils/net/NetUtils.java +++ b/utils/src/com/cloud/utils/net/NetUtils.java @@ -1394,4 +1394,13 @@ public class NetUtils { return null; } + public static String generateMacOnIncrease(String baseMac, long l) { + long mac = mac2Long(baseMac); + if (l > 0xFFFFl) { + return null; + } + mac = mac + (l << 24); + mac = mac & 0x06FFFFFFFFFFl; + return long2Mac(mac); + } } diff --git a/utils/test/com/cloud/utils/net/NetUtilsTest.java b/utils/test/com/cloud/utils/net/NetUtilsTest.java index 9952d3cd864..38fe21d5324 100644 --- a/utils/test/com/cloud/utils/net/NetUtilsTest.java +++ b/utils/test/com/cloud/utils/net/NetUtilsTest.java @@ -155,4 +155,17 @@ public class NetUtilsTest extends TestCase { //Check for Incorrect format of CIDR assertFalse(NetUtils.isSameIpRange(cidrFirst, "10.3.6.5/50")); } + + public void testMacGenerateion() { + String mac = "06:01:23:00:45:67"; + String newMac = NetUtils.generateMacOnIncrease(mac, 2); + assertTrue(newMac.equals("06:01:25:00:45:67")); + newMac = NetUtils.generateMacOnIncrease(mac, 16); + assertTrue(newMac.equals("06:01:33:00:45:67")); + mac = "06:ff:ff:00:45:67"; + newMac = NetUtils.generateMacOnIncrease(mac, 1); + assertTrue(newMac.equals("06:00:00:00:45:67")); + newMac = NetUtils.generateMacOnIncrease(mac, 16); + assertTrue(newMac.equals("06:00:0f:00:45:67")); + } }