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
121 lines
4.9 KiB
Python
Executable File
121 lines
4.9 KiB
Python
Executable File
# 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.
|
|
import logging
|
|
import os.path
|
|
from os import listdir
|
|
import re
|
|
from cs.CsDatabag import CsDataBag
|
|
from .CsProcess import CsProcess
|
|
from .CsFile import CsFile
|
|
from . import CsHelper
|
|
|
|
HAPROXY_CONF_T = "/etc/haproxy/haproxy.cfg.new"
|
|
HAPROXY_CONF_P = "/etc/haproxy/haproxy.cfg"
|
|
|
|
SSL_CERTS_DIR = "/etc/cloudstack/ssl/"
|
|
|
|
class CsLoadBalancer(CsDataBag):
|
|
""" Manage Load Balancer entries """
|
|
|
|
def process(self):
|
|
if "config" not in list(self.dbag.keys()):
|
|
return
|
|
if 'configuration' not in list(self.dbag['config'][0].keys()):
|
|
return
|
|
if 'ssl_certs' in list(self.dbag['config'][0].keys()):
|
|
self._create_pem_for_sslcert(self.dbag['config'][0]['ssl_certs'])
|
|
|
|
config = self.dbag['config'][0]['configuration']
|
|
file1 = CsFile(HAPROXY_CONF_T)
|
|
file1.empty()
|
|
for x in config:
|
|
[file1.append(w, -1) for w in x.split('\n')]
|
|
|
|
file1.commit()
|
|
file2 = CsFile(HAPROXY_CONF_P)
|
|
if not file2.compare(file1):
|
|
# Verify new haproxy config before haproxy restart/reload
|
|
haproxy_err = self._verify_haproxy_config(HAPROXY_CONF_T)
|
|
if haproxy_err:
|
|
raise Exception("haproxy config is invalid with error \n%s" % haproxy_err)
|
|
|
|
CsHelper.copy(HAPROXY_CONF_T, HAPROXY_CONF_P)
|
|
|
|
proc = CsProcess(['/run/haproxy.pid'])
|
|
if not proc.find():
|
|
logging.debug("CsLoadBalancer:: will restart HAproxy!")
|
|
CsHelper.service("haproxy", "restart")
|
|
else:
|
|
logging.debug("CsLoadBalancer:: will reload HAproxy!")
|
|
CsHelper.service("haproxy", "reload")
|
|
|
|
add_rules = self.dbag['config'][0]['add_rules']
|
|
remove_rules = self.dbag['config'][0]['remove_rules']
|
|
stat_rules = self.dbag['config'][0]['stat_rules']
|
|
self._configure_firewall(add_rules, remove_rules, stat_rules)
|
|
|
|
def _configure_firewall(self, add_rules, remove_rules, stat_rules):
|
|
firewall = self.config.get_fw()
|
|
|
|
logging.debug("CsLoadBalancer:: configuring firewall. Add rules ==> %s" % add_rules)
|
|
logging.debug("CsLoadBalancer:: configuring firewall. Remove rules ==> %s" % remove_rules)
|
|
logging.debug("CsLoadBalancer:: configuring firewall. Stat rules ==> %s" % stat_rules)
|
|
|
|
for rules in add_rules:
|
|
path = rules.split(':')
|
|
ip = path[0]
|
|
port = path[1]
|
|
firewall.append(["filter", "", "-A INPUT -p tcp -m tcp -d %s --dport %s -m state --state NEW -j ACCEPT" % (ip, port)])
|
|
|
|
for rules in remove_rules:
|
|
path = rules.split(':')
|
|
ip = path[0]
|
|
port = path[1]
|
|
firewall.append(["filter", "", "-D INPUT -p tcp -m tcp -d %s --dport %s -m state --state NEW -j ACCEPT" % (ip, port)])
|
|
|
|
for rules in stat_rules:
|
|
path = rules.split(':')
|
|
ip = path[0]
|
|
port = path[1]
|
|
firewall.append(["filter", "", "-A INPUT -p tcp -m tcp -d %s --dport %s -m state --state NEW -j ACCEPT" % (ip, port)])
|
|
|
|
def _create_pem_for_sslcert(self, ssl_certs):
|
|
logging.debug("CsLoadBalancer:: creating new pem files in %s and cleaning up it" % SSL_CERTS_DIR)
|
|
if not os.path.exists(SSL_CERTS_DIR):
|
|
CsHelper.execute("mkdir -p %s" % SSL_CERTS_DIR)
|
|
cert_names = []
|
|
for cert in ssl_certs:
|
|
cert_names.append(cert['name'] + ".pem")
|
|
file = CsFile("%s/%s.pem" % (SSL_CERTS_DIR, cert['name']))
|
|
file.empty()
|
|
file.add("%s\n" % cert['cert'].replace("\r\n", "\n"))
|
|
if 'chain' in cert.keys():
|
|
file.add("%s\n" % cert['chain'].replace("\r\n", "\n"))
|
|
file.add("%s\n" % cert['key'].replace("\r\n", "\n"))
|
|
file.commit()
|
|
for f in listdir(SSL_CERTS_DIR):
|
|
if f not in cert_names:
|
|
CsHelper.execute("rm -rf %s/%s" % (SSL_CERTS_DIR, f))
|
|
|
|
def _verify_haproxy_config(self, config):
|
|
ret = CsHelper.execute2("haproxy -c -f %s" % config)
|
|
if ret.returncode:
|
|
stdout, stderr = ret.communicate()
|
|
logging.error("haproxy config is invalid with error: %s" % stderr)
|
|
return stderr
|
|
return ""
|