diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fa38aec --- /dev/null +++ b/.gitignore @@ -0,0 +1,203 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/#use-with-ide +.pdm.toml + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be added to the global gitignore or merged into this project gitignore. For a PyCharm +# project, it is recommended to include the following files: +# .idea/ +# *.iml +# *.ipr +# *.iws + +# VS Code +.vscode/ +*.code-workspace + +# macOS +.DS_Store +.AppleDouble +.LSOverride + +# Windows +Thumbs.db +ehthumbs.db +Desktop.ini + +# Linux +*~ + +# Temporary files +*.tmp +*.temp +*.swp +*.swo +*~ + +# IDE files +.idea/ +*.iml +*.ipr +*.iws + +# Logs +*.log +logs/ + +# Local configuration files +config.py +.env.local +.env.development +.env.test +.env.production \ No newline at end of file diff --git a/zvml/vpgs.py b/zvml/vpgs.py index 0ed1163..081a6ab 100644 --- a/zvml/vpgs.py +++ b/zvml/vpgs.py @@ -15,6 +15,7 @@ import time import json from .tasks import Tasks from .common import ZertoVPGStatus, ZertoVPGSubstatus, ZertoProtectedSiteType, ZertoRecoverySiteType, ZertoVPGPriority +from .localsite import LocalSite from typing import Optional, Union, Dict, List class VPGs: @@ -152,7 +153,8 @@ class VPGs: if sync: # Wait for task completion self.tasks.wait_for_task_completion(task_id, timeout=timeout, interval=interval) - logging.debug('sleeping 5 seconds ...') + logging.debug('sleeping 5 seconds ...') # looks like there is a bug in the Zerto API, so there is a need to sleep for 5 seconds + time.sleep(5) self.wait_for_vpg_ready(vpg_name=vpg_name, timeout=30, interval=5, expected_status=expected_status) return task_id return task_id @@ -201,6 +203,25 @@ class VPGs: if elapsed_time > timeout: raise TimeoutError(f"VPG {vpg_name} did not reach the {ZertoVPGStatus.get_name_by_value(expected_status.value)} state within the allotted time. Current status: {ZertoVPGStatus.get_name_by_value(vpg_status.value)}") + + def add_vm_to_vpg_by_name(self, vpg_name, vm_name): + logging.info(f'VPGs.add_vm_to_vpg_by_name(zvm_address={self.client.zvm_address}, vpg_name={vpg_name}, vm_name={vm_name})') + + local_site = LocalSite(self.client.zvm_address, self.client.token) + local_site_identifier = local_site.get_local_site()['SiteIdentifier'] + vms = self.client.virtualization_sites.get_virtualization_site_vms(site_identifier=local_site_identifier) + vm_dict = {vm.get('VmName'): vm for vm in vms} + + if vm_name not in vm_dict: + logging.error(f"VM with name '{vm_name}' not found.") + return + + vm_id = vm_dict[vm_name]['VmIdentifier'] + vm_payload = { + "VmIdentifier": vm_id + } + return self.add_vm_to_vpg(vpg_name, vm_payload) + def add_vm_to_vpg(self, vpg_name, vm_list_payload): logging.info(f'VPGs.add_vm_to_vpg(zvm_address={self.client.zvm_address}, vpg_name={vpg_name})') vpg = self.list_vpgs(vpg_name=vpg_name)