|
35 | 35 | Router, |
36 | 36 | StaticNATRule, |
37 | 37 | NetworkACL, |
38 | | - PublicIPAddress) |
| 38 | + PublicIPAddress, |
| 39 | + Host, |
| 40 | + Cluster, |
| 41 | + Configurations, |
| 42 | + Resources) |
39 | 43 | from marvin.lib.common import (get_zone, |
40 | 44 | get_domain, |
41 | 45 | get_template, |
|
51 | 55 |
|
52 | 56 |
|
53 | 57 | class Services: |
54 | | - |
55 | 58 | """Test VPC network services |
56 | 59 | """ |
57 | 60 |
|
@@ -187,7 +190,9 @@ def __init__(self): |
187 | 190 | "network": { |
188 | 191 | "name": "Test Network", |
189 | 192 | "displaytext": "Test Network", |
190 | | - "netmask": '255.255.255.0' |
| 193 | + "netmask": '255.255.255.0', |
| 194 | + # Max networks allowed per VPC: Xenserver -> 7, VMWare -> 10 & KVM -> 27 |
| 195 | + "limit": 5, |
191 | 196 | }, |
192 | 197 | "lbrule": { |
193 | 198 | "name": "SSH", |
@@ -2756,3 +2761,307 @@ def test_stop_start_vpc_router(self): |
2756 | 2761 | if (exceptionOccurred or (not isRouterInDesiredState)): |
2757 | 2762 | self.fail(exceptionMessage) |
2758 | 2763 | return |
| 2764 | + |
| 2765 | + |
| 2766 | +class TestVPCNetworkHypervisorLimit(cloudstackTestCase): |
| 2767 | + |
| 2768 | + @classmethod |
| 2769 | + def setUpClass(cls): |
| 2770 | + cls.testClient = super(TestVPCNetworkHypervisorLimit, cls).getClsTestClient() |
| 2771 | + cls.api_client = cls.testClient.getApiClient() |
| 2772 | + |
| 2773 | + cls.services = Services().services |
| 2774 | + |
| 2775 | + cls.domain = get_domain(cls.api_client) |
| 2776 | + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) |
| 2777 | + |
| 2778 | + cls._cleanup = [] |
| 2779 | + |
| 2780 | + return |
| 2781 | + |
| 2782 | + def setUp(self): |
| 2783 | + self.apiclient = self.testClient.getApiClient() |
| 2784 | + self.dbclient = self.testClient.getDbConnection() |
| 2785 | + self.account = Account.create( |
| 2786 | + self.apiclient, |
| 2787 | + self.services["account"], |
| 2788 | + admin=True, |
| 2789 | + domainid=self.domain.id |
| 2790 | + ) |
| 2791 | + self.cleanup = [self.account] |
| 2792 | + |
| 2793 | + return |
| 2794 | + |
| 2795 | + @classmethod |
| 2796 | + def tearDownClass(cls): |
| 2797 | + super(TestVPCNetworkHypervisorLimit, cls).tearDownClass() |
| 2798 | + |
| 2799 | + def tearDown(self): |
| 2800 | + super(TestVPCNetworkHypervisorLimit, self).tearDown() |
| 2801 | + |
| 2802 | + def validate_vpc_network(self, network, state=None): |
| 2803 | + """Validates the VPC network""" |
| 2804 | + |
| 2805 | + self.debug("Checking if the VPC network was created successfully.") |
| 2806 | + vpc_networks = VPC.list( |
| 2807 | + self.apiclient, |
| 2808 | + id=network.id |
| 2809 | + ) |
| 2810 | + self.assertEqual( |
| 2811 | + isinstance(vpc_networks, list), |
| 2812 | + True, |
| 2813 | + "List VPC network should return a valid list" |
| 2814 | + ) |
| 2815 | + self.assertEqual( |
| 2816 | + network.name, |
| 2817 | + vpc_networks[0].name, |
| 2818 | + "Name of the VPC network should match with listVPC data" |
| 2819 | + ) |
| 2820 | + if state: |
| 2821 | + self.assertEqual( |
| 2822 | + vpc_networks[0].state, |
| 2823 | + state, |
| 2824 | + "VPC state should be '%s'" % state |
| 2825 | + ) |
| 2826 | + self.debug("VPC network validated - %s" % network.name) |
| 2827 | + |
| 2828 | + return |
| 2829 | + |
| 2830 | + def validate_vpc_offering(self, vpc_offering): |
| 2831 | + """Validates the VPC offering""" |
| 2832 | + |
| 2833 | + self.debug("Checking if the VPC offering was created successfully.") |
| 2834 | + vpc_offs = VpcOffering.list( |
| 2835 | + self.apiclient, |
| 2836 | + id=vpc_offering.id |
| 2837 | + ) |
| 2838 | + self.assertEqual( |
| 2839 | + isinstance(vpc_offs, list), |
| 2840 | + True, |
| 2841 | + "List VPC offerings should return a valid list" |
| 2842 | + ) |
| 2843 | + self.assertEqual( |
| 2844 | + vpc_offering.name, |
| 2845 | + vpc_offs[0].name, |
| 2846 | + "Name of the VPC offering should match with listVPCOff data" |
| 2847 | + ) |
| 2848 | + self.debug("VPC offering was created successfully - %s" % vpc_offering.name) |
| 2849 | + |
| 2850 | + return |
| 2851 | + |
| 2852 | + def create_network_max_limit_hypervisor_test(self, hypervisor): |
| 2853 | + Configurations.update( |
| 2854 | + self.apiclient, |
| 2855 | + accountid=self.account.id, |
| 2856 | + name="vpc.max.networks", |
| 2857 | + value=30 |
| 2858 | + ) |
| 2859 | + |
| 2860 | + self.debug("Creating a VPC offering.") |
| 2861 | + vpc_off = VpcOffering.create( |
| 2862 | + self.apiclient, |
| 2863 | + self.services["vpc_offering"] |
| 2864 | + ) |
| 2865 | + |
| 2866 | + self._cleanup.append(vpc_off) |
| 2867 | + self.validate_vpc_offering(vpc_off) |
| 2868 | + |
| 2869 | + self.debug("Enabling the VPC offering.") |
| 2870 | + vpc_off.update(self.apiclient, state='Enabled') |
| 2871 | + |
| 2872 | + self.debug("Creating a VPC network in the account: %s" % self.account.name) |
| 2873 | + self.services["vpc"]["cidr"] = '10.1.1.1/16' |
| 2874 | + vpc = VPC.create( |
| 2875 | + self.apiclient, |
| 2876 | + self.services["vpc"], |
| 2877 | + vpcofferingid=vpc_off.id, |
| 2878 | + zoneid=self.zone.id, |
| 2879 | + account=self.account.name, |
| 2880 | + domainid=self.account.domainid |
| 2881 | + ) |
| 2882 | + self.validate_vpc_network(vpc) |
| 2883 | + |
| 2884 | + vpc_router = Router.list( |
| 2885 | + self.apiclient, |
| 2886 | + vpcId=vpc.id, |
| 2887 | + listAll=True |
| 2888 | + )[0] |
| 2889 | + |
| 2890 | + host = Host.list( |
| 2891 | + self.apiclient, |
| 2892 | + id=vpc_router.hostId |
| 2893 | + )[0] |
| 2894 | + |
| 2895 | + cluster = Cluster.list( |
| 2896 | + self.apiclient, |
| 2897 | + id=host.clusterId |
| 2898 | + )[0] |
| 2899 | + |
| 2900 | + cluster_old_hypervisor_type = cluster.hypervisortype |
| 2901 | + |
| 2902 | + self.debug("Updating cluster %s hypervisor from %s to %s." % |
| 2903 | + (cluster.name, cluster_old_hypervisor_type, hypervisor)) |
| 2904 | + Cluster.update( |
| 2905 | + self.apiclient, |
| 2906 | + id=cluster.id, |
| 2907 | + hypervisor=hypervisor |
| 2908 | + ) |
| 2909 | + |
| 2910 | + network_offering = NetworkOffering.create( |
| 2911 | + self.apiclient, |
| 2912 | + self.services["network_offering"], |
| 2913 | + conservemode=False |
| 2914 | + ) |
| 2915 | + # Enable Network offering |
| 2916 | + self._cleanup.append(network_offering) |
| 2917 | + network_offering.update(self.apiclient, state='Enabled') |
| 2918 | + |
| 2919 | + # Empty list to store all networks |
| 2920 | + networks = [] |
| 2921 | + |
| 2922 | + # Creating network using the network offering created |
| 2923 | + self.debug("Creating network with network offering: %s." % network_offering.id) |
| 2924 | + network_1 = Network.create( |
| 2925 | + self.apiclient, |
| 2926 | + self.services["network"], |
| 2927 | + accountid=self.account.name, |
| 2928 | + domainid=self.account.domainid, |
| 2929 | + networkofferingid=network_offering.id, |
| 2930 | + zoneid=self.zone.id, |
| 2931 | + gateway='10.1.0.1', |
| 2932 | + vpcid=vpc.id |
| 2933 | + ) |
| 2934 | + |
| 2935 | + self.debug("Created network with ID: %s." % network_1.id) |
| 2936 | + |
| 2937 | + config_name = "virtual.machine.max.nics.%s" % hypervisor.lower() |
| 2938 | + |
| 2939 | + configs = Configurations.list( |
| 2940 | + self.apiclient, |
| 2941 | + name=config_name, |
| 2942 | + listall=True |
| 2943 | + ) |
| 2944 | + if not isinstance(configs, list): |
| 2945 | + raise Exception("Failed to find %s virtual machine max NICs." % hypervisor) |
| 2946 | + |
| 2947 | + self.services["network"]["limit"] = int(configs[0].value) |
| 2948 | + |
| 2949 | + self.debug("Updating network resource limit for account %s with value %s." % ( |
| 2950 | + self.account.name, self.services["network"]["limit"])) |
| 2951 | + Resources.updateLimit( |
| 2952 | + self.apiclient, |
| 2953 | + resourcetype=6, |
| 2954 | + account=self.account.name, |
| 2955 | + domainid=self.domain.id, |
| 2956 | + max=self.services["network"]["limit"] |
| 2957 | + ) |
| 2958 | + |
| 2959 | + # Create networks till max limit of hypervisor |
| 2960 | + for i in range(self.services["network"]["limit"] - 3): |
| 2961 | + # Creating network using the network offering created |
| 2962 | + self.debug("Creating network with network offering: %s." % |
| 2963 | + network_offering.id) |
| 2964 | + gateway = '10.1.' + str(i + 1) + '.1' |
| 2965 | + self.debug("Gateway for new network: %s." % gateway) |
| 2966 | + |
| 2967 | + network = Network.create( |
| 2968 | + self.apiclient, |
| 2969 | + self.services["network"], |
| 2970 | + accountid=self.account.name, |
| 2971 | + domainid=self.account.domainid, |
| 2972 | + networkofferingid=network_offering.id, |
| 2973 | + zoneid=self.zone.id, |
| 2974 | + gateway=gateway, |
| 2975 | + vpcid=vpc.id |
| 2976 | + ) |
| 2977 | + self.debug("Created network with ID: %s." % network.id) |
| 2978 | + networks.append(network) |
| 2979 | + |
| 2980 | + self.debug( |
| 2981 | + "Trying to create one more network than %s hypervisor limit in VPC: %s." % (hypervisor, vpc.name)) |
| 2982 | + gateway = '10.1.' + str(self.services["network"]["limit"]) + '.1' |
| 2983 | + |
| 2984 | + with self.assertRaises(Exception): |
| 2985 | + Network.create( |
| 2986 | + self.apiclient, |
| 2987 | + self.services["network"], |
| 2988 | + accountid=self.account.name, |
| 2989 | + domainid=self.account.domainid, |
| 2990 | + networkofferingid=network_offering.id, |
| 2991 | + zoneid=self.zone.id, |
| 2992 | + gateway=gateway, |
| 2993 | + vpcid=vpc.id |
| 2994 | + ) |
| 2995 | + |
| 2996 | + self.debug("Deleting one of the existing networks.") |
| 2997 | + try: |
| 2998 | + network_1.delete(self.apiclient) |
| 2999 | + except Exception as e: |
| 3000 | + self.fail("Failed to delete network: %s - %s." % |
| 3001 | + (network_1.name, e)) |
| 3002 | + |
| 3003 | + self.debug("Creating a new network in VPC: %s." % vpc.name) |
| 3004 | + network = Network.create( |
| 3005 | + self.apiclient, |
| 3006 | + self.services["network"], |
| 3007 | + accountid=self.account.name, |
| 3008 | + domainid=self.account.domainid, |
| 3009 | + networkofferingid=network_offering.id, |
| 3010 | + zoneid=self.zone.id, |
| 3011 | + gateway=gateway, |
| 3012 | + vpcid=vpc.id |
| 3013 | + ) |
| 3014 | + self.debug("Created a new network: %s." % network.name) |
| 3015 | + networks.append(network) |
| 3016 | + |
| 3017 | + self.debug( |
| 3018 | + "Updating cluster %s hypervisor to its old hypervisor %s." % (cluster.name, cluster_old_hypervisor_type)) |
| 3019 | + Cluster.update( |
| 3020 | + self.apiclient, |
| 3021 | + id=cluster.id, |
| 3022 | + hypervisor=cluster_old_hypervisor_type |
| 3023 | + ) |
| 3024 | + |
| 3025 | + return |
| 3026 | + |
| 3027 | + @attr(tags=["advanced", "intervlan"], required_hardware="true") |
| 3028 | + def test_01_create_network_max_limit_xenserver(self): |
| 3029 | + """ Test create networks in VPC up to maximum limit for XenServer hypervisor. |
| 3030 | + """ |
| 3031 | + |
| 3032 | + # Validate the following |
| 3033 | + # 1. Create a VPC and add maximum # of supported networks to the VPC; |
| 3034 | + # 2. After reaching the maximum networks, adding another network to the VPC must raise an exception; |
| 3035 | + # 3. Delete a network from VPC; |
| 3036 | + # 4. Add a new network to the VPC. |
| 3037 | + |
| 3038 | + self.create_network_max_limit_hypervisor_test("XenServer") |
| 3039 | + return |
| 3040 | + |
| 3041 | + @attr(tags=["advanced", "intervlan"], required_hardware="true") |
| 3042 | + def test_02_create_network_max_limit_vmware(self): |
| 3043 | + """ Test create networks in VPC up to maximum limit for VMware hypervisor. |
| 3044 | + """ |
| 3045 | + |
| 3046 | + # Validate the following |
| 3047 | + # 1. Create a VPC and add maximum # of supported networks to the VPC; |
| 3048 | + # 2. After reaching the maximum networks, adding another network to the VPC must raise an exception; |
| 3049 | + # 3. Delete a network from VPC; |
| 3050 | + # 4. Add a new network to the VPC. |
| 3051 | + |
| 3052 | + self.create_network_max_limit_hypervisor_test("VMware") |
| 3053 | + return |
| 3054 | + |
| 3055 | + @attr(tags=["advanced", "intervlan"], required_hardware="true") |
| 3056 | + def test_03_create_network_max_limit_kvm(self): |
| 3057 | + """ Test create networks in VPC up to maximum limit for KVM hypervisor. |
| 3058 | + """ |
| 3059 | + |
| 3060 | + # Validate the following |
| 3061 | + # 1. Create a VPC and add maximum # of supported networks to the VPC; |
| 3062 | + # 2. After reaching the maximum networks, adding another network to the VPC must raise an exception; |
| 3063 | + # 3. Delete a network from VPC; |
| 3064 | + # 4. Add a new network to the VPC. |
| 3065 | + |
| 3066 | + self.create_network_max_limit_hypervisor_test("KVM") |
| 3067 | + return |
0 commit comments