cloudstack/test/integration/smoke/test_ssl_offloading.py
Wei Zhou b46e29dc67
Improvement: SSL offloading with Virtual Router (#11468)
* SSL offloading with Virtual Router

* PR11468: fix pre-commit errors

* PR11468: api->getAPI/postAPI in UI

* SSL: add smoke tests for VPC in user project

* PR11468: address Daan's comments

* Fix test/integration/smoke/test_ssl_offloading.py

* SSL: remove ssl certificates when clean up account

* SSL offloading: add unit tests

* SSL offloading: UI fixes part 1

* SSL offloading: UI changes part 2

* SSL offloading: add more unit tests

* SSL offloading: more unit tests 3

* SSL offloading: wrong check

* SSL offloading: more and more unit tests

* SSL offloading: add testUpdateLoadBalancerRule5
2025-09-11 16:37:18 +05:30

569 lines
26 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.
from marvin.codes import FAILED
from marvin.cloudstackTestCase import cloudstackTestCase
from marvin.lib.utils import wait_until
from marvin.lib.base import (Account,
Project,
UserData,
SslCertificate,
Template,
NetworkOffering,
ServiceOffering,
VirtualMachine,
Network,
VPC,
VpcOffering,
PublicIPAddress,
LoadBalancerRule)
from marvin.lib.common import (get_domain, get_zone, get_test_template)
from nose.plugins.attrib import attr
import os
import subprocess
import logging
_multiprocess_shared_ = True
DOMAIN = "test-ssl-offloading.cloudstack.org"
CONTENT = "Test page"
FULL_CHAIN = "/tmp/full_chain.crt"
CERT = {
"privatekey": """-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCph7jsoMCQirRn
3obuvgnnefTXRQYd9tF9k2aCVkTiiisvC39px7MGdgvDXADhD9fmR7oyXVQlfNu0
rXjjgsVT3r4bv+DVi81YGXnuU7h10yCOZJt21i6QGHN1CS0/TAfg0UhlACCEYNRx
kB0klwUcj/jk/AKil1DoUGpvAm2gZsek/njb76/AeIfxc+Es4ZOPCVqQOHp6gI0q
t6KDMkUwv8fyzrpScygMUPVYrLmm6D0pn8yd3ihW07wGxMjND6UgOnao8t6H3LaM
Pe7eqSFzxunF9NFFjnUrKcHZZSledDM/37Kbqb/8T5f+4SwjioS1OdPCh8ApdiXq
HNUwYkALAgMBAAECggEAK5JiiQ7X7053B6s96uaVDRVfRGTNKa5iMXBNDHq3wbHZ
X4IJAVr+PE7ivxdKco3r45fT11X9ZpUsssdTJsZZiTDak69BTiFcaaRCnmqOIlpd
J7vb6TMrTIW8RvxQ0M/txm6DuNHLibqJX5a2pszZ13l5cwECfF9/v/XLJTTukCbu
6D/f3fBVFl1tM8y9saOEYLkdb4dILWY61bVSDNswgprz2EV1SFnk5jxz2FuBrM/Q
+7hINvjDcaRvcm59hRb1rkljv7S10VoNw/CFkU451csJkUe4vWZwB8lZK/XxLQG0
HEdS1zU1XY8H8Y1RCrxjGRyiiWsBtUThhWYlPrGCoQKBgQDkP09YAlKqXhT69Kx5
keg2i1jV2hA73zWbWXt9xp5jG5r3pl3m170DvKL93YIDnHtpTC56mlzGrzS7DSTN
p0buY9Qb3fkJxunCpPVFo0HMFkpeR77ax0v34NzSohlRLKFo5R2M1cmDfbVbnSSl
MB57FfRRMxzjrk+dJvjOeJsxjwKBgQC+JLb4B8CZjpurXYg3ySiRqFsCqkqob+kf
9dR+rWvcR6vMTEyha0hUlDvTikDepU2smYR4oPHfdcXF9lAJ7T02UmQDeizAqR68
u9e+yS0q3tdRnPPZmXJfaDCXG1hKMqF4YA5Vs0XAjleF3zHB+vBLrnlPpShtd/Mu
sWTpxICTxQKBgQDSr/n+pE5IQwYczOO0aFGwn5pF9L9NdPHXz5aleETV+TJn7WL6
ZiRsoaDWs7SCvtxQS2kP9RM0t5/2FeDmEMXx4aZ2fsSWGM3IxVo+iL+Aswa81n8/
Ff5y9lb/+29hNdBcsjk/ukwEG3Lf+UNNVAie15oppgPByzJkPwgmFsAy0wKBgHDX
/TZp82WuerhSw/rHiSoYjhqg0bnw4Ju1Gy0q4q5SYqTWS0wpDT4U0wSSMjlwRQ6/
9RxZ9/G0RXFc4tdhUkig0PY3VcPpGnLL0BhL8GBW69ZlnVpwdK4meV/UPKucLLPx
3dACmszSLSMn+LG0qVNg8mHQFJQS8eGuKcOKePw5AoGACuxtefROKdKOALh4lTi2
VOwPZ+1jxsm6lKNccIEvbUpe3UXPgNWpJiDX8mUcob4/NBLzmV3BUVKbG7Exbo5J
LoMfp7OsztWUFwt7YAvRfS8fHdhkEsxEf3T72ADieH5ZAuXFF+K0H3r6HtWPD4ws
mTJjGP4+Bl/dFakA5FJcjHg=
-----END PRIVATE KEY-----""",
"certificate": """-----BEGIN CERTIFICATE-----
MIIFKjCCAxKgAwIBAgIUJ7BtN56KI8OuzbbM8SdtCLCB2UgwDQYJKoZIhvcNAQEL
BQAwXjELMAkGA1UEBhMCWFgxCzAJBgNVBAgMAlhYMQswCQYDVQQHDAJYWDETMBEG
A1UECgwKQ2xvdWRTdGFjazEPMA0GA1UECwwGQXBhY2hlMQ8wDQYDVQQDDAZBcGFj
aGUwHhcNMjUwNjIzMTMxMzA3WhcNMzUwNjIxMTMxMzA3WjBoMQswCQYDVQQGEwJY
WDELMAkGA1UECAwCWFgxCzAJBgNVBAcMAlhYMQ8wDQYDVQQKDAZBcGFjaGUxEzAR
BgNVBAsMCkNsb3VkU3RhY2sxGTAXBgNVBAMMECouY2xvdWRzdGFjay5vcmcwggEi
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCph7jsoMCQirRn3obuvgnnefTX
RQYd9tF9k2aCVkTiiisvC39px7MGdgvDXADhD9fmR7oyXVQlfNu0rXjjgsVT3r4b
v+DVi81YGXnuU7h10yCOZJt21i6QGHN1CS0/TAfg0UhlACCEYNRxkB0klwUcj/jk
/AKil1DoUGpvAm2gZsek/njb76/AeIfxc+Es4ZOPCVqQOHp6gI0qt6KDMkUwv8fy
zrpScygMUPVYrLmm6D0pn8yd3ihW07wGxMjND6UgOnao8t6H3LaMPe7eqSFzxunF
9NFFjnUrKcHZZSledDM/37Kbqb/8T5f+4SwjioS1OdPCh8ApdiXqHNUwYkALAgMB
AAGjgdUwgdIwKwYDVR0RBCQwIoIQKi5jbG91ZHN0YWNrLm9yZ4IOY2xvdWRzdGFj
ay5vcmcwHQYDVR0OBBYEFCcq7jrdsqTD+Xi85DCqjYdL1gOqMIGDBgNVHSMEfDB6
oWKkYDBeMQswCQYDVQQGEwJYWDELMAkGA1UECAwCWFgxCzAJBgNVBAcMAlhYMRMw
EQYDVQQKDApDbG91ZFN0YWNrMQ8wDQYDVQQLDAZBcGFjaGUxDzANBgNVBAMMBkFw
YWNoZYIURVB9+qvRJyOnJnqmYOw467vW3vQwDQYJKoZIhvcNAQELBQADggIBACld
lEXgn/A4/kZQbLwwMxBvaoPDDaDaYVpPbOoPw7a8YkrL0rmPIc04PyX9GAqxdC+c
qaEXvmp3I+BdT13XGcBosXO8uEQ3kses9F3MhOHORPS2mJag7t4eLnNX/0CgKTlR
6yC2Gu7d3xPNJ+CKMxekdoF31StEFNAYI/La/q3D+IGsRCbrVu3xpPaw2XlXI7Ro
RU7yebVmQPSNc75bm8Ydo1cdYtz9h8PVnc+6ThhSrdS3jYScj9DrX5ZJaKuZqSlu
0ZqFXoBflme+cYB7nb9HqnIO67r9vzd2dTcErJVAk5jQqG5Y38d1tingDx1A5opU
z4BkXEbHNV6VXYUQ5VE0dXO2sNvXVJrstwMPE8d3EvbX/1gWj8kuymbskrCjySE4
4Yztkb0dsJkVU793lz3EV75DsXvj3gevK049nPv2Grt1+rTgFNa6NJnLvKIKk/mv
fWjxbK2b/AAJ1ci6xtw/vKmIWoEu6uEMIJmhfBwuP+VnVJWJbmYXpNW/L5g21B76
Fn8RuQa3mlm5lZrxEcJ/b6fF+2NPJwj7sh6l688VtNXoVSSyXUeV5HwqCv+YMjKn
CtwpEN/eNHMbrkJvgYwSoOzqhV/wpmNi28S7MOm66JMECHOXOhk/eX2chIEjiVna
MXhvr/Twfj2N4gNVtcgXkrk39HEYjk5+uF7SdNf4
-----END CERTIFICATE-----""",
"certchain": """-----BEGIN CERTIFICATE-----
MIIFQzCCAysCFEVQffqr0ScjpyZ6pmDsOOu71t70MA0GCSqGSIb3DQEBCwUAMF4x
CzAJBgNVBAYTAlhYMQswCQYDVQQIDAJYWDELMAkGA1UEBwwCWFgxEzARBgNVBAoM
CkNsb3VkU3RhY2sxDzANBgNVBAsMBkFwYWNoZTEPMA0GA1UEAwwGQXBhY2hlMB4X
DTI1MDYxNjEwMjc1NloXDTMwMDYxNTEwMjc1NlowXjELMAkGA1UEBhMCWFgxCzAJ
BgNVBAgMAlhYMQswCQYDVQQHDAJYWDETMBEGA1UECgwKQ2xvdWRTdGFjazEPMA0G
A1UECwwGQXBhY2hlMQ8wDQYDVQQDDAZBcGFjaGUwggIiMA0GCSqGSIb3DQEBAQUA
A4ICDwAwggIKAoICAQCLiQmSjrht15R1F+r79m/LZN5hsfQBGp+dy+yrtsWfOOur
RdXAwgbLxxsyKMQKWCQxlRI7wdhqh0L0ZBrIr9MjltYqsqLAoLmgY4eG/f6G8YGr
O/rxzfwTLbCeaIseF/OMA6Sz125HXYp1bltYK4LsuC7tihZXbeVa5pUGs3Jwgcfx
LYm4eB42Hp7Eg05uL8LbwT/1AjcwoWkTewKAWXA83zgLRDFDbl1t0IPHI4cdVvia
BNwNbG49ZCF6OgmokSarQSe4Vbems1u9T9pAySXAVjEYBqFjKWyswpdr782uNLmB
lCGm0pDeJ9/WASxbTJr7k9H6ZpnaHr54DG6ZqennWMz8w6r2pf7bp/EGZ3mZQ4s3
5ylSP4cQt8CSSI8k2CflPGUyytUAiWlDS3qSyIuAOPKXDg7wIpcbwcu4VMeKnH0Z
x7Uu9j1UDZEZoSu6UI/VInTl47k1/ECD+AO9yBzZSv+pTQmO3/Im3CcxsTHmVd5s
Tl0CJ/jWNpo9DAMtmGvt6CBWBXGRsO2XNk7djRcq2CubiCpvODg+7CcR6CiZK73L
1aOisLiq3+ofiJSSXRRuKtJlkQ4eSPSbYWkNJcKmIhbCoYOdH/Pe3/+RHjvNc1kO
OUb+icmfzcMVAs3C5jybpazsfjDNQZXWAFx4FLDcqOVbrCwom+tMukw+hzlZnwID
AQABMA0GCSqGSIb3DQEBCwUAA4ICAQAdexoMwn+Ol1A3+NOHk9WJZX+t2Q8/9wWb
K+jSVleSfXXWsB1mC3fABVJQdCxtXCH3rpt4w7FK6aUes9VjqAHap4tt9WBq0Wqq
vvMURFHfllxEM31Z35kBOCSQY9xwpGV1rRh/zYs4h55YixomR3nXNZ9cI8xzlSCi
sMG0mv0y+yxPohKrZj3AzLYz/M11SimSoyRPIANI+cUg1nJXyQoHzVHWEp1Nj0HB
M/GW05cxsWea7f5YcAW1JQI3FOkpwb72fIZOtMDa4PO8IYWXJAeAc/chw745/MTi
Rvl2NT4RZBAcrSNbhCOzRPG/ZiG+ArQuCluZ9HHAXRBMTtlLk5DO4+XxZlyGpjwf
uKniK8dccy9uU0ho73p9SNDhXH0yb9Naj8vd9NWzCUYaaBXt/92cIyhaAHAVFxJu
o6jr2FLbnhSGF9EO/tHvF7LxZv1dnbInvlWHwoFQjwmoeB+e17lHBdPMnWnPKBZe
jA2VH/IzGCucWuWQhruummO5GT8Z6F4jBwvafBo+QARKPZgEBpx3LycXrpkYI3LT
GGOpGCxFt5tVZOEsC/jQ5rIljNSeTzWmzfNRn/yRUW97uWsrzcQIBAUtu/pQnyFQ
WCnC1ipCp1zhJsXAFUKuqEfLngXodOvC4tAOr76h11S57o5lN4506Poq2mWgAZe/
JZr9MEn1+w==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFnzCCA4egAwIBAgIUcUNMqgWoDLsvMj0YmEudj60EG5swDQYJKoZIhvcNAQEL
BQAwXjELMAkGA1UEBhMCWFgxCzAJBgNVBAgMAlhYMQswCQYDVQQHDAJYWDETMBEG
A1UECgwKQ2xvdWRTdGFjazEPMA0GA1UECwwGQXBhY2hlMQ8wDQYDVQQDDAZBcGFj
aGUwIBcNMjUwNjE2MTAyNzM2WhgPMjEyNTA1MjMxMDI3MzZaMF4xCzAJBgNVBAYT
AlhYMQswCQYDVQQIDAJYWDELMAkGA1UEBwwCWFgxEzARBgNVBAoMCkNsb3VkU3Rh
Y2sxDzANBgNVBAsMBkFwYWNoZTEPMA0GA1UEAwwGQXBhY2hlMIICIjANBgkqhkiG
9w0BAQEFAAOCAg8AMIICCgKCAgEAwVQaePulUM523gKw168ToYp+gt05bXbu4Gg8
uaRDKhnRAX1sEgYwkQ36Q+iTDEM9sKRma8lMNMIqkZMQdk6sIGX6BL+6wUOb7mL0
5+I0yO9i8ooaGgNaeNvZftNIRlLsnPMGJaeom2/66XV4CsMqoZKaJ1H/I8N+bAeD
GvrBx+B4l9D3G390nQvot9JUzrJgGuLl0KDHapvhlR39cCgEfIii02uX1iy0qXlV
b+G1kLvpeC7T+lsJxondPJ69aO3lbDv/izyWw7qqBC57UhT/oKDxJmjQqklqzhgt
nM/p3YE7M0nkRi3LnRmsZBz7o1DRf+M29zypKzXVk1aJflL46AtLMmpDIzVrEB2M
q7o47rstXusYRYsBCqGTgdI1fV/CkDsZY5XkPZh2dsjZCHIS4P03OqFGsc6PQha2
+y2AhV1pvywkDl48kPKSukHfV1RtaPZUZtcQKztwHH+aFfo9mD8z0H2HcExdXKzd
jhRhI9ZSwFj3HEN9f5P8fS3lf5+fV7EEbG4NisieBj/UivW6QiTHpLD7wRLIUt2g
XgXNF0lfJzYHbIcxQ6kfC5McU2fu6mUC+p/pNN8G0POS3S2T55tEUqLL4N0SadQy
N1TZlTd2xTn+Hb6WlG0f5m97xGcNlGHKBvntFrHvOIfkEQ9ne3MlOO1Gjlintowo
fRGf15kCAwEAAaNTMFEwHQYDVR0OBBYEFM4WEQJpN9M07Q8CHq+5owG93Dj8MB8G
A1UdIwQYMBaAFM4WEQJpN9M07Q8CHq+5owG93Dj8MA8GA1UdEwEB/wQFMAMBAf8w
DQYJKoZIhvcNAQELBQADggIBABr5RKGc/rKx4fOgyXNJR4aCJCTtPZKs4AUCCBYz
cWOjJYGNvThOPSVx51nAD8+YP2BwkOIPfhl2u/+vQSSbz4OlauXLki2DUN8E2OFe
gJfxPDzWOfAo/QOJcyHwSlnIQjiZzG2lK3eyf5IFnfQILQzDvXaUYvMBkl2hb5Q7
44H6tRw78uuf/KsT4rY0bBFMN5DayjiyvoIDUvzCRqcb2KOi9DnZ7pXjduL7tO0j
PhlQ24B77LVUUAvydIGUzmbhGC2VvY1qE7uaYgYtgSUZ0zSjJrHjUjVLMzRouNP7
jpbBQRAcP4FDcOFZBHogunA0hxQdm0d8u3LqDYPNS0rpfW0ddU/72nfBX4bnoDEN
+anw4wOgFuUcoEThALWZ9ESVKxXQ9Fpvd6FRW8fLLqhXAuli1BqP1c1WRxagldYe
nPGm/FGZyJ2xOak9Uigi9NAQ/vX6CEfgcJgFZmCo8EKH0d4Ut72vGUcPqiUhT2EI
AFAd6drSyoUdXXniSMWky9Vrt+qtLuAD1nhHTv8ZPdItXokoiD6ea/4xrbUZn0qY
lLMDyfY76UVF0ruTR2Q6IdSq/zSggdwgkTooOW4XZcRf5l/ZnoeVQ1QH9C85SIKH
IKZwPeGUm+EntmpuCBDmQSHLRCGEThd64iOAjqLR6arLj4TBJzBrZsGHFJbm0OcI
dwa9
-----END CERTIFICATE-----""",
"enabledrevocationcheck": False
}
# Install apache2 via userdata
USER_DATA="""I2Nsb3VkLWNvbmZpZwpydW5jbWQ6CiAgLSBzdWRvIGFwdC1nZXQgdXBkYXRlCiAgLSBzdWRvIGFw
dC1nZXQgaW5zdGFsbCAteSBhcGFjaGUyCiAgLSBzdWRvIHN5c3RlbWN0bCBlbmFibGUgYXBhY2hl
MgogIC0gc3VkbyBzeXN0ZW1jdGwgc3RhcnQgYXBhY2hlMgogIC0gZWNobyAiVGVzdCBwYWdlIiB8
c3VkbyB0ZWUgL3Zhci93d3cvaHRtbC90ZXN0Lmh0bWwK"""
# #cloud-config
# runcmd:
# - sudo apt-get update
# - sudo apt-get install -y apache2
# - sudo systemctl enable apache2
# - sudo systemctl start apache2
# - echo "Test page" |sudo tee /var/www/html/test.html
class TestSslOffloading(cloudstackTestCase):
@classmethod
def setUpClass(cls):
testClient = super(TestSslOffloading, cls).getClsTestClient()
cls.apiclient = testClient.getApiClient()
cls.services = testClient.getParsedTestDataConfig()
cls._cleanup = []
# Get Zone, Domain and templates
cls.domain = get_domain(cls.apiclient)
cls.zone = get_zone(cls.apiclient, testClient.getZoneForTests())
cls.hypervisor = testClient.getHypervisorInfo()
cls.services["virtual_machine"]["zoneid"] = cls.zone.id
# Save full chain as a file
with open(FULL_CHAIN, "w", encoding="utf-8") as f:
f.write(CERT["certchain"])
# Register template if needed
if cls.hypervisor.lower() == 'simulator':
cls.template = get_test_template(
cls.apiclient,
cls.zone.id,
cls.hypervisor)
else:
cls.template = Template.register(
cls.apiclient,
cls.services["test_templates_cloud_init"][cls.hypervisor.lower()],
zoneid=cls.zone.id,
hypervisor=cls.hypervisor,
)
cls.template.download(cls.apiclient)
cls._cleanup.append(cls.template)
if cls.template == FAILED:
assert False, "get_test_template() failed to return template"
# Create service offering
cls.service_offering = ServiceOffering.create(
cls.apiclient,
cls.services["service_offerings"]["big"] # 512MB memory
)
cls._cleanup.append(cls.service_offering)
# Create network offering
cls.services["isolated_network_offering"]["egress_policy"] = "true"
cls.network_offering = NetworkOffering.create(cls.apiclient,
cls.services["isolated_network_offering"],
conservemode=True)
cls.network_offering.update(cls.apiclient, state='Enabled')
cls._cleanup.append(cls.network_offering)
#Create an account, network, VM and IP addresses
cls.account = Account.create(
cls.apiclient,
cls.services["account"],
admin=True,
domainid=cls.domain.id
)
cls._cleanup.append(cls.account)
cls.user = cls.account.user[0]
cls.userapiclient = cls.testClient.getUserApiClient(cls.user.username, cls.domain.name)
cls.logger = logging.getLogger("TestSslOffloading")
cls.stream_handler = logging.StreamHandler()
cls.logger.setLevel(logging.DEBUG)
cls.logger.addHandler(cls.stream_handler)
def setUp(self):
self.apiclient = self.testClient.getApiClient()
self.cleanup = []
def tearDown(self):
super(TestSslOffloading, self).tearDown()
@classmethod
def tearDownClass(cls):
super(TestSslOffloading, cls).tearDownClass()
# Remove full chain file
if os.path.exists(FULL_CHAIN):
os.remove(FULL_CHAIN)
def wait_for_service_ready(self, command, expected, retries=60):
output = None
self.logger.debug("======================================")
self.logger.debug("Checking output of command '%s', expected result: '%s'" % (command, expected))
def check_output():
try:
output = subprocess.check_output(command + ' 2>&1', shell=True).strip().decode('utf-8')
except Exception as e:
self.logger.debug("Failed to get output of command '%s': '%s'" % (command, e))
if expected is None:
self.logger.debug("But it is expected")
return True, None
return False, None
self.logger.debug("Output of command '%s' is '%s'" % (command, output))
if expected is None:
self.logger.debug("But it is expected to be None")
return False, None
return (expected in output), None
res, _ = wait_until(10, retries, check_output)
if not res:
self.fail("Failed to wait for http server to show content '%s'. The output is '%s'" % (expected, output))
@attr(tags = ["advanced", "advancedns", "smoke"], required_hardware="true")
def test_01_ssl_offloading_isolated_network(self):
"""Test to create Load balancing rule with SSL offloading"""
# Validate:
# 1. Create isolated network and vm instance
# 2. create LB with port 80 -> 80, verify the website (should get expected content)
# 3. create LB with port 443 -> 80, verify the website (should not work)
# 4. add cert to LB with port 443
# 5. verify the website (should get expected content)
# 6. remove cert from LB with port 443
# 7. delete SSL certificate
# Register Userdata
self.userdata = UserData.register(self.apiclient,
name="test-userdata",
userdata=USER_DATA,
account=self.account.name,
domainid=self.account.domainid
)
# Upload SSL Certificate
self.sslcert = SslCertificate.create(self.apiclient,
CERT,
name="test-ssl-certificate",
account=self.account.name,
domainid=self.account.domainid)
# 1. Create network
self.network = Network.create(self.apiclient,
zoneid=self.zone.id,
services=self.services["network"],
domainid=self.domain.id,
account=self.account.name,
networkofferingid=self.network_offering.id)
self.cleanup.append(self.network)
self.services["virtual_machine"]["networkids"] = [str(self.network.id)]
# Create vm instance
self.vm_1 = VirtualMachine.create(
self.apiclient,
self.services["virtual_machine"],
templateid=self.template.id,
accountid=self.account.name,
domainid=self.account.domainid,
userdataid=self.userdata.userdata.id,
serviceofferingid=self.service_offering.id
)
self.cleanup.append(self.vm_1)
self.public_ip = PublicIPAddress.create(
self.apiclient,
self.account.name,
self.zone.id,
self.account.domainid,
self.services["virtual_machine"],
self.network.id)
# 2. create LB with port 80 -> 80, verify the website (should get expected content).
# firewall is open by default
lb_http = {
"name": "http",
"alg": "roundrobin",
"privateport": 80,
"publicport": 80,
"protocol": "tcp"
}
lb_rule_http = LoadBalancerRule.create(
self.apiclient,
lb_http,
self.public_ip.ipaddress.id,
accountid=self.account.name,
domainid=self.domain.id,
networkid=self.network.id
)
lb_rule_http.assign(self.apiclient, [self.vm_1])
command = "curl -sL --connect-timeout 3 http://%s/test.html" % self.public_ip.ipaddress.ipaddress
# wait 10 minutes until the webpage is available. it returns "503 Service Unavailable" if not available
self.wait_for_service_ready(command, CONTENT, 60)
# 3. create LB with port 443 -> 80, verify the website (should not work)
# firewall is open by default
lb_https = {
"name": "https",
"alg": "roundrobin",
"privateport": 80,
"publicport": 443,
"protocol": "ssl"
}
lb_rule_https = LoadBalancerRule.create(
self.apiclient,
lb_https,
self.public_ip.ipaddress.id,
accountid=self.account.name,
domainid=self.domain.id,
networkid=self.network.id
)
lb_rule_https.assign(self.apiclient, [self.vm_1])
command = "curl -L --connect-timeout 3 -k --resolve %s:443:%s https://%s/test.html" % (DOMAIN, self.public_ip.ipaddress.ipaddress, DOMAIN)
self.wait_for_service_ready(command, None, 1)
command = "curl -L --connect-timeout 3 --resolve %s:443:%s https://%s/test.html" % (DOMAIN, self.public_ip.ipaddress.ipaddress, DOMAIN)
self.wait_for_service_ready(command, None, 1)
# 4. add cert to LB with port 443
lb_rule_https.assignCert(self.apiclient, self.sslcert.id)
# 5. verify the website (should get expected content)
command = "curl -L --connect-timeout 3 --resolve %s:443:%s https://%s/test.html" % (DOMAIN, self.public_ip.ipaddress.ipaddress, DOMAIN)
self.wait_for_service_ready(command, None, 1)
command = "curl -sL --connect-timeout 3 -k --resolve %s:443:%s https://%s/test.html" % (DOMAIN, self.public_ip.ipaddress.ipaddress, DOMAIN)
self.wait_for_service_ready(command, CONTENT, 1)
command = "curl -sL --connect-timeout 3 --cacert %s --resolve %s:443:%s https://%s/test.html" % (FULL_CHAIN, DOMAIN, self.public_ip.ipaddress.ipaddress, DOMAIN)
self.wait_for_service_ready(command, CONTENT, 1)
# 6. remove cert from LB with port 443
lb_rule_https.removeCert(self.apiclient)
# 7. delete SSL certificate
self.sslcert.delete(self.apiclient)
@attr(tags = ["advanced", "advancedns", "smoke"], required_hardware="true")
def test_02_ssl_offloading_project_vpc(self):
"""Test to create Load balancing rule with SSL offloading in VPC in user project"""
# Validate:
# 1. Create VPC, VPC tier and vm instance
# 2. create LB with port 80 -> 80, verify the website (should get expected content)
# 3. create LB with port 443 -> 80, verify the website (should not work)
# 4. add cert to LB with port 443
# 5. verify the website (should get expected content)
# 6. remove cert from LB with port 443
# 7. delete SSL certificate
# Create project by user
self.project = Project.create(
self.userapiclient,
self.services["project"]
)
self.cleanup.append(self.project)
# Register Userdata by user
self.userdata = UserData.register(self.userapiclient,
name="test-user-userdata",
userdata=USER_DATA,
projectid=self.project.id
)
# Upload SSL Certificate by user
self.sslcert = SslCertificate.create(self.userapiclient,
CERT,
name="test-user-ssl-certificate",
projectid=self.project.id
)
# 1. Create VPC and VPC tier
vpcOffering = VpcOffering.list(self.userapiclient, name="Default VPC offering")
self.assertTrue(vpcOffering is not None and len(
vpcOffering) > 0, "No VPC offerings found")
self.vpc = VPC.create(
apiclient=self.userapiclient,
services=self.services["vpc_vpn"]["vpc"],
vpcofferingid=vpcOffering[0].id,
zoneid=self.zone.id,
projectid=self.project.id
)
self.cleanup.append(self.vpc)
networkOffering = NetworkOffering.list(
self.userapiclient, name="DefaultIsolatedNetworkOfferingForVpcNetworks")
self.assertTrue(networkOffering is not None and len(
networkOffering) > 0, "No VPC based network offering")
self.network = Network.create(
apiclient=self.userapiclient,
services=self.services["vpc_vpn"]["network_1"],
networkofferingid=networkOffering[0].id,
zoneid=self.zone.id,
vpcid=self.vpc.id,
projectid=self.project.id
)
self.cleanup.append(self.network)
self.services["virtual_machine"]["networkids"] = [str(self.network.id)]
# Create vm instance
self.vm_2 = VirtualMachine.create(
self.userapiclient,
self.services["virtual_machine"],
templateid=self.template.id,
userdataid=self.userdata.userdata.id,
serviceofferingid=self.service_offering.id,
projectid=self.project.id
)
self.cleanup.append(self.vm_2)
self.public_ip = PublicIPAddress.create(
self.userapiclient,
zoneid=self.zone.id,
services=self.services["virtual_machine"],
networkid=self.network.id,
vpcid=self.vpc.id,
projectid=self.project.id
)
# 2. create LB with port 80 -> 80, verify the website (should get expected content).
# firewall is open by default
lb_http = {
"name": "http",
"alg": "roundrobin",
"privateport": 80,
"publicport": 80,
"protocol": "tcp"
}
lb_rule_http = LoadBalancerRule.create(
self.userapiclient,
lb_http,
self.public_ip.ipaddress.id,
networkid=self.network.id,
projectid=self.project.id
)
lb_rule_http.assign(self.userapiclient, [self.vm_2])
command = "curl -sL --connect-timeout 3 http://%s/test.html" % self.public_ip.ipaddress.ipaddress
# wait 10 minutes until the webpage is available. it returns "503 Service Unavailable" if not available
self.wait_for_service_ready(command, CONTENT, 60)
# 3. create LB with port 443 -> 80, verify the website (should not work)
# firewall is open by default
lb_https = {
"name": "https",
"alg": "roundrobin",
"privateport": 80,
"publicport": 443,
"protocol": "ssl"
}
lb_rule_https = LoadBalancerRule.create(
self.userapiclient,
lb_https,
self.public_ip.ipaddress.id,
networkid=self.network.id,
projectid=self.project.id
)
lb_rule_https.assign(self.userapiclient, [self.vm_2])
command = "curl -L --connect-timeout 3 -k --resolve %s:443:%s https://%s/test.html" % (DOMAIN, self.public_ip.ipaddress.ipaddress, DOMAIN)
self.wait_for_service_ready(command, None, 1)
command = "curl -L --connect-timeout 3 --resolve %s:443:%s https://%s/test.html" % (DOMAIN, self.public_ip.ipaddress.ipaddress, DOMAIN)
self.wait_for_service_ready(command, None, 1)
# 4. add cert to LB with port 443
lb_rule_https.assignCert(self.userapiclient, self.sslcert.id)
# 5. verify the website (should get expected content)
command = "curl -L --connect-timeout 3 --resolve %s:443:%s https://%s/test.html" % (DOMAIN, self.public_ip.ipaddress.ipaddress, DOMAIN)
self.wait_for_service_ready(command, None, 1)
command = "curl -sL --connect-timeout 3 -k --resolve %s:443:%s https://%s/test.html" % (DOMAIN, self.public_ip.ipaddress.ipaddress, DOMAIN)
self.wait_for_service_ready(command, CONTENT, 1)
command = "curl -sL --connect-timeout 3 --cacert %s --resolve %s:443:%s https://%s/test.html" % (FULL_CHAIN, DOMAIN, self.public_ip.ipaddress.ipaddress, DOMAIN)
self.wait_for_service_ready(command, CONTENT, 1)
# 6. remove cert from LB with port 443
lb_rule_https.removeCert(self.userapiclient)
# 7. delete SSL certificate
self.sslcert.delete(self.userapiclient)