feat(windows): add recoverable existing-agent credential upgrade
This commit is contained in:
1 parent
3cfb0d1abe
commit
97a0139e3d
25 files changed
+11122
-108
No files matched your search
@@ -62,6 +62,7 @@ class AgentManagementFrontendTests(unittest.TestCase):
|
||||
self.assertIn('id="agentSite"', managed)
|
||||
self.assertIn('id="agentZone"', managed)
|
||||
self.assertIn('id="agentDisplayName"', managed)
|
||||
self.assertIn('data-can-manage-agents="true"', managed)
|
||||
self.assertIn("Linux x64 — coming later", managed)
|
||||
self.assertIn("Linux ARM64 / Raspberry Pi — coming later", managed)
|
||||
|
||||
@@ -100,6 +101,11 @@ class AgentManagementFrontendTests(unittest.TestCase):
|
||||
'api("/api/agent-enrollments", {',
|
||||
source,
|
||||
)
|
||||
self.assertIn(
|
||||
'api("/api/agent-credential-transitions", {',
|
||||
source,
|
||||
)
|
||||
self.assertIn("Upgrade credential", source)
|
||||
|
||||
for unsafe in (
|
||||
"innerHTML",
|
||||
@@ -153,9 +159,10 @@ class AgentManagementFrontendTests(unittest.TestCase):
|
||||
source,
|
||||
)
|
||||
self.assertIn(
|
||||
'link.download = "MinerOpsAgent-Windows.zip"',
|
||||
'packageFilename = "MinerOpsAgent-Windows.zip"',
|
||||
source,
|
||||
)
|
||||
self.assertIn("link.download = packageFilename", source)
|
||||
self.assertIn(
|
||||
"window.URL.revokeObjectURL(downloadUrl)",
|
||||
source,
|
||||
|
||||
@@ -65,6 +65,7 @@ class WindowsPackageBuilderTests(unittest.TestCase):
|
||||
)
|
||||
|
||||
self.assertEqual(enrollment["token"], TOKEN)
|
||||
self.assertEqual(enrollment["workflow"], "new_agent")
|
||||
self.assertEqual(
|
||||
enrollment["hub_url"],
|
||||
"https://minerops.example.test",
|
||||
@@ -77,6 +78,50 @@ class WindowsPackageBuilderTests(unittest.TestCase):
|
||||
self.assertNotIn("api3_account", serialized)
|
||||
self.assertNotIn("agent-config.json", "\n".join(names))
|
||||
|
||||
def test_existing_agent_transition_package_is_generic_and_distinct(self):
|
||||
with tempfile.TemporaryDirectory() as temporary:
|
||||
root = Path(temporary)
|
||||
self.source_tree(root)
|
||||
package = build_windows_agent_package(
|
||||
enrollment_token=TOKEN,
|
||||
hub_url="https://minerops.example.test",
|
||||
workflow="existing_agent_credential_transition",
|
||||
source_root=root,
|
||||
)
|
||||
|
||||
with zipfile.ZipFile(io.BytesIO(package)) as archive:
|
||||
enrollment = json.loads(
|
||||
archive.read(
|
||||
f"{WINDOWS_PACKAGE_ROOT}/enrollment.json"
|
||||
)
|
||||
)
|
||||
instructions = archive.read(
|
||||
f"{WINDOWS_PACKAGE_ROOT}/INSTALL.txt"
|
||||
).decode("utf-8")
|
||||
names = set(archive.namelist())
|
||||
|
||||
self.assertEqual(
|
||||
enrollment,
|
||||
{
|
||||
"hub_url": "https://minerops.example.test",
|
||||
"token": TOKEN,
|
||||
"workflow": "existing_agent_credential_transition",
|
||||
},
|
||||
)
|
||||
self.assertIn("Upgrade-MinerOpsAgentCredential.ps1", instructions)
|
||||
self.assertIn(
|
||||
f"{WINDOWS_PACKAGE_ROOT}/Upgrade-MinerOpsAgentCredential.ps1",
|
||||
names,
|
||||
)
|
||||
serialized = json.dumps(enrollment)
|
||||
for forbidden in (
|
||||
"plexus-windows-agent",
|
||||
"site_id",
|
||||
"agent_zone_id",
|
||||
"agent_secret",
|
||||
):
|
||||
self.assertNotIn(forbidden, serialized)
|
||||
|
||||
def test_missing_canonical_source_fails_closed(self):
|
||||
with tempfile.TemporaryDirectory() as temporary:
|
||||
root = Path(temporary)
|
||||
@@ -134,6 +179,13 @@ class WindowsPackageRouteTests(unittest.TestCase):
|
||||
),
|
||||
"agents.manage",
|
||||
)
|
||||
self.assertEqual(
|
||||
required_api_permission(
|
||||
"POST",
|
||||
"/api/agent-credential-transitions/windows-package",
|
||||
),
|
||||
"agents.manage",
|
||||
)
|
||||
|
||||
def test_view_only_user_cannot_download_package(self):
|
||||
self.authenticate(("agents.view",))
|
||||
@@ -180,6 +232,35 @@ class WindowsPackageRouteTests(unittest.TestCase):
|
||||
)
|
||||
)
|
||||
self.assertEqual(enrollment["token"], TOKEN)
|
||||
self.assertEqual(enrollment["workflow"], "new_agent")
|
||||
|
||||
def test_manager_downloads_distinct_existing_agent_upgrade_package(self):
|
||||
self.authenticate(("agents.view", "agents.manage"))
|
||||
|
||||
response = self.client.post(
|
||||
"/api/agent-credential-transitions/windows-package",
|
||||
headers={"Origin": "http://testserver"},
|
||||
json={"token": TOKEN},
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(response.headers["cache-control"], "no-store")
|
||||
self.assertIn(
|
||||
"MinerOpsAgent-Credential-Upgrade-Windows.zip",
|
||||
response.headers["content-disposition"],
|
||||
)
|
||||
with zipfile.ZipFile(io.BytesIO(response.content)) as archive:
|
||||
enrollment = json.loads(
|
||||
archive.read(f"{WINDOWS_PACKAGE_ROOT}/enrollment.json")
|
||||
)
|
||||
instructions = archive.read(
|
||||
f"{WINDOWS_PACKAGE_ROOT}/INSTALL.txt"
|
||||
).decode("utf-8")
|
||||
self.assertEqual(
|
||||
enrollment["workflow"],
|
||||
"existing_agent_credential_transition",
|
||||
)
|
||||
self.assertIn("Upgrade-MinerOpsAgentCredential.ps1", instructions)
|
||||
|
||||
def test_package_requires_browser_origin(self):
|
||||
self.authenticate(("agents.view", "agents.manage"))
|
||||
|
||||
Reference in new issue
Block a user