Skip to content

Commit

Permalink
Merge branch 'release/2.1.0'
Browse files Browse the repository at this point in the history
Release v2.1.0
  • Loading branch information
jhollowe authored Aug 10, 2024
2 parents cdcb40d + a60ab7a commit 3156b09
Show file tree
Hide file tree
Showing 29 changed files with 1,131 additions and 80 deletions.
4 changes: 2 additions & 2 deletions .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.166.1/containers/python-3/.devcontainer/base.Dockerfile

# [Choice] Python version: 3, 3.9, 3.8, 3.7, 3.6
# [Choice] Python version: 3, 3.11, 3.10, 3.9, 3.8, 3.7, 3.6
ARG VARIANT="3"
FROM mcr.microsoft.com/vscode/devcontainers/python:0-${VARIANT}
FROM mcr.microsoft.com/vscode/devcontainers/python:${VARIANT}

# [Optional] If your pip requirements rarely change, uncomment this section to add them to the image.
COPY test_requirements.txt dev_requirements.txt /tmp/pip-tmp/
Expand Down
52 changes: 28 additions & 24 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -1,37 +1,41 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
// https://github.com/microsoft/vscode-dev-containers/tree/v0.166.1/containers/python-3
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/python
{
"name": "Proxmoxer Development",
"build": {
"dockerfile": "Dockerfile",
"context": "..",
"args": {
// Update 'VARIANT' to pick a Python version: 3, 3.6, 3.7, 3.8, 3.9
"VARIANT": "3",
// Update 'VARIANT' to pick a Python version: 3, 3.6, 3.7, 3.8, 3.9, 3.10, 3.11
"VARIANT": "3.8"
}
},
// Set *default* container specific settings.json values on container create.
"settings": {
"terminal.integrated.shell.linux": "/bin/bash",
"python.pythonPath": "/usr/local/bin/python",
"python.formatting.autopep8Path": "/usr/local/py-utils/bin/autopep8",
"python.formatting.blackPath": "/usr/local/py-utils/bin/black",
"python.formatting.yapfPath": "/usr/local/py-utils/bin/yapf",
"python.linting.banditPath": "/usr/local/py-utils/bin/bandit",
"python.linting.flake8Path": "/usr/local/py-utils/bin/flake8",
"python.linting.mypyPath": "/usr/local/py-utils/bin/mypy",
"python.linting.pycodestylePath": "/usr/local/py-utils/bin/pycodestyle",
"python.linting.pydocstylePath": "/usr/local/py-utils/bin/pydocstyle",
"python.linting.pylintPath": "/usr/local/py-utils/bin/pylint"
"customizations": {
"vscode": {
"settings": {
"terminal.integrated.shell.linux": "/bin/bash",
"python.pythonPath": "/usr/local/bin/python",
"python.formatting.autopep8Path": "/usr/local/py-utils/bin/autopep8",
"python.formatting.blackPath": "/usr/local/py-utils/bin/black",
"python.formatting.yapfPath": "/usr/local/py-utils/bin/yapf",
"python.linting.banditPath": "/usr/local/py-utils/bin/bandit",
"python.linting.flake8Path": "/usr/local/py-utils/bin/flake8",
"python.linting.mypyPath": "/usr/local/py-utils/bin/mypy",
"python.linting.pycodestylePath": "/usr/local/py-utils/bin/pycodestyle",
"python.linting.pydocstylePath": "/usr/local/py-utils/bin/pydocstyle",
"python.linting.pylintPath": "/usr/local/py-utils/bin/pylint"
},
// Add the IDs of extensions you want installed when the container is created.
"extensions": [
"mhutchie.git-graph",
"ms-python.python",
"njpwerner.autodocstring",
"ryanluker.vscode-coverage-gutters",
"streetsidesoftware.code-spell-checker"
]
}
},
// Add the IDs of extensions you want installed when the container is created.
"extensions": [
"mhutchie.git-graph",
"ms-python.python",
"njpwerner.autodocstring",
"ryanluker.vscode-coverage-gutters",
"streetsidesoftware.code-spell-checker"
],
// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [],
// Run commands to prepare the container for use
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ jobs:
fail-fast: false
matrix:
python-version:
- "3.7"
- "3.8"
- "3.9"
- "3.10"
- "3.11"
- "3.12"

steps:
- name: Checkout
Expand Down
18 changes: 9 additions & 9 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
repos:
###### FORMATTING ######
- repo: https://github.com/psf/black
rev: 22.6.0
- repo: https://github.com/psf/black-pre-commit-mirror
rev: 23.11.0
hooks:
- id: black
language_version: python3 # Should be a command that runs python3.6+

- repo: https://github.com/PyCQA/isort
rev: 5.10.1
rev: 5.12.0
hooks:
- id: isort
name: isort (python)
Expand All @@ -17,13 +17,13 @@ repos:

###### LINTING ######
- repo: https://github.com/PyCQA/bandit
rev: 1.7.4
rev: 1.7.5
hooks:
- id: bandit
args: ["--configfile", ".bandit", "--baseline", "tests/known_issues.json"]

- repo: https://github.com/PyCQA/flake8
rev: 4.0.1
rev: 6.1.0
hooks:
- id: flake8
# any flake8 plugins must be included in the hook venv
Expand All @@ -35,7 +35,7 @@ repos:
# - id: pylint

- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.3.0
rev: v4.5.0
hooks:
- id: check-case-conflict
- id: check-symlinks
Expand All @@ -46,13 +46,13 @@ repos:
args: [--fix=no]

- repo: https://github.com/asottile/blacken-docs
rev: v1.12.1
rev: 1.16.0
hooks:
- id: blacken-docs
additional_dependencies: [black==21.5b1]
additional_dependencies: [black==23.11.0]

- repo: https://github.com/pre-commit/pygrep-hooks
rev: v1.9.0
rev: v1.10.0
hooks:
- id: python-no-eval
- id: rst-backticks
Expand Down
29 changes: 27 additions & 2 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"version": "2.0.0",
"tasks": [
{
"label": "Run Tests (with coverage)",
"label": "Run Tests (with coverage file)",
"type": "shell",
"command": "pytest -v --cov --cov-report xml:coverage.xml tests/",
"problemMatcher": [],
Expand All @@ -28,6 +28,31 @@
"clear": true
},
},
{
"label": "Run Tests (with coverage)",
"type": "shell",
"command": "pytest --cov tests/",
"problemMatcher": [],
"icon": {
"id": "beaker",
"color": "terminal.ansiGreen"
},
"runOptions": {
"instanceLimit": 1
},
"group": {
"kind": "test",
"isDefault": false
},
"presentation": {
"echo": true,
"reveal": "always",
"focus": false,
"panel": "dedicated",
"showReuseMessage": true,
"clear": true
},
},
{
"label": "Run Tests",
"type": "shell",
Expand Down Expand Up @@ -74,7 +99,7 @@
{
"label": "Clean Cache/tmp files",
"type": "shell",
"command": "rm -rf ./.mypy_cache/ ./.pytest_cache/ ./.coverage.xml ./.coverage",
"command": "rm -rf ./.mypy_cache/ ./.pytest_cache/ ./coverage.xml ./.coverage",
"problemMatcher": [],
"group": {
"kind": "none"
Expand Down
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
## 2.1.0 (2024-08-10)

* Improvement (docs): Update Readme with updated example ([Rob Wolinski](https://github.com/trekie86))
* Addition (tools): Added Files tools ([John Hollowell](https://github.com/jhollowe))
* Improvement (all): Add repr to some classes and add to tests ([John Hollowell](https://github.com/jhollowe))
* Bugfix (all): Correct metadata to match supported Python versions (3.6+) ([Alexei Znamensky](https://github.com/russoz))
* Bugfix (https): Fix BytesWarning when logging response status/content ([Walter Doekes](https://github.com/wdoekes))
* Improvement (meta): Update devcontainer to modern unified schema ([John Hollowell](https://github.com/jhollowe))
* Improvement (meta): Add 3.12 to CI matrix, remove 3.7 testing ([John Hollowell](https://github.com/jhollowe))
* Improvement (all): Fix improper spliting of non-exec QEMU commands ([John Hollowell](https://github.com/jhollowe))

## 2.0.1 (2022-12-19)

* Bugfix (https): properly pass verify_ssl all the way to the backend auth ([Dominik Rimpf](https://github.com/domrim))
Expand Down
4 changes: 2 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@ API calls using the access methods above.
.. code-block:: pycon
>>> for node in proxmox.nodes.get():
... for vm in proxmox.nodes(node["node"]).openvz.get():
... print "{0}. {1} => {2}".format(vm["vmid"], vm["name"], vm["status"])
... for vm in proxmox.nodes(node["node"]).qemu.get():
... print(f"{vm['vmid']}. {vm['name']} => {vm['status']}")
...
141. puppet-2.london.example.com => running
Expand Down
2 changes: 1 addition & 1 deletion proxmoxer/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
__author__ = "Oleg Butovich"
__copyright__ = "(c) Oleg Butovich 2013-2017"
__version__ = "2.0.1"
__version__ = "2.1.0"
__license__ = "MIT"

from .core import * # noqa
6 changes: 5 additions & 1 deletion proxmoxer/backends/command_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,11 +145,15 @@ def loads_errors(self, response):


class CommandBaseBackend:
def __init__(self):
self.session = None
self.target = ""

def get_session(self):
return self.session

def get_base_url(self):
return ""
return self.target

def get_serializer(self):
return JsonSimpleSerializer()
10 changes: 6 additions & 4 deletions proxmoxer/backends/https.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@
import requests
from requests.auth import AuthBase
from requests.cookies import cookiejar_from_dict

# Disable warnings about using untrusted TLS
requests.packages.urllib3.disable_warnings()
except ImportError:
logger.error("Chosen backend requires 'requests' module\n")
sys.exit(1)
Expand Down Expand Up @@ -171,7 +174,6 @@ def request(
cert=None,
serializer=None,
):

a = auth or self.auth
c = cookies or self.cookies

Expand All @@ -192,7 +194,7 @@ def request(
total_file_size = 0
for k, v in data.copy().items():
# split qemu exec commands for proper parsing by PVE (issue#89)
if k == "command":
if k == "command" and url.endswith("agent/exec"):
if isinstance(v, list):
data[k] = v
elif "Windows" not in platform.platform():
Expand All @@ -201,7 +203,8 @@ def request(
total_file_size += get_file_size(v)

# add in filename from file pointer (patch for https://github.com/requests/toolbelt/pull/316)
files[k] = (requests.utils.guess_filename(v), v)
# add Content-Type since Proxmox requires it (https://bugzilla.proxmox.com/show_bug.cgi?id=4344)
files[k] = (requests.utils.guess_filename(v), v, "application/octet-stream")
del data[k]

# if there are any large files, send all data and files using streaming multipart encoding
Expand Down Expand Up @@ -261,7 +264,6 @@ def __init__(
path_prefix=None,
service="PVE",
):

host_port = ""
if len(host.split(":")) > 2: # IPv6
if host.startswith("["):
Expand Down
1 change: 1 addition & 0 deletions proxmoxer/backends/local.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ def upload_file_obj(self, file_obj, remote_path):
class Backend(CommandBaseBackend):
def __init__(self, *args, **kwargs):
self.session = LocalSession(*args, **kwargs)
self.target = "localhost"
1 change: 1 addition & 0 deletions proxmoxer/backends/openssh.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,4 @@ def upload_file_obj(self, file_obj, remote_path):
class Backend(CommandBaseBackend):
def __init__(self, *args, **kwargs):
self.session = OpenSSHSession(*args, **kwargs)
self.target = self.session.host
1 change: 1 addition & 0 deletions proxmoxer/backends/ssh_paramiko.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,4 @@ def upload_file_obj(self, file_obj, remote_path):
class Backend(CommandBaseBackend):
def __init__(self, *args, **kwargs):
self.session = SshParamikoSession(*args, **kwargs)
self.target = self.session.host
15 changes: 8 additions & 7 deletions proxmoxer/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,18 +78,16 @@ def __init__(self, status_code, status_message, content, errors=None):


class AuthenticationError(Exception):
def __init__(self, msg):
super().__init__(msg)
self.msg = msg

def __str__(self):
return self.msg
pass


class ProxmoxResource:
def __init__(self, **kwargs):
self._store = kwargs

def __repr__(self):
return f"ProxmoxResource ({self._store.get('base_url')})"

def __getattr__(self, item):
if item.startswith("_"):
raise AttributeError(item)
Expand Down Expand Up @@ -142,7 +140,7 @@ def _request(self, method, data=None, params=None):
del data[key]

resp = self._store["session"].request(method, url, data=data, params=params)
logger.debug(f"Status code: {resp.status_code}, output: {resp.content}")
logger.debug(f"Status code: {resp.status_code}, output: {resp.content!r}")

if resp.status_code >= 400:
if hasattr(resp, "reason"):
Expand Down Expand Up @@ -218,6 +216,9 @@ def __init__(self, host=None, backend="https", service="PVE", **kwargs):
"serializer": self._backend.get_serializer(),
}

def __repr__(self):
return f"ProxmoxAPI ({self._backend_name} backend for {self._store['base_url']})"

def get_tokens(self):
"""Return the auth and csrf tokens.
Expand Down
1 change: 1 addition & 0 deletions proxmoxer/tools/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@
__license__ = "MIT"

from . import * # noqa: F401 F403
from .files import * # noqa: F401 F403
from .tasks import * # noqa: F401 F403
Loading

0 comments on commit 3156b09

Please sign in to comment.