Merge "Handle stack not found during inventory generation"
This commit is contained in:
commit
3328727e44
|
@ -16,6 +16,7 @@
|
|||
# under the License.
|
||||
|
||||
from collections import OrderedDict
|
||||
import logging
|
||||
import os.path
|
||||
import sys
|
||||
import yaml
|
||||
|
@ -28,6 +29,10 @@ UNDERCLOUD_CONNECTION_SSH = 'ssh'
|
|||
|
||||
UNDERCLOUD_CONNECTION_LOCAL = 'local'
|
||||
|
||||
logging.basicConfig()
|
||||
LOG = logging.getLogger(__name__)
|
||||
LOG.setLevel(logging.INFO)
|
||||
|
||||
|
||||
class TemplateDumper(yaml.SafeDumper):
|
||||
def represent_ordered_dict(self, data):
|
||||
|
@ -47,26 +52,17 @@ class StackOutputs(object):
|
|||
on unnecessary Heat calls.
|
||||
"""
|
||||
|
||||
def __init__(self, plan, hclient):
|
||||
self.plan = plan
|
||||
def __init__(self, stack):
|
||||
self.outputs = {}
|
||||
self.hclient = hclient
|
||||
self.stack = None
|
||||
self.stack = stack
|
||||
|
||||
def _load_outputs(self):
|
||||
"""Load outputs from the stack if necessary
|
||||
|
||||
Retrieves the stack outputs if that has not already happened. If it
|
||||
has then this is a noop.
|
||||
|
||||
Sets the outputs to an empty dict if the stack is not found.
|
||||
"""
|
||||
if not self.stack:
|
||||
try:
|
||||
self.stack = self.hclient.stacks.get(self.plan)
|
||||
except HTTPNotFound:
|
||||
self.outputs = {}
|
||||
return
|
||||
if not self.outputs:
|
||||
self.outputs = {i['output_key']: i['output_value']
|
||||
for i in self.stack.outputs
|
||||
}
|
||||
|
@ -106,7 +102,6 @@ class TripleoInventory(object):
|
|||
self.undercloud_key_file = undercloud_key_file
|
||||
self.plan_name = plan_name
|
||||
self.ansible_python_interpreter = ansible_python_interpreter
|
||||
self.stack_outputs = StackOutputs(self.plan_name, self.hclient)
|
||||
self.hostvars = {}
|
||||
self.undercloud_connection = undercloud_connection
|
||||
self.serial = serial
|
||||
|
@ -153,6 +148,16 @@ class TripleoInventory(object):
|
|||
else:
|
||||
return alist
|
||||
|
||||
def _get_stack(self):
|
||||
try:
|
||||
stack = self.hclient.stacks.get(self.plan_name)
|
||||
except HTTPNotFound:
|
||||
LOG.warning("Stack not found: %s. Only the undercloud will "
|
||||
"be added to the inventory." % self.plan_name)
|
||||
stack = None
|
||||
|
||||
return stack
|
||||
|
||||
def list(self):
|
||||
ret = OrderedDict({
|
||||
'Undercloud': {
|
||||
|
@ -191,19 +196,30 @@ class TripleoInventory(object):
|
|||
interface='public')
|
||||
ret['Undercloud']['vars']['undercloud_swift_url'] = swift_url
|
||||
|
||||
keystone_url = self.stack_outputs.get('KeystoneURL')
|
||||
if keystone_url:
|
||||
ret['Undercloud']['vars']['overcloud_keystone_url'] = keystone_url
|
||||
ret['Undercloud']['vars']['undercloud_service_list'] = \
|
||||
self.get_undercloud_service_list()
|
||||
|
||||
admin_password = self.get_overcloud_environment().get(
|
||||
'parameter_defaults', {}).get('AdminPassword')
|
||||
if admin_password:
|
||||
ret['Undercloud']['vars']['overcloud_admin_password'] =\
|
||||
admin_password
|
||||
|
||||
if not self.hosts_format_dict:
|
||||
# Prevent Ansible from repeatedly calling us to get empty host
|
||||
# details
|
||||
ret['_meta'] = {'hostvars': self.hostvars}
|
||||
|
||||
self.stack = self._get_stack()
|
||||
if not self.stack:
|
||||
return ret
|
||||
self.stack_outputs = StackOutputs(self.stack)
|
||||
|
||||
keystone_url = self.stack_outputs.get('KeystoneURL')
|
||||
if keystone_url:
|
||||
ret['Undercloud']['vars']['overcloud_keystone_url'] = keystone_url
|
||||
|
||||
endpoint_map = self.stack_outputs.get('EndpointMap')
|
||||
|
||||
ret['Undercloud']['vars']['undercloud_service_list'] = \
|
||||
self.get_undercloud_service_list()
|
||||
|
||||
if endpoint_map:
|
||||
horizon_endpoint = endpoint_map.get('HorizonPublic', {}).get('uri')
|
||||
if horizon_endpoint:
|
||||
|
@ -333,11 +349,6 @@ class TripleoInventory(object):
|
|||
ret[svc_host]['vars']['ansible_python_interpreter'] = \
|
||||
self.ansible_python_interpreter
|
||||
|
||||
if not self.hosts_format_dict:
|
||||
# Prevent Ansible from repeatedly calling us to get empty host
|
||||
# details
|
||||
ret['_meta'] = {'hostvars': self.hostvars}
|
||||
|
||||
return ret
|
||||
|
||||
def host(self):
|
||||
|
|
|
@ -115,7 +115,7 @@ class TestInventory(base.TestCase):
|
|||
self.session.get_token.return_value = 'atoken'
|
||||
self.session.get_endpoint.return_value = 'anendpoint'
|
||||
|
||||
self.outputs = StackOutputs('overcloud', self.hclient)
|
||||
self.outputs = StackOutputs(self.mock_stack)
|
||||
self.inventory = TripleoInventory(
|
||||
session=self.session,
|
||||
hclient=self.hclient,
|
||||
|
@ -143,10 +143,10 @@ class TestInventory(base.TestCase):
|
|||
}
|
||||
self.assertDictEqual(services, expected)
|
||||
|
||||
def test_outputs_are_empty_if_stack_doesnt_exist(self):
|
||||
def test_stack_not_found(self):
|
||||
self.hclient.stacks.get.side_effect = HTTPNotFound('not found')
|
||||
stack_outputs = StackOutputs('no-plan', self.hclient)
|
||||
self.assertEqual(list(stack_outputs), [])
|
||||
self.assertEqual(None,
|
||||
self.inventory._get_stack())
|
||||
|
||||
def test_outputs_valid_key_calls_api(self):
|
||||
expected = 'xyz://keystone'
|
||||
|
|
Loading…
Reference in New Issue