Pulumi — это мощный инструмент для управления инфраструктурой как кодом, а его гибкость в работе с разными языками делает его популярным выбором среди разработчиков. Хотя синтаксис TypeScript от Pulumi предлагает чистый и удобный способ обработки выходных и входных данных, перевод этих функций на Python может оказаться сложной задачей. В этой статье рассматриваются нюансы использования pulumi.interpolate в TypeScript и способы достижения аналогичной функциональности в Python.
В синтаксисе TypeScript Pulumi существует простой подход к объединению выходных данных. Он использует тегированные литералы шаблонов, которые недоступны в Python. Согласно справочной документации 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 или apply. Однако, когда я начал работать с Pulumi в Python и обратился к pulumi.interpolate, я понял, что его нет.
Это побудило глубже погрузиться в понимание того, что значит быть выходом по сравнению с входом и как это перевести:
pulumi.interpolate`http://${server.hostname}:${loadBalancer.port}`
к:
pulumi.concat('http://', server.hostname, ':', loadBalancer.port)
Выходные данные — это значения из ресурсов, которые могут быть заполнены или будут разрешены и заполнены в будущем. Поскольку выход связан с ресурсом, из которого он получен, ребро может быть создано, когда оно передается в качестве входных данных в pulumi.interpolate или pulumi.concat, а затем используется для создания другого ресурса. Граф зависимостей между ресурсами, созданный узлами (ресурсами) и их ребрами (Выход -> Вход), позволяет Pulumi создавать ресурсы в правильном порядке и гарантирует, что выходы заполняются при необходимости следующим ресурсом в графе.
Ввод может быть необработанным значением, обещанием или результатом. Если вход для ресурса является выходом, то у вас есть ссылка на ресурс, где изначально был создан выход. Тот факт, что вход может быть выходом, позволяет отслеживать его зависимости.
Вот определение типа:
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 Момент лампочки наступает, когда вы понимаете, что на самом деле вы просто пересылаете выходные значения и оборачиваете их в родительские выходные данные.
Вернемся к Питону
Вы можете допустить несколько глупых ошибок при переносе интерполяции в конкат. Давайте продемонстрируем на примере.
В TypeScript я бы сделал это:
function get_image_name(imageRegistry: Repository, name: string, version: Input) { 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 эффективно позволяет нам добиться аналогичной функциональности. Управляя зависимостями вручную и обеспечивая правильную обработку всех выходных значений, мы можем гарантировать, что наш код Pulumi на Python будет таким же надежным и эффективным, как и в TypeScript.
Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.
Copyright© 2022 湘ICP备2022001581号-3