Pulumi 是用於管理基礎設施即程式碼的強大工具,其跨不同語言的靈活性使其成為開發人員的熱門選擇。雖然 Pulumi 的 TypeScript 語法提供了一種乾淨、方便的方式來處理輸出和輸入,但將這些功能轉換為 Python 可能具有挑戰性。本文探討了在 TypeScript 中使用 pulumi.interpolate 的細微差別以及如何在 Python 中實現類似的功能。
在 Pulumi 的 TypeScript 語法中,有一種用於連接輸出的乾淨方法。它利用標記模板文字,這在 Python 中不可用。根據 Pulumi 參考文檔,插值與 concat 類似,但設計為用作標記模板表達式。例如:
// 'server' and 'loadBalancer' are both resources that expose [Output] properties. let val: Output<string> = pulumi.interpolate `http://${server.hostname}:${loadBalancer.port}`
與 concat 一樣,${} 之間的「佔位符」可以是任何輸入,即它們可以是 Promise、輸出或只是普通的 JavaScript 值。
我的大部分 Pulumi 工作都是在 TypeScript 中完成的,每當我需要將輸入傳遞到新資源時,我經常使用 pulumi.interpolate 標記模板文字。我沒有多想,就廣泛使用了它,而沒有將它與 pulumi.concat 或 apply 進行深入比較。然而,當我開始在 Python 中使用 Pulumi 並使用 pulumi.interpolate 時,我意識到它丟失了。
這促使我們更深入地了解輸出與輸入的含義以及如何翻譯:
pulumi.interpolate`http://${server.hostname}:${loadBalancer.port}`
致:
pulumi.concat('http://', server.hostname, ':', loadBalancer.port)
輸出是來自可能填充或將來將解析和填充的資源的值。由於輸出與其來源的資源相關聯,因此當將其作為輸入傳遞到 pulumi.interpolate 或 pulumi.concat 時,可以建立一條邊,然後用於建立另一個資源。由節點(資源)及其邊(輸出 -> 輸入)創建的資源之間的依賴關係圖允許 Pulumi 以正確的順序建立資源,並確保在圖中下一個資源需要時填充輸出。
輸入可以是原始值、承諾或輸出。如果資源的輸入是輸出,則您可以引用最初建立輸出的資源。輸入可以是輸出這一事實使其能夠追蹤其依賴關係。
這是它的型別定義:
type Input<T> = T | Promise<T> | OutputInstance<T>;
下面是我們如何僅將值(${} 之間的「佔位符」)大寫的範例,而不更改範本文字的文字字串部分:
function uppercaseValues(strings, ...values) { const result = []; strings.forEach((string, i) => { result.push(string); if (i < values.length) { result.push(values[i].toString().toUpperCase()); } }); return result.join(''); } const name = "Chris"; const hobby = "TypeScript"; console.log(uppercaseValues`Hello, my name is ${name} and I love ${hobby}.`); // Output: "Hello, my name is CHRIS and I love TYPESCRIPT."
在不知道確切的原始碼的情況下,從上面的範例展開,我們可以想像如何自己實作 pulumi.interpolate。它可能看起來像這樣:
function interpolate(strings, ...values) { const result = []; strings.forEach((string, i) => { result.push(string); if (i < values.length) { result.push(values[i]); } }); return pulumi.concat(...result); }
我們所做的就是用對 pulumi.concat 的呼叫取代最終的 join 呼叫。如果這是實現,我們將檢查是否需要從輸出類型中解包原始字串,而不是僅對佔位符進行操作,這才是真正的實現所做的。
它在 TypeScript 中的函數定義是:
function interpolate(literals: TemplateStringsArray, ...placeholders: Input<any>[]): Output<string>;
這與 concat 非常相似:
function concat(...params: Input<any>[]): Output<string>
當您意識到您實際上只是沿著輸出值轉發並將它們包裝在父輸出中時,靈光一現。
將 interpolate 移植到 concat 時,您可能會犯一些愚蠢的錯誤。讓我們用一個例子來示範。
在 TypeScript 中,我會這樣做:
function get_image_name(imageRegistry: Repository, name: string, version: Input<string>) { return pulumi.interpolate`${image_registry.repository_id}/${name}:${version}` }
當移植到Python時,我可能會得到這樣的結果:
def get_image_tag(image_registry: Repository, name: str, version: Input[str]): return pulumi.Output.concat( image_registry.repository_id, f"/{name}:{version}" )
但是,插值會單獨迭代每個佔位符以建立相依性並解析輸出。在我們的 Python 程式碼中,我們巧妙地失去了與版本參數的連結。我們需要手動分解輸出並將它們作為單獨的參數呈現給 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 中的工作方式。雖然 Python 不支援標記模板文字,但使用 pulumi.concat 有效地允許我們實現類似的功能。透過手動管理依賴項並確保正確處理所有輸出值,我們可以確保 Python 中的 Pulumi 程式碼與 TypeScript 中的一樣健壯和高效。
以上是Python 中的 Pulumi:翻譯內插的詳細內容。更多資訊請關注PHP中文網其他相關文章!