mirror of
https://github.com/thegeeklab/prometheus-pve-sd.git
synced 2024-11-23 09:50:40 +00:00
feat: add option to authenticate with api token instead of password (#460)
Co-authored-by: Bruno MATEU <pro+github@brunomat.eu> Co-authored-by: Bruno MATEU <mateubruno@gmail.com>
This commit is contained in:
parent
a6d128d605
commit
35bfa8bc6a
@ -35,18 +35,30 @@ include_vmid: []
|
|||||||
exclude_tags: []
|
exclude_tags: []
|
||||||
include_tags: []
|
include_tags: []
|
||||||
|
|
||||||
|
# Set either password or token_name and token_value
|
||||||
pve:
|
pve:
|
||||||
server:
|
server:
|
||||||
user:
|
user:
|
||||||
password:
|
password:
|
||||||
|
token_name:
|
||||||
|
token_value:
|
||||||
auth_timeout: 5
|
auth_timeout: 5
|
||||||
verify_ssl: true
|
verify_ssl: true
|
||||||
|
|
||||||
# Example
|
# Example with password
|
||||||
# pve:
|
# pve:
|
||||||
# server: proxmox.example.com
|
# server: proxmox.example.com
|
||||||
# user: root
|
# user: root
|
||||||
# password: secure
|
# password: secure
|
||||||
# auth_timeout: 5
|
# auth_timeout: 5
|
||||||
# verify_ssl: true
|
# verify_ssl: true
|
||||||
|
|
||||||
|
# Example with API token
|
||||||
|
# pve:
|
||||||
|
# server: proxmox.example.com
|
||||||
|
# user: root
|
||||||
|
# token_name: pve_sd
|
||||||
|
# token_value: 01234567-89ab-cdef-0123-456789abcdef
|
||||||
|
# auth_timeout: 5
|
||||||
|
# verify_ssl: true
|
||||||
```
|
```
|
||||||
|
@ -36,6 +36,8 @@ PROMETHEUS_PVE_SD_INCLUDE_TAGS=
|
|||||||
PROMETHEUS_PVE_SD_PVE_SERVER=
|
PROMETHEUS_PVE_SD_PVE_SERVER=
|
||||||
PROMETHEUS_PVE_SD_PVE_USER=
|
PROMETHEUS_PVE_SD_PVE_USER=
|
||||||
PROMETHEUS_PVE_SD_PVE_PASSWORD=
|
PROMETHEUS_PVE_SD_PVE_PASSWORD=
|
||||||
|
PROMETHEUS_PVE_SD_PVE_TOKEN_NAME=
|
||||||
|
PROMETHEUS_PVE_SD_PVE_TOKEN_VALUE=
|
||||||
PROMETHEUS_PVE_SD_PVE_AUTH_TIMEOUT=5
|
PROMETHEUS_PVE_SD_PVE_AUTH_TIMEOUT=5
|
||||||
PROMETHEUS_PVE_SD_PVE_VERIFY_SSL=true
|
PROMETHEUS_PVE_SD_PVE_VERIFY_SSL=true
|
||||||
```
|
```
|
||||||
|
@ -114,12 +114,20 @@ class PrometheusSD:
|
|||||||
self.log.sysexit_with_message(f"Can not set log level.\n{e!s}")
|
self.log.sysexit_with_message(f"Can not set log level.\n{e!s}")
|
||||||
|
|
||||||
required = [("pve.server", config.config["pve"]["server"]),
|
required = [("pve.server", config.config["pve"]["server"]),
|
||||||
("pve.user", config.config["pve"]["user"]),
|
("pve.user", config.config["pve"]["user"])]
|
||||||
("pve.password", config.config["pve"]["password"])]
|
|
||||||
for name, value in required:
|
for name, value in required:
|
||||||
if not value:
|
if not value:
|
||||||
self.log.sysexit_with_message(f"Option '{name}' is required but not set")
|
self.log.sysexit_with_message(f"Option '{name}' is required but not set")
|
||||||
|
|
||||||
|
if (
|
||||||
|
not config.config["pve"]["password"]
|
||||||
|
and not (config.config["pve"]["token_name"] and config.config["pve"]["token_value"])
|
||||||
|
):
|
||||||
|
self.log.sysexit_with_message(
|
||||||
|
"Either 'pve.password' or 'pve.token_name' and 'pve.token_value' "
|
||||||
|
"are required but not set"
|
||||||
|
)
|
||||||
|
|
||||||
self.logger.info(f"Using config file {config.config_file}")
|
self.logger.info(f"Using config file {config.config_file}")
|
||||||
|
|
||||||
return config
|
return config
|
||||||
|
@ -44,6 +44,18 @@ class ProxmoxClient:
|
|||||||
self.config.config["pve"]["server"], self.config.config["pve"]["user"]
|
self.config.config["pve"]["server"], self.config.config["pve"]["user"]
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if self.config.config["pve"]["token_name"]:
|
||||||
|
self.logger.debug("Using token login")
|
||||||
|
return ProxmoxAPI(
|
||||||
|
self.config.config["pve"]["server"],
|
||||||
|
user=self.config.config["pve"]["user"],
|
||||||
|
token_name=self.config.config["pve"]["token_name"],
|
||||||
|
token_value=self.config.config["pve"]["token_value"],
|
||||||
|
verify_ssl=to_bool(self.config.config["pve"]["verify_ssl"]),
|
||||||
|
timeout=self.config.config["pve"]["auth_timeout"]
|
||||||
|
)
|
||||||
|
|
||||||
return ProxmoxAPI(
|
return ProxmoxAPI(
|
||||||
self.config.config["pve"]["server"],
|
self.config.config["pve"]["server"],
|
||||||
user=self.config.config["pve"]["user"],
|
user=self.config.config["pve"]["user"],
|
||||||
|
@ -135,6 +135,18 @@ class Config:
|
|||||||
"file": True,
|
"file": True,
|
||||||
"type": environs.Env().str
|
"type": environs.Env().str
|
||||||
},
|
},
|
||||||
|
"pve.token_name": {
|
||||||
|
"default": "",
|
||||||
|
"env": "PVE_TOKEN_NAME",
|
||||||
|
"file": True,
|
||||||
|
"type": environs.Env().str
|
||||||
|
},
|
||||||
|
"pve.token_value": {
|
||||||
|
"default": "",
|
||||||
|
"env": "PVE_TOKEN_VALUE",
|
||||||
|
"file": True,
|
||||||
|
"type": environs.Env().str
|
||||||
|
},
|
||||||
"pve.auth_timeout": {
|
"pve.auth_timeout": {
|
||||||
"default": 5,
|
"default": 5,
|
||||||
"env": "PVE_AUTH_TIMEOUT",
|
"env": "PVE_AUTH_TIMEOUT",
|
||||||
|
@ -19,8 +19,10 @@ class Host:
|
|||||||
self.add_label("vmid", vmid)
|
self.add_label("vmid", vmid)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"{self.hostname}({self.vmid}): {self.pve_type} \
|
return (
|
||||||
{self.ipv4_address} {self.ipv6_address}"
|
f"{self.hostname}({self.vmid}): "
|
||||||
|
f"{self.pve_type} {self.ipv4_address} {self.ipv6_address}"
|
||||||
|
)
|
||||||
|
|
||||||
def add_label(self, key, value):
|
def add_label(self, key, value):
|
||||||
key = key.replace("-", "_").replace(" ", "_")
|
key = key.replace("-", "_").replace(" ", "_")
|
||||||
|
@ -24,5 +24,7 @@ pve:
|
|||||||
server: proxmox.example.com
|
server: proxmox.example.com
|
||||||
user: root
|
user: root
|
||||||
password: secure
|
password: secure
|
||||||
|
token_name: pve_sd
|
||||||
|
token_value: 01234567-89ab-cdef-0123-456789abcdef
|
||||||
auth_timeout: 5
|
auth_timeout: 5
|
||||||
verify_ssl: true
|
verify_ssl: true
|
||||||
|
14
prometheuspvesd/test/fixtures/fixtures.py
vendored
14
prometheuspvesd/test/fixtures/fixtures.py
vendored
@ -114,6 +114,18 @@ def builtins():
|
|||||||
"file": True,
|
"file": True,
|
||||||
"type": environs.Env().str
|
"type": environs.Env().str
|
||||||
},
|
},
|
||||||
|
"pve.token_name": {
|
||||||
|
"default": "dummyname",
|
||||||
|
"env": "PVE_TOKEN_NAME",
|
||||||
|
"file": True,
|
||||||
|
"type": environs.Env().str
|
||||||
|
},
|
||||||
|
"pve.token_value": {
|
||||||
|
"default": "dummyvalue",
|
||||||
|
"env": "PVE_TOKEN_VALUE",
|
||||||
|
"file": True,
|
||||||
|
"type": environs.Env().str
|
||||||
|
},
|
||||||
"pve.auth_timeout": {
|
"pve.auth_timeout": {
|
||||||
"default": 5,
|
"default": 5,
|
||||||
"env": "PVE_AUTH_TIMEOUT",
|
"env": "PVE_AUTH_TIMEOUT",
|
||||||
@ -154,6 +166,8 @@ def defaults():
|
|||||||
"password": "",
|
"password": "",
|
||||||
"server": "",
|
"server": "",
|
||||||
"user": "",
|
"user": "",
|
||||||
|
"token_name": "",
|
||||||
|
"token_value": "",
|
||||||
"verify_ssl": True
|
"verify_ssl": True
|
||||||
},
|
},
|
||||||
"service": True,
|
"service": True,
|
||||||
|
@ -29,6 +29,65 @@ def test_cli_required_error(mocker, capsys):
|
|||||||
assert e.value.code == 1
|
assert e.value.code == 1
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"testinput", [{
|
||||||
|
"pve.user": "dummy",
|
||||||
|
"pve.password": "",
|
||||||
|
"pve.token_name": "",
|
||||||
|
"pve.token_value": ""
|
||||||
|
}, {
|
||||||
|
"pve.user": "dummy",
|
||||||
|
"pve.password": "",
|
||||||
|
"pve.token_name": "dummy",
|
||||||
|
"pve.token_value": ""
|
||||||
|
}, {
|
||||||
|
"pve.user": "dummy",
|
||||||
|
"pve.password": "",
|
||||||
|
"pve.token_name": "",
|
||||||
|
"pve.token_value": "dummy"
|
||||||
|
}]
|
||||||
|
)
|
||||||
|
def test_cli_auth_required_error(mocker, capsys, builtins, testinput):
|
||||||
|
for key, value in testinput.items():
|
||||||
|
builtins[key]["default"] = value
|
||||||
|
|
||||||
|
mocker.patch.dict(Config.SETTINGS, builtins)
|
||||||
|
mocker.patch.object(ProxmoxClient, "_auth", return_value=mocker.create_autospec(ProxmoxAPI))
|
||||||
|
mocker.patch.object(PrometheusSD, "_fetch", return_value=True)
|
||||||
|
|
||||||
|
with pytest.raises(SystemExit) as e:
|
||||||
|
PrometheusSD()
|
||||||
|
|
||||||
|
stdout, stderr = capsys.readouterr()
|
||||||
|
assert "Either 'pve.password' or 'pve.token_name' and 'pve.token_value' are required but not set" in stderr
|
||||||
|
assert e.value.code == 1
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"testinput", [{
|
||||||
|
"pve.password": "dummy",
|
||||||
|
"pve.token_name": "",
|
||||||
|
"pve.token_value": ""
|
||||||
|
}, {
|
||||||
|
"pve.password": "",
|
||||||
|
"pve.token_name": "dummy",
|
||||||
|
"pve.token_value": "dummy"
|
||||||
|
}]
|
||||||
|
)
|
||||||
|
def test_cli_auth_no_error(mocker, capsys, builtins, testinput):
|
||||||
|
for key, value in testinput.items():
|
||||||
|
builtins[key]["default"] = value
|
||||||
|
|
||||||
|
mocker.patch.dict(Config.SETTINGS, builtins)
|
||||||
|
mocker.patch.object(ProxmoxClient, "_auth", return_value=mocker.create_autospec(ProxmoxAPI))
|
||||||
|
mocker.patch.object(PrometheusSD, "_fetch", return_value=True)
|
||||||
|
|
||||||
|
psd = PrometheusSD()
|
||||||
|
|
||||||
|
for key, value in testinput.items():
|
||||||
|
assert psd.config.config["pve"][key.split(".")[1]] == value
|
||||||
|
|
||||||
|
|
||||||
def test_cli_config_error(mocker, capsys):
|
def test_cli_config_error(mocker, capsys):
|
||||||
mocker.patch(
|
mocker.patch(
|
||||||
"prometheuspvesd.config.SingleConfig.__init__",
|
"prometheuspvesd.config.SingleConfig.__init__",
|
||||||
|
@ -19,6 +19,8 @@ def test_yaml_config(mocker, defaults):
|
|||||||
defaults["pve"]["user"] = "root"
|
defaults["pve"]["user"] = "root"
|
||||||
defaults["pve"]["password"] = "secure"
|
defaults["pve"]["password"] = "secure"
|
||||||
defaults["pve"]["server"] = "proxmox.example.com"
|
defaults["pve"]["server"] = "proxmox.example.com"
|
||||||
|
defaults["pve"]["token_name"] = "pve_sd"
|
||||||
|
defaults["pve"]["token_value"] = "01234567-89ab-cdef-0123-456789abcdef"
|
||||||
|
|
||||||
assert config.config == defaults
|
assert config.config == defaults
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ sections = ["FUTURE", "STDLIB", "THIRDPARTY", "FIRSTPARTY", "LOCALFOLDER"]
|
|||||||
skip_glob = ["**/.env*", "**/env/*", "**/.venv/*", "**/docs/*"]
|
skip_glob = ["**/.env*", "**/env/*", "**/.venv/*", "**/docs/*"]
|
||||||
|
|
||||||
[tool.pytest.ini_options]
|
[tool.pytest.ini_options]
|
||||||
addopts = "prometheuspvesd --cov=prometheuspvesd --cov-report=xml:coverage.xml --cov-report=term --no-cov-on-fail"
|
addopts = "prometheuspvesd --cov=prometheuspvesd --cov-report=xml:coverage.xml --cov-report=term-missing --no-cov-on-fail --cov-fail-under=80"
|
||||||
filterwarnings = [
|
filterwarnings = [
|
||||||
"ignore::FutureWarning",
|
"ignore::FutureWarning",
|
||||||
"ignore::DeprecationWarning",
|
"ignore::DeprecationWarning",
|
||||||
|
Loading…
Reference in New Issue
Block a user