def get_app_image(request, app_fqdn): package = pkg_cli.app_by_fqn(request, app_fqdn) url = static('dashboard/img/stack-green.svg') if package: app_id = package.id url = reverse("horizon:murano:catalog:images", args=(app_id,)) return url
def _reverse(_fqn): _app = pkg_api.app_by_fqn(request, _fqn) if _app is None: msg = "Application with FQN='{0}' doesn't exist" messages.error(request, msg.format(_fqn)) raise Http404(msg.format(_fqn)) args = (_app.id, environment_id, False, True) return _app.name, reverse(ns_url, args=args)
def update(self, request, environment_id, **kwargs): matching_classes = [] fqns_seen = set() # NOTE(kzaitsev): it's possible to have a private # and public apps with the same fqn, however the engine would # currently favor private package. Therefore we should squash # these until we devise a better way to work with this # situation and versioning for class_fqn in fqns: app_found = pkg_api.app_by_fqn(request, class_fqn) if app_found: fqns_seen.add(app_found.fully_qualified_name) matching_classes.append(app_found) apps_found = pkg_api.apps_that_inherit(request, class_fqn) for app in apps_found: if app.fully_qualified_name in fqns_seen: continue fqns_seen.add(app.fully_qualified_name) matching_classes.append(app) if not matching_classes: msg = _("Couldn't find any apps, required for this field.\n" "Tried: {fqns}").format(fqns=', '.join(fqns)) self.widget = ErrorWidget(message=msg) # NOTE(kzaitsev): this closure is needed to allow us have custom # logic when clicking add button def _make_link(): ns_url = 'horizon:app-catalog:catalog:add' ns_url_args = (environment_id, False, True) # This will prevent horizon from adding an extra '+' button if not matching_classes: return '' return json.dumps([(app.name, reverse(ns_url, args=((app.id, ) + ns_url_args))) for app in matching_classes]) self.widget.add_item_link = _make_link apps = env_api.service_list_by_fqns( request, environment_id, [app.fully_qualified_name for app in matching_classes]) choices = [('', self.empty_value_message)] choices.extend([(app['?']['id'], html.escape(app.name)) for app in apps]) self.choices = choices # NOTE(tsufiev): streamline the drop-down UX: auto-select the # single available option in a drop-down if len(choices) == 2: self.initial = choices[1][0]
def update(self, request, environment_id, **kwargs): matching_classes = [] fqns_seen = set() # NOTE(kzaitsev): it's possible to have a private # and public apps with the same fqn, however the engine would # currently favor private package. Therefore we should squash # these until we devise a better way to work with this # situation and versioning for class_fqn in fqns: app_found = pkg_api.app_by_fqn(request, class_fqn) if app_found: fqns_seen.add(app_found.fully_qualified_name) matching_classes.append(app_found) apps_found = pkg_api.apps_that_inherit(request, class_fqn) for app in apps_found: if app.fully_qualified_name in fqns_seen: continue fqns_seen.add(app.fully_qualified_name) matching_classes.append(app) if not matching_classes: msg = _( "Couldn't find any apps, required for this field.\n" "Tried: {fqns}").format(fqns=', '.join(fqns)) self.widget = ErrorWidget(message=msg) # NOTE(kzaitsev): this closure is needed to allow us have custom # logic when clicking add button def _make_link(): ns_url = 'horizon:app-catalog:catalog:add' ns_url_args = (environment_id, False, True) # This will prevent horizon from adding an extra '+' button if not matching_classes: return '' return json.dumps([ (app.name, reverse(ns_url, args=((app.id,) + ns_url_args))) for app in matching_classes]) self.widget.add_item_link = _make_link apps = env_api.service_list_by_fqns( request, environment_id, [app.fully_qualified_name for app in matching_classes]) choices = [('', self.empty_value_message)] choices.extend([(app['?']['id'], html.escape(app.name)) for app in apps]) self.choices = choices # NOTE(tsufiev): streamline the drop-down UX: auto-select the # single available option in a drop-down if len(choices) == 2: self.initial = choices[1][0]
def test_app_by_fqn_except_stop_iteration(self): self.mock_client = mock.Mock(spec=client) self.mock_client.packages.filter().next.side_effect = StopIteration packages.api.muranoclient.return_value = self.mock_client self.mock_client.reset_mock() setattr(packages.settings, "MURANO_USE_GLARE", True) app = packages.app_by_fqn(self.mock_request, 'test_fqn', version='1.0') self.assertIsNone(app) self.mock_client.packages.filter.assert_called_once_with( fqn='test_fqn', catalog=True, version='1.0')
def test_app_by_fqn(self): self.mock_client = MagicIterMock(spec=client) mock_next(self.mock_client.packages.filter(), 'return_value', self.packages[0]) packages.api.muranoclient.return_value = self.mock_client self.mock_client.reset_mock() setattr(packages.settings, "MURANO_USE_GLARE", True) app = packages.app_by_fqn(self.mock_request, 'test_fqn', version='1.0') self.assertIsNotNone(app) self.assertEqual(self.packages[0], app) self.mock_client.packages.filter.assert_called_once_with( fqn='test_fqn', catalog=True, version='1.0')
def get_app_image(request, app_fqdn, status=None): package = pkg_cli.app_by_fqn(request, app_fqdn) if status in [ consts.STATUS_ID_DEPLOY_FAILURE, consts.STATUS_ID_DELETE_FAILURE, ]: url = static('dashboard/img/stack-red.svg') elif status == consts.STATUS_ID_READY: url = static('dashboard/img/stack-green.svg') else: url = static('dashboard/img/stack-gray.svg') if package: app_id = package.id url = reverse("horizon:murano:catalog:images", args=(app_id,)) return url
def get_app_image(request, app_fqdn, status=None): package = pkg_cli.app_by_fqn(request, app_fqdn) if status in [ consts.STATUS_ID_DEPLOY_FAILURE, consts.STATUS_ID_DELETE_FAILURE, ]: url = static('dashboard/img/stack-red.svg') elif status == consts.STATUS_ID_READY: url = static('dashboard/img/stack-green.svg') else: url = static('dashboard/img/stack-gray.svg') if package: app_id = package.id url = reverse("horizon:murano:catalog:images", args=(app_id, )) return url
def test_app_by_fqn_except_stop_iteration(self): self.mock_client = MagicIterMock(spec=client) mock_next( self.mock_client.packages.filter(), 'side_effect', StopIteration ) packages.api.muranoclient.return_value = self.mock_client self.mock_client.reset_mock() setattr(packages.settings, "MURANO_USE_GLARE", True) app = packages.app_by_fqn(self.mock_request, 'test_fqn', version='1.0') self.assertIsNone(app) self.mock_client.packages.filter.assert_called_once_with( fqn='test_fqn', catalog=True, version='1.0')
def test_app_by_fqn(self): self.mock_client = MagicIterMock(spec=client) mock_next( self.mock_client.packages.filter(), 'return_value', self.packages[0] ) packages.api.muranoclient.return_value = self.mock_client self.mock_client.reset_mock() setattr(packages.settings, "MURANO_USE_GLARE", True) app = packages.app_by_fqn(self.mock_request, 'test_fqn', version='1.0') self.assertIsNotNone(app) self.assertEqual(self.packages[0], app) self.mock_client.packages.filter.assert_called_once_with( fqn='test_fqn', catalog=True, version='1.0')
def get_app_image(request, app_fqdn, status=None): if '@' in app_fqdn: class_fqn, package_fqn = app_fqdn.split('@') if '/' in class_fqn: class_fqn, version = class_fqn.split('/') else: version = None else: package_fqn = app_fqdn version = None package = pkg_cli.app_by_fqn(request, package_fqn, version=version) if status in [ consts.STATUS_ID_DEPLOY_FAILURE, consts.STATUS_ID_DELETE_FAILURE, ]: url = static('dashboard/img/stack-red.svg') elif status == consts.STATUS_ID_READY: url = static('dashboard/img/stack-green.svg') else: url = static('dashboard/img/stack-gray.svg') if package: app_id = package.id url = reverse("horizon:app-catalog:catalog:images", args=(app_id,)) return url
def get_app_image(request, app_fqdn, status=None): if '@' in app_fqdn: class_fqn, package_fqn = app_fqdn.split('@') if '/' in class_fqn: class_fqn, version = class_fqn.split('/') else: version = None else: package_fqn = app_fqdn version = None package = pkg_cli.app_by_fqn(request, package_fqn, version=version) if status in [ consts.STATUS_ID_DEPLOY_FAILURE, consts.STATUS_ID_DELETE_FAILURE, ]: url = static('dashboard/img/stack-red.svg') elif status == consts.STATUS_ID_READY: url = static('dashboard/img/stack-green.svg') else: url = static('dashboard/img/stack-gray.svg') if package: app_id = package.id url = reverse("horizon:app-catalog:catalog:images", args=(app_id, )) return url
def services_list(request, environment_id): """Get environment applications. This function collects data from Murano API and modifies it only for dashboard purposes. Those changes don't impact application deployment parameters. """ def strip(msg, to=100): return u'%s...' % msg[:to] if len(msg) > to else msg services = [] # need to create new session to see services deployed by other user session_id = Session.get(request, environment_id) get_environment = api.muranoclient(request).environments.get environment = get_environment(environment_id, session_id) try: client = api.muranoclient(request) reports = client.environments.last_status(environment_id, session_id) except exc.HTTPNotFound: LOG.exception( _('Could not retrieve latest status for ' 'the {0} environment').format(environment_id)) reports = {} for service_item in environment.services or []: service_data = service_item service_id = service_data['?']['id'] if service_id in reports and reports[service_id]: last_operation = strip(reports[service_id].text) time = reports[service_id].updated else: last_operation = 'Component draft created' \ if environment.version == 0 else '' try: time = service_data['updated'][:-7] except KeyError: time = None service_data['environment_id'] = environment_id service_data['environment_version'] = environment.version service_data['operation'] = last_operation service_data['operation_updated'] = time if service_data['?'].get('name'): service_data['name'] = service_data['?']['name'] if (consts.DASHBOARD_ATTRS_KEY not in service_data['?'] or not service_data['?'][consts.DASHBOARD_ATTRS_KEY].get('name')): fqn = service_data['?']['type'] version = None if '/' in fqn: version, fqn = fqn.split('/')[1].split('@') pkg = packages_api.app_by_fqn(request, fqn, version=version) if pkg: app_name = pkg.name storage = service_data['?'].setdefault( consts.DASHBOARD_ATTRS_KEY, {}) storage['name'] = app_name services.append(service_data) LOG.debug('Service::List') return [utils.Bunch(**service) for service in services]
def services_list(request, environment_id): """Get environment applications. This function collects data from Murano API and modifies it only for dashboard purposes. Those changes don't impact application deployment parameters. """ def strip(msg, to=100): return u'%s...' % msg[:to] if len(msg) > to else msg services = [] # need to create new session to see services deployed by other user session_id = Session.get(request, environment_id) get_environment = api.muranoclient(request).environments.get environment = get_environment(environment_id, session_id) try: client = api.muranoclient(request) reports = client.environments.last_status(environment_id, session_id) except exc.HTTPNotFound: LOG.exception(_('Could not retrieve latest status for ' 'the {0} environment').format(environment_id)) reports = {} for service_item in environment.services or []: service_data = service_item try: service_id = service_data['?']['id'] except KeyError as e: exceptions.handle_recoverable( request, KEY_ERROR_TEMPLATE % e.message) continue if service_id in reports and reports[service_id]: last_operation = strip(reports[service_id].text) time = reports[service_id].updated else: last_operation = 'Component draft created' \ if environment.version == 0 else '' try: time = service_data['updated'][:-7] except KeyError: time = None service_data['environment_id'] = environment_id service_data['environment_version'] = environment.version service_data['operation'] = last_operation service_data['operation_updated'] = time if service_data['?'].get('name'): service_data['name'] = service_data['?']['name'] if (consts.DASHBOARD_ATTRS_KEY not in service_data['?'] or not service_data['?'][consts.DASHBOARD_ATTRS_KEY].get('name')): try: fqn = service_data['?']['type'] except KeyError as e: exceptions.handle_recoverable( request, KEY_ERROR_TEMPLATE % e.message) continue version = None if '/' in fqn: version, fqn = fqn.split('/')[1].split('@') pkg = packages_api.app_by_fqn(request, fqn, version=version) if pkg: app_name = pkg.name storage = service_data['?'].setdefault( consts.DASHBOARD_ATTRS_KEY, {}) storage['name'] = app_name services.append(service_data) LOG.debug('Service::List') return [utils.Bunch(**service) for service in services]