mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
* 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
569 lines
26 KiB
Python
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)
|