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: []
|
||||
include_tags: []
|
||||
|
||||
# Set either password or token_name and token_value
|
||||
pve:
|
||||
server:
|
||||
user:
|
||||
password:
|
||||
token_name:
|
||||
token_value:
|
||||
auth_timeout: 5
|
||||
verify_ssl: true
|
||||
|
||||
# Example
|
||||
# Example with password
|
||||
# pve:
|
||||
# server: proxmox.example.com
|
||||
# user: root
|
||||
# password: secure
|
||||
# auth_timeout: 5
|
||||
# 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_USER=
|
||||
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_VERIFY_SSL=true
|
||||
```
|
||||
|
@ -114,12 +114,20 @@ class PrometheusSD:
|
||||
self.log.sysexit_with_message(f"Can not set log level.\n{e!s}")
|
||||
|
||||
required = [("pve.server", config.config["pve"]["server"]),
|
||||
("pve.user", config.config["pve"]["user"]),
|
||||
("pve.password", config.config["pve"]["password"])]
|
||||
("pve.user", config.config["pve"]["user"])]
|
||||
for name, value in required:
|
||||
if not value:
|
||||
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}")
|
||||
|
||||
return config
|
||||
|
@ -44,6 +44,18 @@ class ProxmoxClient:
|
||||
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(
|
||||
self.config.config["pve"]["server"],
|
||||
user=self.config.config["pve"]["user"],
|
||||
|
@ -135,6 +135,18 @@ class Config:
|
||||
"file": True,
|
||||
"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": {
|
||||
"default": 5,
|
||||
"env": "PVE_AUTH_TIMEOUT",
|
||||
|
@ -19,8 +19,10 @@ class Host:
|
||||
self.add_label("vmid", vmid)
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.hostname}({self.vmid}): {self.pve_type} \
|
||||
{self.ipv4_address} {self.ipv6_address}"
|
||||
return (
|
||||
f"{self.hostname}({self.vmid}): "
|
||||
f"{self.pve_type} {self.ipv4_address} {self.ipv6_address}"
|
||||
)
|
||||
|
||||
def add_label(self, key, value):
|
||||
key = key.replace("-", "_").replace(" ", "_")
|
||||
|
@ -24,5 +24,7 @@ pve:
|
||||
server: proxmox.example.com
|
||||
user: root
|
||||
password: secure
|
||||
token_name: pve_sd
|
||||
token_value: 01234567-89ab-cdef-0123-456789abcdef
|
||||
auth_timeout: 5
|
||||
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,
|
||||
"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": {
|
||||
"default": 5,
|
||||
"env": "PVE_AUTH_TIMEOUT",
|
||||
@ -154,6 +166,8 @@ def defaults():
|
||||
"password": "",
|
||||
"server": "",
|
||||
"user": "",
|
||||
"token_name": "",
|
||||
"token_value": "",
|
||||
"verify_ssl": True
|
||||
},
|
||||
"service": True,
|
||||
|
@ -29,6 +29,65 @@ def test_cli_required_error(mocker, capsys):
|
||||
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):
|
||||
mocker.patch(
|
||||
"prometheuspvesd.config.SingleConfig.__init__",
|
||||
|
@ -19,6 +19,8 @@ def test_yaml_config(mocker, defaults):
|
||||
defaults["pve"]["user"] = "root"
|
||||
defaults["pve"]["password"] = "secure"
|
||||
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
|
||||
|
||||
|
@ -66,7 +66,7 @@ sections = ["FUTURE", "STDLIB", "THIRDPARTY", "FIRSTPARTY", "LOCALFOLDER"]
|
||||
skip_glob = ["**/.env*", "**/env/*", "**/.venv/*", "**/docs/*"]
|
||||
|
||||
[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 = [
|
||||
"ignore::FutureWarning",
|
||||
"ignore::DeprecationWarning",
|
||||
|
Loading…
Reference in New Issue
Block a user