ea77b5f857
Metadata service in the NSX-V plugin is handled by a Edge DHCP or router VM. Currently the traffic between nova and the metadata service is insecure. This patch adds the SSL support for metadata service which will make the connection secure. The certificate used for secure communication will be created on the VC under the edge scope. If user does not supply the certificate and private key for secure communication, a self signed certificate will be generated in the backend. This self signed certificate will last for a period of 10yrs. A certifcate with the given details will be created in the backend if such a configuration exists in nsx.ini Appropriate config is pushed for the loadbalancer with the protocol set to HTTPS if SSL is enabled for metadata service. DocImpact Change-Id: I5582cc1186ef4b8451f999b46e55bc2c684b1be3
400 lines
13 KiB
Python
400 lines
13 KiB
Python
# Copyright 2014 VMware, Inc.
|
|
# All Rights Reserved
|
|
#
|
|
# Licensed 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 oslo_log import log as logging
|
|
|
|
from vmware_nsx.plugins.nsx_v.vshield import nsxv_edge_cfg_obj
|
|
|
|
|
|
LOG = logging.getLogger(__name__)
|
|
|
|
|
|
class NsxvLoadbalancer(nsxv_edge_cfg_obj.NsxvEdgeCfgObj):
|
|
|
|
SERVICE_NAME = 'loadbalancer'
|
|
|
|
def __init__(
|
|
self,
|
|
enabled=True,
|
|
enable_service_insertion=False,
|
|
acceleration_enabled=False):
|
|
super(NsxvLoadbalancer, self).__init__()
|
|
self.payload = {
|
|
'enabled': enabled,
|
|
'enableServiceInsertion': enable_service_insertion,
|
|
'accelerationEnabled': acceleration_enabled}
|
|
self.virtual_servers = {}
|
|
|
|
def get_service_name(self):
|
|
return self.SERVICE_NAME
|
|
|
|
def add_virtual_server(self, virtual_server):
|
|
self.virtual_servers[virtual_server.payload['name']] = virtual_server
|
|
|
|
def del_virtual_server(self, name):
|
|
self.virtual_servers.pop(name, None)
|
|
|
|
def serializable_payload(self):
|
|
virt_servers = []
|
|
app_profiles = []
|
|
app_rules = []
|
|
pools = []
|
|
monitors = []
|
|
|
|
virt_id = 1
|
|
app_prof_id = 1
|
|
app_rule_id = 1
|
|
pool_id = 1
|
|
monitor_id = 1
|
|
member_id = 1
|
|
|
|
for virtual_server in self.virtual_servers.values():
|
|
s_virt = virtual_server.payload.copy()
|
|
s_virt['virtualServerId'] = 'virtualServer-%d' % virt_id
|
|
virt_id += 1
|
|
|
|
# Setup app profile
|
|
s_app_prof = virtual_server.app_profile.payload.copy()
|
|
s_app_prof['applicationProfileId'] = ('applicationProfile-%d' %
|
|
app_prof_id)
|
|
app_profiles.append(s_app_prof)
|
|
app_prof_id += 1
|
|
|
|
# Bind virtual server to app profile
|
|
s_virt['applicationProfileId'] = s_app_prof['applicationProfileId']
|
|
|
|
# Setup app rules
|
|
if virtual_server.app_rules.values():
|
|
s_virt['applicationRuleId'] = []
|
|
for app_rule in virtual_server.app_rules.values():
|
|
s_app_rule = app_rule.payload.copy()
|
|
s_app_rule['applicationRuleId'] = ('applicationRule-%d' %
|
|
app_rule_id)
|
|
app_rule_id += 1
|
|
|
|
# Add to LB object, bind to virtual server
|
|
app_rules.append(s_app_rule)
|
|
s_virt['applicationRuleId'].append(
|
|
s_app_rule['applicationRuleId'])
|
|
|
|
# Setup pools
|
|
s_pool = virtual_server.default_pool.payload.copy()
|
|
s_pool['poolId'] = 'pool-%d' % pool_id
|
|
pool_id += 1
|
|
pools.append(s_pool)
|
|
|
|
# Add pool members
|
|
s_pool['member'] = []
|
|
for member in virtual_server.default_pool.members.values():
|
|
s_m = member.payload.copy()
|
|
s_m['memberId'] = 'member-%d' % member_id
|
|
member_id += 1
|
|
s_pool['member'].append(s_m)
|
|
|
|
# Bind pool to virtual server
|
|
s_virt['defaultPoolId'] = s_pool['poolId']
|
|
|
|
s_pool['monitorId'] = []
|
|
# Add monitors
|
|
for monitor in virtual_server.default_pool.monitors.values():
|
|
s_mon = monitor.payload.copy()
|
|
s_mon['monitorId'] = 'monitor-%d' % monitor_id
|
|
monitor_id += 1
|
|
|
|
s_pool['monitorId'].append(s_mon['monitorId'])
|
|
|
|
monitors.append(s_mon)
|
|
|
|
virt_servers.append(s_virt)
|
|
|
|
payload = self.payload.copy()
|
|
payload['applicationProfile'] = app_profiles
|
|
if app_rules:
|
|
payload['applicationRule'] = app_rules
|
|
payload['monitor'] = monitors
|
|
payload['pool'] = pools
|
|
payload['virtualServer'] = virt_servers
|
|
payload['featureType'] = 'loadbalancer_4.0'
|
|
|
|
return payload
|
|
|
|
@staticmethod
|
|
def get_loadbalancer(vcns_obj, edge_id):
|
|
edge_lb = nsxv_edge_cfg_obj.NsxvEdgeCfgObj.get_object(
|
|
vcns_obj,
|
|
edge_id,
|
|
'%s/config' % NsxvLoadbalancer.SERVICE_NAME)
|
|
|
|
lb_obj = NsxvLoadbalancer(
|
|
edge_lb['enabled'],
|
|
edge_lb['enableServiceInsertion'],
|
|
edge_lb['accelerationEnabled'])
|
|
|
|
# Construct loadbalancer objects
|
|
for virt_srvr in edge_lb['virtualServer']:
|
|
v_s = NsxvLBVirtualServer(
|
|
virt_srvr['name'],
|
|
virt_srvr['ipAddress'],
|
|
virt_srvr['port'],
|
|
virt_srvr['protocol'],
|
|
virt_srvr['enabled'],
|
|
virt_srvr['accelerationEnabled'],
|
|
virt_srvr['connectionLimit'])
|
|
|
|
# Find application profile objects, attach to virtual server
|
|
for app_prof in edge_lb['applicationProfile']:
|
|
if (virt_srvr['applicationProfileId']
|
|
== app_prof['applicationProfileId']):
|
|
a_p = NsxvLBAppProfile(
|
|
app_prof['name'],
|
|
app_prof['serverSslEnabled'],
|
|
app_prof['sslPassthrough'],
|
|
app_prof['template'],
|
|
app_prof['insertXForwardedFor'])
|
|
|
|
if app_prof.get('persistence'):
|
|
a_p.set_persistence(
|
|
True,
|
|
app_prof['persistence']['method'],
|
|
app_prof['persistence'].get('cookieName'),
|
|
app_prof['persistence'].get('cookieMode'),
|
|
app_prof['persistence'].get('expire'))
|
|
|
|
v_s.set_app_profile(a_p)
|
|
|
|
# Find default pool, attach to virtual server
|
|
for pool in edge_lb['pool']:
|
|
if virt_srvr['defaultPoolId'] == pool['poolId']:
|
|
p = NsxvLBPool(
|
|
pool['name'],
|
|
pool['algorithm'],
|
|
pool['transparent'])
|
|
|
|
# Add pool members to pool
|
|
for member in pool['member']:
|
|
m = NsxvLBPoolMember(
|
|
member['name'],
|
|
member['ipAddress'],
|
|
member['port'],
|
|
member['monitorPort'],
|
|
member['condition'],
|
|
member['weight'],
|
|
member['minConn'],
|
|
member['maxConn'])
|
|
|
|
p.add_member(m)
|
|
|
|
# Add monitors to pool
|
|
for mon in edge_lb['monitor']:
|
|
if mon['monitorId'] in pool['monitorId']:
|
|
m = NsxvLBMonitor(
|
|
mon['name'],
|
|
mon['interval'],
|
|
mon['maxRetries'],
|
|
mon['method'],
|
|
mon['timeout'],
|
|
mon['type'],
|
|
mon['url'])
|
|
|
|
p.add_monitor(m)
|
|
|
|
v_s.set_default_pool(p)
|
|
|
|
# Add application rules to virtual server
|
|
for rule in edge_lb['applicationRule']:
|
|
if rule['applicationRuleId'] in virt_srvr['applicationRuleId']:
|
|
r = NsxvLBAppRule(
|
|
rule['name'],
|
|
rule['script'])
|
|
|
|
v_s.add_app_rule(r)
|
|
|
|
lb_obj.add_virtual_server(v_s)
|
|
|
|
return lb_obj
|
|
|
|
|
|
class NsxvLBAppProfile(object):
|
|
def __init__(
|
|
self,
|
|
name,
|
|
server_ssl_enabled=False,
|
|
ssl_pass_through=False,
|
|
template='TCP',
|
|
insert_xff=False,
|
|
client_ssl_cert=None,
|
|
persist=False,
|
|
persist_method='cookie',
|
|
persist_cookie_name='JSESSIONID',
|
|
persist_cookie_mode='insert',
|
|
persist_expire=30):
|
|
self.payload = {
|
|
'name': name,
|
|
'serverSslEnabled': server_ssl_enabled,
|
|
'sslPassthrough': ssl_pass_through,
|
|
'template': template,
|
|
'insertXForwardedFor': insert_xff}
|
|
|
|
if persist:
|
|
self.payload['persistence'] = {
|
|
'method': persist_method,
|
|
'expire': persist_expire
|
|
}
|
|
if persist_cookie_mode == 'cookie':
|
|
self.payload['persistence']['cookieMode'] = persist_cookie_mode
|
|
self.payload['persistence']['cookieName'] = persist_cookie_name
|
|
|
|
if client_ssl_cert:
|
|
self.payload['clientSsl'] = {
|
|
'clientAuth': 'ignore',
|
|
'serviceCertificate': [client_ssl_cert]
|
|
}
|
|
|
|
def set_persistence(
|
|
self,
|
|
persist=False,
|
|
persist_method='cookie',
|
|
persist_cookie_name='JSESSIONID',
|
|
persist_cookie_mode='insert',
|
|
persist_expire=30):
|
|
|
|
if persist:
|
|
self.payload['persistence'] = {
|
|
'method': persist_method,
|
|
'expire': persist_expire
|
|
}
|
|
if persist_cookie_mode == 'cookie':
|
|
self.payload['persistence']['cookieMode'] = persist_cookie_mode
|
|
self.payload['persistence']['cookieName'] = persist_cookie_name
|
|
|
|
else:
|
|
self.payload.pop('persistence', None)
|
|
|
|
|
|
class NsxvLBAppRule(object):
|
|
def __init__(self, name, script):
|
|
self.payload = {
|
|
'name': name,
|
|
'script': script}
|
|
|
|
|
|
class NsxvLBVirtualServer(object):
|
|
def __init__(
|
|
self,
|
|
name,
|
|
ip_address,
|
|
port=80,
|
|
protocol='HTTP',
|
|
enabled=True,
|
|
acceleration_enabled=False,
|
|
connection_limit=0,
|
|
enable_service_insertion=False):
|
|
self.payload = {
|
|
'name': name,
|
|
'ipAddress': ip_address,
|
|
'port': port,
|
|
'protocol': protocol,
|
|
'enabled': enabled,
|
|
'accelerationEnabled': acceleration_enabled,
|
|
'connectionLimit': connection_limit,
|
|
'enableServiceInsertion': enable_service_insertion}
|
|
|
|
self.app_rules = {}
|
|
self.app_profile = None
|
|
self.default_pool = None
|
|
|
|
def add_app_rule(self, app_rule):
|
|
self.app_rules[app_rule.payload['name']] = app_rule
|
|
|
|
def del_app_rule(self, name):
|
|
self.app_rules.pop(name, None)
|
|
|
|
def set_default_pool(self, pool):
|
|
self.default_pool = pool
|
|
|
|
def set_app_profile(self, app_profile):
|
|
self.app_profile = app_profile
|
|
|
|
|
|
class NsxvLBMonitor(object):
|
|
def __init__(
|
|
self,
|
|
name,
|
|
interval=10,
|
|
max_retries=3,
|
|
method='GET',
|
|
timeout=15,
|
|
mon_type='http',
|
|
url='/'):
|
|
self.payload = {
|
|
'name': name,
|
|
'interval': interval,
|
|
'maxRetries': max_retries,
|
|
'method': method,
|
|
'timeout': timeout,
|
|
'type': mon_type,
|
|
'url': url}
|
|
|
|
|
|
class NsxvLBPoolMember(object):
|
|
def __init__(
|
|
self,
|
|
name,
|
|
ip_address,
|
|
port,
|
|
monitor_port=None,
|
|
condition='enabled',
|
|
weight=1,
|
|
min_conn=0,
|
|
max_conn=0):
|
|
|
|
self.payload = {
|
|
'name': name,
|
|
'ipAddress': ip_address,
|
|
'port': port,
|
|
'monitorPort': monitor_port,
|
|
'condition': condition,
|
|
'weight': weight,
|
|
'minConn': min_conn,
|
|
'maxConn': max_conn}
|
|
|
|
|
|
class NsxvLBPool(object):
|
|
def __init__(
|
|
self,
|
|
name,
|
|
algorithm='round-robin',
|
|
transparent=False):
|
|
self.payload = {
|
|
'name': name,
|
|
'algorithm': algorithm,
|
|
'transparent': transparent}
|
|
|
|
self.members = {}
|
|
self.monitors = {}
|
|
|
|
def add_member(self, member):
|
|
self.members[member.payload['name']] = member
|
|
|
|
def del_member(self, name):
|
|
self.members.pop(name, None)
|
|
|
|
def add_monitor(self, monitor):
|
|
self.monitors[monitor.payload['name']] = monitor
|
|
|
|
def del_monitor(self, name):
|
|
self.monitors.pop(name, None)
|