|
30 | 30 | Renamed from ``test_network_extension_provider.py``. The canonical test file |
31 | 31 | is ``test_network_extension_namespace.py``. |
32 | 32 | """ |
33 | | -import base64 |
34 | 33 | import json |
35 | 34 | import logging |
36 | 35 | import os |
|
97 | 96 | NETWORK_CAPABILITIES_JSON = json.dumps({ |
98 | 97 | "services": [ |
99 | 98 | "Dhcp", "Dns", "UserData", |
100 | | - "SourceNat", "StaticNat", "PortForwarding", "Firewall", "Lb" |
| 99 | + "SourceNat", "StaticNat", "PortForwarding", "Firewall", "Lb", "NetworkACL" |
101 | 100 | ], |
102 | 101 | "capabilities": { |
| 102 | + "Lb": { |
| 103 | + "SupportedLBAlgorithms": "roundrobin,leastconn,source", |
| 104 | + "SupportedLBIsolation": "dedicated", |
| 105 | + "SupportedProtocols": "tcp,udp,tcp-proxy", |
| 106 | + "SupportedStickinessMethods": "lbcookie,appsession", |
| 107 | + "LbSchemes": "Public", |
| 108 | + "SslTermination": "false", |
| 109 | + "VmAutoScaling": "false" |
| 110 | + }, |
| 111 | + "Firewall": { |
| 112 | + "TrafficStatistics": "per public ip", |
| 113 | + "SupportedProtocols": "tcp,udp,icmp", |
| 114 | + "SupportedEgressProtocols": "tcp,udp,icmp,all", |
| 115 | + "SupportedTrafficDirection": "ingress,egress", |
| 116 | + "MultipleIps": "true" |
| 117 | + }, |
| 118 | + "Dns": { |
| 119 | + "AllowDnsSuffixModification": "true", |
| 120 | + "ExternalDns": "true" |
| 121 | + }, |
| 122 | + "Dhcp": { |
| 123 | + "DhcpAccrossMultipleSubnets": "true" |
| 124 | + }, |
| 125 | + "Gateway": { |
| 126 | + "RedundantRouter": "false" |
| 127 | + }, |
103 | 128 | "SourceNat": { |
104 | 129 | "SupportedSourceNatTypes": "peraccount", |
105 | 130 | "RedundantRouter": "false" |
106 | 131 | }, |
107 | | - "Firewall": { |
108 | | - "TrafficStatistics": "per public ip" |
| 132 | + "StaticNat": { |
| 133 | + "Supported": "true" |
| 134 | + }, |
| 135 | + "PortForwarding": { |
| 136 | + "SupportedProtocols": "tcp,udp" |
| 137 | + }, |
| 138 | + "UserData": { |
| 139 | + "Supported": "true" |
| 140 | + }, |
| 141 | + "NetworkACL": { |
| 142 | + "SupportedProtocols": "tcp,udp,icmp" |
109 | 143 | } |
110 | 144 | } |
111 | 145 | }) |
@@ -230,10 +264,9 @@ def _ssh_copy_file(host_ip, host_port, username, password, local_path, remote_pa |
230 | 264 | """Transfer *local_path* to *remote_path* on *host_ip* via SshClient.""" |
231 | 265 | ssh = SshClient(host_ip, int(host_port), username, password) |
232 | 266 | ssh.execute("mkdir -p '%s'" % os.path.dirname(remote_path)) |
233 | | - with open(local_path, 'rb') as fh: |
234 | | - b64 = base64.b64encode(fh.read()).decode() |
235 | | - ssh.execute("echo '%s' | base64 -d > '%s' && chmod 755 '%s'" % |
236 | | - (b64, remote_path, remote_path)) |
| 267 | + # Use SFTP upload to avoid very large shell arguments for script content. |
| 268 | + ssh.scp(local_path, remote_path) |
| 269 | + ssh.execute("chmod 755 '%s'" % remote_path) |
237 | 270 |
|
238 | 271 |
|
239 | 272 | # --------------------------------------------------------------------------- |
@@ -484,9 +517,8 @@ def _deploy_scripts(self): |
484 | 517 |
|
485 | 518 | self.mgmt_deployer = MgmtServerDeployer(self.mgtSvrDetails, |
486 | 519 | logger=self.logger) |
487 | | - # The extension framework executes <extension-name>.sh from extension_path. |
488 | | - extension_script = "%s.sh" % os.path.basename(self.extension_path.rstrip('/')) |
489 | | - self._mgmt_script_path = os.path.join(self.extension_path, extension_script) |
| 520 | + # Extension path is the entrypoint file path; append .sh if omitted. |
| 521 | + self._mgmt_script_path = (self.extension_path or "").strip().rstrip('/') |
490 | 522 | self.mgmt_deployer.copy_file(entry_point_src, self._mgmt_script_path) |
491 | 523 | self.logger.info("network-namespace.sh deployed to mgmt at %s", |
492 | 524 | self._mgmt_script_path) |
@@ -659,9 +691,9 @@ def _setup_extension_nsp_offering(self, ext_name_prefix, |
659 | 691 |
|
660 | 692 | # Register extension to physical network |
661 | 693 | register_details = [ |
662 | | - {"key": "hosts", "value": kvm_hosts_csv}, |
663 | | - {"key": "username", "value": self.kvm_host_configs[0].get('username', 'root')}, |
664 | | - {"key": "password", "value": self.kvm_host_configs[0].get('password', '')}, |
| 694 | + {"hosts": kvm_hosts_csv}, |
| 695 | + {"username": self.kvm_host_configs[0].get('username', 'root')}, |
| 696 | + {"password": self.kvm_host_configs[0].get('password', '')}, |
665 | 697 | ] |
666 | 698 |
|
667 | 699 | self.extension.register( |
@@ -1000,9 +1032,9 @@ def test_05_isolated_network_full_lifecycle(self): |
1000 | 1032 | → assert SSH works (namespace rebuilt, rules reapplied) |
1001 | 1033 | """ |
1002 | 1034 | # ---- Setup ---- |
1003 | | - svc = "SourceNat,StaticNat,PortForwarding,Firewall,Lb,UserData" |
| 1035 | + svc = "SourceNat,StaticNat,PortForwarding,Firewall,Lb,UserData,Dhcp,Dns" |
1004 | 1036 | nw_offering, _ext_name = self._setup_extension_nsp_offering( |
1005 | | - "extnet-iso", supported_services=svc) |
| 1037 | + "extnet-isolated", supported_services=svc) |
1006 | 1038 | account, network, vm = self._create_account_network_vm( |
1007 | 1039 | nw_offering, name_suffix="iso") |
1008 | 1040 |
|
@@ -1181,12 +1213,12 @@ def test_06_vpc_multi_tier_and_restart(self): |
1181 | 1213 | CloudStack for VPC-associated tier networks. |
1182 | 1214 | """ |
1183 | 1215 | # ---- Setup: extension + NSP + isolated offering (for reference) ---- |
1184 | | - svc = "SourceNat,StaticNat,PortForwarding,Lb,UserData" |
| 1216 | + svc = "SourceNat,StaticNat,PortForwarding,Lb,UserData,Dhcp,Dns" |
1185 | 1217 | _nw_offering, ext_name = self._setup_extension_nsp_offering( |
1186 | 1218 | "extnet-vpc", supported_services=svc) |
1187 | 1219 |
|
1188 | 1220 | # ---- VPC tier network offering (useVpc=on) ---- |
1189 | | - vpc_tier_svc = "SourceNat,StaticNat,PortForwarding,Lb,UserData" |
| 1221 | + vpc_tier_svc = "SourceNat,StaticNat,PortForwarding,Lb,UserData,Dhcp,Dns" |
1190 | 1222 | _tier_prov = {s.strip(): ext_name for s in vpc_tier_svc.split(',')} |
1191 | 1223 | vpc_tier_offering = NetworkOffering.create(self.apiclient, { |
1192 | 1224 | "name": "ExtNet-VPCTier-%s" % random_gen(), |
|
0 commit comments