تكوين Cockpit (appsettings)
يُكوّن مضيف Cockpit من خلال appsettings.json
(DUOKEY.ADMIN.Web.Host/appsettings.json). تصف هذه الصفحة الإعدادات التي تحتاج
إلى تعبئتها لنشر محلي.
جميع القيم المعروضة هنا قيم نائبة. يجب ألا تُرمّز الأسرار (سلاسل الاتصال،
ورموز الترخيص، وأسرار API، وأسرار العميل، والرموز المميزة) بشكل ثابت أو تُودع في Git
أبدًا. في النشر المرجعي، تحمل هذه القيم العلامة الحارسة set_as_keyvault_secret
وتُحلّ وقت التشغيل من مخزن الأسرار الخاص بك — راجع
مصدر الأسرار أدناه و
تكامل مدير الأسرار.
يُخزّن ملف appsettings.json الخاص بـ Cockpit في OpenBao (محرك الأسرار
الخاص بك) ويُحقن عند وقت النشر — لا يُدمج أبدًا في الصورة ولا يُودع أبدًا في
Git. عند النشر، يُجسّد مشغّل الأسرار الخارجية الملف من OpenBao إلى Kubernetes Secret
في الذاكرة (tmpfs)، والذي يُركّب كملف appsettings.json في حاوية Cockpit.
حدّث القيمة في OpenBao وأعد النشر لطرح تغيير في التكوين. راجع
مصدر الأسرار.
مصدر الأسرار
محليًا، يُحفظ ملف appsettings.json بالكامل في OpenBao ويُحقن عند النشر،
بحيث تعيش قيم الأسرار فقط في محرك الأسرار الخاص بك.
كيف يعمل:
- يُخزّن ملف
appsettings.jsonالكامل الخاص بالبيئة (مع قيم الأسرار الحقيقية مكان كل قيمة نائبةset_as_keyvault_secret) كسر في OpenBao. - عند النشر، يجلبه مشغّل الأسرار الخارجية ويجسّد Kubernetes Secret في الذاكرة
(
tmpfs). - يُركّب ذلك السر كملف
appsettings.jsonفي حاوية Cockpit. - لتغيير التكوين: حدّث القيمة في OpenBao وأعد النشر — لا يُحرّر أي شيء داخل الصورة أو يُخزّن في Git.
يمكن أيضًا للبناء المرجعي حلّ الأسرار من Azure Key Vault
(Configuration:AzureKeyVault) لعمليات النشر المتصلة/السحابية. للنشر المحلي،
اتركه معطّلًا — OpenBao هو مصدر الحقيقة.
"Configuration": { "AzureKeyVault": { "IsEnabled": "false" } }
1. قاعدة البيانات
اختر الموفّر وسلسلة الاتصال. راجع موفّر قاعدة البيانات المزدوج للتفاصيل.
{
"ConnectionStrings": {
"Default": "set_as_keyvault_secret"
},
"DatabaseProvider": "PostgreSQL"
}
DatabaseProvider:"SqlServer"(افتراضي) أو"PostgreSQL".- تعتمد صيغة سلسلة الاتصال على الموفّر (الأمثلة أدناه).
2. ذاكرة التخزين المؤقت Redis
"Abp": {
"RedisCache": {
"ConnectionString": "<redis-host>:6379",
"DatabaseId": -1
}
}
وجّه هذا إلى خدمة Redis داخل المجموعة أو إلى أجهزة Redis الافتراضية.
3. عناوين URL للتطبيق وCORS
اضبط هذه على أسماء المضيفين الخاصة بك (راجع سجلات DNS).
"App": {
"ServerRootAddress": "https://cockpit-api.example.com/",
"ClientRootAddress": "https://cockpit.example.com/",
"CorsOrigins": "https://cockpit.example.com",
"SwaggerEndPoint": "/swagger/v1/swagger.json",
"HomePageUrl": "/index.html"
}
ServerRootAddress/ClientRootAddress: عناوين URL الأساسية لواجهة API وواجهة المستخدم.CorsOrigins: قائمة بالأصول المسموح بها مفصولة بفواصل — احتفظ بها محكمة.
4. المصادقة وSSO
فعّل الموفّرين الذين تستخدمهم ووجّههم إلى موفّر الهوية (IdP) الخاص بك. الإرشادات الكاملة في الهوية وSSO والتحكم في الوصول.
"Authentication": {
"OpenId": {
"IsEnabled": "true",
"ClientId": "<entra-app-client-id>",
"Authority": "https://login.microsoftonline.com/<entra-tenant-id>/v2.0",
"LoginUrl": "https://login.microsoftonline.com/<entra-tenant-id>/oauth2/v2.0/authorize",
"TokenEndpoint": "https://login.microsoftonline.com/<entra-tenant-id>/oauth2/v2.0/token",
"ValidateIssuer": "true",
"ResponseType": "id_token",
"ClaimsMapping": [
{ "claim": "unique_name", "key": "preferred_username" }
]
},
"Okta": {
"IsEnabled": "false",
"ClientId": "set_as_keyvault_secret",
"ClientSecret": "set_as_keyvault_secret",
"Authority": "https://<your-org>.okta.com",
"ValidateIssuer": "true"
},
"JwtBearer": {
"IsEnabled": "true",
"SecurityKey": "set_as_keyvault_secret",
"Issuer": "ADMIN",
"Audience": "ADMIN"
}
}
تسجيلات الدخول الاجتماعية (Facebook، Twitter، Google، Microsoft للمستهلكين) معطّلة افتراضيًا — اتركها مطفأة ما لم تكن مطلوبة.
5. IdentityServer
"IdentityServer": {
"IsEnabled": "true",
"Authority": "https://cockpit-api.example.com/",
"ApiName": "default-api",
"ApiSecret": "set_as_keyvault_secret",
"AccessTokenExpirationDays": 1,
"RefreshTokenExpirationDays": 365
}
تُوفّر شهادة توقيع IdentityServer بشكل منفصل:
"IdentityServerCert": {
"Password": "set_as_keyvault_secret",
"Path": "/var/ssl/certs/",
"Name": "certificate.pfx"
}
6. HSM — Securosys CloudsHSM
لعهدة المفاتيح المدعومة بالأجهزة، كوّن تكامل Securosys CloudsHSM (راجع تكامل مدير الأسرار):
"SecurosysCloudsHSM": {
"HostName": "https://<securosys-host>/v1/key/{0}/export/plain",
"TLSClientCert": "set_as_keyvault_secret",
"TLSClientPrivateKey": "set_as_keyvault_secret",
"AzureADCredentials": {
"ClientId": "set_as_keyvault_secret",
"ClientSecret": "set_as_keyvault_secret",
"TenantId": "set_as_keyvault_secret"
}
}
7. التسجيل / SIEM
أعد توجيه السجلات إلى SIEM الخاص بك (راجع الامتثال والتدقيق). يشحن البناء المرجعي مصرف Splunk HEC:
"SplunkLogSetting": {
"Token": "set_as_keyvault_secret",
"Url": "https://<your-splunk-host>:8088/services/collector"
}
8. DKE 365 — Microsoft Graph
لتكامل DKE 365، وفّر تسجيل تطبيق Microsoft Graph:
"AzureGraphAppSettings": {
"ClientId": "set_as_keyvault_secret",
"ClientSecret": "set_as_keyvault_secret",
"TenantId": "set_as_keyvault_secret"
}
راجع استكشاف أخطاء DKE وإصلاحها لفحوصات نقطة نهاية المفتاح وEntra ID ذات الصلة.
9. HTTPS وتحديد المعدل
"HttpsRedirection": {
"IsEnabled": true,
"HttpsPort": 443,
"RedirectStatusCode": 301
},
"IpRateLimiting": {
"EnableEndpointRateLimiting": true,
"GeneralRules": [
{ "Endpoint": "*", "Period": "10s", "Limit": 10 },
{ "Endpoint": "*", "Period": "10m", "Limit": 100 }
]
}
10. توفير خدمة GitOps (GitLab ← ArgoCD ← Helm)
بالإضافة إلى استضافة تكوينه الخاص، يعمل Cockpit كـ مستوى تحكم لمثيلات خدمة DuoKey (DKE 365، AWS XKS، Genesys LKM، Pass-Kit). عندما ينشئ المسؤول خدمة أو يحدّثها من Cockpit، فإنه لا ينشر مباشرة — بل يودع قيم Helm الخاصة بالخدمة وبيان تطبيق ArgoCD في مستودع GitLab. يراقب ArgoCD ذلك المستودع باستمرار وينشر أو يحدّث الخدمة تلقائيًا إلى المجموعة عبر مخطط Helm الخاص بها.
هذا هو نفس نموذج GitOps المستخدم للمنصة نفسها (التثبيت ← تمهيد GitOps): يصبح توفير الخدمة تصريحيًا، ومُصدرًا، وقابلًا للتدقيق — كل مثيل خدمة هو إيداع Git، يُنشر بواسطة ArgoCD عبر Helm.
الإعدادات ذات الصلة (منقّحة)
GitlabClientRepository — كيفية تواصل Cockpit مع GitLab وArgoCD:
"GitlabClientRepository": {
"ApiHostUrl": "https://<gitlab-host>/api/v4/",
"Url": "https://<gitlab-host>/<group>/",
"ProjectID": "set_as_keyvault_secret",
"Branch": "staging",
"PatToken": "set_as_keyvault_secret",
"ArgoToken": "set_as_keyvault_secret",
"DKEAppURL": "https://<argocd-host>/api/v1/applications/{0}?cascade=true&propagationPolicy=Foreground",
"DKEDomain": "https://{app.Externalid}.<service-domain>"
}
GitlabAppYMLFile / GitLabYAMLAppFolder — قالب تطبيق ArgoCD ومسارات التطبيقات
لكل خدمة:
"GitlabAppYMLFile": {
"RepoURL": "git@<gitlab-host>:<group>/dke-devops.git",
"TargetRevision": "staging",
"Server": "https://kubernetes.default.svc",
"Namespace": "default",
"Project": "default"
}
GitLabYAMLValuesFolder — مسارات قيم مخطط Helm ومستودعات الصور لكل خدمة:
"GitLabYAMLValuesFolder": {
"DKEDockerRepoURL": "<registry-host>/dke-apps-dke365/dke-apps-dke365:<tag>",
"DKE365RootPath": "dke365-service/chart/values"
}
للنشر المحلي
وجّه هذه إلى بيئتك:
- GitLab (
<gitlab-host>، المجموعة، مستودعdke-devops) — GitLab ذاتي الاستضافة، أو GitLab SaaS حيث تسمح السياسة. - ArgoCD (
<argocd-host>) — مثيل OpenShift GitOps داخل المجموعة. - السجل (
<registry-host>) — Harbor / المرآة الخاصة بك (راجع صور الحاويات). - الرموز المميزة (
PatToken،ArgoToken،ProjectID) — مخزّنة في OpenBao، مُحقنة عند النشر.
يحتاج تدفق التوفير هذا إلى مستودع GitLab يمكن الوصول إليه، ومثيل ArgoCD، وسجل صور. في موقع معزول عن الشبكة (air-gapped)، تعمل الثلاثة جميعها محليًا. يوفّر ممثل DuoKey هيكل المستودع والرموز المميزة أثناء الإعداد الأولي.
الكتل الأخرى في ملف appsettings.json المرجعي اختيارية أو خاصة بسيناريو معيّن:
موفّرو الدفع (Payment)، وTwilio، وRecaptcha، وأي PkiIssuerEnvironments
خاصة بالعميل. اتركها عند قيمها الافتراضية / معطّلة ما لم تكن مطلوبة — يؤكد ممثل
DuoKey أيها ينطبق عليك.
موفّر قاعدة البيانات المزدوج
يدعم التطبيق SQL Server وPostgreSQL، ويُختار عبر
DatabaseProvider.
أمثلة سلسلة الاتصال
SQL Server
{
"ConnectionStrings": {
"Default": "Server=<host>;Database=ADMINDb;Trusted_Connection=True;TrustServerCertificate=True;"
},
"DatabaseProvider": "SqlServer"
}
PostgreSQL
{
"ConnectionStrings": {
"Default": "User ID=postgres;Password=<password>;Host=<host>;Port=5432;Database=ADMINDb;Pooling=true;"
},
"DatabaseProvider": "PostgreSQL"
}
السلوك الخاص بالموفّر
- PostgreSQL: يضبط تلقائيًا
Npgsql.DisableDateTimeInfinityConversionsعلىtrue؛ وتُعالج حدود طول السلاسل تلقائيًا (بحد أقصى 10 ميغابايت). جميع الوظائف متطابقة. - SQL Server: لا تغييرات سلوكية؛ توافق كامل مع الإصدارات السابقة.
تشغيل عمليات الترحيل
تُطبّق عمليات الترحيل بواسطة Migrator على قاعدة البيانات المستهدفة. يُقرأ الموفّر وسلسلة الاتصال من نفس التكوين.
cd src/DUOKEY.ADMIN.Migrator
dotnet run
في نشر محلي محوّى، شغّل Migrator كـ Job أحادي التشغيل (أو حاوية تهيئة) موجّهًا إلى قاعدة بياناتك قبل بدء تشغيل مضيف Cockpit.
تأليف نصوص ترحيل جديدة هو عملية تطوير داخلية لدى DuoKey وليست مطلوبة لتشغيل نشر محلي — أنت فقط تشغّل Migrator.
استراتيجية الترحيل للعملاء الحاليين
- عملاء SQL Server: لا إجراء مطلوب — SQL Server هو الافتراضي وتستمر التكوينات الحالية في العمل دون أي توقف.
- PostgreSQL: اضبط
"DatabaseProvider": "PostgreSQL"، ووجّه سلسلة الاتصال إلى مثيل PostgreSQL الخاص بك، وشغّل Migrator، وتحقق من الوظائف.
استكشاف الأخطاء وإصلاحها
| العرَض | السبب | الحل |
|---|---|---|
| لا يبدأ التطبيق، خطأ في قاعدة البيانات | موفّر أو سلسلة اتصال خاطئة | تحقق من أن DatabaseProvider يطابق صيغة سلسلة الاتصال |
| حلقة إعادة توجيه المصادقة / 401 | عدم تطابق سلطة/عميل موفّر الهوية | أعد فحص سلطة Authentication:OpenId، ومعرّف العميل، وValidateIssuer |
قيمة السر حرفيًا set_as_keyvault_secret | مخزن الأسرار غير موصول | تأكد من أن OpenBao/ESO (أو Key Vault) يحقن القيمة وقت التشغيل |
| أخطاء CORS في واجهة المستخدم | الأصل غير مسموح به | أضف أصل واجهة المستخدم إلى App:CorsOrigins |
| أخطاء الترحيل | قاعدة البيانات المستهدفة مفقودة/غير قابلة للوصول | تأكد من وجود قاعدة البيانات وإمكانية الوصول إليها من Migrator |