cloudstack/test/integration/smoke/test_vpc_vpn.py
Wei Zhou 87284f03f0
Upgrade to JRE17 and Upgrade System VMs/VRs to Python3 and Debian 12 (#8497)
* Update to 4.20.0

* Update to python3

* Upgrade to JRE 17

* Upgrade to Debian 12.4.0

* VR: upgrade to python3

for f in `find systemvm/ -name *.py`;do
    if grep "print " $f >/dev/null;then
        2to3-2.7 -w $f
    else
        2to3-2.7 -p -w $f
    fi
done

* java: Use JRE17 in cloudstack packages and systemvmtemplate

Signed-off-by: Rohit Yadav <rohit.yadav@shapeblue.com>

* Add --add-opens to JAVA_OPTS in systemd config

* Add --add-opens to JAVA_OPTS in systemd config for usage

* python3: fix "TypeError: a bytes-like object is required, not 'str'"

* python3: fix "ValueError: must have exactly one of create/read/write/append mode"

* Add --add-exports=java.base/sun.security.x509=ALL-UNNAMED for management server

* Use pip3 instead of pip for centos8

* python3: fix "TypeError: write() argument must be str, not bytes"

```
root@r-1037-VM:~# /opt/cloud/bin/passwd_server_ip.py 10.1.1.1
Traceback (most recent call last):
  File "/opt/cloud/bin/passwd_server_ip.py", line 201, in <module>
    serve()
  File "/opt/cloud/bin/passwd_server_ip.py", line 187, in serve
    initToken()
  File "/opt/cloud/bin/passwd_server_ip.py", line 60, in initToken
    f.write(secureToken)
TypeError: write() argument must be str, not bytes
root@r-1037-VM:~#
```

* Python3: fix "name 'file' is not defined"

```
root@r-1037-VM:~# /opt/cloud/bin/passwd_server_ip.py 10.1.1.1
Traceback (most recent call last):
  File "/opt/cloud/bin/passwd_server_ip.py", line 201, in <module>
    serve()
  File "/opt/cloud/bin/passwd_server_ip.py", line 188, in serve
    loadPasswordFile()
  File "/opt/cloud/bin/passwd_server_ip.py", line 67, in loadPasswordFile
    with file(getPasswordFile()) as f:
NameError: name 'file' is not defined
```

* python3: fix "TypeError: write() argument must be str, not bytes" (two more files)

* Upgrade jaxb version

* python3: fix more "TypeError: a bytes-like object is required, not str"

* python3: fix "Failed to update password server"

Failed to update password server due to: POST data should be bytes, an iterable of bytes, or a file object. It cannot be of type str.

* python3: fix "bad duration value: ikelifetime=24.0h"

Jan 15 13:57:20 systemvm ipsec[3080]: # bad duration value: ikelifetime=24.0h

* python3: fix password server "invalid save_password token"

* test: incease retries in test_vpc_vpn.py

* python3: fix passwd_server_ip.py

see error below
```
Jan 15 18:51:21 systemvm passwd_server_ip.py[1507]: ----------------------------------------
Jan 15 18:51:21 systemvm passwd_server_ip.py[1507]: Exception occurred during processing of request from ('10.1.1.129', 32782)
Jan 15 18:51:21 systemvm passwd_server_ip.py[1507]: Traceback (most recent call last):
Jan 15 18:51:21 systemvm passwd_server_ip.py[1507]:   File "/usr/lib/python3.9/socketserver.py", line 650, in process_request_thread
Jan 15 18:51:21 systemvm passwd_server_ip.py[1507]:     self.finish_request(request, client_address)
Jan 15 18:51:21 systemvm passwd_server_ip.py[1507]:   File "/usr/lib/python3.9/socketserver.py", line 360, in finish_request
Jan 15 18:51:21 systemvm passwd_server_ip.py[1507]:     self.RequestHandlerClass(request, client_address, self)
Jan 15 18:51:21 systemvm passwd_server_ip.py[1507]:   File "/usr/lib/python3.9/socketserver.py", line 720, in __init__
Jan 15 18:51:21 systemvm passwd_server_ip.py[1507]:     self.handle()
Jan 15 18:51:21 systemvm passwd_server_ip.py[1507]:   File "/usr/lib/python3.9/http/server.py", line 427, in handle
Jan 15 18:51:21 systemvm passwd_server_ip.py[1507]:     self.handle_one_request()
Jan 15 18:51:21 systemvm passwd_server_ip.py[1507]:   File "/usr/lib/python3.9/http/server.py", line 415, in handle_one_request
Jan 15 18:51:21 systemvm passwd_server_ip.py[1507]:     method()
Jan 15 18:51:21 systemvm passwd_server_ip.py[1507]:   File "/opt/cloud/bin/passwd_server_ip.py", line 120, in do_GET
Jan 15 18:51:21 systemvm passwd_server_ip.py[1507]:     self.wfile.write(password)
Jan 15 18:51:21 systemvm passwd_server_ip.py[1507]:   File "/usr/lib/python3.9/socketserver.py", line 799, in write
Jan 15 18:51:21 systemvm passwd_server_ip.py[1507]:     self._sock.sendall(b)
Jan 15 18:51:21 systemvm passwd_server_ip.py[1507]: TypeError: a bytes-like object is required, not 'str'
```

* python3: fix self.cl.get_router_password in Redundant VRs

```
File "/opt/cloud/bin/cs/CsDatabag.py", line 154, in get_router_password
    md5.update(passwd)
TypeError: Unicode-objects must be encoded before hashing"]
```

* scripts: mark multipath scripts as executable

* systemvm template: remove hyperv packages and do not export

* VR: update default RAM size of System VMs/VRs to 512MiB

Before
```
mysql> select id,name,cpu,speed,ram_size,unique_name,system_use from service_offering where name like "System%";
+----+----------------------------------------------------------+------+-------+----------+----------------------------------+------------+
| id | name                                                     | cpu  | speed | ram_size | unique_name                      | system_use |
+----+----------------------------------------------------------+------+-------+----------+----------------------------------+------------+
|  3 | System Offering For Software Router                      |    1 |   500 |      256 | Cloud.Com-SoftwareRouter         |          1 |
|  4 | System Offering For Software Router - Local Storage      |    1 |   500 |      256 | Cloud.Com-SoftwareRouter-Local   |          1 |
|  5 | System Offering For Internal LB VM                       |    1 |   256 |      256 | Cloud.Com-InternalLBVm           |          1 |
|  6 | System Offering For Internal LB VM - Local Storage       |    1 |   256 |      256 | Cloud.Com-InternalLBVm-Local     |          1 |
|  7 | System Offering For Console Proxy                        |    1 |   500 |     1024 | Cloud.com-ConsoleProxy           |          1 |
|  8 | System Offering For Console Proxy - Local Storage        |    1 |   500 |     1024 | Cloud.com-ConsoleProxy-Local     |          1 |
|  9 | System Offering For Secondary Storage VM                 |    1 |   500 |      512 | Cloud.com-SecondaryStorage       |          1 |
| 10 | System Offering For Secondary Storage VM - Local Storage |    1 |   500 |      512 | Cloud.com-SecondaryStorage-Local |          1 |
| 11 | System Offering For Elastic LB VM                        |    1 |   128 |      128 | Cloud.Com-ElasticLBVm            |          1 |
| 12 | System Offering For Elastic LB VM - Local Storage        |    1 |   128 |      128 | Cloud.Com-ElasticLBVm-Local      |          1 |
+----+----------------------------------------------------------+------+-------+----------+----------------------------------+------------+
10 rows in set (0.00 sec)
```

New value
```
mysql> select id,name,cpu,speed,ram_size,unique_name,system_use from service_offering where name like "System%";
+----+----------------------------------------------------------+------+-------+----------+----------------------------------+------------+
| id | name                                                     | cpu  | speed | ram_size | unique_name                      | system_use |
+----+----------------------------------------------------------+------+-------+----------+----------------------------------+------------+
|  3 | System Offering For Software Router                      |    1 |   500 |      512 | Cloud.Com-SoftwareRouter         |          1 |
|  4 | System Offering For Software Router - Local Storage      |    1 |   500 |      512 | Cloud.Com-SoftwareRouter-Local   |          1 |
|  5 | System Offering For Internal LB VM                       |    1 |   256 |      512 | Cloud.Com-InternalLBVm           |          1 |
|  6 | System Offering For Internal LB VM - Local Storage       |    1 |   256 |      512 | Cloud.Com-InternalLBVm-Local     |          1 |
|  7 | System Offering For Console Proxy                        |    1 |   500 |     1024 | Cloud.com-ConsoleProxy           |          1 |
|  8 | System Offering For Console Proxy - Local Storage        |    1 |   500 |     1024 | Cloud.com-ConsoleProxy-Local     |          1 |
|  9 | System Offering For Secondary Storage VM                 |    1 |   500 |      512 | Cloud.com-SecondaryStorage       |          1 |
| 10 | System Offering For Secondary Storage VM - Local Storage |    1 |   500 |      512 | Cloud.com-SecondaryStorage-Local |          1 |
| 11 | System Offering For Elastic LB VM                        |    1 |   128 |      512 | Cloud.Com-ElasticLBVm            |          1 |
| 12 | System Offering For Elastic LB VM - Local Storage        |    1 |   128 |      512 | Cloud.Com-ElasticLBVm-Local      |          1 |
+----+----------------------------------------------------------+------+-------+----------+----------------------------------+------------+
10 rows in set (0.01 sec)
```

* debian12: fix test_network_ipv6 and test_vpc_ipv6

* python3: remove duplicated imports

* debian12: failed to start Apache2 server (SSLCipherSuite @SECLEVEL=0)

error message
```
[Sat Jan 20 22:51:14.595143 2024] [ssl:emerg] [pid 10200:tid 140417063888768] AH02562: Failed to configure certificate cloudinternal.com:443:0 (with chain), check /etc/ssl/certs/cert_apache.crt
[Sat Jan 20 22:51:14.595234 2024] [ssl:emerg] [pid 10200:tid 140417063888768] SSL Library Error: error:0A00018E:SSL routines::ca md too weak
AH00016: Configuration Failed
```

openssl version
```
root@s-167-VM:~# openssl version -a
OpenSSL 3.0.11 19 Sep 2023 (Library: OpenSSL 3.0.11 19 Sep 2023)
built on: Mon Oct 23 17:52:22 2023 UTC
platform: debian-amd64
options:  bn(64,64)
compiler: gcc -fPIC -pthread -m64 -Wa,--noexecstack -Wall -fzero-call-used-regs=used-gpr -DOPENSSL_TLS_SECURITY_LEVEL=2 -Wa,--noexecstack -g -O2 -ffile-prefix-map=/build/reproducible-path/openssl-3.0.11=. -fstack-protector-strong -Wformat -Werror=format-security -DOPENSSL_USE_NODELETE -DL_ENDIAN -DOPENSSL_PIC -DOPENSSL_BUILDING_OPENSSL -DNDEBUG -Wdate-time -D_FORTIFY_SOURCE=2
OPENSSLDIR: "/usr/lib/ssl"
ENGINESDIR: "/usr/lib/x86_64-linux-gnu/engines-3"
MODULESDIR: "/usr/lib/x86_64-linux-gnu/ossl-modules"
Seeding source: os-specific
CPUINFO: OPENSSL_ia32cap=0x80202001478bfffd:0x0
```

certificate
```
root@s-167-VM:~# keytool -printcert -rfc -file /usr/local/cloud/systemvm/certs/realhostip.crt
-----BEGIN CERTIFICATE-----
MIIFZTCCBE2gAwIBAgIHKBCduBUoKDANBgkqhkiG9w0BAQUFADCByjELMAkGA1UE
BhMCVVMxEDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAY
BgNVBAoTEUdvRGFkZHkuY29tLCBJbmMuMTMwMQYDVQQLEypodHRwOi8vY2VydGlm
aWNhdGVzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkxMDAuBgNVBAMTJ0dvIERhZGR5
IFNlY3VyZSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTERMA8GA1UEBRMIMDc5Njky
ODcwHhcNMTIwMjAzMDMzMDQwWhcNMTcwMjA3MDUxMTIzWjBZMRkwFwYDVQQKDBAq
LnJlYWxob3N0aXAuY29tMSEwHwYDVQQLDBhEb21haW4gQ29udHJvbCBWYWxpZGF0
ZWQxGTAXBgNVBAMMECoucmVhbGhvc3RpcC5jb20wggEiMA0GCSqGSIb3DQEBAQUA
A4IBDwAwggEKAoIBAQCDT9AtEfs+s/I8QXp6rrCw0iNJ0+GgsybNHheU+JpL39LM
TZykCrZhZnyDvwdxCoOfE38Sa32baHKNds+y2SHnMNsOkw8OcNucHEBX1FIpOBGp
h9D6xC+umx9od6xMWETUv7j6h2u+WC3OhBM8fHCBqIiAol31/IkcqDxxsHlQ8S/o
CfTlXJUY6Yn628OA1XijKdRnadV0hZ829cv/PZKljjwQUTyrd0KHQeksBH+YAYSo
2JUl8ekNLsOi8/cPtfojnltzRI1GXi0ZONs8VnDzJ0a2gqZY+uxlz+CGbLnGnlN4
j9cBpE+MfUE+35Dq121sTpsSgF85Mz+pVhn2S633AgMBAAGjggG+MIIBujAPBgNV
HRMBAf8EBTADAQEAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAOBgNV
HQ8BAf8EBAMCBaAwMwYDVR0fBCwwKjAooCagJIYiaHR0cDovL2NybC5nb2RhZGR5
LmNvbS9nZHMxLTY0LmNybDBTBgNVHSAETDBKMEgGC2CGSAGG/W0BBxcBMDkwNwYI
KwYBBQUHAgEWK2h0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5jb20vcmVwb3Np
dG9yeS8wgYAGCCsGAQUFBwEBBHQwcjAkBggrBgEFBQcwAYYYaHR0cDovL29jc3Au
Z29kYWRkeS5jb20vMEoGCCsGAQUFBzAChj5odHRwOi8vY2VydGlmaWNhdGVzLmdv
ZGFkZHkuY29tL3JlcG9zaXRvcnkvZ2RfaW50ZXJtZWRpYXRlLmNydDAfBgNVHSME
GDAWgBT9rGEyk2xF1uLuhV+auud2mWjM5zArBgNVHREEJDAighAqLnJlYWxob3N0
aXAuY29tgg5yZWFsaG9zdGlwLmNvbTAdBgNVHQ4EFgQUZyJz9/QLy5TWIIscTXID
E8Xk47YwDQYJKoZIhvcNAQEFBQADggEBAKiUV3KK16mP0NpS92fmQkCLqm+qUWyN
BfBVgf9/M5pcT8EiTZlS5nAtzAE/eRpBeR3ubLlaAogj4rdH7YYVJcDDLLoB2qM3
qeCHu8LFoblkb93UuFDWqRaVPmMlJRnhsRkL1oa2gM2hwQTkBDkP7w5FG1BELCgl
gZI2ij2yxjge6pOEwSyZCzzbCcg9pN+dNrYyGEtB4k+BBnPA3N4r14CWbk+uxjrQ
6j2Ip+b7wOc5IuMEMl8xwTyjuX3lsLbAZyFI9RCyofwA9NqIZ1GeB6Zd196rubQp
93cmBqGGjZUs3wMrGlm7xdjlX6GQ9UvmvkMub9+lL99A5W50QgCmFeI=
-----END CERTIFICATE-----

Warning:
The certificate uses the SHA1withRSA signature algorithm which is considered a security risk. This algorithm will be disabled in a future update.
```

it comes from
```
$ openssl x509 -in ./systemvm/agent/certs/realhostip.crt -noout -text
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 11277268652730408 (0x28109db8152828)
        Signature Algorithm: sha1WithRSAEncryption
        Issuer: C = US, ST = Arizona, L = Scottsdale, O = "GoDaddy.com, Inc.", OU = http://certificates.godaddy.com/repository, CN = Go Daddy Secure Certification Authority, serialNumber = 07969287
        Validity
            Not Before: Feb  3 03:30:40 2012 GMT
            Not After : Feb  7 05:11:23 2017 GMT
        Subject: O = *.realhostip.com, OU = Domain Control Validated, CN = *.realhostip.com
```

* debian12: use ed25519 instead of rsa as ssh-rsa has been deprecated in OpenSSH

on xenserver
```
[root@pr8497-t8906-xenserver-71-xs2 ~]# ssh -i .ssh/id_rsa.cloud -p 3922 169.254.214.153
Warning: Permanently added '[169.254.214.153]:3922' (ECDSA) to the list of known hosts.
Permission denied (publickey).
```
in the CPVM
Jan 22 19:31:09 v-1-VM sshd[2869]: userauth_pubkey: signature algorithm ssh-rsa not in PubkeyAcceptedAlgorithms [preauth]
Jan 22 19:31:09 v-1-VM sshd[2869]: Connection closed by authenticating user root 169.254.0.1 port 54704 [preauth]
```

ssh-dss (DSA) is not supported either

* debian12: add PubkeyAcceptedAlgorithms=+ssh-rsa to sshd_config

* VR: install python3 packages in case of Debian 11

* pom.xml: exclude systemvm/agent/packages/* in license check

* systemvm: do not patch router/systemvm during startup

this will cause 4.19 SYSTEM template not work, but may be expected
- python3 VS python2 (default)
- openSSL 3.0.1 VS 1.1.1w
- openssh-server 9.1 VS 8.4

* VR: patch router/systemvm if template is debian11

This supports debian 11 template by
- revert change in systemvm/debian/etc/ssh/sshd_config
- patch VR/systemvms during startup
- install packages during patching system vm/routers

* python3 flake: fix E502 the backslash is redundant between brackets

```
../debian/root/health_checks/router_version_check.py:55:70: E502 the backslash is redundant between brackets
../debian/root/health_checks/router_version_check.py:58:61: E502 the backslash is redundant between brackets
../debian/root/health_checks/router_version_check.py:67:71: E502 the backslash is redundant between brackets
../debian/root/health_checks/router_version_check.py:70:60: E502 the backslash is redundant between brackets
../debian/root/health_checks/haproxy_check.py:47:71: E502 the backslash is redundant between brackets
../debian/root/health_checks/haproxy_check.py:48:64: E502 the backslash is redundant between brackets
../debian/root/health_checks/cpu_usage_check.py:43:54: E502 the backslash is redundant between brackets
../debian/root/health_checks/cpu_usage_check.py:46:58: E502 the backslash is redundant between brackets
../debian/root/health_checks/memory_usage_check.py:31:65: E502 the backslash is redundant between brackets
../debian/root/health_checks/memory_usage_check.py:42:57: E502 the backslash is redundant between brackets
../debian/root/health_checks/memory_usage_check.py:45:63: E502 the backslash is redundant between brackets
```

* python3 flake: fix E275 missing whitespace after keyword

```
../debian/opt/cloud/bin/cs_firewallrules.py:29:20: E275 missing whitespace after keyword
../debian/opt/cloud/bin/cs_dhcp.py:27:16: E275 missing whitespace after keyword
../debian/opt/cloud/bin/cs_dhcp.py:36:16: E275 missing whitespace after keyword
../debian/opt/cloud/bin/cs_guestnetwork.py:33:20: E275 missing whitespace after keyword
../debian/opt/cloud/bin/cs_guestnetwork.py:35:16: E275 missing whitespace after keyword
../debian/opt/cloud/bin/cs_vpnusers.py:37:16: E275 missing whitespace after keyword
../debian/opt/cloud/bin/merge.py:230:11: E275 missing whitespace after keyword
../debian/opt/cloud/bin/merge.py:239:19: E275 missing whitespace after keyword
../debian/opt/cloud/bin/cs_remoteaccessvpn.py:24:12: E275 missing whitespace after keyword
../debian/opt/cloud/bin/cs_site2sitevpn.py:24:12: E275 missing whitespace after keyword
../debian/opt/cloud/bin/cs/CsHelper.py:90:15: E275 missing whitespace after keyword
../debian/opt/cloud/bin/cs/CsAddress.py:367:15: E275 missing whitespace after keyword
```

* python3 flake: fix configure.py

```
../debian/opt/cloud/bin/configure.py:24:22: E401 multiple imports on one line
../debian/opt/cloud/bin/configure.py:43:180: E501 line too long (294 > 179 characters)
../debian/opt/cloud/bin/configure.py:46:1: E302 expected 2 blank lines, found 1
../debian/opt/cloud/bin/configure.py:63:1: E302 expected 2 blank lines, found 1
../debian/opt/cloud/bin/configure.py:65:12: E721 do not compare types, for exact checks use `is` / `is not`, for instance checks use `isinstance()`
../debian/opt/cloud/bin/configure.py:72:1: E302 expected 2 blank lines, found 1
../debian/opt/cloud/bin/configure.py:310:25: E711 comparison to None should be 'if cond is not None:'
../debian/opt/cloud/bin/configure.py:312:29: E711 comparison to None should be 'if cond is None:'
../debian/opt/cloud/bin/configure.py:378:25: E711 comparison to None should be 'if cond is not None:'
../debian/opt/cloud/bin/configure.py:380:29: E711 comparison to None should be 'if cond is None:'
../debian/opt/cloud/bin/configure.py:490:29: E712 comparison to False should be 'if cond is False:' or 'if not cond:'
../debian/opt/cloud/bin/configure.py:642:16: E721 do not compare types, for exact checks use `is` / `is not`, for instance checks use `isinstance()`
../debian/opt/cloud/bin/configure.py:644:18: E721 do not compare types, for exact checks use `is` / `is not`, for instance checks use `isinstance()`
../debian/opt/cloud/bin/configure.py:1416:1: E305 expected 2 blank lines after class or function definition, found 1
```

* python3 flake: fix other python files

```
../debian/opt/cloud/bin/vmdata.py:97:12: E721 do not compare types, for exact checks use `is` / `is not`, for instance checks use `isinstance()`
../debian/opt/cloud/bin/vmdata.py:99:14: E721 do not compare types, for exact checks use `is` / `is not`, for instance checks use `isinstance()`

../debian/opt/cloud/bin/cs/CsRedundant.py:438:53: E203 whitespace before ':'
../debian/opt/cloud/bin/cs/CsRedundant.py:461:53: E203 whitespace before ':'
../debian/opt/cloud/bin/cs/CsRedundant.py:499:5: E303 too many blank lines (2)

../debian/opt/cloud/bin/cs/CsDatabag.py:189:1: E302 expected 2 blank lines, found 1
../debian/opt/cloud/bin/cs/CsDatabag.py:193:37: E721 do not compare types, for exact checks use `is` / `is not`, for instance checks use `isinstance()`

../debian/opt/cloud/bin/cs/CsHelper.py:118:30: E231 missing whitespace after ','
../debian/opt/cloud/bin/cs/CsHelper.py:119:15: E225 missing whitespace around operator
../debian/opt/cloud/bin/cs/CsHelper.py:127:19: E225 missing whitespace around operator

../debian/opt/cloud/bin/cs/CsAddress.py:324:43: E221 multiple spaces before operator

../debian/opt/cloud/bin/cs/CsVpcGuestNetwork.py:28:1: E302 expected 2 blank lines, found 1
```

* python3 flake: fix CsNetfilter.py

```
../debian/opt/cloud/bin/cs/CsNetfilter.py:226:13: E117 over-indented
../debian/opt/cloud/bin/cs/CsNetfilter.py:233:180: E501 line too long (197 > 179 characters)
../debian/opt/cloud/bin/cs/CsNetfilter.py:241:14: E201 whitespace after '{'
../debian/opt/cloud/bin/cs/CsNetfilter.py:242:14: E201 whitespace after '{'
../debian/opt/cloud/bin/cs/CsNetfilter.py:247:18: E201 whitespace after '{'
../debian/opt/cloud/bin/cs/CsNetfilter.py:247:74: E202 whitespace before '}'
../debian/opt/cloud/bin/cs/CsNetfilter.py:248:18: E201 whitespace after '{'
```

* systemvm/test: fix sys.path

```
$ bash runtests.sh
/usr/bin/python
Python 3.10.12
Running pycodestyle to check systemvm/python code for errors
Running pylint to check systemvm/python code for errors
Python 3.10.12
pylint 2.12.2
astroid 2.9.3
Python 3.10.12 (main, Nov 20 2023, 15:14:05) [GCC 11.4.0]

--------------------------------------------------------------------
Your code has been rated at 10.00/10 (previous run: 10.00/10, +0.00)

--------------------------------------------------------------------
Your code has been rated at 10.00/10 (previous run: 10.00/10, +0.00)

Running systemvm/python unit tests
....Device "eth0" does not exist.
.....................
----------------------------------------------------------------------
Ran 25 tests in 0.008s

OK
```

* Revert "systemvm template: remove hyperv packages and do not export"

This reverts commit 4383d59d031bde6eae7ebba261ff641ca0a66cd5.

* debian12: move SQL change to schema-41900to42000.sql

* debian12: update systemvm template version to 4.20 in pom.xml

* pom.xml: fix NPE if templates do not exist on download.cloudstack.org

* debian12: increase default system offering for routers to 384MiB RAM

* CKS: fix addkubernetessupportedversion failed with JRE17

```
marvin.cloudstackException.CloudstackAPIException: Execute cmd: addkubernetessupportedversion failed, due to: errorCode: 530, errorText:Cannot invoke "org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine$State.toString()" because the return value of "com.cloud.api.query.vo.TemplateJoinVO.getState()" is null
```

* python3: revert changes by 2to3 with systemvm/debian/root/health_checks/*.py

* debian12: use ISO/packages on download.cloudstack.org

* VR: Update default ram size to 384

* debian12: fix router_version_check.py after VR live-patch and add health check in test_routers.py

* debian12: fix build error after log4j 2.x merge

* VR: Update default ram size to 512MB (again)

This reverts commit 578dd2b73f380e8231ae1eb59827230757cac5e8 and efafa8c4d63775653a2cd406fca10784fbcec3e3.

* systemvmtemplate: Upgrade to Debian 12.5.0

* systemvm template: increase swap to 512MB

* VR: fix health check error due to deprecated SafeConfigParser

warning below
```
root@r-20-VM:~# /opt/cloud/bin/getRouterMonitorResults.sh true
/root/monitorServices.py:59: DeprecationWarning: The SafeConfigParser class has been renamed to ConfigParser in Python 3.2. This alias will be removed in Python 3.12. Use ConfigParser directly instead.
  parser = SafeConfigParser()
```

* test: fix wget does not work in macchinina vms on vmware80u1

fixes error below
```
{Cmd: wget -t 1 -T 1 www.google.com via Host: 10.0.55.186} {returns: ["wget: '/usr/lib/libpcre.so.1' is not an ELF file", "wget: can't load library 'libpcre.so.1'"]}
```

* packaging: add message for VR memory upgrade after packages installation

---------

Signed-off-by: Rohit Yadav <rohit.yadav@shapeblue.com>
Co-authored-by: Rohit Yadav <rohit.yadav@shapeblue.com>
Co-authored-by: Vishesh <vishesh92@gmail.com>
2024-02-26 18:07:50 +05:30

1430 lines
56 KiB
Python

# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
""" Tests for VPN in VPC
"""
# Import Local Modules
from marvin.codes import PASS, FAILED
from marvin.cloudstackTestCase import cloudstackTestCase
from marvin.lib.utils import (validateList,
wait_until)
from marvin.lib.base import (Account,
VPC,
VpcOffering,
ServiceOffering,
NetworkOffering,
Network,
PublicIPAddress,
NATRule,
NetworkACLList,
VirtualMachine,
Vpn,
VpnCustomerGateway,
VpnUser
)
from marvin.sshClient import SshClient
from marvin.lib.common import (get_zone,
get_domain,
get_test_template)
from nose.plugins.attrib import attr
import logging
import time
class TestVpcRemoteAccessVpn(cloudstackTestCase):
@classmethod
def setUpClass(cls):
cls.logger = logging.getLogger('TestVPCRemoteAccessVPN')
cls.stream_handler = logging.StreamHandler()
cls.logger.setLevel(logging.DEBUG)
cls.logger.addHandler(cls.stream_handler)
testClient = super(TestVpcRemoteAccessVpn, cls).getClsTestClient()
cls.apiclient = testClient.getApiClient()
cls.services = testClient.getParsedTestDataConfig()
cls.zone = get_zone(cls.apiclient, testClient.getZoneForTests())
cls.domain = get_domain(cls.apiclient)
cls._cleanup = []
cls.compute_offering = ServiceOffering.create(
cls.apiclient,
cls.services["vpc_vpn"]["compute_offering"]
)
cls._cleanup.append(cls.compute_offering)
cls.account = Account.create(
cls.apiclient, services=cls.services["vpc_vpn"]["account"])
cls._cleanup.append(cls.account)
cls.hypervisor = testClient.getHypervisorInfo()
cls.template = get_test_template(cls.apiclient, cls.zone.id, cls.hypervisor)
if cls.template == FAILED:
assert False, "get_test_template() failed to return template"
cls.logger.debug("Successfully created account: %s, id: \
%s" % (cls.account.name,
cls.account.id))
return
@attr(tags=["advanced"], required_hardware="true")
def test_01_vpc_remote_access_vpn(self):
"""Test Remote Access VPN in VPC"""
self.logger.debug("Starting test: test_01_vpc_remote_access_vpn")
# 0) Get the default network offering for VPC
self.logger.debug("Retrieving default VPC offering")
networkOffering = NetworkOffering.list(
self.apiclient, name="DefaultIsolatedNetworkOfferingForVpcNetworks")
self.assertTrue(networkOffering is not None and len(
networkOffering) > 0, "No VPC based network offering")
# 1) Create VPC
vpcOffering = VpcOffering.list(self.apiclient, name="Default VPC offering")
self.assertTrue(vpcOffering is not None and len(
vpcOffering) > 0, "No VPC offerings found")
vpc = None
try:
vpc = VPC.create(
apiclient=self.apiclient,
services=self.services["vpc_vpn"]["vpc"],
networkDomain="vpc.vpn",
vpcofferingid=vpcOffering[0].id,
zoneid=self.zone.id,
account=self.account.name,
domainid=self.domain.id
)
self.cleanup.append(vpc)
except Exception as e:
self.fail(e)
finally:
self.assertTrue(vpc is not None, "VPC creation failed")
self.logger.debug("VPC %s created" % (vpc.id))
try:
# 2) Create network in VPC
ntwk = Network.create(
apiclient=self.apiclient,
services=self.services["vpc_vpn"]["network_1"],
accountid=self.account.name,
domainid=self.domain.id,
networkofferingid=networkOffering[0].id,
zoneid=self.zone.id,
vpcid=vpc.id
)
self.cleanup.append(ntwk)
except Exception as e:
self.fail(e)
finally:
self.assertIsNotNone(ntwk, "Network failed to create")
self.logger.debug(
"Network %s created in VPC %s" % (ntwk.id, vpc.id))
try:
# 3) Deploy a vm
vm = VirtualMachine.create(self.apiclient, services=self.services["vpc_vpn"]["virtual_machine"],
templateid=self.template.id,
zoneid=self.zone.id,
accountid=self.account.name,
domainid=self.domain.id,
serviceofferingid=self.compute_offering.id,
networkids=ntwk.id,
hypervisor=self.hypervisor
)
self.cleanup.append(vm)
self.debug("VM %s deployed in VPC %s" % (vm.id, vpc.id))
except Exception as e:
self.fail(e)
finally:
self.assertTrue(vm is not None, "VM failed to deploy")
self.assertTrue(vm.state == 'Running', "VM is not running")
self.logger.debug("Deployed virtual machine: OK")
try:
# 4) Enable VPN for VPC
src_nat_list = PublicIPAddress.list(
self.apiclient,
account=self.account.name,
domainid=self.account.domainid,
listall=True,
issourcenat=True,
vpcid=vpc.id
)
ip = src_nat_list[0]
except Exception as e:
self.fail(e)
finally:
self.logger.debug("Acquired public ip address: OK")
vpn = None
try:
vpn = Vpn.create(self.apiclient,
publicipid=ip.id,
account=self.account.name,
domainid=self.account.domainid,
iprange=self.services["vpc_vpn"]["vpn"]["iprange"],
fordisplay=self.services["vpc_vpn"]["vpn"]["fordisplay"]
)
except Exception as e:
self.fail(e)
finally:
self.assertIsNotNone(vpn, "Failed to create Remote Access VPN")
self.logger.debug("Created Remote Access VPN: OK")
vpnUser = None
# 5) Add VPN user for VPC
try:
vpnUser = VpnUser.create(self.apiclient,
account=self.account.name,
domainid=self.account.domainid,
username=self.services["vpc_vpn"]["vpn"]["vpn_user"],
password=self.services["vpc_vpn"]["vpn"]["vpn_pass"]
)
except Exception as e:
self.fail(e)
finally:
self.assertIsNotNone(
vpnUser, "Failed to create Remote Access VPN User")
self.logger.debug("Created VPN User: OK")
# TODO: Add an actual remote vpn connection test from a remote vpc
try:
# 9) Disable VPN for VPC
vpn.delete(self.apiclient)
except Exception as e:
self.fail(e)
finally:
self.logger.debug("Deleted the Remote Access VPN: OK")
@classmethod
def tearDownClass(cls):
super(TestVpcRemoteAccessVpn, cls).tearDownClass()
def setUp(self):
self.apiclient = self.testClient.getApiClient()
self.hypervisor = self.testClient.getHypervisorInfo()
self.cleanup = []
def tearDown(self):
super(TestVpcRemoteAccessVpn, self).tearDown()
class TestVpcSite2SiteVpn(cloudstackTestCase):
@classmethod
def setUpClass(cls):
cls.logger = logging.getLogger('TestVPCSite2SiteVPN')
cls.stream_handler = logging.StreamHandler()
cls.logger.setLevel(logging.DEBUG)
cls.logger.addHandler(cls.stream_handler)
testClient = super(TestVpcSite2SiteVpn, cls).getClsTestClient()
cls.apiclient = testClient.getApiClient()
cls.services = testClient.getParsedTestDataConfig()
cls.zone = get_zone(cls.apiclient, testClient.getZoneForTests())
cls.domain = get_domain(cls.apiclient)
cls._cleanup = []
cls.compute_offering = ServiceOffering.create(
cls.apiclient,
cls.services["vpc_vpn"]["compute_offering"]
)
cls._cleanup.append(cls.compute_offering)
cls.account = Account.create(
cls.apiclient, services=cls.services["vpc_vpn"]["account"])
cls._cleanup.append(cls.account)
cls.hypervisor = testClient.getHypervisorInfo()
cls.template = get_test_template(cls.apiclient, cls.zone.id, cls.hypervisor)
if cls.template == FAILED:
assert False, "get_test_template() failed to return template"
cls.logger.debug("Successfully created account: %s, id: \
%s" % (cls.account.name,
cls.account.id))
return
def setUp(self):
self.apiclient = self.testClient.getApiClient()
self.hypervisor = self.testClient.getHypervisorInfo()
self.cleanup = []
def _get_ssh_client(self, virtual_machine, services, retries):
""" Setup ssh client connection and return connection
vm requires attributes public_ip, public_port, username, password """
try:
ssh_client = SshClient(
virtual_machine.public_ip,
services["vpc_vpn"]["virtual_machine"]["ssh_port"],
services["vpc_vpn"]["virtual_machine"]["username"],
services["vpc_vpn"]["virtual_machine"]["password"],
retries)
except Exception as e:
self.fail("Unable to create ssh connection: " % e)
self.assertIsNotNone(
ssh_client, "Failed to setup ssh connection to vm=%s on public_ip=%s" % (virtual_machine.name, virtual_machine.public_ip))
return ssh_client
def _create_natrule(self, vpc, vm, public_port, private_port, public_ip, network, services=None):
self.logger.debug("Creating NAT rule in network for vm with public IP")
if not services:
self.services["vpc_vpn"]["natrule"]["privateport"] = private_port
self.services["vpc_vpn"]["natrule"]["publicport"] = public_port
self.services["vpc_vpn"]["natrule"]["startport"] = public_port
self.services["vpc_vpn"]["natrule"]["endport"] = public_port
services = self.services["vpc_vpn"]["natrule"]
nat_rule = NATRule.create(
apiclient=self.apiclient,
services=services,
ipaddressid=public_ip.ipaddress.id,
virtual_machine=vm,
networkid=network.id
)
self.assertIsNotNone(
nat_rule, "Failed to create NAT Rule for %s" % public_ip.ipaddress.ipaddress)
self.logger.debug(
"Adding NetworkACL rules to make NAT rule accessible")
vm.ssh_ip = nat_rule.ipaddress
vm.public_ip = nat_rule.ipaddress
vm.public_port = int(public_port)
return nat_rule
def _validate_vpc_offering(self, vpc_offering):
self.logger.debug("Check if the VPC offering is created successfully?")
vpc_offs = VpcOffering.list(
self.apiclient,
id=vpc_offering.id
)
offering_list = validateList(vpc_offs)
self.assertEqual(offering_list[0],
PASS,
"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.logger.debug(
"VPC offering is created successfully - %s" %
vpc_offering.name)
return
def _create_vpc_offering(self, offering_name):
vpc_off = None
if offering_name is not None:
self.logger.debug("Creating VPC offering: %s", offering_name)
vpc_off = VpcOffering.create(
self.apiclient,
self.services["vpc_vpn"][offering_name]
)
self._validate_vpc_offering(vpc_off)
self.cleanup.append(vpc_off)
return vpc_off
@attr(tags=["advanced"], required_hardware="true")
def test_01_vpc_site2site_vpn(self):
"""Test Site 2 Site VPN Across VPCs"""
self.logger.debug("Starting test: test_01_vpc_site2site_vpn")
# 0) Get the default network offering for VPC
networkOffering = NetworkOffering.list(
self.apiclient, name="DefaultIsolatedNetworkOfferingForVpcNetworks")
self.assertTrue(networkOffering is not None and len(
networkOffering) > 0, "No VPC based network offering")
# Create and Enable VPC offering
vpc_offering = self._create_vpc_offering('vpc_offering')
self.assertTrue(vpc_offering is not None, "Failed to create VPC Offering")
vpc_offering.update(self.apiclient, state='Enabled')
vpc1 = None
# Create VPC 1
try:
vpc1 = VPC.create(
apiclient=self.apiclient,
services=self.services["vpc_vpn"]["vpc"],
networkDomain="vpc1.vpn",
vpcofferingid=vpc_offering.id,
zoneid=self.zone.id,
account=self.account.name,
domainid=self.domain.id
)
except Exception as e:
self.fail(e)
finally:
self.assertTrue(vpc1 is not None, "VPC1 creation failed")
self.cleanup.append(vpc1)
self.logger.debug("VPC1 %s created" % vpc1.id)
vpc2 = None
# Create VPC 2
try:
vpc2 = VPC.create(
apiclient=self.apiclient,
services=self.services["vpc_vpn"]["vpc2"],
networkDomain="vpc2.vpn",
vpcofferingid=vpc_offering.id,
zoneid=self.zone.id,
account=self.account.name,
domainid=self.account.domainid
)
except Exception as e:
self.fail(e)
finally:
self.assertTrue(vpc2 is not None, "VPC2 creation failed")
self.cleanup.append(vpc2)
self.logger.debug("VPC2 %s created" % vpc2.id)
default_acl = NetworkACLList.list(
self.apiclient, name="default_allow")[0]
ntwk1 = None
# Create network in VPC 1
try:
ntwk1 = Network.create(
apiclient=self.apiclient,
services=self.services["vpc_vpn"]["network_1"],
accountid=self.account.name,
domainid=self.account.domainid,
networkofferingid=networkOffering[0].id,
zoneid=self.zone.id,
vpcid=vpc1.id,
aclid=default_acl.id
)
except Exception as e:
self.fail(e)
finally:
self.assertIsNotNone(ntwk1, "Network failed to create")
self.cleanup.append(ntwk1)
self.logger.debug("Network %s created in VPC %s" % (ntwk1.id, vpc1.id))
ntwk2 = None
# Create network in VPC 2
try:
ntwk2 = Network.create(
apiclient=self.apiclient,
services=self.services["vpc_vpn"]["network_2"],
accountid=self.account.name,
domainid=self.account.domainid,
networkofferingid=networkOffering[0].id,
zoneid=self.zone.id,
vpcid=vpc2.id,
aclid=default_acl.id
)
except Exception as e:
self.fail(e)
finally:
self.assertIsNotNone(ntwk2, "Network failed to create")
self.cleanup.append(ntwk2)
self.logger.debug("Network %s created in VPC %s" % (ntwk2.id, vpc2.id))
vm1 = None
# Deploy a vm in network 1
try:
vm1 = VirtualMachine.create(self.apiclient, services=self.services["vpc_vpn"]["virtual_machine"],
templateid=self.template.id,
zoneid=self.zone.id,
accountid=self.account.name,
domainid=self.account.domainid,
serviceofferingid=self.compute_offering.id,
networkids=ntwk1.id,
hypervisor=self.hypervisor
)
except Exception as e:
self.fail(e)
finally:
self.assertTrue(vm1 is not None, "VM failed to deploy")
self.assertTrue(vm1.state == 'Running', "VM is not running")
self.cleanup.append(vm1)
self.logger.debug("VM %s deployed in VPC %s" % (vm1.id, vpc1.id))
vm2 = None
# Deploy a vm in network 2
try:
vm2 = VirtualMachine.create(self.apiclient, services=self.services["vpc_vpn"]["virtual_machine"],
templateid=self.template.id,
zoneid=self.zone.id,
accountid=self.account.name,
domainid=self.account.domainid,
serviceofferingid=self.compute_offering.id,
networkids=ntwk2.id,
hypervisor=self.hypervisor
)
except Exception as e:
self.fail(e)
finally:
self.assertTrue(vm2 is not None, "VM failed to deploy")
self.assertTrue(vm2.state == 'Running', "VM is not running")
self.cleanup.append(vm2)
self.debug("VM %s deployed in VPC %s" % (vm2.id, vpc2.id))
# 4) Enable Site-to-Site VPN for VPC
vpn1_response = Vpn.createVpnGateway(self.apiclient, vpc1.id)
self.assertTrue(
vpn1_response is not None, "Failed to enable VPN Gateway 1")
self.logger.debug("VPN gateway for VPC %s enabled" % vpc1.id)
vpn2_response = Vpn.createVpnGateway(self.apiclient, vpc2.id)
self.assertTrue(
vpn2_response is not None, "Failed to enable VPN Gateway 2")
self.logger.debug("VPN gateway for VPC %s enabled" % vpc2.id)
# 5) Add VPN Customer gateway info
src_nat_list = PublicIPAddress.list(
self.apiclient,
account=self.account.name,
domainid=self.account.domainid,
listall=True,
issourcenat=True,
vpcid=vpc1.id
)
ip1 = src_nat_list[0]
src_nat_list = PublicIPAddress.list(
self.apiclient,
account=self.account.name,
domainid=self.account.domainid,
listall=True,
issourcenat=True,
vpcid=vpc2.id
)
ip2 = src_nat_list[0]
services = self.services["vpc_vpn"]["vpncustomergateway"]
customer1_response = VpnCustomerGateway.create(
self.apiclient, services, "Peer VPC1", ip1.ipaddress, vpc1.cidr, self.account.name, self.domain.id)
self.debug("VPN customer gateway added for VPC %s enabled" % vpc1.id)
self.logger.debug(vars(customer1_response))
customer2_response = VpnCustomerGateway.create(
self.apiclient, services, "Peer VPC2", ip2.ipaddress, vpc2.cidr, self.account.name, self.domain.id)
self.debug("VPN customer gateway added for VPC %s enabled" % vpc2.id)
self.logger.debug(vars(customer2_response))
# 6) Connect two VPCs
vpnconn1_response = Vpn.createVpnConnection(
self.apiclient, customer1_response.id, vpn2_response['id'], True)
self.debug("VPN passive connection created for VPC %s" % vpc2.id)
vpnconn2_response = Vpn.createVpnConnection(
self.apiclient, customer2_response.id, vpn1_response['id'])
self.debug("VPN connection created for VPC %s" % vpc1.id)
def checkVpnConnected():
connections = Vpn.listVpnConnection(
self.apiclient,
listall='true',
vpcid=vpc2.id)
if isinstance(connections, list):
return connections[0].state == 'Connected', None
return False, None
# Wait up to 60 seconds for passive connection to show up as Connected
res, _ = wait_until(2, 30, checkVpnConnected)
if not res:
self.fail("Failed to connect between VPCs, see VPN state as Connected")
# acquire an extra ip address to use to ssh into vm2
try:
vm2.public_ip = PublicIPAddress.create(
apiclient=self.apiclient,
accountid=self.account.name,
zoneid=self.zone.id,
domainid=self.account.domainid,
services=self.services,
networkid=ntwk2.id,
vpcid=vpc2.id)
except Exception as e:
self.fail(e)
finally:
self.assertTrue(
vm2.public_ip is not None, "Failed to aqcuire public ip for vm2")
natrule = None
# Create port forward to be able to ssh into vm2
try:
natrule = self._create_natrule(
vpc2, vm2, 22, 22, vm2.public_ip, ntwk2)
except Exception as e:
self.fail(e)
finally:
self.assertTrue(
natrule is not None, "Failed to create portforward for vm2")
time.sleep(20)
# setup ssh connection to vm2
ssh_client = self._get_ssh_client(vm2, self.services, 30)
if ssh_client:
# run ping test
packet_loss = ssh_client.execute("/bin/ping -c 3 -t 10 " + vm1.nic[0].ipaddress + " | grep packet | sed 's/.*received, //g' | sed 's/[% ]*packet.*//g'")[0]
# during startup, some packets may not reply due to link/ipsec-route setup
self.assertTrue(int(packet_loss) < 50, "Ping did not succeed")
else:
self.fail("Failed to setup ssh connection to %s" % vm2.public_ip)
@classmethod
def tearDownClass(cls):
super(TestVpcSite2SiteVpn, cls).tearDownClass()
def tearDown(self):
super(TestVpcSite2SiteVpn, self).tearDown()
class TestRVPCSite2SiteVpn(cloudstackTestCase):
@classmethod
def setUpClass(cls):
cls.logger = logging.getLogger('TestRVPCSite2SiteVPN')
cls.stream_handler = logging.StreamHandler()
cls.logger.setLevel(logging.DEBUG)
cls.logger.addHandler(cls.stream_handler)
testClient = super(TestRVPCSite2SiteVpn, cls).getClsTestClient()
cls.apiclient = testClient.getApiClient()
cls.services = testClient.getParsedTestDataConfig()
cls.zone = get_zone(cls.apiclient, testClient.getZoneForTests())
cls.domain = get_domain(cls.apiclient)
cls._cleanup = []
cls.compute_offering = ServiceOffering.create(
cls.apiclient,
cls.services["vpc_vpn"]["compute_offering"]
)
cls._cleanup.append(cls.compute_offering)
cls.account = Account.create(
cls.apiclient, services=cls.services["vpc_vpn"]["account"])
cls._cleanup.append(cls.account)
cls.hypervisor = testClient.getHypervisorInfo()
cls.template = get_test_template(cls.apiclient, cls.zone.id, cls.hypervisor)
if cls.template == FAILED:
assert False, "get_test_template() failed to return template"
cls.logger.debug("Successfully created account: %s, id: \
%s" % (cls.account.name,
cls.account.id))
return
def _validate_vpc_offering(self, vpc_offering):
self.logger.debug("Check if the VPC offering is created successfully?")
vpc_offs = VpcOffering.list(
self.apiclient,
id=vpc_offering.id
)
offering_list = validateList(vpc_offs)
self.assertEqual(offering_list[0],
PASS,
"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.logger.debug(
"VPC offering is created successfully - %s" %
vpc_offering.name)
return
def _create_vpc_offering(self, offering_name):
vpc_off = None
if offering_name is not None:
self.logger.debug("Creating VPC offering: %s", offering_name)
vpc_off = VpcOffering.create(
self.apiclient,
self.services["vpc_vpn"][offering_name]
)
self._validate_vpc_offering(vpc_off)
self.cleanup.append(vpc_off)
return vpc_off
def _get_ssh_client(self, virtual_machine, services, retries):
""" Setup ssh client connection and return connection
vm requires attributes public_ip, public_port, username, password """
try:
ssh_client = SshClient(
virtual_machine.public_ip,
services["vpc_vpn"]["virtual_machine"]["ssh_port"],
services["vpc_vpn"]["virtual_machine"]["username"],
services["vpc_vpn"]["virtual_machine"]["password"],
retries)
except Exception as e:
self.fail("Unable to create ssh connection: %s" % e)
self.assertIsNotNone(
ssh_client, "Failed to setup ssh connection to vm=%s on public_ip=%s" % (virtual_machine.name, virtual_machine.public_ip))
return ssh_client
def _create_natrule(self, vpc, vm, public_port, private_port, public_ip, network, services=None):
self.logger.debug("Creating NAT rule in network for vm with public IP")
if not services:
self.services["vpc_vpn"]["natrule"]["privateport"] = private_port
self.services["vpc_vpn"]["natrule"]["publicport"] = public_port
self.services["vpc_vpn"]["natrule"]["startport"] = public_port
self.services["vpc_vpn"]["natrule"]["endport"] = public_port
services = self.services["vpc_vpn"]["natrule"]
nat_rule = NATRule.create(
apiclient=self.apiclient,
services=services,
ipaddressid=public_ip.ipaddress.id,
virtual_machine=vm,
networkid=network.id
)
self.assertIsNotNone(
nat_rule, "Failed to create NAT Rule for %s" % public_ip.ipaddress.ipaddress)
self.logger.debug(
"Adding NetworkACL rules to make NAT rule accessible")
vm.ssh_ip = nat_rule.ipaddress
vm.public_ip = nat_rule.ipaddress
vm.public_port = int(public_port)
return nat_rule
@attr(tags=["advanced"], required_hardware="true")
def test_01_redundant_vpc_site2site_vpn(self):
"""Test Site 2 Site VPN Across redundant VPCs"""
self.logger.debug("Starting test: test_02_redundant_vpc_site2site_vpn")
# 0) Get the default network offering for VPC
networkOffering = NetworkOffering.list(
self.apiclient, name="DefaultIsolatedNetworkOfferingForVpcNetworks")
self.assertTrue(networkOffering is not None and len(
networkOffering) > 0, "No VPC based network offering")
# Create and enable redundant VPC offering
redundant_vpc_offering = self._create_vpc_offering(
'redundant_vpc_offering')
self.assertTrue(redundant_vpc_offering is not None,
"Failed to create redundant VPC Offering")
redundant_vpc_offering.update(self.apiclient, state='Enabled')
# Create VPC 1
vpc1 = None
try:
vpc1 = VPC.create(
apiclient=self.apiclient,
services=self.services["vpc_vpn"]["vpc"],
networkDomain="vpc1.vpn",
vpcofferingid=redundant_vpc_offering.id,
zoneid=self.zone.id,
account=self.account.name,
domainid=self.domain.id
)
except Exception as e:
self.fail(e)
finally:
self.assertTrue(vpc1 is not None, "VPC1 creation failed")
self.cleanup.append(vpc1)
self.logger.debug("VPC1 %s created" % vpc1.id)
# Create VPC 2
vpc2 = None
try:
vpc2 = VPC.create(
apiclient=self.apiclient,
services=self.services["vpc_vpn"]["vpc2"],
networkDomain="vpc2.vpn",
vpcofferingid=redundant_vpc_offering.id,
zoneid=self.zone.id,
account=self.account.name,
domainid=self.account.domainid
)
except Exception as e:
self.fail(e)
finally:
self.assertTrue(vpc2 is not None, "VPC2 creation failed")
self.cleanup.append(vpc2)
self.logger.debug("VPC2 %s created" % vpc2.id)
default_acl = NetworkACLList.list(
self.apiclient, name="default_allow")[0]
# Create network in VPC 1
ntwk1 = None
try:
ntwk1 = Network.create(
apiclient=self.apiclient,
services=self.services["vpc_vpn"]["network_1"],
accountid=self.account.name,
domainid=self.account.domainid,
networkofferingid=networkOffering[0].id,
zoneid=self.zone.id,
vpcid=vpc1.id,
aclid=default_acl.id
)
except Exception as e:
self.fail(e)
finally:
self.assertIsNotNone(ntwk1, "Network failed to create")
self.cleanup.append(ntwk1)
self.logger.debug("Network %s created in VPC %s" % (ntwk1.id, vpc1.id))
# Create network in VPC 2
ntwk2 = None
try:
ntwk2 = Network.create(
apiclient=self.apiclient,
services=self.services["vpc_vpn"]["network_2"],
accountid=self.account.name,
domainid=self.account.domainid,
networkofferingid=networkOffering[0].id,
zoneid=self.zone.id,
vpcid=vpc2.id,
aclid=default_acl.id
)
except Exception as e:
self.fail(e)
finally:
self.assertIsNotNone(ntwk2, "Network failed to create")
self.cleanup.append(ntwk2)
self.logger.debug("Network %s created in VPC %s" % (ntwk2.id, vpc2.id))
# Deploy a vm in network 1
vm1 = None
try:
vm1 = VirtualMachine.create(self.apiclient, services=self.services["vpc_vpn"]["virtual_machine"],
templateid=self.template.id,
zoneid=self.zone.id,
accountid=self.account.name,
domainid=self.account.domainid,
serviceofferingid=self.compute_offering.id,
networkids=ntwk1.id,
hypervisor=self.hypervisor
)
except Exception as e:
self.fail(e)
finally:
self.assertTrue(vm1 is not None, "VM failed to deploy")
self.assertTrue(vm1.state == 'Running', "VM is not running")
self.cleanup.append(vm1)
self.logger.debug("VM %s deployed in VPC %s" % (vm1.id, vpc1.id))
# Deploy a vm in network 2
vm2 = None
try:
vm2 = VirtualMachine.create(self.apiclient, services=self.services["vpc_vpn"]["virtual_machine"],
templateid=self.template.id,
zoneid=self.zone.id,
accountid=self.account.name,
domainid=self.account.domainid,
serviceofferingid=self.compute_offering.id,
networkids=ntwk2.id,
hypervisor=self.hypervisor
)
except Exception as e:
self.fail(e)
finally:
self.assertTrue(vm2 is not None, "VM failed to deploy")
self.assertTrue(vm2.state == 'Running', "VM is not running")
self.cleanup.append(vm2)
self.debug("VM %s deployed in VPC %s" % (vm2.id, vpc2.id))
# 4) Enable Site-to-Site VPN for VPC
vpn1_response = Vpn.createVpnGateway(self.apiclient, vpc1.id)
self.assertTrue(
vpn1_response is not None, "Failed to enable VPN Gateway 1")
self.logger.debug("VPN gateway for VPC %s enabled" % vpc1.id)
vpn2_response = Vpn.createVpnGateway(self.apiclient, vpc2.id)
self.assertTrue(
vpn2_response is not None, "Failed to enable VPN Gateway 2")
self.logger.debug("VPN gateway for VPC %s enabled" % vpc2.id)
# 5) Add VPN Customer gateway info
src_nat_list = PublicIPAddress.list(
self.apiclient,
account=self.account.name,
domainid=self.account.domainid,
listall=True,
issourcenat=True,
vpcid=vpc1.id
)
ip1 = src_nat_list[0]
src_nat_list = PublicIPAddress.list(
self.apiclient,
account=self.account.name,
domainid=self.account.domainid,
listall=True,
issourcenat=True,
vpcid=vpc2.id
)
ip2 = src_nat_list[0]
services = self.services["vpc_vpn"]["vpncustomergateway"]
customer1_response = VpnCustomerGateway.create(
self.apiclient, services, "Peer VPC1", ip1.ipaddress, vpc1.cidr, self.account.name, self.domain.id)
self.debug("VPN customer gateway added for VPC %s enabled" % vpc1.id)
self.logger.debug(vars(customer1_response))
customer2_response = VpnCustomerGateway.create(
self.apiclient, services, "Peer VPC2", ip2.ipaddress, vpc2.cidr, self.account.name, self.domain.id)
self.debug("VPN customer gateway added for VPC %s enabled" % vpc2.id)
self.logger.debug(vars(customer2_response))
# 6) Connect two VPCs
vpnconn1_response = Vpn.createVpnConnection(
self.apiclient, customer1_response.id, vpn2_response['id'], True)
self.debug("VPN passive connection created for VPC %s" % vpc2.id)
vpnconn2_response = Vpn.createVpnConnection(
self.apiclient, customer2_response.id, vpn1_response['id'])
self.debug("VPN connection created for VPC %s" % vpc1.id)
def checkVpnConnected():
connections = Vpn.listVpnConnection(
self.apiclient,
listall='true',
vpcid=vpc2.id)
if isinstance(connections, list):
return connections[0].state == 'Connected', None
return False, None
# Wait up to 60 seconds for passive connection to show up as Connected
res, _ = wait_until(2, 30, checkVpnConnected)
if not res:
self.fail("Failed to connect between VPCs, see VPN state as Connected")
# acquire an extra ip address to use to ssh into vm2
try:
vm2.public_ip = PublicIPAddress.create(
apiclient=self.apiclient,
accountid=self.account.name,
zoneid=self.zone.id,
domainid=self.account.domainid,
services=self.services,
networkid=ntwk2.id,
vpcid=vpc2.id)
except Exception as e:
self.fail(e)
finally:
self.assertTrue(
vm2.public_ip is not None, "Failed to aqcuire public ip for vm2")
# Create port forward to be able to ssh into vm2
natrule = None
try:
natrule = self._create_natrule(
vpc2, vm2, 22, 22, vm2.public_ip, ntwk2)
except Exception as e:
self.fail(e)
finally:
self.assertTrue(
natrule is not None, "Failed to create portforward for vm2")
time.sleep(20)
# setup ssh connection to vm2
ssh_client = self._get_ssh_client(vm2, self.services, 10)
if ssh_client:
# run ping test
packet_loss = ssh_client.execute("/bin/ping -c 3 -t 10 " + vm1.nic[0].ipaddress + " | grep packet | sed 's/.*received, //g' | sed 's/[% ]*packet.*//g'")[0]
self.assertTrue(int(packet_loss) < 50, "Ping did not succeed")
else:
self.fail("Failed to setup ssh connection to %s" % vm2.public_ip)
@classmethod
def tearDownClass(cls):
super(TestRVPCSite2SiteVpn, cls).tearDownClass()
def setUp(self):
self.apiclient = self.testClient.getApiClient()
self.hypervisor = self.testClient.getHypervisorInfo()
self.cleanup = []
def tearDown(self):
super(TestRVPCSite2SiteVpn, self).tearDown()
class TestVPCSite2SiteVPNMultipleOptions(cloudstackTestCase):
@classmethod
def setUpClass(cls):
cls.logger = logging.getLogger('TestVPCSite2SiteVPNMultipleOptions')
cls.stream_handler = logging.StreamHandler()
cls.logger.setLevel(logging.DEBUG)
cls.logger.addHandler(cls.stream_handler)
testClient = super(TestVPCSite2SiteVPNMultipleOptions, cls).getClsTestClient()
cls.apiclient = testClient.getApiClient()
cls.services = testClient.getParsedTestDataConfig()
cls.zone = get_zone(cls.apiclient, testClient.getZoneForTests())
cls.domain = get_domain(cls.apiclient)
cls._cleanup = []
cls.compute_offering = ServiceOffering.create(
cls.apiclient,
cls.services["vpc_vpn"]["compute_offering"]
)
cls._cleanup.append(cls.compute_offering)
cls.account = Account.create(
cls.apiclient, services=cls.services["vpc_vpn"]["account"])
cls._cleanup.append(cls.account)
cls.hypervisor = testClient.getHypervisorInfo()
cls.template = get_test_template(cls.apiclient, cls.zone.id, cls.hypervisor)
if cls.template == FAILED:
assert False, "get_test_template() failed to return template"
cls.logger.debug("Successfully created account: %s, id: \
%s" % (cls.account.name,
cls.account.id))
return
def setUp(self):
self.apiclient = self.testClient.getApiClient()
self.hypervisor = self.testClient.getHypervisorInfo()
self.cleanup = []
def _get_ssh_client(self, virtual_machine, services, retries):
""" Setup ssh client connection and return connection
vm requires attributes public_ip, public_port, username, password """
try:
ssh_client = SshClient(
virtual_machine.public_ip,
services["vpc_vpn"]["virtual_machine"]["ssh_port"],
services["vpc_vpn"]["virtual_machine"]["username"],
services["vpc_vpn"]["virtual_machine"]["password"],
retries)
except Exception as e:
self.fail("Unable to create ssh connection: " % e)
self.assertIsNotNone(
ssh_client, "Failed to setup ssh connection to vm=%s on public_ip=%s" % (virtual_machine.name, virtual_machine.public_ip))
return ssh_client
def _create_natrule(self, vpc, vm, public_port, private_port, public_ip, network, services=None):
self.logger.debug("Creating NAT rule in network for vm with public IP")
if not services:
self.services["vpc_vpn"]["natrule"]["privateport"] = private_port
self.services["vpc_vpn"]["natrule"]["publicport"] = public_port
self.services["vpc_vpn"]["natrule"]["startport"] = public_port
self.services["vpc_vpn"]["natrule"]["endport"] = public_port
services = self.services["vpc_vpn"]["natrule"]
nat_rule = NATRule.create(
apiclient=self.apiclient,
services=services,
ipaddressid=public_ip.ipaddress.id,
virtual_machine=vm,
networkid=network.id
)
self.assertIsNotNone(
nat_rule, "Failed to create NAT Rule for %s" % public_ip.ipaddress.ipaddress)
self.logger.debug(
"Adding NetworkACL rules to make NAT rule accessible")
vm.ssh_ip = nat_rule.ipaddress
vm.public_ip = nat_rule.ipaddress
vm.public_port = int(public_port)
return nat_rule
def _validate_vpc_offering(self, vpc_offering):
self.logger.debug("Check if the VPC offering is created successfully?")
vpc_offs = VpcOffering.list(
self.apiclient,
id=vpc_offering.id
)
offering_list = validateList(vpc_offs)
self.assertEqual(offering_list[0],
PASS,
"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.logger.debug(
"VPC offering is created successfully - %s" %
vpc_offering.name)
return
def _create_vpc_offering(self, offering_name):
vpc_off = None
if offering_name is not None:
self.logger.debug("Creating VPC offering: %s", offering_name)
vpc_off = VpcOffering.create(
self.apiclient,
self.services["vpc_vpn"][offering_name]
)
self._validate_vpc_offering(vpc_off)
self.cleanup.append(vpc_off)
return vpc_off
@attr(tags=["advanced"], required_hardware="true")
def test_01_vpc_site2site_vpn_multiple_options(self):
"""Test Site 2 Site VPN Across VPCs"""
self.logger.debug("Starting test: test_01_vpc_site2site_vpn_multiple_options")
# 0) Get the default network offering for VPC
networkOffering = NetworkOffering.list(
self.apiclient, name="DefaultIsolatedNetworkOfferingForVpcNetworks")
self.assertTrue(networkOffering is not None and len(
networkOffering) > 0, "No VPC based network offering")
# Create and Enable VPC offering
vpc_offering = self._create_vpc_offering('vpc_offering')
self.assertTrue(vpc_offering is not None, "Failed to create VPC Offering")
vpc_offering.update(self.apiclient, state='Enabled')
vpc1 = None
# Create VPC 1
try:
vpc1 = VPC.create(
apiclient=self.apiclient,
services=self.services["vpc_vpn"]["vpc"],
networkDomain="vpc1.vpn",
vpcofferingid=vpc_offering.id,
zoneid=self.zone.id,
account=self.account.name,
domainid=self.domain.id
)
except Exception as e:
self.fail(e)
finally:
self.assertTrue(vpc1 is not None, "VPC1 creation failed")
self.cleanup.append(vpc1)
self.logger.debug("VPC1 %s created" % vpc1.id)
vpc2 = None
# Create VPC 2
try:
vpc2 = VPC.create(
apiclient=self.apiclient,
services=self.services["vpc_vpn"]["vpc2"],
networkDomain="vpc2.vpn",
vpcofferingid=vpc_offering.id,
zoneid=self.zone.id,
account=self.account.name,
domainid=self.domain.id
)
except Exception as e:
self.fail(e)
finally:
self.assertTrue(vpc2 is not None, "VPC2 creation failed")
self.cleanup.append(vpc2)
self.logger.debug("VPC2 %s created" % vpc2.id)
default_acl = NetworkACLList.list(
self.apiclient, name="default_allow")[0]
ntwk1 = None
# Create network in VPC 1
try:
ntwk1 = Network.create(
apiclient=self.apiclient,
services=self.services["vpc_vpn"]["network_1"],
accountid=self.account.name,
domainid=self.account.domainid,
networkofferingid=networkOffering[0].id,
zoneid=self.zone.id,
vpcid=vpc1.id,
aclid=default_acl.id
)
except Exception as e:
self.fail(e)
finally:
self.assertIsNotNone(ntwk1, "Network failed to create")
self.cleanup.append(ntwk1)
self.logger.debug("Network %s created in VPC %s" % (ntwk1.id, vpc1.id))
ntwk2 = None
# Create network in VPC 2
try:
ntwk2 = Network.create(
apiclient=self.apiclient,
services=self.services["vpc_vpn"]["network_2"],
accountid=self.account.name,
domainid=self.account.domainid,
networkofferingid=networkOffering[0].id,
zoneid=self.zone.id,
vpcid=vpc2.id,
aclid=default_acl.id
)
except Exception as e:
self.fail(e)
finally:
self.assertIsNotNone(ntwk2, "Network failed to create")
self.cleanup.append(ntwk2)
self.logger.debug("Network %s created in VPC %s" % (ntwk2.id, vpc2.id))
vm1 = None
# Deploy a vm in network 1
try:
vm1 = VirtualMachine.create(self.apiclient, services=self.services["vpc_vpn"]["virtual_machine"],
templateid=self.template.id,
zoneid=self.zone.id,
accountid=self.account.name,
domainid=self.account.domainid,
serviceofferingid=self.compute_offering.id,
networkids=ntwk1.id,
hypervisor=self.hypervisor
)
except Exception as e:
self.fail(e)
finally:
self.assertTrue(vm1 is not None, "VM failed to deploy")
self.assertTrue(vm1.state == 'Running', "VM is not running")
self.cleanup.append(vm1)
self.logger.debug("VM %s deployed in VPC %s" % (vm1.id, vpc1.id))
vm2 = None
# Deploy a vm in network 2
try:
vm2 = VirtualMachine.create(self.apiclient, services=self.services["vpc_vpn"]["virtual_machine"],
templateid=self.template.id,
zoneid=self.zone.id,
accountid=self.account.name,
domainid=self.account.domainid,
serviceofferingid=self.compute_offering.id,
networkids=ntwk2.id,
hypervisor=self.hypervisor
)
except Exception as e:
self.fail(e)
finally:
self.assertTrue(vm2 is not None, "VM failed to deploy")
self.assertTrue(vm2.state == 'Running', "VM is not running")
self.cleanup.append(vm2)
self.debug("VM %s deployed in VPC %s" % (vm2.id, vpc2.id))
# default config
config = {
'ike_enc' :'aes128',
'ike_hash' :'sha1',
'ike_dh' :'modp1536',
'esp_enc' :'aes128',
'esp_hash' :'sha1',
'esp_pfs' :'modp1536',
'psk' :'secreatKey',
'ike_life' :86400,
'esp_life' :3600,
'dpd' :True,
'force_encap' :False,
'passive_1' :False,
'passive_2' :False
}
test_confs = [
{}, # default
{'force_encap': True},
{'ike_life': ''},
{'esp_life': ''},
{'ike_life': '', 'esp_life': ''},
{'passive_1': True, 'passive_2': True},
{'passive_1': False, 'passive_2': True},
{'passive_1': True, 'passive_2': False},
{'passive_1': False, 'passive_2': False, 'dpd': False},
{'passive_1': True, 'passive_2': True, 'dpd': False},
{'passive_1': True, 'passive_2': False, 'dpd': False},
{'passive_1': False, 'passive_2': True, 'dpd': False},
{'passive_1': True, 'passive_2': False, 'esp_pfs': ''},
{'ike_dh': 'modp3072', 'ike_hash': 'sha256', 'esp_pfs': 'modp2048', 'esp_hash':'sha384'},
{'ike_dh': 'modp4096', 'ike_hash': 'sha384', 'esp_pfs': 'modp6144', 'esp_hash':'sha512'},
{'ike_dh': 'modp8192', 'ike_hash': 'sha512', 'esp_pfs': 'modp8192', 'esp_hash':'sha384'}
]
# 4) Enable Site-to-Site VPN for VPC
vpn1_response = Vpn.createVpnGateway(self.apiclient, vpc1.id)
self.assertTrue(
vpn1_response is not None, "Failed to enable VPN Gateway 1")
self.logger.debug("VPN gateway for VPC %s enabled" % vpc1.id)
vpn2_response = Vpn.createVpnGateway(self.apiclient, vpc2.id)
self.assertTrue(
vpn2_response is not None, "Failed to enable VPN Gateway 2")
self.logger.debug("VPN gateway for VPC %s enabled" % vpc2.id)
# 5) Add VPN Customer gateway info
src_nat_list = PublicIPAddress.list(
self.apiclient,
account=self.account.name,
domainid=self.account.domainid,
listall=True,
issourcenat=True,
vpcid=vpc1.id
)
ip1 = src_nat_list[0]
src_nat_list = PublicIPAddress.list(
self.apiclient,
account=self.account.name,
domainid=self.account.domainid,
listall=True,
issourcenat=True,
vpcid=vpc2.id
)
ip2 = src_nat_list[0]
# acquire an extra ip address to use to ssh into vm2
try:
vm2.public_ip = PublicIPAddress.create(
apiclient=self.apiclient,
accountid=self.account.name,
zoneid=self.zone.id,
domainid=self.account.domainid,
services=self.services,
networkid=ntwk2.id,
vpcid=vpc2.id)
except Exception as e:
self.fail(e)
finally:
self.assertTrue(
vm2.public_ip is not None, "Failed to aqcuire public ip for vm2")
natrule = None
# Create port forward to be able to ssh into vm2
try:
natrule = self._create_natrule(
vpc2, vm2, 22, 22, vm2.public_ip, ntwk2)
except Exception as e:
self.fail(e)
finally:
self.assertTrue(
natrule is not None, "Failed to create portforward for vm2")
time.sleep(20)
# setup ssh connection to vm2
ssh_client = self._get_ssh_client(vm2, self.services, 10)
if not ssh_client:
self.fail("Failed to setup ssh connection to %s" % vm2.public_ip)
for test_c in test_confs:
c = config.copy()
c.update(test_c)
services = self._get_vpn_config(c)
self.logger.debug(services)
customer1_response = VpnCustomerGateway.create(
self.apiclient,
services,
"Peer VPC1",
ip1.ipaddress,
vpc1.cidr,
account=self.account.name,
domainid=self.account.domainid)
self.logger.debug("VPN customer gateway added for VPC %s enabled" % vpc1.id)
customer2_response = VpnCustomerGateway.create(
self.apiclient,
services,
"Peer VPC2",
ip2.ipaddress,
vpc2.cidr,
account=self.account.name,
domainid=self.account.domainid)
self.logger.debug("VPN customer gateway added for VPC %s enabled" % vpc2.id)
# 6) Connect two VPCs
vpnconn1_response = Vpn.createVpnConnection(
self.apiclient, customer1_response.id, vpn2_response['id'], c['passive_1'])
self.logger.debug("VPN connection created for VPC %s" % vpc2.id)
time.sleep(5)
vpnconn2_response = Vpn.createVpnConnection(
self.apiclient, customer2_response.id, vpn1_response['id'], c['passive_2'])
self.logger.debug("VPN connection created for VPC %s" % vpc1.id)
def checkVpnConnected():
connections = Vpn.listVpnConnection(
self.apiclient,
listall='true',
vpcid=vpc2.id)
if isinstance(connections, list):
return connections[0].state == 'Connected', None
return False, None
# Wait up to 60 seconds for passive connection to show up as Connected
res, _ = wait_until(2, 30, checkVpnConnected)
if not res:
self.logger.debug("Failed to see VPN state as Connected, we'll attempt ssh+pinging")
# run ping test
packet_loss = ssh_client.execute("/bin/ping -c 3 -t 10 " + vm1.nic[0].ipaddress + " | grep packet | sed 's/.*received, //g' | sed 's/[% ]*packet.*//g'")[0]
self.logger.debug("Packet loss %s" % packet_loss)
self.assertTrue(int(packet_loss) < 50, "Ping did not succeed")
# Cleanup
Vpn.deleteVpnConnection(self.apiclient, vpnconn1_response['id'])
Vpn.deleteVpnConnection(self.apiclient, vpnconn2_response['id'])
customer1_response.delete(self.apiclient)
customer2_response.delete(self.apiclient)
def _get_vpn_config(self, c):
ike_policy = '%s-%s;%s' % (c['ike_enc'], c['ike_hash'], c['ike_dh']) if c['ike_dh'] else '%s-%s' % (c['ike_enc'], c['ike_hash'])
esp_policy = '%s-%s;%s' % (c['esp_enc'], c['esp_hash'], c['esp_pfs']) if c['esp_pfs'] else '%s-%s' % (c['esp_enc'], c['esp_hash'])
out = {
'ipsecpsk': c['psk'],
'ikepolicy':ike_policy,
'esppolicy':esp_policy,
'dpd':c['dpd'],
'forceencap':c['force_encap']
}
if c['ike_life']:
out['ikelifetime'] = c['ike_life']
if c['esp_life']:
out['esplifetime'] = c['esp_life']
return out
@classmethod
def tearDownClass(cls):
super(TestVPCSite2SiteVPNMultipleOptions, cls).tearDownClass()