# Kubernetes Control Plane Server Template
# Extracted from wuji infrastructure patterns (real production config)
# Provides control plane server configuration with proven settings

import providers.upcloud.kcl.defaults_upcloud as upcloud_prov
import workspace_templates.lib.compose as comp

# Storage configuration for control plane
schema ControlPlaneStorage {
    name: str = "root"
    size: int = 35
    total: int = 80
    parts: [any] = [
        {name = "root", size = 35, type = "ext4", mount = True, mount_path = "/"}
        {name = "kluster", size = 45, type = "xfs", mount = True, mount_path = "/kluster"}
    ]
}

# Base control plane server configuration from wuji production
schema ControlPlaneServer {
    # Basic server configuration
    hostname: str  # Must be provided (e.g., "{infra}-cp-0")
    title: str    # Must be provided (e.g., "{Infra} Control-Panel 0")
    plan: str = "2xCPU-4GB"  # Production-tested plan from wuji

    # Storage configuration (production-tested from wuji)
    storages: [ControlPlaneStorage] = [
        ControlPlaneStorage {}
    ]

    # Network configuration
    network_private_ip: str  # Must be provided (e.g., "10.11.1.20")
    liveness_ip: str = "{{network_public_ip}}"
    liveness_port: int = 22
    extra_hostnames: [str] = []  # Will include hostname by default

    # Labels (production patterns from wuji)
    labels: str = "use=k8s-cp"

    # Taskservs for control plane (from wuji production)
    default_taskservs: [any] = [
        {name = "os", profile = "controlpanel"}
        {name = "resolv"}
        {name = "runc"}
        {name = "crun"}
        {name = "youki"}
        {name = "containerd"}
        {name = "kubernetes"}
        {name = "external-nfs"}
    ]

    # Additional taskservs
    additional_taskservs: [any] = []

    # Custom configuration
    custom_config: {str: any} = {}
}

# Template function to create control plane server
def create_control_plane_server [
    infra_name: str,
    private_ip: str,
    additional_taskservs: [any] = [],
    overrides: {str: any} = {}
] -> any {
    let base_config = ControlPlaneServer {
        hostname: $"($infra_name)-cp-0"
        title: $"($infra_name | str title-case) Control-Panel 0"
        network_private_ip: $private_ip
        extra_hostnames: [$"($infra_name)-cp-0"]
        additional_taskservs: $additional_taskservs
    }

    # Apply overrides
    let final_config = comp.deep_merge $base_config $overrides

    # Combine taskservs
    let all_taskservs = $final_config.default_taskservs | append $final_config.additional_taskservs

    # Create UpCloud server configuration
    upcloud_prov.Server_upcloud {
        hostname: $final_config.hostname
        title: $final_config.title
        plan: $final_config.plan
        storages: $final_config.storages | each {|storage|
            upcloud_prov.Storage_upcloud {
                name: $storage.name
                size: $storage.size
                total: $storage.total
                parts: $storage.parts
            }
        }
        labels: $final_config.labels
        network_private_ip: $final_config.network_private_ip
        liveness_ip: $final_config.liveness_ip
        liveness_port: $final_config.liveness_port
        extra_hostnames: $final_config.extra_hostnames
        taskservs: $all_taskservs
    } | comp.deep_merge $final_config.custom_config
}

# Common control plane configurations
control_plane_configs = {
    small: {
        plan: "1xCPU-2GB"
        storages: [{
            name: "root"
            size: 25
            total: 50
            parts: [
                {name = "root", size = 25, type = "ext4", mount = True, mount_path = "/"}
                {name = "kluster", size = 25, type = "xfs", mount = True, mount_path = "/kluster"}
            ]
        }]
    }
    standard: {
        plan: "2xCPU-4GB"  # Default from wuji
    }
    large: {
        plan: "4xCPU-8GB"
        storages: [{
            name: "root"
            size: 50
            total: 120
            parts: [
                {name = "root", size = 50, type = "ext4", mount = True, mount_path = "/"}
                {name = "kluster", size = 70, type = "xfs", mount = True, mount_path = "/kluster"}
            ]
        }]
    }
}

# Export the template for use in infrastructure
_server = upcloud_prov.Server_upcloud {
    hostname = "cp-0"
    title = "Control Plane 0"
    plan = "2xCPU-4GB"
    storages = [
        {
            name = "root"
            size = 35
            total = 80
            parts = [
                {name = "root", size = 35, type = "ext4", mount = True, mount_path = "/"}
                {name = "kluster", size = 45, type = "xfs", mount = True, mount_path = "/kluster"}
            ]
        }
    ]
    labels = "use=k8s-cp"
    network_private_ip = "10.11.1.20"
    liveness_ip = "{{network_public_ip}}"
    liveness_port = 22
    extra_hostnames = ["cp-0"]
    taskservs = [
        {name = "os", profile = "controlpanel"}
        {name = "resolv"}
        {name = "runc"}
        {name = "crun"}
        {name = "youki"}
        {name = "containerd"}
        {name = "kubernetes"}
        {name = "external-nfs"}
    ]
}

_server
