إنتقل إلى المحتوى الرئيسي

تكوين Cockpit (appsettings)

يُكوّن مضيف Cockpit من خلال appsettings.json (DUOKEY.ADMIN.Web.Host/appsettings.json). تصف هذه الصفحة الإعدادات التي تحتاج إلى تعبئتها لنشر محلي.

لا تودع الأسرار الحقيقية أبدًا في المستودع

جميع القيم المعروضة هنا قيم نائبة. يجب ألا تُرمّز الأسرار (سلاسل الاتصال، ورموز الترخيص، وأسرار API، وأسرار العميل، والرموز المميزة) بشكل ثابت أو تُودع في Git أبدًا. في النشر المرجعي، تحمل هذه القيم العلامة الحارسة set_as_keyvault_secret وتُحلّ وقت التشغيل من مخزن الأسرار الخاص بك — راجع مصدر الأسرار أدناه و تكامل مدير الأسرار.

كيفية تطبيقه — مخزّن في OpenBao، مُحقن عند النشر

يُخزّن ملف appsettings.json الخاص بـ Cockpit في OpenBao (محرك الأسرار الخاص بك) ويُحقن عند وقت النشر — لا يُدمج أبدًا في الصورة ولا يُودع أبدًا في Git. عند النشر، يُجسّد مشغّل الأسرار الخارجية الملف من OpenBao إلى Kubernetes Secret في الذاكرة (tmpfs)، والذي يُركّب كملف appsettings.json في حاوية Cockpit. حدّث القيمة في OpenBao وأعد النشر لطرح تغيير في التكوين. راجع مصدر الأسرار.


مصدر الأسرار​

محليًا، يُحفظ ملف appsettings.json بالكامل في OpenBao ويُحقن عند النشر، بحيث تعيش قيم الأسرار فقط في محرك الأسرار الخاص بك.

كيف يعمل:

  1. يُخزّن ملف appsettings.json الكامل الخاص بالبيئة (مع قيم الأسرار الحقيقية مكان كل قيمة نائبة set_as_keyvault_secret) كسر في OpenBao.
  2. عند النشر، يجلبه مشغّل الأسرار الخارجية ويجسّد Kubernetes Secret في الذاكرة (tmpfs).
  3. يُركّب ذلك السر كملف appsettings.json في حاوية Cockpit.
  4. لتغيير التكوين: حدّث القيمة في OpenBao وأعد النشر — لا يُحرّر أي شيء داخل الصورة أو يُخزّن في Git.
Azure Key Vault غير مطلوب محليًا

يمكن أيضًا للبناء المرجعي حلّ الأسرار من 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 + السجل

يحتاج تدفق التوفير هذا إلى مستودع 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