move Kubernetes.ClientHelper to its own package to minimize changes to the generated code

This commit is contained in:
Shimin Guo
2018-01-29 06:27:29 +00:00
parent c0923b91bf
commit 96652da057
7 changed files with 91 additions and 55 deletions

View File

@@ -6,48 +6,6 @@ Targeted swagger version: 2.0
OpenAPI-Specification: https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md
## Example
## Usage
```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)
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
(Kubernetes.API.CoreV1.listPodForAllNamespaces (Accept MimeJSON))
>>= print
```
You'll need the following additional package:
- tls
Please refer to the README of the `kubernetes-client-helper` package.

View File

@@ -57,15 +57,6 @@ library
, unordered-containers
, vector >=0.10.9 && <0.13
, katip >=0.4 && < 0.6
-- below are manually added deps
, pem
, x509
, tls
, x509-system
, x509-store
, data-default-class
, connection
, x509-validation
exposed-modules:
Kubernetes
Kubernetes.API.Admissionregistration
@@ -126,8 +117,6 @@ library
Kubernetes.MimeTypes
Kubernetes.Model
Kubernetes.ModelLens
-- below are hand-written modules
Kubernetes.ClientHelper
other-modules:
Paths_kubernetes
default-language: Haskell2010

View File

@@ -1,121 +0,0 @@
{-# LANGUAGE OverloadedStrings #-}
module Kubernetes.ClientHelper where
import qualified Kubernetes.Core as K
import qualified Kubernetes.Model as K
import Control.Exception.Safe (Exception, MonadThrow, throwM)
import Control.Monad.IO.Class (MonadIO, liftIO)
import qualified Data.ByteString as B
import qualified Data.ByteString.Lazy as LazyB
import Data.Default.Class (def)
import Data.Either (rights)
import Data.PEM (pemContent, pemParseBS)
import qualified Data.Text as T
import qualified Data.Text.Encoding as T
import Data.Typeable (Typeable)
import Data.X509 (SignedCertificate,
decodeSignedCertificate)
import qualified Data.X509 as X509
import Data.X509.CertificateStore (makeCertificateStore)
import qualified Data.X509.Validation as X509
import Network.Connection (TLSSettings (..))
import qualified Network.HTTP.Client as NH
import Network.HTTP.Client.TLS (mkManagerSettings)
import Network.TLS (Credential, defaultParamsClient)
import qualified Network.TLS as TLS
import qualified Network.TLS.Extra as TLS
import System.X509 (getSystemCertificateStore)
-- |Sets the master URI in the 'K.KubernetesConfig'.
setMasterURI
:: T.Text -- ^ Master URI
-> K.KubernetesConfig
-> K.KubernetesConfig
setMasterURI server kcfg =
kcfg { K.configHost = (LazyB.fromStrict . T.encodeUtf8) server }
-- |Disables the client-side auth methods validation. This is necessary if you are using client cert authentication.
disableValidateAuthMethods :: K.KubernetesConfig -> K.KubernetesConfig
disableValidateAuthMethods kcfg = kcfg { K.configValidateAuthMethods = False }
-- |Configures the 'K.KubernetesConfig' to use token authentication.
setTokenAuth
:: T.Text -- ^Authentication token
-> K.KubernetesConfig
-> K.KubernetesConfig
setTokenAuth token kcfg = kcfg
{ K.configAuthMethods = [K.AnyAuthMethod (K.AuthApiKeyBearerToken token)]
}
-- |Creates a 'NH.Manager' that can handle TLS.
newManager :: TLS.ClientParams -> IO NH.Manager
newManager cp = NH.newManager (mkManagerSettings (TLSSettings cp) Nothing)
-- |Default TLS settings using the system CA store.
defaultTLSClientParams :: IO TLS.ClientParams
defaultTLSClientParams = do
let defParams = defaultParamsClient "" ""
systemCAStore <- getSystemCertificateStore
return defParams
{ TLS.clientSupported = def
{ TLS.supportedCiphers = TLS.ciphersuite_strong
}
, TLS.clientShared = (TLS.clientShared defParams)
{ TLS.sharedCAStore = systemCAStore
}
}
-- |Don't check whether the cert presented by the server matches the name of the server you are connecting to.
-- This is necessary if you specify the server host by its IP address.
disableServerNameValidation :: TLS.ClientParams -> TLS.ClientParams
disableServerNameValidation cp = cp
{ TLS.clientHooks = (TLS.clientHooks cp)
{ TLS.onServerCertificate = X509.validate
X509.HashSHA256
def
def { X509.checkFQHN = False }
}
}
-- |Insecure mode. The client will not validate the server cert at all.
disableServerCertValidation :: TLS.ClientParams -> TLS.ClientParams
disableServerCertValidation cp = cp
{ TLS.clientHooks = (TLS.clientHooks cp)
{ TLS.onServerCertificate = (\_ _ _ _ -> return [])
}
}
-- |Use a custom CA store.
setCAStore :: [SignedCertificate] -> TLS.ClientParams -> TLS.ClientParams
setCAStore certs cp = cp
{ TLS.clientShared = (TLS.clientShared cp)
{ TLS.sharedCAStore = (makeCertificateStore certs)
}
}
-- |Use a client cert for authentication.
setClientCert :: Credential -> TLS.ClientParams -> TLS.ClientParams
setClientCert cred cp = cp
{ TLS.clientHooks = (TLS.clientHooks cp)
{ TLS.onCertificateRequest = (\_ -> return (Just cred))
}
}
-- |Parses a PEM-encoded @ByteString@ into a list of certificates.
parsePEMCerts :: B.ByteString -> Either String [SignedCertificate]
parsePEMCerts b = do
pems <- pemParseBS b
return $ rights $ map (decodeSignedCertificate . pemContent) pems
data ParsePEMCertsException = ParsePEMCertsException String deriving (Typeable, Show)
instance Exception ParsePEMCertsException
-- |Loads certificates from a PEM-encoded file.
loadPEMCerts :: (MonadIO m, MonadThrow m) => FilePath -> m [SignedCertificate]
loadPEMCerts p = do
liftIO (B.readFile p)
>>= either (throwM . ParsePEMCertsException) return
. parsePEMCerts