@hackage kubernetes-webhook-haskell0.2.0.3

Create Kubernetes Admission Webhooks in Haskell

kubernetes-webhook-haskell

This library lets you create Kubernetes Admission Webhooks in Haskell.

Using webhooks in Kubernetes requires some configuration, in the dhall directory you can find some useful templates that you can reuse to deploy your webhooks. cert-manager is required to be installed in the cluster to use the templates.

Example webhook using Servant:

module Kubernetes.Example
    ( startApp,
    app,
    )
where

import Control.Monad.IO.Class
import qualified Data.Aeson as A
import qualified Data.ByteString as BS
import qualified Data.HashMap.Strict as HM
import Data.Text
import GHC.Generics
import qualified Kubernetes.Webhook as W
import Network.Wai
import Network.Wai.Handler.Warp
import Network.Wai.Handler.WarpTLS
import Servant
import System.Environment

type API =
"mutate" :> ReqBody '[JSON] W.AdmissionReviewRequest :> Post '[JSON] W.AdmissionReviewResponse

data Toleration
= Toleration
    { effect :: Maybe TolerationEffect,
        key :: Maybe Text,
        operator :: Maybe TolerationOperator,
        tolerationSeconds :: Maybe Integer,
        value :: Maybe Text
    }
deriving (Generic, A.ToJSON)

data TolerationEffect = NoSchedule | PreferNoSchedule | NoExecute deriving (Generic, A.ToJSON)

data TolerationOperator = Exists | Equal deriving (Generic, A.ToJSON)

testToleration :: Toleration
testToleration =
Toleration
    { effect = Just NoSchedule,
    key = Just "dedicated",
    operator = Just Equal,
    tolerationSeconds = Nothing,
    value = Just "test"
    }

startApp :: IO ()
startApp = do
let tlsOpts = tlsSettings "/certs/tls.crt" "/certs/tls.key"
    warpOpts = setPort 8080 defaultSettings
runTLS tlsOpts warpOpts app

app :: Application
app = serve api server

api :: Proxy API
api = Proxy

server :: Server API
server = mutate

mutate :: W.AdmissionReviewRequest -> Handler W.AdmissionReviewResponse
mutate req = pure $ W.mutatingWebhook req (\_ -> Right addToleration)

addToleration :: W.Patch
addToleration = 
W.Patch
    [ W.PatchOperation
        { op = W.Add,
        path = "/spec/tolerations/-",
        from = Nothing,
        value = Just $ A.toJSON testToleration
        }
    ]