diff --git a/CHANGES.md b/CHANGES.md index db77fc9598a..f151343137f 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -11,6 +11,7 @@ Apollo 2.4.0 * [Fix: Resolve issues with duplicate comments and blank lines in configuration management](https://github.com/apolloconfig/apollo/pull/5232) * [Fix link namespace published items show missing some items](https://github.com/apolloconfig/apollo/pull/5240) * [Feature: Add limit and whitelist for namespace count per appid+cluster](https://github.com/apolloconfig/apollo/pull/5228) +* [Feature support the observe status access-key for pre-check and logging only](https://github.com/apolloconfig/apollo/pull/5236) ------------------ All issues and pull requests are [here](https://github.com/apolloconfig/apollo/milestone/15?closed=1) diff --git a/apollo-adminservice/src/main/java/com/ctrip/framework/apollo/adminservice/controller/AccessKeyController.java b/apollo-adminservice/src/main/java/com/ctrip/framework/apollo/adminservice/controller/AccessKeyController.java index 1e95a2ee8fd..db8aee73e95 100644 --- a/apollo-adminservice/src/main/java/com/ctrip/framework/apollo/adminservice/controller/AccessKeyController.java +++ b/apollo-adminservice/src/main/java/com/ctrip/framework/apollo/adminservice/controller/AccessKeyController.java @@ -16,6 +16,8 @@ */ package com.ctrip.framework.apollo.adminservice.controller; +import static com.ctrip.framework.apollo.common.constants.AccessKeyMode.FILTER; + import com.ctrip.framework.apollo.biz.entity.AccessKey; import com.ctrip.framework.apollo.biz.service.AccessKeyService; import com.ctrip.framework.apollo.common.dto.AccessKeyDTO; @@ -27,6 +29,7 @@ import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; /** @@ -61,9 +64,11 @@ public void delete(@PathVariable String appId, @PathVariable long id, String ope } @PutMapping(value = "/apps/{appId}/accesskeys/{id}/enable") - public void enable(@PathVariable String appId, @PathVariable long id, String operator) { + public void enable(@PathVariable String appId, @PathVariable long id, + @RequestParam(required = false, defaultValue = "" + FILTER) int mode, String operator) { AccessKey entity = new AccessKey(); entity.setId(id); + entity.setMode(mode); entity.setEnabled(true); entity.setDataChangeLastModifiedBy(operator); @@ -74,6 +79,7 @@ public void enable(@PathVariable String appId, @PathVariable long id, String ope public void disable(@PathVariable String appId, @PathVariable long id, String operator) { AccessKey entity = new AccessKey(); entity.setId(id); + entity.setMode(FILTER); entity.setEnabled(false); entity.setDataChangeLastModifiedBy(operator); diff --git a/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/entity/AccessKey.java b/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/entity/AccessKey.java index 3e927bbf914..a66ade65c15 100644 --- a/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/entity/AccessKey.java +++ b/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/entity/AccessKey.java @@ -36,6 +36,9 @@ public class AccessKey extends BaseEntity { @Column(name = "`Secret`", nullable = false) private String secret; + @Column(name = "`Mode`") + private int mode; + @Column(name = "`IsEnabled`", columnDefinition = "Bit default '0'") private boolean enabled; @@ -55,6 +58,14 @@ public void setSecret(String secret) { this.secret = secret; } + public int getMode() { + return mode; + } + + public void setMode(int mode) { + this.mode = mode; + } + public boolean isEnabled() { return enabled; } @@ -66,6 +77,6 @@ public void setEnabled(boolean enabled) { @Override public String toString() { return toStringHelper().add("appId", appId).add("secret", secret) - .add("enabled", enabled).toString(); + .add("mode", mode).add("enabled", enabled).toString(); } } diff --git a/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/service/AccessKeyService.java b/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/service/AccessKeyService.java index f70f8be6822..641d801d2e0 100644 --- a/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/service/AccessKeyService.java +++ b/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/service/AccessKeyService.java @@ -74,6 +74,7 @@ public AccessKey update(String appId, AccessKey entity) { throw BadRequestException.accessKeyNotExists(); } + accessKey.setMode(entity.getMode()); accessKey.setEnabled(entity.isEnabled()); accessKey.setDataChangeLastModifiedBy(operator); accessKeyRepository.save(accessKey); diff --git a/apollo-biz/src/test/resources/sql/accesskey-test.sql b/apollo-biz/src/test/resources/sql/accesskey-test.sql index 2ea1c96e9f2..36ffb2a1b6b 100644 --- a/apollo-biz/src/test/resources/sql/accesskey-test.sql +++ b/apollo-biz/src/test/resources/sql/accesskey-test.sql @@ -13,9 +13,9 @@ -- See the License for the specific language governing permissions and -- limitations under the License. -- -INSERT INTO "AccessKey" (`Id`, `AppId`, `Secret`, `IsEnabled`, `IsDeleted`, `DataChange_CreatedBy`, `DataChange_CreatedTime`, `DataChange_LastModifiedBy`, `DataChange_LastTime`) +INSERT INTO "AccessKey" (`Id`, `AppId`, `Secret`, `Mode`, `IsEnabled`, `IsDeleted`, `DataChange_CreatedBy`, `DataChange_CreatedTime`, `DataChange_LastModifiedBy`, `DataChange_LastTime`) VALUES - (1, 'someAppId', 'someSecret', 0, 0, 'apollo', '2019-12-19 10:28:40', 'apollo', '2019-12-19 10:28:40'), - (2, '100004458', 'c715cbc80fc44171b43732c3119c9456', 0, 0, 'apollo', '2019-12-19 10:39:54', 'apollo', '2019-12-19 14:46:35'), - (3, '100004458', '25a0e68d2a3941edb1ed3ab6dd0646cd', 0, 1, 'apollo', '2019-12-19 13:44:13', 'apollo', '2019-12-19 13:44:19'), - (4, '100004458', '4003c4d7783443dc9870932bebf3b7fe', 0, 0, 'apollo', '2019-12-19 13:43:52', 'apollo', '2019-12-19 13:44:21'); + (1, 'someAppId', 'someSecret', 0, 0, 0, 'apollo', '2019-12-19 10:28:40', 'apollo', '2019-12-19 10:28:40'), + (2, '100004458', 'c715cbc80fc44171b43732c3119c9456', 0, 0, 0, 'apollo', '2019-12-19 10:39:54', 'apollo', '2019-12-19 14:46:35'), + (3, '100004458', '25a0e68d2a3941edb1ed3ab6dd0646cd', 0, 0, 1, 'apollo', '2019-12-19 13:44:13', 'apollo', '2019-12-19 13:44:19'), + (4, '100004458', '4003c4d7783443dc9870932bebf3b7fe', 0, 0, 0, 'apollo', '2019-12-19 13:43:52', 'apollo', '2019-12-19 13:44:21'); diff --git a/apollo-common/src/main/java/com/ctrip/framework/apollo/common/constants/AccessKeyMode.java b/apollo-common/src/main/java/com/ctrip/framework/apollo/common/constants/AccessKeyMode.java new file mode 100644 index 00000000000..24844c407fa --- /dev/null +++ b/apollo-common/src/main/java/com/ctrip/framework/apollo/common/constants/AccessKeyMode.java @@ -0,0 +1,25 @@ +/* + * Copyright 2024 Apollo Authors + * + * 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. + * + */ +package com.ctrip.framework.apollo.common.constants; + +public interface AccessKeyMode { + + int FILTER = 0; + + int OBSERVER = 1; + +} diff --git a/apollo-common/src/main/java/com/ctrip/framework/apollo/common/dto/AccessKeyDTO.java b/apollo-common/src/main/java/com/ctrip/framework/apollo/common/dto/AccessKeyDTO.java index 4ba5a32d5ab..ecd7eb37511 100644 --- a/apollo-common/src/main/java/com/ctrip/framework/apollo/common/dto/AccessKeyDTO.java +++ b/apollo-common/src/main/java/com/ctrip/framework/apollo/common/dto/AccessKeyDTO.java @@ -24,6 +24,8 @@ public class AccessKeyDTO extends BaseDTO { private String appId; + private Integer mode; + private Boolean enabled; public Long getId() { @@ -50,6 +52,14 @@ public void setAppId(String appId) { this.appId = appId; } + public Integer getMode() { + return mode; + } + + public void setMode(Integer mode) { + this.mode = mode; + } + public Boolean getEnabled() { return enabled; } diff --git a/apollo-configservice/src/main/java/com/ctrip/framework/apollo/configservice/filter/ClientAuthenticationFilter.java b/apollo-configservice/src/main/java/com/ctrip/framework/apollo/configservice/filter/ClientAuthenticationFilter.java index 25677b5626a..43329e135c4 100644 --- a/apollo-configservice/src/main/java/com/ctrip/framework/apollo/configservice/filter/ClientAuthenticationFilter.java +++ b/apollo-configservice/src/main/java/com/ctrip/framework/apollo/configservice/filter/ClientAuthenticationFilter.java @@ -17,9 +17,11 @@ package com.ctrip.framework.apollo.configservice.filter; import com.ctrip.framework.apollo.biz.config.BizConfig; +import com.ctrip.framework.apollo.common.utils.WebUtils; import com.ctrip.framework.apollo.configservice.util.AccessKeyUtil; import com.ctrip.framework.apollo.core.signature.Signature; import com.ctrip.framework.apollo.core.utils.StringUtils; +import com.ctrip.framework.apollo.tracer.Tracer; import com.google.common.net.HttpHeaders; import java.io.IOException; import java.util.List; @@ -70,29 +72,60 @@ public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain List availableSecrets = accessKeyUtil.findAvailableSecret(appId); if (!CollectionUtils.isEmpty(availableSecrets)) { - String timestamp = request.getHeader(Signature.HTTP_HEADER_TIMESTAMP); - String authorization = request.getHeader(HttpHeaders.AUTHORIZATION); - - // check timestamp, valid within 1 minute - if (!checkTimestamp(timestamp)) { - logger.warn("Invalid timestamp. appId={},timestamp={}", appId, timestamp); - response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "RequestTimeTooSkewed"); + if (!doCheck(request, response, appId, availableSecrets, false)) { return; } - - // check signature - String uri = request.getRequestURI(); - String query = request.getQueryString(); - if (!checkAuthorization(authorization, availableSecrets, timestamp, uri, query)) { - logger.warn("Invalid authorization. appId={},authorization={}", appId, authorization); - response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized"); - return; + } else { + // pre-check for observable secrets + List observableSecrets = accessKeyUtil.findObservableSecrets(appId); + if (!CollectionUtils.isEmpty(observableSecrets)) { + doCheck(request, response, appId, observableSecrets, true); } } chain.doFilter(request, response); } + /** + * Performs authentication checks(timestamp and signature) for the request. + * + * @param preCheck Boolean flag indicating whether this is a pre-check + * @return true if authentication checks is successful, false otherwise + */ + private boolean doCheck(HttpServletRequest req, HttpServletResponse resp, + String appId, List secrets, boolean preCheck) throws IOException { + + String timestamp = req.getHeader(Signature.HTTP_HEADER_TIMESTAMP); + String authorization = req.getHeader(HttpHeaders.AUTHORIZATION); + String ip = WebUtils.tryToGetClientIp(req); + + // check timestamp, valid within 1 minute + if (!checkTimestamp(timestamp)) { + if (preCheck) { + preCheckInvalidLogging(String.format("Invalid timestamp in pre-check. " + + "appId=%s,clientIp=%s,timestamp=%s", appId, ip, timestamp)); + } else { + logger.warn("Invalid timestamp. appId={},clientIp={},timestamp={}", appId, ip, timestamp); + resp.sendError(HttpServletResponse.SC_UNAUTHORIZED, "RequestTimeTooSkewed"); + return false; + } + } + + // check signature + if (!checkAuthorization(authorization, secrets, timestamp, req.getRequestURI(), req.getQueryString())) { + if (preCheck) { + preCheckInvalidLogging(String.format("Invalid authorization in pre-check. " + + "appId=%s,clientIp=%s,authorization=%s", appId, ip, authorization)); + } else { + logger.warn("Invalid authorization. appId={},clientIp={},authorization={}", appId, ip, authorization); + resp.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized"); + return false; + } + } + + return true; + } + @Override public void destroy() { //nothing @@ -130,4 +163,9 @@ private boolean checkAuthorization(String authorization, List availableS } return false; } + + protected void preCheckInvalidLogging(String message) { + logger.warn(message); + Tracer.logEvent("Apollo.AccessKey.PreCheck", message); + } } diff --git a/apollo-configservice/src/main/java/com/ctrip/framework/apollo/configservice/service/AccessKeyServiceWithCache.java b/apollo-configservice/src/main/java/com/ctrip/framework/apollo/configservice/service/AccessKeyServiceWithCache.java index 4dc3519f11d..46c449f445f 100644 --- a/apollo-configservice/src/main/java/com/ctrip/framework/apollo/configservice/service/AccessKeyServiceWithCache.java +++ b/apollo-configservice/src/main/java/com/ctrip/framework/apollo/configservice/service/AccessKeyServiceWithCache.java @@ -19,6 +19,7 @@ import com.ctrip.framework.apollo.biz.config.BizConfig; import com.ctrip.framework.apollo.biz.entity.AccessKey; import com.ctrip.framework.apollo.biz.repository.AccessKeyRepository; +import com.ctrip.framework.apollo.common.constants.AccessKeyMode; import com.ctrip.framework.apollo.core.utils.ApolloThreadFactory; import com.ctrip.framework.apollo.tracer.Tracer; import com.ctrip.framework.apollo.tracer.spi.Transaction; @@ -37,11 +38,11 @@ import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; +import java.util.function.Predicate; import java.util.stream.Collectors; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.InitializingBean; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; @@ -86,13 +87,21 @@ private void initialize() { } public List getAvailableSecrets(String appId) { + return getSecrets(appId, key -> key.isEnabled() && key.getMode() == AccessKeyMode.FILTER); + } + + public List getObservableSecrets(String appId) { + return getSecrets(appId, key -> key.isEnabled() && key.getMode() == AccessKeyMode.OBSERVER); + } + + public List getSecrets(String appId, Predicate filter) { List accessKeys = accessKeyCache.get(appId); if (CollectionUtils.isEmpty(accessKeys)) { return Collections.emptyList(); } return accessKeys.stream() - .filter(AccessKey::isEnabled) + .filter(filter) .map(AccessKey::getSecret) .collect(Collectors.toList()); } diff --git a/apollo-configservice/src/main/java/com/ctrip/framework/apollo/configservice/util/AccessKeyUtil.java b/apollo-configservice/src/main/java/com/ctrip/framework/apollo/configservice/util/AccessKeyUtil.java index 910d203d964..472e1c37c43 100644 --- a/apollo-configservice/src/main/java/com/ctrip/framework/apollo/configservice/util/AccessKeyUtil.java +++ b/apollo-configservice/src/main/java/com/ctrip/framework/apollo/configservice/util/AccessKeyUtil.java @@ -46,6 +46,10 @@ public List findAvailableSecret(String appId) { return accessKeyServiceWithCache.getAvailableSecrets(appId); } + public List findObservableSecrets(String appId) { + return accessKeyServiceWithCache.getObservableSecrets(appId); + } + public String extractAppIdFromRequest(HttpServletRequest request) { String appId = null; String servletPath = request.getServletPath(); diff --git a/apollo-configservice/src/test/java/com/ctrip/framework/apollo/configservice/filter/ClientAuthenticationFilterTest.java b/apollo-configservice/src/test/java/com/ctrip/framework/apollo/configservice/filter/ClientAuthenticationFilterTest.java index b5676f9f149..5d060aa4263 100644 --- a/apollo-configservice/src/test/java/com/ctrip/framework/apollo/configservice/filter/ClientAuthenticationFilterTest.java +++ b/apollo-configservice/src/test/java/com/ctrip/framework/apollo/configservice/filter/ClientAuthenticationFilterTest.java @@ -17,7 +17,9 @@ package com.ctrip.framework.apollo.configservice.filter; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -26,6 +28,7 @@ import com.ctrip.framework.apollo.configservice.util.AccessKeyUtil; import com.ctrip.framework.apollo.core.signature.Signature; import com.google.common.collect.Lists; +import java.util.Collections; import java.util.List; import javax.servlet.FilterChain; import javax.servlet.http.HttpServletRequest; @@ -58,7 +61,7 @@ public class ClientAuthenticationFilterTest { @Before public void setUp() { - clientAuthenticationFilter = new ClientAuthenticationFilter(bizConfig, accessKeyUtil); + clientAuthenticationFilter = spy(new ClientAuthenticationFilter(bizConfig, accessKeyUtil)); } @Test @@ -141,6 +144,54 @@ public void testAuthorizedSuccessfully() throws Exception { clientAuthenticationFilter.doFilter(request, response, filterChain); + verifySuccessAndDoFilter(); + } + + @Test + public void testPreCheckInvalid() throws Exception { + String appId = "someAppId"; + String availableSignature = "someSignature"; + List secrets = Lists.newArrayList("someSecret"); + String oneMinAgoTimestamp = Long.toString(System.currentTimeMillis() - 61 * 1000); + String errorAuthorization = "Apollo someAppId:wrongSignature"; + + when(accessKeyUtil.extractAppIdFromRequest(any())).thenReturn(appId); + when(accessKeyUtil.findAvailableSecret(appId)).thenReturn(Collections.emptyList()); + when(accessKeyUtil.findObservableSecrets(appId)).thenReturn(secrets); + when(accessKeyUtil.buildSignature(any(), any(), any(), any())).thenReturn(availableSignature); + when(request.getHeader(Signature.HTTP_HEADER_TIMESTAMP)).thenReturn(oneMinAgoTimestamp); + when(request.getHeader(HttpHeaders.AUTHORIZATION)).thenReturn(errorAuthorization); + when(bizConfig.accessKeyAuthTimeDiffTolerance()).thenReturn(60); + + clientAuthenticationFilter.doFilter(request, response, filterChain); + + verifySuccessAndDoFilter(); + verify(clientAuthenticationFilter, times(2)).preCheckInvalidLogging(anyString()); + } + + @Test + public void testPreCheckSuccessfully() throws Exception { + String appId = "someAppId"; + String availableSignature = "someSignature"; + List secrets = Lists.newArrayList("someSecret"); + String oneMinAgoTimestamp = Long.toString(System.currentTimeMillis()); + String correctAuthorization = "Apollo someAppId:someSignature"; + + when(accessKeyUtil.extractAppIdFromRequest(any())).thenReturn(appId); + when(accessKeyUtil.findAvailableSecret(appId)).thenReturn(Collections.emptyList()); + when(accessKeyUtil.findObservableSecrets(appId)).thenReturn(secrets); + when(accessKeyUtil.buildSignature(any(), any(), any(), any())).thenReturn(availableSignature); + when(request.getHeader(Signature.HTTP_HEADER_TIMESTAMP)).thenReturn(oneMinAgoTimestamp); + when(request.getHeader(HttpHeaders.AUTHORIZATION)).thenReturn(correctAuthorization); + when(bizConfig.accessKeyAuthTimeDiffTolerance()).thenReturn(60); + + clientAuthenticationFilter.doFilter(request, response, filterChain); + + verifySuccessAndDoFilter(); + verify(clientAuthenticationFilter, never()).preCheckInvalidLogging(anyString()); + } + + private void verifySuccessAndDoFilter() throws Exception { verify(response, never()).sendError(HttpServletResponse.SC_BAD_REQUEST, "InvalidAppId"); verify(response, never()).sendError(HttpServletResponse.SC_UNAUTHORIZED, "RequestTimeTooSkewed"); verify(response, never()).sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized"); diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/api/AdminServiceAPI.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/api/AdminServiceAPI.java index b8035aae7a2..b05c2cc77df 100644 --- a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/api/AdminServiceAPI.java +++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/api/AdminServiceAPI.java @@ -317,9 +317,9 @@ public void delete(Env env, String appId, long id, String operator) { } @ApolloAuditLog(type = OpType.RPC, name = "AccessKey.enableInRemote") - public void enable(Env env, String appId, long id, String operator) { - restTemplate.put(env, "apps/{appId}/accesskeys/{id}/enable?operator={operator}", - null, appId, id, operator); + public void enable(Env env, String appId, long id, int mode, String operator) { + restTemplate.put(env, "apps/{appId}/accesskeys/{id}/enable?mode={mode}&operator={operator}", + null, appId, id, mode, operator); } @ApolloAuditLog(type = OpType.RPC, name = "AccessKey.disableInRemote") diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/AccessKeyController.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/AccessKeyController.java index fb8518d7dec..b5ef6f123f5 100644 --- a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/AccessKeyController.java +++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/AccessKeyController.java @@ -16,6 +16,8 @@ */ package com.ctrip.framework.apollo.portal.controller; +import static com.ctrip.framework.apollo.common.constants.AccessKeyMode.FILTER; + import com.ctrip.framework.apollo.audit.annotation.ApolloAuditLog; import com.ctrip.framework.apollo.audit.annotation.OpType; import com.ctrip.framework.apollo.common.dto.AccessKeyDTO; @@ -77,9 +79,10 @@ public void delete(@PathVariable String appId, @ApolloAuditLog(type = OpType.UPDATE, name = "AccessKey.enable") public void enable(@PathVariable String appId, @PathVariable String env, - @PathVariable long id) { + @PathVariable long id, + @RequestParam(required = false, defaultValue = "" + FILTER) int mode) { String operator = userInfoHolder.getUser().getUserId(); - accessKeyService.enable(Env.valueOf(env), appId, id, operator); + accessKeyService.enable(Env.valueOf(env), appId, id, mode, operator); } @PreAuthorize(value = "@permissionValidator.isAppAdmin(#appId)") diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/service/AccessKeyService.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/service/AccessKeyService.java index 26ba0ff92c0..9f7890ccf8e 100644 --- a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/service/AccessKeyService.java +++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/service/AccessKeyService.java @@ -49,8 +49,8 @@ public void deleteAccessKey(Env env, String appId, long id, String operator) { accessKeyAPI.delete(env, appId, id, operator); } - public void enable(Env env, String appId, long id, String operator) { - accessKeyAPI.enable(env, appId, id, operator); + public void enable(Env env, String appId, long id, int mode, String operator) { + accessKeyAPI.enable(env, appId, id, mode, operator); } public void disable(Env env, String appId, long id, String operator) { diff --git a/apollo-portal/src/main/resources/static/app/access_key.html b/apollo-portal/src/main/resources/static/app/access_key.html index debca68fd0f..4cb1c9c4993 100644 --- a/apollo-portal/src/main/resources/static/app/access_key.html +++ b/apollo-portal/src/main/resources/static/app/access_key.html @@ -60,10 +60,11 @@

{{'Common.Environment' | translate }}: {{env}} {{accessKey.secret}} - {{accessKey.enabled ? ('AccessKey.Operator.Enabled' | translate) : ('AccessKey.Operator.Disabled' | translate) }} + {{'AccessKey.Operator.Enabled' | translate}} + {{'AccessKey.Operator.Observed' | translate}} + {{'AccessKey.Operator.Disabled' | translate}} {{accessKey.dataChangeLastModifiedBy}} {{accessKey.dataChangeLastModifiedTime | date: 'yyyy-MM-dd HH:mm:ss'}} - {{'AccessKey.Operator.Enable' | translate}} - {{'AccessKey.Operator.Disable' | translate}} - {{'AccessKey.Operator.Remove' | translate }} + {{'AccessKey.Operator.Enable' | translate}} + {{'AccessKey.Operator.Observe' | translate}} + {{'AccessKey.Operator.Disable' | translate}} + {{'AccessKey.Operator.Remove' | translate }} diff --git a/apollo-portal/src/main/resources/static/i18n/en.json b/apollo-portal/src/main/resources/static/i18n/en.json index 81c3bded0a6..69ae8e5e4cf 100644 --- a/apollo-portal/src/main/resources/static/i18n/en.json +++ b/apollo-portal/src/main/resources/static/i18n/en.json @@ -517,10 +517,11 @@ "ServiceConfig.KeyExistsAndSaveTip": "Key: '{{key}}' already exists. Click Save will override the configuration item.", "AccessKey.Tips.1": "Add up to 5 access keys per environment.", "AccessKey.Tips.2": "Once the environment has any enabled access key, the client will be required to configure access key, or the configurations cannot be obtained.", - "AccessKey.Tips.3": "Configure the access key to prevent unauthorized clients from obtaining the application configuration. The configuration method is as follows(only apollo-client version 1.6.0+):", - "AccessKey.Tips.3.1": "Via jvm parameter: apollo-client version >=1.9.0 is recommended to use -Dapollo.access-key.secret; other versions use -Dapollo.accesskey.secret", - "AccessKey.Tips.3.2": "Through the os environment variable: apollo-client version >=1.9.0 is recommended to use APOLLO_ACCESS_KEY_SECRET; other versions use APOLLO_ACCESSKEY_SECRET", - "AccessKey.Tips.3.3": "Via META-INF/app.properties or application.properties: apollo-client version >=1.9.0 is recommended to use apollo.access-key.secret; other versions use apollo.accesskey.secret(note that the multi-environment secret is different)", + "AccessKey.Tips.3": "Observed access keys are used for pre-check and logging only. Note: Once the environment has any enabled access key, the observed status will no longer take effect.", + "AccessKey.Tips.4": "Configure the access key to prevent unauthorized clients from obtaining the application configuration. The configuration method is as follows(only apollo-client version 1.6.0+):", + "AccessKey.Tips.4.1": "Via jvm parameter: apollo-client version >=1.9.0 is recommended to use -Dapollo.access-key.secret; other versions use -Dapollo.accesskey.secret", + "AccessKey.Tips.4.2": "Through the os environment variable: apollo-client version >=1.9.0 is recommended to use APOLLO_ACCESS_KEY_SECRET; other versions use APOLLO_ACCESSKEY_SECRET", + "AccessKey.Tips.4.3": "Via META-INF/app.properties or application.properties: apollo-client version >=1.9.0 is recommended to use apollo.access-key.secret; other versions use apollo.accesskey.secret(note that the multi-environment secret is different)", "AccessKey.NoAccessKeyServiceTips": "There are no access keys in this environment.", "AccessKey.ConfigAccessKeys.Secret": "Access Key Secret", "AccessKey.ConfigAccessKeys.Status": "Status", @@ -529,19 +530,24 @@ "AccessKey.ConfigAccessKeys.Operator": "Operation", "AccessKey.Operator.Disable": "Disable", "AccessKey.Operator.Enable": "Enable", + "AccessKey.Operator.Observe": "Observe", "AccessKey.Operator.Disabled": "Disabled", "AccessKey.Operator.Enabled": "Enabled", + "AccessKey.Operator.Observed": "Observed", "AccessKey.Operator.Remove": "Remove", "AccessKey.Operator.CreateSuccess": "Access key created successfully", "AccessKey.Operator.DisabledSuccess": "Access key disabled successfully", "AccessKey.Operator.EnabledSuccess": "Access key enabled successfully", + "AccessKey.Operator.ObservedSuccess": "Access key observed successfully", "AccessKey.Operator.RemoveSuccess": "Access key removed successfully", "AccessKey.Operator.CreateError": "Access key created failed", "AccessKey.Operator.DisabledError": "Access key disabled failed", "AccessKey.Operator.EnabledError": "Access key enabled failed", + "AccessKey.Operator.ObservedError": "Access key observed failed", "AccessKey.Operator.RemoveError": "Access key removed failed", "AccessKey.Operator.DisabledTips": "Are you sure you want to disable the access key?", "AccessKey.Operator.EnabledTips": "Are you sure you want to enable the access key?", + "AccessKey.Operator.ObservedTips": "Are you sure you want to observe the access key?", "AccessKey.Operator.RemoveTips": "Are you sure you want to remove the access key?", "AccessKey.LoadError": "Error Loading access keys", "SystemInfo.Title": "System Information", diff --git a/apollo-portal/src/main/resources/static/i18n/zh-CN.json b/apollo-portal/src/main/resources/static/i18n/zh-CN.json index 2ef309b46dc..8ae676eda59 100644 --- a/apollo-portal/src/main/resources/static/i18n/zh-CN.json +++ b/apollo-portal/src/main/resources/static/i18n/zh-CN.json @@ -516,11 +516,12 @@ "ServiceConfig.KeyNotExistsAndCreateTip": "Key: '{{key}}' 不存在,点击保存后会创建该配置项", "ServiceConfig.KeyExistsAndSaveTip": "Key: '{{key}}' 已存在,点击保存后会覆盖该配置项", "AccessKey.Tips.1": "每个环境最多可添加 5 个访问密钥", - "AccessKey.Tips.2": "一旦该环境有启用的访问密钥,客户端将被要求配置密钥,否则无法获取配置", - "AccessKey.Tips.3": "配置访问密钥防止非法客户端获取该应用配置,配置方式如下:(仅支持apollo-client 1.6.0+)", - "AccessKey.Tips.3.1": "通过JVM参数配置: apollo-client >=1.9.0 推荐使用 -Dapollo.access-key.secret; 其它版本使用 -Dapollo.accesskey.secret", - "AccessKey.Tips.3.2": "通过操作系统环境变量配置: apollo-client >=1.9.0 推荐使用 APOLLO_ACCESS_KEY_SECRET; 其它版本使用 APOLLO_ACCESSKEY_SECRET", - "AccessKey.Tips.3.3": "通过 META-INF/app.properties 或 application.properties配置: apollo-client >=1.9.0 推荐使用 apollo.access-key.secret; 其它版本使用 apollo.accesskey.secret(注意多环境 secret 不一样)", + "AccessKey.Tips.2": "一旦该环境有启用状态的访问密钥,客户端将被要求配置密钥,否则无法获取配置", + "AccessKey.Tips.3": "观察状态密钥用于预校验,只做日志记录不拦截配置获取,注意:一旦该环境有启用状态的访问密钥,观察状态将不再生效", + "AccessKey.Tips.4": "配置访问密钥防止非法客户端获取该应用配置,配置方式如下:(仅支持apollo-client 1.6.0+)", + "AccessKey.Tips.4.1": "通过JVM参数配置: apollo-client >=1.9.0 推荐使用 -Dapollo.access-key.secret; 其它版本使用 -Dapollo.accesskey.secret", + "AccessKey.Tips.4.2": "通过操作系统环境变量配置: apollo-client >=1.9.0 推荐使用 APOLLO_ACCESS_KEY_SECRET; 其它版本使用 APOLLO_ACCESSKEY_SECRET", + "AccessKey.Tips.4.3": "通过 META-INF/app.properties 或 application.properties配置: apollo-client >=1.9.0 推荐使用 apollo.access-key.secret; 其它版本使用 apollo.accesskey.secret(注意多环境 secret 不一样)", "AccessKey.NoAccessKeyServiceTips": "该环境没有配置访问密钥", "AccessKey.ConfigAccessKeys.Secret": "访问密钥", "AccessKey.ConfigAccessKeys.Status": "状态", @@ -529,19 +530,24 @@ "AccessKey.ConfigAccessKeys.Operator": "操作", "AccessKey.Operator.Disable": "禁用", "AccessKey.Operator.Enable": "启用", + "AccessKey.Operator.Observe": "观察", "AccessKey.Operator.Disabled": "已禁用", "AccessKey.Operator.Enabled": "已启用", + "AccessKey.Operator.Observed": "已观察", "AccessKey.Operator.Remove": "删除", "AccessKey.Operator.CreateSuccess": "访问密钥创建成功", "AccessKey.Operator.DisabledSuccess": "访问密钥禁用成功", "AccessKey.Operator.EnabledSuccess": "访问密钥启用成功", + "AccessKey.Operator.ObservedSuccess": "访问密钥观察成功", "AccessKey.Operator.RemoveSuccess": "访问密钥删除成功", "AccessKey.Operator.CreateError": "访问密钥创建失败", "AccessKey.Operator.DisabledError": "访问密钥禁用失败", "AccessKey.Operator.EnabledError": "访问密钥启用失败", + "AccessKey.Operator.ObservedError": "访问密钥观察失败", "AccessKey.Operator.RemoveError": "访问密钥删除失败", "AccessKey.Operator.DisabledTips": "是否确定禁用该访问密钥?", "AccessKey.Operator.EnabledTips": " 是否确定启用该访问密钥?", + "AccessKey.Operator.ObservedTips": " 是否确定观察该访问密钥?", "AccessKey.Operator.RemoveTips": " 是否确定删除该访问密钥?", "AccessKey.LoadError": "加载访问密钥出错", "SystemInfo.Title": "系统信息", diff --git a/apollo-portal/src/main/resources/static/scripts/controller/AccessKeyController.js b/apollo-portal/src/main/resources/static/scripts/controller/AccessKeyController.js index 7044ba54286..b34f939486f 100644 --- a/apollo-portal/src/main/resources/static/scripts/controller/AccessKeyController.js +++ b/apollo-portal/src/main/resources/static/scripts/controller/AccessKeyController.js @@ -136,17 +136,19 @@ function AccessKeyController($scope, $location, $translate, toastr, } } - function enable(id, env) { - var confirmTips = $translate.instant('AccessKey.Operator.EnabledTips', { + function enable(id, env, mode) { + mode = (mode === 1) ? 1 : 0; + var tipsPrefix = mode === 1 ? 'AccessKey.Operator.Observed' : 'AccessKey.Operator.Enabled'; + var confirmTips = $translate.instant(tipsPrefix + 'Tips', { appId: $scope.pageContext.appId }); if (confirm(confirmTips)) { - AccessKeyService.enable_access_key($scope.pageContext.appId, env, id) + AccessKeyService.enable_access_key($scope.pageContext.appId, env, id, mode) .then(function () { - toastr.success($translate.instant('AccessKey.Operator.EnabledSuccess', {env})); + toastr.success($translate.instant(tipsPrefix + 'Success', {env})); loadAccessKeys(env); }, function (result) { - toastr.error(AppUtil.errorMsg(result), $translate.instant('AccessKey.Operator.EnabledError', {env})); + toastr.error(AppUtil.errorMsg(result), $translate.instant(tipsPrefix + 'Error', {env})); }); } } diff --git a/apollo-portal/src/main/resources/static/scripts/services/AccessKeyService.js b/apollo-portal/src/main/resources/static/scripts/services/AccessKeyService.js index 35a42c0fe0a..aca9c393735 100644 --- a/apollo-portal/src/main/resources/static/scripts/services/AccessKeyService.js +++ b/apollo-portal/src/main/resources/static/scripts/services/AccessKeyService.js @@ -31,7 +31,7 @@ appService.service('AccessKeyService', ['$resource', '$q', 'AppUtil', function ( }, enable_access_key: { method: 'PUT', - url: AppUtil.prefixPath() + '/apps/:appId/envs/:env/accesskeys/:id/enable' + url: AppUtil.prefixPath() + '/apps/:appId/envs/:env/accesskeys/:id/enable?mode=:mode' }, disable_access_key: { method: 'PUT', @@ -79,12 +79,13 @@ appService.service('AccessKeyService', ['$resource', '$q', 'AppUtil', function ( }); return d.promise; }, - enable_access_key: function (appId, env, id) { + enable_access_key: function (appId, env, id, mode) { var d = $q.defer(); access_key_resource.enable_access_key({ appId: appId, env: env, - id: id + id: id, + mode: mode }, {}, function (result) { d.resolve(result); diff --git a/changes/changes-2.4.0.md b/changes/changes-2.4.0.md index 615d7c1d7a4..3ebe2e98381 100644 --- a/changes/changes-2.4.0.md +++ b/changes/changes-2.4.0.md @@ -8,6 +8,7 @@ Apollo 2.4.0 * [Update the server config link in system info page](https://github.com/apolloconfig/apollo/pull/5204) * [Feature support portal restTemplate Client connection pool config](https://github.com/apolloconfig/apollo/pull/5200) * [Feature added the ability for administrators to globally search for Value](https://github.com/apolloconfig/apollo/pull/5182) +* [Feature support the observe status access-key for pre-check and logging only](https://github.com/apolloconfig/apollo/pull/5236) ------------------ All issues and pull requests are [here](https://github.com/apolloconfig/apollo/milestone/15?closed=1) diff --git a/scripts/sql/profiles/h2-default/apolloconfigdb.sql b/scripts/sql/profiles/h2-default/apolloconfigdb.sql index 8a24f1c82c9..9fb40f0c21f 100644 --- a/scripts/sql/profiles/h2-default/apolloconfigdb.sql +++ b/scripts/sql/profiles/h2-default/apolloconfigdb.sql @@ -393,6 +393,7 @@ CREATE TABLE `AccessKey` ( `Id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增主键', `AppId` varchar(64) NOT NULL DEFAULT 'default' COMMENT 'AppID', `Secret` varchar(128) NOT NULL DEFAULT '' COMMENT 'Secret', + `Mode` tinyint unsigned NOT NULL DEFAULT '0' COMMENT '密钥模式,0: filter,1: observer', `IsEnabled` boolean NOT NULL DEFAULT FALSE COMMENT '1: enabled, 0: disabled', `IsDeleted` boolean NOT NULL DEFAULT FALSE COMMENT '1: deleted, 0: normal', `DeletedAt` BIGINT(20) NOT NULL DEFAULT '0' COMMENT 'Delete timestamp based on milliseconds', diff --git a/scripts/sql/profiles/h2-default/delta/v230-v240/apolloconfigdb-v230-v240.sql b/scripts/sql/profiles/h2-default/delta/v230-v240/apolloconfigdb-v230-v240.sql new file mode 100644 index 00000000000..459c12ff9b4 --- /dev/null +++ b/scripts/sql/profiles/h2-default/delta/v230-v240/apolloconfigdb-v230-v240.sql @@ -0,0 +1,43 @@ +-- +-- Copyright 2024 Apollo Authors +-- +-- 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. +-- +-- delta schema to upgrade apollo config db from v2.3.0 to v2.4.0 + +-- +-- =============================================================================== +-- == == +-- == Generated from 'scripts/sql/src/' == +-- == by running 'mvn compile -pl apollo-build-sql-converter -Psql-converter'. == +-- == DO NOT EDIT !!! == +-- == == +-- =============================================================================== +-- + +-- H2 Function +-- ------------------------------------------------------------ +CREATE ALIAS IF NOT EXISTS UNIX_TIMESTAMP FOR "com.ctrip.framework.apollo.common.jpa.H2Function.unixTimestamp"; + +-- + +ALTER TABLE `AccessKey` ADD COLUMN `Mode` tinyint unsigned NOT NULL DEFAULT '0' COMMENT '密钥模式,0: filter,1: observer' AFTER `Secret`; + +-- +-- =============================================================================== +-- == == +-- == Generated from 'scripts/sql/src/' == +-- == by running 'mvn compile -pl apollo-build-sql-converter -Psql-converter'. == +-- == DO NOT EDIT !!! == +-- == == +-- =============================================================================== diff --git a/scripts/sql/profiles/mysql-database-not-specified/apolloconfigdb.sql b/scripts/sql/profiles/mysql-database-not-specified/apolloconfigdb.sql index 4d2e0c19118..dd9b4dcae8e 100644 --- a/scripts/sql/profiles/mysql-database-not-specified/apolloconfigdb.sql +++ b/scripts/sql/profiles/mysql-database-not-specified/apolloconfigdb.sql @@ -404,6 +404,7 @@ CREATE TABLE `AccessKey` ( `Id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增主键', `AppId` varchar(64) NOT NULL DEFAULT 'default' COMMENT 'AppID', `Secret` varchar(128) NOT NULL DEFAULT '' COMMENT 'Secret', + `Mode` tinyint unsigned NOT NULL DEFAULT '0' COMMENT '密钥模式,0: filter,1: observer', `IsEnabled` bit(1) NOT NULL DEFAULT b'0' COMMENT '1: enabled, 0: disabled', `IsDeleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '1: deleted, 0: normal', `DeletedAt` BIGINT(20) NOT NULL DEFAULT '0' COMMENT 'Delete timestamp based on milliseconds', diff --git a/scripts/sql/profiles/mysql-database-not-specified/delta/v230-v240/apolloconfigdb-v230-v240.sql b/scripts/sql/profiles/mysql-database-not-specified/delta/v230-v240/apolloconfigdb-v230-v240.sql new file mode 100644 index 00000000000..c71b792aa6e --- /dev/null +++ b/scripts/sql/profiles/mysql-database-not-specified/delta/v230-v240/apolloconfigdb-v230-v240.sql @@ -0,0 +1,39 @@ +-- +-- Copyright 2024 Apollo Authors +-- +-- 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. +-- +-- delta schema to upgrade apollo config db from v2.3.0 to v2.4.0 + +-- +-- =============================================================================== +-- == == +-- == Generated from 'scripts/sql/src/' == +-- == by running 'mvn compile -pl apollo-build-sql-converter -Psql-converter'. == +-- == DO NOT EDIT !!! == +-- == == +-- =============================================================================== +-- +-- + +ALTER TABLE `AccessKey` + ADD COLUMN `Mode` tinyint unsigned NOT NULL DEFAULT '0' COMMENT '密钥模式,0: filter,1: observer' AFTER `Secret`; + +-- +-- =============================================================================== +-- == == +-- == Generated from 'scripts/sql/src/' == +-- == by running 'mvn compile -pl apollo-build-sql-converter -Psql-converter'. == +-- == DO NOT EDIT !!! == +-- == == +-- =============================================================================== diff --git a/scripts/sql/profiles/mysql-default/apolloconfigdb.sql b/scripts/sql/profiles/mysql-default/apolloconfigdb.sql index 3736ea599f3..9416af7380a 100644 --- a/scripts/sql/profiles/mysql-default/apolloconfigdb.sql +++ b/scripts/sql/profiles/mysql-default/apolloconfigdb.sql @@ -409,6 +409,7 @@ CREATE TABLE `AccessKey` ( `Id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增主键', `AppId` varchar(64) NOT NULL DEFAULT 'default' COMMENT 'AppID', `Secret` varchar(128) NOT NULL DEFAULT '' COMMENT 'Secret', + `Mode` tinyint unsigned NOT NULL DEFAULT '0' COMMENT '密钥模式,0: filter,1: observer', `IsEnabled` bit(1) NOT NULL DEFAULT b'0' COMMENT '1: enabled, 0: disabled', `IsDeleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '1: deleted, 0: normal', `DeletedAt` BIGINT(20) NOT NULL DEFAULT '0' COMMENT 'Delete timestamp based on milliseconds', diff --git a/scripts/sql/profiles/mysql-default/delta/v230-v240/apolloconfigdb-v230-v240.sql b/scripts/sql/profiles/mysql-default/delta/v230-v240/apolloconfigdb-v230-v240.sql new file mode 100644 index 00000000000..8bb5fdc1a0e --- /dev/null +++ b/scripts/sql/profiles/mysql-default/delta/v230-v240/apolloconfigdb-v230-v240.sql @@ -0,0 +1,41 @@ +-- +-- Copyright 2024 Apollo Authors +-- +-- 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. +-- +-- delta schema to upgrade apollo config db from v2.3.0 to v2.4.0 + +-- +-- =============================================================================== +-- == == +-- == Generated from 'scripts/sql/src/' == +-- == by running 'mvn compile -pl apollo-build-sql-converter -Psql-converter'. == +-- == DO NOT EDIT !!! == +-- == == +-- =============================================================================== +-- +-- +-- Use Database +Use ApolloConfigDB; + +ALTER TABLE `AccessKey` + ADD COLUMN `Mode` tinyint unsigned NOT NULL DEFAULT '0' COMMENT '密钥模式,0: filter,1: observer' AFTER `Secret`; + +-- +-- =============================================================================== +-- == == +-- == Generated from 'scripts/sql/src/' == +-- == by running 'mvn compile -pl apollo-build-sql-converter -Psql-converter'. == +-- == DO NOT EDIT !!! == +-- == == +-- =============================================================================== diff --git a/scripts/sql/src/apolloconfigdb.sql b/scripts/sql/src/apolloconfigdb.sql index 9f85a8791ce..216dfdd9a33 100644 --- a/scripts/sql/src/apolloconfigdb.sql +++ b/scripts/sql/src/apolloconfigdb.sql @@ -397,6 +397,7 @@ CREATE TABLE `AccessKey` ( `Id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增主键', `AppId` varchar(64) NOT NULL DEFAULT 'default' COMMENT 'AppID', `Secret` varchar(128) NOT NULL DEFAULT '' COMMENT 'Secret', + `Mode` tinyint unsigned NOT NULL DEFAULT '0' COMMENT '密钥模式,0: filter,1: observer', `IsEnabled` bit(1) NOT NULL DEFAULT b'0' COMMENT '1: enabled, 0: disabled', `IsDeleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '1: deleted, 0: normal', `DeletedAt` BIGINT(20) NOT NULL DEFAULT '0' COMMENT 'Delete timestamp based on milliseconds', diff --git a/scripts/sql/src/delta/v230-v240/apolloconfigdb-v230-v240.sql b/scripts/sql/src/delta/v230-v240/apolloconfigdb-v230-v240.sql new file mode 100644 index 00000000000..2e3cddfbbea --- /dev/null +++ b/scripts/sql/src/delta/v230-v240/apolloconfigdb-v230-v240.sql @@ -0,0 +1,25 @@ +-- +-- Copyright 2024 Apollo Authors +-- +-- 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. +-- +-- delta schema to upgrade apollo config db from v2.3.0 to v2.4.0 + +-- ${gists.autoGeneratedDeclaration} +-- ${gists.h2Function} +-- ${gists.useDatabase} + +ALTER TABLE `AccessKey` + ADD COLUMN `Mode` tinyint unsigned NOT NULL DEFAULT '0' COMMENT '密钥模式,0: filter,1: observer' AFTER `Secret`; + +-- ${gists.autoGeneratedDeclaration}