提交 f16274a3 编写于 作者: H huangchenhai 提交者: Jason Song

Add access key management UI

上级 759d3643
<!doctype html>
<html ng-app="access_key">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="icon" href="../img/config.png">
<!-- styles -->
<link rel="stylesheet" type="text/css" href="../vendor/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="../vendor/angular/angular-toastr-1.4.1.min.css">
<link rel="stylesheet" type="text/css" media='all' href="../vendor/angular/loading-bar.min.css">
<link rel="stylesheet" type="text/css" href="../styles/common-style.css">
<link rel="stylesheet" type="text/css" href="../vendor/select2/select2.min.css">
<title>{{'Config.AccessKeyManage' | translate }}</title>
</head>
<body>
<apollonav></apollonav>
<div class="container-fluid apollo-container project-setting" ng-controller="AccessKeyController">
<section class="col-md-10 col-md-offset-1 panel hidden">
<header class="panel-heading">
<div class="row">
<div class="col-md-7">
<h4 class="modal-title">{{'Config.AccessKeyManage' | translate }} (
{{'Common.AppId' | translate }}:<label ng-bind="pageContext.appId"></label> )
</h4>
</div>
<div class="col-md-5 text-right">
<a type="button" class="btn btn-info" data-dismiss="modal"
href="/config.html?#appid={{pageContext.appId}}">{{'Common.ReturnToIndex' | translate }}
</a>
</div>
</div>
</header>
<div class="panel-body row">
<section class="context" ng-show="hasAssignUserPermission">
<!--project admin-->
<section class="form-horizontal" ng-show="hasManageAppMasterPermission">
<h5>{{'App.Setting.Admin' | translate }}
<small>
{{'App.AccessKey.AdminTips' | translate }}
</small>
</h5>
<hr>
<div class="row">
<label class="col-sm-1 control-label" style="width: 150px;">
{{'AccessKey.AddButton.Label' | translate }}
</label>
<form class="col-sm-8 form-inline" ng-submit="create()">
<div class="form-group" style="padding-left: 15px">
<select class="form-control input-sm" style="width: 450px;" ng-model="addAccessKeySelectedEnv">
<option value="">{{'Cluster.PleaseChooseEnvironment' | translate }}</option>
<option ng-repeat="env in envs" ng-value="env">{{env}}</option>
</select>
</div>
<button type="submit" class="btn btn-default" style="margin-left: 20px;"
ng-disabled="addAccessKeySelectedEnv == ''">{{'App.Setting.Add' | translate }}
</button>
</form>
</div>
</section>
<!--application info-->
<section ng-repeat="env in envs" ng-value="env">
<hr>
<h4>{{'Common.Environment' | translate }}: {{env}}
</h4>
<table class="table table-striped table-hover table-bordered">
<thead>
<tr>
<th>{{'AccessKey.ConfigAccessKeys.Secret' | translate }}</th>
<th>{{'AccessKey.ConfigAccessKeys.Status' | translate }}</th>
<th>{{'AccessKey.ConfigAccessKeys.LastModify' | translate }}</th>
<th>{{'AccessKey.ConfigAccessKeys.LastModifyTime' | translate }}</th>
<th>{{'AccessKey.ConfigAccessKeys.Operator' | translate }}</th>
</tr>
</thead>
<tbody>
<tr ng-show="(!accessKeys[env] || accessKeys[env].length < 1)">
<td colspan="4">{{'AccessKey.NoAccessKeyServiceTips' | translate }}</td>
</tr>
<tr ng-show="accessKeys[env] && accessKeys[env].length > 0"
ng-repeat="accessKey in accessKeys[env]">
<td style="text-align: center;">{{accessKey.secret}}</td>
<td style="text-align: center;" ng-style="{'color': accessKey.enabled ? '#5cb85c' : '#d20707'}">{{accessKey.enabled ? ('AccessKey.Operator.Enabled' | translate) : ('AccessKey.Operator.Disabled' | translate) }}</td>
<td style="text-align: center;">
{{accessKey.dataChangeLastModifiedBy}}
</td>
<td style="text-align: center;">{{accessKey.dataChangeLastModifiedTime
| date: 'yyyy-MM-dd HH:mm:ss'}}
</td>
<td style="text-align: center;">
<a href="javascript:;"
ng-click="enable(accessKey.id, env)" ng-if="!accessKey.enabled">{{'AccessKey.Operator.Enable' | translate}}</a>
<a href="javascript:;"
ng-click="disable(accessKey.id, env)" ng-if="accessKey.enabled">{{'AccessKey.Operator.Disable' | translate}}</a>
<a href="javascript:;"
ng-click="remove(accessKey.id, env)">{{'AccessKey.Operator.Remove' | translate }}</a>
</td>
</tr>
</tbody>
</table>
</section>
</section>
<section class="context" ng-show="!hasAssignUserPermission">
<div class="panel-body text-center">
<h4 translate="App.AccessKey.NoPermissionTips" translate-value-users="{{admins.join(',')}}"></h4>
</div>
</section>
</div>
</section>
</div>
<div ng-include="'../views/common/footer.html'"></div>
<!-- jquery.js -->
<script src="../vendor/jquery.min.js" type="text/javascript"></script>
<!--angular-->
<script src="../vendor/angular/angular.min.js"></script>
<script src="../vendor/angular/angular-route.min.js"></script>
<script src="../vendor/angular/angular-resource.min.js"></script>
<script src="../vendor/angular/angular-toastr-1.4.1.tpls.min.js"></script>
<script src="../vendor/angular/loading-bar.min.js"></script>
<script src="../vendor/angular/angular-cookies.min.js"></script>
<script src="../vendor/angular/angular-translate.2.18.1/angular-translate.min.js"></script>
<script src="../vendor/angular/angular-translate.2.18.1/angular-translate-loader-static-files.min.js"></script>
<script src="../vendor/angular/angular-translate.2.18.1/angular-translate-storage-cookie.min.js"></script>
<!--valdr-->
<script src="../vendor/valdr/valdr.min.js" type="text/javascript"></script>
<script src="../vendor/valdr/valdr-message.min.js" type="text/javascript"></script>
<!-- bootstrap.js -->
<script src="../vendor/bootstrap/js/bootstrap.min.js" type="text/javascript"></script>
<script src="../vendor/lodash.min.js"></script>
<script src="../vendor/select2/select2.min.js" type="text/javascript"></script>
<!--biz-->
<!--must import-->
<script type="application/javascript" src="../scripts/app.js"></script>
<script type="application/javascript" src="../scripts/services/AppService.js"></script>
<script type="application/javascript" src="../scripts/services/EnvService.js"></script>
<script type="application/javascript" src="../scripts/services/UserService.js"></script>
<script type="application/javascript" src="../scripts/services/CommonService.js"></script>
<script type="application/javascript" src="../scripts/services/PermissionService.js"></script>
<script type="application/javascript" src="../scripts/services/OrganizationService.js"></script>
<script type="application/javascript" src="../scripts/services/PermissionService.js"></script>
<script type="application/javascript" src="../scripts/services/AccessKeyService.js"></script>
<script type="application/javascript" src="../scripts/AppUtils.js"></script>
<script type="application/javascript" src="../scripts/PageCommon.js"></script>
<script type="application/javascript" src="../scripts/directive/directive.js"></script>
<script type="application/javascript" src="../scripts/valdr.js"></script>
<script type="application/javascript" src="../scripts/controller/AccessKeyController.js"></script>
</body>
</html>
\ No newline at end of file
......@@ -120,6 +120,11 @@
apollo-img-src="'project-manage'"
apollo-href="'app/setting.html?#/appid=' + pageContext.appId"></apolloentrance>
<apolloentrance apollo-title="'Config.AccessKeyManage' | translate"
apollo-img-src="'project-manage'"
apollo-href="'/app/access_key.html?#/appid=' + pageContext.appId"
ng-show="hasCreateClusterPermission"></apolloentrance>
<a class="list-group-item" ng-show="missEnvs.length > 0" ng-click="createAppInMissEnv()">
<div class="row icon-text icon-plus-orange">
<p class="btn-title ng-binding">{{'Config.CreateAppMissEnv' | translate }}</p>
......
......@@ -334,6 +334,7 @@
"Config.MissEnv": "Missing environment",
"Config.MissNamespace": "Missing Namespace",
"Config.ProjectManage": "Manage Project",
"Config.AccessKeyManage": "Manage AccessKey",
"Config.CreateAppMissEnv": "Recover Environments",
"Config.CreateAppMissNamespace": "Recover Namespaces",
"Config.AddCluster": "Add Cluster",
......@@ -463,6 +464,30 @@
"ServiceConfig.PleaseEnterKey": "Please enter key",
"ServiceConfig.KeyNotExistsAndCreateTip": "Key: '{{key}}' does not exist. Click Save to create the configuration item.",
"ServiceConfig.KeyExistsAndSaveTip": "Key: '{{key}}' already exists. Click Save will override the configuration item.",
"AccessKey.AddButton.Label": "Create AccessKey",
"AccessKey.NoAccessKeyServiceTips": "No accessKey found!",
"AccessKey.ConfigAccessKeys.Secret": "AccessKey Secret",
"AccessKey.ConfigAccessKeys.Status": "Status",
"AccessKey.ConfigAccessKeys.LastModify": "Last Modifier",
"AccessKey.ConfigAccessKeys.LastModifyTime": "Last Modified Time",
"AccessKey.ConfigAccessKeys.Operator": "Operation",
"AccessKey.Operator.Disable": "Disable",
"AccessKey.Operator.Enable": "Enable",
"AccessKey.Operator.Disabled": "Disabled",
"AccessKey.Operator.Enabled": "Enabled",
"AccessKey.Operator.Remove": "Remove",
"AccessKey.Operator.CreateSuccess": "Create accessKey for '{{env}}' success",
"AccessKey.Operator.DisabledSuccess": "Disabled accessKey for '{{env}}' success",
"AccessKey.Operator.EnabledSuccess": "Enabled accessKey for '{{env}}' success",
"AccessKey.Operator.RemoveSuccess": "Remove accessKey for '{{env}}' success",
"AccessKey.Operator.CreateError": "Failed to create accessKey for '{{env}}'",
"AccessKey.Operator.DisabledError": "Failed to disabled accessKey for '{{env}}'",
"AccessKey.Operator.EnabledError": "Failed to enabled accessKey for '{{env}}'",
"AccessKey.Operator.RemoveError": "Failed to remove accessKey for '{{env}}'",
"AccessKey.Operator.DisabledTips": "Are you sure disable {{env}} AccessKey?",
"AccessKey.Operator.EnabledTips": "Are you sure enable {{env}} AccessKey?",
"AccessKey.Operator.RemoveTips": "Are you sure remove {{env}} AccessKey?",
"AccessKey.LoadError": "Failed to load accessKeys for '{{env}}'",
"SystemInfo.Title": "System Information",
"SystemInfo.SystemVersion": "System version",
"SystemInfo.Tips1": "The environment list comes from the <strong>apollo.portal.envs</strong> configuration in Apollo PortalDB.ServerConfig, and can be configured in <a href=\"{{serverConfigUrl}}\">System Configuration</a> page. For more information, please refer the <strong>apollo.portal.envs - supportable environment list</strong> section in <a href=\"{{wikiUrl}}\">Distributed Deployment Guide</a>.",
......@@ -649,6 +674,8 @@
"App.AppOwnerTips": "(After enabling the application administrator allocation restrictions, the application owner and project administrator are default to current account, not subject to change)",
"App.AppAdminTips1": "(The application owner has project administrator permission by default.",
"App.AppAdminTips2": "Project administrators can create namespace, cluster, and assign user permissions)",
"App.AccessKey.AdminTips": "(Project administrators can config accessKey)",
"App.AccessKey.NoPermissionTips": "You do not have permission to operate, please ask [{{users}}] to authorize",
"App.Setting.Title": "Manage Project",
"App.Setting.Admin": "Administrators",
"App.Setting.AdminTips": "(Project administrators have the following permissions: 1. Create namespace 2. Create clusters 3. Manage project and namespace permissions)",
......
......@@ -334,6 +334,7 @@
"Config.MissEnv": "缺失的环境",
"Config.MissNamespace": "缺失的Namespace",
"Config.ProjectManage": "管理项目",
"Config.AccessKeyManage": "管理秘钥",
"Config.CreateAppMissEnv": "补缺环境",
"Config.CreateAppMissNamespace": "补缺Namespace",
"Config.AddCluster": "添加集群",
......@@ -463,6 +464,30 @@
"ServiceConfig.PleaseEnterKey": "请输入key",
"ServiceConfig.KeyNotExistsAndCreateTip": "Key: '{{key}}' 不存在,点击保存后会创建该配置项",
"ServiceConfig.KeyExistsAndSaveTip": "Key: '{{key}}' 已存在,点击保存后会覆盖该配置项",
"AccessKey.AddButton.Label": "创建AccessKey",
"AccessKey.NoAccessKeyServiceTips": "No accessKey found!",
"AccessKey.ConfigAccessKeys.Secret": "AccessKey Secret",
"AccessKey.ConfigAccessKeys.Status": "状态",
"AccessKey.ConfigAccessKeys.LastModify": "最后修改人",
"AccessKey.ConfigAccessKeys.LastModifyTime": "最后修改时间",
"AccessKey.ConfigAccessKeys.Operator": "操作",
"AccessKey.Operator.Disable": "禁用",
"AccessKey.Operator.Enable": "启用",
"AccessKey.Operator.Disabled": "已禁用",
"AccessKey.Operator.Enabled": "已启用",
"AccessKey.Operator.Remove": "删除",
"AccessKey.Operator.CreateSuccess": " {{env}}环境AccessKey创建成功",
"AccessKey.Operator.DisabledSuccess": " {{env}}环境AccessKey禁用成功",
"AccessKey.Operator.EnabledSuccess": " {{env}}环境AccessKey启用成功",
"AccessKey.Operator.RemoveSuccess": " {{env}}环境AccessKey删除成功",
"AccessKey.Operator.CreateError": " {{env}}环境AccessKey创建失败",
"AccessKey.Operator.DisabledError": " {{env}}环境AccessKey禁用失败",
"AccessKey.Operator.EnabledError": " {{env}}环境AccessKey启用失败",
"AccessKey.Operator.RemoveError": " {{env}}环境AccessKey删除失败",
"AccessKey.Operator.DisabledTips": "是否确定禁用{{env}}AccessKey?",
"AccessKey.Operator.EnabledTips": " 是否确定启用{{env}}AccessKey?",
"AccessKey.Operator.RemoveTips": " 是否确定删除{{env}}AccessKey?",
"AccessKey.LoadError": "加载 '{{env}}' AccessKeys出错",
"SystemInfo.Title": "系统信息",
"SystemInfo.SystemVersion": "系统版本",
"SystemInfo.Tips1": "环境列表来自于ApolloPortalDB.ServerConfig中的<strong>apollo.portal.envs</strong>配置,可以到<a href=\"{{serverConfigUrl}}\">系统参数</a>页面配置,更多信息可以参考<a href=\"{{wikiUrl}}\">分布式部署指南</a>中的<strong>apollo.portal.envs - 可支持的环境列表</strong>章节。",
......@@ -649,6 +674,8 @@
"App.AppOwnerTips": "(开启项目管理员分配权限控制后,应用负责人和项目管理员默认为本账号,不可选择)",
"App.AppAdminTips1": "(应用负责人默认具有项目管理员权限,",
"App.AppAdminTips2": "项目管理员可以创建Namespace和集群、分配用户权限)",
"App.AccessKey.AdminTips": "(项目管理员可以配置秘钥)",
"App.AccessKey.NoPermissionTips": "您没有权限操作,请找 [{{users}}] 开通权限",
"App.Setting.Title": "项目管理",
"App.Setting.Admin": "管理员",
"App.Setting.AdminTips": "(项目管理员具有以下权限: 1. 创建Namespace 2. 创建集群 3. 管理项目、Namespace权限)",
......
......@@ -66,3 +66,5 @@ var login_module = angular.module('login', ['app.service', 'toastr', 'app.util',
var delete_app_cluster_namespace_module = angular.module('delete_app_cluster_namespace', ['app.service', 'apollo.directive', 'app.util', 'toastr', 'angular-loading-bar']);
//system info
var system_info_module = angular.module('system_info', ['app.service', 'apollo.directive', 'app.util', 'toastr', 'angular-loading-bar']);
//access secretKey
var access_key_module = angular.module('access_key', ['app.service', 'apollo.directive', 'app.util', 'toastr', 'angular-loading-bar']);
access_key_module.controller('AccessKeyController',
['$scope', '$location', '$translate', 'toastr',
'AppService', 'AppUtil', 'PermissionService',
'EnvService', 'UserService', 'AccessKeyService',
AccessKeyController]);
function AccessKeyController($scope, $location, $translate, toastr,
AppService, AppUtil, PermissionService,
EnvService, UserService, AccessKeyService) {
var params = AppUtil.parseParams($location.$$url);
$scope.pageContext = {
appId: params.appid
};
$scope.display = {
app: {
edit: false
}
};
$scope.addAccessKeySelectedEnv = "";
$scope.accessKeys = null;
$scope.submitBtnDisabled = false;
$scope.userSelectWidgetId = 'toAssignMasterRoleUser';
$scope.create = create;
$scope.remove = remove;
$scope.enable = enable;
$scope.disable = disable;
init();
function init() {
initEnv();
initPermission();
initApplication();
}
function initEnv() {
EnvService.find_all_envs()
.then(function (result) {
$scope.envs = result;
initAccessKeys();
});
}
function initPermission() {
PermissionService.has_assign_user_permission($scope.pageContext.appId)
.then(function (result) {
$scope.hasAssignUserPermission = result.hasPermission;
PermissionService.has_open_manage_app_master_role_limit().then(function (value) {
if (!value.isManageAppMasterPermissionEnabled) {
$scope.hasManageAppMasterPermission = $scope.hasAssignUserPermission;
return;
}
PermissionService.has_manage_app_master_permission($scope.pageContext.appId).then(function (res) {
$scope.hasManageAppMasterPermission = res.hasPermission && $scope.hasAssignUserPermission;
PermissionService.has_root_permission().then(function (value) {
$scope.hasManageAppMasterPermission = value.hasPermission || $scope.hasManageAppMasterPermission;
});
});
});
});
}
function initApplication() {
AppService.load($scope.pageContext.appId).then(function (app) {
$scope.app = app;
$scope.viewApp = _.clone(app);
$('.project-setting .panel').removeClass('hidden');
})
}
function initAccessKeys() {
$scope.accessKeys = {};
for (var iLoop = 0; iLoop < $scope.envs.length; iLoop++) {
loadAccessKeys($scope.envs[iLoop])
}
}
function loadAccessKeys(env) {
AccessKeyService.load_access_keys($scope.pageContext.appId, env)
.then(function (result) {
$scope.accessKeys[env] = result;
}, function (result) {
toastr.error(AppUtil.errorMsg(result), $translate.instant('AccessKey.LoadError', { env }));
});
}
function create() {
var env = $scope.addAccessKeySelectedEnv;
UserService.load_user().then(function (result) {
AccessKeyService.create_access_key($scope.pageContext.appId, env, result.userId)
.then(function () {
toastr.success($translate.instant('AccessKey.Operator.CreateSuccess', {env}));
loadAccessKeys(env);
}, function (result) {
toastr.error(AppUtil.errorMsg(result), $translate.instant('AccessKey.Operator.CreateError', {env}));
});
});
}
function remove(id, env) {
var confirmTips = $translate.instant('AccessKey.Operator.RemoveTips', {
appId: $scope.pageContext.appId
});
if (confirm(confirmTips)) {
AccessKeyService.remove_access_key($scope.pageContext.appId, env, id)
.then(function () {
toastr.success($translate.instant('AccessKey.Operator.RemoveSuccess', {env}));
loadAccessKeys(env);
}, function (result) {
toastr.error(AppUtil.errorMsg(result), $translate.instant('AccessKey.Operator.RemoveError', {env}));
});
}
}
function enable(id, env) {
var confirmTips = $translate.instant('AccessKey.Operator.EnabledTips', {
appId: $scope.pageContext.appId
});
if (confirm(confirmTips)) {
AccessKeyService.enable_access_key($scope.pageContext.appId, env, id)
.then(function () {
toastr.success($translate.instant('AccessKey.Operator.EnabledSuccess', {env}));
loadAccessKeys(env);
}, function (result) {
toastr.error(AppUtil.errorMsg(result), $translate.instant('AccessKey.Operator.EnabledError', {env}));
});
}
}
function disable(id, env) {
var confirmTips = $translate.instant('AccessKey.Operator.DisabledTips', {
appId: $scope.pageContext.appId
});
if (confirm(confirmTips)) {
AccessKeyService.disable_access_key($scope.pageContext.appId, env, id)
.then(function () {
toastr.success($translate.instant('AccessKey.Operator.DisabledSuccess', {env}));
loadAccessKeys(env);
}, function (result) {
toastr.error(AppUtil.errorMsg(result), $translate.instant('AccessKey.Operator.DisabledError', {env}));
});
}
}
}
......@@ -345,13 +345,19 @@ function ConfigBaseInfoController($rootScope, $scope, $window, $location, $trans
});
PermissionService.has_assign_user_permission(appId).then(function (result) {
$scope.hasAssignUserPermission = result.hasPermission;
}, function (result) {
});
PermissionService.has_manage_access_key_permission(appId).then(
function (result) {
$scope.hasCreateClusterPermission = result.hasPermission;
}, function (result) {
});
$scope.showMasterPermissionTips = function () {
$("#masterNoPermissionDialog").modal('show');
};
......
appService.service('AccessKeyService', ['$resource', '$q', function ($resource, $q) {
var access_key_resource = $resource('', {}, {
load_access_keys: {
method: 'GET',
isArray: true,
url: '/apps/:appId/envs/:env/accesskeys'
},
create_access_key: {
method: 'POST',
url: '/apps/:appId/envs/:env/accesskeys'
},
remove_access_key: {
method: 'DELETE',
url: '/apps/:appId/envs/:env/accesskeys/:id'
},
enable_access_key: {
method: 'PUT',
url: '/apps/:appId/envs/:env/accesskeys/:id/enable'
},
disable_access_key: {
method: 'PUT',
url: '/apps/:appId/envs/:env/accesskeys/:id/disable'
}
});
return {
load_access_keys: function (appId, env) {
var d = $q.defer();
access_key_resource.load_access_keys({
appId: appId,
env: env
},
function (result) {
d.resolve(result);
}, function (result) {
d.reject(result);
});
return d.promise;
},
create_access_key: function (appId, env, user) {
var d = $q.defer();
access_key_resource.create_access_key({
appId: appId,
env: env
}, { dataChangeCreatedBy: user },
function (result) {
d.resolve(result);
}, function (result) {
d.reject(result);
});
return d.promise;
},
remove_access_key: function (appId, env, id) {
var d = $q.defer();
access_key_resource.remove_access_key({
appId: appId,
env: env,
id: id
},
function (result) {
d.resolve(result);
}, function (result) {
d.reject(result);
});
return d.promise;
},
enable_access_key: function (appId, env, id) {
var d = $q.defer();
access_key_resource.enable_access_key({
appId: appId,
env: env,
id: id
}, {},
function (result) {
d.resolve(result);
}, function (result) {
d.reject(result);
});
return d.promise;
},
disable_access_key: function (appId, env, id) {
var d = $q.defer();
access_key_resource.disable_access_key({
appId: appId,
env: env,
id: id
}, {},
function (result) {
d.resolve(result);
}, function (result) {
d.reject(result);
});
return d.promise;
}
}
}]);
......@@ -212,6 +212,9 @@ appService.service('PermissionService', ['$resource', '$q', 'AppUtil', function
has_assign_user_permission: function (appId) {
return hasAppPermission(appId, 'AssignRole');
},
has_manage_access_key_permission: function (appId) {
return hasAppPermission(appId, 'ManageAccessKey');
},
has_modify_namespace_permission: function (appId, namespaceName) {
return hasNamespacePermission(appId, namespaceName, 'ModifyNamespace');
},
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册