diff --git a/devstack/lib/vmware_nsx_v b/devstack/lib/vmware_nsx_v index ef3b9ebedb..0b0074d26f 100644 --- a/devstack/lib/vmware_nsx_v +++ b/devstack/lib/vmware_nsx_v @@ -84,6 +84,8 @@ function neutron_plugin_configure_service { _nsxv_ini_set vdn_scope_id "$NSXV_VDN_SCOPE_ID" _nsxv_ini_set dvs_id "$NSXV_DVS_ID" _nsxv_ini_set manager_uri "$NSXV_MANAGER_URI" + _nsxv_ini_set ca_file "$NSXV_CA_FILE" + _nsxv_ini_set insecure "$NSXV_INSECURE" _nsxv_ini_set datacenter_moid "$NSXV_DATACENTER_MOID" _nsxv_ini_set datastore_id "$NSXV_DATASTORE_ID" _nsxv_ini_set resource_pool_id "$NSXV_RESOURCE_POOL_ID" diff --git a/vmware_nsx/etc/nsx.ini b/vmware_nsx/etc/nsx.ini index 560cebccfb..24ce95f71d 100644 --- a/vmware_nsx/etc/nsx.ini +++ b/vmware_nsx/etc/nsx.ini @@ -58,6 +58,14 @@ # Password for NSXv manager # password = default +# Specify a CA bundle file to use in verifying the NSXv server certificate. +# ca_file = + +# If true, the NSXv server certificate is not verified. If false, +# then the default CA truststore is used for verification. This option +# is ignored if "ca_file" is set. +# insecure = true + # (Required) Datacenter ID for Edge deployment # datacenter_moid = diff --git a/vmware_nsx/neutron/plugins/vmware/common/config.py b/vmware_nsx/neutron/plugins/vmware/common/config.py index bea9e24108..1de0160ce0 100644 --- a/vmware_nsx/neutron/plugins/vmware/common/config.py +++ b/vmware_nsx/neutron/plugins/vmware/common/config.py @@ -206,6 +206,15 @@ nsxv_opts = [ cfg.StrOpt('manager_uri', deprecated_group="vcns", help=_('uri for vsm')), + cfg.StrOpt('ca_file', + help='Specify a CA bundle file to use in verifying the NSXv ' + 'server certificate.'), + cfg.BoolOpt('insecure', + default=True, + help='If true, the NSXv server certificate is not verified. ' + 'If false, then the default CA truststore is used for ' + 'verification. This option is ignored if "ca_file" is ' + 'set.'), cfg.ListOpt('cluster_moid', default=[], help=_('Parameter listing the IDs of the clusters ' diff --git a/vmware_nsx/neutron/plugins/vmware/vshield/common/VcnsApiClient.py b/vmware_nsx/neutron/plugins/vmware/vshield/common/VcnsApiClient.py index 2f26b455b8..b67603428e 100644 --- a/vmware_nsx/neutron/plugins/vmware/vshield/common/VcnsApiClient.py +++ b/vmware_nsx/neutron/plugins/vmware/vshield/common/VcnsApiClient.py @@ -73,7 +73,8 @@ class VcnsApiHelper(object): 503: exceptions.ServiceUnavailable } - def __init__(self, address, user, password, format='json'): + def __init__(self, address, user, password, format='json', ca_file=None, + insecure=True): self.authToken = base64.encodestring(six.b("%s:%s" % (user, password))) self.user = user self.passwd = password @@ -83,12 +84,18 @@ class VcnsApiHelper(object): self.encode = jsonutils.dumps else: self.encode = xmldumps + self.ca_file = ca_file + self.insecure = insecure def request(self, method, uri, params=None, headers=None, encodeparams=True): uri = self.address + uri http = httplib2.Http() - http.disable_ssl_certificate_validation = True + if self.ca_file is not None: + http.ca_certs = self.ca_file + http.disable_ssl_certificate_validation = False + else: + http.disable_ssl_certificate_validation = self.insecure if headers is None: headers = {} diff --git a/vmware_nsx/neutron/plugins/vmware/vshield/vcns.py b/vmware_nsx/neutron/plugins/vmware/vshield/vcns.py index 1ea73a3b36..c37a077e1f 100644 --- a/vmware_nsx/neutron/plugins/vmware/vshield/vcns.py +++ b/vmware_nsx/neutron/plugins/vmware/vshield/vcns.py @@ -72,14 +72,22 @@ def retry_upon_exception(exc, delay=500, max_delay=2000, class Vcns(object): - def __init__(self, address, user, password): + def __init__(self, address, user, password, ca_file, insecure): self.address = address self.user = user self.password = password + self.ca_file = ca_file + self.insecure = insecure self.jsonapi_client = VcnsApiClient.VcnsApiHelper(address, user, - password, 'json') + password, + format='json', + ca_file=ca_file, + insecure=insecure) self.xmlapi_client = VcnsApiClient.VcnsApiHelper(address, user, - password, 'xml') + password, + format='xml', + ca_file=ca_file, + insecure=insecure) @retry_upon_exception(exceptions.ServiceConflict) def _client_request(self, client, method, uri, diff --git a/vmware_nsx/neutron/plugins/vmware/vshield/vcns_driver.py b/vmware_nsx/neutron/plugins/vmware/vshield/vcns_driver.py index dfc5a23399..46c5e57a44 100644 --- a/vmware_nsx/neutron/plugins/vmware/vshield/vcns_driver.py +++ b/vmware_nsx/neutron/plugins/vmware/vshield/vcns_driver.py @@ -38,13 +38,16 @@ class VcnsDriver(edge_appliance_driver.EdgeApplianceDriver, self.vcns_uri = cfg.CONF.nsxv.manager_uri self.vcns_user = cfg.CONF.nsxv.user self.vcns_passwd = cfg.CONF.nsxv.password + self.ca_file = cfg.CONF.nsxv.ca_file + self.insecure = cfg.CONF.nsxv.insecure self.datacenter_moid = cfg.CONF.nsxv.datacenter_moid self.deployment_container_id = cfg.CONF.nsxv.deployment_container_id self.resource_pool_id = cfg.CONF.nsxv.resource_pool_id self.datastore_id = cfg.CONF.nsxv.datastore_id self.external_network = cfg.CONF.nsxv.external_network self._task_manager = None - self.vcns = vcns.Vcns(self.vcns_uri, self.vcns_user, self.vcns_passwd) + self.vcns = vcns.Vcns(self.vcns_uri, self.vcns_user, self.vcns_passwd, + self.ca_file, self.insecure) @property def task_manager(self): diff --git a/vmware_nsx/neutron/tests/unit/vmware/nsx_v/test_nsxv_loadbalancer.py b/vmware_nsx/neutron/tests/unit/vmware/nsx_v/test_nsxv_loadbalancer.py index f61cbe33cf..a09602f17e 100644 --- a/vmware_nsx/neutron/tests/unit/vmware/nsx_v/test_nsxv_loadbalancer.py +++ b/vmware_nsx/neutron/tests/unit/vmware/nsx_v/test_nsxv_loadbalancer.py @@ -74,7 +74,7 @@ class NsxvLoadbalancerTestCase(base.BaseTestCase): def setUp(self): super(NsxvLoadbalancerTestCase, self).setUp() self._lb = nsxv_loadbalancer.NsxvLoadbalancer() - self._vcns = vcns.Vcns(None, None, None) + self._vcns = vcns.Vcns(None, None, None, None, True) def test_get_edge_loadbalancer(self): h = None