diff --git a/neutron_plugin_contrail/plugins/opencontrail/agent/contrail_vif_driver.py b/neutron_plugin_contrail/plugins/opencontrail/agent/contrail_vif_driver.py index 2b657a1..3012669 100644 --- a/neutron_plugin_contrail/plugins/opencontrail/agent/contrail_vif_driver.py +++ b/neutron_plugin_contrail/plugins/opencontrail/agent/contrail_vif_driver.py @@ -54,6 +54,8 @@ def _parse_class_args(cls, cfg_parser): 'api_server_ip', '127.0.0.1') cls._api_server_port = _read_cfg(cfg_parser, 'APISERVER', 'api_server_port', '8082') + cls._api_server_use_ssl = _read_cfg(cfg_parser, 'APISERVER', + 'use_ssl', False) def __init__(self, conf): super(ContrailInterfaceDriver, self).__init__(conf) @@ -68,7 +70,8 @@ def _connect_to_api_server(self): ContrailInterfaceDriver._parse_class_args(cfg_parser) try: client = VncApi(api_server_host=self._api_server_ip, - api_server_port=self._api_server_port) + api_server_port=self._api_server_port, + api_server_use_ssl=self._api_server_use_ssl) return client except: pass diff --git a/neutron_plugin_contrail/plugins/opencontrail/contrail_plugin.py b/neutron_plugin_contrail/plugins/opencontrail/contrail_plugin.py index ed07e0a..49b7ec8 100644 --- a/neutron_plugin_contrail/plugins/opencontrail/contrail_plugin.py +++ b/neutron_plugin_contrail/plugins/opencontrail/contrail_plugin.py @@ -43,9 +43,15 @@ from oslo_log import log as logging from simplejson import JSONDecodeError +from cfgm_common import utils as cfgmutils LOG = logging.getLogger(__name__) +_DEFAULT_KS_CERT_BUNDLE="/tmp/keystonecertbundle.pem" +_DEFAULT_API_CERT_BUNDLE="/tmp/apiservercertbundle.pem" +_DEFAULT_SERVER_CONNECT="http" +_DEFAULT_SECURE_SERVER_CONNECT="https" + vnc_opts = [ cfg.StrOpt('api_server_ip', default='127.0.0.1', help='IP address to connect to VNC controller'), @@ -53,6 +59,16 @@ help='Port to connect to VNC controller'), cfg.DictOpt('contrail_extensions', default={}, help='Enable Contrail extensions(policy, ipam)'), + cfg.BoolOpt('use_ssl', default=False, + help='Use SSL to connect with VNC controller'), + cfg.BoolOpt('insecure', default=False, + help='Insecurely connect to VNC controller'), + cfg.StrOpt('certfile', default='', + help='certfile to connect securely to VNC controller'), + cfg.StrOpt('keyfile', default='', + help='keyfile to connect securely to VNC controller'), + cfg.StrOpt('cafile', default='', + help='cafile to connect securely to VNC controller'), ] analytics_opts = [ @@ -132,6 +148,37 @@ def _parse_class_args(self): cfg.CONF.keystone_authtoken.auth_port, "/v2.0/tokens") + #Keystone SSL Support + self._ksinsecure=cfg.CONF.keystone_authtoken.insecure + kscertfile=cfg.CONF.keystone_authtoken.certfile + kskeyfile=cfg.CONF.keystone_authtoken.keyfile + kscafile=cfg.CONF.keystone_authtoken.cafile + + self._use_ks_certs=False + if kscertfile and kskeyfile and kscafile \ + and cfg.CONF.keystone_authtoken.auth_protocol == _DEFAULT_SECURE_SERVER_CONNECT: + certs=[kscertfile, kskeyfile, kscafile] + self._kscertbundle=cfgmutils.getCertKeyCaBundle(_DEFAULT_KS_CERT_BUNDLE,certs) + self._use_ks_certs=True + + #API Server SSL support + self._apiusessl=cfg.CONF.APISERVER.use_ssl + self._apiinsecure=cfg.CONF.APISERVER.insecure + apicertfile=cfg.CONF.APISERVER.certfile + apikeyfile=cfg.CONF.APISERVER.keyfile + apicafile=cfg.CONF.APISERVER.cafile + + if self._apiusessl: + self._apiserverconnect=_DEFAULT_SECURE_SERVER_CONNECT + else: + self._apiserverconnect=_DEFAULT_SERVER_CONNECT + + self._use_api_certs=False + if apicertfile and apikeyfile and apicafile and self._apiusessl: + certs=[apicertfile, apikeyfile, apicafile] + self._apicertbundle=cfgmutils.getCertKeyCaBundle(_DEFAULT_API_CERT_BUNDLE,certs) + self._use_api_certs=True + def __init__(self): super(NeutronPluginContrailCoreV2, self).__init__() portbindings_base.register_port_dict_function() @@ -161,12 +208,26 @@ def get_agents(self, context, filters=None, fields=None): def _request_api_server(self, url, data=None, headers=None): # Attempt to post to Api-Server - response = requests.post(url, data=data, headers=headers) + if self._apiinsecure: + response = requests.post(url, data=data, headers=headers,verify=False) + elif not self._apiinsecure and self._use_api_certs: + response = requests.post(url, data=data, headers=headers,verify=self._apicertbundle) + else: + response = requests.post(url, data=data, headers=headers) if (response.status_code == requests.codes.unauthorized): # Get token from keystone and save it for next request - response = requests.post(self._keystone_url, - data=self._authn_body, - headers={'Content-type': 'application/json'}) + if self._ksinsecure: + response = requests.post(self._keystone_url, + data=self._authn_body, + headers={'Content-type': 'application/json'},verify=False) + elif not self._ksinsecure and self._use_ks_certs: + response = requests.post(self._keystone_url, + data=self._authn_body, + headers={'Content-type': 'application/json'},verify=self._kscertbundle) + else: + response = requests.post(self._keystone_url, + data=self._authn_body, + headers={'Content-type': 'application/json'}) if (response.status_code == requests.codes.ok): # plan is to re-issue original request with new token auth_headers = headers or {} @@ -188,9 +249,10 @@ def _request_api_server_authn(self, url, data=None, headers=None): def _relay_request(self, url_path, data=None): """Send received request to api server.""" - url = "http://%s:%s%s" % (cfg.CONF.APISERVER.api_server_ip, - cfg.CONF.APISERVER.api_server_port, - url_path) + url = "%s://%s:%s%s" % (self._apiserverconnect, + cfg.CONF.APISERVER.api_server_ip, + cfg.CONF.APISERVER.api_server_port, + url_path) return self._request_api_server_authn( url, data=data, headers={'Content-type': 'application/json'}) diff --git a/neutron_plugin_contrail/plugins/opencontrail/loadbalancer/loadbalancer_db.py b/neutron_plugin_contrail/plugins/opencontrail/loadbalancer/loadbalancer_db.py index 5cabff4..76b38fa 100644 --- a/neutron_plugin_contrail/plugins/opencontrail/loadbalancer/loadbalancer_db.py +++ b/neutron_plugin_contrail/plugins/opencontrail/loadbalancer/loadbalancer_db.py @@ -28,6 +28,7 @@ def __init__(self): admin_tenant_name = cfg.CONF.keystone_authtoken.admin_tenant_name api_srvr_ip = cfg.CONF.APISERVER.api_server_ip api_srvr_port = cfg.CONF.APISERVER.api_server_port + api_srvr_use_ssl= cfg.CONF.APISERVER.use_ssl try: auth_host = cfg.CONF.keystone_authtoken.auth_host except cfg.NoSuchOptError: @@ -67,7 +68,8 @@ def __init__(self): api_srvr_ip, api_srvr_port, api_server_url, auth_host=auth_host, auth_port=auth_port, auth_protocol=auth_protocol, auth_url=auth_url, - auth_type=auth_type, wait_for_connect=True) + auth_type=auth_type, wait_for_connect=True, + api_server_use_ssl=api_srvr_use_ssl) connected = True except requests.exceptions.RequestException as e: time.sleep(3) diff --git a/neutron_plugin_contrail/plugins/opencontrail/quota/driver.py b/neutron_plugin_contrail/plugins/opencontrail/quota/driver.py index 8f2f283..4e79712 100644 --- a/neutron_plugin_contrail/plugins/opencontrail/quota/driver.py +++ b/neutron_plugin_contrail/plugins/opencontrail/quota/driver.py @@ -62,7 +62,8 @@ def _get_vnc_conn(cls): cfg.CONF.APISERVER.api_server_port, auth_host=cfg.CONF.keystone_authtoken.auth_host, auth_port=cfg.CONF.keystone_authtoken.auth_port, - auth_protocol=cfg.CONF.keystone_authtoken.auth_protocol) + auth_protocol=cfg.CONF.keystone_authtoken.auth_protocol, + api_server_use_ssl=cfg.CONF.APISERVER.use_ssl) return vnc_conn except requests.exceptions.RequestException as e: time.sleep(3)