260 lines
7.1 KiB
Python
260 lines
7.1 KiB
Python
import json
|
|
from pathlib import Path
|
|
|
|
import responses
|
|
|
|
from certctl.scripts.nsconsole_certpoll import build_arg_parser, run
|
|
|
|
|
|
def _args(args):
|
|
parser = build_arg_parser()
|
|
return parser.parse_args(args)
|
|
|
|
|
|
def _add_login(resps, base):
|
|
resps.add(
|
|
responses.POST,
|
|
f"{base}/nitro/v2/config/login",
|
|
json={"login": [{"sessionid": "token"}]},
|
|
status=200,
|
|
)
|
|
|
|
|
|
def _add_inventory(resps, base):
|
|
resps.add(
|
|
responses.POST,
|
|
f"{base}/nitro/v2/config/ns_ssl_certkey",
|
|
match=[responses.matchers.query_param_matcher({"action": "inventory"})],
|
|
json={"errorcode": 0, "message": "Done"},
|
|
status=200,
|
|
)
|
|
|
|
|
|
def _add_certkey_get(resps, base, items):
|
|
resps.add(
|
|
responses.GET,
|
|
f"{base}/nitro/v2/config/ns_ssl_certkey",
|
|
json={"errorcode": 0, "ns_ssl_certkey": items},
|
|
status=200,
|
|
)
|
|
|
|
|
|
@responses.activate
|
|
def test_certpoll_filters_in_use(monkeypatch, tmp_path):
|
|
base = "https://console.example"
|
|
monkeypatch.setenv("CERTCTL_CONSOLE_PASSWORD", "secret")
|
|
|
|
_add_login(responses, base)
|
|
_add_certkey_get(
|
|
responses,
|
|
base,
|
|
[
|
|
{
|
|
"certkeypair_name": "active-bound",
|
|
"no_of_bound_entities": 2,
|
|
"days_to_expiry": 10,
|
|
"entity_binding_arr": [
|
|
{"entity_name": "lb1", "entity_type": "sslvserver", "display_name": "adc-1"}
|
|
],
|
|
},
|
|
{"certkeypair_name": "active-unbound", "certkey_status": "ACTIVE", "days_to_expiry": 15},
|
|
{"certkeypair_name": "inactive", "certkey_status": "INACTIVE", "days_to_expiry": 20},
|
|
],
|
|
)
|
|
|
|
out_path = tmp_path / "report.json"
|
|
args = _args(
|
|
[
|
|
"--console",
|
|
base,
|
|
"--user",
|
|
"nsroot",
|
|
"--format",
|
|
"json",
|
|
"--out",
|
|
str(out_path),
|
|
]
|
|
)
|
|
assert run(args) == 0
|
|
|
|
payload = json.loads(out_path.read_text(encoding="utf-8"))
|
|
assert payload["count"] == 2
|
|
names = {item["certkeypair_name"] for item in payload["items"]}
|
|
assert names == {"active-bound", "active-unbound"}
|
|
bound = next(item for item in payload["items"] if item["certkeypair_name"] == "active-bound")
|
|
assert bound["binding_count"] == 1
|
|
assert bound["binding_entities"] == "lb1"
|
|
assert bound["binding_types"] == "sslvserver"
|
|
assert bound["binding_devices"] == "adc-1"
|
|
|
|
|
|
@responses.activate
|
|
def test_certpoll_includes_cert_store_mapping(monkeypatch, tmp_path):
|
|
base = "https://console.example"
|
|
monkeypatch.setenv("CERTCTL_CONSOLE_PASSWORD", "secret")
|
|
|
|
_add_login(responses, base)
|
|
_add_certkey_get(
|
|
responses,
|
|
base,
|
|
[
|
|
{
|
|
"certkeypair_name": "mapped",
|
|
"certkey_status": "ACTIVE",
|
|
"cert_store_id": "cert-1",
|
|
}
|
|
],
|
|
)
|
|
responses.add(
|
|
responses.GET,
|
|
f"{base}/nitro/v2/config/cert_store_mapping",
|
|
json={
|
|
"errorcode": 0,
|
|
"cert_store_mapping": [
|
|
{
|
|
"cert_id": "cert-1",
|
|
"entity_name": "svc-1",
|
|
"entity_type": "service",
|
|
"instance_display_name": "adc-2",
|
|
"instance_ip": "10.0.0.1",
|
|
}
|
|
],
|
|
},
|
|
status=200,
|
|
)
|
|
|
|
out_path = tmp_path / "report.json"
|
|
args = _args(
|
|
[
|
|
"--console",
|
|
base,
|
|
"--user",
|
|
"nsroot",
|
|
"--format",
|
|
"json",
|
|
"--out",
|
|
str(out_path),
|
|
"--include-mappings",
|
|
]
|
|
)
|
|
assert run(args) == 0
|
|
|
|
payload = json.loads(out_path.read_text(encoding="utf-8"))
|
|
item = payload["items"][0]
|
|
assert item["mapping_count"] == 1
|
|
assert item["mapping_entities"] == "svc-1"
|
|
assert item["mapping_entity_types"] == "service"
|
|
assert item["mapping_instances"] == "adc-2"
|
|
assert item["mapping_instance_ips"] == "10.0.0.1"
|
|
|
|
|
|
@responses.activate
|
|
def test_certpoll_filters_by_expiry(monkeypatch, tmp_path):
|
|
base = "https://console.example"
|
|
monkeypatch.setenv("CERTCTL_CONSOLE_PASSWORD", "secret")
|
|
|
|
_add_login(responses, base)
|
|
_add_certkey_get(
|
|
responses,
|
|
base,
|
|
[
|
|
{"certkeypair_name": "soon", "certkey_status": "ACTIVE", "days_to_expiry": 10},
|
|
{"certkeypair_name": "later", "certkey_status": "ACTIVE", "days_to_expiry": 45},
|
|
],
|
|
)
|
|
|
|
out_path = tmp_path / "report.json"
|
|
args = _args(
|
|
[
|
|
"--console",
|
|
base,
|
|
"--user",
|
|
"nsroot",
|
|
"--format",
|
|
"json",
|
|
"--out",
|
|
str(out_path),
|
|
"--expires-within",
|
|
"30",
|
|
]
|
|
)
|
|
assert run(args) == 0
|
|
|
|
payload = json.loads(out_path.read_text(encoding="utf-8"))
|
|
names = {item["certkeypair_name"] for item in payload["items"]}
|
|
assert names == {"soon"}
|
|
|
|
|
|
@responses.activate
|
|
def test_certpoll_inventory_and_all(monkeypatch, capsys):
|
|
base = "https://console.example"
|
|
monkeypatch.setenv("CERTCTL_CONSOLE_PASSWORD", "secret")
|
|
|
|
_add_login(responses, base)
|
|
_add_inventory(responses, base)
|
|
_add_certkey_get(
|
|
responses,
|
|
base,
|
|
[
|
|
{"certkeypair_name": "active", "certkey_status": "ACTIVE", "days_to_expiry": 10},
|
|
{"certkeypair_name": "inactive", "certkey_status": "INACTIVE", "days_to_expiry": 20},
|
|
],
|
|
)
|
|
|
|
args = _args(
|
|
[
|
|
"--console",
|
|
base,
|
|
"--user",
|
|
"nsroot",
|
|
"--inventory",
|
|
"--all",
|
|
]
|
|
)
|
|
assert run(args) == 0
|
|
|
|
stdout = capsys.readouterr().out
|
|
assert "certkeypair_name" in stdout
|
|
assert "active" in stdout
|
|
assert "inactive" in stdout
|
|
assert any("action=inventory" in call.request.url for call in responses.calls)
|
|
|
|
|
|
@responses.activate
|
|
def test_certpoll_uses_config_profile(monkeypatch, tmp_path):
|
|
base = "https://console.example"
|
|
monkeypatch.setenv("CERTCTL_CONSOLE_PASSWORD", "secret")
|
|
|
|
config_path = tmp_path / "certctl.json"
|
|
config_path.write_text(
|
|
json.dumps(
|
|
{
|
|
"defaults": {"format": "json", "inventory": True},
|
|
"consoles": {
|
|
"test": {
|
|
"url": base,
|
|
"user": "nsroot",
|
|
"insecure": True,
|
|
}
|
|
},
|
|
}
|
|
),
|
|
encoding="utf-8",
|
|
)
|
|
|
|
_add_login(responses, base)
|
|
_add_inventory(responses, base)
|
|
_add_certkey_get(
|
|
responses,
|
|
base,
|
|
[{"certkeypair_name": "active", "certkey_status": "ACTIVE", "days_to_expiry": 10}],
|
|
)
|
|
|
|
out_path = tmp_path / "report.json"
|
|
args = _args(["--config", str(config_path), "--profile", "test", "--out", str(out_path)])
|
|
assert run(args) == 0
|
|
|
|
payload = json.loads(out_path.read_text(encoding="utf-8"))
|
|
assert payload["count"] == 1
|
|
assert payload["items"][0]["certkeypair_name"] == "active"
|