sandzhaj.space

Меню
  • главная
  • cтатьи
  • книги
  • про автора
Меню

Зачем DevOps’у ООП с его классами и прочим

Опубликовано в 29.03.202329.03.2023 от sandzhaj

Долгое время после изучения основ python меня мучало два вопроса:

  • ЗАЧЕМ мне вообще нужны классы при написании скриптов?
  • КАК мне использовать фишки ООП при написании скриптов?

Решая небольшие задачи и правда очень сложно найти им применение.

Сейчас же я до сих пор не отрицаю, что любую задачу можно решить скриптом-одностраничником не используя всех доступных нам возможностей, однако такие скрипты будет очень сложно сопровождать не только левому человеку, но и Вам. Даже сам процесс написания такого кода может вызывать боль.

И тут уже совершенно не важно, это скрипт «на один раз» или полноценная cli утилита для множественного использования.

В этой статье я не буду скатываться к объяснению, почему нам нужно разбивать код на функции, разносить по файлам и прочее. Это уже как-то без меня.

Я приведу лишь 1 частный пример использования классов, так как именно они у меня вызывали недопонимание — как применять к своей сфере. Возможно, этот пример может послужить толчком для таких же как и я.

Кейс

У вас есть много проектов, которые вы сопровождаете. Для каждого проекта у вас есть часть yaml файлов в одном репозитории и часть в другом.
Вам нужно проанализировать содержимое из первого репозитория и переделать второй, добавив много информации из первого. По сути, мы пишем конвертер, преобразующий данные в нужный вид.

Более детальное описание

Предположим, у вас есть:

  • Репозитории с микросервисами, в которых каждый микросервис имеет свой Openshift шаблон, включающий DeploymentConfig, Route, Service и различные Istio операторы.
  • Репозиторий с Inventory, где для разных стендов вы храните ConfigMaps и Secrets для каждого приложения.

Однажды вы решаете перенести все свои проекты на Helm. Это позволит вам параметризировать различные сущности и добавить опции. Например, указав в Inventory «istio: false», вы можете отключить Istio одной строкой, вместо редактирования каждого Openshift шаблона.

Пусть вы уже создали Helm чарты, учитывающие различия ваших шаблонов. Теперь ваша задача — анализировать шаблон каждого сервиса с его спецификой, объектами и переделать инвентарь, добавив Helm параметры для каждого сервиса так, чтобы при деплое ничего не изменилось.

Реализация

Как раз для анализа и хранении информации о файле мы можем воспользоваться датаклассом.

Если кратко о разнице с обычными классами:

  1. Синтаксис: Датаклассы используют декоратор @dataclass, введенный в Python 3.7, для определения класса, в то время как обычные классы определяются ключевым словом class.
  2. Автоматическая генерация методов: Датаклассы автоматически генерируют ряд методов, таких как __init__, __repr__, __eq__ и т. д., основанных на аннотациях полей. В обычных классах эти методы нужно определять вручную.
  3. Наследование: Обычные классы поддерживают наследование, тогда как датаклассы не наследуются. Однако, датаклассы могут использовать наследование атрибутов, определенных в обычных классах.
  4. Назначение: Датаклассы предназначены для хранения данных, тогда как обычные классы могут выполнять любые задачи.

Создаем датакласс Template.py

from dataclasses import dataclass

@dataclass  
class Template:  
    file: str = None  
    appName: str = None  
    containerPort: str = None  
    jaegerEnabled: bool = None  
    host: str = None  
    path: str = None  
    # и прочие атрибуты которые мы хотим выяснить в ходе нашего анализа  
  
    def __post_init__(self):  
        self.parse()  
  
    def parse(self) -> None:
	with open(self.file) as tmpl:  
	    content = yaml.load(tmpl)
        for param in content["parameters"]:  
            if param["name"] == "APP_PORT":  
                self.containerPort = param["value"]  
            if param["name"] == "APP_NAME":  
                self.appName = param["value"]  
  
        for obj in content["objects"]:  
            self.objects.append(obj["kind"])  
            if obj["kind"] == "DeploymentConfig":   
                # JAEGER  
                for container in obj["spec"]["template"]["spec"]["containers"]:  
                    self.jaegerEnabled = "jaeger" in container["image"]  
                    if self.jaegerEnabled:  
                        break        
                for container in obj["spec"]["template"]["spec"]["containers"]:  
                    if container['name'] == self.appName:  
		    if obj["kind"] == "Route":  
                self.path = obj["spec"]["path"]  
                self.host = obj["spec"]["host"]
            # и так далее

В атрибутах датакласса мы описываем все атрибуты, которыми характерезуется наш анализируемый файл. Имя пода, порт приложения, адрес хоста, включен ли истио в этом шаблоне, подключены ли ConfigMaps и Secrets.

Далее создаем внутри датакласса функцию parse, где мы считываем yaml файл переданный при инициализации класса, и достаем из него всю нужную информацию, обновляя наши атрибуты.

Осталось лишь добавить нашу функцию parse в метод __post_init__ чтобы функция автоматически запустилась после инициализации.

Использование

Теперь, проходясь по нашим yaml файлам, мы можем сделать из них объекты с проанализированной информацией и сразу воспользоваться ей. Или, как в примере ниже — сохранить и воспользоваться потом:

data = {}
for filepath in что_угодно:
	data[filepath] = Template(file=filepath)

print(data['myapp.yaml'].jaegerEnabled)

Теперь мы можем использовать наши данные для любых целей, например для заполнения jija шаблонов и прочего.

Итог

Если попробовать ответить на вопрос «ЗАЧЕМ?», ведь с одной стороны можно было бы использовать сложные и гигатские массивы. Хотя бы просто для того, что использование хотя бы датаклассов дает вам возможность куда проще отлаживать и сопровождать код.

Это повышает читаемость, и когда в ходе разработки вам понадобится что-то изменить в «анализирующем» механизме, скорее всего вам будет сложнее в этом заблудится и вы потратите меньше времени.

А на вопрос — «КАК?» я уже ответил. 🙂

  • python
  • автоматизация
  • ооп
  • Поиск

    Подпишись

    Теги

    bash git helm python zsh автоматизация нейросеть ооп терминал трекинг

    ©2025 sandzhaj.space