التعامل مع JSON وYAML وملفات الإعداد
التعامل مع JSON وYAML وملفات الإعداد
تعتمد سكريبتات DevOps في نجاحها أو فشلها على قدرتها في قراءة البيانات المهيكلة والتحقق منها وإصدارها. مانيفستات Kubernetes، ومتغيرات Terraform، وتعريفات خطوط CI، وأعلام الميزات، ومخزون Ansible — كلها YAML أو JSON. إتقان التعامل مع هذه الصيغ، بما في ذلك أوضاع الفشل في الإنتاج، هو ما يميّز المهندس الموثوق عمّن تُفسد سكريبته إعداد الإنتاج بصمت.
JSON: لغة API العالمية
وحدة json في Python جزء من المكتبة القياسية وتغطي 95٪ من عمل JSON الفعلي. العمليات الأساسية: json.loads() (نص إلى dict)، وjson.dumps() (dict إلى نص)، وjson.load() (مقبض ملف إلى dict)، وjson.dump() (dict إلى مقبض ملف).
rename() أو Path.replace() في Python. على Linux، إعادة التسمية في نفس نظام الملفات عملية ذرية على مستوى النواة.YAML: صيغة إعداد المكدس السحابي الأصلي
YAML ليست في المكتبة القياسية. الاختيار الإنتاجي هو PyYAML (اسم الاستيراد yaml). استخدم دائمًا yaml.safe_load() — لا تستخدم أبدًا yaml.load() بدون وسيط Loader صريح، لأن المُحمِّل الافتراضي قادر على تنفيذ كود Python عشوائي مضمّن في ملف YAML، وهو ثغرة تنفيذ تعليمات برمجية عن بُعد خطيرة.
sort_keys=False إلى yaml.dump(). Kubernetes وHelm لا يشترطان ترتيبًا معينًا، لكن المهندسين يتوقعون أن يأتي apiVersion قبل spec. الترتيب الأبجدي يجعل مقارنات الفروق (diffs) مزعجة ومراجعات الكود أصعب.مشكلة النرويج في YAML وأخطاء شائعة أخرى
لدى YAML عدة مفاجآت تحليلية أسببت في أعطال إنتاجية فعلية. أشهرها مشكلة النرويج: يحلّل YAML 1.1 (الذي لا يزال PyYAML يستخدمه افتراضيًا) الكلمة المجردة NO كقيمة منطقية False. رموز الدول في مخزون Ansible قد تتحول صامتة إلى False. أحِط دائمًا النصوص التي تشبه القيم المنطقية أو null بعلامات اقتباس: "NO"، "yes"، "null"، "true"، "on".
مصائد أخرى: مفتاح العدد الصحيح المجرد (123: value) يصبح مفتاح Python من نوع int لا نصًا، مما يُفشل البحث dict["123"]. والأعداد الثمانية (0777) تُحلَّل كأعداد صحيحة. والتواريخ (2024-01-15) تصبح كائنات datetime.date في Python.
التحقق من الإعداد باستخدام jsonschema وPydantic
تحليل ملف YAML بدون التحقق منه يعني أن السكريبت سيفشل لاحقًا بخطأ KeyError أو TypeError مبهم في عمق منطق الأعمال. تحقق عند الحدود — مباشرة بعد التحميل وقبل أي معالجة. خياران يهيمنان في شركات التقنية الكبرى:
- jsonschema — يُحقق من أي dict مقابل تعريف JSON Schema؛ يعمل لبيانات JSON وYAML معًا؛ تبعية خفيفة الوزن.
- Pydantic v2 — يُعرّف النماذج كفئات Python؛ يمنحك سمات مكتوبة وقيمًا افتراضية ورسائل خطأ غنية؛ مفضل للإعدادات المعقدة وعندما تحتاج إلى إكمال تلقائي في IDE.
container > port) ورسالة مقروءة. أرسل هذه الرسالة إلى نظام التسجيل لديك قبل الخروج.الإعداد المبني على متغيرات البيئة: منهجية Twelve-Factor
خدمات الإنتاج لا ينبغي أن تقرأ الأسرار من ملفات YAML مُدرجة في git. نمط Twelve-Factor App يخزن بيانات الاعتماد وعناوين URL لقواعد البيانات ومفاتيح API في متغيرات البيئة، ويقرأ ملفات الإعداد فقط للإعدادات غير السرية القابلة للإصدار. os.environ في Python وحزمة python-dotenv تتولى هذا بشكل نظيف.
os.environ["KEY"] (لا .get()) للأسرار المطلوبة. إذا كان متغير مطلوب غائبًا، تريد KeyError صاخبًا عند بدء التشغيل، لا نصًا فارغًا صامتًا يتسبب في فشل مصادقة غامض بعد 200 طلب. احتفظ بـ.get("KEY", default) للإعدادات الاختيارية فعلًا.TOML: صيغة الإعداد الخاصة بنظام Python
منذ Python 3.11، أصبحت tomllib في المكتبة القياسية (للقراءة فقط). وهي صيغة pyproject.toml ويُستخدم بصورة متزايدة لإعدادات الأدوات. إذا كنت بحاجة للكتابة بتنسيق TOML، ثبّت tomli-w.
إطار القرار الكامل: استخدم JSON عند التواصل مع APIs أو الآلات؛ استخدم YAML لـKubernetes وAnsible وخطوط CI (بشر + آلات)؛ استخدم TOML لبيانات مشاريع Python وإعدادات الأدوات؛ استخدم متغيرات البيئة للأسرار والتجاوزات أثناء التشغيل.