Skip to content

Latest commit

 

History

History
466 lines (357 loc) · 12.2 KB

dev.org

File metadata and controls

466 lines (357 loc) · 12.2 KB

nats.dhall

A Dhall package to configure NATS.

NATS.dhall

NATS Package

Include the types for the NATS Server and its Config format.

{
  , Server = ./server/package.dhall
  , Conf = ./conf/package.dhall
  , K8S = ./k8s/package.dhall
}

NATS.Conf

Includes the NATS.Conf format types and NATS.Conf/render.

NATS.Server

Package

{
  , toConf = ./toConf.dhall
  , Config = ./config.dhall
  , ClusterConfig = ./config/cluster.dhall
  , LoggingConfig = ./config/logging.dhall
}

[0/10] [0%] Types

NATS.Server.Config

let ClusterConfig = ./config/cluster.dhall
let LoggingConfig = ./config/logging.dhall

let Config
    : Type
    = { 
        , host : Text
        , port : Natural
        , cluster : Optional ClusterConfig.Type
        , logging : Optional LoggingConfig.Type
      }

let default =
      { 
        , host = "0.0.0.0"
        , port = 4222
        , cluster = None ClusterConfig.Type
        , logging = None LoggingConfig.Type
      }

in  { default = default, Type = Config }

NATS.Server.LoggingConfig

let LoggingConfig
    : Type
    = { 
        , debug : Bool
        , trace : Bool
        , logtime : Bool
      }

let default =
      { , debug = False
        , trace = False
        , logtime = False
      }

in { default = default, Type = LoggingConfig }

NATS.Server.ClusterConfig

https://github.com/nats-io/nats-server/blob/c25e8d4bbe4ec231885ee2778a6945c7f4d945bb/server/opts.go#L959

let ClusterConfig
    : Type
    = { 
        , host : Text
        , port : Natural
        , routes : List Text
        , clusterAdvertise : Text
        , noAdvertise : Bool
      }

let default =
      { , host = "0.0.0.0"
        , port = 6222
        , routes = [] : List Text
        , clusterAdvertise = ""
        , noAdvertise = False
      }

in { default = default, Type = ClusterConfig }

NATS.Server.TLSConfig

https://github.com/nats-io/nats-server/blob/master/server/opts.go#L2876

NATS.Server.AuthorizationConfig

https://github.com/nats-io/nats-server/blob/master/server/opts.go#L2448

NATS.Server.UserConfig
NATS.Server.PermissionsConfig

NATS.Server.AccountsConfig

https://github.com/nats-io/nats-server/blob/master/server/opts.go#L1731

NATS.Server.ServiceImportConfig || NATS.Server.StreamImportConfig

https://github.com/nats-io/nats-server/blob/c25e8d4bbe4ec231885ee2778a6945c7f4d945bb/server/opts.go#L2013

NATS.Server.ServiceExportConfig || NATS.Server.StreamExportConfig

NATS.Server.WebsocketConfig

https://github.com/nats-io/nats-server/blob/master/server/opts.go#L2981

NATS.Server.GatewayConfig

https://github.com/nats-io/nats-server/blob/master/server/opts.go#L1098

NATS.Server.RemoteGatewayConfig

NATS.Server.LeafnodeConfig

https://github.com/nats-io/nats-server/blob/master/server/opts.go#L1300

NATS.Server.RemoteLeafnodeConfig

NATS.Server.JetstreamConfig

https://github.com/nats-io/nats-server/blob/c25e8d4bbe4ec231885ee2778a6945c7f4d945bb/server/opts.go#L1250

Function

toConf

let Natural/equal =
      https://raw.githubusercontent.com/dhall-lang/dhall-lang/v16.0.0/Prelude/Natural/equal

let List/concat =
      https://raw.githubusercontent.com/dhall-lang/dhall-lang/v16.0.0/Prelude/List/concat

let List/map =
      https://raw.githubusercontent.com/dhall-lang/dhall-lang/v16.0.0/Prelude/List/map

let Natural/enumerate =
      https://raw.githubusercontent.com/dhall-lang/dhall-lang/v16.0.0/Prelude/Natural/enumerate

let Config = ./config.dhall
let ClusterConfig = ./config/cluster.dhall
let LoggingConfig = ./config/logging.dhall

let NATS/Cluster = ./cluster.dhall

let NATS/Conf = ../conf/package.dhall

let toConf =
    {- toConf takes a NATS Server Config and generates the NATS/Conf type object
       that can be rendered
    -}
        λ(nats : Config.Type)
       let port = Natural/toInteger nats.port

        -- Initialize empty config
        let empty = [ ] : List { mapKey : Text, mapValue : NATS/Conf.Type }

        -- Add the port, work with records that can be merged
        let clientConf = toMap {
          port = NATS/Conf.integer port
        }

        -- CLUSTER
        --
        let clusterConf = merge 
        {
          , Some = \(cluster : ClusterConfig.Type) -> (toMap {
            , cluster = NATS/Conf.object (toMap { 
                , port = NATS/Conf.integer (Natural/toInteger cluster.port)
              })
            })
          , None = empty
        } nats.cluster

        -- LOGGING
        -- NOTE: Ideally we should omit all the false ones from the output.
        let loggingConf = merge 
        {
          , Some = \(logging : LoggingConfig.Type) -> (toMap {
              , debug = NATS/Conf.bool logging.debug
              , trace = NATS/Conf.bool logging.trace
              , logtime = NATS/Conf.bool logging.logtime
            })
          , None = empty
        } nats.logging

        let conf = List/concat { mapKey : Text, mapValue : NATS/Conf.Type } [ 
           , clientConf
           , clusterConf
           , loggingConf
        ]

        -- Return the list of configured blocks as NATS/Conf types
        in NATS/Conf.object conf
in  toConf

NATS.K8S

Package

{
  , Cluster = ./cluster.dhall
  , toK8S = ./toK8S.dhall
  , toList = ./toList.dhall
}

NATS.K8S.Cluster

let Config = ../server/config.dhall

let Cluster
    : Type
    = { name : Text
      , namespace : Text
      , image : Text
      , size : Natural
      , externalAccess : Bool
      , config : Config.Type
      }

let default =
      { name = None Text
      , namespace = "default"
      , image = "nats:latest"
      , size = 1
      , externalAccess = False
      , config = Config::{=}
      }

in  { default = default, Type = Cluster }

NATS.K8S.toK8S

let kubernetes =
      https://raw.githubusercontent.com/dhall-lang/dhall-kubernetes/v4.0.0/1.17/package.dhall sha256:d9eac5668d5ed9cb3364c0a39721d4694e4247dad16d8a82827e4619ee1d6188

let NATS/Server/toConf = ../server/toConf.dhall

let NATS/Server/Config = ../server/config.dhall

let NATS/Conf/render = ../conf/render

let NATS/K8S/Cluster = ./cluster.dhall

let toK8S =
      λ(nats : NATS/K8S/Cluster.Type) 
        let labels = Some (toMap { app = nats.name })

        let metadata =
              kubernetes.ObjectMeta::{
              , name = nats.name
              , labels
              , namespace = Some nats.namespace
              }

        let cmMetadata =
              kubernetes.ObjectMeta::{
              , name = "${nats.name}-config"
              , labels
              , namespace = Some nats.namespace
              }

        let clientHostPort =
              if    nats.externalAccess
              then  Some nats.config.port
              else  None Natural

        let clientPort =
              kubernetes.ContainerPort::{
              , containerPort = nats.config.port
              , name = Some nats.name
              , hostPort = clientHostPort
              }

        let natsConfFile = "nats.conf"

        let natsConf = NATS/Server/toConf nats.config

        let serverConfig = NATS/Conf/render natsConf

        let cm =
              kubernetes.ConfigMap::{
              , metadata = cmMetadata
              , data = Some
                [ { mapKey = natsConfFile, mapValue = serverConfig } ]
              }

        let configVolume =
              kubernetes.Volume::{
              , name = "config-volume"
              , configMap = Some kubernetes.ConfigMapVolumeSource::{
                , name = Some cmMetadata.name
                }
              }

        let configVolMount =
              kubernetes.VolumeMount::{
              , name = configVolume.name
              , mountPath = "/etc/nats"
              }

        let command =
              [ "/nats-server"
              , "-c"
              , "${configVolMount.mountPath}/${natsConfFile}"
              ]

        let natsContainer =
              kubernetes.Container::{
              , name = "nats"
              , image = Some nats.image
              , ports = Some [ clientPort ]
              , command = Some command
              , volumeMounts = Some [ configVolMount ]
              }

        let sts =
              kubernetes.StatefulSet::{
              , metadata
              , spec = Some kubernetes.StatefulSetSpec::{
                , serviceName = nats.name
                , selector = kubernetes.LabelSelector::{ matchLabels = labels }
                , replicas = Some nats.size
                , template = kubernetes.PodTemplateSpec::{
                  , metadata
                  , spec = Some kubernetes.PodSpec::{
                    , containers = [ natsContainer ]
                    , volumes = Some [ configVolume ]
                    }
                  }
                }
              }

        let svc =
              kubernetes.Service::{
              , metadata
              , spec = Some kubernetes.ServiceSpec::{
                , selector = labels
                , clusterIP = Some "None"
                , ports = Some
                  [ kubernetes.ServicePort::{
                    , name = Some "client"
                    , port = nats.config.port
                    , targetPort = Some
                        (kubernetes.IntOrString.Int nats.config.port)
                    }
                  ]
                }
              }

        in  { StatefulSet = sts, ConfigMap = cm, Service = svc }

in  toK8S

toList

let kind =
      https://raw.githubusercontent.com/dhall-lang/dhall-kubernetes/v4.0.0/1.17/typesUnion.dhall sha256:61d9d79f8de701e9442a796f35cf1761a33c9d60e0dadb09f882c9eb60978323

let kubernetes =
      https://raw.githubusercontent.com/dhall-lang/dhall-kubernetes/v4.0.0/1.17/package.dhall sha256:d9eac5668d5ed9cb3364c0a39721d4694e4247dad16d8a82827e4619ee1d6188

let NATS/K8S/Cluster : Type = {
  , StatefulSet : kubernetes.StatefulSet.Type
  , ConfigMap : kubernetes.ConfigMap.Type
  , Service : kubernetes.Service.Type
}

in let toList =
        λ(nats : NATS/K8S/Cluster)
       { apiVersion = "v1"
        , kind = "List"
        , items =
          [ kind.StatefulSet nats.StatefulSet
          , kind.ConfigMap nats.ConfigMap
          , kind.Service nats.Service
          ]
        }

in  toList