You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficcontrol.apache.org by de...@apache.org on 2018/04/04 16:32:11 UTC

[incubator-trafficcontrol] branch master updated: adds roles and capabilities tables to TP

This is an automated email from the ASF dual-hosted git repository.

dewrich pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-trafficcontrol.git


The following commit(s) were added to refs/heads/master by this push:
     new 74c742a  adds roles and capabilities tables to TP
74c742a is described below

commit 74c742a3c8691ee0d0b4e856cafdfb0c4a505852
Author: Jeremy Mitchell <mi...@gmail.com>
AuthorDate: Mon Aug 28 20:54:05 2017 -0600

    adds roles and capabilities tables to TP
---
 traffic_portal/app/src/app.js                      |  6 +++
 .../app/src/common/api/CapabilityService.js        | 57 ++++++++++++++++++++++
 traffic_portal/app/src/common/api/RoleService.js   |  4 +-
 traffic_portal/app/src/common/api/index.js         |  1 +
 .../common/modules/navigation/navigation.tpl.html  |  2 +
 .../capabilities/TableCapabilitiesController.js    | 39 +++++++++++++++
 .../src/common/modules/table/capabilities/index.js | 21 ++++++++
 .../table/capabilities/table.capabilities.tpl.html | 50 +++++++++++++++++++
 .../modules/table/roles/TableRolesController.js    | 39 +++++++++++++++
 .../app/src/common/modules/table/roles/index.js    | 21 ++++++++
 .../modules/table/roles/table.roles.tpl.html       | 52 ++++++++++++++++++++
 .../private/capabilities/capabilities.tpl.html     | 22 +++++++++
 .../app/src/modules/private/capabilities/index.js  | 34 +++++++++++++
 .../src/modules/private/capabilities/list/index.js | 39 +++++++++++++++
 .../app/src/modules/private/roles/index.js         | 34 +++++++++++++
 .../app/src/modules/private/roles/list/index.js    | 39 +++++++++++++++
 .../app/src/modules/private/roles/roles.tpl.html   | 22 +++++++++
 17 files changed, 480 insertions(+), 2 deletions(-)

diff --git a/traffic_portal/app/src/app.js b/traffic_portal/app/src/app.js
index 990e8f6..49a4645 100644
--- a/traffic_portal/app/src/app.js
+++ b/traffic_portal/app/src/app.js
@@ -59,6 +59,8 @@ var trafficPortal = angular.module('trafficPortal', [
         require('./modules/private/cacheGroups/staticDnsEntries').name,
         require('./modules/private/cacheChecks').name,
         require('./modules/private/cacheStats').name,
+        require('./modules/private/capabilities').name,
+        require('./modules/private/capabilities/list').name,
         require('./modules/private/cdns').name,
         require('./modules/private/cdns/config').name,
         require('./modules/private/cdns/deliveryServices').name,
@@ -143,6 +145,8 @@ var trafficPortal = angular.module('trafficPortal', [
         require('./modules/private/regions/list').name,
         require('./modules/private/regions/physLocations').name,
         require('./modules/private/regions/new').name,
+        require('./modules/private/roles').name,
+        require('./modules/private/roles/list').name,
         require('./modules/private/servers').name,
         require('./modules/private/servers/configFiles').name,
         require('./modules/private/servers/deliveryServices').name,
@@ -272,6 +276,7 @@ var trafficPortal = angular.module('trafficPortal', [
         require('./common/modules/table/cacheGroupParameters').name,
         require('./common/modules/table/cacheGroupServers').name,
         require('./common/modules/table/cacheGroupStaticDnsEntries').name,
+        require('./common/modules/table/capabilities').name,
         require('./common/modules/table/changeLogs').name,
         require('./common/modules/table/asns').name,
         require('./common/modules/table/cdns').name,
@@ -304,6 +309,7 @@ var trafficPortal = angular.module('trafficPortal', [
         require('./common/modules/table/profiles').name,
         require('./common/modules/table/regions').name,
         require('./common/modules/table/regionPhysLocations').name,
+        require('./common/modules/table/roles').name,
         require('./common/modules/table/servers').name,
         require('./common/modules/table/serverConfigFiles').name,
         require('./common/modules/table/serverDeliveryServices').name,
diff --git a/traffic_portal/app/src/common/api/CapabilityService.js b/traffic_portal/app/src/common/api/CapabilityService.js
new file mode 100644
index 0000000..da8df4f
--- /dev/null
+++ b/traffic_portal/app/src/common/api/CapabilityService.js
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+var CapabilityService = function(Restangular, messageModel) {
+
+	this.getCapabilities = function(queryParams) {
+		return Restangular.all('capabilities').getList(queryParams);
+	};
+
+	this.getCapability = function(id) {
+		return Restangular.one("capabilities", id).get();
+	};
+
+	this.updateCapability = function(capability) {
+		return capability.put()
+			.then(
+				function() {
+					messageModel.setMessages([ { level: 'success', text: 'Capability updated' } ], false);
+				},
+				function(fault) {
+					messageModel.setMessages(fault.data.alerts, false);
+				}
+			);
+	};
+
+	this.deleteCapability = function(capability) {
+		return capability.remove()
+			.then(
+				function() {
+					messageModel.setMessages([ { level: 'success', text: 'Capability deleted' } ], true);
+				},
+				function(fault) {
+					messageModel.setMessages(fault.data.alerts, true);
+				}
+			);
+	};
+
+};
+
+CapabilityService.$inject = ['Restangular', 'messageModel'];
+module.exports = CapabilityService;
diff --git a/traffic_portal/app/src/common/api/RoleService.js b/traffic_portal/app/src/common/api/RoleService.js
index bcd9b3b..70b77bc 100644
--- a/traffic_portal/app/src/common/api/RoleService.js
+++ b/traffic_portal/app/src/common/api/RoleService.js
@@ -39,8 +39,8 @@ var RoleService = function(Restangular, messageModel) {
         );
     };
 
-    this.deleteRole = function(id) {
-        return Restangular.one("roles", id).remove()
+    this.deleteRole = function(role) {
+        return role.remove()
             .then(
                 function() {
                     messageModel.setMessages([ { level: 'success', text: 'Role deleted' } ], true);
diff --git a/traffic_portal/app/src/common/api/index.js b/traffic_portal/app/src/common/api/index.js
index 3942a76..9da91f6 100644
--- a/traffic_portal/app/src/common/api/index.js
+++ b/traffic_portal/app/src/common/api/index.js
@@ -23,6 +23,7 @@ module.exports = angular.module('trafficPortal.api', [])
     .service('cacheGroupService', require('./CacheGroupService'))
     .service('cacheGroupParameterService', require('./CacheGroupParameterService'))
 	.service('cacheStatsService', require('./CacheStatsService'))
+	.service('capabilityService', require('./CapabilityService'))
 	.service('cdnService', require('./CDNService'))
     .service('changeLogService', require('./ChangeLogService'))
     .service('deliveryServiceService', require('./DeliveryServiceService'))
diff --git a/traffic_portal/app/src/common/modules/navigation/navigation.tpl.html b/traffic_portal/app/src/common/modules/navigation/navigation.tpl.html
index be46a18..50cc57d 100644
--- a/traffic_portal/app/src/common/modules/navigation/navigation.tpl.html
+++ b/traffic_portal/app/src/common/modules/navigation/navigation.tpl.html
@@ -42,6 +42,7 @@ under the License.
                     <ul class="nav child_menu" style="display: none">
                         <li class="side-menu-category-item" ng-class="{'current-page': isState('trafficPortal.private.asns')}"><a href="/#!/asns">ASNs</a></li>
                         <li class="side-menu-category-item" ng-class="{'current-page': isState('trafficPortal.private.cacheGroups')}"><a href="/#!/cache-groups">Cache Groups</a></li>
+                        <!--<li class="side-menu-category-item" ng-class="{'current-page': isState('trafficPortal.private.capabilities')}"><a href="/#!/capabilities">Capabilities</a></li>-->
                         <li class="side-menu-category-item" ng-class="{'current-page': isState('trafficPortal.private.cdns')}"><a href="/#!/cdns">CDNs</a></li>
                         <li class="side-menu-category-item" ng-class="{'current-page': isState('trafficPortal.private.divisions')}"><a href="/#!/divisions">Divisions</a></li>
                         <li class="side-menu-category-item" ng-class="{'current-page': isState('trafficPortal.private.jobs')}"><a href="/#!/jobs">Jobs</a></li>
@@ -49,6 +50,7 @@ under the License.
                         <li class="side-menu-category-item" ng-class="{'current-page': isState('trafficPortal.private.parameters')}"><a href="/#!/parameters">Parameters</a></li>
                         <li class="side-menu-category-item" ng-class="{'current-page': isState('trafficPortal.private.profiles')}"><a href="/#!/profiles">Profiles</a></li>
                         <li class="side-menu-category-item" ng-class="{'current-page': isState('trafficPortal.private.regions')}"><a href="/#!/regions">Regions</a></li>
+                        <li class="side-menu-category-item" ng-class="{'current-page': isState('trafficPortal.private.roles')}"><a href="/#!/roles">Roles</a></li>
                         <li class="side-menu-category-item" ng-class="{'current-page': isState('trafficPortal.private.servers')}"><a href="/#!/servers">Servers</a></li>
                         <li class="side-menu-category-item" ng-class="{'current-page': isState('trafficPortal.private.statuses')}"><a href="/#!/statuses">Statuses</a></li>
                         <li class="side-menu-category-item" ng-class="{'current-page': isState('trafficPortal.private.tenants')}"><a href="/#!/tenants">Tenants</a></li>
diff --git a/traffic_portal/app/src/common/modules/table/capabilities/TableCapabilitiesController.js b/traffic_portal/app/src/common/modules/table/capabilities/TableCapabilitiesController.js
new file mode 100644
index 0000000..0184f41
--- /dev/null
+++ b/traffic_portal/app/src/common/modules/table/capabilities/TableCapabilitiesController.js
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+var TableCapabilitiesController = function(capabilities, $scope, $state) {
+
+	$scope.capabilities = capabilities;
+
+	$scope.refresh = function() {
+		$state.reload(); // reloads all the resolves for the view
+	};
+
+	angular.element(document).ready(function () {
+		$('#capabilitiesTable').dataTable({
+			"aLengthMenu": [[25, 50, 100, -1], [25, 50, 100, "All"]],
+			"iDisplayLength": 25,
+			"aaSorting": []
+		});
+	});
+
+};
+
+TableCapabilitiesController.$inject = ['capabilities', '$scope', '$state'];
+module.exports = TableCapabilitiesController;
diff --git a/traffic_portal/app/src/common/modules/table/capabilities/index.js b/traffic_portal/app/src/common/modules/table/capabilities/index.js
new file mode 100644
index 0000000..4a1f252
--- /dev/null
+++ b/traffic_portal/app/src/common/modules/table/capabilities/index.js
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+module.exports = angular.module('trafficPortal.table.capabilities', [])
+	.controller('TableCapabilitiesController', require('./TableCapabilitiesController'));
diff --git a/traffic_portal/app/src/common/modules/table/capabilities/table.capabilities.tpl.html b/traffic_portal/app/src/common/modules/table/capabilities/table.capabilities.tpl.html
new file mode 100644
index 0000000..bf43e04
--- /dev/null
+++ b/traffic_portal/app/src/common/modules/table/capabilities/table.capabilities.tpl.html
@@ -0,0 +1,50 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you 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.
+-->
+
+<div class="x_panel">
+    <div class="x_title">
+        <ol class="breadcrumb pull-left">
+            <li class="active">Capabilities</li>
+        </ol>
+        <div class="pull-right">
+            <button class="btn btn-default" title="Refresh" ng-click="refresh()"><i class="fa fa-refresh"></i></button>
+        </div>
+        <div class="clearfix"></div>
+    </div>
+    <div class="x_content">
+        <br>
+        <table id="capabilitiesTable" class="table responsive-utilities jambo_table">
+            <thead>
+            <tr class="headings">
+                <th>name</th>
+                <th>description</th>
+            </tr>
+            </thead>
+            <tbody>
+            <tr ng-repeat="capability in ::capabilities">
+                <td>{{::capability.name}}</td>
+                <td>{{::capability.description}}</td>
+            </tr>
+            </tbody>
+        </table>
+    </div>
+</div>
+
+
+
diff --git a/traffic_portal/app/src/common/modules/table/roles/TableRolesController.js b/traffic_portal/app/src/common/modules/table/roles/TableRolesController.js
new file mode 100644
index 0000000..22d3cb1
--- /dev/null
+++ b/traffic_portal/app/src/common/modules/table/roles/TableRolesController.js
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+var TableRolesController = function(roles, $scope, $state) {
+
+	$scope.roles = roles;
+
+	$scope.refresh = function() {
+		$state.reload(); // reloads all the resolves for the view
+	};
+
+	angular.element(document).ready(function () {
+		$('#rolesTable').dataTable({
+			"aLengthMenu": [[25, 50, 100, -1], [25, 50, 100, "All"]],
+			"iDisplayLength": 25,
+			"aaSorting": []
+		});
+	});
+
+};
+
+TableRolesController.$inject = ['roles', '$scope', '$state'];
+module.exports = TableRolesController;
diff --git a/traffic_portal/app/src/common/modules/table/roles/index.js b/traffic_portal/app/src/common/modules/table/roles/index.js
new file mode 100644
index 0000000..b50b89f
--- /dev/null
+++ b/traffic_portal/app/src/common/modules/table/roles/index.js
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+module.exports = angular.module('trafficPortal.table.roles', [])
+	.controller('TableRolesController', require('./TableRolesController'));
diff --git a/traffic_portal/app/src/common/modules/table/roles/table.roles.tpl.html b/traffic_portal/app/src/common/modules/table/roles/table.roles.tpl.html
new file mode 100644
index 0000000..a3193a5
--- /dev/null
+++ b/traffic_portal/app/src/common/modules/table/roles/table.roles.tpl.html
@@ -0,0 +1,52 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you 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.
+-->
+
+<div class="x_panel">
+    <div class="x_title">
+        <ol class="breadcrumb pull-left">
+            <li class="active">Roles</li>
+        </ol>
+        <div class="pull-right">
+            <button class="btn btn-default" title="Refresh" ng-click="refresh()"><i class="fa fa-refresh"></i></button>
+        </div>
+        <div class="clearfix"></div>
+    </div>
+    <div class="x_content">
+        <br>
+        <table id="rolesTable" class="table responsive-utilities jambo_table">
+            <thead>
+            <tr class="headings">
+                <th>name</th>
+                <th>privilege level</th>
+                <th>description</th>
+            </tr>
+            </thead>
+            <tbody>
+            <tr ng-repeat="role in ::roles">
+                <td>{{::role.name}}</td>
+                <td>{{::role.privLevel}}</td>
+                <td>{{::role.description}}</td>
+            </tr>
+            </tbody>
+        </table>
+    </div>
+</div>
+
+
+
diff --git a/traffic_portal/app/src/modules/private/capabilities/capabilities.tpl.html b/traffic_portal/app/src/modules/private/capabilities/capabilities.tpl.html
new file mode 100644
index 0000000..4ad28d4
--- /dev/null
+++ b/traffic_portal/app/src/modules/private/capabilities/capabilities.tpl.html
@@ -0,0 +1,22 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you 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.
+-->
+
+<div id="capabilitiesContainer">
+    <div ui-view="capabilitiesContent"></div>
+</div>
diff --git a/traffic_portal/app/src/modules/private/capabilities/index.js b/traffic_portal/app/src/modules/private/capabilities/index.js
new file mode 100644
index 0000000..35e452d
--- /dev/null
+++ b/traffic_portal/app/src/modules/private/capabilities/index.js
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+module.exports = angular.module('trafficPortal.private.capabilities', [])
+	.config(function($stateProvider, $urlRouterProvider) {
+		$stateProvider
+			.state('trafficPortal.private.capabilities', {
+				url: 'capabilities',
+				abstract: true,
+				views: {
+					privateContent: {
+						templateUrl: 'modules/private/capabilities/capabilities.tpl.html'
+					}
+				}
+			})
+		;
+		$urlRouterProvider.otherwise('/');
+	});
diff --git a/traffic_portal/app/src/modules/private/capabilities/list/index.js b/traffic_portal/app/src/modules/private/capabilities/list/index.js
new file mode 100644
index 0000000..08b6e42
--- /dev/null
+++ b/traffic_portal/app/src/modules/private/capabilities/list/index.js
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+module.exports = angular.module('trafficPortal.private.capabilities.list', [])
+	.config(function($stateProvider, $urlRouterProvider) {
+		$stateProvider
+			.state('trafficPortal.private.capabilities.list', {
+				url: '',
+				views: {
+					capabilitiesContent: {
+						templateUrl: 'common/modules/table/capabilities/table.capabilities.tpl.html',
+						controller: 'TableCapabilitiesController',
+						resolve: {
+							capabilities: function(capabilityService) {
+								return capabilityService.getCapabilities();
+							}
+						}
+					}
+				}
+			})
+		;
+		$urlRouterProvider.otherwise('/');
+	});
diff --git a/traffic_portal/app/src/modules/private/roles/index.js b/traffic_portal/app/src/modules/private/roles/index.js
new file mode 100644
index 0000000..57c2407
--- /dev/null
+++ b/traffic_portal/app/src/modules/private/roles/index.js
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+module.exports = angular.module('trafficPortal.private.roles', [])
+	.config(function($stateProvider, $urlRouterProvider) {
+		$stateProvider
+			.state('trafficPortal.private.roles', {
+				url: 'roles',
+				abstract: true,
+				views: {
+					privateContent: {
+						templateUrl: 'modules/private/roles/roles.tpl.html'
+					}
+				}
+			})
+		;
+		$urlRouterProvider.otherwise('/');
+	});
diff --git a/traffic_portal/app/src/modules/private/roles/list/index.js b/traffic_portal/app/src/modules/private/roles/list/index.js
new file mode 100644
index 0000000..f991001
--- /dev/null
+++ b/traffic_portal/app/src/modules/private/roles/list/index.js
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+module.exports = angular.module('trafficPortal.private.roles.list', [])
+	.config(function($stateProvider, $urlRouterProvider) {
+		$stateProvider
+			.state('trafficPortal.private.roles.list', {
+				url: '',
+				views: {
+					rolesContent: {
+						templateUrl: 'common/modules/table/roles/table.roles.tpl.html',
+						controller: 'TableRolesController',
+						resolve: {
+							roles: function(roleService) {
+								return roleService.getRoles({ orderby: 'priv_level DESC' });
+							}
+						}
+					}
+				}
+			})
+		;
+		$urlRouterProvider.otherwise('/');
+	});
diff --git a/traffic_portal/app/src/modules/private/roles/roles.tpl.html b/traffic_portal/app/src/modules/private/roles/roles.tpl.html
new file mode 100644
index 0000000..7f9d903
--- /dev/null
+++ b/traffic_portal/app/src/modules/private/roles/roles.tpl.html
@@ -0,0 +1,22 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you 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.
+-->
+
+<div id="rolesContainer">
+    <div ui-view="rolesContent"></div>
+</div>

-- 
To stop receiving notification emails like this one, please contact
dewrich@apache.org.