From 9b8dfc4a8c70e4494af63dfa189ffa332d0ba6a8 Mon Sep 17 00:00:00 2001 From: Lennart Regebro Date: Tue, 20 Jan 2015 17:32:19 +0100 Subject: [PATCH] Various SAT6 integration fixes Updated the API calls, the MAC address had to be uppercase and in quotes. The URL in the errata rendering works now. Moved the configuration into local_settings.py. Change-Id: Ib596bfd334a8b97be5bd4cdd6ecde03706863a73 --- tuskar_sat_ui/nodes/tables.py | 3 +- tuskar_sat_ui/nodes/tabs.py | 71 ++++++------ tuskar_sat_ui/nodes/tests.py | 108 ++++++++++-------- .../nodes/_detail_overview_sat.html | 2 +- 4 files changed, 100 insertions(+), 84 deletions(-) diff --git a/tuskar_sat_ui/nodes/tables.py b/tuskar_sat_ui/nodes/tables.py index 23d8c9a..9f7b430 100644 --- a/tuskar_sat_ui/nodes/tables.py +++ b/tuskar_sat_ui/nodes/tables.py @@ -16,7 +16,8 @@ from horizon import tables def get_errata_link(errata): - return "http://www.google.com" + d = errata._asdict() + return "{admin_url}/content_hosts/{host_id}/errata/{id}".format(**d) class ErrataTable(tables.DataTable): diff --git a/tuskar_sat_ui/nodes/tabs.py b/tuskar_sat_ui/nodes/tabs.py index 6e1b9b2..68446a4 100644 --- a/tuskar_sat_ui/nodes/tabs.py +++ b/tuskar_sat_ui/nodes/tabs.py @@ -12,7 +12,6 @@ # License for the specific language governing permissions and limitations # under the License. import collections -import json import logging @@ -28,16 +27,21 @@ from tuskar_ui.infrastructure.nodes import tabs as nodes_tabs from tuskar_sat_ui.nodes import tables -SAT_HOST_PARAM = 'SatelliteHost' -SAT_AUTH_PARAM = 'SatelliteAuth' -SAT_ORG_PARAM = 'SatelliteOrg' +SAT_HOST_PARAM = 'satellite_host' +SAT_API_PARAM = 'satellite_api' +SAT_AUTH_PARAM = 'satellite_auth' +SAT_ORG_PARAM = 'satellite_org' +SAT_CONFIG = 'SATELLITE_CONFIG' + VERIFY_SSL = not getattr(settings, 'OPENSTACK_SSL_NO_VERIFY', False) LOG = logging.getLogger('tuskar_sat_ui') ErrataItem = collections.namedtuple('ErrataItem', [ 'title', 'type', 'id', + 'host_id', 'issued', + 'admin_url', ]) @@ -69,7 +73,7 @@ class NoErrataError(Error): """There is no errata for that node.""" -def _get_satellite_config(parameters): +def _get_satellite_config(): """Find the Satellite configuration data. The configuration data is store in Heat as parameters. They may be @@ -77,22 +81,18 @@ def _get_satellite_config(parameters): in ExtraConfig. """ - param = 'Satellite' try: - config = parameters[param] - except KeyError: - try: - extra = json.loads(parameters['compute-1::ExtraConfig']) - config = extra[param] - except (KeyError, ValueError, TypeError): - raise NoConfigError(param, 'Parameter %r missing.' % param) + config = getattr(settings, SAT_CONFIG) + except AttributeError: + raise NoConfigError(SAT_CONFIG, 'Parameter %r missing.' % SAT_CONFIG) for param in [SAT_HOST_PARAM, SAT_AUTH_PARAM, SAT_ORG_PARAM]: if param not in config: raise NoConfigError(param, 'Parameter %r missing.' % param) - host = config[SAT_HOST_PARAM] - host = host.strip('/') # Get rid of any trailing slash in the host url + admin_url = config[SAT_HOST_PARAM] + # Get rid of any trailing slash in the admin url + admin_url = admin_url.strip('/') try: auth = config[SAT_AUTH_PARAM].split(':', 2) @@ -105,7 +105,15 @@ def _get_satellite_config(parameters): else: raise BadAuthError(auth=auth[0]) organization = config[SAT_ORG_PARAM] - return host, auth, organization + + if SAT_API_PARAM in config: + api_url = config[SAT_API_PARAM] + # Get rid of any trailing slash in the API url + api_url = api_url.strip('/') + else: + api_url = admin_url + + return admin_url, api_url, auth, organization def _get_stack(request): @@ -122,7 +130,7 @@ def _get_stack(request): return stack -def _find_uuid_by_mac(host, auth, organization, addresses): +def _find_uuid_by_mac(api_url, auth, organization, addresses): """Pick up the UUID from the MAC address. This makes no sense, as we need both MAC address and the interface, and @@ -131,11 +139,11 @@ def _find_uuid_by_mac(host, auth, organization, addresses): isn't, we need to store a mapping somewhere. """ - url = '{host}/katello/api/v2/systems'.format(host=host) + url = '{api_url}/katello/api/v2/systems'.format(api_url=api_url) for mac in addresses: for interface in ['eth0', 'eth1', 'en0', 'en1']: - q = 'facts.net.interface.{iface}.mac_address:{mac}'.format( - iface=interface, mac=mac) + q = 'facts.net.interface.{iface}.mac_address:"{mac}"'.format( + iface=interface, mac=mac.upper()) params = {'search': q, 'organization_id': organization} r = requests.get(url, params=params, auth=auth, verify=VERIFY_SSL) @@ -146,18 +154,18 @@ def _find_uuid_by_mac(host, auth, organization, addresses): raise NodeNotFound() -def _get_errata_data(host, auth, uuid): +def _get_errata_data(admin_url, api_url, auth, uuid): """Get the errata here, while it's hot.""" - url = '{host}/katello/api/v2/systems/{id}/errata'.format(host=host, - id=uuid) + url = '{url}/katello/api/v2/systems/{id}/errata'.format(url=api_url, + id=uuid) r = requests.get(url, auth=auth, verify=VERIFY_SSL) r.raise_for_status() # Raise an error if the request failed - errata = r.json()['contexts'] + errata = r.json()['results'] if not errata: raise NoErrataError() - data = [ErrataItem(x['title'], x['type'], x['id'], x['issued']) - for x in errata] + data = [ErrataItem(x['title'], x['type'], x['errata_id'], uuid, + x['issued'], admin_url) for x in errata] return data @@ -170,13 +178,8 @@ class DetailOverviewTab(nodes_tabs.DetailOverviewTab): if context['node'].uuid is None: return context - # TODO(rdopiera) We can probably get the stack from the context. - stack = _get_stack(request) - if stack is None: - return context - try: - host, auth, organization = _get_satellite_config(stack.parameters) + admin_url, api_url, auth, organization = _get_satellite_config() except NoConfigError as e: horizon.messages.error(request, _( "No Satellite configuration found. " @@ -192,13 +195,13 @@ class DetailOverviewTab(nodes_tabs.DetailOverviewTab): addresses = context['node'].addresses try: - uuid = _find_uuid_by_mac(host, auth, organization, addresses) + uuid = _find_uuid_by_mac(api_url, auth, organization, addresses) except NodeNotFound: return context # TODO(rdopiera) Should probably catch that requests exception here. try: - data = _get_errata_data(host, auth, uuid) + data = _get_errata_data(admin_url, api_url, auth, uuid) except NoErrataError: return context context['errata'] = tables.ErrataTable(request, data=data) diff --git a/tuskar_sat_ui/nodes/tests.py b/tuskar_sat_ui/nodes/tests.py index 5a0d80f..9a55924 100644 --- a/tuskar_sat_ui/nodes/tests.py +++ b/tuskar_sat_ui/nodes/tests.py @@ -12,87 +12,99 @@ # License for the specific language governing permissions and limitations # under the License. -import json - from tuskar_ui.test import helpers from tuskar_sat_ui.nodes import tabs class SatTests(helpers.BaseAdminViewTests): - def test_satellite_config_direct(self): + def test_satellite_config(self): config = { - 'Satellite': { - 'SatelliteHost': 'http://example.com/', - 'SatelliteAuth': 'basic:user:pass', - 'SatelliteOrg': 'ACME', + tabs.SAT_CONFIG: { + tabs.SAT_HOST_PARAM: 'http://example.com/', + tabs.SAT_AUTH_PARAM: 'basic:user:pass', + tabs.SAT_ORG_PARAM: 'ACME', }, } - host, auth, org = tabs._get_satellite_config(config) - self.assertEqual(host, 'http://example.com') - self.assertEqual(auth, ('user', 'pass')) - self.assertEqual(org, 'ACME') - def test_satellite_config_extra(self): + with self.settings(**config): + host_url, api_url, auth, org = tabs._get_satellite_config() + self.assertEqual(host_url, 'http://example.com') + self.assertEqual(api_url, 'http://example.com') + self.assertEqual(auth, ('user', 'pass')) + self.assertEqual(org, 'ACME') + + def test_satellite_config_different_api_url(self): config = { - 'compute-1::ExtraConfig': json.dumps({ - 'Satellite': { - 'SatelliteHost': 'http://example.com/', - 'SatelliteAuth': 'basic:user:pass', - 'SatelliteOrg': 'ACME', - } - }), + tabs.SAT_CONFIG: { + tabs.SAT_HOST_PARAM: 'http://example.com/', + tabs.SAT_API_PARAM: 'https://example.com/', + tabs.SAT_AUTH_PARAM: 'basic:user:pass', + tabs.SAT_ORG_PARAM: 'ACME', + }, } - host, auth, org = tabs._get_satellite_config(config) - self.assertEqual(host, 'http://example.com') - self.assertEqual(auth, ('user', 'pass')) - self.assertEqual(org, 'ACME') + + with self.settings(**config): + host_url, api_url, auth, org = tabs._get_satellite_config() + self.assertEqual(host_url, 'http://example.com') + self.assertEqual(api_url, 'https://example.com') + self.assertEqual(auth, ('user', 'pass')) + self.assertEqual(org, 'ACME') def test_satellite_config_missing_all(self): config = {} - with self.assertRaises(tabs.NoConfigError) as e: - host, auth, org = tabs._get_satellite_config(config) - self.assertEqual(e.exception.param, 'Satellite') + + with self.settings(**config): + with self.assertRaises(tabs.NoConfigError) as e: + host_url, api_url, auth, org = tabs._get_satellite_config() + self.assertEqual(e.exception.param, tabs.SAT_CONFIG) def test_satellite_config_missing_one(self): params = { - 'SatelliteHost': 'http://example.com/', - 'SatelliteAuth': 'basic:user:pass', - 'SatelliteOrg': 'ACME', + tabs.SAT_HOST_PARAM: 'http://example.com/', + tabs.SAT_AUTH_PARAM: 'basic:user:pass', + tabs.SAT_ORG_PARAM: 'ACME', } + for param in [ tabs.SAT_HOST_PARAM, tabs.SAT_AUTH_PARAM, tabs.SAT_ORG_PARAM, ]: broken_config = { - 'Satellite': dict(kv for kv in params.items() - if kv[0] != param), + tabs.SAT_CONFIG: dict(kv for kv in params.items() + if kv[0] != param), } - with self.assertRaises(tabs.NoConfigError) as e: - host, auth, org = tabs._get_satellite_config(broken_config) - self.assertEqual(e.exception.param, param) + + with self.settings(**broken_config): + with self.assertRaises(tabs.NoConfigError) as e: + host_url, api_url, auth, org = tabs._get_satellite_config() + self.assertEqual(e.exception.param, param) def test_satellite_config_unknown_auth(self): config = { - 'Satellite': { - 'SatelliteHost': 'http://example.com/', - 'SatelliteAuth': 'bad:user:pass', - 'SatelliteOrg': 'ACME', + tabs.SAT_CONFIG: { + tabs.SAT_HOST_PARAM: 'http://example.com/', + tabs.SAT_AUTH_PARAM: 'bad:user:pass', + tabs.SAT_ORG_PARAM: 'ACME', }, } - with self.assertRaises(tabs.BadAuthError) as e: - host, auth, org = tabs._get_satellite_config(config) - self.assertEqual(e.exception.auth, 'bad') + + with self.settings(**config): + with self.assertRaises(tabs.BadAuthError) as e: + host_url, api_url, auth, org = tabs._get_satellite_config() + self.assertEqual(e.exception.auth, 'bad') def test_satellite_config_malformed_auth(self): config = { - 'Satellite': { - 'SatelliteHost': 'http://example.com/', - 'SatelliteAuth': 'bad', - 'SatelliteOrg': 'ACME', + tabs.SAT_CONFIG: { + tabs.SAT_HOST_PARAM: 'http://example.com/', + tabs.SAT_AUTH_PARAM: 'bad', + tabs.SAT_ORG_PARAM: 'ACME', }, } - with self.assertRaises(tabs.BadAuthError) as e: - host, auth, org = tabs._get_satellite_config(config) - self.assertEqual(e.exception.auth, 'bad') + + with self.settings(**config): + with self.assertRaises(tabs.BadAuthError) as e: + api_url, api_url_url, auth, org = tabs._get_satellite_config() + self.assertEqual(e.exception.auth, 'bad') diff --git a/tuskar_sat_ui/templates/infrastructure/nodes/_detail_overview_sat.html b/tuskar_sat_ui/templates/infrastructure/nodes/_detail_overview_sat.html index e51042f..445299a 100644 --- a/tuskar_sat_ui/templates/infrastructure/nodes/_detail_overview_sat.html +++ b/tuskar_sat_ui/templates/infrastructure/nodes/_detail_overview_sat.html @@ -9,7 +9,7 @@ {% if errata %} {{ errata.render }} {% else %} -

{% trans "No errata found" %}

+

{% trans "Could not fetch errata" %}

{% endif %} {% endif %}