Skip to content

Commit

Permalink
Adds ability to configure various clients used by the Heat
Browse files Browse the repository at this point in the history
This commit adds config sections [clients_nova], [clients_swift],
[clients_neutron], [clients_cinder], [clients_ceilometer] and
[clients_keystone]. These sections contain additional configuration
options for corresponding OpenStack clients.
Currently those are only SSL-related setting ca_file, cert_file,
key_file and insecure. Note, than not every client library is
currently capable of utilizing all of the SSL settings.

There is also a plain [clients] section that holds shared client
options. Each option searched first at specific group (clients_xxx)
and if it not found there then the value from [clients] group
are taken (or default values if there is no such setting in this
group). This allows defining shared configuration that would be
used by most (or all) clients without repeating the same settings
for each and every client separately

Closes-Bug: #1213122
Implements: blueprint clients-ssl-options

Change-Id: Id9ccbffce0d5c266202fdb1cf24a9ffb63e507e6
  • Loading branch information
Stan Lagun committed Nov 22, 2013
1 parent bca4b68 commit 838bdfc
Show file tree
Hide file tree
Showing 5 changed files with 268 additions and 25 deletions.
182 changes: 168 additions & 14 deletions etc/heat/heat.conf.sample
Expand Up @@ -465,6 +465,43 @@
#matchmaker_heartbeat_ttl=600


[clients_swift]

#
# Options defined in heat.common.config
#

# Optional CA cert file to use in SSL connections (string
# value)
#ca_file=<None>

# Optional PEM-formatted certificate chain file (string value)
#cert_file=<None>

# Optional PEM-formatted file that contains the private key
# (string value)
#key_file=<None>

# If set then the server's certificate will not be verified
# (boolean value)
#insecure=false


[auth_password]

#
# Options defined in heat.common.config
#

# Allow orchestration of multiple clouds (boolean value)
#multi_cloud=false

# Allowed keystone endpoints for auth_uri when multi_cloud is
# enabled. At least one endpoint needs to be specified. (list
# value)
#allowed_auth_uris=


[ssl]

#
Expand Down Expand Up @@ -560,6 +597,104 @@
#api_paste_config=api-paste.ini


[clients_cinder]

#
# Options defined in heat.common.config
#

# Optional CA cert file to use in SSL connections (string
# value)
#ca_file=<None>

# Optional PEM-formatted certificate chain file (string value)
#cert_file=<None>

# Optional PEM-formatted file that contains the private key
# (string value)
#key_file=<None>

# If set then the server's certificate will not be verified
# (boolean value)
#insecure=false


[clients]

#
# Options defined in heat.common.config
#

# Optional CA cert file to use in SSL connections (string
# value)
#ca_file=<None>

# Optional PEM-formatted certificate chain file (string value)
#cert_file=<None>

# Optional PEM-formatted file that contains the private key
# (string value)
#key_file=<None>

# If set then the server's certificate will not be verified
# (boolean value)
#insecure=false


[clients_nova]

#
# Options defined in heat.common.config
#

# Optional CA cert file to use in SSL connections (string
# value)
#ca_file=<None>

# Optional PEM-formatted certificate chain file (string value)
#cert_file=<None>

# Optional PEM-formatted file that contains the private key
# (string value)
#key_file=<None>

# If set then the server's certificate will not be verified
# (boolean value)
#insecure=false


[matchmaker_ring]

#
# Options defined in heat.openstack.common.rpc.matchmaker_ring
#

# Matchmaker ring file (JSON) (string value)
#ringfile=/etc/oslo/matchmaker_ring.json


[clients_ceilometer]

#
# Options defined in heat.common.config
#

# Optional CA cert file to use in SSL connections (string
# value)
#ca_file=<None>

# Optional PEM-formatted certificate chain file (string value)
#cert_file=<None>

# Optional PEM-formatted file that contains the private key
# (string value)
#key_file=<None>

# If set then the server's certificate will not be verified
# (boolean value)
#insecure=false


[rpc_notifier2]

#
Expand Down Expand Up @@ -788,29 +923,26 @@
#memcache_secret_key=<None>


[auth_password]
[clients_neutron]

#
# Options defined in heat.common.config
#

# Allow orchestration of multiple clouds (boolean value)
#multi_cloud=false

# Allowed keystone endpoints for auth_uri when multi_cloud is
# enabled. At least one endpoint needs to be specified. (list
# Optional CA cert file to use in SSL connections (string
# value)
#allowed_auth_uris=

#ca_file=<None>

[matchmaker_ring]
# Optional PEM-formatted certificate chain file (string value)
#cert_file=<None>

#
# Options defined in heat.openstack.common.rpc.matchmaker_ring
#
# Optional PEM-formatted file that contains the private key
# (string value)
#key_file=<None>

# Matchmaker ring file (JSON) (string value)
#ringfile=/etc/oslo/matchmaker_ring.json
# If set then the server's certificate will not be verified
# (boolean value)
#insecure=false


[matchmaker_redis]
Expand All @@ -829,3 +961,25 @@
#password=<None>


[clients_keystone]

#
# Options defined in heat.common.config
#

# Optional CA cert file to use in SSL connections (string
# value)
#ca_file=<None>

# Optional PEM-formatted certificate chain file (string value)
#cert_file=<None>

# Optional PEM-formatted file that contains the private key
# (string value)
#key_file=<None>

# If set then the server's certificate will not be verified
# (boolean value)
#insecure=false


28 changes: 27 additions & 1 deletion heat/common/config.py
Expand Up @@ -17,7 +17,7 @@
"""
Routines for configuring Heat
"""

import copy
import logging as sys_logging
import os

Expand Down Expand Up @@ -124,6 +124,31 @@
help=_('Allowed keystone endpoints for auth_uri when '
'multi_cloud is enabled. At least one endpoint needs '
'to be specified.'))]
clients_opts = [
cfg.StrOpt('ca_file',
help=_('Optional CA cert file to use in SSL connections')),
cfg.StrOpt('cert_file',
help=_('Optional PEM-formatted certificate chain file')),
cfg.StrOpt('key_file',
help=_('Optional PEM-formatted file that contains the '
'private key')),
cfg.BoolOpt('insecure',
default=False,
help=_("If set then the server's certificate will not "
"be verified"))]


def register_clients_opts():
cfg.CONF.register_opts(clients_opts, group='clients')
for client in ('nova', 'swift', 'neutron', 'cinder',
'ceilometer', 'keystone'):
client_specific_group = 'clients_' + client
# register opts copy and put it to globals in order to
# generate_sample.sh to work
opts_copy = copy.deepcopy(clients_opts)
globals()[client_specific_group + '_opts'] = opts_copy
cfg.CONF.register_opts(opts_copy, group=client_specific_group)


cfg.CONF.register_opts(engine_opts)
cfg.CONF.register_opts(service_opts)
Expand All @@ -132,6 +157,7 @@
cfg.CONF.register_opts(paste_deploy_opts, group=paste_deploy_group)
cfg.CONF.register_group(auth_password_group)
cfg.CONF.register_opts(auth_password_opts, group=auth_password_group)
register_clients_opts()


def rpc_set_default():
Expand Down
17 changes: 17 additions & 0 deletions heat/common/heat_keystoneclient.py
Expand Up @@ -100,6 +100,10 @@ def _v2_client_init(self):
logger.error("Keystone v2 API connection failed, no password or "
"auth_token!")
raise exception.AuthorizationFailure()
kwargs['cacert'] = self._get_client_option('ca_file')
kwargs['insecure'] = self._get_client_option('insecure')
kwargs['cert'] = self._get_client_option('cert_file')
kwargs['key'] = self._get_client_option('key_file')
client_v2 = kc.Client(**kwargs)

client_v2.authenticate(**auth_kwargs)
Expand Down Expand Up @@ -161,12 +165,25 @@ def _v3_client_init(self):
"auth_token!")
raise exception.AuthorizationFailure()

kwargs['cacert'] = self._get_client_option('ca_file')
kwargs['insecure'] = self._get_client_option('insecure')
kwargs['cert'] = self._get_client_option('cert_file')
kwargs['key'] = self._get_client_option('key_file')
client = kc_v3.Client(**kwargs)
# Have to explicitly authenticate() or client.auth_ref is None
client.authenticate()

return client

def _get_client_option(self, option):
try:
cfg.CONF.import_opt(option, 'heat.common.config',
group='clients_keystone')
return getattr(cfg.CONF.clients_keystone, option)
except (cfg.NoSuchGroupError, cfg.NoSuchOptError):
cfg.CONF.import_opt(option, 'heat.common.config', group='clients')
return getattr(cfg.CONF.clients, option)

def create_trust_context(self):
"""
If cfg.CONF.deferred_auth_method is trusts, we create a
Expand Down
30 changes: 26 additions & 4 deletions heat/engine/clients.py
Expand Up @@ -103,7 +103,9 @@ def nova(self, service_type='compute'):
'service_type': service_type,
'username': None,
'api_key': None,
'extensions': extensions
'extensions': extensions,
'cacert': self._get_client_option('nova', 'ca_file'),
'insecure': self._get_client_option('nova', 'insecure')
}

client = novaclient.Client(1.1, **args)
Expand Down Expand Up @@ -133,7 +135,9 @@ def swift(self):
'key': None,
'authurl': None,
'preauthtoken': self.auth_token,
'preauthurl': self.url_for(service_type='object-store')
'preauthurl': self.url_for(service_type='object-store'),
'cacert': self._get_client_option('swift', 'ca_file'),
'insecure': self._get_client_option('swift', 'insecure')
}
self._swift = swiftclient.Connection(**args)
return self._swift
Expand All @@ -153,7 +157,9 @@ def neutron(self):
'auth_url': con.auth_url,
'service_type': 'network',
'token': self.auth_token,
'endpoint_url': self.url_for(service_type='network')
'endpoint_url': self.url_for(service_type='network'),
'ca_cert': self._get_client_option('neutron', 'ca_file'),
'insecure': self._get_client_option('neutron', 'insecure')
}

self._neutron = neutronclient.Client(**args)
Expand All @@ -176,7 +182,9 @@ def cinder(self):
'auth_url': con.auth_url,
'project_id': con.tenant,
'username': None,
'api_key': None
'api_key': None,
'cacert': self._get_client_option('cinder', 'ca_file'),
'insecure': self._get_client_option('cinder', 'insecure')
}

self._cinder = cinderclient.Client('1', **args)
Expand All @@ -202,13 +210,27 @@ def ceilometer(self):
'project_id': con.tenant,
'token': lambda: self.auth_token,
'endpoint': self.url_for(service_type='metering'),
'ca_file': self._get_client_option('ceilometer', 'ca_file'),
'cert_file': self._get_client_option('ceilometer', 'cert_file'),
'key_file': self._get_client_option('ceilometer', 'key_file'),
'insecure': self._get_client_option('ceilometer', 'insecure')
}

client = ceilometerclient.Client(**args)

self._ceilometer = client
return self._ceilometer

def _get_client_option(self, client, option):
try:
group_name = 'clients_' + client
cfg.CONF.import_opt(option, 'heat.common.config',
group=group_name)
return getattr(getattr(cfg.CONF, group_name), option)
except (cfg.NoSuchGroupError, cfg.NoSuchOptError):
cfg.CONF.import_opt(option, 'heat.common.config', group='clients')
return getattr(cfg.CONF.clients, option)


class ClientBackend(object):
'''Delay choosing the backend client module until the client's class needs
Expand Down

0 comments on commit 838bdfc

Please sign in to comment.