mirror of
https://github.com/iflytek/skillhub.git
synced 2026-08-27 11:14:59 +00:00
fix(chart): 修复 PR review 反馈项
- 删除 subchart image block,使用 Bitnami 默认版本 - 移除 Ingress cert-manager annotation,消除双重签发 - 清空默认明文密码,改为空字符串 - 排除 tgz 进 git,CI 添加 helm dependency build - checksum 改为模板级渲染,修复文件末尾换行 - sentinel default 3,列表生成改用 append+join - 添加 externalRedis.sentinel.password 字段 - README 补充 existingSecret key 清单 - CI 添加 kubeconform -strict 校验 - RedissonConfig 添加注释,补充空密码测试用例 Signed-off-by: jangrui <admin@jangrui.com>
This commit is contained in:
parent
07c97cf7cd
commit
0605357316
12 changed files with 68 additions and 37 deletions
23
.github/workflows/pr-helm-chart.yml
vendored
23
.github/workflows/pr-helm-chart.yml
vendored
|
|
@ -36,6 +36,9 @@ jobs:
|
|||
with:
|
||||
version: latest
|
||||
|
||||
- name: Build dependencies
|
||||
run: helm dependency build .
|
||||
|
||||
- name: Lint chart
|
||||
run: helm lint .
|
||||
|
||||
|
|
@ -124,24 +127,26 @@ jobs:
|
|||
with:
|
||||
version: latest
|
||||
|
||||
- name: Build dependencies
|
||||
run: helm dependency build .
|
||||
|
||||
- name: Render template - ${{ matrix.scenario.name }}
|
||||
run: |
|
||||
echo "## ${{ matrix.scenario.description }}"
|
||||
helm template test-release . ${{ matrix.scenario.args }} > /tmp/rendered.yaml
|
||||
helm template test-release . ${{ matrix.scenario.args }} > rendered.yaml
|
||||
echo "✅ Template rendered successfully"
|
||||
|
||||
- name: Validate resources
|
||||
run: |
|
||||
RESOURCES=$(grep -c '^kind:' /tmp/rendered.yaml || true)
|
||||
RESOURCES=$(grep -c '^kind:' rendered.yaml || true)
|
||||
echo "Rendered $RESOURCES resources for ${{ matrix.scenario.name }}"
|
||||
if [ "$RESOURCES" -eq 0 ]; then
|
||||
echo "ERROR: No resources rendered for ${{ matrix.scenario.name }}"
|
||||
exit 1
|
||||
fi
|
||||
grep -E '^ name:' /tmp/rendered.yaml | while read -r line; do
|
||||
if echo "$line" | grep -qP '\{\{'; then
|
||||
echo "ERROR: Unrendered template in name: $line"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
echo "✅ All resource names properly rendered"
|
||||
|
||||
- name: Schema validation (kubeconform)
|
||||
uses: docker://ghcr.io/yannh/kubeconform:latest
|
||||
with:
|
||||
entrypoint: '/kubeconform'
|
||||
args: "-strict -summary -output text charts/skillhub/rendered.yaml"
|
||||
|
|
|
|||
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -84,5 +84,8 @@ docs/superpowers/
|
|||
# Local workspace metadata
|
||||
CLAUDE.md
|
||||
|
||||
# Helm chart dependencies
|
||||
charts/skillhub/charts/*.tgz
|
||||
|
||||
# Local config file
|
||||
.mcp.json
|
||||
|
|
|
|||
|
|
@ -53,6 +53,30 @@ helm -n skillhub upgrade -i skillhub ./charts/skillhub \
|
|||
--set externalRedis.password=your-redis-password
|
||||
```
|
||||
|
||||
### 使用 existingSecret
|
||||
|
||||
通过 `existingSecret` 引用已存在的 Secret 对象,避免在 values 中明文写入密码。该 Secret 必须包含以下 key:
|
||||
|
||||
| Key | 必填 | 说明 |
|
||||
|-----|------|------|
|
||||
| `spring-datasource-url` | 是 | JDBC 连接 URL |
|
||||
| `spring-datasource-username` | 是 | 数据库用户名 |
|
||||
| `spring-datasource-password` | 是 | 数据库密码 |
|
||||
| `redis-password` | 是 | Redis 密码 |
|
||||
| `redis-sentinel-password` | 否 | Redis Sentinel 密码(sentinel 模式) |
|
||||
| `bootstrap-admin-password` | 是 | 初始管理员密码 |
|
||||
| `oauth2-github-client-id` | 否 | GitHub OAuth2 Client ID |
|
||||
| `oauth2-github-client-secret` | 否 | GitHub OAuth2 Client Secret |
|
||||
| `skill-scanner-llm-api-key` | 否 | Scanner LLM API Key |
|
||||
| `skill-scanner-llm-model` | 否 | Scanner LLM 模型名称 |
|
||||
| `s3-access-key` | 否 | S3 Access Key |
|
||||
| `s3-secret-key` | 否 | S3 Secret Key |
|
||||
|
||||
```bash
|
||||
helm -n skillhub upgrade -i skillhub ./charts/skillhub \
|
||||
--set existingSecret=my-custom-secret
|
||||
```
|
||||
|
||||
## 配置参考
|
||||
|
||||
### 副本数配置
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
|
|
@ -138,8 +138,8 @@ app.kubernetes.io/component: scanner
|
|||
{{- $prefix := printf "%s-redis-node" (include "skillhub.fullname" .) -}}
|
||||
{{- $headless := printf "%s-redis-headless" (include "skillhub.fullname" .) -}}
|
||||
{{- $port := include "skillhub.redis.port" . -}}
|
||||
{{- $replicas := .Values.redis.replica.replicaCount | default 2 | int -}}
|
||||
{{- $first := true -}}{{- range $i := until $replicas -}}{{- if not $first -}},{{- end -}}{{ $prefix }}-{{ $i }}.{{ $headless }}.{{ $.Release.Namespace }}.svc.cluster.local:{{ $port }}{{- $first = false -}}{{- end -}}
|
||||
{{- $replicas := .Values.redis.replica.replicaCount | default 3 | int -}}
|
||||
{{- $nodes := list -}}{{- range $i := until $replicas -}}{{- $nodes = append $nodes (printf "%s-%d.%s.%s.svc.cluster.local:%s" $prefix $i $headless $.Release.Namespace $port) -}}{{- end -}}{{- join "," $nodes -}}
|
||||
{{- end }}
|
||||
|
||||
{{- /* Redis Host */}}
|
||||
|
|
|
|||
|
|
@ -10,14 +10,6 @@ metadata:
|
|||
{{- if .Values.ingress.annotations }}
|
||||
{{- toYaml .Values.ingress.annotations | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- if .Values.ingress.certManager.enabled }}
|
||||
{{- if eq .Values.ingress.certManager.issuerKind "ClusterIssuer" }}
|
||||
cert-manager.io/cluster-issuer: {{ .Values.ingress.certManager.issuerName }}
|
||||
{{- else }}
|
||||
cert-manager.io/issuer: {{ .Values.ingress.certManager.issuerName }}
|
||||
{{- end }}
|
||||
cert-manager.io/issuer-kind: {{ .Values.ingress.certManager.issuerKind }}
|
||||
{{- end }}
|
||||
spec:
|
||||
ingressClassName: {{ .Values.ingress.className }}
|
||||
{{- if or .Values.ingress.tls.enabled .Values.ingress.certManager.enabled }}
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ stringData:
|
|||
redis-sentinel-password: {{ .Values.redis.auth.sentinelPassword | default .Values.redis.auth.password | quote }}
|
||||
{{- end }}
|
||||
{{- else if and (not .Values.redis.enabled) .Values.externalRedis.sentinel.enabled }}
|
||||
redis-sentinel-password: {{ .Values.externalRedis.password | default "" | quote }}
|
||||
redis-sentinel-password: {{ .Values.externalRedis.sentinel.password | default .Values.externalRedis.password | default "" | quote }}
|
||||
{{- end }}
|
||||
# Bootstrap 管理员密码
|
||||
# 优先级: secrets.bootstrapAdminPassword → bootstrapAdmin.password → 集群已有 Secret → 随机生成
|
||||
|
|
|
|||
|
|
@ -17,8 +17,8 @@ spec:
|
|||
labels:
|
||||
{{- include "skillhub.server.selectorLabels" . | nindent 8 }}
|
||||
annotations:
|
||||
checksum/config: {{ toYaml (dict "redisHost" (include "skillhub.redis.host" .) "redisPort" (include "skillhub.redis.port" .) "storage" .Values.server.storage "s3" .Values.s3 "session" .Values.session "springProfilesActive" .Values.springProfilesActive "bootstrapAdmin" .Values.bootstrapAdmin "scannerEnabled" .Values.scanner.enabled "scannerPort" .Values.scanner.service.port) | sha256sum }}
|
||||
checksum/secret: {{ toYaml (dict "secrets" .Values.secrets "bootstrapAdmin" .Values.bootstrapAdmin) | sha256sum }}
|
||||
checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
|
||||
checksum/secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }}
|
||||
{{- range $key, $val := .Values.server.podAnnotations }}
|
||||
{{ $key }}: {{ $val }}
|
||||
{{- end }}
|
||||
|
|
@ -285,4 +285,4 @@ spec:
|
|||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
|
|
|||
|
|
@ -82,19 +82,13 @@ secrets:
|
|||
postgresql:
|
||||
enabled: true
|
||||
|
||||
image:
|
||||
registry: docker.io
|
||||
repository: bitnami/postgresql
|
||||
tag: latest
|
||||
digest: ""
|
||||
|
||||
architecture: standalone
|
||||
|
||||
auth:
|
||||
postgresPassword: ""
|
||||
database: skillhub
|
||||
username: skillhub
|
||||
password: "skillhub_demo"
|
||||
password: ""
|
||||
|
||||
primary:
|
||||
persistence:
|
||||
|
|
@ -163,17 +157,11 @@ externalDatabase:
|
|||
redis:
|
||||
enabled: true
|
||||
|
||||
image:
|
||||
registry: docker.io
|
||||
repository: bitnami/redis
|
||||
tag: latest
|
||||
digest: ""
|
||||
|
||||
architecture: standalone
|
||||
|
||||
auth:
|
||||
enabled: true
|
||||
password: "skillhub_redis"
|
||||
password: ""
|
||||
sentinelPassword: ""
|
||||
|
||||
master:
|
||||
|
|
@ -235,6 +223,7 @@ externalRedis:
|
|||
enabled: false
|
||||
masterSet: mymaster
|
||||
nodes: []
|
||||
password: ""
|
||||
|
||||
# ============================================================================
|
||||
# Server 配置
|
||||
|
|
|
|||
|
|
@ -42,6 +42,8 @@ public class RedissonConfig {
|
|||
SentinelServersConfig sentinelServersConfig = config.useSentinelServers()
|
||||
.setMasterName(redisProperties.getSentinel().getMaster())
|
||||
.setDatabase(redisProperties.getDatabase())
|
||||
// K8s headless DNS 场景下,客户端通过 pod FQDN 连接 sentinel,
|
||||
// 与 sentinel 自身上报的地址格式不同,跳过地址一致性检查避免误报连接失败
|
||||
.setCheckSentinelsList(false);
|
||||
List<String> nodes = redisProperties.getSentinel().getNodes();
|
||||
nodes.stream()
|
||||
|
|
|
|||
|
|
@ -136,6 +136,22 @@ class RedissonConfigTest {
|
|||
assertThat(sentinelConfig.isCheckSentinelsList()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void createConfig_doesNotSetSentinelPasswordWhenEmpty() throws Exception {
|
||||
RedisProperties properties = new RedisProperties();
|
||||
RedisProperties.Sentinel sentinel = new RedisProperties.Sentinel();
|
||||
sentinel.setMaster("mymaster");
|
||||
sentinel.setNodes(List.of("redis-sentinel-1:26379"));
|
||||
properties.setSentinel(sentinel);
|
||||
properties.setPassword("master-secret");
|
||||
|
||||
Config config = RedissonConfig.createConfig(properties);
|
||||
SentinelServersConfig sentinelConfig = sentinelConfig(config);
|
||||
|
||||
assertThat(sentinelConfig.getPassword()).isEqualTo("master-secret");
|
||||
assertThat(sentinelConfig.getSentinelPassword()).isNull();
|
||||
}
|
||||
|
||||
private SentinelServersConfig sentinelConfig(Config config) throws Exception {
|
||||
Method method = Config.class.getDeclaredMethod("getSentinelServersConfig");
|
||||
method.setAccessible(true);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue