Исходный код esu.vm

from esu.base import BaseAPI, Field, FieldList, ObjectAlreadyHasId, \
    ObjectHasNoId


[документация]class Vm(BaseAPI): """ Args: id (str): Идентификатор name (str): Имя description (str): Описание. Любой произвольный пользовательский текст cpu (int): Количество ядер ram (int): Количество ОЗУ в ГБ power (bool): Текущее состояние питания. Включен или выключен vdc (object): Объект класса :class:`esu.Vdc`. ВЦОД, к которому относится данный виртуальный сервер template (object): Объект класса :class:`esu.Template`. Шаблон операционной системы metadata (list): Список объектов класса :class:`esu.VmMetadata`. Список полей, необходимых для создания виртуального выделенного сервера. Например, пароль или имя пользователя. ports (list): Список объектов класса :class:`esu.Port`. Список сетей, к которым подключен данный виртуальный сервер disks (list): Список объектов класса :class:`esu.Disk`. Список дисков, подключенных к данному виртуальному серверу floating (object): Объект класса :class:`esu.Port`. Порт подключения виртаульаного выделенного сервера к внешней сети. Если None, сервер не имеет подключения к внешней сети. token (str): Токен для доступа к API. Если не передан, будет использована переменная окружения **ESU_API_TOKEN** .. note:: Поля ``name``, ``cpu``, ``ram``, ``template``, ``ports``, ``disks`` и ``vdc`` необходимы для создания. Поля ``metadata``, ``description`` и ``floating`` опциональны при создании. Поля ``name``, ``description``, ``cpu``, ``ram``, ``floating`` могут быть изменены для существующего объекта. """ class Meta: id = Field() name = Field() description = Field() cpu = Field() ram = Field() power = Field() vdc = Field('esu.Vdc') template = Field('esu.Template') metadata = FieldList('esu.VmMetadata') ports = FieldList('esu.Port') disks = FieldList('esu.Disk') floating = Field('esu.Port', allow_none=True) hotadd_feature = Field() cdrom = Field('esu.Image', allow_none=True)
[документация] @classmethod def get_object(cls, id, token=None): """ Получить объект виртуального сервера по его ID Args: id (str): Идентификатор виртуального сервера token (str): Токен для доступа к API. Если не передан, будет использована переменная окружения **ESU_API_TOKEN** Returns: object: Возвращает объект виртуального сервера :class:`esu.Vm` """ vm = cls(token=token, id=id) vm._get_object('v1/vm', vm.id) for disk in vm.disks: disk.vm = vm return vm
[документация] def create(self): """ Создать объект Raises: ObjectAlreadyHasId: Если производится попытка создать объект, который уже существует """ if self.id is not None: raise ObjectAlreadyHasId self._commit()
[документация] def save(self): """ Сохранить изменения """ if self.id is None: raise ObjectHasNoId self._commit() return self
def _commit(self): vm = { 'vdc': self.vdc.id, 'template': self.template.id, 'name': self.name, 'cpu': self.cpu, 'ram': self.ram, 'description': self.description or '', 'ports': [{ 'id': o.id, } if o.id else { 'network': o.network.id, 'fw_templates': [o2.id for o2 in o.fw_templates or []] } for o in self.ports], 'disks': [{ 'name': o.name, 'size': o.size, 'storage_profile': o.storage_profile.id } for o in self.disks] } if self.id is None: vm['metadata'] = [{ 'field': o.field.id, 'value': o.value } for o in self.metadata] floating = None if self.floating: # keep/change or get a new IP floating = self.floating.id or '0.0.0.0' vm['floating'] = floating if self.hotadd_feature: vm['hotadd_feature'] = True self._commit_object('v1/vm', **vm)
[документация] def destroy(self): """ Удалить объект Raises: ObjectHasNoId: Когда производится попытка удалить несуществующий объект """ if self.id is None: raise ObjectHasNoId self._destroy_object('v1/vm', self.id) self.id = None
[документация] def add_disk(self, disk): """ Создать и присоединить к виртуальному серверу новый диск Args: disk (object): Объект диска :class:`esu.Disk` """ if disk.id: raise ValueError('You must pass a new Disk object') disk.vm = self disk._commit() self.disks.append(disk)
[документация] def attach_disk(self, disk): """ Присоединить существующий во ВЦОДе диск к виртуальному серверу Args: disk (object): Объект диска :class:`esu.Disk` """ if not disk.id: raise ValueError('Disk is not exists') if disk.vm is not None: raise ValueError('Disk must be unattached') disk.vm = self disk.save() self.disks.append(disk)
[документация] def detach_disk(self, disk): """ Отсоединить диск от виртуального сервера Args: disk (object): Объект диска :class:`esu.Disk` """ self._call('POST', 'v1/disk/{}/detach'.format(disk.id)) disk.vm = None self.disks = [d for d in self.disks if d.id != disk.id]
[документация] def add_port(self, port): """ Добавить подключение Args: port (object): Новый объект :class:`esu.Port` """ port = self._call('POST', 'v1/port', vm=self.id, network=port.network.id) self.ports.append(port) self._fill()
[документация] def remove_port(self, port): """ Удалить подключение Args: port (object): Существующий объект :class:`esu.Port` """ self._call('DELETE', 'v1/port/{}'.format(port.id)) self.ports = [o for o in self.ports if o.id != port.id]
[документация] def power_on(self): """ Включить виртуальный сервер """ self._call('POST', 'v1/vm/{}/state'.format(self.id), state='power_on') self.power = True
[документация] def power_off(self): """ Выключить виртуальный сервер """ self._call('POST', 'v1/vm/{}/state'.format(self.id), state='power_off') self.power = False
[документация] def reboot(self): """ Перезагрузить виртуальный сервер """ self._call('POST', 'v1/vm/{}/state'.format(self.id), state='reboot')
[документация] def get_vnc_url(self): """ Получить ссылку на VNC для открытия консоли управления сервером Returns: str: Адрес VNC консоли """ vnc = self._call('POST', 'v1/vm/{}/vnc'.format(self.id)) uri = vnc['url'] return '{}{}'.format(self.endpoint_url, uri)
[документация] def revert(self, snapshot): """ Восстановить сервер из снапшота Args: snapshot (object): объект снапшота :class:`esu.Snapshot` """ vm = self._call('POST', 'v2/snapshot/{}/revert'.format(snapshot.id)) return vm
[документация] def mount_iso(self, image): """ Примонтировать iso к серверу как CD-ROM. После перезагрузки сервера он будет загружен с этого диска если он загрузочный Args: image (object): объект образа :class:`esu.Image` """ image = {'image': image.id} self._call('POST', 'v1/vm/{}/mount_iso'.format(self.id), **image)
[документация] def unmount_iso(self): """ Отмонтировать iso от сервера После перезагрузки сервера он будет загружен с основного диска """ self._call('POST', 'v1/vm/{}/unmount_iso'.format(self.id))