隔离 Ayatori 数据库 Dev/Prod 接入声明并修正 Instance 作用域 #167
@@ -1,45 +0,0 @@
|
|||||||
# SecretStore 由独立控制面的部署管理,必须只读下述两个管理凭据路径。
|
|
||||||
apiVersion: external-secrets.io/v1
|
|
||||||
kind: ExternalSecret
|
|
||||||
metadata:
|
|
||||||
name: homelab-postgresql-prod-admin
|
|
||||||
spec:
|
|
||||||
refreshInterval: 1h
|
|
||||||
secretStoreRef:
|
|
||||||
name: homelab-postgresql-admin
|
|
||||||
kind: SecretStore
|
|
||||||
target:
|
|
||||||
name: homelab-postgresql-prod-admin
|
|
||||||
creationPolicy: Owner
|
|
||||||
data:
|
|
||||||
- secretKey: username
|
|
||||||
remoteRef:
|
|
||||||
key: infra/postgresql/ayatori/prod
|
|
||||||
property: username
|
|
||||||
- secretKey: password
|
|
||||||
remoteRef:
|
|
||||||
key: infra/postgresql/ayatori/prod
|
|
||||||
property: password
|
|
||||||
---
|
|
||||||
# SecretStore 由独立控制面的部署管理,必须只读下述两个管理凭据路径。
|
|
||||||
apiVersion: external-secrets.io/v1
|
|
||||||
kind: ExternalSecret
|
|
||||||
metadata:
|
|
||||||
name: homelab-postgresql-dev-admin
|
|
||||||
spec:
|
|
||||||
refreshInterval: 1h
|
|
||||||
secretStoreRef:
|
|
||||||
name: homelab-postgresql-admin
|
|
||||||
kind: SecretStore
|
|
||||||
target:
|
|
||||||
name: homelab-postgresql-dev-admin
|
|
||||||
creationPolicy: Owner
|
|
||||||
data:
|
|
||||||
- secretKey: username
|
|
||||||
remoteRef:
|
|
||||||
key: infra/postgresql/ayatori/dev
|
|
||||||
property: username
|
|
||||||
- secretKey: password
|
|
||||||
remoteRef:
|
|
||||||
key: infra/postgresql/ayatori/dev
|
|
||||||
property: password
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIDMzCCAhugAwIBAgIUMs0iV657yC9UhA2p2vomLIbFnzgwDQYJKoZIhvcNAQEL
|
|
||||||
BQAwITEfMB0GA1UEAxMWZGR1cGFuLnRvcCBJbnRlcm5hbCBDQTAeFw0yNjA3MjQy
|
|
||||||
MDE1MDFaFw0zNjA3MjEyMDE1MzFaMCExHzAdBgNVBAMTFmRkdXBhbi50b3AgSW50
|
|
||||||
ZXJuYWwgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6QWlwBe6f
|
|
||||||
t7Ca3KCTvr4Pz+jVO60WrMBoEDYYM8Mp04btBHzhAQHf9Pp8+15aEW9iUcQhqqm+
|
|
||||||
2vT6H0JEhIbplyCWY6Guv0mTu8f+lvFknJIl2b3JqnMLHJKjh/rBrsE12XZ3i17M
|
|
||||||
2tCr34BWcei85IZyQl5HMW6dB8lAE6bdom+YynK4oLJdej9DD6bSyM8WcL0OsneZ
|
|
||||||
NsjwOlNMy3zjbtaH6mH71SgbFinxLp3AAAuLVe1DIKhFxuTQeVr/WaPum5y/oOsc
|
|
||||||
0gJp9If6nsC33lpRGcPLiZE9kfFZa4fPe8laCaN8q1K253qZ0rjRiDhbTAppW4Fy
|
|
||||||
r5P67h+2D+TbAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTAD
|
|
||||||
AQH/MB0GA1UdDgQWBBSOgk1fR0qhz/Bo4wD9g2BnOAzDXzAfBgNVHSMEGDAWgBSO
|
|
||||||
gk1fR0qhz/Bo4wD9g2BnOAzDXzANBgkqhkiG9w0BAQsFAAOCAQEANm5kKkts1Ar2
|
|
||||||
7IlS+TxLFrZ/C9yhIdGcBk2SL5E+5E8S3skQWLEPGLRwvV4RmiB8gQ2V6UyGLrCx
|
|
||||||
1MuuSmCDaSYL9G66sGX1MIHlQ0F0bHIOxxtsTwIYzb5Sl8h3MfsARabmOhE3xUkn
|
|
||||||
jaAT9YUweHhjF4vi0U1Q4F8oOSvu4eJp5dMx1r7b2bLN90A1xh9sfdkEenSBX0tm
|
|
||||||
xK82ROYXI2Ejv/EO+lPUIn3jfqbqrS2itw75Xz/ECHjIfSxvW98puP69U54a1gf6
|
|
||||||
gWdXslr0pGkyMHqxw4dmaecpK0QK3jvqCNycNwNBfMdCypS2QRy03adcUosEAP3O
|
|
||||||
LZU7Kd8aeg==
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
common/ca.crt
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDMzCCAhugAwIBAgIUMs0iV657yC9UhA2p2vomLIbFnzgwDQYJKoZIhvcNAQEL
|
||||||
|
BQAwITEfMB0GA1UEAxMWZGR1cGFuLnRvcCBJbnRlcm5hbCBDQTAeFw0yNjA3MjQy
|
||||||
|
MDE1MDFaFw0zNjA3MjEyMDE1MzFaMCExHzAdBgNVBAMTFmRkdXBhbi50b3AgSW50
|
||||||
|
ZXJuYWwgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6QWlwBe6f
|
||||||
|
t7Ca3KCTvr4Pz+jVO60WrMBoEDYYM8Mp04btBHzhAQHf9Pp8+15aEW9iUcQhqqm+
|
||||||
|
2vT6H0JEhIbplyCWY6Guv0mTu8f+lvFknJIl2b3JqnMLHJKjh/rBrsE12XZ3i17M
|
||||||
|
2tCr34BWcei85IZyQl5HMW6dB8lAE6bdom+YynK4oLJdej9DD6bSyM8WcL0OsneZ
|
||||||
|
NsjwOlNMy3zjbtaH6mH71SgbFinxLp3AAAuLVe1DIKhFxuTQeVr/WaPum5y/oOsc
|
||||||
|
0gJp9If6nsC33lpRGcPLiZE9kfFZa4fPe8laCaN8q1K253qZ0rjRiDhbTAppW4Fy
|
||||||
|
r5P67h+2D+TbAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTAD
|
||||||
|
AQH/MB0GA1UdDgQWBBSOgk1fR0qhz/Bo4wD9g2BnOAzDXzAfBgNVHSMEGDAWgBSO
|
||||||
|
gk1fR0qhz/Bo4wD9g2BnOAzDXzANBgkqhkiG9w0BAQsFAAOCAQEANm5kKkts1Ar2
|
||||||
|
7IlS+TxLFrZ/C9yhIdGcBk2SL5E+5E8S3skQWLEPGLRwvV4RmiB8gQ2V6UyGLrCx
|
||||||
|
1MuuSmCDaSYL9G66sGX1MIHlQ0F0bHIOxxtsTwIYzb5Sl8h3MfsARabmOhE3xUkn
|
||||||
|
jaAT9YUweHhjF4vi0U1Q4F8oOSvu4eJp5dMx1r7b2bLN90A1xh9sfdkEenSBX0tm
|
||||||
|
xK82ROYXI2Ejv/EO+lPUIn3jfqbqrS2itw75Xz/ECHjIfSxvW98puP69U54a1gf6
|
||||||
|
gWdXslr0pGkyMHqxw4dmaecpK0QK3jvqCNycNwNBfMdCypS2QRy03adcUosEAP3O
|
||||||
|
LZU7Kd8aeg==
|
||||||
|
-----END CERTIFICATE-----
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
|
kind: Kustomization
|
||||||
|
# 公共部分只含公开 CA;接入时必须选择 dev/ 或 prod/,不提供跨环境聚合入口。
|
||||||
|
configMapGenerator:
|
||||||
|
- name: homelab-postgresql-ca
|
||||||
|
namespace: ayatori-system
|
||||||
|
files: [ca.crt]
|
||||||
|
generatorOptions:
|
||||||
|
disableNameSuffixHash: true
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
apiVersion: external-secrets.io/v1
|
||||||
|
kind: ExternalSecret
|
||||||
|
metadata:
|
||||||
|
name: homelab-postgresql-dev-admin
|
||||||
|
namespace: ayatori-system
|
||||||
|
spec:
|
||||||
|
refreshInterval: 1h
|
||||||
|
secretStoreRef:
|
||||||
|
name: homelab-postgresql-dev-admin
|
||||||
|
kind: SecretStore
|
||||||
|
target:
|
||||||
|
name: homelab-postgresql-dev-admin
|
||||||
|
creationPolicy: Owner
|
||||||
|
data:
|
||||||
|
- secretKey: username
|
||||||
|
remoteRef:
|
||||||
|
key: infra/postgresql/ayatori/dev
|
||||||
|
property: username
|
||||||
|
- secretKey: password
|
||||||
|
remoteRef:
|
||||||
|
key: infra/postgresql/ayatori/dev
|
||||||
|
property: password
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
# 仅交付本环境管理凭据;由控制面部署流程绑定专用 ESO 身份。
|
||||||
|
path "kv/data/infra/postgresql/ayatori/dev" { capabilities = ["read"] }
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
apiVersion: database.ayatori.ddupan.top/v1alpha1
|
||||||
|
kind: PostgreSQLInstance
|
||||||
|
metadata:
|
||||||
|
name: homelab-dev
|
||||||
|
spec:
|
||||||
|
endpoint:
|
||||||
|
host: pg-dev.ad.ddupan.top
|
||||||
|
hostaddr: 192.168.10.127
|
||||||
|
port: 5433
|
||||||
|
database: postgres
|
||||||
|
sslMode: verify-full
|
||||||
|
adminCredentialRef:
|
||||||
|
name: homelab-postgresql-dev-admin
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
|
kind: Kustomization
|
||||||
|
resources:
|
||||||
|
- ../common
|
||||||
|
- instance.yaml
|
||||||
|
- admin-credentials.yaml
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
# 供未来独立控制面管理 SecretStore 的 ESO 身份绑定;本文件尚未应用。
|
|
||||||
path "kv/data/infra/postgresql/ayatori/prod" { capabilities = ["read"] }
|
|
||||||
path "kv/data/infra/postgresql/ayatori/dev" { capabilities = ["read"] }
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
# 尚未 apply:须先准备管理 Secret、CA bundle 和角色感知的生产稳定入口。
|
|
||||||
apiVersion: database.ayatori.ddupan.top/v1alpha1
|
|
||||||
kind: PostgreSQLInstance
|
|
||||||
metadata:
|
|
||||||
name: homelab-prod
|
|
||||||
spec:
|
|
||||||
endpoint:
|
|
||||||
host: pg-prod.ad.ddupan.top
|
|
||||||
hostaddr: 192.168.10.2
|
|
||||||
port: 5432
|
|
||||||
database: postgres
|
|
||||||
sslMode: verify-full
|
|
||||||
adminCredentialRef:
|
|
||||||
name: homelab-postgresql-prod-admin
|
|
||||||
---
|
|
||||||
apiVersion: database.ayatori.ddupan.top/v1alpha1
|
|
||||||
kind: PostgreSQLInstance
|
|
||||||
metadata:
|
|
||||||
name: homelab-dev
|
|
||||||
spec:
|
|
||||||
endpoint:
|
|
||||||
host: pg-dev.ad.ddupan.top
|
|
||||||
hostaddr: 192.168.10.127
|
|
||||||
port: 5433
|
|
||||||
database: postgres
|
|
||||||
sslMode: verify-full
|
|
||||||
adminCredentialRef:
|
|
||||||
name: homelab-postgresql-dev-admin
|
|
||||||
@@ -1,12 +1,5 @@
|
|||||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
kind: Kustomization
|
kind: Kustomization
|
||||||
# 仅供未来独立 Ayatori 控制面;此 namespace 必须与 manager 的 Secret namespace 一致。
|
# 公共入口不注册实例或同步凭据;必须显式选择 dev/ 或 prod/。
|
||||||
namespace: ayatori-system
|
|
||||||
resources:
|
resources:
|
||||||
- instances.yaml
|
- common
|
||||||
- admin-credentials.yaml
|
|
||||||
configMapGenerator:
|
|
||||||
- name: homelab-postgresql-ca
|
|
||||||
files: [ca.crt]
|
|
||||||
generatorOptions:
|
|
||||||
disableNameSuffixHash: true
|
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
apiVersion: external-secrets.io/v1
|
||||||
|
kind: ExternalSecret
|
||||||
|
metadata:
|
||||||
|
name: homelab-postgresql-prod-admin
|
||||||
|
namespace: ayatori-system
|
||||||
|
spec:
|
||||||
|
refreshInterval: 1h
|
||||||
|
secretStoreRef:
|
||||||
|
name: homelab-postgresql-prod-admin
|
||||||
|
kind: SecretStore
|
||||||
|
target:
|
||||||
|
name: homelab-postgresql-prod-admin
|
||||||
|
creationPolicy: Owner
|
||||||
|
data:
|
||||||
|
- secretKey: username
|
||||||
|
remoteRef:
|
||||||
|
key: infra/postgresql/ayatori/prod
|
||||||
|
property: username
|
||||||
|
- secretKey: password
|
||||||
|
remoteRef:
|
||||||
|
key: infra/postgresql/ayatori/prod
|
||||||
|
property: password
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
# 仅交付本环境管理凭据;由控制面部署流程绑定专用 ESO 身份。
|
||||||
|
path "kv/data/infra/postgresql/ayatori/prod" { capabilities = ["read"] }
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
apiVersion: database.ayatori.ddupan.top/v1alpha1
|
||||||
|
kind: PostgreSQLInstance
|
||||||
|
metadata:
|
||||||
|
name: homelab-prod
|
||||||
|
spec:
|
||||||
|
endpoint:
|
||||||
|
host: pg-prod.ad.ddupan.top
|
||||||
|
hostaddr: 192.168.10.2
|
||||||
|
port: 5432
|
||||||
|
database: postgres
|
||||||
|
sslMode: verify-full
|
||||||
|
adminCredentialRef:
|
||||||
|
name: homelab-postgresql-prod-admin
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
|
kind: Kustomization
|
||||||
|
resources:
|
||||||
|
- ../common
|
||||||
|
- instance.yaml
|
||||||
|
- admin-credentials.yaml
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
"""校验渲染后的环境隔离与引用关系,无网络、集群写入或凭据访问。"""
|
||||||
|
from pathlib import Path
|
||||||
|
import re
|
||||||
|
import subprocess
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
import yaml
|
||||||
|
|
||||||
|
ROOT = Path(__file__).resolve().parents[1] / 'ayatori'
|
||||||
|
|
||||||
|
|
||||||
|
def render(environment):
|
||||||
|
return list(yaml.safe_load_all(subprocess.check_output(
|
||||||
|
['kubectl', 'kustomize', str(ROOT / environment)], text=True)))
|
||||||
|
|
||||||
|
|
||||||
|
class AyatoriManifestTests(unittest.TestCase):
|
||||||
|
def test_common_entry_cannot_register_instances_or_sync_credentials(self):
|
||||||
|
objects = render('.')
|
||||||
|
self.assertEqual([x['kind'] for x in objects], ['ConfigMap'])
|
||||||
|
self.assertEqual(objects[0]['metadata']['namespace'], 'ayatori-system')
|
||||||
|
|
||||||
|
def test_environment_isolation_scope_and_references(self):
|
||||||
|
for env, address, port in [('dev', '192.168.10.127', 5433), ('prod', '192.168.10.2', 5432)]:
|
||||||
|
with self.subTest(environment=env):
|
||||||
|
objects = render(env)
|
||||||
|
self.assertEqual(sorted(x['kind'] for x in objects),
|
||||||
|
['ConfigMap', 'ExternalSecret', 'PostgreSQLInstance'])
|
||||||
|
instance = next(x for x in objects if x['kind'] == 'PostgreSQLInstance')
|
||||||
|
secret = next(x for x in objects if x['kind'] == 'ExternalSecret')
|
||||||
|
self.assertNotIn('namespace', instance['metadata'])
|
||||||
|
self.assertEqual(instance['metadata']['name'], 'homelab-' + env)
|
||||||
|
self.assertEqual(instance['spec']['endpoint'], {
|
||||||
|
'host': 'pg-' + env + '.ad.ddupan.top', 'hostaddr': address,
|
||||||
|
'port': port, 'database': 'postgres', 'sslMode': 'verify-full'})
|
||||||
|
self.assertEqual(secret['metadata']['namespace'], 'ayatori-system')
|
||||||
|
self.assertEqual(instance['spec']['adminCredentialRef']['name'], secret['spec']['target']['name'])
|
||||||
|
self.assertEqual(secret['spec']['secretStoreRef'],
|
||||||
|
{'name': 'homelab-postgresql-' + env + '-admin', 'kind': 'SecretStore'})
|
||||||
|
self.assertEqual({x['remoteRef']['key'] for x in secret['spec']['data']},
|
||||||
|
{'infra/postgresql/ayatori/' + env})
|
||||||
|
self.assertEqual({x['secretKey'] for x in secret['spec']['data']}, {'username', 'password'})
|
||||||
|
self.assertEqual({x['remoteRef']['property'] for x in secret['spec']['data']}, {'username', 'password'})
|
||||||
|
policy = (ROOT / env / 'eso-policy.hcl').read_text()
|
||||||
|
self.assertEqual(re.findall(r'path\s+"([^"]+)"', policy),
|
||||||
|
['kv/data/infra/postgresql/ayatori/' + env])
|
||||||
|
self.assertEqual(re.findall(r'capabilities\s*=\s*\[([^]]+)\]', policy), ['"read"'])
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main()
|
||||||
Reference in New Issue
Block a user