12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970 |
- import os
- from typing import TYPE_CHECKING
- if TYPE_CHECKING:
- from render import Render
- try:
- from .error import RenderError
- except ImportError:
- from error import RenderError
- def is_truenas_system():
- """Check if we're running on a TrueNAS system"""
- return "truenas" in os.uname().release
- # Import based on system detection
- if is_truenas_system():
- from truenas_api_client import Client as TrueNASClient
- try:
- # 25.04 and later
- from truenas_api_client.exc import ValidationErrors
- except ImportError:
- # 24.10 and earlier
- from truenas_api_client import ValidationErrors
- else:
- # Mock classes for non-TrueNAS systems
- class TrueNASClient:
- def call(self, *args, **kwargs):
- return None
- class ValidationErrors(Exception):
- def __init__(self, errors):
- self.errors = errors
- class Client:
- def __init__(self, render_instance: "Render"):
- self.client = TrueNASClient()
- self._render_instance = render_instance
- self._app_name: str = self._render_instance.values.get("ix_context", {}).get("app_name", "") or "unknown"
- def validate_ip_port_combo(self, ip: str, port: int) -> None:
- # Example of an error messages:
- # The port is being used by following services: 1) "0.0.0.0:80" used by WebUI Service
- # The port is being used by following services: 1) "0.0.0.0:9998" used by Applications ('$app_name' application)
- try:
- self.client.call("port.validate_port", f"render.{self._app_name}.schema", port, ip, None, True)
- except ValidationErrors as e:
- err_str = str(e)
- # If the IP:port combo appears more than once in the error message,
- # means that the port is used by more than one service/app.
- # This shouldn't happen in a well-configured system.
- # Notice that the ip portion is not included check,
- # because input might be a specific IP, but another service or app
- # might be using the same port on a wildcard IP
- if err_str.count(f':{port}" used by') > 1:
- raise RenderError(err_str) from None
- # If the error complains about the current app, we ignore it
- # This is to handle cases where the app is being updated or edited
- if f"Applications ('{self._app_name}' application)" in err_str:
- # During upgrade, we want to ignore the error if it is related to the current app
- return
- raise RenderError(err_str) from None
- except Exception:
- pass
|