diff --git a/kingbird_dashboard/api/client.py b/kingbird_dashboard/api/client.py index 09212e1..d6b3f16 100644 --- a/kingbird_dashboard/api/client.py +++ b/kingbird_dashboard/api/client.py @@ -1,138 +1,77 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at +# Copyright 2018 - Ericsson AB. # -# http://www.apache.org/licenses/LICENSE-2.0 +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at # -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from django.conf import settings + +from horizon.utils import memoized + +import kingbirdclient + +from kingbirdclient.api import client as kb_client + +SERVICE_TYPE = 'synchronization' -from __future__ import absolute_import - -import logging - -# enable following after client product implemented. -# from kingbird_dashboardclient.v1 import client as kingbird_dashboard_client - -from horizon import exceptions -from horizon.utils.memoized import memoized -from openstack_dashboard.api import base - -# for stab, should remove when use CLI API -import copy -from datetime import datetime -import uuid +@memoized.memoized +def kingbird_dashboardclient(request): + """Kingbird Client for API calls.""" + return kb_client.client( + username=request.user.username, + auth_token=request.user.token.id, + project_id=request.user.tenant_id, + auth_url=getattr(settings, 'OPENSTACK_KEYSTONE_URL') + ) -LOG = logging.getLogger(__name__) - -ATTRIBUTES = ['name', 'description', 'enabled', 'size', 'temperature', - 'base', 'flavor', 'topping'] - -STUB_DATA = {} +def list_defaults(request): + """Default Quota Limits.""" + return kingbird_dashboardclient(request).quota_manager.\ + list_defaults() -# for stab, should be removed when use CLI API -class StubResponse(object): - - def __init__(self, info): - self._info = info - - def __repr__(self): - reprkeys = sorted(k for k in self.__dict__.keys() if k[0] != '_') - info = ", ".join("%s=%s" % (k, getattr(self, k)) for k in reprkeys) - return "<%s %s>" % (self.__class__.__name__, info) - - def to_dict(self): - return copy.deepcopy(self._info) +def global_limits(request, target_tenant_id): + """Global Quota Limits for any tenant.""" + return kingbird_dashboardclient(request).quota_manager.\ + global_limits(target_tenant_id) -@memoized -def apiclient(request): - api_url = "" - c = None +def update_global_limits(request, target_tenant_id, **data): + """Update Global Limits for a tenant.""" + return kingbird_dashboardclient(request).quota_manager.\ + update_global_limits(target_tenant_id, **data) + +def sync_quota(request, target_tenant_id): + """On Demand Quota Sync.""" + return kingbird_dashboardclient(request).quota_manager.\ + sync_quota(target_tenant_id) + + +def delete_quota(request, target_tenant_id): + """Delete Quota for a tenant.""" try: - api_url = base.url_for(request, 'kingbird') - except exceptions.ServiceCatalogException: - LOG.debug('No Kingbird Management service is configured.') - return None - - LOG.debug('kingbird_dashboardclient using the token "%s" and url' - '"%s"' % (request.user.token.id, api_url)) - # enable following after client product implemented. - # c = kingbird_dashboard_client.Client( - # username=request.user.username, - # project_id=request.user.tenant_id, - # input_auth_token=request.user.token.id, - # api_url=api_url) - return c + kingbird_dashboardclient(request).quota_manager.\ + delete_quota(target_tenant_id) + return True + except kingbirdclient.exceptions.APIException: + raise -def kingbird_create(request, **kwargs): - args = {} - for (key, value) in kwargs.items(): - if key in ATTRIBUTES: - args[str(key)] = value - else: - raise exceptions.BadRequest( - "Key must be in %s" % ",".join(ATTRIBUTES)) - # created = apiclient(request).kingbirds.create(**args) - - # create dummy response - args["uuid"] = uuid.uuid1().hex - args["created_at"] = datetime.now().isoformat() - created = StubResponse(args) - for k in args: - setattr(created, k, args[k]) - STUB_DATA[created.uuid] = created - - return created - - -def kingbird_update(request, id, **kwargs): - args = {} - for (key, value) in kwargs.items(): - if key in ATTRIBUTES: - args[str(key)] = value - else: - raise exceptions.BadRequest( - "Key must be in %s" % ",".join(ATTRIBUTES)) - # updated = apiclient(request).kingbird.update(id, **args) - - # update dummy response - args["uuid"] = id - args["updated_at"] = datetime.now().isoformat() - updated = StubResponse(args) - for k in args: - setattr(updated, k, args[k]) - STUB_DATA[updated.uuid] = updated - - return updated - - -def kingbird_delete(request, id): - # deleted = apiclient(request).kingbirds.delete(id) - deleted = STUB_DATA.pop(id) - - return deleted - - -def kingbird_list( - request, limit=None, marker=None, sort_key=None, - sort_dir=None, detail=True): - - # list = apiclient(request).Kingbirds.list(limit, marker, sort_key, - # sort_dir, detail) - list = [STUB_DATA[data] for data in STUB_DATA] - return list - - -def kingbird_show(request, id): - # show = apiclient(request).kingbirds.get(id) - show = STUB_DATA.get(id) - return show +def detail_quota(request, target_tenant_id): + """Quota Information of a tenant.""" + try: + return kingbird_dashboardclient(request).quota_manager.\ + quota_detail(target_tenant_id) + except kingbirdclient.exceptions.APIException: + raise diff --git a/kingbird_dashboard/api/rest_api.py b/kingbird_dashboard/api/rest_api.py deleted file mode 100644 index f18e0d6..0000000 --- a/kingbird_dashboard/api/rest_api.py +++ /dev/null @@ -1,86 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from django.views import generic - -from kingbird_dashboard.api import client - -from openstack_dashboard.api.rest import urls -from openstack_dashboard.api.rest import utils as rest_utils - - -def change_to_id(obj): - """Change key named 'uuid' to 'id' - - API returns objects with a field called 'uuid' many of Horizons - directives however expect objects to have a field called 'id'. - """ - obj['id'] = obj.pop('uuid') - return obj - - -@urls.register -class Kingbird(generic.View): - """API for retrieving a single Kingbird""" - url_regex = r'kingbird_dashboard/kingbirds/(?P[^/]+)$' - - @rest_utils.ajax() - def get(self, request, id): - """Get a specific kingbird""" - return change_to_id(client.kingbird_show(request, id).to_dict()) - - @rest_utils.ajax(data_required=True) - def post(self, request, id): - """Update a Kingbird. - - Returns the updated Kingbird object on success. - """ - kingbird = client.kingbird_update(request, id, **request.DATA) - return rest_utils.CreatedResponse( - '/api/kingbird_dashboard/kingbird/%s' % kingbird.uuid, - kingbird.to_dict()) - - -@urls.register -class Kingbirds(generic.View): - """API for Kingbirds""" - url_regex = r'kingbird_dashboard/kingbirds/$' - - @rest_utils.ajax() - def get(self, request): - """Get a list of the Kingbirds for a project. - - The returned result is an object with property 'items' and each - item under this is a Kingbird. - """ - result = client.kingbird_list(request) - return {'items': [change_to_id(n.to_dict()) for n in result]} - - @rest_utils.ajax(data_required=True) - def delete(self, request): - """Delete one or more Kingbirds by id. - - Returns HTTP 204 (no content) on successful deletion. - """ - for id in request.DATA: - client.kingbird_delete(request, id) - - @rest_utils.ajax(data_required=True) - def put(self, request): - """Create a new Kingbird. - - Returns the new Kingbird object on success. - """ - kingbird = client.kingbird_create(request, **request.DATA) - return rest_utils.CreatedResponse( - '/api/kingbird_dashboard/kingbird/%s' % kingbird.uuid, - kingbird.to_dict()) diff --git a/kingbird_dashboard/content/kingbirds/panel.py b/kingbird_dashboard/dashboard.py similarity index 65% rename from kingbird_dashboard/content/kingbirds/panel.py rename to kingbird_dashboard/dashboard.py index b139977..36c3826 100644 --- a/kingbird_dashboard/content/kingbirds/panel.py +++ b/kingbird_dashboard/dashboard.py @@ -1,3 +1,5 @@ +# Copyright 2018 Ericsson AB. +# # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at @@ -11,13 +13,21 @@ # under the License. from django.utils.translation import ugettext_lazy as _ + import horizon -# This panel will be loaded from horizon, because specified in enabled file. -# To register REST api, import below here. -from kingbird_dashboard.api import rest_api # noqa: F401 +from kingbird_dashboard.default import panel -class Kingbirds(horizon.Panel): - name = _("Kingbirds") - slug = "kingbirds" +class Kingbird(horizon.Dashboard): + name = _("Kingbird") + slug = "kingbird" + panels = ( + 'default' + 'resource management', + 'quota management') + default_panel = "default" + + +horizon.register(Kingbird) +Kingbird.register(panel.Default) diff --git a/kingbird_dashboard/content/__init__.py b/kingbird_dashboard/default/__init__.py similarity index 100% rename from kingbird_dashboard/content/__init__.py rename to kingbird_dashboard/default/__init__.py diff --git a/kingbird_dashboard/default/panel.py b/kingbird_dashboard/default/panel.py new file mode 100644 index 0000000..7864414 --- /dev/null +++ b/kingbird_dashboard/default/panel.py @@ -0,0 +1,24 @@ +# Copyright 2018 Ericsson AB. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from django.utils.translation import ugettext_lazy as _ + +import horizon + + +class Default(horizon.Panel): + name = _("Default") + slug = 'default' + urls = 'kingbird_dashboard.quota_management.urls' + nav = False diff --git a/kingbird_dashboard/default/templates/default/base.html b/kingbird_dashboard/default/templates/default/base.html new file mode 100644 index 0000000..a60127c --- /dev/null +++ b/kingbird_dashboard/default/templates/default/base.html @@ -0,0 +1,8 @@ +{% extends 'base.html' %} +{% load i18n %} + +{% block css %} + {% include "_stylesheets.html" %} + +{% endblock %} + diff --git a/kingbird_dashboard/default/templates/default/table.html b/kingbird_dashboard/default/templates/default/table.html new file mode 100644 index 0000000..07a3d06 --- /dev/null +++ b/kingbird_dashboard/default/templates/default/table.html @@ -0,0 +1,7 @@ +{% extends 'kingbird/default/base.html' %} + +{% block main %} +
+ {{ table.render }} +
+{% endblock %} diff --git a/kingbird_dashboard/enabled/_91_kingbird_quotasync.py b/kingbird_dashboard/enabled/_91_kingbird_quotasync.py index 0f4bdb4..9500128 100644 --- a/kingbird_dashboard/enabled/_91_kingbird_quotasync.py +++ b/kingbird_dashboard/enabled/_91_kingbird_quotasync.py @@ -22,5 +22,10 @@ PANEL = 'quota_management' # The slug of the dashboard the PANEL_GROUP associated with. Required. PANEL_DASHBOARD = 'kingbird' -# Python panel class of the PANEL to be added +# Python panel class of the PANEL to be added. ADD_PANEL = 'kingbird_dashboard.quota_management.panel.QuotaManagement' + +# Static CSS files to be added to Kingbird. +ADD_SCSS_FILES = ['dashboard/kingbird_dashboard/css/style.css'] + +AUTO_DISCOVER_STATIC_FILES = True diff --git a/kingbird_dashboard/error_handling.py b/kingbird_dashboard/error_handling.py new file mode 100644 index 0000000..1ae68ba --- /dev/null +++ b/kingbird_dashboard/error_handling.py @@ -0,0 +1,74 @@ +# Copyright 2018 Ericsson AB. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import functools +import inspect + +import horizon.exceptions + + +def handle_errors(error_message, error_default=None, request_arg=None): + """A decorator for adding default error handling to API calls. + + It wraps the original method in a try-except block, with horizon's + error handling added. + + Note: it should only be used on functions or methods that take request as + their argument (it has to be named "request", or ``request_arg`` has to be + provided, indicating which argument is the request). + + The decorated method accepts a number of additional parameters: + + :param _error_handle: whether to handle the errors in this call + :param _error_message: override the error message + :param _error_default: override the default value returned on error + :param _error_redirect: specify a redirect url for errors + :param _error_ignore: ignore known errors + """ + def decorator(func): + if request_arg is None: + _request_arg = 'request' + if _request_arg not in inspect.getargspec(func).args: + raise RuntimeError( + "The handle_errors decorator requires 'request' as " + "an argument of the function or method being decorated") + else: + _request_arg = request_arg + + @functools.wraps(func) + def wrapper(*args, **kwargs): + _error_handle = kwargs.pop('_error_handle', True) + _error_message = kwargs.pop('_error_message', error_message) + _error_default = kwargs.pop('_error_default', error_default) + _error_redirect = kwargs.pop('_error_redirect', None) + _error_ignore = kwargs.pop('_error_ignore', False) + + if not _error_handle: + return func(*args, **kwargs) + try: + return func(*args, **kwargs) + except Exception as e: + callargs = inspect.getcallargs(func, *args, **kwargs) + request = callargs[_request_arg] + _error_message += ': ' + str(e) + horizon.exceptions.handle(request, _error_message, + ignore=_error_ignore, + redirect=_error_redirect) + return _error_default + + wrapper.wrapped = func + + return wrapper + + return decorator diff --git a/kingbird_dashboard/karma.conf.js b/kingbird_dashboard/karma.conf.js deleted file mode 100644 index d7c4e44..0000000 --- a/kingbird_dashboard/karma.conf.js +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 (the 'License'); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an 'AS IS' BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -'use strict'; - -var fs = require('fs'); -var path = require('path'); - -module.exports = function (config) { - // This tox venv is setup in the post-install npm step - var toxPath = '../.tox/py27/lib/python2.7/site-packages/'; - - config.set({ - preprocessors: { - // Used to collect templates for preprocessing. - // NOTE: the templates must also be listed in the files section below. - './static/**/*.html': ['ng-html2js'], - // Used to indicate files requiring coverage reports. - './static/**/!(*.spec).js': ['coverage'], - }, - - // Sets up module to process templates. - ngHtml2JsPreprocessor: { - prependPrefix: '/', - moduleName: 'templates' - }, - - basePath: './', - - // Contains both source and test files. - files: [ - /* - * shim, partly stolen from /i18n/js/horizon/ - * Contains expected items not provided elsewhere (dynamically by - * Django or via jasmine template. - */ - '../test-shim.js', - - // from jasmine.html - toxPath + 'xstatic/pkg/jquery/data/jquery.js', - toxPath + 'xstatic/pkg/angular/data/angular.js', - toxPath + 'xstatic/pkg/angular/data/angular-route.js', - toxPath + 'xstatic/pkg/angular/data/angular-mocks.js', - toxPath + 'xstatic/pkg/angular/data/angular-cookies.js', - toxPath + 'xstatic/pkg/angular_bootstrap/data/angular-bootstrap.js', - toxPath + 'xstatic/pkg/angular_gettext/data/angular-gettext.js', - toxPath + 'xstatic/pkg/angular/data/angular-sanitize.js', - toxPath + 'xstatic/pkg/d3/data/d3.js', - toxPath + 'xstatic/pkg/rickshaw/data/rickshaw.js', - toxPath + 'xstatic/pkg/angular_smart_table/data/smart-table.js', - toxPath + 'xstatic/pkg/angular_lrdragndrop/data/lrdragndrop.js', - toxPath + 'xstatic/pkg/spin/data/spin.js', - toxPath + 'xstatic/pkg/spin/data/spin.jquery.js', - toxPath + 'xstatic/pkg/tv4/data/tv4.js', - toxPath + 'xstatic/pkg/objectpath/data/ObjectPath.js', - toxPath + 'xstatic/pkg/angular_schema_form/data/schema-form.js', - toxPath + 'xstatic/pkg/angular_fileupload/data/ng-file-upload.js', - - - // TODO: These should be mocked. - toxPath + '/horizon/static/horizon/js/horizon.js', - - /** - * Include framework source code from horizon that we need. - * Otherwise, karma will not be able to find them when testing. - * These files should be mocked in the foreseeable future. - */ - toxPath + 'horizon/static/framework/**/*.module.js', - toxPath + 'horizon/static/framework/**/!(*.spec|*.mock).js', - toxPath + 'openstack_dashboard/static/**/*.module.js', - toxPath + 'openstack_dashboard/static/**/!(*.spec|*.mock).js', - toxPath + 'openstack_dashboard/dashboards/**/static/**/*.module.js', - toxPath + 'openstack_dashboard/dashboards/**/static/**/!(*.spec|*.mock).js', - - /** - * First, list all the files that defines application's angular modules. - * Those files have extension of `.module.js`. The order among them is - * not significant. - */ - './static/**/*.module.js', - - /** - * Followed by other JavaScript files that defines angular providers - * on the modules defined in files listed above. And they are not mock - * files or spec files defined below. The order among them is not - * significant. - */ - './static/**/!(*.spec|*.mock).js', - - /** - * Then, list files for mocks with `mock.js` extension. The order - * among them should not be significant. - */ - toxPath + 'openstack_dashboard/static/**/*.mock.js', - - /** - * Finally, list files for spec with `spec.js` extension. The order - * among them should not be significant. - */ - './static/**/*.spec.js', - - /** - * Angular external templates - */ - './static/**/*.html' - ], - - autoWatch: true, - - frameworks: ['jasmine'], - - browsers: ['Chrome'], - - browserNoActivityTimeout: 60000, - - reporters: ['progress', 'coverage', 'threshold'], - - plugins: [ - 'karma-chrome-launcher', - 'karma-jasmine', - 'karma-ng-html2js-preprocessor', - 'karma-coverage', - 'karma-threshold-reporter' - ], - - // Places coverage report in HTML format in the subdirectory below. - coverageReporter: { - type: 'html', - dir: '../cover/karma/' - }, - - // Coverage threshold values. - thresholdReporter: { - statements: 10, // target 100 - branches: 0, // target 100 - functions: 10, // target 100 - lines: 10 // target 100 - } - }); -}; diff --git a/kingbird_dashboard/content/kingbirds/__init__.py b/kingbird_dashboard/quota_management/__init__.py similarity index 100% rename from kingbird_dashboard/content/kingbirds/__init__.py rename to kingbird_dashboard/quota_management/__init__.py diff --git a/kingbird_dashboard/quota_management/forms.py b/kingbird_dashboard/quota_management/forms.py new file mode 100644 index 0000000..8d30382 --- /dev/null +++ b/kingbird_dashboard/quota_management/forms.py @@ -0,0 +1,119 @@ +# Copyright 2018 - Ericsson AB. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +from django.core.urlresolvers import reverse +from django.utils.translation import ugettext_lazy as _ + +from horizon import exceptions +from horizon import forms +from horizon import messages + +from kingbird_dashboard.api import client as kb_client + + +INDEX_URL = "horizon:kingbird:quota_management:index" + + +class UpdateForm(forms.SelfHandlingForm): + ifcb_label = _("Injected File Content (Bytes)") + ifpb_label = _("Length of Injected File Path") + metadata_items = forms.IntegerField(min_value=-1, + label=_("Metadata Items")) + cores = forms.IntegerField(min_value=-1, label=_("VCPUs")) + instances = forms.IntegerField(min_value=-1, label=_("Instances")) + key_pairs = forms.IntegerField(min_value=-1, label=_("Key Pairs")) + volumes = forms.IntegerField(min_value=-1, label=_("Volumes")) + snapshots = forms.IntegerField(min_value=-1, label=_("Volume Snapshots")) + gigabytes = forms.IntegerField( + min_value=-1, label=_("Total Size of Volumes and Snapshots (GiB)")) + backup_gigabytes = forms.IntegerField( + min_value=-1, label=_( + "Total Size of backup Volumes and Snapshots (GiB)")) + backups = forms.IntegerField( + min_value=-1, label=_( + "Total Size of backup Volumes and Snapshots (GiB)")) + ram = forms.IntegerField(min_value=-1, label=_("RAM (MB)")) + floating_ips = forms.IntegerField(min_value=-1, label=_("Floating IPs")) + fixed_ips = forms.IntegerField(min_value=-1, label=_("Fixed IPs")) + security_groups = forms.IntegerField(min_value=-1, + label=_("Security Groups")) + security_group = forms.IntegerField(min_value=-1, + label=_("Security Groups")) + security_group_rule = forms.IntegerField(min_value=-1, + label=_("Security Group Rules")) + floatingip = forms.IntegerField(min_value=-1, label=_("Floating IPs")) + network = forms.IntegerField(min_value=-1, label=_("Networks")) + port = forms.IntegerField(min_value=-1, label=_("Ports")) + router = forms.IntegerField(min_value=-1, label=_("Routers")) + subnet = forms.IntegerField(min_value=-1, label=_("Subnets")) + + def __init__(self, request, *args, **kwargs): + super(UpdateForm, self).__init__(request, *args, + **kwargs) + target_tenant_id = request.build_absolute_uri().split('/')[-2] + quotas = kb_client.global_limits(request, target_tenant_id) + result = {i._data: i._Limit for i in quotas} + for field in result: + if field in self.fields: + self.fields[field].initial = result[field] + + def handle(self, request, data): + try: + target_tenant_id = request.build_absolute_uri().split('/')[-2] + default_quota_obj = kb_client.global_limits(request, + target_tenant_id) + default_quota = {i._data: i._Limit for i in default_quota_obj} + for resource in default_quota: + if default_quota[resource] == data[resource]: + del data[resource] + if data: + kb_client.update_global_limits(request, target_tenant_id, + **data) + msg = _('Quotas updated successfully for tenant "%s".') \ + % target_tenant_id + messages.success(request, msg) + + return True + except Exception as e: + msg = _('Failed to update "%s".') % e + redirect = reverse('horizon:kingbird:quota_management:index') + exceptions.handle(request, msg, redirect=redirect) + + +class SyncQuotaForm(forms.SelfHandlingForm): + def handle(self, request, data=None): + target_tenant = request.build_absolute_uri().split('/')[-2] + try: + kb_client.sync_quota(request, target_tenant) + msg = _('On demand Quota sync has been triggered.') + messages.success(request, msg) + return True + except Exception as e: + msg = _('Failed to Sync Quota "%s".') % e + + +class DeleteQuotaForm(forms.SelfHandlingForm): + def handle(self, request, data=None): + target_tenant = request.build_absolute_uri().split('/')[-2] + msg = _('Request to delete quotas has been triggered.') + err_msg = _('Failed to Delete Quota .') + try: + kb_client.delete_quota(request, target_tenant) + messages.success(request, msg) + return True + except Exception as e: + msg = _('Failed to delete quotas for the tenant "%s".') % e + redirect = reverse('horizon:kingbird:quota_management:index') + exceptions.handle(request, err_msg, redirect=redirect) diff --git a/kingbird_dashboard/content/kingbirds/urls.py b/kingbird_dashboard/quota_management/panel.py similarity index 72% rename from kingbird_dashboard/content/kingbirds/urls.py rename to kingbird_dashboard/quota_management/panel.py index 772c238..39c4f72 100644 --- a/kingbird_dashboard/content/kingbirds/urls.py +++ b/kingbird_dashboard/quota_management/panel.py @@ -1,3 +1,5 @@ +# Copyright 2018 Ericsson AB. +# # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at @@ -10,11 +12,15 @@ # License for the specific language governing permissions and limitations # under the License. -from django.conf.urls import url from django.utils.translation import ugettext_lazy as _ -from horizon.browsers import views -title = _("Kingbirds") -urlpatterns = [ - url('', views.AngularIndexView.as_view(title=title), name='index'), -] +import horizon + +from kingbird_dashboard import dashboard + + +class QuotaManagement(horizon.Panel): + name = _("Quota Management") + slug = 'quota_management' + +dashboard.Kingbird.register(QuotaManagement) diff --git a/kingbird_dashboard/quota_management/tables.py b/kingbird_dashboard/quota_management/tables.py new file mode 100644 index 0000000..df12a5c --- /dev/null +++ b/kingbird_dashboard/quota_management/tables.py @@ -0,0 +1,63 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from django.utils.translation import ugettext_lazy as _ + +from horizon import tables + + +class UpdateQuota(tables.LinkAction): + name = "update" + verbose_name = _("Update") + url = "horizon:kingbird:quota_management:update" + classes = ("ajax-modal", "btn-edit") + + +class QuotaSync(tables.LinkAction): + name = "quota_sync" + verbose_name = _("Sync Quota") + url = "horizon:kingbird:quota_management:sync" + classes = ("ajax-modal", "btn-edit") + + +class DeleteQuota(tables.LinkAction): + name = "delete_quota" + verbose_name = _("Delete Quota") + url = "horizon:kingbird:quota_management:delete" + classes = ("ajax-modal", "btn-edit") + + +class TenantsTable(tables.DataTable): + name = tables.Column( + "name", + verbose_name=_("Name") + ) + description = tables.Column( + "description", + verbose_name=_("Description") + ) + id = tables.Column( + "id", + verbose_name=_("Project ID"), + ) + enabled = tables.Column( + "enabled", + verbose_name=_("Enabled"), + ) + + def get_object_id(self, datum): + return datum.id + + class Meta(object): + name = "tenant_set" + verbose_name = _("Quota Management") + row_actions = (UpdateQuota, QuotaSync, DeleteQuota) diff --git a/kingbird_dashboard/quota_management/templates/quota_management/_delete.html b/kingbird_dashboard/quota_management/templates/quota_management/_delete.html new file mode 100644 index 0000000..96ec464 --- /dev/null +++ b/kingbird_dashboard/quota_management/templates/quota_management/_delete.html @@ -0,0 +1,18 @@ +{% extends "horizon/common/_modal_form.html" %} +{% load i18n %} + +{% block form_id %}Delete Quota{% endblock %} +{% block form_action %}{% url 'horizon:kingbird:quota_management:delete' project_id %}{% endblock %} + +{% block modal-header %}{% trans "Delete Quota Sync" %}{% endblock %} + +{% block modal-body %} +
+
+ {% include "horizon/common/_form_fields.html" %} +
+

Delete Quotas for this tenant.

+
+ +{% endblock %} + diff --git a/kingbird_dashboard/quota_management/templates/quota_management/_sync.html b/kingbird_dashboard/quota_management/templates/quota_management/_sync.html new file mode 100644 index 0000000..da98fe6 --- /dev/null +++ b/kingbird_dashboard/quota_management/templates/quota_management/_sync.html @@ -0,0 +1,18 @@ +{% extends "horizon/common/_modal_form.html" %} +{% load i18n %} + +{% block form_id %}Sync Quota{% endblock %} +{% block form_action %}{% url 'horizon:kingbird:quota_management:sync' project_id %}{% endblock %} + +{% block modal-header %}{% trans "Trigger Quota Sync" %}{% endblock %} + +{% block modal-body %} +
+
+ {% include "horizon/common/_form_fields.html" %} +
+

Click Sync to sync Quotas Dynamically.

+
+ +{% endblock %} + diff --git a/kingbird_dashboard/quota_management/templates/quota_management/_update.html b/kingbird_dashboard/quota_management/templates/quota_management/_update.html new file mode 100644 index 0000000..68831be --- /dev/null +++ b/kingbird_dashboard/quota_management/templates/quota_management/_update.html @@ -0,0 +1,20 @@ +{% extends "horizon/common/_modal_form.html" %} +{% load i18n %} + +{% block form_id %}update_quota{% endblock %} +{% block form_action %}{% url 'horizon:kingbird:quota_management:update' project_id %}{% endblock %} + +{% block modal-header %}{% trans "Update Quotas" %}{% endblock %} + +{% block modal-body %} +
+
+ {% include "horizon/common/_form_fields.html" %} +
+
+
+

{% trans "Description:" %}

+

{% trans "From here you can update quotas." %}

+
+{% endblock %} + diff --git a/kingbird_dashboard/quota_management/templates/quota_management/delete.html b/kingbird_dashboard/quota_management/templates/quota_management/delete.html new file mode 100644 index 0000000..6b864f6 --- /dev/null +++ b/kingbird_dashboard/quota_management/templates/quota_management/delete.html @@ -0,0 +1,11 @@ +{% extends 'kingbird/default/base.html' %} +{% load i18n %} +{% block title %}{% trans "Delete Quota" %}{% endblock %} + +{% block page_header %} + {% include "horizon/common/_page_header.html" with title=_("Delete Quota") %} +{% endblock page_header %} + +{% block main %} + {% include 'kingbird/quota_management/_delete.html' %} +{% endblock %} diff --git a/kingbird_dashboard/quota_management/templates/quota_management/index.html b/kingbird_dashboard/quota_management/templates/quota_management/index.html new file mode 100644 index 0000000..56a9aa4 --- /dev/null +++ b/kingbird_dashboard/quota_management/templates/quota_management/index.html @@ -0,0 +1,11 @@ +{% extends 'base.html' %} +{% load i18n %} +{% block title %}{% trans "Quota Management" %}{% endblock %} + +{% block page_header %} + {% include "horizon/common/_domain_page_header.html" with title=page_title %} +{% endblock page_header %} + +{% block main %} + {{ table.render }} +{% endblock %} diff --git a/kingbird_dashboard/quota_management/templates/quota_management/sync.html b/kingbird_dashboard/quota_management/templates/quota_management/sync.html new file mode 100644 index 0000000..a8a43de --- /dev/null +++ b/kingbird_dashboard/quota_management/templates/quota_management/sync.html @@ -0,0 +1,11 @@ +{% extends 'kingbird/default/base.html' %} +{% load i18n %} +{% block title %}{% trans "Update Quota" %}{% endblock %} + +{% block page_header %} + {% include "horizon/common/_page_header.html" with title=_("Update Quota") %} +{% endblock page_header %} + +{% block main %} + {% include 'kingbird/quota_management/_sync.html' %} +{% endblock %} diff --git a/kingbird_dashboard/quota_management/templates/quota_management/update.html b/kingbird_dashboard/quota_management/templates/quota_management/update.html new file mode 100644 index 0000000..f543be8 --- /dev/null +++ b/kingbird_dashboard/quota_management/templates/quota_management/update.html @@ -0,0 +1,11 @@ +{% extends 'kingbird/default/base.html' %} +{% load i18n %} +{% block title %}{% trans "Update Quota" %}{% endblock %} + +{% block page_header %} + {% include "horizon/common/_page_header.html" with title=_("Update Quota") %} +{% endblock page_header %} + +{% block main %} + {% include 'kingbird/quota_management/_update.html' %} +{% endblock %} diff --git a/kingbird_dashboard/content/kingbirds/tests.py b/kingbird_dashboard/quota_management/urls.py similarity index 54% rename from kingbird_dashboard/content/kingbirds/tests.py rename to kingbird_dashboard/quota_management/urls.py index cee7fff..4a33729 100644 --- a/kingbird_dashboard/content/kingbirds/tests.py +++ b/kingbird_dashboard/quota_management/urls.py @@ -1,3 +1,5 @@ +# Copyright 2018 Ericsson AB. +# # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at @@ -10,10 +12,17 @@ # License for the specific language governing permissions and limitations # under the License. -from openstack_dashboard.test import helpers as test +from django.conf.urls import url +from kingbird_dashboard.quota_management import views -class KingbirdsTests(test.TestCase): - # Unit tests for kingbird. - def test_me(self): - self.assertTrue(1 + 1 == 2) +PROJECT_ID = r'^(?P[^/]+)/%s$' + +urlpatterns = [ + url(r'^$', views.IndexView.as_view(), name='index'), + url(PROJECT_ID % 'update', views.UpdateQuotaView.as_view(), + name='update'), + url(PROJECT_ID % 'sync', views.SyncQuotaView.as_view(), name='sync'), + url(PROJECT_ID % 'delete', views.DeleteQuotaView.as_view(), + name='delete'), +] diff --git a/kingbird_dashboard/quota_management/views.py b/kingbird_dashboard/quota_management/views.py new file mode 100644 index 0000000..327e67a --- /dev/null +++ b/kingbird_dashboard/quota_management/views.py @@ -0,0 +1,144 @@ +# Copyright 2018 Ericsson AB. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from django.conf import settings +from django.core.urlresolvers import reverse_lazy +from django.utils.translation import ugettext_lazy as _ + +from horizon import exceptions +from horizon import forms +from horizon import messages +from horizon import tables + +from kingbird_dashboard.quota_management import forms as kb_forms +from kingbird_dashboard.quota_management import tables as kb_tables + +from openstack_dashboard import api as os_api +from openstack_dashboard import policy +from openstack_dashboard.utils import identity + + +class IndexView(tables.DataTableView): + table_id = "tenants" + table_class = kb_tables.TenantsTable + template_name = 'kingbird/quota_management/index.html' + page_title = _("Quota Management") + + def needs_filter_first(self, table): + return self._needs_filter_first + + def has_more_data(self, table): + return self._more + + def get_data(self): + tenants = [] + marker = self.request.GET.get( + kb_tables.TenantsTable._meta.pagination_param, None) + self._more = False + filters = self.get_filters() + + self._needs_filter_first = False + + if policy.check((("identity", "identity:list_projects"),), + self.request): + + # If filter_first is set and if there are not other filters + # selected, then search criteria must be provided and + # return an empty list + filter_first = getattr(settings, 'FILTER_DATA_FIRST', {}) + if filter_first.get('identity.projects', False) and len( + filters) == 0: + self._needs_filter_first = True + self._more = False + return tenants + + domain_id = identity.get_domain_id_for_operation(self.request) + try: + tenants, self._more = os_api.keystone.tenant_list( + self.request, + domain=domain_id, + paginate=True, + filters=filters, + marker=marker) + except Exception: + exceptions.handle(self.request, + _("Unable to retrieve project list.")) + elif policy.check((("identity", "identity:list_user_projects"),), + self.request): + try: + tenants, self._more = os_api.keystone.tenant_list( + self.request, + user=self.request.user.id, + paginate=True, + marker=marker, + filters=filters, + admin=False) + except Exception: + exceptions.handle(self.request, + _("Unable to retrieve project information.")) + else: + msg = \ + _("Insufficient privilege level to view project information.") + messages.info(self.request, msg) + + if os_api.keystone.VERSIONS.active >= 3: + domain_lookup = os_api.keystone.domain_lookup(self.request) + for t in tenants: + t.domain_name = domain_lookup.get(t.domain_id) + return tenants + + +class UpdateQuotaView(forms.ModalFormView): + form_class = kb_forms.UpdateForm + template_name = 'kingbird/quota_management/update.html' + success_url = reverse_lazy("horizon:kingbird:quota_management:index") + submit_label = _("Update") + + def get_context_data(self, **kwargs): + context = super(UpdateQuotaView, self).get_context_data(**kwargs) + context["project_id"] = self.kwargs['project_id'] + return context + + def get_initial(self, **kwargs): + return {'project_id': self.kwargs['project_id']} + + +class SyncQuotaView(forms.ModalFormView): + form_class = kb_forms.SyncQuotaForm + template_name = 'kingbird/quota_management/sync.html' + success_url = reverse_lazy("horizon:kingbird:quota_management:index") + submit_label = _("Sync") + + def get_context_data(self, **kwargs): + context = super(SyncQuotaView, self).get_context_data(**kwargs) + context["project_id"] = self.kwargs['project_id'] + return context + + def get_initial(self, **kwargs): + return {'project_id': self.kwargs['project_id']} + + +class DeleteQuotaView(forms.ModalFormView): + form_class = kb_forms.DeleteQuotaForm + template_name = 'kingbird/quota_management/delete.html' + success_url = reverse_lazy("horizon:kingbird:quota_management:index") + submit_label = _("Delete") + + def get_context_data(self, **kwargs): + context = super(DeleteQuotaView, self).get_context_data(**kwargs) + context["project_id"] = self.kwargs['project_id'] + return context + + def get_initial(self, **kwargs): + return {'project_id': self.kwargs['project_id']} diff --git a/kingbird_dashboard/static/dashboard/kingbird/kingbird.module.js b/kingbird_dashboard/static/dashboard/kingbird/kingbird.module.js deleted file mode 100644 index 0bca840..0000000 --- a/kingbird_dashboard/static/dashboard/kingbird/kingbird.module.js +++ /dev/null @@ -1,40 +0,0 @@ -/** - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. You may obtain - * a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ - -(function() { - 'use strict'; - - /** - * @ngdoc overview - * @name horizon.dashboard.kingbird - * @description - * Dashboard module to host various kingbird panels. - */ - // fixme: if ngRoute and $routeProvider are unnecessary, remove them - /* eslint-disable no-unused-vars */ - angular - .module('horizon.dashboard.kingbird', [ - 'horizon.dashboard.kingbird.kingbirds', - 'ngRoute' - ]) - .config(config); - - config.$inject = ['$provide', '$windowProvider', '$routeProvider']; - - function config($provide, $windowProvider, $routeProvider) { - var path = $windowProvider.$get().STATIC_URL + 'dashboard/kingbird/'; - $provide.constant('horizon.dashboard.kingbird.basePath', path); - } - /* eslint-disable no-unused-vars */ -})(); diff --git a/kingbird_dashboard/static/dashboard/kingbird/kingbird.module.spec.js b/kingbird_dashboard/static/dashboard/kingbird/kingbird.module.spec.js deleted file mode 100644 index e3e50bb..0000000 --- a/kingbird_dashboard/static/dashboard/kingbird/kingbird.module.spec.js +++ /dev/null @@ -1,23 +0,0 @@ -/** - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. You may obtain - * a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ -(function() { - 'use strict'; - - describe('horizon.dashboard.kingbird', function() { - it('should exist', function() { - expect(angular.module('horizon.dashboard.kingbird')).toBeDefined(); - }); - }); - -})(); diff --git a/kingbird_dashboard/static/dashboard/kingbird/kingbird.scss b/kingbird_dashboard/static/dashboard/kingbird/kingbird.scss deleted file mode 100644 index fa4f79a..0000000 --- a/kingbird_dashboard/static/dashboard/kingbird/kingbird.scss +++ /dev/null @@ -1,8 +0,0 @@ -@import "kingbirds/kingbirds"; - -.batch-action { - float: right; - action-list { - padding-left: 0.3em; - } -} diff --git a/kingbird_dashboard/static/dashboard/kingbird/kingbird_dashboard.service.js b/kingbird_dashboard/static/dashboard/kingbird/kingbird_dashboard.service.js deleted file mode 100644 index 4335ed5..0000000 --- a/kingbird_dashboard/static/dashboard/kingbird/kingbird_dashboard.service.js +++ /dev/null @@ -1,80 +0,0 @@ -/** - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -(function () { - 'use strict'; - - angular - .module('horizon.app.core.openstack-service-api') - .factory('horizon.app.core.openstack-service-api.kingbird_dashboard', API); - - API.$inject = [ - 'horizon.framework.util.http.service', - 'horizon.framework.widgets.toast.service', - 'horizon.framework.util.i18n.gettext' - ]; - - function API(apiService, toastService, gettext) { - var service = { - getKingbird: getKingbird, - getKingbirds: getKingbirds, - createKingbird: createKingbird, - updateKingbird: updateKingbird, - deleteKingbird: deleteKingbird - }; - - return service; - - /////////////////////////////// - // Kingbirds - - function getKingbird(id) { - return apiService.get('/api/kingbird_dashboard/kingbirds/' + id) - .error(function() { - var msg = gettext('Unable to retrieve the Kingbird with id: %(id)s.'); - toastService.add('error', interpolate(msg, {id: id}, true)); - }); - } - - function getKingbirds() { - return apiService.get('/api/kingbird_dashboard/kingbirds/') - .error(function() { - toastService.add('error', gettext('Unable to retrieve the Kingbirds.')); - }); - } - - function createKingbird(params) { - return apiService.put('/api/kingbird_dashboard/kingbirds/', params) - .error(function() { - var msg = gettext('Unable to create the Kingbird with name: %(name)s'); - toastService.add('error', interpolate(msg, { name: params.name }, true)); - }); - } - - function updateKingbird(id, params) { - return apiService.post('/api/kingbird_dashboard/kingbirds/' + id, params) - .error(function() { - var msg = gettext('Unable to update the Kingbird with id: %(id)s'); - toastService.add('error', interpolate(msg, { id: params.id }, true)); - }); - } - - function deleteKingbird(id, suppressError) { - var promise = apiService.delete('/api/kingbird_dashboard/kingbirds/', [id]); - return suppressError ? promise : promise.error(function() { - var msg = gettext('Unable to delete the Kingbird with id: %(id)s'); - toastService.add('error', interpolate(msg, { id: id }, true)); - }); - } - } -}()); diff --git a/kingbird_dashboard/static/dashboard/kingbird/kingbirds/actions/actions.module.js b/kingbird_dashboard/static/dashboard/kingbird/kingbirds/actions/actions.module.js deleted file mode 100644 index 317066a..0000000 --- a/kingbird_dashboard/static/dashboard/kingbird/kingbirds/actions/actions.module.js +++ /dev/null @@ -1,87 +0,0 @@ -/** - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. You may obtain - * a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ - -(function() { - 'use strict'; - - /** - * @ngdoc overview - * @ngname horizon.dashboard.kingbird.kingbirds.actions - * - * @description - * Provides all of the actions for Kingbirds. - */ - angular - .module('horizon.dashboard.kingbird.kingbirds.actions', [ - 'horizon.framework', - 'horizon.dashboard.kingbird' - ]) - .run(registerKingbirdActions); - - registerKingbirdActions.$inject = [ - 'horizon.framework.conf.resource-type-registry.service', - 'horizon.framework.util.i18n.gettext', - 'horizon.dashboard.kingbird.kingbirds.create.service', - 'horizon.dashboard.kingbird.kingbirds.update.service', - 'horizon.dashboard.kingbird.kingbirds.delete.service', - 'horizon.dashboard.kingbird.kingbirds.resourceType' - ]; - - function registerKingbirdActions ( - registry, - gettext, - createKingbirdService, - updateKingbirdService, - deleteKingbirdService, - resourceType - ) { - var kingbirdsResourceType = registry.getResourceType(resourceType); - kingbirdsResourceType.globalActions - .append({ - id: 'createKingbirdAction', - service: createKingbirdService, - template: { - type: 'create', - text: gettext('Create Kingbird') - } - }); - - kingbirdsResourceType.batchActions - .append({ - id: 'batchDeleteKingbirdAction', - service: deleteKingbirdService, - template: { - type: 'delete-selected', - text: gettext('Delete Kingbirds') - } - }); - - kingbirdsResourceType.itemActions - .append({ - id: 'updateKingbirdAction', - service: updateKingbirdService, - template: { - text: gettext('Update Kingbird') - } - }) - .append({ - id: 'deleteKingbirdAction', - service: deleteKingbirdService, - template: { - type: 'delete', - text: gettext('Delete Kingbird') - } - }); - } -})(); diff --git a/kingbird_dashboard/static/dashboard/kingbird/kingbirds/actions/create.service.js b/kingbird_dashboard/static/dashboard/kingbird/kingbirds/actions/create.service.js deleted file mode 100644 index 023e805..0000000 --- a/kingbird_dashboard/static/dashboard/kingbird/kingbirds/actions/create.service.js +++ /dev/null @@ -1,103 +0,0 @@ -/** - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. You may obtain - * a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ - -(function() { - 'use strict'; - - /** - * @ngdoc overview - * @name horizon.dashboard.kingbird.kingbirds.create.service - * @description Service for the kingbird create modal - */ - angular - .module('horizon.dashboard.kingbird.kingbirds') - .factory('horizon.dashboard.kingbird.kingbirds.create.service', createService); - - createService.$inject = [ - '$location', - 'horizon.app.core.openstack-service-api.kingbird_dashboard', - 'horizon.app.core.openstack-service-api.policy', - 'horizon.framework.util.actions.action-result.service', - 'horizon.framework.util.i18n.gettext', - 'horizon.framework.util.q.extensions', - 'horizon.framework.widgets.toast.service', - 'horizon.dashboard.kingbird.kingbirds.events', - 'horizon.dashboard.kingbird.kingbirds.model', - 'horizon.dashboard.kingbird.kingbirds.resourceType', - 'horizon.dashboard.kingbird.kingbirds.workflow' - ]; - - function createService( - $location, api, policy, actionResult, gettext, $qExtensions, - toast, events, model, resourceType, workflow - ) { - - var message = { - success: gettext('Kingbird %s was successfully created.') - }; - - var service = { - initAction: initAction, - perform: perform, - allowed: allowed - }; - - return service; - - ////////////// - - // fixme: include this function in your service - // if you plan to emit events to the parent controller, - // otherwise remove it - function initAction() { - } - - // fixme: if newScope is unnecessary, remove it - /* eslint-disable no-unused-vars */ - function perform(selected, newScope) { - // modal title, buttons - var title, submitText, submitIcon; - title = gettext("Create Kingbird"); - submitText = gettext("Create"); - submitIcon = "fa fa-check"; - model.init(); - - var result = workflow.init(title, submitText, submitIcon, model.spec); - return result.then(submit); - } - - function allowed() { - return $qExtensions.booleanAsPromise(true); - // fixme: if you need to set policy, change as follow - //return policy.ifAllowed({ rules: [['kingbird', 'create_kingbird']] }); - } - - function submit() { - model.cleanProperties(); - return api.createKingbird(model.spec).then(success); - } - - function success(response) { - response.data.id = response.data.uuid; - toast.add('success', interpolate(message.success, [response.data.id])); - var result = actionResult.getActionResult() - .created(resourceType, response.data.id); - if (result.result.failed.length === 0 && result.result.created.length > 0) { - $location.path('/kingbird/kingbirds'); - } else { - return result.result; - } - } - } -})(); diff --git a/kingbird_dashboard/static/dashboard/kingbird/kingbirds/actions/delete.service.js b/kingbird_dashboard/static/dashboard/kingbird/kingbirds/actions/delete.service.js deleted file mode 100644 index d595367..0000000 --- a/kingbird_dashboard/static/dashboard/kingbird/kingbirds/actions/delete.service.js +++ /dev/null @@ -1,156 +0,0 @@ -/** - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use self file except in compliance with the License. You may obtain - * a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ - -(function() { - 'use strict'; - - /** - * @ngDoc factory - * @name horizon.dashboard.kingbird.kingbirds.delete.service - * @Description - * Brings up the delete kingbirds confirmation modal dialog. - * On submit, delete selected resources. - * On cancel, do nothing. - */ - angular - .module('horizon.dashboard.kingbird.kingbirds') - .factory('horizon.dashboard.kingbird.kingbirds.delete.service', deleteService); - - deleteService.$inject = [ - '$location', - '$q', - 'horizon.app.core.openstack-service-api.kingbird_dashboard', - 'horizon.app.core.openstack-service-api.policy', - 'horizon.framework.util.actions.action-result.service', - 'horizon.framework.util.i18n.gettext', - 'horizon.framework.util.q.extensions', - 'horizon.framework.widgets.modal.deleteModalService', - 'horizon.framework.widgets.toast.service', - 'horizon.dashboard.kingbird.kingbirds.resourceType', - 'horizon.dashboard.kingbird.kingbirds.events' - ]; - - function deleteService( - $location, $q, api, policy, actionResult, gettext, $qExtensions, - deleteModal, toast, resourceType, events - ) { - var scope; - var context = { - labels: null, - deleteEntity: deleteEntity, - successEvent: events.DELETE_SUCCESS - }; - var service = { - initAction: initAction, - allowed: allowed, - perform: perform - }; - var notAllowedMessage = - gettext("You are not allowed to delete kingbirds: %s"); - - return service; - - ////////////// - - // fixme: include this function in your service - // if you plan to emit events to the parent controller, - // otherwise remove it - function initAction() { - } - - function allowed() { - return $qExtensions.booleanAsPromise(true); - // fixme: if you need to set policy, change as follow - //return policy.ifAllowed({ rules: [['kingbird', 'delete_kingbird']] }); - } - - // delete selected resource objects - function perform(selected, newScope) { - scope = newScope; - selected = angular.isArray(selected) ? selected : [selected]; - context.labels = labelize(selected.length); - return $qExtensions.allSettled(selected.map(checkPermission)).then(afterCheck); - } - - function labelize(count) { - return { - title: ngettext('Confirm Delete Kingbird', - 'Confirm Delete Kingbirds', count), - /* eslint-disable max-len */ - message: ngettext('You have selected "%s". Please confirm your selection. Deleted kingbird is not recoverable.', - 'You have selected "%s". Please confirm your selection. Deleted kingbirds are not recoverable.', count), - /* eslint-enable max-len */ - submit: ngettext('Delete Kingbird', - 'Delete Kingbirds', count), - success: ngettext('Deleted Kingbird: %s.', - 'Deleted Kingbirds: %s.', count), - error: ngettext('Unable to delete Kingbird: %s.', - 'Unable to delete Kingbirds: %s.', count) - }; - } - - // for batch delete - function checkPermission(selected) { - return {promise: allowed(selected), context: selected}; - } - - // for batch delete - function afterCheck(result) { - var outcome = $q.reject(); // Reject the promise by default - if (result.fail.length > 0) { - toast.add('error', getMessage(notAllowedMessage, result.fail)); - outcome = $q.reject(result.fail); - } - if (result.pass.length > 0) { - outcome = deleteModal.open(scope, result.pass.map(getEntity), context).then(createResult); - } - return outcome; - } - - function createResult(deleteModalResult) { - // To make the result of this action generically useful, reformat the return - // from the deleteModal into a standard form - var result = actionResult.getActionResult(); - deleteModalResult.pass.forEach(function markDeleted(item) { - result.deleted(resourceType, getEntity(item).id); - }); - deleteModalResult.fail.forEach(function markFailed(item) { - result.failed(resourceType, getEntity(item).id); - }); - if (result.result.failed.length === 0 && result.result.deleted.length > 0) { - $location.path('/kingbird/kingbirds'); - } else { - return result.result; - } - } - - function getMessage(message, entities) { - return interpolate(message, [entities.map(getName).join(", ")]); - } - - function getName(result) { - return getEntity(result).name; - } - - // for batch delete - function getEntity(result) { - return result.context; - } - - // call delete REST API - function deleteEntity(id) { - return api.deleteKingbird(id, true); - } - } -})(); diff --git a/kingbird_dashboard/static/dashboard/kingbird/kingbirds/actions/update.service.js b/kingbird_dashboard/static/dashboard/kingbird/kingbirds/actions/update.service.js deleted file mode 100644 index 97b9513..0000000 --- a/kingbird_dashboard/static/dashboard/kingbird/kingbirds/actions/update.service.js +++ /dev/null @@ -1,122 +0,0 @@ -/** - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. You may obtain - * a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ - -(function() { - 'use strict'; - - /** - * @ngdoc overview - * @name horizon.dashboard.kingbird.kingbirds.update.service - * @description Service for the kingbird update modal - */ - angular - .module('horizon.dashboard.kingbird.kingbirds') - .factory('horizon.dashboard.kingbird.kingbirds.update.service', updateService); - - updateService.$inject = [ - '$location', - 'horizon.app.core.openstack-service-api.kingbird_dashboard', - 'horizon.app.core.openstack-service-api.policy', - 'horizon.framework.util.actions.action-result.service', - 'horizon.framework.util.i18n.gettext', - 'horizon.framework.util.q.extensions', - 'horizon.framework.widgets.toast.service', - 'horizon.dashboard.kingbird.kingbirds.events', - 'horizon.dashboard.kingbird.kingbirds.model', - 'horizon.dashboard.kingbird.kingbirds.resourceType', - 'horizon.dashboard.kingbird.kingbirds.workflow' - ]; - - function updateService( - $location, api, policy, actionResult, gettext, $qExtensions, - toast, events, model, resourceType, workflow - ) { - - var message = { - success: gettext('Kingbird %s was successfully updated.') - }; - - var service = { - initAction: initAction, - perform: perform, - allowed: allowed - }; - - var id; - - return service; - - ////////////// - - // fixme: include this function in your service - // if you plan to emit events to the parent controller, - // otherwise remove it - function initAction() { - } - - // fixme: if newScope is unnecessary, remove it - /* eslint-disable no-unused-vars */ - function perform(selected, newScope) { - // modal title, buttons - var title, submitText, submitIcon; - title = gettext("Update Kingbird"); - submitText = gettext("Update"); - submitIcon = "fa fa-check"; - model.init(); - - // load current data - id = selected.id; - var deferred = api.getKingbird(id); - deferred.then(onLoad); - - function onLoad(response) { - model.spec.id = response.data.id; - model.spec.name = response.data.name; - model.spec.description = response.data.description; - model.spec.enabled = response.data.enabled; - model.spec.size = response.data.size; - model.spec.temperature = response.data.temperature; - model.spec.base = response.data.base; - model.spec.flavor = response.data.flavor; - model.spec.topping = response.data.topping; - } - - var result = workflow.init(title, submitText, submitIcon, model.spec); - return result.then(submit); - } - - function allowed() { - return $qExtensions.booleanAsPromise(true); - // fixme: if you need to set policy, change as follow - //return policy.ifAllowed({ rules: [['kingbird', 'update_kingbird']] }); - } - - function submit() { - model.cleanProperties(); - return api.updateKingbird(id, model.spec).then(success); - } - - function success(response) { - response.data.id = response.data.uuid; - toast.add('success', interpolate(message.success, [response.data.id])); - var result = actionResult.getActionResult() - .updated(resourceType, response.data.id); - if (result.result.failed.length === 0 && result.result.updated.length > 0) { - $location.path('/kingbird/kingbirds'); - } else { - return result.result; - } - } - } -})(); diff --git a/kingbird_dashboard/static/dashboard/kingbird/kingbirds/details/details.module.js b/kingbird_dashboard/static/dashboard/kingbird/kingbirds/details/details.module.js deleted file mode 100644 index 1fcf790..0000000 --- a/kingbird_dashboard/static/dashboard/kingbird/kingbirds/details/details.module.js +++ /dev/null @@ -1,57 +0,0 @@ -/** - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. You may obtain - * a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ - -(function() { - 'use strict'; - - /** - * @ngdoc overview - * @ngname horizon.dashboard.kingbird.kingbirds.details - * - * @description - * Provides details features for Kingbird. - */ - angular - .module('horizon.dashboard.kingbird.kingbirds.details', [ - 'horizon.app.core', - 'horizon.framework.conf' - ]) - .run(registerDetails); - - registerDetails.$inject = [ - 'horizon.app.core.openstack-service-api.kingbird_dashboard', - 'horizon.dashboard.kingbird.kingbirds.basePath', - 'horizon.dashboard.kingbird.kingbirds.resourceType', - 'horizon.framework.conf.resource-type-registry.service' - ]; - - function registerDetails( - api, - basePath, - resourceType, - registry - ) { - registry.getResourceType(resourceType) - .setLoadFunction(loadFunction) - .detailsViews.append({ - id: 'kingbirdDetailsOverview', - name: gettext('Overview'), - template: basePath + 'details/overview.html' - }); - - function loadFunction(identifier) { - return api.getKingbird(identifier); - } - } -})(); diff --git a/kingbird_dashboard/static/dashboard/kingbird/kingbirds/details/drawer.html b/kingbird_dashboard/static/dashboard/kingbird/kingbirds/details/drawer.html deleted file mode 100644 index 872b5ff..0000000 --- a/kingbird_dashboard/static/dashboard/kingbird/kingbirds/details/drawer.html +++ /dev/null @@ -1,6 +0,0 @@ - - diff --git a/kingbird_dashboard/static/dashboard/kingbird/kingbirds/details/overview.controller.js b/kingbird_dashboard/static/dashboard/kingbird/kingbirds/details/overview.controller.js deleted file mode 100644 index 3e455d8..0000000 --- a/kingbird_dashboard/static/dashboard/kingbird/kingbirds/details/overview.controller.js +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 (the 'License'); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an 'AS IS' BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -(function() { - "use strict"; - - angular - .module('horizon.dashboard.kingbird.kingbirds') - .controller('horizon.dashboard.kingbird.kingbirds.OverviewController', controller); - - controller.$inject = [ - '$scope' - ]; - - function controller( - $scope - ) { - var ctrl = this; - ctrl.kingbird = {}; - - $scope.context.loadPromise.then(onGetKingbird); - - function onGetKingbird(kingbird) { - ctrl.kingbird = kingbird.data; - } - } -})(); diff --git a/kingbird_dashboard/static/dashboard/kingbird/kingbirds/details/overview.html b/kingbird_dashboard/static/dashboard/kingbird/kingbirds/details/overview.html deleted file mode 100644 index 8f89844..0000000 --- a/kingbird_dashboard/static/dashboard/kingbird/kingbirds/details/overview.html +++ /dev/null @@ -1,16 +0,0 @@ -
-
-
-

Kingbird

-
- - -
-
-
diff --git a/kingbird_dashboard/static/dashboard/kingbird/kingbirds/kingbirds.module.js b/kingbird_dashboard/static/dashboard/kingbird/kingbirds/kingbirds.module.js deleted file mode 100644 index 2f53b5a..0000000 --- a/kingbird_dashboard/static/dashboard/kingbird/kingbirds/kingbirds.module.js +++ /dev/null @@ -1,169 +0,0 @@ -/** - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. You may obtain - * a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ - -(function() { - 'use strict'; - - /** - * @ngdoc overview - * @name horizon.dashboard.kingbird.kingbirds - * @ngModule - * @description - * Provides all the services and widgets require to display the Kingbird - * panel - */ - angular - .module('horizon.dashboard.kingbird.kingbirds', [ - 'ngRoute', - 'horizon.dashboard.kingbird.kingbirds.actions', - 'horizon.dashboard.kingbird.kingbirds.details' - ]) - .constant('horizon.dashboard.kingbird.kingbirds.events', events()) - .constant('horizon.dashboard.kingbird.kingbirds.resourceType', 'OS::kingbird_dashboard::Kingbird') - .run(run) - .config(config); - - /** - * @ngdoc constant - * @name horizon.dashboard.kingbird.kingbirds.events - * @description A list of events used by Kingbird - * @returns {Object} events - */ - function events() { - return { - CREATE_SUCCESS: 'horizon.dashboard.kingbird.kingbirds.CREATE_SUCCESS', - DELETE_SUCCESS: 'horizon.dashboard.kingbird.kingbirds.DELETE_SUCCESS' - }; - } - - run.$inject = [ - 'horizon.framework.conf.resource-type-registry.service', - 'horizon.dashboard.kingbird.kingbirds.service', - 'horizon.dashboard.kingbird.kingbirds.basePath', - 'horizon.dashboard.kingbird.kingbirds.resourceType' - ]; - - function run(registry, service, basePath, resourceType) { - registry.getResourceType(resourceType) - .setNames(gettext('Kingbird'), gettext('Kingbirds')) - // for detail summary view on table row - .setSummaryTemplateUrl(basePath + 'details/drawer.html') - // specify items for table row items, summary view and details view - .setProperties(properties()) - // get items for table - .setListFunction(service.getPromise) - // specify table columns - .tableColumns - .append({ - id: 'name', - priority: 1, - sortDefault: true, - filters: ['noName'], - urlFunction: service.urlFunction - }) - .append({ - id: 'size', - priority: 1, - filters: ['noValue'] - }) - .append({ - id: 'temperature', - priority: 1, - filters: ['noValue'] - }) - .append({ - id: 'base', - priority: 1, - filters: ['noValue'] - }) - .append({ - id: 'flavor', - priority: 1, - filters: ['noValue'] - }) - .append({ - id: 'topping', - priority: 2, - filters: ['noValue'] - }) - .append({ - id: 'created_at', - priority: 2 - }) - .append({ - id: 'updated_at', - priority: 2 - }); - // for magic-search - registry.getResourceType(resourceType).filterFacets - .append({ - 'label': gettext('Name'), - 'name': 'name', - 'singleton': true - }) - .append({ - 'label': gettext('Base'), - 'name': 'base', - 'singleton': true - }) - .append({ - 'label': gettext('Flavor'), - 'name': 'flavor', - 'singleton': true - }) - .append({ - 'label': gettext('ID'), - 'name': 'id', - 'singleton': true - }); - } - - function properties() { - return { - id: { label: gettext('ID'), filters: ['noValue'] }, - name: { label: gettext('Name'), filters: ['noName'] }, - description: { label: gettext('Description'), filters: ['noValue'] }, - enabled: { label: gettext('Enabled'), filters: ['yesno'] }, - size: { label: gettext('Size'), filters: ['noValue'] }, - temperature: { label: gettext('Temperature'), filters: ['noValue'] }, - base: { label: gettext('Base'), filters: ['noValue'] }, - flavor: { label: gettext('Flavor'), filters: ['noValue'] }, - topping: { label: gettext('Topping'), filters: ['noValue'] }, - created_at: { label: gettext('Created'), filters: ['simpleDate', 'noValue'] }, - updated_at: { label: gettext('Updated'), filters: ['simpleDate', 'noValue'] } - }; - } - - config.$inject = [ - '$provide', - '$windowProvider', - '$routeProvider' - ]; - - /** - * @name config - * @param {Object} $provide - * @param {Object} $windowProvider - * @param {Object} $routeProvider - * @description Routes used by this module. - * @returns {undefined} Returns nothing - */ - function config($provide, $windowProvider, $routeProvider) { - var path = $windowProvider.$get().STATIC_URL + 'dashboard/kingbird/kingbirds/'; - $provide.constant('horizon.dashboard.kingbird.kingbirds.basePath', path); - $routeProvider.when('/kingbird/kingbirds', { - templateUrl: path + 'panel.html' - }); - } -})(); diff --git a/kingbird_dashboard/static/dashboard/kingbird/kingbirds/kingbirds.module.spec.js b/kingbird_dashboard/static/dashboard/kingbird/kingbirds/kingbirds.module.spec.js deleted file mode 100644 index 1be2433..0000000 --- a/kingbird_dashboard/static/dashboard/kingbird/kingbirds/kingbirds.module.spec.js +++ /dev/null @@ -1,23 +0,0 @@ -/** - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. You may obtain - * a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ -(function() { - 'use strict'; - - describe('horizon.dashboard.kingbird.kingbirds', function() { - it('should exist', function() { - expect(angular.module('horizon.dashboard.kingbird.kingbirds')).toBeDefined(); - }); - }); - -})(); diff --git a/kingbird_dashboard/static/dashboard/kingbird/kingbirds/kingbirds.scss b/kingbird_dashboard/static/dashboard/kingbird/kingbirds/kingbirds.scss deleted file mode 100644 index e69de29..0000000 diff --git a/kingbird_dashboard/static/dashboard/kingbird/kingbirds/kingbirds.service.js b/kingbird_dashboard/static/dashboard/kingbird/kingbirds/kingbirds.service.js deleted file mode 100644 index e99ca3a..0000000 --- a/kingbird_dashboard/static/dashboard/kingbird/kingbirds/kingbirds.service.js +++ /dev/null @@ -1,63 +0,0 @@ -/** - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. You may obtain - * a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ - -(function() { - "use strict"; - - angular.module('horizon.dashboard.kingbird.kingbirds') - .factory('horizon.dashboard.kingbird.kingbirds.service', - service); - - service.$inject = [ - '$filter', - 'horizon.app.core.detailRoute', - 'horizon.app.core.openstack-service-api.kingbird_dashboard' - ]; - - /* - * @ngdoc factory - * @name horizon.dashboard.kingbird.kingbirds.service - * - * @description - * This service provides functions that are used through the Kingbirds - * features. These are primarily used in the module registrations - * but do not need to be restricted to such use. Each exposed function - * is documented below. - */ - function service($filter, detailRoute, api) { - return { - getPromise: getPromise, - urlFunction: urlFunction - }; - - function getPromise(params) { - return api.getKingbirds(params).then(modifyResponse); - } - - function modifyResponse(response) { - return {data: {items: response.data.items.map(modifyItem)}}; - - function modifyItem(item) { - var timestamp = item.updated_at ? item.updated_at : item.created_at; - item.trackBy = item.id.concat(timestamp); - return item; - } - } - - function urlFunction(item) { - return detailRoute + 'OS::kingbird_dashboard::Kingbird/' + item.id; - } - } -})(); - diff --git a/kingbird_dashboard/static/dashboard/kingbird/kingbirds/kingbirds.service.spec.js b/kingbird_dashboard/static/dashboard/kingbird/kingbirds/kingbirds.service.spec.js deleted file mode 100644 index d1600f6..0000000 --- a/kingbird_dashboard/static/dashboard/kingbird/kingbirds/kingbirds.service.spec.js +++ /dev/null @@ -1,52 +0,0 @@ -/** - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -(function() { - "use strict"; - - describe('Kingbirds service', function() { - var service; - beforeEach(module('horizon.dashboard.kingbird.kingbirds')); - beforeEach(inject(function($injector) { - service = $injector.get('horizon.dashboard.kingbird.kingbirds.service'); - })); - - describe('getPromise', function() { - it("provides a promise", inject(function($q, $injector, $timeout) { - var api = $injector.get('horizon.app.core.openstack-service-api.kingbird_dashboard'); - var deferred = $q.defer(); - spyOn(api, 'getKingbirds').and.returnValue(deferred.promise); - var result = service.getPromise({}); - deferred.resolve({ - data:{ - items: [{id: 123, name: 'resource1'}] - } - }); - $timeout.flush(); - expect(api.getKingbirds).toHaveBeenCalled(); - expect(result.$$state.value.data.items[0].name).toBe('resource1'); - })); - }); - - describe('urlFunction', function() { - it("get url", inject(function() { - var detailRoute = $injector.get('horizon.app.core.detailRoute'); - var result = service.urlFunction({id:"123abc"}); - expect(result).toBe(detailRoute + "OS::kingbird_dashboard::Kingbird/123abc"); - })); - }); - - }); - -})(); - diff --git a/kingbird_dashboard/static/dashboard/kingbird/kingbirds/panel.html b/kingbird_dashboard/static/dashboard/kingbird/kingbirds/panel.html deleted file mode 100644 index cfc7d07..0000000 --- a/kingbird_dashboard/static/dashboard/kingbird/kingbirds/panel.html +++ /dev/null @@ -1,6 +0,0 @@ - - - - - diff --git a/kingbird_dashboard/static/dashboard/kingbird/kingbirds/workflow/info.help.html b/kingbird_dashboard/static/dashboard/kingbird/kingbirds/workflow/info.help.html deleted file mode 100644 index 56f3e80..0000000 --- a/kingbird_dashboard/static/dashboard/kingbird/kingbirds/workflow/info.help.html +++ /dev/null @@ -1,4 +0,0 @@ -
-
Kingbird Name
-
An arbitrary human-readable name
-
diff --git a/kingbird_dashboard/static/dashboard/kingbird/kingbirds/workflow/kingbird-model.js b/kingbird_dashboard/static/dashboard/kingbird/kingbirds/workflow/kingbird-model.js deleted file mode 100644 index c11d3b9..0000000 --- a/kingbird_dashboard/static/dashboard/kingbird/kingbirds/workflow/kingbird-model.js +++ /dev/null @@ -1,63 +0,0 @@ -/** - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. You may obtain - * a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ - -(function() { - 'use strict'; - - /** - * @ngdoc model - * @name horizon.dashboard.kingbird.kingbirds.model - * @description Service for the kingbird model - */ - angular - .module('horizon.dashboard.kingbird.kingbirds') - .factory('horizon.dashboard.kingbird.kingbirds.model', model); - - model.$inject = [ - ]; - - function model() { - var model = { - // params - "spec": {}, - - // methods - "init": init, - "cleanProperties": cleanProperties - }; - - function init() { - // initialize model - model.spec = { - "id": "", - "name": "", // text required - "description": "", // textarea - "enabled": true, // checkbox - "size": "M", // radio - "temperature": "H", // radio - "base": "", // select - "flavor": "", // select - "topping": "" // checkboxes - }; - } - - function cleanProperties() { - delete model.spec.id; - delete model.spec.tabs; - } - - return model; - } -})(); - diff --git a/kingbird_dashboard/static/dashboard/kingbird/kingbirds/workflow/recipe.help.html b/kingbird_dashboard/static/dashboard/kingbird/kingbirds/workflow/recipe.help.html deleted file mode 100644 index 7f7cd85..0000000 --- a/kingbird_dashboard/static/dashboard/kingbird/kingbirds/workflow/recipe.help.html +++ /dev/null @@ -1,7 +0,0 @@ -
-
Base
-
Choose base drink.
-
Other options
-
Choose favorite options.
-
- diff --git a/kingbird_dashboard/static/dashboard/kingbird/kingbirds/workflow/workflow.service.js b/kingbird_dashboard/static/dashboard/kingbird/kingbirds/workflow/workflow.service.js deleted file mode 100644 index c4925b6..0000000 --- a/kingbird_dashboard/static/dashboard/kingbird/kingbirds/workflow/workflow.service.js +++ /dev/null @@ -1,211 +0,0 @@ -/** - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. You may obtain - * a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ - -(function() { - 'use strict'; - - /** - * @ngdoc workflow - * @name horizon.dashboard.kingbird.kingbirds.workflow - * @description Service for the create/update workflow - */ - angular - .module('horizon.dashboard.kingbird.kingbirds') - .factory('horizon.dashboard.kingbird.kingbirds.workflow', workflow); - - workflow.$inject = [ - 'horizon.dashboard.kingbird.basePath', - 'horizon.framework.util.i18n.gettext', - 'horizon.framework.widgets.form.ModalFormService' - ]; - - function workflow(basePath, gettext, modal) { - var workflow = { - init: init - }; - - function init(title, submitText, submitIcon, model) { - var schema, form; - - // schema - schema = { - "type": "object", - "properties": { - "name": { - "title": gettext("Name"), - "type": "string" - }, - "description": { - "title": gettext("Description"), - "type": "string" - }, - "enabled": { - "title": gettext("Enabled"), - "type": "boolean", - "default": true - }, - "size": { - "title": gettext("Size"), - "type": "string", - "default": "M" - }, - "temperature": { - "title": gettext("Temperature"), - "type": "string", - "default": "H" - }, - "base": { - "title": gettext("Base"), - "type": "string", - "default": "" - }, - "flavor": { - "title": gettext("Flavor"), - "type": "string", - "default": "" - }, - "topping": { - "title": gettext("Topping") - } - } - }; - - // form - form = [ - { - "type": "tabs", - "tabs": [ - { - "title": gettext("Info"), - "help": basePath + "kingbirds/workflow/info.help.html", - "items": [ - { - "key": "name", - "placeholder": gettext("Name of the kingbird."), - "required": true - }, - { - "key": "description", - "type": "textarea" - }, - { - "key": "enabled", - "type": "checkbox" - } - ] - }, - { - "title": gettext("Recipe"), - "help": basePath + "kingbirds/workflow/recipe.help.html", - "items": [ - { - "key": "size", - "type": "radiobuttons", - "titleMap": [ - {"value": "S", "name": gettext("Small")}, - {"value": "M", "name": gettext("Medium")}, - {"value": "L", "name": gettext("Large")}, - {"value": "XL", "name": gettext("Extra Large")} - ] - }, - { - "key": "temperature", - "type": "radiobuttons", - "titleMap": [ - {"value": "H", "name": gettext("Hot")}, - {"value": "I", "name": gettext("Ice")} - ] - }, - { - "key": "base", - "type": "select", - "titleMap": [ - {"value": "", "name": gettext("Choose base.")}, - { - "value": "blend", - "name": gettext("House Blend"), - "group": gettext("Coffee") - }, - { - "value": "mandheling", - "name": gettext("Mandheling"), - "group": gettext("Coffee")}, - { - "value": "colombia", - "name": gettext("Colombia"), - "group": gettext("Coffee") - }, - { - "value": "espresso", - "name": gettext("Espresso"), - "group": gettext("Coffee") - }, - { - "value": "earl_gray", - "name": gettext("Earl Gray"), - "group": gettext("Tea") - }, - { - "value": "darjeeling", - "name": gettext("Darjeeling"), - "group": gettext("Tea")}, - { - "value": "orange_pekoe", - "name": gettext("Orange Pekoe"), - "group": gettext("Tea") - } - ] - }, - { - "key": "flavor", - "type": "select", - "titleMap": [ - {"value": "", "name": gettext("Choose flavor.")}, - {"value": "chocolate", "name": gettext("Chocolate")}, - {"value": "mocha", "name": gettext("Mocha")}, - {"value": "strawberry", "name": gettext("Strawberry")}, - {"value": "blueberry", "name": gettext("Blueberry")}, - {"value": "raspberry", "name": gettext("Raspberry")} - ] - }, - { - "key": "topping", - "type": "checkboxes", - "titleMap": [ - {"value": "clushed_nuts", "name": gettext("Clushed Nuts")}, - {"value": "whip_cream", "name": gettext("Whip Cream")}, - {"value": "mixed_serial", "name": gettext("Mixed Serial")} - ] - } - ] // items - } // tab - ] // tabs - } - ]; // form - - var config = { - "title": title, - "submitText": submitText, - "schema": schema, - "form": form, - "model": model - }; - - return modal.open(config); - } - - return workflow; - } -})(); - diff --git a/kingbird_dashboard/version.py b/kingbird_dashboard/version.py deleted file mode 100644 index 4e3242f..0000000 --- a/kingbird_dashboard/version.py +++ /dev/null @@ -1,14 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. -import pbr.version - -version_info = pbr.version.VersionInfo('kingbird_dashboard')