Перенесены секреты из .env в SM
This commit is contained in:
@@ -44,11 +44,13 @@ class InfrastructureConfigTests(unittest.TestCase):
|
||||
application = (ROOT / "infra/compose/application.yml").read_text(encoding="utf-8")
|
||||
self.assertIn("networks: [backend, observability, egress]", application)
|
||||
self.assertIn("networks: [public, backend, observability, egress]", application)
|
||||
self.assertIn('KEYCLOAK_YANDEX_CAPTCHA_SERVER_KEY: ""', application)
|
||||
self.assertIn(
|
||||
"KEYCLOAK_YANDEX_CAPTCHA_SERVER_KEY_FILE: "
|
||||
"/run/secrets/keycloak_yandex_captcha_server_key",
|
||||
application,
|
||||
)
|
||||
self.assertEqual(
|
||||
application.count(
|
||||
"IDGTL_SMS_API_KEY: ${IDGTL_SMS_API_KEY:?IDGTL_SMS_API_KEY is required}"
|
||||
),
|
||||
application.count("IDGTL_SMS_API_KEY_FILE: /run/secrets/idgtl_sms_api_key"),
|
||||
1,
|
||||
)
|
||||
|
||||
@@ -56,7 +58,7 @@ class InfrastructureConfigTests(unittest.TestCase):
|
||||
self.assertEqual(jobs.count("networks: [backend, egress]"), 5)
|
||||
|
||||
observability = (ROOT / "observability/docker-compose.yml").read_text(encoding="utf-8")
|
||||
self.assertIn("networks: [observability, backend, egress]", observability)
|
||||
self.assertIn("networks: [observability, egress]", observability)
|
||||
|
||||
redis = (ROOT / "redis/docker-compose.yml").read_text(encoding="utf-8")
|
||||
self.assertNotIn("egress", redis)
|
||||
@@ -64,6 +66,8 @@ class InfrastructureConfigTests(unittest.TestCase):
|
||||
def test_only_nginx_fragment_publishes_ports(self) -> None:
|
||||
forbidden = (
|
||||
ROOT / "infra/compose/application.yml",
|
||||
ROOT / "api-backend/docker-compose.yml",
|
||||
ROOT / "keycloak/docker-compose.yml",
|
||||
ROOT / "redis/docker-compose.yml",
|
||||
ROOT / "observability/docker-compose.yml",
|
||||
ROOT / "deployment/docker-compose.jobs.yml",
|
||||
@@ -177,6 +181,10 @@ class InfrastructureConfigTests(unittest.TestCase):
|
||||
self.assertIn("storage: file_storage", config)
|
||||
self.assertIn("retry_on_failure:", config)
|
||||
self.assertIn('insecure: "${env:OTEL_REMOTE_TLS_INSECURE}"', config)
|
||||
self.assertIn(
|
||||
"authorization: ${file:/run/secrets/otel_remote_auth_header}", config
|
||||
)
|
||||
self.assertNotIn("OTEL_REMOTE_AUTH_HEADER", config)
|
||||
self.assertIn("tail_sampling:", config)
|
||||
self.assertNotIn("probabilistic_sampler:", config)
|
||||
self.assertIn('targets: ["sms-service:8080"]', config)
|
||||
@@ -231,7 +239,7 @@ class InfrastructureConfigTests(unittest.TestCase):
|
||||
|
||||
def test_smoke_script_does_not_source_env_as_shell(self) -> None:
|
||||
smoke = (ROOT / "deployment/scripts/smoke.sh").read_text(encoding="utf-8")
|
||||
self.assertNotIn('. "./$ENV_FILE"', smoke)
|
||||
self.assertNotIn('. "./$CONFIG_FILE"', smoke)
|
||||
for variable in ("PUBLIC_HOST", "PUBLIC_WEB_URL", "KEYCLOAK_REALM"):
|
||||
self.assertIn(f"{variable}=$(env_value {variable})", smoke)
|
||||
|
||||
@@ -298,18 +306,64 @@ class InfrastructureConfigTests(unittest.TestCase):
|
||||
for variable in (
|
||||
"KC_DB_SCHEMA",
|
||||
"KEYCLOAK_OTP_MOCK_ENABLED",
|
||||
"KEYCLOAK_OTP_MOCK_CODE",
|
||||
"KEYCLOAK_YANDEX_CAPTCHA_ENABLED",
|
||||
"KEYCLOAK_YANDEX_CAPTCHA_CLIENT_KEY",
|
||||
"KEYCLOAK_YANDEX_CAPTCHA_SERVER_KEY",
|
||||
"KEYCLOAK_OTP_HMAC_KEY",
|
||||
"KEYCLOAK_OTP_SETTINGS_MAX_STALE_SEC",
|
||||
"KEYCLOAK_SETTINGS_BRIDGE_URL",
|
||||
"KEYCLOAK_SETTINGS_BRIDGE_TOKEN",
|
||||
"KEYCLOAK_SMS_SERVICE_URL",
|
||||
"KEYCLOAK_SMS_SERVICE_TOKEN",
|
||||
):
|
||||
self.assertIn(f" {variable}:", application)
|
||||
for variable in (
|
||||
"KEYCLOAK_OTP_MOCK_CODE",
|
||||
"KEYCLOAK_YANDEX_CAPTCHA_SERVER_KEY",
|
||||
"KEYCLOAK_OTP_HMAC_KEY",
|
||||
"KEYCLOAK_SETTINGS_BRIDGE_TOKEN",
|
||||
"KEYCLOAK_SMS_SERVICE_TOKEN",
|
||||
):
|
||||
self.assertIn(f" {variable}_FILE:", application)
|
||||
self.assertIn(
|
||||
" KEYCLOAK_YANDEX_CAPTCHA_CLIENT_KEY: "
|
||||
"${KEYCLOAK_YANDEX_CAPTCHA_CLIENT_KEY:-}",
|
||||
application,
|
||||
)
|
||||
|
||||
def test_compose_secrets_do_not_enter_config_environment(self) -> None:
|
||||
compose_paths = (
|
||||
ROOT / "infra/compose/application.yml",
|
||||
ROOT / "redis/docker-compose.yml",
|
||||
ROOT / "observability/docker-compose.yml",
|
||||
ROOT / "deployment/docker-compose.jobs.yml",
|
||||
)
|
||||
combined = "\n".join(path.read_text(encoding="utf-8") for path in compose_paths)
|
||||
self.assertNotIn("env_file:", combined)
|
||||
for path in compose_paths:
|
||||
self.assertIn(
|
||||
"core: {soft: 0, hard: 0}",
|
||||
path.read_text(encoding="utf-8"),
|
||||
path,
|
||||
)
|
||||
for variable in (
|
||||
"DATABASE_URL",
|
||||
"REDIS_URL",
|
||||
"SMS_SERVICE_TOKEN",
|
||||
"KEYCLOAK_DB_PASSWORD",
|
||||
"OTEL_REMOTE_AUTH_HEADER",
|
||||
):
|
||||
self.assertNotIn(f"${{{variable}", combined)
|
||||
self.assertIn(
|
||||
"${HAN_SECRETS_DIR:-/run/han-chat/secrets}/DATABASE_URL", combined
|
||||
)
|
||||
self.assertNotIn("entrypoint: []", combined)
|
||||
|
||||
for service in (
|
||||
"api-backend",
|
||||
"sms-service",
|
||||
"message-safety",
|
||||
"bitrix-local-app",
|
||||
"bitrix-sync",
|
||||
"keycloak",
|
||||
):
|
||||
dockerfile = (ROOT / service / "Dockerfile").read_text(encoding="utf-8")
|
||||
self.assertIn("han-container-entrypoint", dockerfile, service)
|
||||
|
||||
def test_env_validator_accepts_materialized_example(self) -> None:
|
||||
example = (ROOT / ".env.example").read_text(encoding="utf-8")
|
||||
@@ -317,15 +371,10 @@ class InfrastructureConfigTests(unittest.TestCase):
|
||||
self.assertNotIn("currentSchema=", example)
|
||||
self.assertIn("KEYCLOAK_DB_SCHEMA=keycloak", example)
|
||||
self.assertIn("HAN_PG_PORT=5433", example)
|
||||
for required in (
|
||||
"CURSOR_HMAC_SECRET=",
|
||||
"BITRIX_TOKEN_ENCRYPTION_KEY=",
|
||||
"KEYCLOAK_INTERNAL_URL=http://keycloak:8080/auth",
|
||||
"KEYCLOAK_SMS_SERVICE_URL=http://sms-service:8080",
|
||||
"IDGTL_SMS_CALLBACK_PUBLIC_URL=https://chat.example.ru/callbacks/idgtl/sms",
|
||||
):
|
||||
self.assertIn(required, example)
|
||||
materialized = example.replace("change-me", "0123456789abcdef0123456789abcdef")
|
||||
self.assertIn("SECRETS_SOURCE=file", example)
|
||||
self.assertNotIn("CURSOR_HMAC_SECRET=", example)
|
||||
self.assertNotIn("BITRIX_TOKEN_ENCRYPTION_KEY=", example)
|
||||
materialized = example
|
||||
materialized = materialized.replace(
|
||||
"KEYCLOAK_OTP_MOCK_RISK_ACCEPTED=false",
|
||||
"KEYCLOAK_OTP_MOCK_RISK_ACCEPTED=true",
|
||||
@@ -341,11 +390,9 @@ class InfrastructureConfigTests(unittest.TestCase):
|
||||
)
|
||||
self.assertEqual(result.returncode, 0, result.stderr)
|
||||
|
||||
def test_env_validator_requires_captcha_keys_only_when_enabled(self) -> None:
|
||||
def test_env_validator_keeps_captcha_server_key_out_of_config(self) -> None:
|
||||
example = (ROOT / ".env.example").read_text(encoding="utf-8")
|
||||
materialized = example.replace(
|
||||
"change-me", "0123456789abcdef0123456789abcdef"
|
||||
).replace(
|
||||
"KEYCLOAK_OTP_MOCK_RISK_ACCEPTED=false",
|
||||
"KEYCLOAK_OTP_MOCK_RISK_ACCEPTED=true",
|
||||
)
|
||||
@@ -353,33 +400,17 @@ class InfrastructureConfigTests(unittest.TestCase):
|
||||
"KEYCLOAK_YANDEX_CAPTCHA_ENABLED=false",
|
||||
"KEYCLOAK_YANDEX_CAPTCHA_ENABLED=true",
|
||||
)
|
||||
enabled_with_keys = enabled_without_keys.replace(
|
||||
"KEYCLOAK_YANDEX_CAPTCHA_CLIENT_KEY=",
|
||||
"KEYCLOAK_YANDEX_CAPTCHA_CLIENT_KEY=client-key",
|
||||
).replace(
|
||||
"KEYCLOAK_YANDEX_CAPTCHA_SERVER_KEY=",
|
||||
"KEYCLOAK_YANDEX_CAPTCHA_SERVER_KEY=server-key-0123456789",
|
||||
)
|
||||
with tempfile.TemporaryDirectory() as directory:
|
||||
env_file = Path(directory) / ".env"
|
||||
env_file.write_text(enabled_without_keys, encoding="utf-8")
|
||||
missing = subprocess.run(
|
||||
result = subprocess.run(
|
||||
[sys.executable, str(ROOT / "scripts/validate-env"), str(env_file)],
|
||||
text=True,
|
||||
capture_output=True,
|
||||
check=False,
|
||||
)
|
||||
env_file.write_text(enabled_with_keys, encoding="utf-8")
|
||||
configured = subprocess.run(
|
||||
[sys.executable, str(ROOT / "scripts/validate-env"), str(env_file)],
|
||||
text=True,
|
||||
capture_output=True,
|
||||
check=False,
|
||||
)
|
||||
self.assertNotEqual(missing.returncode, 0)
|
||||
self.assertIn("KEYCLOAK_YANDEX_CAPTCHA_CLIENT_KEY", missing.stderr)
|
||||
self.assertIn("KEYCLOAK_YANDEX_CAPTCHA_SERVER_KEY", missing.stderr)
|
||||
self.assertEqual(configured.returncode, 0, configured.stderr)
|
||||
self.assertEqual(result.returncode, 0, result.stderr)
|
||||
self.assertNotIn("KEYCLOAK_YANDEX_CAPTCHA_SERVER_KEY=", example)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
Reference in New Issue
Block a user