Skip to content

Merging hand-written code into one package #33

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Mar 12, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 0 additions & 23 deletions kubeconfig/package.yaml

This file was deleted.

9 changes: 0 additions & 9 deletions kubernetes-client-helper/.gitignore

This file was deleted.

21 changes: 0 additions & 21 deletions kubernetes-client-helper/package.yaml

This file was deleted.

2 changes: 1 addition & 1 deletion kubeconfig/.gitignore → kubernetes-client/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ dist-newstyle
cabal.project.local
.cabal-sandbox
cabal.sandbox.config
*.cabal
*.cabal
1 change: 1 addition & 0 deletions kubernetes-client/LICENSE
117 changes: 117 additions & 0 deletions kubernetes-client/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
# kubernetes-client

## Example

```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)
Original file line number Diff line number Diff line change
@@ -1,29 +1,22 @@
# kubernetes-client-helper

Library of convenience functions for working with the `kubernetes` package.

## Example

Include the following packages as dependencies:
- kubernetes
- kubernetes-client-helper
- tls

```haskell
{-# LANGUAGE OverloadedStrings #-}

module Main where

import Data.Function ((&))
import qualified Kubernetes.API.CoreV1
import Kubernetes.Client (dispatchMime)
import Kubernetes.ClientHelper
import Kubernetes.Core (newConfig)
import Kubernetes.MimeTypes (Accept (..), MimeJSON (..))
import Network.TLS (credentialLoadX509)
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
example :: IO ()
example = 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.
Expand All @@ -46,7 +39,8 @@ main = do
dispatchMime
manager
kcfg
(Kubernetes.API.CoreV1.listPodForAllNamespaces (Accept MimeJSON))
(CoreV1.listPodForAllNamespaces (Accept MimeJSON))
>>= print
```
s

main :: IO ()
main = return ()
49 changes: 49 additions & 0 deletions kubernetes-client/package.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
name: kubernetes-client
version: 0.1.0.0
description: |
Client library for interacting with a Kubernetes cluster.

This package contains hand-written code while kubernetes-client-core contains code auto-generated from the OpenAPI spec.
synopsis: Client library for Kubernetes
maintainer: Shimin Guo <[email protected]>
category: Web
license: Apache-2.0
license-file: LICENSE
library:
source-dirs: src
tests:
spec:
main: Spec.hs
source-dirs: test
dependencies:
- kubernetes-client
- hspec
- yaml
example:
main: App.hs
source-dirs: example
dependencies:
- kubernetes-client
extra-source-files:
- test/testdata/*
dependencies:
- base >=4.7 && <5.0
- bytestring >=0.10.0 && <0.11
- aeson >=1.0 && <2.0
- connection
- containers
- data-default-class
- http-client >=0.5 && <0.6
- http-client-tls
- kubernetes-openapi-client-gen == 0.1.0.0

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should change to kubernetes-client-core right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will update it when I regen the code to use the new package name.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

- microlens >= 0.4.3 && <0.5
- mtl >=2.2.1
- pem
- safe-exceptions <0.2
- streaming-bytestring >= 0.1.5 && < 0.2.0
- text >=0.11 && <1.3
- tls
- x509
- x509-system
- x509-store
- x509-validation
9 changes: 9 additions & 0 deletions kubernetes-client/src/Kubernetes/Client.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module Kubernetes.Client
( module Kubernetes.Client.Config
, module Kubernetes.Client.KubeConfig
, module Kubernetes.Client.Watch
) where

import Kubernetes.Client.Config
import Kubernetes.Client.KubeConfig
import Kubernetes.Client.Watch
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{-# LANGUAGE OverloadedStrings #-}

module Kubernetes.ClientHelper where
module Kubernetes.Client.Config where

import qualified Kubernetes.OpenAPI.Core as K
import qualified Kubernetes.OpenAPI.Model as K
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ The official definition of the kubeconfig is defined in https://github.com/kuber

This is a mostly straightforward translation into Haskell, with 'FromJSON' and 'ToJSON' instances defined.
-}
module Kubernetes.KubeConfig where
module Kubernetes.Client.KubeConfig where

import Data.Aeson (FromJSON (..), Options, ToJSON (..),
Value (..), camelTo2, defaultOptions,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE OverloadedStrings #-}
module Kubernetes.Watch.Client
module Kubernetes.Client.Watch
( WatchEvent
, eventType
, eventObject
Expand Down
14 changes: 8 additions & 6 deletions kubeconfig/test/Spec.hs → kubernetes-client/test/Spec.hs
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}

import Data.Aeson (decode, encode, parseJSON, toJSON)
import Data.Maybe (fromJust)
import Data.Yaml (decodeFile)
import Kubernetes.KubeConfig (AuthInfo (..), Cluster (..), Config,
Context (..), getAuthInfo, getCluster,
getContext)
import Data.Aeson (decode, encode, parseJSON,
toJSON)
import Data.Maybe (fromJust)
import Data.Yaml (decodeFile)
import Kubernetes.Client.KubeConfig (AuthInfo (..), Cluster (..),
Config, Context (..),
getAuthInfo, getCluster,
getContext)
import Test.Hspec

main :: IO ()
Expand Down
Loading