Merge "NSX|V3 support different credentials for the NSX manages"
This commit is contained in:
commit
a3b17e2441
@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
prelude: >
|
||||||
|
The NSX-v3 plugin supports different credentials for the NSX managers.
|
||||||
|
features:
|
||||||
|
The nsxv3 configuration parameters ca_file, nsx_api_user & nsx_api_password
|
||||||
|
are now lists, in order to support different credentials for each of the
|
||||||
|
NSX managers.
|
@ -246,15 +246,15 @@ nsx_common_opts = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
nsx_v3_opts = [
|
nsx_v3_opts = [
|
||||||
cfg.StrOpt('nsx_api_user',
|
cfg.ListOpt('nsx_api_user',
|
||||||
deprecated_name='nsx_user',
|
deprecated_name='nsx_user',
|
||||||
default='admin',
|
default=['admin'],
|
||||||
help=_('User name for the NSX manager')),
|
help=_('User names for the NSX managers')),
|
||||||
cfg.StrOpt('nsx_api_password',
|
cfg.ListOpt('nsx_api_password',
|
||||||
deprecated_name='nsx_password',
|
deprecated_name='nsx_password',
|
||||||
default='default',
|
default=['default'],
|
||||||
secret=True,
|
secret=True,
|
||||||
help=_('Password for the NSX manager')),
|
help=_('Passwords for the NSX managers')),
|
||||||
cfg.ListOpt('nsx_api_managers',
|
cfg.ListOpt('nsx_api_managers',
|
||||||
default=[],
|
default=[],
|
||||||
deprecated_name='nsx_manager',
|
deprecated_name='nsx_manager',
|
||||||
@ -291,10 +291,10 @@ nsx_v3_opts = [
|
|||||||
default=10,
|
default=10,
|
||||||
help=_('Maximum number of times to retry API requests upon '
|
help=_('Maximum number of times to retry API requests upon '
|
||||||
'stale revision errors.')),
|
'stale revision errors.')),
|
||||||
cfg.StrOpt('ca_file',
|
cfg.ListOpt('ca_file',
|
||||||
help=_('Specify a CA bundle file to use in verifying the NSX '
|
help=_('Specify a CA bundle files to use in verifying the NSX '
|
||||||
'Manager server certificate. This option is ignored if '
|
'Managers server certificate. This option is ignored '
|
||||||
'"insecure" is set to True. If "insecure" is set to '
|
'if "insecure" is set to True. If "insecure" is set to '
|
||||||
'False and ca_file is unset, the system root CAs will '
|
'False and ca_file is unset, the system root CAs will '
|
||||||
'be used to verify the server certificate.')),
|
'be used to verify the server certificate.')),
|
||||||
cfg.BoolOpt('insecure',
|
cfg.BoolOpt('insecure',
|
||||||
|
@ -124,14 +124,14 @@ class NSXRequestsHTTPProvider(AbstractHTTPProvider):
|
|||||||
def new_connection(self, cluster_api, provider):
|
def new_connection(self, cluster_api, provider):
|
||||||
session = TimeoutSession(cluster_api.http_timeout,
|
session = TimeoutSession(cluster_api.http_timeout,
|
||||||
cluster_api.http_read_timeout)
|
cluster_api.http_read_timeout)
|
||||||
session.auth = (cluster_api.username, cluster_api.password)
|
session.auth = (provider.username, provider.password)
|
||||||
# NSX v3 doesn't use redirects
|
# NSX v3 doesn't use redirects
|
||||||
session.max_redirects = 0
|
session.max_redirects = 0
|
||||||
|
|
||||||
session.verify = not cluster_api.insecure
|
session.verify = not cluster_api.insecure
|
||||||
if session.verify and cluster_api.ca_file:
|
if session.verify and provider.ca_file:
|
||||||
# verify using the said ca bundle path
|
# verify using the said ca bundle path
|
||||||
session.verify = cluster_api.ca_file
|
session.verify = provider.ca_file
|
||||||
|
|
||||||
# we are pooling with eventlet in the cluster class
|
# we are pooling with eventlet in the cluster class
|
||||||
adapter = adapters.HTTPAdapter(
|
adapter = adapters.HTTPAdapter(
|
||||||
@ -172,12 +172,15 @@ class EndpointState(object):
|
|||||||
|
|
||||||
class Provider(object):
|
class Provider(object):
|
||||||
"""Data holder for a provider which has a unique id
|
"""Data holder for a provider which has a unique id
|
||||||
and a connection URL.
|
a connection URL, and the credential details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, provider_id, provider_url):
|
def __init__(self, provider_id, provider_url, username, password, ca_file):
|
||||||
self.id = provider_id
|
self.id = provider_id
|
||||||
self.url = provider_url
|
self.url = provider_url
|
||||||
|
self.username = username
|
||||||
|
self.password = password
|
||||||
|
self.ca_file = ca_file
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return str(self.url)
|
return str(self.url)
|
||||||
@ -459,11 +462,15 @@ class NSXClusteredAPI(ClusteredAPI):
|
|||||||
http_read_timeout=None,
|
http_read_timeout=None,
|
||||||
conn_idle_timeout=None,
|
conn_idle_timeout=None,
|
||||||
http_provider=None):
|
http_provider=None):
|
||||||
self.username = username or cfg.CONF.nsx_v3.nsx_api_user
|
|
||||||
self.password = password or cfg.CONF.nsx_v3.nsx_api_password
|
|
||||||
self.retries = retries or cfg.CONF.nsx_v3.http_retries
|
self.retries = retries or cfg.CONF.nsx_v3.http_retries
|
||||||
self.insecure = insecure or cfg.CONF.nsx_v3.insecure
|
self.insecure = insecure or cfg.CONF.nsx_v3.insecure
|
||||||
self.ca_file = ca_file or cfg.CONF.nsx_v3.ca_file
|
|
||||||
|
# username, password & ca_file may be lists, in order to support
|
||||||
|
# different credentials per nsx manager
|
||||||
|
self._username = username or cfg.CONF.nsx_v3.nsx_api_user
|
||||||
|
self._password = password or cfg.CONF.nsx_v3.nsx_api_password
|
||||||
|
self._ca_file = ca_file or cfg.CONF.nsx_v3.ca_file
|
||||||
|
|
||||||
self.conns_per_pool = (concurrent_connections or
|
self.conns_per_pool = (concurrent_connections or
|
||||||
cfg.CONF.nsx_v3.concurrent_connections)
|
cfg.CONF.nsx_v3.concurrent_connections)
|
||||||
self.http_timeout = http_timeout or cfg.CONF.nsx_v3.http_timeout
|
self.http_timeout = http_timeout or cfg.CONF.nsx_v3.http_timeout
|
||||||
@ -494,14 +501,40 @@ class NSXClusteredAPI(ClusteredAPI):
|
|||||||
conf_urls = cfg.CONF.nsx_v3.nsx_api_managers[:]
|
conf_urls = cfg.CONF.nsx_v3.nsx_api_managers[:]
|
||||||
urls = []
|
urls = []
|
||||||
providers = []
|
providers = []
|
||||||
|
provider_index = -1
|
||||||
for conf_url in conf_urls:
|
for conf_url in conf_urls:
|
||||||
|
provider_index += 1
|
||||||
conf_url = _schemed_url(conf_url)
|
conf_url = _schemed_url(conf_url)
|
||||||
if conf_url in urls:
|
if conf_url in urls:
|
||||||
LOG.warning(_LW("'%s' already defined in configuration file. "
|
LOG.warning(_LW("'%s' already defined in configuration file. "
|
||||||
"Skipping."), urlparse.urlunparse(conf_url))
|
"Skipping."), urlparse.urlunparse(conf_url))
|
||||||
continue
|
continue
|
||||||
urls.append(conf_url)
|
urls.append(conf_url)
|
||||||
providers.append(Provider(
|
providers.append(
|
||||||
conf_url.netloc, urlparse.urlunparse(conf_url)))
|
Provider(
|
||||||
|
conf_url.netloc,
|
||||||
|
urlparse.urlunparse(conf_url),
|
||||||
|
self.username(provider_index),
|
||||||
|
self.password(provider_index),
|
||||||
|
self.ca_file(provider_index)))
|
||||||
return providers
|
return providers
|
||||||
|
|
||||||
|
def _attribute_by_index(self, scalar_or_list, index):
|
||||||
|
if isinstance(scalar_or_list, list):
|
||||||
|
if not len(scalar_or_list):
|
||||||
|
return None
|
||||||
|
if len(scalar_or_list) > index:
|
||||||
|
return scalar_or_list[index]
|
||||||
|
# if not long enough - use the first one as default
|
||||||
|
return scalar_or_list[0]
|
||||||
|
# this is a scalar
|
||||||
|
return scalar_or_list
|
||||||
|
|
||||||
|
def username(self, index):
|
||||||
|
return self._attribute_by_index(self._username, index)
|
||||||
|
|
||||||
|
def password(self, index):
|
||||||
|
return self._attribute_by_index(self._password, index)
|
||||||
|
|
||||||
|
def ca_file(self, index):
|
||||||
|
return self._attribute_by_index(self._ca_file, index)
|
||||||
|
@ -39,16 +39,17 @@ class RequestsHTTPProviderTestCase(unittest.TestCase):
|
|||||||
|
|
||||||
def test_new_connection(self):
|
def test_new_connection(self):
|
||||||
mock_api = mock.Mock()
|
mock_api = mock.Mock()
|
||||||
mock_api.username = 'nsxuser'
|
mock_api._username = 'nsxuser'
|
||||||
mock_api.password = 'nsxpassword'
|
mock_api._password = 'nsxpassword'
|
||||||
mock_api.retries = 100
|
mock_api.retries = 100
|
||||||
mock_api.insecure = True
|
mock_api.insecure = True
|
||||||
mock_api.ca_file = None
|
mock_api._ca_file = None
|
||||||
mock_api.http_timeout = 99
|
mock_api.http_timeout = 99
|
||||||
mock_api.conn_idle_timeout = 39
|
mock_api.conn_idle_timeout = 39
|
||||||
provider = cluster.NSXRequestsHTTPProvider()
|
provider = cluster.NSXRequestsHTTPProvider()
|
||||||
session = provider.new_connection(
|
session = provider.new_connection(
|
||||||
mock_api, cluster.Provider('9.8.7.6', 'https://9.8.7.6'))
|
mock_api, cluster.Provider('9.8.7.6', 'https://9.8.7.6',
|
||||||
|
'nsxuser', 'nsxpassword', None))
|
||||||
|
|
||||||
self.assertEqual(session.auth, ('nsxuser', 'nsxpassword'))
|
self.assertEqual(session.auth, ('nsxuser', 'nsxpassword'))
|
||||||
self.assertEqual(session.verify, False)
|
self.assertEqual(session.verify, False)
|
||||||
|
Loading…
Reference in New Issue
Block a user