# kubernetes-client ## Example ### Load KubeConfig file ```haskell import Control.Concurrent.STM (atomically, newTVar) import Kubernetes.Client (KubeConfigSource (..), mkKubeClientConfig) import Kubernetes.OpenAPI (Accept (..), MimeJSON (..), dispatchMime) import qualified Data.Map as Map import qualified Kubernetes.OpenAPI.API.CoreV1 as CoreV1 main :: IO () main = do oidcCache <- atomically $ newTVar $ Map.fromList [] (mgr, kcfg) <- mkKubeClientConfig oidcCache $ KubeConfigFile "/path/to/kubeconfig" dispatchMime mgr kcfg (CoreV1.listPodForAllNamespaces (Accept MimeJSON)) >>= print ``` ### Load InCluster Config ```haskell import Control.Concurrent.STM (atomically, newTVar) import Data.Function ((&)) import Kubernetes.Client (KubeConfigSource (..), mkKubeClientConfig) import Kubernetes.OpenAPI (Accept (..), MimeJSON (..), dispatchMime) import Network.TLS (credentialLoadX509) import qualified Data.Map as Map import qualified Kubernetes.OpenAPI.API.CoreV1 as CoreV1 main :: IO () main = do oidcCache <- atomically $ newTVar $ Map.fromList [] (mgr, kcfg) <- mkKubeClientConfig oidcCache KubeConfigCluster dispatchMime mgr kcfg (CoreV1.listPodForAllNamespaces (Accept MimeJSON)) >>= print ``` ### Load config from URL and paths ```haskell {-# LANGUAGE OverloadedStrings #-} module Main where import Data.Function ((&)) import Kubernetes.Client (defaultTLSClientParams, disableServerCertValidation, disableServerNameValidation, disableValidateAuthMethods, loadPEMCerts, newManager, setCAStore, setClientCert, setMasterURI, setTokenAuth) import Kubernetes.OpenAPI (Accept (..), MimeJSON (..), dispatchMime, newConfig) import qualified Kubernetes.OpenAPI.API.CoreV1 as CoreV1 import Network.TLS (credentialLoadX509) main :: IO () main = do -- We need to first create a Kubernetes.Core.KubernetesConfig and a Network.HTTP.Client.Manager. -- Currently we need to construct these objects manually. Work is underway to construct these -- objects automatically from a kubeconfig file. See https://github.com/kubernetes-client/haskell/issues/2. kcfg <- newConfig & fmap (setMasterURI "https://mycluster.example.com") -- fill in master URI & fmap (setTokenAuth "mytoken") -- if using token auth & fmap disableValidateAuthMethods -- if using client cert auth myCAStore <- loadPEMCerts "/path/to/ca.crt" -- if using custom CA certs myCert <- -- if using client cert credentialLoadX509 "/path/to/client.crt" "/path/to/client.key" >>= either error return tlsParams <- defaultTLSClientParams & fmap disableServerNameValidation -- if master address is specified as an IP address & fmap disableServerCertValidation -- if you don't want to validate the server cert at all (insecure) & fmap (setCAStore myCAStore) -- if using custom CA certs & fmap (setClientCert myCert) -- if using client cert manager <- newManager tlsParams dispatchMime manager kcfg (CoreV1.listPodForAllNamespaces (Accept MimeJSON)) >>= print ``` ## Watch Example Following is a simple example which just streams to stdout. First some setup - this assumes kubernetes is accessible at http://localhost:8001, e.g. after running `kubectl proxy`: ```haskell > import qualified Data.ByteString.Streaming.Char8 as Q > manager <- newManager defaultManagerSettings > defaultConfig <- newConfig > config = defaultConfig { configHost = "http://localhost:8001", configValidateAuthMethods = False } > request = listEndpointsForAllNamespaces (Accept MimeJSON) ``` Launching 'dispatchWatch' with the above we get a stream of endpoints data: ```haskell > dispatchWatch manager config request Q.stdout {"type":\"ADDED\","object":{"kind":\"Endpoints\","apiVersion":"v1","metadata":{"name":"heapster" .... ``` A more complex example involving some ggprocessing of the stream, the following prints out the event types of each event. First, define functions to allow us apply a parser to a stream: ```haskell import Data.Aeson import qualified Data.ByteString.Streaming.Char8 as Q import Data.JsonStream.Parser import qualified Streaming.Prelude as S -- | Parse the stream using the given parser. streamParse :: FromJSON a => Parser a -> Q.ByteString IO r -> Stream (Of [a]) IO r streamParse parser byteStream = do byteStream & Q.lines & parseEvent parser -- | Parse a single event from the stream. parseEvent :: (FromJSON a, Monad m) => Parser a -> Stream (Q.ByteString m) m r -> Stream (Of [a]) m r parseEvent parser byteStream = S.map (parseByteString parser) (S.mapped Q.toStrict byteStream) ``` Next, define the parser and apply it to the stream: ```haskell > eventParser = value :: Parser (WatchEvent V1Endpoints) > withResponseBody body = streamParse eventParser body & S.map (map eventType) > dispatchWatch manager config request (S.print . withResponseBody) [\"ADDED\"] [\"ADDED\"] [\"MODIFIED\"] ... ``` Packages in this example: * Data.Aeson -- from [aeson](https://hackage.haskell.org/package/aeson) * Data.ByteString.Streaming.Char8 from [streaming-bytestring](https://hackage.haskell.org/package/streaming-bytestring-0.1.5/docs/Data-ByteString-Streaming-Char8.html) * Data.JsonStream.Parser from [json-stream](https://hackage.haskell.org/package/json-stream-0.4.1.5/docs/Data-JsonStream-Parser.html) * Streaming.Prelude from [streaming](https://hackage.haskell.org/package/streaming-0.2.0.0/docs/Streaming-Prelude.html)