# Kubernetes Storage Node Server Template
# Extracted from wuji infrastructure patterns (real production config)
# Provides storage node server configuration for Ceph/Rook

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

# Storage configuration for storage nodes
schema StorageNodeStorage {
    name: str = "root"
    size: int = 35
    total: int = 80
    parts: [any] = [
        {name = "root", size = 35, type = "ext4", mount = True, mount_path = "/"}
        {name = "ceph_0", size = 25, type = "raw", mount = True, mount_path = ""}
        {name = "ceph_1", size = 20, type = "raw", mount = True, mount_path = ""}
    ]
}

# Base storage node server configuration from wuji production
schema StorageNodeServer {
    # Basic server configuration
    hostname: str  # Must be provided (e.g., "{infra}-strg-0")
    title: str    # Must be provided (e.g., "{Infra} Storage 0")
    plan: str = "2xCPU-4GB"  # Production-tested plan from wuji

    # Storage configuration (optimized for Ceph from wuji)
    storages: [StorageNodeStorage] = [
        StorageNodeStorage {}
    ]

    # Network configuration
    network_private_ip: str  # Must be provided (e.g., "10.11.1.30")
    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-storage"

    # Taskservs for storage nodes (from wuji production)
    default_taskservs: [any] = [
        {name = "os", profile = "worker"}
        {name = "resolv"}
        {name = "runc"}
        {name = "crun"}
        {name = "youki"}
        {name = "containerd"}
        {name = "kubernetes"}
        {name = "kubernetes", profile = "k8s-nodejoin"}
        {name = "external-nfs"}
    ]

    # Additional taskservs
    additional_taskservs: [any] = []

    # Enable/disable the server
    not_use: bool = False

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

# Template function to create storage node server
def create_storage_node_server [
    infra_name: str,
    node_index: int,
    private_ip: str,
    ceph_devices: [str] = ["vda3", "vda4"],
    overrides: {str: any} = {}
] -> any {
    let base_config = StorageNodeServer {
        hostname: $"($infra_name)-strg-($node_index)"
        title: $"($infra_name | str title-case) Storage ($node_index)"
        network_private_ip: $private_ip
        extra_hostnames: [$"($infra_name)-strg-($node_index)"]
        labels: $"use=k8s-($infra_name), use=k8s-storage"
    }

    # 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
        not_use: $final_config.not_use
        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 storage configurations
storage_configs = {
    small: {
        plan: "2xCPU-4GB"
        storages: [{
            name: "root"
            size: 25
            total: 60
            parts: [
                {name = "root", size = 25, type = "ext4", mount = True, mount_path = "/"}
                {name = "ceph_0", size = 35, type = "raw", mount = True, mount_path = ""}
            ]
        }]
    }
    standard: {
        plan: "2xCPU-4GB"  # Default from wuji
    }
    large: {
        plan: "4xCPU-8GB"
        storages: [{
            name: "root"
            size: 50
            total: 200
            parts: [
                {name = "root", size = 50, type = "ext4", mount = True, mount_path = "/"}
                {name = "ceph_0", size = 75, type = "raw", mount = True, mount_path = ""}
                {name = "ceph_1", size = 75, type = "raw", mount = True, mount_path = ""}
            ]
        }]
    }
}

# Export the template for use in infrastructure
_server = upcloud_prov.Server_upcloud {
    hostname = "storage-0"
    title = "Storage Node 0"
    plan = "2xCPU-4GB"
    storages = [
        {
            name = "root"
            size = 35
            total = 80
            parts = [
                {name = "root", size = 35, type = "ext4", mount = True, mount_path = "/"}
                {name = "ceph_0", size = 25, type = "raw", mount = True, mount_path = ""}
                {name = "ceph_1", size = 20, type = "raw", mount = True, mount_path = ""}
            ]
        }
    ]
    labels = "use=k8s-storage"
    network_private_ip = "10.11.1.30"
    liveness_ip = "{{network_public_ip}}"
    liveness_port = 22
    extra_hostnames = ["storage-0"]
    taskservs = [
        {name = "os", profile = "worker"}
        {name = "resolv"}
        {name = "runc"}
        {name = "crun"}
        {name = "youki"}
        {name = "containerd"}
        {name = "kubernetes"}
        {name = "kubernetes", profile = "k8s-nodejoin"}
        {name = "external-nfs"}
    ]
}

_server
