提交 e2276f2d 编写于 作者: L lepdou

发布时可以查看变更集 & 自定义集群选择标签可以设置默认选择 & 获取adminservice地址增加重试和缓存机制

上级 fc38ec96
......@@ -25,6 +25,6 @@ public class API {
}
public String getAdminServiceHost(Env env) {
return serviceLocator.getAdminService(env).getHomepageUrl();
return serviceLocator.getServiceAddress(env).getHomepageUrl();
}
}
......@@ -30,7 +30,7 @@ public class PortalConfigController {
@Autowired
private PortalConfigService configService;
@RequestMapping(value = "/apps/{appId}/env/{env}/clusters/{clusterName}/namespaces/{namespaceName}/items", method = RequestMethod.PUT, consumes = {
@RequestMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/items", method = RequestMethod.PUT, consumes = {
"application/json"})
public void modifyItems(@PathVariable String appId, @PathVariable String env,
@PathVariable String clusterName, @PathVariable String namespaceName,
......@@ -51,7 +51,7 @@ public class PortalConfigController {
configService.updateConfigItemByText(model);
}
@RequestMapping(value = "/apps/{appId}/env/{env}/clusters/{clusterName}/namespaces/{namespaceName}/item", method = RequestMethod.POST)
@RequestMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/item", method = RequestMethod.POST)
public ItemDTO createItem(@PathVariable String appId, @PathVariable String env,
@PathVariable String clusterName, @PathVariable String namespaceName,
@RequestBody ItemDTO item){
......@@ -64,7 +64,7 @@ public class PortalConfigController {
return configService.createOrUpdateItem(appId, Env.valueOf(env), clusterName, namespaceName, item);
}
@RequestMapping(value = "/apps/{appId}/env/{env}/clusters/{clusterName}/namespaces/{namespaceName}/item", method = RequestMethod.PUT)
@RequestMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/item", method = RequestMethod.PUT)
public ItemDTO updateItem(@PathVariable String appId, @PathVariable String env,
@PathVariable String clusterName, @PathVariable String namespaceName,
@RequestBody ItemDTO item){
......@@ -85,7 +85,7 @@ public class PortalConfigController {
configService.deleteItem(Env.valueOf(env), itemId);
}
@RequestMapping(value = "/apps/{appId}/env/{env}/clusters/{clusterName}/namespaces/{namespaceName}/release", method = RequestMethod.POST, consumes = {
@RequestMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/release", method = RequestMethod.POST, consumes = {
"application/json"})
public ReleaseDTO createRelease(@PathVariable String appId,
@PathVariable String env, @PathVariable String clusterName,
......@@ -106,7 +106,7 @@ public class PortalConfigController {
}
@RequestMapping(value = "/apps/{appId}/env/{env}/clusters/{clusterName}/namespaces/{namespaceName}/items")
@RequestMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/items")
public List<ItemDTO> findItems(@PathVariable String appId, @PathVariable String env,
@PathVariable String clusterName, @PathVariable String namespaceName){
......
......@@ -45,7 +45,7 @@ public class PortalNamespaceController {
namespaceService.createAppNamespace(appNamespace);
}
@RequestMapping("/apps/{appId}/env/{env}/clusters/{clusterName}/namespaces")
@RequestMapping("/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces")
public List<NamespaceVO> findNamespaces(@PathVariable String appId, @PathVariable String env,
@PathVariable String clusterName) {
if (StringUtils.isContainEmpty(appId, env, clusterName)) {
......
......@@ -16,7 +16,7 @@ public class NamespaceTextModel implements Verifiable {
@Override
public boolean isInvalid(){
return StringUtils.isContainEmpty(appId, env, clusterName, namespaceName, configText) || namespaceId <= 0;
return StringUtils.isContainEmpty(appId, env, clusterName, namespaceName) || namespaceId <= 0;
}
public String getAppId() {
return appId;
......
......@@ -8,6 +8,7 @@ import com.ctrip.framework.apollo.core.dto.ItemDTO;
import com.ctrip.framework.apollo.core.dto.NamespaceDTO;
import com.ctrip.framework.apollo.core.dto.ReleaseDTO;
import com.ctrip.framework.apollo.core.enums.Env;
import com.ctrip.framework.apollo.core.exception.NotFoundException;
import com.ctrip.framework.apollo.core.utils.StringUtils;
import com.ctrip.framework.apollo.portal.PortalSettings;
import com.ctrip.framework.apollo.portal.api.AdminServiceAPI;
......@@ -47,11 +48,11 @@ public class PortalNamespaceService {
private Gson gson = new Gson();
public List<AppNamespaceDTO> findPublicAppNamespaces(){
public List<AppNamespaceDTO> findPublicAppNamespaces() {
return namespaceAPI.findPublicAppNamespaces(portalSettings.getFirstAliveEnv());
}
public NamespaceDTO createNamespace(Env env, NamespaceDTO namespace){
public NamespaceDTO createNamespace(Env env, NamespaceDTO namespace) {
return namespaceAPI.createNamespace(env, namespace);
}
......
package com.ctrip.framework.apollo.portal.service;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
......@@ -33,57 +31,21 @@ public class ServiceLocator {
private static final int DEFAULT_TIMEOUT_MS = 1000;
private static final int RETRY_TIMES = 3;
private static final int CALL_META_SERVER_THRESHOLD = 10;
private static final String ADMIN_SERVICE_URL_PATH = "/services/admin";
private RestTemplate restTemplate;
@Autowired
private HttpMessageConverters httpMessageConverters;
private Map<Env, List<ServiceDTO>> serviceCaches = new ConcurrentHashMap<Env, List<ServiceDTO>>();
private Map<Env, ServiceDTO[]> serviceAddressCache = new ConcurrentHashMap<>();
private final AtomicInteger adminCallCounts = new AtomicInteger(0);
private final AtomicInteger configCallCounts = new AtomicInteger(0);
public ServiceDTO getAdminService(Env env) throws ServiceException {
List<ServiceDTO> services = getServices(env, "admin");
if (services == null || services.size() == 0) {
throw new ServiceException("No available admin service");
}
return services.get(Math.abs(adminCallCounts.getAndIncrement()) % services.size());
}
public ServiceDTO getConfigService(Env env) throws ServiceException {
List<ServiceDTO> services = getServices(env, "config");
if (services == null || services.size() == 0) {
throw new ServiceException("No available config service");
}
return services.get(Math.abs(configCallCounts.getAndIncrement()) % services.size());
}
private List<ServiceDTO> getServices(Env env, String serviceUrl) {
String domainName = MetaDomainConsts.getDomain(env);
String url = domainName + "/services/" + serviceUrl;
List<ServiceDTO> serviceDtos = null;
try {
ServiceDTO[] services = restTemplate.getForObject(new URI(url), ServiceDTO[].class);
if (services != null && services.length > 0) {
if (!serviceCaches.containsKey(env)) {
serviceDtos = new ArrayList<ServiceDTO>();
serviceCaches.put(env, serviceDtos);
} else {
serviceDtos = serviceCaches.get(env);
serviceDtos.clear();
}
for (ServiceDTO service : services) {
serviceDtos.add(service);
}
}
} catch (Exception ex) {
logger.warn(ex.getMessage());
}
return serviceDtos;
}
@PostConstruct
private void postConstruct() {
restTemplate = new RestTemplate(httpMessageConverters.getConverters());
......@@ -99,4 +61,55 @@ public class ServiceLocator {
rf.setConnectTimeout(DEFAULT_TIMEOUT_MS);
}
}
public ServiceDTO getServiceAddress(Env env) throws ServiceException {
if (adminCallCounts.get() % CALL_META_SERVER_THRESHOLD == 0) {
return getServiceAddressFromMetaServer(env);
} else {
//if cached then return from cache
ServiceDTO[] serviceDTOs = serviceAddressCache.get(env);
if (serviceDTOs != null && serviceDTOs.length > 0){
return randomServiceAddress(serviceDTOs);
}else {//return from meta server
return getServiceAddressFromMetaServer(env);
}
}
}
public ServiceDTO getServiceAddressFromMetaServer(Env env) {
//retry
for (int i = 0; i < RETRY_TIMES; i++) {
ServiceDTO[] services = getServices(env);
if (services != null && services.length > 0) {
serviceAddressCache.put(env, services);
return randomServiceAddress(services);
} else {
logger.warn(String.format("can not get %s admin service address at %d time", env, i));
}
}
logger.error(String.format("can not get %s admin service address", env));
throw new ServiceException("No available admin service");
}
private ServiceDTO[] getServices(Env env) {
String domainName = MetaDomainConsts.getDomain(env);
String url = domainName + ADMIN_SERVICE_URL_PATH;
try {
return restTemplate.getForObject(new URI(url), ServiceDTO[].class);
} catch (Exception ex) {
logger.warn(ex.getMessage());
return null;
}
}
private ServiceDTO randomServiceAddress(ServiceDTO[] services){
return services[Math.abs(adminCallCounts.getAndIncrement()) % services.length];
}
}
......@@ -3,7 +3,6 @@ package com.ctrip.framework.apollo.portal.service.txtresolver;
import com.ctrip.framework.apollo.core.dto.ItemChangeSets;
import com.ctrip.framework.apollo.core.dto.ItemDTO;
import com.ctrip.framework.apollo.core.exception.BadRequestException;
import com.ctrip.framework.apollo.core.utils.StringUtils;
import com.ctrip.framework.apollo.common.utils.BeanUtils;
import org.springframework.stereotype.Component;
......
......@@ -222,7 +222,8 @@
<!--table view-->
<div class="namespace-view-table">
<table class="table table-bordered table-striped text-center table-hover"
ng-show="namespace.viewType == 'table' && namespace.items.length > 0">
ng-show="namespace.viewType == 'table' && namespace.items.length > 0
&& !(namespace.items.length == 1 && !namespace.items[0].key)">
<thead>
<tr>
<th>
......@@ -283,7 +284,7 @@
<span class="glyphicon glyphicon-remove" aria-hidden="true"
data-toggle="modal" data-target="#deleteModal"
data-tooltip="tooltip" data-placement="bottom" title="删除"
ng-click="preDeleteItem(config.item.id)">
ng-click="preDeleteItem(config.item.id)">
</span>
</td>
......@@ -390,7 +391,7 @@
<!--create release modal-->
<form class="modal fade form-horizontal" id="releaseModal" tabindex="-1" role="dialog"
ng-submit="release()">
<div class="modal-dialog" role="document">
<div class="modal-dialog" role="document" style="width: 960px">
<div class="modal-content">
<div class="modal-header panel-primary">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
......@@ -399,17 +400,71 @@
</div>
<div class="modal-body">
<div class="form-group">
<label class="col-sm-3 control-label">
<label class="col-sm-2 control-label">
Changes:</label>
<div class="col-sm-10">
<table class="table table-bordered table-striped text-center table-hover"
ng-show="toReleaseNamespace.itemModifiedCnt">
<thead>
<tr>
<th>
Key
</th>
<th>
Old Value
</th>
<th>
New Value
</th>
<th>
最后修改人
</th>
<th>
最后修改时间
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="config in toReleaseNamespace.items"
ng-if="config.item.key && config.isModified">
<td width="20%" title="{{config.item.key}}">
<span ng-bind="config.item.key | limitTo: 250"></span>
<span ng-bind="config.item.key.length > 250 ? '...' :''"></span>
</td>
<td width="25%" title="{{config.oldValue}}">
<span ng-bind="config.oldValue | limitTo: 250"></span>
<span ng-bind="config.oldValue.length > 250 ? '...': ''"></span>
</td>
<td width="25%" title="{{config.item.value}}">
<span ng-bind="config.item.value | limitTo: 250"></span>
<span ng-bind="config.item.value.length > 250 ? '...': ''"></span>
</td>
<td width="15%" ng-bind="config.item.lastModifiedBy">
</td>
<td width="15%"
ng-bind="config.item.lastModifiedTime | date: 'yyyy-MM-dd HH:mm:ss'">
</td>
</tr>
</tbody>
</table>
<span ng-show="!toReleaseNamespace.itemModifiedCnt">
配置没有变化
</span>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">
<apollorequiredfiled></apollorequiredfiled>
Release Name:</label>
<div class="col-sm-9">
<div class="col-sm-5">
<input type="text" class="form-control" placeholder="input release title"
ng-model="releaseTitle" ng-required="true">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">Comment:</label>
<div class="col-sm-9">
<label class="col-sm-2 control-label">Comment:</label>
<div class="col-sm-10">
<textarea rows="4" class="form-control" style="margin-top: 15px;"
ng-model="releaseComment"
placeholder="Add an optional extended description..."></textarea>
......@@ -420,7 +475,7 @@
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
<button type="submit" class="btn btn-primary">提交
<button type="submit" class="btn btn-primary">发布
</button>
</div>
</div>
......@@ -442,14 +497,22 @@
</div>
<div class="modal-body">
<div class="form-group">
<label class="col-sm-2 control-label"><apollorequiredfiled></apollorequiredfiled>Key</label>
<label class="col-sm-2 control-label">
<apollorequiredfiled
ng-show="tableViewOperType != 'retrieve'"></apollorequiredfiled>
Key
</label>
<div class="col-sm-10">
<input type="text" class="form-control" ng-model="item.key"
ng-required="true" ng-disabled="tableViewOperType != 'create'">
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label"><apollorequiredfiled></apollorequiredfiled>Value</label>
<label class="col-sm-2 control-label">
<apollorequiredfiled
ng-show="tableViewOperType != 'retrieve'"></apollorequiredfiled>
Value
</label>
<div class="col-sm-10">
<textarea type="text" class="form-control" rows="6" ng-model="item.value"
ng-required="true" ng-show="tableViewOperType != 'retrieve'">
......@@ -460,7 +523,8 @@
<div class="form-group" ng-show="tableViewOperType == 'retrieve'">
<label class="col-sm-2 control-label">Released Value</label>
<div class="col-sm-10">
<span ng-show="!item.oldVale">这是新增的配置</span>
<p ng-show="!item.oldValue">这是新增的配置</p>
<p ng-show="item.oldValue" ng-bind="item.oldValue"></p>
</div>
</div>
<div class="form-group">
......@@ -473,18 +537,28 @@
</div>
</div>
<div class="form-group" ng-show="tableViewOperType != 'retrieve'">
<label class="col-sm-2 control-label"><apollorequiredfiled></apollorequiredfiled>选择集群</label>
<label class="col-sm-2 control-label">
<apollorequiredfiled></apollorequiredfiled>
选择集群</label>
<div class="col-sm-10">
<apolloclusterselector apollo-app-id="pageContext.appId" apollo-default-checked="false"
apollo-select="collectSelectedClusters"></apolloclusterselector>
<apolloclusterselector apollo-app-id="pageContext.appId"
apollo-default-all-checked="false"
apollo-default-checked-env="pageContext.env"
apollo-default-checked-cluster="pageContext.clusterName"
apollo-select="collectSelectedClusters">
</apolloclusterselector>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" ng-click="switchToEdit()" ng-show="tableViewOperType == 'retrieve'">修改</button>
<button type="button" class="btn btn-default" ng-click="switchToEdit()"
ng-show="tableViewOperType == 'retrieve'">修改
</button>
<button type="button" class="btn btn-default" data-dismiss="modal">关闭
</button>
<button type="submit" class="btn btn-primary" ng-show="tableViewOperType != 'retrieve'">提交
<button type="submit" class="btn btn-primary"
ng-show="tableViewOperType != 'retrieve'">提交
</button>
</div>
</div>
......
......@@ -46,7 +46,7 @@
<div class="form-group">
<label class="col-sm-2 control-label">同步到那个集群</label>
<div class="col-sm-6">
<apolloclusterselector apollo-app-id="pageContext.appId" apollo-default-checked="true"
<apolloclusterselector apollo-app-id="pageContext.appId" apollo-default-all-checked="true"
apollo-select="collectSelectedClusters"></apolloclusterselector>
</div>
</div>
......
......@@ -41,7 +41,7 @@
<div class="form-group">
<label class="col-sm-3 control-label"><font style="color: red">*</font>选择集群</label>
<div class="col-sm-6">
<apolloclusterselector apollo-app-id="appId" apollo-default-checked="true"
<apolloclusterselector apollo-app-id="appId" apollo-default-all-checked="true"
apollo-select="collectSelectedClusters"></apolloclusterselector>
</div>
</div>
......
......@@ -26,12 +26,12 @@ appUtil.service('AppUtil', ['toastr', function (toastr) {
collectData: function (response) {
var data = [];
response.entities.forEach(function (entity) {
if (entity.code == 200){
if (entity.code == 200) {
data.push(entity.body);
}else {
} else {
toastr.warning(entity.message);
}
});
});
return data;
}
}
......
......@@ -14,3 +14,28 @@ $(document).ready(function () {
$(function () {
$('[data-toggle="tooltip"]').tooltip()
});
// (new Date()).Format("yyyy-MM-dd hh:mm:ss.S") ==> 2006-07-02 08:09:04.423
// (new Date()).Format("yyyy-M-d h:m:s.S") ==> 2006-7-2 8:9:4.18
Date.prototype.Format = function (fmt) {
var o = {
"M+": this.getMonth() + 1, //月份
"d+": this.getDate(), //日
"h+": this.getHours(), //小时
"m+": this.getMinutes(), //分
"s+": this.getSeconds(), //秒
"q+": Math.floor((this.getMonth() + 3) / 3), //季度
"S": this.getMilliseconds() //毫秒
};
if (/(y+)/.test(fmt)) {
fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
}
for (var k in o) {
if (new RegExp("(" + k + ")").test(fmt)) {
fmt =
fmt.replace(RegExp.$1,
(RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
}
}
return fmt;
};
......@@ -2,8 +2,6 @@ application_module.controller("ConfigNamespaceController",
['$rootScope', '$scope', '$location', 'toastr', 'AppUtil', 'ConfigService',
function ($rootScope, $scope, $location, toastr, AppUtil, ConfigService) {
////// namespace //////
var namespace_view_type = {
TEXT: 'text',
TABLE: 'table',
......@@ -53,8 +51,6 @@ application_module.controller("ConfigNamespaceController",
});
};
////// global view oper //////
$scope.switchView = function (namespace, viewType) {
if (namespace_view_type.TEXT == viewType) {
namespace.text = parseModel2Text(namespace);
......@@ -89,8 +85,6 @@ application_module.controller("ConfigNamespaceController",
return result;
}
////// text view oper //////
$scope.toCommitNamespace = {};
$scope.setCommitNamespace = function (namespace) {
......@@ -133,19 +127,20 @@ application_module.controller("ConfigNamespaceController",
}
};
/////// release ///////
var releaseModal = $('#releaseModal');
var releaseNamespace = {};
$scope.toReleaseNamespace = {};
$scope.prepareReleaseNamespace = function (namespace) {
releaseNamespace = namespace;
$scope.releaseTitle = new Date().Format("yyyy-MM-dd hh:mm:ss");
$scope.toReleaseNamespace = namespace;
};
$scope.releaseComment = '';
$scope.releaseTitle = '';
$scope.release = function () {
ConfigService.release($rootScope.pageContext.appId, $rootScope.pageContext.env,
$rootScope.pageContext.clusterName,
releaseNamespace.namespace.namespaceName,
$scope.toReleaseNamespace.namespace.namespaceName,
$scope.releaseTitle,
$scope.releaseComment).then(
function (result) {
......@@ -182,12 +177,13 @@ application_module.controller("ConfigNamespaceController",
};
$scope.deleteItem = function () {
ConfigService.delete_item($rootScope.pageContext.env, toDeleteItemId).then(function (result) {
toastr.success("删除成功!");
$rootScope.refreshNamespaces();
}, function (result) {
toastr.error(AppUtil.errorMsg(result), "删除失败");
});
ConfigService.delete_item($rootScope.pageContext.env, toDeleteItemId).then(
function (result) {
toastr.success("删除成功!");
$rootScope.refreshNamespaces();
}, function (result) {
toastr.error(AppUtil.errorMsg(result), "删除失败");
});
};
var toOperationNamespaceName = '';
......
......@@ -116,7 +116,6 @@ directive_module.directive('apollonav', function ($compile, $window, toastr, App
});
/** env cluster selector*/
directive_module.directive('apolloclusterselector', function ($compile, $window, AppService, AppUtil, toastr) {
return {
restrict: 'E',
......@@ -125,28 +124,42 @@ directive_module.directive('apolloclusterselector', function ($compile, $window,
replace: true,
scope: {
appId: '=apolloAppId',
defaultChecked: '=apolloDefaultChecked',
select: '=apolloSelect'
defaultAllChecked: '=apolloDefaultAllChecked',
select: '=apolloSelect',
defaultCheckedEnv: '=apolloDefaultCheckedEnv',
defaultCheckedCluster: '=apolloDefaultCheckedCluster'
},
link: function (scope, element, attrs) {
////// load env //////
AppService.load_nav_tree(scope.appId).then(function (result) {
scope.clusters = [];
var envClusterInfo = AppUtil.collectData(result);
envClusterInfo.forEach(function (node) {
var env = node.env;
node.clusters.forEach(function (cluster) {
cluster.env = env;
cluster.checked = scope.defaultChecked;
scope.clusters.push(cluster);
})
});
scope.select(collectSelectedClusters());
}, function (result) {
toastr.error(AppUtil.errorMsg(result), "加载环境信息出错");
scope.$watch("defaultCheckedEnv", function (newValue, oldValue) {
refreshClusterList();
});
scope.envAllSelected = scope.defaultChecked;
refreshClusterList();
function refreshClusterList() {
AppService.load_nav_tree(scope.appId).then(function (result) {
scope.clusters = [];
var envClusterInfo = AppUtil.collectData(result);
envClusterInfo.forEach(function (node) {
var env = node.env;
node.clusters.forEach(function (cluster) {
cluster.env = env;
cluster.checked = scope.defaultAllChecked ||
(cluster.env == scope.defaultCheckedEnv && cluster.name
== scope.defaultCheckedCluster);
scope.clusters.push(cluster);
})
});
scope.select(collectSelectedClusters());
}, function (result) {
toastr.error(AppUtil.errorMsg(result), "加载环境信息出错");
});
}
scope.envAllSelected = scope.defaultAllChecked;
scope.toggleEnvsCheckedStatus = function () {
scope.envAllSelected = !scope.envAllSelected;
......
......@@ -3,20 +3,20 @@ appService.service("ConfigService", ['$resource', '$q', function ($resource, $q)
load_all_namespaces: {
method: 'GET',
isArray: true,
url: '/apps/:appId/env/:env/clusters/:clusterName/namespaces'
url: '/apps/:appId/envs/:env/clusters/:clusterName/namespaces'
},
find_items: {
method: 'GET',
isArray: true,
url: '/apps/:appId/env/:env/clusters/:clusterName/namespaces/:namespaceName/items'
url: '/apps/:appId/envs/:env/clusters/:clusterName/namespaces/:namespaceName/items'
},
modify_items: {
method: 'PUT',
url: '/apps/:appId/env/:env/clusters/:clusterName/namespaces/:namespaceName/items'
url: '/apps/:appId/envs/:env/clusters/:clusterName/namespaces/:namespaceName/items'
},
release: {
method: 'POST',
url: '/apps/:appId/env/:env/clusters/:clusterName/namespaces/:namespaceName/release'
url: '/apps/:appId/envs/:env/clusters/:clusterName/namespaces/:namespaceName/release'
},
diff: {
method: 'POST',
......@@ -30,11 +30,11 @@ appService.service("ConfigService", ['$resource', '$q', function ($resource, $q)
},
create_item: {
method: 'POST',
url: '/apps/:appId/env/:env/clusters/:clusterName/namespaces/:namespaceName/item'
url: '/apps/:appId/envs/:env/clusters/:clusterName/namespaces/:namespaceName/item'
},
update_item: {
method: 'PUT',
url: '/apps/:appId/env/:env/clusters/:clusterName/namespaces/:namespaceName/item'
url: '/apps/:appId/envs/:env/clusters/:clusterName/namespaces/:namespaceName/item'
},
delete_item: {
method: 'DELETE',
......@@ -56,6 +56,7 @@ appService.service("ConfigService", ['$resource', '$q', function ($resource, $q)
});
return d.promise;
},
find_items: function (appId, env, clusterName, namespaceName) {
var d = $q.defer();
config_source.find_items({
......
......@@ -1691,7 +1691,7 @@
for (r in i.events)x.removeEvent(t, r, i.handle);
t.removeAttribute(x.expando)
}
"script" === n && t.text !== e.text ? (Ht(t).text = e.text, qt(t)) : "object" === n ? (t.parentNode && (t.outerHTML = e.outerHTML), x.support.html5Clone && e.innerHTML && !x.trim(t.innerHTML) && (t.innerHTML = e.innerHTML)) : "input" === n && Ct.test(e.type) ? (t.defaultChecked = t.checked = e.checked, t.value !== e.value && (t.value = e.value)) : "option" === n ? t.defaultSelected = t.selected = e.defaultSelected : ("input" === n || "textarea" === n) && (t.defaultValue = e.defaultValue)
"script" === n && t.text !== e.text ? (Ht(t).text = e.text, qt(t)) : "object" === n ? (t.parentNode && (t.outerHTML = e.outerHTML), x.support.html5Clone && e.innerHTML && !x.trim(t.innerHTML) && (t.innerHTML = e.innerHTML)) : "input" === n && Ct.test(e.type) ? (t.defaultAllChecked = t.checked = e.checked, t.value !== e.value && (t.value = e.value)) : "option" === n ? t.defaultSelected = t.selected = e.defaultSelected : ("input" === n || "textarea" === n) && (t.defaultValue = e.defaultValue)
}
}
......@@ -1715,7 +1715,7 @@
}
function Bt(e) {
Ct.test(e.type) && (e.defaultChecked = e.checked)
Ct.test(e.type) && (e.defaultAllChecked = e.checked)
}
x.extend({
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册