diff --git a/app/models/clusterroletemplate.js b/app/models/clusterroletemplate.js
new file mode 100644
index 000000000..855f336d7
--- /dev/null
+++ b/app/models/clusterroletemplate.js
@@ -0,0 +1,43 @@
+import { inject as service } from '@ember/service';
+import { getOwner } from '@ember/application';
+import { next } from '@ember/runloop';
+
+import Resource from 'ember-api-store/models/resource';
+import PolledResource from 'ui/mixins/cattle-polled-resource';
+
+var ClusterRoleTemplate = Resource.extend(PolledResource, {
+ type: 'clusterRoleTemplate',
+ router: service(),
+
+ actions: {
+ edit: function () {
+ this.get('router').transitionTo('global-admin.roles.edit', this.get('id'), { queryParams: { type: 'cluster' } });
+ },
+ },
+
+ availableActions: function () {
+ return [
+ { label: 'action.edit', icon: 'icon icon-edit', action: 'edit', enabled: true },
+ { divider: true },
+ { label: 'action.remove', icon: 'icon icon-trash', action: 'promptDelete', enabled: true, altAction: 'delete', bulkable: true },
+ { divider: true },
+ { label: 'action.viewInApi', icon: 'icon icon-external-link', action: 'goToApi', enabled: true },
+ ];
+ }.property(),
+
+ delete: function (/*arguments*/) {
+ var promise = this._super.apply(this, arguments);
+ return promise.then(() => {
+ this.set('state', 'removed');
+ }).catch((err) => {
+ this.get('growl').fromError('Error deleting', err);
+ });
+ },
+});
+
+ClusterRoleTemplate.reopenClass({
+ pollTransitioningDelay: 1000,
+ pollTransitioningInterval: 5000,
+});
+
+export default ClusterRoleTemplate;
diff --git a/app/models/projectroletemplate.js b/app/models/projectroletemplate.js
index a22c487cf..26e45ee73 100644
--- a/app/models/projectroletemplate.js
+++ b/app/models/projectroletemplate.js
@@ -11,7 +11,7 @@ var ProjectRoleTemplate = Resource.extend(PolledResource, {
actions: {
edit: function() {
- this.get('router').transitionTo('global-admin.roles.edit', this.get('id'));
+ this.get('router').transitionTo('global-admin.roles.edit', this.get('id'), { queryParams: { type: 'project' } });
},
},
diff --git a/lib/global-admin/addon/components/new-edit-role/component.js b/lib/global-admin/addon/components/new-edit-role/component.js
index 967b2c45e..d0ebd7297 100644
--- a/lib/global-admin/addon/components/new-edit-role/component.js
+++ b/lib/global-admin/addon/components/new-edit-role/component.js
@@ -15,10 +15,11 @@ export default Component.extend(NewOrEdit, {
ruleArray: alias('model.role.rules'),
roleArray: null,
ruleVerbs,
+ roleType: null,
actions: {
cancel() {
- this.get('router').transitionTo('global-admin.roles.index');
+ this.goBack();
},
addRule() {
this.get('ruleArray').pushObject({
@@ -41,18 +42,27 @@ export default Component.extend(NewOrEdit, {
},
},
+ goBack: function() {
+ const route = this.get('roleType') === 'project' ? '/admin/roles' : '/admin/roles?type=cluster'
+ this.get('router').transitionTo(route);
+ },
+
init: function () {
this._super();
- this.set('roleArray', (this.get('primaryResource.projectRoleTemplateIds') || []).map(r => {
+ this.set('roleArray', (this.get(`primaryResource.${this.get('roleType')}RoleTemplateIds`) || []).map(r => {
return {
value: r
};
}));
},
+ otherRoles: function () {
+ return this.get('model.roles').filter(role => this.get('model.role.name') !== role.id);
+ }.property('model'),
+
roleDidChange: function () {
const role = this.get('model.role');
- role.set('projectRoleTemplateIds', (this.get('roleArray') || []).filter(r => r.value).map(r => r.value));
+ role.set(`${this.get('roleType')}RoleTemplateIds`, (this.get('roleArray') || []).filter(r => r.value).map(r => r.value));
}.observes('roleArray.@each.value'),
doesNameExist() {
@@ -100,16 +110,17 @@ export default Component.extend(NewOrEdit, {
willSave() {
let ok = this._super(...arguments);
if (ok) {
+ const templateIdsKey = `${this.get('roleType')}RoleTemplateIds`;
const role = this.get('primaryResource');
const name = (role.get('name') || '').trim().toLowerCase();
- const otherRoles = role.get('projectRoleTemplateIds').filter(r => r).uniq();
+ const otherRoles = role.get(templateIdsKey).filter(r => r).uniq();
role.set('name', name);
- role.set('projectRoleTemplateIds', otherRoles);
+ role.set(templateIdsKey, otherRoles);
}
return ok;
},
doneSaving() {
- this.get('router').transitionTo('global-admin.roles.index');
+ this.goBack();
},
});
\ No newline at end of file
diff --git a/lib/global-admin/addon/components/new-edit-role/template.hbs b/lib/global-admin/addon/components/new-edit-role/template.hbs
index cef1e69c7..b2a8cbf0b 100644
--- a/lib/global-admin/addon/components/new-edit-role/template.hbs
+++ b/lib/global-admin/addon/components/new-edit-role/template.hbs
@@ -1,9 +1,17 @@
@@ -38,7 +46,7 @@
{{#each ruleArray as |rule|}}
- {{role-rule-row rule=rule remove="removeRule"}}
+ {{role-rule-row roleType=roleType rule=rule remove="removeRule"}}
{{/each}}
@@ -67,7 +75,7 @@
{{#each roleArray as |role|}}
- {{other-role-row role=role otherRoles=model.roles remove="removeOtherRole"}}
+ {{other-role-row role=role otherRoles=otherRoles remove="removeOtherRole"}}
{{/each}}
diff --git a/lib/global-admin/addon/components/role-rule-row/component.js b/lib/global-admin/addon/components/role-rule-row/component.js
index d1584367a..a48fb4379 100644
--- a/lib/global-admin/addon/components/role-rule-row/component.js
+++ b/lib/global-admin/addon/components/role-rule-row/component.js
@@ -3,7 +3,6 @@ import { get, set, observer } from '@ember/object'
import C from 'ui/utils/constants';
import layout from './template';
-const rules = C.PROJECT_ROLE_RULES;
const verbs = C.RULE_VERBS;
export default Component.extend({
@@ -11,6 +10,7 @@ export default Component.extend({
rule: null,
rules: null,
resource: null,
+ roleType: null,
tagName: 'TR',
classNames: 'main-row',
@@ -31,6 +31,7 @@ export default Component.extend({
value: currentVerbs.indexOf(verb) > -1,
};
}));
+ const rules = C[`${this.get('roleType').toUpperCase()}_ROLE_RULES`];
this.set('rules', rules.map(rule => {
return {
label: rule,
diff --git a/lib/global-admin/addon/components/roles-header/component.js b/lib/global-admin/addon/components/roles-header/component.js
new file mode 100644
index 000000000..50b86e6ba
--- /dev/null
+++ b/lib/global-admin/addon/components/roles-header/component.js
@@ -0,0 +1,6 @@
+import Component from '@ember/component';
+import layout from './template';
+
+export default Component.extend({
+ layout,
+});
diff --git a/lib/global-admin/addon/components/roles-header/template.hbs b/lib/global-admin/addon/components/roles-header/template.hbs
new file mode 100644
index 000000000..4e3ed50e2
--- /dev/null
+++ b/lib/global-admin/addon/components/roles-header/template.hbs
@@ -0,0 +1,10 @@
+
diff --git a/lib/global-admin/addon/controllers/roles/edit.js b/lib/global-admin/addon/controllers/roles/edit.js
new file mode 100644
index 000000000..f6f9be640
--- /dev/null
+++ b/lib/global-admin/addon/controllers/roles/edit.js
@@ -0,0 +1,7 @@
+import Controller from '@ember/controller';
+import { inject as service } from '@ember/service';
+
+export default Controller.extend({
+ queryParams: ['type'],
+ type: 'project',
+});
diff --git a/lib/global-admin/addon/controllers/roles/index.js b/lib/global-admin/addon/controllers/roles/index.js
index ee76d28df..69e157b05 100644
--- a/lib/global-admin/addon/controllers/roles/index.js
+++ b/lib/global-admin/addon/controllers/roles/index.js
@@ -1,4 +1,5 @@
import Controller from '@ember/controller';
+import { inject as service } from '@ember/service';
import FilterState from 'ui/mixins/filter-state';
const headers = [
@@ -18,4 +19,22 @@ const headers = [
export default Controller.extend(FilterState, {
sortBy: 'name',
headers: headers,
+ queryParams: ['type'],
+ authzStore: service('authz-store'),
+ type: 'project',
+ searchText: '',
+
+ onRoleTypeChanged: function () {
+ const roleType = this.get('type');
+ return this.get('authzStore').find(`${roleType}RoleTemplate`, null, {
+ url: `${roleType}RoleTemplates`,
+ forceReload: true,
+ removeMissing: true,
+ sortBy: 'name',
+ })
+ .then((roles) => {
+ this.set('model', roles);
+ this.set('searchText', '');
+ });
+ }.observes('type'),
});
diff --git a/lib/global-admin/addon/controllers/roles/new.js b/lib/global-admin/addon/controllers/roles/new.js
new file mode 100644
index 000000000..01932dce9
--- /dev/null
+++ b/lib/global-admin/addon/controllers/roles/new.js
@@ -0,0 +1,7 @@
+import Controller from '@ember/controller';
+import { inject as service } from '@ember/service';
+
+export default Controller.extend({
+ queryParams: ['type'],
+ type: 'project',
+});
\ No newline at end of file
diff --git a/lib/global-admin/addon/routes/roles/edit.js b/lib/global-admin/addon/routes/roles/edit.js
index e3ada89f8..8275fd484 100644
--- a/lib/global-admin/addon/routes/roles/edit.js
+++ b/lib/global-admin/addon/routes/roles/edit.js
@@ -3,11 +3,14 @@ import { inject as service } from '@ember/service';
export default Route.extend({
authzStore: service('authz-store'),
+ queryParams: {
+ type: 'project',
+ },
model: function (params) {
- return this.get('authzStore').find('projectRoleTemplate', null, { url: 'projectRoleTemplates', forceReload: true, removeMissing: true }).then((roles) => {
+ return this.get('authzStore').find(`${params.type}RoleTemplate`, null, { url: `${params.type}RoleTemplates`, forceReload: true, removeMissing: true }).then((roles) => {
const role = roles.findBy('id', params.role_id);
if (!role) {
- this.replaceWith('roles.index');
+ this.replaceWith('roles.index', { queryParams: { type: 'project' } });
}
return {
role,
diff --git a/lib/global-admin/addon/routes/roles/index.js b/lib/global-admin/addon/routes/roles/index.js
index 8d9d113cf..e4fc9ba3b 100644
--- a/lib/global-admin/addon/routes/roles/index.js
+++ b/lib/global-admin/addon/routes/roles/index.js
@@ -3,7 +3,10 @@ import { inject as service } from '@ember/service';
export default Route.extend({
authzStore: service('authz-store'),
- model: function () {
- return this.get('authzStore').find('projectRoleTemplate', null, { url: 'projectRoleTemplates', forceReload: true, removeMissing: true }).then((roles) => roles);
+ queryParams: {
+ type: 'project',
+ },
+ model: function (params) {
+ return this.get('authzStore').find(`${params.type}RoleTemplate`, null, { url: `${params.type}RoleTemplates`, forceReload: true, removeMissing: true }).then((roles) => roles);
},
});
diff --git a/lib/global-admin/addon/routes/roles/new.js b/lib/global-admin/addon/routes/roles/new.js
index 4fd1bdd29..c8046ee9f 100644
--- a/lib/global-admin/addon/routes/roles/new.js
+++ b/lib/global-admin/addon/routes/roles/new.js
@@ -3,9 +3,12 @@ import { inject as service } from '@ember/service';
export default Route.extend({
authzStore: service('authz-store'),
- model: function () {
+ queryParams: {
+ type: 'project',
+ },
+ model: function (params) {
var role = this.get('authzStore').createRecord({
- type: 'projectRoleTemplate',
+ type: `${params.type}RoleTemplate`,
name: '',
rules: [{
apiGroups: ['*'],
@@ -13,9 +16,9 @@ export default Route.extend({
resources: [],
verbs: [],
}],
- projectRoleTemplateIds: [''],
});
- return this.get('authzStore').find('projectRoleTemplate', null, { url: 'projectRoleTemplates', forceReload: true, removeMissing: true }).then((roles) => {
+ role.set(`${params.type}RoleTemplateIds`, ['']);
+ return this.get('authzStore').find(`${params.type}RoleTemplate`, null, { url: `${params.type}RoleTemplates`, forceReload: true, removeMissing: true }).then((roles) => {
return {
role: role,
roles: roles,
diff --git a/lib/global-admin/addon/templates/application.hbs b/lib/global-admin/addon/templates/application.hbs
index c54f96d8c..4474bb56e 100644
--- a/lib/global-admin/addon/templates/application.hbs
+++ b/lib/global-admin/addon/templates/application.hbs
@@ -2,7 +2,7 @@