""" Bare Metal Resource Bare metal server management """ from typing import Dict, List from .base import BaseResource class BareMetalResource(BaseResource): """ Bare metal server management Usage: # List bare metal servers servers = client.bare_metal.list() # Create server server = client.bare_metal.create( region="ewr", plan="vbm-4c-32gb", os_id=215 ) """ def list( self, per_page: int = 100, cursor: str = None, tag: str = None, label: str = None, main_ip: str = None, region: str = None, ) -> Dict: """ List bare metal servers Returns: Dict with 'bare_metals' list and 'meta' pagination """ params = {"per_page": per_page} if cursor: params["cursor"] = cursor if tag: params["tag"] = tag if label: params["label"] = label if main_ip: params["main_ip"] = main_ip if region: params["region"] = region return self.client.get("bare-metals", params=params) def list_all(self, **kwargs) -> List[Dict]: """List all bare metal servers (auto-paginate)""" return self.client.paginate("bare-metals", "bare_metals", params=kwargs) def get(self, baremetal_id: str) -> Dict: """ Get bare metal server details Args: baremetal_id: Bare metal ID Returns: Server details """ response = self.client.get(f"bare-metals/{baremetal_id}") return response.get("bare_metal", {}) def create( self, region: str, plan: str, os_id: int = None, script_id: str = None, snapshot_id: str = None, enable_ipv6: bool = False, label: str = None, sshkey_id: List[str] = None, app_id: int = None, image_id: str = None, user_data: str = None, activation_email: bool = False, hostname: str = None, tag: str = None, tags: List[str] = None, reserved_ipv4: str = None, persistent_pxe: bool = False, attach_vpc2: List[str] = None, ) -> Dict: """ Create a bare metal server Args: region: Region ID plan: Plan ID os_id: Operating System ID script_id: Startup script ID snapshot_id: Snapshot ID enable_ipv6: Enable IPv6 label: Server label sshkey_id: SSH key IDs app_id: Application ID image_id: Custom image ID user_data: Cloud-init user data activation_email: Send activation email hostname: Server hostname tag: Deprecated, use tags tags: Tags reserved_ipv4: Reserved IPv4 to assign persistent_pxe: Enable persistent PXE attach_vpc2: VPC 2.0 IDs to attach Returns: Created server details """ data = {"region": region, "plan": plan} if os_id is not None: data["os_id"] = os_id if script_id: data["script_id"] = script_id if snapshot_id: data["snapshot_id"] = snapshot_id if enable_ipv6: data["enable_ipv6"] = enable_ipv6 if label: data["label"] = label if sshkey_id: data["sshkey_id"] = sshkey_id if app_id is not None: data["app_id"] = app_id if image_id: data["image_id"] = image_id if user_data: data["user_data"] = user_data if activation_email: data["activation_email"] = activation_email if hostname: data["hostname"] = hostname if tag: data["tag"] = tag if tags: data["tags"] = tags if reserved_ipv4: data["reserved_ipv4"] = reserved_ipv4 if persistent_pxe: data["persistent_pxe"] = persistent_pxe if attach_vpc2: data["attach_vpc2"] = attach_vpc2 response = self.client.post("bare-metals", data) return response.get("bare_metal", {}) def update( self, baremetal_id: str, user_data: str = None, label: str = None, tag: str = None, tags: List[str] = None, os_id: int = None, app_id: int = None, image_id: str = None, enable_ipv6: bool = None, ) -> Dict: """ Update a bare metal server Args: baremetal_id: Bare metal ID (other args same as create) Returns: Updated server details """ data = {} if user_data is not None: data["user_data"] = user_data if label is not None: data["label"] = label if tag is not None: data["tag"] = tag if tags is not None: data["tags"] = tags if os_id is not None: data["os_id"] = os_id if app_id is not None: data["app_id"] = app_id if image_id is not None: data["image_id"] = image_id if enable_ipv6 is not None: data["enable_ipv6"] = enable_ipv6 response = self.client.patch(f"bare-metals/{baremetal_id}", data) return response.get("bare_metal", {}) def delete(self, baremetal_id: str) -> None: """ Delete a bare metal server Args: baremetal_id: Bare metal ID to delete """ self.client.delete(f"bare-metals/{baremetal_id}") def start(self, baremetal_id: str) -> None: """Start a bare metal server""" self.client.post(f"bare-metals/{baremetal_id}/start") def halt(self, baremetal_id: str) -> None: """Halt a bare metal server""" self.client.post(f"bare-metals/{baremetal_id}/halt") def reboot(self, baremetal_id: str) -> None: """Reboot a bare metal server""" self.client.post(f"bare-metals/{baremetal_id}/reboot") def reinstall(self, baremetal_id: str, hostname: str = None) -> Dict: """ Reinstall a bare metal server Args: baremetal_id: Bare metal ID hostname: New hostname (optional) Returns: Server details """ data = {} if hostname: data["hostname"] = hostname response = self.client.post(f"bare-metals/{baremetal_id}/reinstall", data) return response.get("bare_metal", {}) def get_bandwidth(self, baremetal_id: str) -> Dict: """Get bandwidth usage""" return self.client.get(f"bare-metals/{baremetal_id}/bandwidth") def get_user_data(self, baremetal_id: str) -> Dict: """Get user data""" return self.client.get(f"bare-metals/{baremetal_id}/user-data") def get_upgrades(self, baremetal_id: str, upgrade_type: str = None) -> Dict: """Get available upgrades""" params = {} if upgrade_type: params["type"] = upgrade_type return self.client.get(f"bare-metals/{baremetal_id}/upgrades", params=params) def get_vnc(self, baremetal_id: str) -> Dict: """Get VNC URL""" return self.client.get(f"bare-metals/{baremetal_id}/vnc") # IPv4 management def list_ipv4(self, baremetal_id: str) -> List[Dict]: """List IPv4 addresses""" response = self.client.get(f"bare-metals/{baremetal_id}/ipv4") return response.get("ipv4s", []) def list_ipv6(self, baremetal_id: str) -> List[Dict]: """List IPv6 addresses""" response = self.client.get(f"bare-metals/{baremetal_id}/ipv6") return response.get("ipv6s", []) # VPC 2.0 def list_vpc2(self, baremetal_id: str) -> List[Dict]: """List attached VPC 2.0 networks""" response = self.client.get(f"bare-metals/{baremetal_id}/vpc2") return response.get("vpcs", []) def attach_vpc2( self, baremetal_id: str, vpc_id: str, ip_address: str = None ) -> None: """Attach VPC 2.0 to bare metal""" data = {"vpc_id": vpc_id} if ip_address: data["ip_address"] = ip_address self.client.post(f"bare-metals/{baremetal_id}/vpc2/attach", data) def detach_vpc2(self, baremetal_id: str, vpc_id: str) -> None: """Detach VPC 2.0 from bare metal""" self.client.post(f"bare-metals/{baremetal_id}/vpc2/detach", {"vpc_id": vpc_id})