Add heat patches and short README on how to apply them.
Change-Id: Ia1a63cf7ed520e43bb6cd7d9f9e5abb747b484e9
This commit is contained in:
parent
5df216c9c1
commit
8f36087c08
|
@ -0,0 +1,168 @@
|
|||
From 94350f3206d067e7c9012ac5fb4c40555949d95c Mon Sep 17 00:00:00 2001
|
||||
From: Timur Sufiev <tsufiev@mirantis.com>
|
||||
Date: Thu, 5 Dec 2013 19:43:57 +0400
|
||||
Subject: [PATCH] Added support for Allow-Address-Pairs feature
|
||||
|
||||
Added support for feature called Allow-Address-Pairs introduced in
|
||||
Ie73b3886c5be8e1fc4ade86a0cfb854267f345ac
|
||||
|
||||
Implements: blueprint allowed-address-pairs
|
||||
Ported from: icehouse.
|
||||
---
|
||||
heat/engine/resources/neutron/port.py | 19 +++++++-
|
||||
heat/tests/test_neutron.py | 84 +++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 102 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/heat/engine/resources/neutron/port.py b/heat/engine/resources/neutron/port.py
|
||||
index 06c219a..b12b74a 100644
|
||||
--- a/heat/engine/resources/neutron/port.py
|
||||
+++ b/heat/engine/resources/neutron/port.py
|
||||
@@ -29,6 +29,9 @@ class Port(neutron.NeutronResource):
|
||||
fixed_ip_schema = {'subnet_id': {'Type': 'String'},
|
||||
'ip_address': {'Type': 'String'}}
|
||||
|
||||
+ address_pair_schema = {'mac_address': {'Type': 'String'},
|
||||
+ 'ip_address': {'Type': 'String', 'Required': True}}
|
||||
+
|
||||
properties_schema = {'network_id': {'Type': 'String',
|
||||
'Required': True},
|
||||
'name': {'Type': 'String'},
|
||||
@@ -41,7 +44,13 @@ class Port(neutron.NeutronResource):
|
||||
'Schema': fixed_ip_schema}},
|
||||
'mac_address': {'Type': 'String'},
|
||||
'device_id': {'Type': 'String'},
|
||||
- 'security_groups': {'Type': 'List'}}
|
||||
+ 'security_groups': {'Type': 'List'},
|
||||
+ 'allowed_address_pairs': {
|
||||
+ 'Type': 'List',
|
||||
+ 'Schema': {'Type': 'Map',
|
||||
+ 'Schema': address_pair_schema}}
|
||||
+ }
|
||||
+
|
||||
attributes_schema = {
|
||||
"admin_state_up": _("The administrative state of this port."),
|
||||
"device_id": _("Unique identifier for the device."),
|
||||
@@ -53,6 +62,8 @@ class Port(neutron.NeutronResource):
|
||||
"security_groups": _("A list of security groups for the port."),
|
||||
"status": _("The status of the port."),
|
||||
"tenant_id": _("Tenant owning the port"),
|
||||
+ "allowed_address_pairs": _("Additional mac/ip address pairs allowed "
|
||||
+ "to pass through a port"),
|
||||
"show": _("All attributes."),
|
||||
}
|
||||
|
||||
@@ -79,6 +90,12 @@ class Port(neutron.NeutronResource):
|
||||
if value is None:
|
||||
fixed_ip.pop(key)
|
||||
|
||||
+ # delete empty MAC addresses so that Neutron validation code
|
||||
+ # wouldn't fail as it not accepts Nones
|
||||
+ for pair in props.get('allowed_address_pairs', []):
|
||||
+ if 'mac_address' in pair and pair['mac_address'] is None:
|
||||
+ del pair['mac_address']
|
||||
+
|
||||
if self.properties['security_groups']:
|
||||
props['security_groups'] = self.get_secgroup_uuids(
|
||||
self.stack, self.properties, 'security_groups', self.name,
|
||||
diff --git a/heat/tests/test_neutron.py b/heat/tests/test_neutron.py
|
||||
index eb5b295..15d9a2d 100644
|
||||
--- a/heat/tests/test_neutron.py
|
||||
+++ b/heat/tests/test_neutron.py
|
||||
@@ -171,6 +171,26 @@ neutron_port_template = '''
|
||||
}
|
||||
'''
|
||||
|
||||
+neutron_port_with_address_pair_template = '''
|
||||
+{
|
||||
+ "AWSTemplateFormatVersion" : "2010-09-09",
|
||||
+ "Description" : "Template to test Neutron resources",
|
||||
+ "Parameters" : {},
|
||||
+ "Resources" : {
|
||||
+ "port": {
|
||||
+ "Type": "OS::Neutron::Port",
|
||||
+ "Properties": {
|
||||
+ "network_id": "abcd1234",
|
||||
+ "allowed_address_pairs": [{
|
||||
+ "ip_address": "10.0.3.21",
|
||||
+ "mac_address": "00-B0-D0-86-BB-F7"
|
||||
+ }]
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+'''
|
||||
+
|
||||
|
||||
class NeutronTest(HeatTestCase):
|
||||
|
||||
@@ -1147,3 +1167,67 @@ class NeutronPortTest(HeatTestCase):
|
||||
port = stack['port']
|
||||
scheduler.TaskRunner(port.create)()
|
||||
self.m.VerifyAll()
|
||||
+
|
||||
+ def test_allowed_address_pair(self):
|
||||
+ clients.OpenStackClients.keystone().AndReturn(
|
||||
+ fakes.FakeKeystoneClient())
|
||||
+ neutronclient.Client.create_port({'port': {
|
||||
+ 'network_id': u'abcd1234',
|
||||
+ 'allowed_address_pairs': [{
|
||||
+ 'ip_address': u'10.0.3.21',
|
||||
+ 'mac_address': u'00-B0-D0-86-BB-F7'
|
||||
+ }],
|
||||
+ 'name': utils.PhysName('test_stack', 'port'),
|
||||
+ 'admin_state_up': True}}
|
||||
+ ).AndReturn({'port': {
|
||||
+ "status": "BUILD",
|
||||
+ "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
|
||||
+ }})
|
||||
+ neutronclient.Client.show_port(
|
||||
+ 'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
|
||||
+ ).AndReturn({'port': {
|
||||
+ "status": "ACTIVE",
|
||||
+ "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
|
||||
+ }})
|
||||
+
|
||||
+ self.m.ReplayAll()
|
||||
+
|
||||
+ t = template_format.parse(neutron_port_with_address_pair_template)
|
||||
+ stack = utils.parse_stack(t)
|
||||
+
|
||||
+ port = stack['port']
|
||||
+ scheduler.TaskRunner(port.create)()
|
||||
+ self.m.VerifyAll()
|
||||
+
|
||||
+ def test_missing_mac_address(self):
|
||||
+ clients.OpenStackClients.keystone().AndReturn(
|
||||
+ fakes.FakeKeystoneClient())
|
||||
+ neutronclient.Client.create_port({'port': {
|
||||
+ 'network_id': u'abcd1234',
|
||||
+ 'allowed_address_pairs': [{
|
||||
+ 'ip_address': u'10.0.3.21',
|
||||
+ }],
|
||||
+ 'name': utils.PhysName('test_stack', 'port'),
|
||||
+ 'admin_state_up': True}}
|
||||
+ ).AndReturn({'port': {
|
||||
+ "status": "BUILD",
|
||||
+ "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
|
||||
+ }})
|
||||
+ neutronclient.Client.show_port(
|
||||
+ 'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
|
||||
+ ).AndReturn({'port': {
|
||||
+ "status": "ACTIVE",
|
||||
+ "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
|
||||
+ }})
|
||||
+
|
||||
+ self.m.ReplayAll()
|
||||
+
|
||||
+ t = template_format.parse(neutron_port_with_address_pair_template)
|
||||
+ t['Resources']['port']['Properties']['allowed_address_pairs'][0].pop(
|
||||
+ 'mac_address'
|
||||
+ )
|
||||
+ stack = utils.parse_stack(t)
|
||||
+
|
||||
+ port = stack['port']
|
||||
+ scheduler.TaskRunner(port.create)()
|
||||
+ self.m.VerifyAll()
|
||||
--
|
||||
1.8.3.2
|
||||
|
|
@ -0,0 +1,504 @@
|
|||
From ac190f0da6ce367cc833b92677266e7bbf7e2270 Mon Sep 17 00:00:00 2001
|
||||
From: Timur Sufiev <tsufiev@mirantis.com>
|
||||
Date: Thu, 5 Dec 2013 19:46:28 +0400
|
||||
Subject: [PATCH] Adds ability to configure various clients used by the Heat
|
||||
|
||||
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
|
||||
Ported from: icehouse.
|
||||
---
|
||||
etc/heat/heat.conf.sample | 182 ++++++++++++++++++++++++++++++++++---
|
||||
heat/common/config.py | 28 +++++-
|
||||
heat/common/heat_keystoneclient.py | 17 ++++
|
||||
heat/engine/clients.py | 30 +++++-
|
||||
heat/tests/test_heatclient.py | 36 ++++++--
|
||||
5 files changed, 268 insertions(+), 25 deletions(-)
|
||||
|
||||
diff --git a/etc/heat/heat.conf.sample b/etc/heat/heat.conf.sample
|
||||
index 1444f9b..20dadd3 100644
|
||||
--- a/etc/heat/heat.conf.sample
|
||||
+++ b/etc/heat/heat.conf.sample
|
||||
@@ -473,6 +473,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]
|
||||
|
||||
#
|
||||
@@ -568,6 +605,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]
|
||||
|
||||
#
|
||||
@@ -683,29 +818,26 @@
|
||||
#workers=0
|
||||
|
||||
|
||||
-[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>
|
||||
|
||||
+# Optional PEM-formatted certificate chain file (string value)
|
||||
+#cert_file=<None>
|
||||
|
||||
-[matchmaker_ring]
|
||||
+# Optional PEM-formatted file that contains the private key
|
||||
+# (string value)
|
||||
+#key_file=<None>
|
||||
|
||||
-#
|
||||
-# Options defined in heat.openstack.common.rpc.matchmaker_ring
|
||||
-#
|
||||
-
|
||||
-# 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]
|
||||
@@ -724,3 +856,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
|
||||
+
|
||||
+
|
||||
diff --git a/heat/common/config.py b/heat/common/config.py
|
||||
index 82b4ca5..b115f20 100644
|
||||
--- a/heat/common/config.py
|
||||
+++ b/heat/common/config.py
|
||||
@@ -17,7 +17,7 @@
|
||||
"""
|
||||
Routines for configuring Heat
|
||||
"""
|
||||
-
|
||||
+import copy
|
||||
import logging as sys_logging
|
||||
import os
|
||||
|
||||
@@ -133,6 +133,31 @@ auth_password_opts = [
|
||||
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(db_opts)
|
||||
cfg.CONF.register_opts(engine_opts)
|
||||
@@ -142,6 +167,7 @@ cfg.CONF.register_group(paste_deploy_group)
|
||||
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():
|
||||
diff --git a/heat/common/heat_keystoneclient.py b/heat/common/heat_keystoneclient.py
|
||||
index 8fb13f7..d052a67 100644
|
||||
--- a/heat/common/heat_keystoneclient.py
|
||||
+++ b/heat/common/heat_keystoneclient.py
|
||||
@@ -100,6 +100,10 @@ class KeystoneClient(object):
|
||||
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)
|
||||
@@ -161,12 +165,25 @@ class KeystoneClient(object):
|
||||
"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
|
||||
diff --git a/heat/engine/clients.py b/heat/engine/clients.py
|
||||
index 6deae5b..a749cd2 100644
|
||||
--- a/heat/engine/clients.py
|
||||
+++ b/heat/engine/clients.py
|
||||
@@ -103,7 +103,9 @@ class OpenStackClients(object):
|
||||
'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)
|
||||
@@ -133,7 +135,9 @@ class OpenStackClients(object):
|
||||
'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
|
||||
@@ -153,7 +157,9 @@ class OpenStackClients(object):
|
||||
'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)
|
||||
@@ -176,7 +182,9 @@ class OpenStackClients(object):
|
||||
'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)
|
||||
@@ -202,6 +210,10 @@ class OpenStackClients(object):
|
||||
'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)
|
||||
@@ -209,6 +221,16 @@ class OpenStackClients(object):
|
||||
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)
|
||||
+
|
||||
|
||||
if cfg.CONF.cloud_backend:
|
||||
cloud_backend_module = importutils.import_module(cfg.CONF.cloud_backend)
|
||||
diff --git a/heat/tests/test_heatclient.py b/heat/tests/test_heatclient.py
|
||||
index 7e195dc..712ffa5 100644
|
||||
--- a/heat/tests/test_heatclient.py
|
||||
+++ b/heat/tests/test_heatclient.py
|
||||
@@ -51,7 +51,11 @@ class KeystoneClientTest(HeatTestCase):
|
||||
self.mock_ks_client = heat_keystoneclient.kc.Client(
|
||||
auth_url=mox.IgnoreArg(),
|
||||
tenant_name='test_tenant',
|
||||
- token='abcd1234')
|
||||
+ token='abcd1234',
|
||||
+ cacert=None,
|
||||
+ cert=None,
|
||||
+ insecure=False,
|
||||
+ key=None)
|
||||
self.mock_ks_client.authenticate().AndReturn(auth_ok)
|
||||
elif method == 'password':
|
||||
self.mock_ks_client = heat_keystoneclient.kc.Client(
|
||||
@@ -59,14 +63,22 @@ class KeystoneClientTest(HeatTestCase):
|
||||
tenant_name='test_tenant',
|
||||
tenant_id='test_tenant_id',
|
||||
username='test_username',
|
||||
- password='password')
|
||||
+ password='password',
|
||||
+ cacert=None,
|
||||
+ cert=None,
|
||||
+ insecure=False,
|
||||
+ key=None)
|
||||
self.mock_ks_client.authenticate().AndReturn(auth_ok)
|
||||
if method == 'trust':
|
||||
self.mock_ks_client = heat_keystoneclient.kc.Client(
|
||||
auth_url='http://server.test:5000/v2.0',
|
||||
password='verybadpass',
|
||||
tenant_name='service',
|
||||
- username='heat')
|
||||
+ username='heat',
|
||||
+ cacert=None,
|
||||
+ cert=None,
|
||||
+ insecure=False,
|
||||
+ key=None)
|
||||
self.mock_ks_client.authenticate(trust_id='atrust123',
|
||||
tenant_id='test_tenant_id'
|
||||
).AndReturn(auth_ok)
|
||||
@@ -81,7 +93,11 @@ class KeystoneClientTest(HeatTestCase):
|
||||
self.mock_ks_v3_client = heat_keystoneclient.kc_v3.Client(
|
||||
token='abcd1234', project_name='test_tenant',
|
||||
auth_url='http://server.test:5000/v3',
|
||||
- endpoint='http://server.test:5000/v3')
|
||||
+ endpoint='http://server.test:5000/v3',
|
||||
+ cacert=None,
|
||||
+ cert=None,
|
||||
+ insecure=False,
|
||||
+ key=None)
|
||||
elif method == 'password':
|
||||
self.mock_ks_v3_client = heat_keystoneclient.kc_v3.Client(
|
||||
username='test_username',
|
||||
@@ -89,13 +105,21 @@ class KeystoneClientTest(HeatTestCase):
|
||||
project_name='test_tenant',
|
||||
project_id='test_tenant_id',
|
||||
auth_url='http://server.test:5000/v3',
|
||||
- endpoint='http://server.test:5000/v3')
|
||||
+ endpoint='http://server.test:5000/v3',
|
||||
+ cacert=None,
|
||||
+ cert=None,
|
||||
+ insecure=False,
|
||||
+ key=None)
|
||||
elif method == 'trust':
|
||||
self.mock_ks_v3_client = heat_keystoneclient.kc_v3.Client(
|
||||
username='heat',
|
||||
password='verybadpass',
|
||||
project_name='service',
|
||||
- auth_url='http://server.test:5000/v3')
|
||||
+ auth_url='http://server.test:5000/v3',
|
||||
+ cacert=None,
|
||||
+ cert=None,
|
||||
+ insecure=False,
|
||||
+ key=None)
|
||||
self.mock_ks_v3_client.authenticate().AndReturn(auth_ok)
|
||||
|
||||
def test_username_length(self):
|
||||
--
|
||||
1.8.3.2
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
How to apply Heat patches
|
||||
==========================
|
||||
|
||||
1. Copy both patches from this dir to the machine with Openstack
|
||||
installation.
|
||||
|
||||
2. Login to the machine with Openstack installation and gain root
|
||||
rights.
|
||||
|
||||
2. Go to the location where the heat python package is installed:
|
||||
cd /usr/lib/python2.7/dist-package
|
||||
|
||||
3. Apply each patch by issuing the following command:
|
||||
patch -b -p1 < /path/to/the/patch-file
|
||||
|
||||
4. Restart the heat service:
|
||||
service heat-engine restart
|
Loading…
Reference in New Issue