تعد Pulumi أداة قوية لإدارة البنية التحتية كرمز، كما أن مرونتها عبر اللغات المختلفة تجعلها خيارًا شائعًا بين المطورين. في حين أن بناء جملة TypeScript الخاص بـ Pulumi يوفر طريقة نظيفة ومريحة للتعامل مع المخرجات والمدخلات، فإن ترجمة هذه الميزات إلى Python قد يكون أمرًا صعبًا. تستكشف هذه المقالة الفروق الدقيقة في استخدام pulumi.interpolate في TypeScript وكيفية تحقيق وظيفة مماثلة في Python.
في بناء جملة TypeScript لـ Pulumi، هناك طريقة نظيفة لتسلسل المخرجات. إنه يستفيد من القيم الحرفية للنماذج ذات العلامات، والتي لا تتوفر في بايثون. وفقًا لمستندات Pulumi المرجعية، فإن الاستيفاء يشبه concat ولكنه مصمم ليتم استخدامه كتعبير قالب مميز. على سبيل المثال:
// 'server' and 'loadBalancer' are both resources that expose [Output] properties. let val: Output= pulumi.interpolate `http://${server.hostname}:${loadBalancer.port}`
كما هو الحال مع concat، يمكن أن تكون "العناصر النائبة" بين ${} أي مدخلات، أي يمكن أن تكون وعودًا أو مخرجات أو مجرد قيم JavaScript عادية.
بعد أن أنجزت معظم أعمالي في Pulumi باستخدام TypeScript، كنت كثيرًا ما أستخدم قالب pulumi.interpolate الموسوم حرفيًا كلما كنت بحاجة إلى تمرير إدخال إلى مورد جديد. دون التفكير كثيرًا في الأمر، استخدمته على نطاق واسع دون مقارنته بعمق بـ pulumi.concat أو تطبيقه. ومع ذلك، عندما بدأت العمل مع Pulumi في Python وتوصلت إلى pulumi.interpolate، أدركت أنه مفقود.
دفع هذا إلى التعمق أكثر في فهم ما يعنيه أن تكون مخرجًا مقابل مدخلاً وكيفية الترجمة:
pulumi.interpolate`http://${server.hostname}:${loadBalancer.port}`
ل:
pulumi.concat('http://', server.hostname, ':', loadBalancer.port)
المخرجات هي قيم من الموارد التي قد يتم ملؤها أو التي سيتم حلها وسيتم ملؤها في المستقبل. نظرًا لأن المخرجات مرتبطة بالمورد الذي تأتي منه، يمكن إنشاء حافة عند تمريرها كمدخل إلى pulumi.interpolate أو pulumi.concat، واستخدامها لاحقًا لإنشاء مورد آخر. يسمح الرسم البياني للتبعية بين الموارد، الذي تم إنشاؤه بواسطة العقد (الموارد) وحوافها (الإخراج -> الإدخال)، لبولومي بإنشاء الموارد بالترتيب الصحيح ويضمن ملء المخرجات عند الحاجة بواسطة المورد التالي في الرسم البياني.
يمكن أن يكون الإدخال قيمة أولية أو وعدًا أو مخرجًا. إذا كان أحد المدخلات إلى أحد الموارد عبارة عن مخرجات، فسيكون لديك مرجع إلى المورد الذي تم إنشاء المخرجات فيه في الأصل. حقيقة أن المدخلات يمكن أن تكون مخرجات تمكنها من تتبع تبعياتها.
إليك تعريف نوعه:
type Input= T | Promise | OutputInstance ;
إليك مثال لكيفية كتابة القيم الكبيرة فقط ("العناصر النائبة" بين ${})، دون تغيير جزء السلسلة الحرفية من القالب الحرفي:
function uppercaseValues(strings, ...values) { const result = []; strings.forEach((string, i) => { result.push(string); if (iتنفيذ pulumi.interpolate
بدون معرفة كود المصدر الدقيق، والتوسع في المثال أعلاه، يمكننا أن نتخيل كيفية تنفيذ pulumi.interpolate بمفردنا. قد يبدو الأمر كالتالي:
function interpolate(strings, ...values) { const result = []; strings.forEach((string, i) => { result.push(string); if (iكل ما فعلناه هو استبدال مكالمة الانضمام النهائية بمكالمة إلى pulumi.concat. إذا كان هذا هو التنفيذ، فسنقوم بإجراء فحوصات حول ما إذا كانت السلاسل الأولية بحاجة إلى إلغاء تغليفها من أنواع المخرجات، بدلاً من العمل فقط على العناصر النائبة، وهو ما يفعله التنفيذ الحقيقي.
تعريف وظيفتها في TypeScript هو:
function interpolate(literals: TemplateStringsArray, ...placeholders: Input[]): Output ; وهو مشابه جدًا لـ concat:
function concat(...params: Input[]): Output تأتي لحظة المصباح عندما تدرك أنك تقوم فقط بإعادة التوجيه عبر قيم المخرجات وتغليفها في المخرجات الأصلية.
العودة إلى بايثون
يمكنك ارتكاب بعض الأخطاء السخيفة عند نقل الاستيفاء إلى concat. دعونا نوضح بمثال.
في TypeScript، كنت سأفعل هذا:
function get_image_name(imageRegistry: Repository, name: string, version: Input) { return pulumi.interpolate`${image_registry.repository_id}/${name}:${version}` } عند النقل إلى بايثون، قد ينتهي بي الأمر بهذا:
def get_image_tag(image_registry: Repository, name: str, version: Input[str]): return pulumi.Output.concat( image_registry.repository_id, f"/{name}:{version}" )ومع ذلك، كان الاستيفاء يتكرر على كل عنصر نائب بشكل فردي لإنشاء التبعيات وحل المخرجات. باستخدام كود بايثون الخاص بنا، فقدنا هذا الاتصال مع وسيطة الإصدار. نحتاج إلى تقسيم مخرجاتنا يدويًا وإظهارها كوسيطات فردية لـ pulumi.Output.concat.
سيبدو الكود المصحح كما يلي:
def get_image_tag(image_registry: Repository, name: str, version: Input[str]): return pulumi.Output.concat( image_registry.repository_id, f"/{name}:", version )الآن، سيتم تضمين الإصدار بشكل صحيح في الرسم البياني للتبعية، وسنكون خاليين من الأخطاء!
خاتمة
تتطلب ترجمة pulumi.interpolate من TypeScript إلى Python فهمًا أعمق لكيفية عمل المخرجات والمدخلات في Pulumi. على الرغم من أن بايثون لا تدعم القيم الحرفية للنماذج ذات العلامات، فإن استخدام pulumi.concat يتيح لنا بشكل فعال تحقيق وظائف مماثلة. من خلال إدارة التبعيات يدويًا والتأكد من التعامل مع جميع قيم المخرجات بشكل صحيح، يمكننا التأكد من أن كود Pulumi الخاص بنا في Python قوي وفعال تمامًا كما هو الحال في TypeScript.
تنصل: جميع الموارد المقدمة هي جزئيًا من الإنترنت. إذا كان هناك أي انتهاك لحقوق الطبع والنشر الخاصة بك أو الحقوق والمصالح الأخرى، فيرجى توضيح الأسباب التفصيلية وتقديم دليل على حقوق الطبع والنشر أو الحقوق والمصالح ثم إرسالها إلى البريد الإلكتروني: [email protected]. سوف نتعامل مع الأمر لك في أقرب وقت ممكن.
Copyright© 2022 湘ICP备2022001581号-3