|
59 | 59 | import sys |
60 | 60 | from pathlib import Path |
61 | 61 | from typing import Any, Dict, Optional, Union |
| 62 | +from urllib.parse import urlparse |
62 | 63 |
|
63 | 64 | import requests |
64 | 65 | from requests.auth import HTTPBasicAuth |
@@ -136,13 +137,15 @@ def __init__( |
136 | 137 | verify: Union[bool, str] = True, |
137 | 138 | auth: Optional[HTTPBasicAuth] = None, |
138 | 139 | cert: Optional[Union[str, tuple]] = None, |
| 140 | + console_host: Optional[str] = None, |
139 | 141 | ) -> None: |
140 | 142 | self.base_url = base_url |
141 | 143 | self.token = token |
142 | 144 | self.timeout = int(timeout or 30) |
143 | 145 | self.verify = verify |
144 | 146 | self.auth = auth |
145 | 147 | self.cert = cert |
| 148 | + self.console_host = console_host or "" |
146 | 149 |
|
147 | 150 | class Ctx(object): |
148 | 151 | """Execution context parsed from JSON + CLI timeout (Python 3.6 compatible).""" |
@@ -181,14 +184,11 @@ def _to_ctx(config_path: str, timeout: int): |
181 | 184 | token = token.strip() or None |
182 | 185 |
|
183 | 186 | # If the provided URL already includes an explicit port, don't append another |
184 | | - if "://" in url: |
185 | | - # Extract the authority part after scheme:// and check for ':' in host:port |
186 | | - authority = url.split("://", 1)[1] |
187 | | - has_explicit_port = ":" in authority.split("/")[0] |
188 | | - else: |
189 | | - has_explicit_port = False |
190 | | - # If no scheme, assume http for completeness |
| 187 | + if "://" not in url: |
191 | 188 | url = f"http://{url}" |
| 189 | + parsed = urlparse(url) |
| 190 | + authority = parsed.netloc or "" |
| 191 | + has_explicit_port = ":" in authority |
192 | 192 |
|
193 | 193 | base_url = f"{url}/v1" if has_explicit_port else f"{url}:{port}/v1" |
194 | 194 |
|
@@ -273,7 +273,8 @@ def _to_ctx(config_path: str, timeout: int): |
273 | 273 | elif isinstance(client_key, str) and client_key: |
274 | 274 | _fail("TLS client key provided but client certificate missing") |
275 | 275 |
|
276 | | - agent = Agent(base_url, token, int(timeout or 30), verify=verify, auth=auth, cert=cert) |
| 276 | + console_host = (host.get("console_host") or parsed.hostname or "").strip() |
| 277 | + agent = Agent(base_url, token, int(timeout or 30), verify=verify, auth=auth, cert=cert, console_host=console_host) |
277 | 278 | return Ctx(data, vm_name, agent) |
278 | 279 |
|
279 | 280 | # -------------------------- HTTP helpers -------------------------- |
@@ -366,6 +367,10 @@ def op_console(ctx): |
366 | 367 | """POST /v1/vms/{name}/console — obtain VNC bridge connection info.""" |
367 | 368 | url = f"{ctx.agent.base_url}/vms/{ctx.vm_name}/console" |
368 | 369 | data = _json_or_fail(_req("POST", url, ctx.agent)) |
| 370 | + console_host = getattr(ctx.agent, "console_host", "") or "" |
| 371 | + resp_host = data.get("host") |
| 372 | + if console_host and (not resp_host or resp_host in {"0.0.0.0", "127.0.0.1", "::"}): |
| 373 | + data["host"] = console_host |
369 | 374 | _ok(data) |
370 | 375 |
|
371 | 376 | # -------------------------- main -------------------------- |
|
0 commit comments