"""Models for Docker API.""" from __future__ import annotations from dataclasses import dataclass, field from enum import IntEnum, StrEnum from typing import Any from mashumaro import field_options from mashumaro.mixins.orjson import DataClassORJSONMixin class DockerContainerState(StrEnum): """Possible states of a Docker container.""" CREATED = "created" RESTARTING = "restarting" RUNNING = "running" REMOVING = "removing" PAUSED = "paused" EXITED = "exited" DEAD = "dead" class EndpointStatus(IntEnum): """Portainer endpoint status.""" UP = 1 DOWN = 2 class StackStatus(IntEnum): """Portainer stack status.""" ACTIVE = 1 INACTIVE = 2 class StackType(IntEnum): """Portainer stack type.""" SWARM = 1 COMPOSE = 2 KUBERNETES = 3 class DockerDFType(StrEnum): """Resource type filter for Docker system df.""" CONTAINER = "container" IMAGE = "image" VOLUME = "volume" BUILD_CACHE = "build-cache" @dataclass(slots=True, kw_only=True) class DockerContainerCPUStats: """Represents CPU statistics for a Docker container.""" cpu_system_usage: float | None = None cpu_system_percentage: float | None = None online_cpus: int | None = None cpu_kernel_usage: float | None = None cpu_kernel_percentage: float | None = None cpu_user_usage: float | None = None cpu_user_percentage: float | None = None container_stats: Any = None container_prev_stats: Any = None @dataclass class LocalImageInformation(DataClassORJSONMixin): # pylint: disable=too-many-instance-attributes """Represents the local image information, from the Docker daemon.""" id: str = field(metadata=field_options(alias="Id")) repo_tags: list[str] | None = field(default=None, metadata=field_options(alias="RepoTags")) repo_digests: list[str] | None = field(default=None, metadata=field_options(alias="RepoDigests")) parent: str | None = field(default=None, metadata=field_options(alias="Parent")) comment: str | None = field(default=None, metadata=field_options(alias="Comment")) created: str | None = field(default=None, metadata=field_options(alias="Created")) container: str | None = field(default=None, metadata=field_options(alias="Container")) container_config: dict[str, Any] | None = field(default=None, metadata=field_options(alias="ContainerConfig")) docker_version: str | None = field(default=None, metadata=field_options(alias="DockerVersion")) author: str | None = field(default=None, metadata=field_options(alias="Author")) config: dict[str, Any] | None = field(default=None, metadata=field_options(alias="Config")) architecture: str | None = field(default=None, metadata=field_options(alias="Architecture")) variant: str | None = field(default=None, metadata=field_options(alias="Variant")) os: str | None = field(default=None, metadata=field_options(alias="Os")) os_version: str | None = field(default=None, metadata=field_options(alias="OsVersion")) size: int | None = field(default=None, metadata=field_options(alias="Size")) virtual_size: int | None = field(default=None, metadata=field_options(alias="VirtualSize")) graph_driver: dict[str, Any] | None = field(default=None, metadata=field_options(alias="GraphDriver")) root_fs: dict[str, Any] | None = field(default=None, metadata=field_options(alias="RootFS")) metadata: dict[str, Any] | None = field(default=None, metadata=field_options(alias="Metadata")) labels: dict[str, str] | None = field(default=None, metadata=field_options(alias="Labels")) @dataclass class ImageInformation(DataClassORJSONMixin): """Represents the image information, from the registry.""" descriptor: ImageManifestDescriptor | None = field(default=None, metadata=field_options(alias="Descriptor")) platforms: list[ImageManifestDescriptorPlatform] | None = field(default=None, metadata=field_options(alias="Platforms")) @dataclass class ImageManifestDescriptorPlatform(DataClassORJSONMixin): """Represents the platform information of an image manifest descriptor.""" architecture: str | None = None os: str | None = None variant: str | None = None os_version: str | None = field(default=None, metadata=field_options(alias="os.version")) os_features: list[str] | None = field(default=None, metadata=field_options(alias="os.features")) @dataclass class ImageManifestDescriptor(DataClassORJSONMixin): """Represents an image manifest descriptor.""" digest: str | None = None size: int | None = None urls: list[str] | None = None annotations: dict[str, str] | None = None data: Any | None = None platform: ImageManifestDescriptorPlatform | None = None media_type: str | None = field(default=None, metadata=field_options(alias="mediaType")) artifact_type: Any | None = field(default=None, metadata=field_options(alias="artifactType")) @dataclass class Port(DataClassORJSONMixin): """Represents a port mapping for a Docker container.""" private_port: int | None = field(default=None, metadata=field_options(alias="PrivatePort")) public_port: int | None = field(default=None, metadata=field_options(alias="PublicPort")) type: str | None = field(default=None, metadata=field_options(alias="Type")) @dataclass class HostConfig(DataClassORJSONMixin): """Represents the host configuration for a Docker container.""" annotations: dict[str, str] | None = None network_mode: str | None = field(default=None, metadata=field_options(alias="NetworkMode")) @dataclass class IPAMConfig(DataClassORJSONMixin): """Represents the IP Address Management (IPAM) configuration for a Docker container.""" ipv4_address: str | None = field(default=None, metadata=field_options(alias="IPv4Address")) ipv6_address: str | None = field(default=None, metadata=field_options(alias="IPv6Address")) link_local_ips: list[str] | None = field(default=None, metadata=field_options(alias="LinkLocalIPs")) @dataclass class Network(DataClassORJSONMixin): """Represents the network configuration for a Docker container.""" endpoint_id: str = field(metadata=field_options(alias="EndpointID")) links: list[str] | None = field(default=None, metadata=field_options(alias="Links")) aliases: list[str] | None = field(default=None, metadata=field_options(alias="Aliases")) gateway: str | None = field(default=None, metadata=field_options(alias="Gateway")) ipam_config: IPAMConfig | None = field(default=None, metadata=field_options(alias="IPAMConfig")) mac_address: str | None = field(default=None, metadata=field_options(alias="MacAddress")) driver_opts: dict[str, str] | None = field(default=None, metadata=field_options(alias="DriverOpts")) network_id: str | None = field(default=None, metadata=field_options(alias="NetworkID")) ip_address: str | None = field(default=None, metadata=field_options(alias="IPAddress")) ip_prefix_len: int | None = field(default=None, metadata=field_options(alias="IPPrefixLen")) ipv6_gateway: str | None = field(default=None, metadata=field_options(alias="IPv6Gateway")) global_ipv6_address: str | None = field(default=None, metadata=field_options(alias="GlobalIPv6Address")) global_ipv6_prefix_len: int | None = field(default=None, metadata=field_options(alias="GlobalIPv6PrefixLen")) dns_names: list[str] | None = field(default=None, metadata=field_options(alias="DNSNames")) @dataclass class NetworkSettings(DataClassORJSONMixin): """Represents the network settings for a Docker container.""" networks: dict[str, Network] | None = field(default=None, metadata=field_options(alias="Networks")) @dataclass class Mount(DataClassORJSONMixin): """Represents a mount point for a Docker container.""" type: str | None = field(default=None, metadata=field_options(alias="Type")) name: str | None = field(default=None, metadata=field_options(alias="Name")) source: str | None = field(default=None, metadata=field_options(alias="Source")) destination: str | None = field(default=None, metadata=field_options(alias="Destination")) driver: str | None = field(default=None, metadata=field_options(alias="Driver")) mode: str | None = field(default=None, metadata=field_options(alias="Mode")) rw: bool | None = field(default=None, metadata=field_options(alias="RW")) propagation: str | None = field(default=None, metadata=field_options(alias="Propagation")) @dataclass class DockerContainer(DataClassORJSONMixin): """Represents a Docker container.""" id: str = field(metadata=field_options(alias="Id")) names: list[str] = field(default_factory=list, metadata=field_options(alias="Names")) image: str | None = field(default=None, metadata=field_options(alias="Image")) command: str | None = field(default=None, metadata=field_options(alias="Command")) created: str | None = field(default=None, metadata=field_options(alias="Created")) ports: list[Port] | None = field(default=None, metadata=field_options(alias="Ports")) labels: dict[str, str] | None = field(default=None, metadata=field_options(alias="Labels")) state: str | None = field(default=None, metadata=field_options(alias="State")) status: str | None = field(default=None, metadata=field_options(alias="Status")) mounts: list[Mount] | None = field(default=None, metadata=field_options(alias="Mounts")) image_id: str | None = field(default=None, metadata=field_options(alias="ImageID")) image_manifest_descriptor: ImageManifestDescriptor | None = field(default=None, metadata=field_options(alias="ImageManifestDescriptor")) size_rw: str | None = field(default=None, metadata=field_options(alias="SizeRw")) size_root_fs: str | None = field(default=None, metadata=field_options(alias="SizeRootFs")) host_config: HostConfig | None = field(default=None, metadata=field_options(alias="HostConfig")) network_settings: NetworkSettings | None = field(default=None, metadata=field_options(alias="NetworkSettings")) @dataclass class PidsStats(DataClassORJSONMixin): """Represents PID statistics for a Docker container.""" current: int | None = None @dataclass class NetworkStats(DataClassORJSONMixin): """Represents network statistics for a Docker container interface.""" rx_bytes: int | None = None rx_dropped: int | None = None rx_errors: int | None = None rx_packets: int | None = None tx_bytes: int | None = None tx_dropped: int | None = None tx_errors: int | None = None tx_packets: int | None = None @dataclass class MemoryStatsDetails(DataClassORJSONMixin): # pylint: disable=too-many-instance-attributes """Represents detailed memory statistics for a Docker container.""" total_pgmajfault: int = field(default=0) cache: int = field(default=0) mapped_file: int = field(default=0) total_inactive_file: int = field(default=0) pgpgout: int = field(default=0) rss: int = field(default=0) total_mapped_file: int = field(default=0) writeback: int = field(default=0) unevictable: int = field(default=0) pgpgin: int = field(default=0) total_unevictable: int = field(default=0) pgmajfault: int = field(default=0) total_rss: int = field(default=0) total_rss_huge: int = field(default=0) total_writeback: int = field(default=0) total_inactive_anon: int = field(default=0) rss_huge: int = field(default=0) hierarchical_memory_limit: int = field(default=0) total_pgfault: int = field(default=0) total_active_file: int = field(default=0) active_anon: int = field(default=0) total_active_anon: int = field(default=0) total_pgpgout: int = field(default=0) total_cache: int = field(default=0) inactive_anon: int = field(default=0) active_file: int = field(default=0) pgfault: int = field(default=0) inactive_file: int = field(default=0) total_pgpgin: int = field(default=0) @dataclass class MemoryStats(DataClassORJSONMixin): """Represents memory statistics for a Docker container.""" stats: MemoryStatsDetails = field(default_factory=MemoryStatsDetails) max_usage: int = field(default=0) usage: int = field(default=0) failcnt: int = field(default=0) limit: int = field(default=0) @dataclass class ThrottlingData(DataClassORJSONMixin): """Represents CPU throttling data for a Docker container.""" periods: int = field(default=0) throttled_periods: int = field(default=0) throttled_time: int = field(default=0) @dataclass class CpuUsage(DataClassORJSONMixin): """Represents CPU usage statistics for a Docker container.""" total_usage: int = field(default=0) usage_in_kernelmode: int = field(default=0) usage_in_usermode: int = field(default=0) percpu_usage: list[int] = field(default_factory=list) @dataclass class CpuStats(DataClassORJSONMixin): """Represents CPU statistics for a Docker container.""" cpu_usage: CpuUsage = field(default_factory=CpuUsage) system_cpu_usage: int = field(default=0) online_cpus: int = field(default=0) throttling_data: ThrottlingData = field(default_factory=ThrottlingData) @dataclass class DockerContainerStats(DataClassORJSONMixin): """Represents Docker container statistics.""" read: str = field(default="") preread: str = field(default="") pids_stats: PidsStats = field(default_factory=PidsStats) networks: dict[str, NetworkStats] = field(default_factory=dict) memory_stats: MemoryStats = field(default_factory=MemoryStats) blkio_stats: dict[str, Any] = field(default_factory=dict) cpu_stats: CpuStats = field(default_factory=CpuStats) precpu_stats: CpuStats | None = field(default_factory=CpuStats) @dataclass class PortainerImageUpdateStatus: """Represents the result of checking if a Docker image has an update available.""" update_available: bool local_digest: str | None = None registry_digest: str | None = None @dataclass class DockerImagePruneResponse(DataClassORJSONMixin): """Represents the response from pruning Docker images.""" images_deleted: list[str] | None = field(default_factory=list, metadata=field_options(alias="ImagesDeleted")) space_reclaimed: int | None = field(default=0, metadata=field_options(alias="SpaceReclaimed")) @dataclass class DockerSystemDFAttribute(DataClassORJSONMixin): """Represents Docker system disk usage attribute.""" active_count: int | None = field(default=None, metadata=field_options(alias="ActiveCount")) total_count: int | None = field(default=None, metadata=field_options(alias="TotalCount")) reclaimable: int | None = field(default=None, metadata=field_options(alias="Reclaimable")) total_size: int | None = field(default=None, metadata=field_options(alias="TotalSize")) items: list[Any] | None = field(default=None, metadata=field_options(alias="Items")) @dataclass class DockerSystemDF(DataClassORJSONMixin): """Represents Docker system disk usage information.""" image_disk_usage: DockerSystemDFAttribute = field(default_factory=DockerSystemDFAttribute, metadata=field_options(alias="ImageUsage")) container_disk_usage: DockerSystemDFAttribute = field(default_factory=DockerSystemDFAttribute, metadata=field_options(alias="ContainerUsage")) volume_disk_usage: DockerSystemDFAttribute = field(default_factory=DockerSystemDFAttribute, metadata=field_options(alias="VolumeUsage")) build_cache_disk_usage: DockerSystemDFAttribute = field(default_factory=DockerSystemDFAttribute, metadata=field_options(alias="BuildCacheUsage")) @dataclass class DockerEventActor(DataClassORJSONMixin): """Represents the actor of a Docker event.""" id: str | None = field(default=None, metadata=field_options(alias="ID")) attributes: dict[str, str] | None = field(default=None, metadata=field_options(alias="Attributes")) @dataclass class DockerEvent(DataClassORJSONMixin): """Represents a Docker daemon event.""" type: str | None = field(default=None, metadata=field_options(alias="Type")) action: str | None = field(default=None, metadata=field_options(alias="Action")) actor: DockerEventActor | None = field(default=None, metadata=field_options(alias="Actor")) scope: str | None = field(default=None, metadata=field_options(alias="scope")) time: int | None = field(default=None, metadata=field_options(alias="time")) time_nano: int | None = field(default=None, metadata=field_options(alias="timeNano")) @dataclass class DockerVolumeUsageData(DataClassORJSONMixin): """Represents usage data for a Docker volume.""" size: int | None = field(default=None, metadata=field_options(alias="Size")) ref_count: int | None = field(default=None, metadata=field_options(alias="RefCount")) @dataclass class DockerClusterVolumeSecret(DataClassORJSONMixin): """Represents a secret for a cluster volume access mode.""" key: str | None = field(default=None, metadata=field_options(alias="Key")) secret: str | None = field(default=None, metadata=field_options(alias="Secret")) @dataclass class DockerClusterVolumeCapacityRange(DataClassORJSONMixin): """Represents a capacity range for a cluster volume.""" required_bytes: int | None = field(default=None, metadata=field_options(alias="RequiredBytes")) limit_bytes: int | None = field(default=None, metadata=field_options(alias="LimitBytes")) @dataclass class DockerClusterVolumeAccessMode(DataClassORJSONMixin): """Represents the access mode for a cluster volume.""" scope: str | None = field(default=None, metadata=field_options(alias="Scope")) sharing: str | None = field(default=None, metadata=field_options(alias="Sharing")) mount_volume: dict[str, Any] | None = field(default=None, metadata=field_options(alias="MountVolume")) secrets: list[DockerClusterVolumeSecret] | None = field(default=None, metadata=field_options(alias="Secrets")) accessibility_requirements: dict[str, Any] | None = field(default=None, metadata=field_options(alias="AccessibilityRequirements")) capacity_range: DockerClusterVolumeCapacityRange | None = field(default=None, metadata=field_options(alias="CapacityRange")) availability: str | None = field(default=None, metadata=field_options(alias="Availability")) @dataclass class DockerClusterVolumeSpec(DataClassORJSONMixin): """Represents the spec of a cluster volume.""" group: str | None = field(default=None, metadata=field_options(alias="Group")) access_mode: DockerClusterVolumeAccessMode | None = field(default=None, metadata=field_options(alias="AccessMode")) @dataclass class DockerClusterVolumeInfo(DataClassORJSONMixin): """Represents the info of a cluster volume.""" capacity_bytes: int | None = field(default=None, metadata=field_options(alias="CapacityBytes")) volume_context: dict[str, str] | None = field(default=None, metadata=field_options(alias="VolumeContext")) volume_id: str | None = field(default=None, metadata=field_options(alias="VolumeID")) accessible_topology: list[dict[str, str]] | None = field(default=None, metadata=field_options(alias="AccessibleTopology")) @dataclass class DockerClusterVolumePublishStatus(DataClassORJSONMixin): """Represents the publish status of a cluster volume.""" node_id: str | None = field(default=None, metadata=field_options(alias="NodeID")) state: str | None = field(default=None, metadata=field_options(alias="State")) publish_context: dict[str, str] | None = field(default=None, metadata=field_options(alias="PublishContext")) @dataclass class DockerClusterVolumeVersion(DataClassORJSONMixin): """Represents the version of a cluster volume.""" index: int | None = field(default=None, metadata=field_options(alias="Index")) @dataclass class DockerClusterVolume(DataClassORJSONMixin): """Represents a cluster volume attached to a Docker volume.""" id: str | None = field(default=None, metadata=field_options(alias="ID")) version: DockerClusterVolumeVersion | None = field(default=None, metadata=field_options(alias="Version")) created_at: str | None = field(default=None, metadata=field_options(alias="CreatedAt")) updated_at: str | None = field(default=None, metadata=field_options(alias="UpdatedAt")) spec: DockerClusterVolumeSpec | None = field(default=None, metadata=field_options(alias="Spec")) info: DockerClusterVolumeInfo | None = field(default=None, metadata=field_options(alias="Info")) publish_status: list[DockerClusterVolumePublishStatus] | None = field(default=None, metadata=field_options(alias="PublishStatus")) @dataclass class DockerVolume(DataClassORJSONMixin): """Represents a Docker volume.""" name: str = field(metadata=field_options(alias="Name")) driver: str | None = field(default=None, metadata=field_options(alias="Driver")) mountpoint: str | None = field(default=None, metadata=field_options(alias="Mountpoint")) created_at: str | None = field(default=None, metadata=field_options(alias="CreatedAt")) status: dict[str, Any] | None = field(default=None, metadata=field_options(alias="Status")) labels: dict[str, str] | None = field(default=None, metadata=field_options(alias="Labels")) scope: str | None = field(default=None, metadata=field_options(alias="Scope")) cluster_volume: DockerClusterVolume | None = field(default=None, metadata=field_options(alias="ClusterVolume")) options: dict[str, str] | None = field(default=None, metadata=field_options(alias="Options")) usage_data: DockerVolumeUsageData | None = field(default=None, metadata=field_options(alias="UsageData"))