Detect neutron endpoint on-the-fly
This change does the following: - reverts commit04de60093b
- reimplements Resource.is_using_neutron to check for neutron by attempting to create a neutron client - fix mocking in tests for changes which landed after04de600
If there is no 'network' entry in the service catalog then keystoneclient will raise an EndpointNotFound. The context will already have a keystone client cached which has a full service catalog locally, so calling is_using_neutron should have no particular overhead. This fixes a tripleo regression where the autodetection is triggered before keystone is ready, so that heat-engine fails to start. This race does not affect devstack as keystone is fully configured before heat services are started. Not adding config option networking_service will also prevent extra work required by downstream installation tools. Change-Id: I45a6154fa560f672d8d1942bf57f39601110bfc6 Closes-Bug: #1362812
This commit is contained in:
parent
99a11f8633
commit
d70da16894
@ -46,31 +46,12 @@ gettextutils.install('heat', lazy=True)
|
||||
|
||||
LOG = logging.getLogger('heat.engine')
|
||||
|
||||
|
||||
def discover_networking_service():
|
||||
from heat.common import heat_keystoneclient as hkc
|
||||
|
||||
# create empty context
|
||||
ctxt = hkc.context.RequestContext()
|
||||
# create admin client
|
||||
admin_client = hkc.KeystoneClient(ctxt).admin_client
|
||||
services = admin_client.services.list()
|
||||
|
||||
if 'network' in [s.type for s in services]:
|
||||
cfg.CONF.set_override('networking_service', 'neutron')
|
||||
else:
|
||||
cfg.CONF.set_override('networking_service', 'nova')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
cfg.CONF(project='heat', prog='heat-engine')
|
||||
logging.setup('heat')
|
||||
messaging.setup()
|
||||
|
||||
if not cfg.CONF.networking_service:
|
||||
discover_networking_service()
|
||||
|
||||
from heat.engine import service as engine
|
||||
|
||||
srv = engine.EngineService(cfg.CONF.host, rpc_api.ENGINE_TOPIC)
|
||||
|
@ -73,10 +73,6 @@
|
||||
# Deprecated. (string value)
|
||||
#onready=<None>
|
||||
|
||||
# Select OpenStack component responsible for networking - nova
|
||||
# or neutron. (string value)
|
||||
#networking_service=<None>
|
||||
|
||||
|
||||
#
|
||||
# Options defined in heat.common.config
|
||||
|
@ -138,11 +138,7 @@ engine_opts = [
|
||||
help=_('RPC timeout for the engine liveness check that is used'
|
||||
' for stack locking.')),
|
||||
cfg.StrOpt('onready',
|
||||
help=_('Deprecated.')),
|
||||
cfg.StrOpt('networking_service',
|
||||
choices=['nova', 'neutron'],
|
||||
help=_('Select OpenStack component '
|
||||
'responsible for networking - nova or neutron.'))]
|
||||
help=_('Deprecated.'))]
|
||||
|
||||
rpc_opts = [
|
||||
cfg.StrOpt('host',
|
||||
|
@ -28,12 +28,14 @@ class NeutronClientPlugin(client_plugin.ClientPlugin):
|
||||
con = self.context
|
||||
|
||||
endpoint_type = self._get_client_option('neutron', 'endpoint_type')
|
||||
endpoint = self.url_for(service_type='network',
|
||||
endpoint_type=endpoint_type)
|
||||
|
||||
args = {
|
||||
'auth_url': con.auth_url,
|
||||
'service_type': 'network',
|
||||
'token': self.auth_token,
|
||||
'endpoint_url': self.url_for(service_type='network',
|
||||
endpoint_type=endpoint_type),
|
||||
'endpoint_url': endpoint,
|
||||
'endpoint_type': endpoint_type,
|
||||
'ca_cert': self._get_client_option('neutron', 'ca_file'),
|
||||
'insecure': self._get_client_option('neutron', 'insecure')
|
||||
|
@ -1116,6 +1116,10 @@ class Resource(object):
|
||||
self._data = None
|
||||
return True
|
||||
|
||||
@staticmethod
|
||||
def is_using_neutron():
|
||||
return cfg.CONF.networking_service == 'neutron'
|
||||
def is_using_neutron(self):
|
||||
try:
|
||||
self.client('neutron')
|
||||
except Exception:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
@ -1002,9 +1002,17 @@ class ResourceTest(HeatTestCase):
|
||||
snippet = rsrc_defn.ResourceDefinition('aresource',
|
||||
'GenericResourceType')
|
||||
res = resource.Resource('aresource', snippet, self.stack)
|
||||
cfg.CONF.set_override('networking_service', 'neutron')
|
||||
self.patch(
|
||||
'heat.engine.clients.os.neutron.NeutronClientPlugin._create')
|
||||
self.assertTrue(res.is_using_neutron())
|
||||
cfg.CONF.set_override('networking_service', 'nova')
|
||||
|
||||
def test_is_not_using_neutron(self):
|
||||
snippet = rsrc_defn.ResourceDefinition('aresource',
|
||||
'GenericResourceType')
|
||||
res = resource.Resource('aresource', snippet, self.stack)
|
||||
mock_create = self.patch(
|
||||
'heat.engine.clients.os.neutron.NeutronClientPlugin._create')
|
||||
mock_create.side_effect = Exception()
|
||||
self.assertFalse(res.is_using_neutron())
|
||||
|
||||
|
||||
|
@ -13,11 +13,11 @@
|
||||
|
||||
import collections
|
||||
|
||||
from keystoneclient import exceptions as keystone_exc
|
||||
from neutronclient.common.exceptions import NeutronClientException
|
||||
from neutronclient.v2_0 import client as neutronclient
|
||||
from novaclient.v1_1 import security_group_rules as nova_sgr
|
||||
from novaclient.v1_1 import security_groups as nova_sg
|
||||
from oslo.config import cfg
|
||||
|
||||
from heat.common import exception
|
||||
from heat.common import template_format
|
||||
@ -145,6 +145,11 @@ Resources:
|
||||
neutronclient.Client, 'delete_security_group_rule')
|
||||
self.m.StubOutWithMock(neutronclient.Client, 'delete_security_group')
|
||||
|
||||
def mock_no_neutron(self):
|
||||
mock_create = self.patch(
|
||||
'heat.engine.clients.os.neutron.NeutronClientPlugin._create')
|
||||
mock_create.side_effect = keystone_exc.EndpointNotFound()
|
||||
|
||||
def create_stack(self, templ):
|
||||
self.stack = self.parse_stack(template_format.parse(templ))
|
||||
self.assertIsNone(self.stack.create())
|
||||
@ -166,6 +171,7 @@ Resources:
|
||||
|
||||
def test_security_group_nova(self):
|
||||
#create script
|
||||
self.mock_no_neutron()
|
||||
nova.NovaClientPlugin._create().AndReturn(self.fc)
|
||||
nova_sg.SecurityGroupManager.list().AndReturn([NovaSG(
|
||||
id=1,
|
||||
@ -258,6 +264,7 @@ Resources:
|
||||
|
||||
def test_security_group_nova_bad_source_group(self):
|
||||
#create script
|
||||
self.mock_no_neutron()
|
||||
nova.NovaClientPlugin._create().AndReturn(self.fc)
|
||||
nova_sg.SecurityGroupManager.list().AndReturn([NovaSG(
|
||||
id=1,
|
||||
@ -322,6 +329,7 @@ Resources:
|
||||
|
||||
def test_security_group_client_exception(self):
|
||||
#create script
|
||||
self.mock_no_neutron()
|
||||
nova.NovaClientPlugin._create().AndReturn(self.fc)
|
||||
sg_name = utils.PhysName('test_stack', 'the_sg')
|
||||
nova_sg.SecurityGroupManager.list().AndReturn([
|
||||
@ -430,6 +438,7 @@ Resources:
|
||||
self.m.VerifyAll()
|
||||
|
||||
def test_security_group_nova_with_egress_rules(self):
|
||||
self.mock_no_neutron()
|
||||
t = template_format.parse(self.test_template_nova_with_egress)
|
||||
stack = self.parse_stack(t)
|
||||
|
||||
@ -437,7 +446,6 @@ Resources:
|
||||
self.assertRaises(exception.EgressRuleNotAllowed, sg.validate)
|
||||
|
||||
def test_security_group_neutron(self):
|
||||
cfg.CONF.set_override('networking_service', 'neutron')
|
||||
#create script
|
||||
sg_name = utils.PhysName('test_stack', 'the_sg')
|
||||
neutronclient.Client.create_security_group({
|
||||
@ -683,7 +691,6 @@ Resources:
|
||||
self.m.VerifyAll()
|
||||
|
||||
def test_security_group_neutron_exception(self):
|
||||
cfg.CONF.set_override('networking_service', 'neutron')
|
||||
#create script
|
||||
sg_name = utils.PhysName('test_stack', 'the_sg')
|
||||
neutronclient.Client.create_security_group({
|
||||
|
@ -11,8 +11,6 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from oslo.config import cfg
|
||||
|
||||
from heat.common import exception
|
||||
from heat.common import template_format
|
||||
from heat.engine import parser
|
||||
@ -577,7 +575,6 @@ Resources:
|
||||
neutronclient.Client.delete_port('dddd').AndReturn(None)
|
||||
|
||||
def test_network_interface(self):
|
||||
cfg.CONF.set_override('networking_service', 'neutron')
|
||||
self.mock_create_security_group()
|
||||
self.mock_create_network()
|
||||
self.mock_create_subnet()
|
||||
@ -603,7 +600,6 @@ Resources:
|
||||
self.m.VerifyAll()
|
||||
|
||||
def test_network_interface_existing_groupset(self):
|
||||
cfg.CONF.set_override('networking_service', 'neutron')
|
||||
self.m.StubOutWithMock(parser.Stack, 'resource_by_refid')
|
||||
|
||||
self.mock_create_security_group()
|
||||
|
Loading…
Reference in New Issue
Block a user