Хабрахабр

Автоматизация задач администрирования API VMware vSphere с использованием Python

image

В ней живут тестовые среды продуктов, демонстрационные стенды, эмуляторы различных инфраструктур заказчиков и прочие не менее важные «виртуалки». В нашей компании активно используется платформа для виртуализации VMware vSphere. Разделение пулов между отделами (инженерами, тестировщиками, сейлами и разработчиками) проблему до конца не решает, поэтому периодически приходится разбираться, кто всем мешает и кто съел все ресурсы. Несмотря на достаточную мощность нашей инфраструктуры, доступ большого числа человек к управлению виртуальными машинами постоянно приводит к конфликтам и снижению производительности фермы. При количестве виртуальных машин далеко за сотню сделать это вручную бывает проблематично, поэтому мы научились использовать API. VMware vSphere имеет довольно богатое API, которое незаслуженно слабо освещено на Хабре, хотя прикладная область применения довольна широка.

В данной статье будут приведены примеры взаимодействия в рамках задач администрирования с помощью Python.
Для Python есть библиотека под названием pyVmomi от самой VMware.

Подготовка

В папке проекта создадим конфигурационный файл config.txt следующего содержания:

[VSphere]
host=10.10.1.2
user=admin@domain
pwd=password

Для его чтения используем модуль configparser.

config = configparser.ConfigParser()
config.read("config.txt")

Чтобы подключиться к сфере, используются методы pyVim.connect.SmartConnect и pyVim.connect.SmartConnectNoSSL. Второй применяется для самоподписанных сертификатов.

from pyVim.connect import SmartConnectNoSSL
connection = SmartConnectNoSSL(**config["VSphere"])

Список машин по месту на датасторах

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

Получить список виртуальных машин можно следующим образом:

from pyVmomi import vim def get_all_vms(): content = connection.content container = content.viewManager.CreateContainerView(content.rootFolder, [vim.VirtualMachine], True) return [VirtualMachine(managed_object_ref) for managed_object_ref in container.view]

Как можно было заметить, возвращается список объектов класса VirtualMachine. Сейчас его и реализуем:

class VirtualMachine: def __init__(self, machine_object): self.vm = machine_object @property def name(self): return self.vm.name @property def provisioned_space(self): return int(self.vm.summary.storage.committed + self.vm.summary.storage.uncommitted) / 1024**3 @property def guest_disk_usage(self): return sum([int(i.capacity - i.freeSpace) for i in self.по размеру снапшотаvm.summary.vm.guest.disk]) / 1024**3 @property def usage_storage(self): return int(self.vm.summary.storage.committed) / 1024**3 def __repr__(self): return " {:.2f} {:.2f} {:.2f}".format(self.name, self.provisioned_space, self.guest_disk_usage, self.usage_storage)

Вывод данных уже зависит от необходимости. Самое простое — вывести в консоль:

for virtual_machine in sorted(get_all_vms(), key=lambda vm: vm.usage_storage, reverse=True): print(virtual_machine)

Размеры и количество снапшотов

С размерами виртуальных машин разобрались. Предположим, мы хотим узнать, сколько снапшотов имеет каждая виртуальная машина, и сколько места они занимают.

Логика предыдущего примера сохраняется, только теперь наш класс VirtualMachine будет выглядеть так:

class VirtualMachine: def __init__(self, machine_object): self.vm = machine_object self.snapshot_count, self.snapshot_size = self._snapshot_info() @property def name(self): return self.vm.name def _snapshot_info(self): disk_list = self.vm.layoutEx.file size = 0 count = 0 for disk in disk_list: if disk.type == 'snapshotData': size += disk.size count += 1 ss_disk = re.search('0000\d\d', disk.name) if ss_disk: size += disk.size return count, size / 1024**3 def __repr__(self): return "{} {:.2f} {}".format(self.name, self.snapshot_size, self.snapshot_count)

И вывод будет отсортирован уже по размеру или по количеству:

for virtual_machine in sorted(get_all_vms(), key=lambda vm: vm.snapshot_size, reverse=True): print(virtual_machine)

Восстановление снапшота

Раз пошла речь про снапшоты, то поговорим об их восстановлении.

Гипотетическая задача — восстановить последние созданные снапшоты, в названии которых присутствует строка infra.

Для восстановления снапшота необходимо создать задачу RevertToSnapshot_Task().

Сперва получим необходимый список машин:

def get_vms(part_of_name): content = connection.content container = content.viewManager.CreateContainerView(content.rootFolder, [vim.VirtualMachine], True) return [managed_object_ref for managed_object_ref in container.view if part_of_name in managed_object_ref.name]

Для получения последнего созданного снапшота вернем последний элемент списка vm.snapshot.rootSnapshotList, отсортированного по полю createTime:

def get_last_snapshot(vm): try: return sorted(vm.snapshot.rootSnapshotList, key=lambda snap: snap.createTime)[-1] except AttributeError: return None

Теперь же можем восстановить этот снапшот:

def restore_snapshot(snaphot_obj): task = snaphot_obj.snapshot.RevertToSnapshot_Task() WaitForTask(task, connection)

Теперь все объединим:

part_of_name = "infra"
for vm in get_vms(part_of_name): last_snapshot = get_last_snapshot(vm) if last_snapshot: restore_snapshot(last_snapshot)

Включение/выключение по списку

Для выключения виртуальной машины необходимо создать задачу PowerOffVM_Task().

Напишем функцию выключения машины, если она включена:

def poweroff_if_enabled(vm): if vm.runtime.powerState == vim.VirtualMachinePowerState.poweredOn: vm.PowerOffVM_Task()

Итоговый скрипт:

part_of_name = "infra"
for vm in get_vms(part_of_name): poweroff_if_enabled(vm)

Такое выключение машины будет принудительным. Гораздо правильнее будет вызвать задачу ShutdownGuest():

def shutdown_guest(vm): if vm.runtime.powerState == vim.VirtualMachinePowerState.poweredOn: vm.ShutdownGuest()

В конце хотелось бы привести еще несколько полезных ссылок:

  • pyvmomi samples — примеры от самой VMware
  • pyvmomi community samples — репозиторий с примерами использования библиотеки, написанными сообществом
  • govmomi — пакет для языка goland. Его использует kubernetes
  • rbvmomi — ruby-интерфейс для vSphere API

Если тема вызовет интерес, мы готовы ее продолжить и рассказать, как автоматизировать развертывание приложения от пуша в Git до создания виртуальной машины с работающим инстансом.

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть