Skip to content

Commit de91fe9

Browse files
authored
Merge pull request #33 from guoshimin/merge
Merging hand-written code into one package
2 parents 4955eb4 + d367033 commit de91fe9

File tree

18 files changed

+208
-177
lines changed

18 files changed

+208
-177
lines changed

kubeconfig/package.yaml

Lines changed: 0 additions & 23 deletions
This file was deleted.

kubernetes-client-helper/.gitignore

Lines changed: 0 additions & 9 deletions
This file was deleted.

kubernetes-client-helper/package.yaml

Lines changed: 0 additions & 21 deletions
This file was deleted.

kubeconfig/.gitignore renamed to kubernetes-client/.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@ dist-newstyle
66
cabal.project.local
77
.cabal-sandbox
88
cabal.sandbox.config
9-
*.cabal
9+
*.cabal

kubernetes-client/LICENSE

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../LICENSE

kubernetes-client/README.md

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
# kubernetes-client
2+
3+
## Example
4+
5+
```haskell
6+
{-# LANGUAGE OverloadedStrings #-}
7+
8+
module Main where
9+
10+
import Data.Function ((&))
11+
import Kubernetes.Client (defaultTLSClientParams,
12+
disableServerCertValidation,
13+
disableServerNameValidation,
14+
disableValidateAuthMethods,
15+
loadPEMCerts, newManager,
16+
setCAStore, setClientCert,
17+
setMasterURI, setTokenAuth)
18+
import Kubernetes.OpenAPI (Accept (..), MimeJSON (..),
19+
dispatchMime, newConfig)
20+
import qualified Kubernetes.OpenAPI.API.CoreV1 as CoreV1
21+
import Network.TLS (credentialLoadX509)
22+
23+
main :: IO ()
24+
main = do
25+
-- We need to first create a Kubernetes.Core.KubernetesConfig and a Network.HTTP.Client.Manager.
26+
-- Currently we need to construct these objects manually. Work is underway to construct these
27+
-- objects automatically from a kubeconfig file. See https://github.com/kubernetes-client/haskell/issues/2.
28+
kcfg <-
29+
newConfig
30+
& fmap (setMasterURI "https://mycluster.example.com") -- fill in master URI
31+
& fmap (setTokenAuth "mytoken") -- if using token auth
32+
& fmap disableValidateAuthMethods -- if using client cert auth
33+
myCAStore <- loadPEMCerts "/path/to/ca.crt" -- if using custom CA certs
34+
myCert <- -- if using client cert
35+
credentialLoadX509 "/path/to/client.crt" "/path/to/client.key"
36+
>>= either error return
37+
tlsParams <-
38+
defaultTLSClientParams
39+
& fmap disableServerNameValidation -- if master address is specified as an IP address
40+
& fmap disableServerCertValidation -- if you don't want to validate the server cert at all (insecure)
41+
& fmap (setCAStore myCAStore) -- if using custom CA certs
42+
& fmap (setClientCert myCert) -- if using client cert
43+
manager <- newManager tlsParams
44+
dispatchMime
45+
manager
46+
kcfg
47+
(CoreV1.listPodForAllNamespaces (Accept MimeJSON))
48+
>>= print
49+
```
50+
51+
## Watch Example
52+
Following is a simple example which
53+
just streams to stdout. First some setup - this assumes kubernetes is accessible
54+
at http://localhost:8001, e.g. after running `kubectl proxy`:
55+
56+
```haskell
57+
> import qualified Data.ByteString.Streaming.Char8 as Q
58+
59+
> manager <- newManager defaultManagerSettings
60+
> defaultConfig <- newConfig
61+
> config = defaultConfig { configHost = "http://localhost:8001", configValidateAuthMethods = False }
62+
> request = listEndpointsForAllNamespaces (Accept MimeJSON)
63+
```
64+
65+
Launching 'dispatchWatch' with the above we get a stream of endpoints data:
66+
67+
```haskell
68+
> dispatchWatch manager config request Q.stdout
69+
{"type":\"ADDED\","object":{"kind":\"Endpoints\","apiVersion":"v1","metadata":{"name":"heapster" ....
70+
```
71+
72+
A more complex example involving some ggprocessing of the stream, the following
73+
prints out the event types of each event. First, define functions to allow us apply
74+
a parser to a stream:
75+
76+
77+
```haskell
78+
import Data.Aeson
79+
import qualified Data.ByteString.Streaming.Char8 as Q
80+
import Data.JsonStream.Parser
81+
import qualified Streaming.Prelude as S
82+
83+
-- | Parse the stream using the given parser.
84+
streamParse ::
85+
FromJSON a =>
86+
Parser a
87+
-> Q.ByteString IO r
88+
-> Stream (Of [a]) IO r
89+
streamParse parser byteStream = do
90+
byteStream & Q.lines & parseEvent parser
91+
92+
-- | Parse a single event from the stream.
93+
parseEvent ::
94+
(FromJSON a, Monad m) =>
95+
Parser a
96+
-> Stream (Q.ByteString m) m r
97+
-> Stream (Of [a]) m r
98+
parseEvent parser byteStream = S.map (parseByteString parser) (S.mapped Q.toStrict byteStream)
99+
```
100+
101+
Next, define the parser and apply it to the stream:
102+
103+
```haskell
104+
> eventParser = value :: Parser (WatchEvent V1Endpoints)
105+
> withResponseBody body = streamParse eventParser body & S.map (map eventType)
106+
> dispatchWatch manager config request (S.print . withResponseBody)
107+
[\"ADDED\"]
108+
[\"ADDED\"]
109+
[\"MODIFIED\"]
110+
...
111+
```
112+
113+
Packages in this example:
114+
* Data.Aeson -- from [aeson](https://hackage.haskell.org/package/aeson)
115+
* Data.ByteString.Streaming.Char8 from [streaming-bytestring](https://hackage.haskell.org/package/streaming-bytestring-0.1.5/docs/Data-ByteString-Streaming-Char8.html)
116+
* Data.JsonStream.Parser from [json-stream](https://hackage.haskell.org/package/json-stream-0.4.1.5/docs/Data-JsonStream-Parser.html)
117+
* Streaming.Prelude from [streaming](https://hackage.haskell.org/package/streaming-0.2.0.0/docs/Streaming-Prelude.html)
Lines changed: 18 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,22 @@
1-
# kubernetes-client-helper
2-
3-
Library of convenience functions for working with the `kubernetes` package.
4-
5-
## Example
6-
7-
Include the following packages as dependencies:
8-
- kubernetes
9-
- kubernetes-client-helper
10-
- tls
11-
12-
```haskell
131
{-# LANGUAGE OverloadedStrings #-}
142

153
module Main where
164

17-
import Data.Function ((&))
18-
import qualified Kubernetes.API.CoreV1
19-
import Kubernetes.Client (dispatchMime)
20-
import Kubernetes.ClientHelper
21-
import Kubernetes.Core (newConfig)
22-
import Kubernetes.MimeTypes (Accept (..), MimeJSON (..))
23-
import Network.TLS (credentialLoadX509)
5+
import Data.Function ((&))
6+
import Kubernetes.Client (defaultTLSClientParams,
7+
disableServerCertValidation,
8+
disableServerNameValidation,
9+
disableValidateAuthMethods,
10+
loadPEMCerts, newManager,
11+
setCAStore, setClientCert,
12+
setMasterURI, setTokenAuth)
13+
import Kubernetes.OpenAPI (Accept (..), MimeJSON (..),
14+
dispatchMime, newConfig)
15+
import qualified Kubernetes.OpenAPI.API.CoreV1 as CoreV1
16+
import Network.TLS (credentialLoadX509)
2417

25-
main :: IO ()
26-
main = do
18+
example :: IO ()
19+
example = do
2720
-- We need to first create a Kubernetes.Core.KubernetesConfig and a Network.HTTP.Client.Manager.
2821
-- Currently we need to construct these objects manually. Work is underway to construct these
2922
-- objects automatically from a kubeconfig file. See https://github.com/kubernetes-client/haskell/issues/2.
@@ -46,7 +39,8 @@ main = do
4639
dispatchMime
4740
manager
4841
kcfg
49-
(Kubernetes.API.CoreV1.listPodForAllNamespaces (Accept MimeJSON))
42+
(CoreV1.listPodForAllNamespaces (Accept MimeJSON))
5043
>>= print
51-
```
52-
s
44+
45+
main :: IO ()
46+
main = return ()

kubernetes-client/package.yaml

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
name: kubernetes-client
2+
version: 0.1.0.0
3+
description: |
4+
Client library for interacting with a Kubernetes cluster.
5+
6+
This package contains hand-written code while kubernetes-client-core contains code auto-generated from the OpenAPI spec.
7+
synopsis: Client library for Kubernetes
8+
maintainer: Shimin Guo <[email protected]>
9+
category: Web
10+
license: Apache-2.0
11+
license-file: LICENSE
12+
library:
13+
source-dirs: src
14+
tests:
15+
spec:
16+
main: Spec.hs
17+
source-dirs: test
18+
dependencies:
19+
- kubernetes-client
20+
- hspec
21+
- yaml
22+
example:
23+
main: App.hs
24+
source-dirs: example
25+
dependencies:
26+
- kubernetes-client
27+
extra-source-files:
28+
- test/testdata/*
29+
dependencies:
30+
- base >=4.7 && <5.0
31+
- bytestring >=0.10.0 && <0.11
32+
- aeson >=1.0 && <2.0
33+
- connection
34+
- containers
35+
- data-default-class
36+
- http-client >=0.5 && <0.6
37+
- http-client-tls
38+
- kubernetes-openapi-client-gen == 0.1.0.0
39+
- microlens >= 0.4.3 && <0.5
40+
- mtl >=2.2.1
41+
- pem
42+
- safe-exceptions <0.2
43+
- streaming-bytestring >= 0.1.5 && < 0.2.0
44+
- text >=0.11 && <1.3
45+
- tls
46+
- x509
47+
- x509-system
48+
- x509-store
49+
- x509-validation
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
module Kubernetes.Client
2+
( module Kubernetes.Client.Config
3+
, module Kubernetes.Client.KubeConfig
4+
, module Kubernetes.Client.Watch
5+
) where
6+
7+
import Kubernetes.Client.Config
8+
import Kubernetes.Client.KubeConfig
9+
import Kubernetes.Client.Watch

kubernetes-client-helper/src/Kubernetes/ClientHelper.hs renamed to kubernetes-client/src/Kubernetes/Client/Config.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{-# LANGUAGE OverloadedStrings #-}
22

3-
module Kubernetes.ClientHelper where
3+
module Kubernetes.Client.Config where
44

55
import qualified Kubernetes.OpenAPI.Core as K
66
import qualified Kubernetes.OpenAPI.Model as K

kubeconfig/src/Kubernetes/KubeConfig.hs renamed to kubernetes-client/src/Kubernetes/Client/KubeConfig.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ The official definition of the kubeconfig is defined in https://github.com/kuber
1616
1717
This is a mostly straightforward translation into Haskell, with 'FromJSON' and 'ToJSON' instances defined.
1818
-}
19-
module Kubernetes.KubeConfig where
19+
module Kubernetes.Client.KubeConfig where
2020

2121
import Data.Aeson (FromJSON (..), Options, ToJSON (..),
2222
Value (..), camelTo2, defaultOptions,

kubernetes-watch/src/Kubernetes/Watch/Client.hs renamed to kubernetes-client/src/Kubernetes/Client/Watch.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{-# LANGUAGE FlexibleContexts #-}
22
{-# LANGUAGE OverloadedStrings #-}
3-
module Kubernetes.Watch.Client
3+
module Kubernetes.Client.Watch
44
( WatchEvent
55
, eventType
66
, eventObject

kubeconfig/test/Spec.hs renamed to kubernetes-client/test/Spec.hs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
{-# LANGUAGE OverloadedStrings #-}
22
{-# LANGUAGE ScopedTypeVariables #-}
33

4-
import Data.Aeson (decode, encode, parseJSON, toJSON)
5-
import Data.Maybe (fromJust)
6-
import Data.Yaml (decodeFile)
7-
import Kubernetes.KubeConfig (AuthInfo (..), Cluster (..), Config,
8-
Context (..), getAuthInfo, getCluster,
9-
getContext)
4+
import Data.Aeson (decode, encode, parseJSON,
5+
toJSON)
6+
import Data.Maybe (fromJust)
7+
import Data.Yaml (decodeFile)
8+
import Kubernetes.Client.KubeConfig (AuthInfo (..), Cluster (..),
9+
Config, Context (..),
10+
getAuthInfo, getCluster,
11+
getContext)
1012
import Test.Hspec
1113

1214
main :: IO ()

0 commit comments

Comments
 (0)