kcl-lang / konfig

KCL Kubernetes Config Abstraction & Composition Module
https://kcl-lang.io
Apache License 2.0
8 stars 7 forks source link

How to add a resource that does not exist in konfig? #14

Closed east4ming closed 3 months ago

east4ming commented 3 months ago

General Question

How do I add a resource that doesn't exist in konfig, such as middleware for traefik? Please help me with an example.

My base/base.k reads as follows.

import konfig.models.kube.frontend
import konfig.models.kube.frontend.service
import konfig.models.kube.frontend.container
import konfig.models.kube.frontend.container.port.container_port
import konfig.models.kube.frontend.serviceaccount as sa
import konfig.models.kube.frontend.rbac
import konfig.models.kube.utils

appPort: container_port.ContainerPort.containerPort = 8989
appOrg: str = "cnrancher"
appBuilder: utils.ApplicationBuilder = utils.ApplicationBuilder {}

rbac.ClusterRoleBinding {
    name = option("app")
    labels: appBuilder.labels
    metadata: {}
    subjects = [{
        kind = "ServiceAccount"
        name = option("app")
        namespace = option("app")
    }]
    roleRef = {
        apiGroup = "rbac.authorization.k8s.io"
        kind = "ClusterRole"
        name = "cluster-admin"
    }
}
# Application Configuration
appConfiguration: frontend.Server {
    # Main Container Configuration
    mainContainer = container.Main {
        ports = [{containerPort = appPort}]
        args = [
            "--https-listen-port=0"
            "--http-listen-port=" + str(appPort)
        ]
    }
    image = appOrg + "/" + option("app") + ":" + "latest"
    services = [service.Service {
        name = option("app")
        type = "ClusterIP"
        ports = [{
            port = appPort
            targetPort = appPort
        }]
        labels: appBuilder.labels
    }]
    serviceAccount = sa.ServiceAccount {
        name = option("app")
        labels: appBuilder.labels
    }
}

How should I write my dev/main.k, my current one looks like this, traefik doesn't generate it correctly, so I commented it out.

kcl mod add traefik
import konfig.models.kube.frontend
import konfig.models.kube.templates.resource as res_tpl
import konfig.models.kube.frontend.ingress
import traefik.v1alpha1.traefik_io_v1alpha1_middleware as mw

# appMW: mw.Middleware {
#     metadata = {
#         name = option("app")
#         namespace = option("app")
#         labels: appBuilder.labels
#     }
#     spec = {
#         basicAuth = {
#             secret = option("app")
#             removeHeader = True
#         }
#     }
# }

# Or?
# mw = {
#     apiVersion = "traefik.containo.us/v1alpha1"
#     kind = "Middleware"
#     metadata = {
#         name = option("app")
#         namespace = option("app")
#         labels = {app = option("app")}
#     }
#     spec = {
#         basicAuth = {
#             secret = option("app")
#             removeHeader = True
#         }
#     }
# }
appConfiguration: frontend.Server {
    schedulingStrategy.resource = res_tpl.tiny
    secrets = [{
        # name = option("app")
        data = {auth = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}
    }]
    ingresses = [ingress.Ingress {
        name = option("app")
        labels: appBuilder.labels
        annotations = {
            "traefik.ingress.kubernetes.io/router.middlewares": "{}-{}@kubernetescrd".format(option("app"), option("app"))
            "traefik.ingress.kubernetes.io/router.entrypoints": "websecure"
        }
        rules = [{
            host = "example.com"
            http.paths = [{
                path = "/"
                pathType = "Prefix"
                backend.service: {
                    name = option("app")
                    port.number = appPort
                }
            }]
        }]
    }]
} 

Thks

Peefy commented 3 months ago

Hello @east4ming

I've added a simple example here: https://github.com/kcl-lang/konfig/pull/15

You can refer to and adjust according to your scene requirements.