Delete unused files and clean up cookie cutter files

These files were auto-generated from the cookiecutter commit
and aren't needed. Some should be renamed.

Change-Id: I2d6f7af84f9c8580b1a753f03b7170fd90e05314
This commit is contained in:
Kaitlin Farr 2017-08-22 16:31:54 -04:00
parent 72a202fb63
commit 2a90199ded
35 changed files with 33 additions and 1675 deletions

22
.gitignore vendored Normal file
View File

@ -0,0 +1,22 @@
AUTHORS
ChangeLog
build
cover
doc/source/contributor/api
node_modules
npm-debug.log
releasenotes/build
castellan_ui/test/.secret_key_store
.coverage*
.jshintrc
.project
.pydevproject
.settings
.tox
.venv
*.egg*
*.lock
*.mo
*.py[cod]
*.swp
*nose_results.html

View File

@ -2,7 +2,7 @@
Castellan UI Castellan UI
=============================== ===============================
Generic Key Manager interface UI plugin for Horizon Generic Key Manager UI Plugin for Horizon
* Free software: Apache license * Free software: Apache license
* Source: http://git.openstack.org/cgit/openstack/castellan-ui * Source: http://git.openstack.org/cgit/openstack/castellan-ui
@ -53,12 +53,12 @@ Install Castellan UI with all dependencies in your virtual environment::
And enable it in Horizon:: And enable it in Horizon::
ln -s ../castellan-ui/castellan_ui/enabled/_90_project_castellan_panelgroup.py openstack_dashboard/local/enabled TODO(kfarr): add the panel group here
ln -s ../castellan-ui/castellan_ui/enabled/_91_project_castellan_manages_panel.py openstack_dashboard/local/enabled TODO(kfarr): add the panels here
To run horizon with the newly enabled Castellan UI plugin run:: To run horizon with the newly enabled Castellan UI plugin run::
./run_tests.sh --runserver 0.0.0.0:8080 ./run_tests.sh --runserver 0.0.0.0:8080
to have the application start on port 8080 and the horizon dashboard will be to have the application start on port 8080 and the horizon dashboard will be
available in your browser at http://localhost:8080/ available in your browser at http://localhost:8080/

View File

@ -1,131 +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 __future__ import absolute_import
import logging
from castellan import key_manager
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
LOG = logging.getLogger(__name__)
ATTRIBUTES = ['name', 'description', 'enabled', 'size', 'temperature',
'base', 'flavor', 'topping']
STUB_DATA = {}
# 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)
@memoized
def apiclient(request):
api_url = ""
try:
api_url = base.url_for(request, 'manage')
except exceptions.ServiceCatalogException:
LOG.debug('No Manage Management service is configured.')
return None
LOG.debug('castellan connection created using the token "%s" and url'
'"%s"' % (request.user.token.id, api_url))
c = key_manager.API()
return c
def manage_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).manages.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 manage_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).manage.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 manage_delete(request, id):
# deleted = apiclient(request).manages.delete(id)
deleted = STUB_DATA.pop(id)
return deleted
def manage_list(
request, limit=None, marker=None, sort_key=None,
sort_dir=None, detail=True):
# list = apiclient(request).Manages.list(limit, marker, sort_key,
# sort_dir, detail)
list = [STUB_DATA[data] for data in STUB_DATA]
return list
def manage_show(request, id):
# show = apiclient(request).manages.get(id)
show = STUB_DATA.get(id)
return show

View File

@ -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 castellan_ui.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 Manage(generic.View):
"""API for retrieving a single Manage"""
url_regex = r'castellan/manages/(?P<id>[^/]+)$'
@rest_utils.ajax()
def get(self, request, id):
"""Get a specific manage"""
return change_to_id(client.manage_show(request, id).to_dict())
@rest_utils.ajax(data_required=True)
def post(self, request, id):
"""Update a Manage.
Returns the updated Manage object on success.
"""
manage = client.manage_update(request, id, **request.DATA)
return rest_utils.CreatedResponse(
'/api/castellan/manage/%s' % manage.uuid,
manage.to_dict())
@urls.register
class Manages(generic.View):
"""API for Manages"""
url_regex = r'castellan/manages/$'
@rest_utils.ajax()
def get(self, request):
"""Get a list of the Manages for a project.
The returned result is an object with property 'items' and each
item under this is a Manage.
"""
result = client.manage_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 Manages by id.
Returns HTTP 204 (no content) on successful deletion.
"""
for id in request.DATA:
client.manage_delete(request, id)
@rest_utils.ajax(data_required=True)
def put(self, request):
"""Create a new Manage.
Returns the new Manage object on success.
"""
manage = client.manage_create(request, **request.DATA)
return rest_utils.CreatedResponse(
'/api/castellan/manage/%s' % manage.uuid,
manage.to_dict())

View File

@ -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.
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 castellan_ui.api import rest_api # noqa: F401
class Manages(horizon.Panel):
name = _("Manages")
slug = "manages"

View File

@ -1,19 +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 openstack_dashboard.test import helpers as test
class ManagesTests(test.TestCase):
# Unit tests for manage.
def test_me(self):
self.assertTrue(1 + 1 == 2)

View File

@ -1,20 +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.conf.urls import url
from django.utils.translation import ugettext_lazy as _
from horizon.browsers import views
title = _("Manages")
urlpatterns = [
url('', views.AngularIndexView.as_view(title=title), name='index'),
]

View File

@ -1,36 +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.utils.translation import ugettext_lazy as _
# The slug of the panel group to be added to HORIZON_CONFIG. Required.
PANEL_GROUP = 'castellan'
# The display name of the PANEL_GROUP. Required.
PANEL_GROUP_NAME = _('Castellan')
# The slug of the dashboard the PANEL_GROUP associated with. Required.
PANEL_GROUP_DASHBOARD = 'project'
ADD_INSTALLED_APPS = ['castellan_ui']
ADD_ANGULAR_MODULES = [
'horizon.dashboard.castellan'
]
ADD_JS_FILES = [
'horizon/lib/angular/angular-route.js'
]
ADD_SCSS_FILES = [
'dashboard/castellan/castellan.scss'
]
AUTO_DISCOVER_STATIC_FILES = True

View File

@ -1,21 +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.
# The slug of the panel to be added to HORIZON_CONFIG. Required.
PANEL = 'manages'
# The slug of the panel group the PANEL is associated with.
PANEL_GROUP = 'castellan'
# The slug of the dashboard the PANEL associated with. Required.
PANEL_DASHBOARD = 'project'
# Python panel class of the PANEL to be added.
ADD_PANEL = 'castellan_ui.content.manages.panel.Manages'

View File

@ -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';
/**
* @ngdoc overview
* @name horizon.dashboard.castellan
* @description
* Dashboard module to host various castellan panels.
*/
angular
.module('horizon.dashboard.castellan', [
'horizon.dashboard.castellan.manages',
'ngRoute'
])
.config(config)
config.$inject = ['$provide', '$windowProvider', '$routeProvider'];
function config($provide, $windowProvider, $routeProvider) {
var path = $windowProvider.$get().STATIC_URL + 'dashboard/castellan/';
$provide.constant('horizon.dashboard.castellan.basePath', path);
}
})();

View File

@ -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.castellan', function() {
it('should exist', function() {
expect(angular.module('horizon.dashboard.castellan')).toBeDefined();
});
});
})();

View File

@ -1,8 +0,0 @@
@import "manages/manages";
.batch-action {
float: right;
action-list {
padding-left: 0.3em;
}
}

View File

@ -1,81 +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.castellan', 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 = {
getManage: getManage,
getManages: getManages,
createManage: createManage,
updateManage: updateManage,
deleteManage: deleteManage,
};
return service;
///////////////
// Manages //
///////////////
function getManage(id) {
return apiService.get('/api/castellan/manages/' + id)
.error(function() {
var msg = gettext('Unable to retrieve the Manage with id: %(id)s.');
toastService.add('error', interpolate(msg, {id: id}, true));
});
}
function getManages() {
return apiService.get('/api/castellan/manages/')
.error(function() {
toastService.add('error', gettext('Unable to retrieve the Manages.'));
});
}
function createManage(params) {
return apiService.put('/api/castellan/manages/', params)
.error(function() {
var msg = gettext('Unable to create the Manage with name: %(name)s');
toastService.add('error', interpolate(msg, { name: params.name }, true));
});
}
function updateManage(id, params) {
return apiService.post('/api/castellan/manages/' + id, params)
.error(function() {
var msg = gettext('Unable to update the Manage with id: %(id)s');
toastService.add('error', interpolate(msg, { id: params.id }, true));
});
}
function deleteManage(id, suppressError) {
var promise = apiService.delete('/api/castellan/manages/', [id]);
return suppressError ? promise : promise.error(function() {
var msg = gettext('Unable to delete the Manage with id: %(id)s');
toastService.add('error', interpolate(msg, { id: id }, true));
});
}
}
}());

View File

@ -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.castellan.manages.actions
*
* @description
* Provides all of the actions for Manages.
*/
angular
.module('horizon.dashboard.castellan.manages.actions', [
'horizon.framework',
'horizon.dashboard.castellan'
])
.run(registerManageActions);
registerManageActions.$inject = [
'horizon.framework.conf.resource-type-registry.service',
'horizon.framework.util.i18n.gettext',
'horizon.dashboard.castellan.manages.create.service',
'horizon.dashboard.castellan.manages.update.service',
'horizon.dashboard.castellan.manages.delete.service',
'horizon.dashboard.castellan.manages.resourceType'
];
function registerManageActions (
registry,
gettext,
createManageService,
updateManageService,
deleteManageService,
resourceType
) {
var managesResourceType = registry.getResourceType(resourceType);
managesResourceType.globalActions
.append({
id: 'createManageAction',
service: createManageService,
template: {
type: 'create',
text: gettext('Create Manage')
}
});
managesResourceType.batchActions
.append({
id: 'batchDeleteManageAction',
service: deleteManageService,
template: {
type: 'delete-selected',
text: gettext('Delete Manages')
}
});
managesResourceType.itemActions
.append({
id: 'updateManageAction',
service: updateManageService,
template: {
text: gettext('Update Manage')
}
})
.append({
id: 'deleteManageAction',
service: deleteManageService,
template: {
type: 'delete',
text: gettext('Delete Manage')
}
});
}
})();

View File

@ -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.castellan.manages.create.service
* @description Service for the manage create modal
*/
angular
.module('horizon.dashboard.castellan.manages')
.factory('horizon.dashboard.castellan.manages.create.service', createService);
createService.$inject = [
'$location',
'horizon.app.core.openstack-service-api.castellan',
'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.castellan.manages.events',
'horizon.dashboard.castellan.manages.model',
'horizon.dashboard.castellan.manages.resourceType',
'horizon.dashboard.castellan.manages.workflow'
];
function createService(
$location, api, policy, actionResult, gettext, $qExtensions,
toast, events, model, resourceType, workflow
) {
var message = {
success: gettext('Manage %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 Manage");
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: [['manage', 'create_manage']] });
}
function submit() {
model.cleanProperties();
return api.createManage(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('/project/manages');
} else {
return result.result;
}
}
}
})();

View File

@ -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.castellan.manages.delete.service
* @Description
* Brings up the delete manages confirmation modal dialog.
* On submit, delete selected resources.
* On cancel, do nothing.
*/
angular
.module('horizon.dashboard.castellan.manages')
.factory('horizon.dashboard.castellan.manages.delete.service', deleteService);
deleteService.$inject = [
'$location',
'$q',
'horizon.app.core.openstack-service-api.castellan',
'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.castellan.manages.resourceType',
'horizon.dashboard.castellan.manages.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 manages: %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: [['manage', 'delete_manage']] });
}
// 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 Manage',
'Confirm Delete Manages', count),
/* eslint-disable max-len */
message: ngettext('You have selected "%s". Please confirm your selection. Deleted manage is not recoverable.',
'You have selected "%s". Please confirm your selection. Deleted manages are not recoverable.', count),
/* eslint-enable max-len */
submit: ngettext('Delete Manage',
'Delete Manages', count),
success: ngettext('Deleted Manage: %s.',
'Deleted Manages: %s.', count),
error: ngettext('Unable to delete Manage: %s.',
'Unable to delete Manages: %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('/project/manages');
} 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.deleteManage(id, true);
}
}
})();

View File

@ -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.castellan.manages.update.service
* @description Service for the manage update modal
*/
angular
.module('horizon.dashboard.castellan.manages')
.factory('horizon.dashboard.castellan.manages.update.service', updateService);
updateService.$inject = [
'$location',
'horizon.app.core.openstack-service-api.castellan',
'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.castellan.manages.events',
'horizon.dashboard.castellan.manages.model',
'horizon.dashboard.castellan.manages.resourceType',
'horizon.dashboard.castellan.manages.workflow'
];
function updateService(
$location, api, policy, actionResult, gettext, $qExtensions,
toast, events, model, resourceType, workflow
) {
var message = {
success: gettext('Manage %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 Manage");
submitText = gettext("Update");
submitIcon = "fa fa-check";
model.init();
// load current data
id = selected.id;
var deferred = api.getManage(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: [['manage', 'update_manage']] });
}
function submit() {
model.cleanProperties();
return api.updateManage(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('/project/manages');
} else {
return result.result;
}
}
}
})();

View File

@ -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.castellan.manages.details
*
* @description
* Provides details features for Manage.
*/
angular
.module('horizon.dashboard.castellan.manages.details', [
'horizon.app.core',
'horizon.framework.conf'
])
.run(registerDetails);
registerDetails.$inject = [
'horizon.app.core.openstack-service-api.castellan',
'horizon.dashboard.castellan.manages.basePath',
'horizon.dashboard.castellan.manages.resourceType',
'horizon.framework.conf.resource-type-registry.service'
];
function registerDetails(
api,
basePath,
resourceType,
registry
) {
registry.getResourceType(resourceType)
.setLoadFunction(loadFunction)
.detailsViews.append({
id: 'manageDetailsOverview',
name: gettext('Overview'),
template: basePath + 'details/overview.html'
});
function loadFunction(identifier) {
return api.getManage(identifier);
}
}
})();

View File

@ -1,6 +0,0 @@
<hz-resource-property-list
resource-type-name="OS::Castellan::Manage"
item="item"
property-groups="[['id'],
['topping', 'created_at', 'updated_at']]">
</hz-resource-property-list>

View File

@ -1,43 +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.castellan.manages')
.controller('horizon.dashboard.castellan.manages.OverviewController', controller);
controller.$inject = [
'$scope',
'horizon.dashboard.castellan.manages.resourceType',
'horizon.dashboard.castellan.manages.events',
'horizon.framework.conf.resource-type-registry.service'
];
function controller(
$scope,
resourceType,
events,
registry
) {
var ctrl = this;
ctrl.manage = {};
$scope.context.loadPromise.then(onGetManage);
function onGetManage(manage) {
ctrl.manage = manage.data;
}
}
})();

View File

@ -1,16 +0,0 @@
<div ng-controller="horizon.dashboard.castellan.manages.OverviewController as ctrl">
<div class="row">
<div class="col-md-12 detail">
<h3 translate>Manage</h3>
<hr>
<hz-resource-property-list
resource-type-name="OS::Castellan::Manage"
cls="dl-horizontal"
item="ctrl.manage"
property-groups="[['name', 'description', 'enabled'],
['size', 'temperature', 'base', 'flavor', 'topping'],
['id', 'created_at', 'updated_at']]">
</hz-resource-property-list>
</div>
</div>
</div>

View File

@ -1,166 +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.castellan.manages
* @ngModule
* @description
* Provides all the services and widgets require to display the Manage
* panel
*/
angular
.module('horizon.dashboard.castellan.manages', [
'ngRoute',
'horizon.dashboard.castellan.manages.actions',
'horizon.dashboard.castellan.manages.details'
])
.constant('horizon.dashboard.castellan.manages.events', events())
.constant('horizon.dashboard.castellan.manages.resourceType', 'OS::Castellan::Manage')
.run(run)
.config(config);
/**
* @ngdoc constant
* @name horizon.dashboard.castellan.manages.events
* @description A list of events used by Manage
*/
function events() {
return {
CREATE_SUCCESS: 'horizon.dashboard.castellan.manages.CREATE_SUCCESS',
DELETE_SUCCESS: 'horizon.dashboard.castellan.manages.DELETE_SUCCESS'
};
}
run.$inject = [
'horizon.framework.conf.resource-type-registry.service',
'horizon.dashboard.castellan.manages.service',
'horizon.dashboard.castellan.manages.basePath',
'horizon.dashboard.castellan.manages.resourceType'
];
function run(registry, service, basePath, resourceType) {
registry.getResourceType(resourceType)
.setNames(gettext('Manage'), gettext('Manages'))
// for detail summary view on table row
.setSummaryTemplateUrl(basePath + 'details/drawer.html')
// for table row items and detail summary view.
.setProperties(properties())
.setListFunction(service.getPromise)
.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/castellan/manages/';
$provide.constant('horizon.dashboard.castellan.manages.basePath', path);
$routeProvider.when('/project/manages', {
templateUrl: path + 'panel.html'
});
}
})();

View File

@ -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.castellan.manages', function() {
it('should exist', function() {
expect(angular.module('horizon.dashboard.castellan.manages')).toBeDefined();
});
});
})();

View File

@ -1,62 +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.castellan.manages')
.factory('horizon.dashboard.castellan.manages.service',
service);
service.$inject = [
'$filter',
'horizon.app.core.detailRoute',
'horizon.app.core.openstack-service-api.castellan'
];
/*
* @ngdoc factory
* @name horizon.dashboard.castellan.manages.service
*
* @description
* This service provides functions that are used through the Manages
* 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.getManages(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::Castellan::Manage/' + item.id;
}
}
})();

View File

@ -1,51 +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('Manages service', function() {
var service;
beforeEach(module('horizon.dashboard.castellan.manages'));
beforeEach(inject(function($injector) {
service = $injector.get('horizon.dashboard.castellan.manages.service');
}));
describe('getPromise', function() {
it("provides a promise", inject(function($q, $injector, $timeout) {
var api = $injector.get('horizon.app.core.openstack-service-api.castellan');
var deferred = $q.defer();
spyOn(api, 'getManages').and.returnValue(deferred.promise);
var result = service.getPromise({});
deferred.resolve({
data:{
items: [{id: 123, name: 'resource1'}]
}
});
$timeout.flush();
expect(api.getManages).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::Castellan::Manage/123abc");
}));
});
});
})();

View File

@ -1,5 +0,0 @@
<hz-resource-panel resource-type-name="OS::Castellan::Manage">
<hz-resource-table resource-type-name="OS::Castellan::Manage"
track-by="trackBy">
</hz-resource-table>
</hz-resource-panel>

View File

@ -1,4 +0,0 @@
<dl>
<dt translate>Manage Name</dt>
<dd translate>An arbitrary human-readable name</dd>
</dl>

View File

@ -1,62 +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.castellan.manages.model
* @description Service for the manage model
*/
angular
.module('horizon.dashboard.castellan.manages')
.factory('horizon.dashboard.castellan.manages.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;
}
})();

View File

@ -1,6 +0,0 @@
<dl>
<dt translate>Base</dt>
<dd translate>Choose base drink.</dd>
<dt translate>Other options</dt>
<dd translate>Choose favorite options.</dd>
</dl>

View File

@ -1,210 +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.castellan.manages.workflow
* @description Service for the create/update workflow
*/
angular
.module('horizon.dashboard.castellan.manages')
.factory('horizon.dashboard.castellan.manages.workflow', workflow);
workflow.$inject = [
'horizon.dashboard.castellan.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 + "manages/workflow/info.help.html",
"items": [
{
"key": "name",
"placeholder": gettext("Name of the manage."),
"required": true
},
{
"key": "description",
"type": "textarea"
},
{
"key": "enabled",
"type": "checkbox"
}
]
},
{
"title": gettext("Recipe"),
"help": basePath + "manages/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;
}
})();

View File

@ -2,7 +2,7 @@
Castellan UI Castellan UI
=============================== ===============================
Generic Key Manager interface UI plugin for Horizon Generic Key Manager UI Plugin for Horizon
* Free software: Apache license * Free software: Apache license
* Source: http://git.openstack.org/cgit/openstack/castellan-ui * Source: http://git.openstack.org/cgit/openstack/castellan-ui
@ -30,4 +30,4 @@ Contributor Guide
:glob: :glob:
:maxdepth: 2 :maxdepth: 2
contributor/index contributor/index

View File

@ -42,12 +42,12 @@ Install Castellan UI with all dependencies in your virtual environment::
And enable it in Horizon:: And enable it in Horizon::
ln -s ../castellan-ui/castellan_ui/enabled/_90_project_castellan_panelgroup.py openstack_dashboard/local/enabled ln -s ../castellan-ui/castellan_ui/enabled/_90_project_key_manager_panelgroup.py openstack_dashboard/local/enabled
ln -s ../castellan-ui/castellan_ui/enabled/_91_project_castellan_manages_panel.py openstack_dashboard/local/enabled ln -s ../castellan-ui/castellan_ui/enabled/_91_project_key_manager_symmetric_keys_panel.py openstack_dashboard/local/enabled
To run horizon with the newly enabled Castellan UI plugin run:: To run horizon with the newly enabled Castellan UI plugin run::
./run_tests.sh --runserver 0.0.0.0:8080 ./run_tests.sh --runserver 0.0.0.0:8080
to have the application start on port 8080 and the horizon dashboard will be to have the application start on port 8080 and the horizon dashboard will be
available in your browser at http://localhost:8080/ available in your browser at http://localhost:8080/

View File

@ -1,6 +1,6 @@
[metadata] [metadata]
name = castellan-ui name = castellan-ui
summary = Generic Key Manager interface UI plugin for Horizon summary = Generic Key Manager UI Plugin for Horizon
description-file = description-file =
README.rst README.rst
author = OpenStack author = OpenStack
@ -26,4 +26,4 @@ packages =
all_files = 1 all_files = 1
build-dir = doc/build build-dir = doc/build
source-dir = doc/source source-dir = doc/source
warning-is-error = 1 warning-is-error = 1