packages feed

mackerel-client 0.0.4 → 0.0.5

raw patch · 13 files changed

+251/−13 lines, 13 files

Files

README.md view
@@ -28,7 +28,7 @@ ```  ## Author-itchyny (https://github.com/itchyny)+itchyny <itchyny@hatena.ne.jp>  ## License This software is released under the MIT License, see LICENSE.
mackerel-client.cabal view
@@ -1,7 +1,7 @@ name:                   mackerel-client-version:                0.0.4+version:                0.0.5 author:                 itchyny-maintainer:             itchyny <https://github.com/itchyny>+maintainer:             itchyny <itchyny@hatena.ne.jp> license:                MIT license-file:           LICENSE category:               Web@@ -23,9 +23,11 @@                       , Web.Mackerel.Types                       , Web.Mackerel.Types.Organization                       , Web.Mackerel.Types.User+                      , Web.Mackerel.Types.Invitation                       , Web.Mackerel.Types.Service                       , Web.Mackerel.Types.Role                       , Web.Mackerel.Types.Host+                      , Web.Mackerel.Types.Metadata                       , Web.Mackerel.Types.Monitor                       , Web.Mackerel.Types.Alert                       , Web.Mackerel.Types.Dashboard@@ -33,9 +35,11 @@                       , Web.Mackerel.Api                       , Web.Mackerel.Api.Organization                       , Web.Mackerel.Api.User+                      , Web.Mackerel.Api.Invitation                       , Web.Mackerel.Api.Service                       , Web.Mackerel.Api.Role                       , Web.Mackerel.Api.Host+                      , Web.Mackerel.Api.Metadata                       , Web.Mackerel.Api.Monitor                       , Web.Mackerel.Api.Alert                       , Web.Mackerel.Api.Dashboard@@ -66,12 +70,15 @@   ghc-options:          -Wall   other-modules:        Types.OrganizationSpec                       , Types.UserSpec+                      , Types.InvitationSpec                       , Types.ServiceSpec                       , Types.RoleSpec                       , Types.HostSpec+                      , Types.MetadataSpec                       , Types.MonitorSpec                       , Types.AlertSpec                       , Types.DashboardSpec+                      , Types.GraphAnnotationSpec                       , ConfigSpec   build-depends:        base >= 4.9 && < 5.0                       , mackerel-client
src/Web/Mackerel/Api.hs view
@@ -4,6 +4,8 @@ import Web.Mackerel.Api.Dashboard as Api import Web.Mackerel.Api.GraphAnnotation as Api import Web.Mackerel.Api.Host as Api+import Web.Mackerel.Api.Invitation as Api+import Web.Mackerel.Api.Metadata as Api import Web.Mackerel.Api.Monitor as Api import Web.Mackerel.Api.Organization as Api import Web.Mackerel.Api.Role as Api
+ src/Web/Mackerel/Api/Invitation.hs view
@@ -0,0 +1,19 @@+{-# LANGUAGE OverloadedStrings, TemplateHaskell #-}+-- | Invitation API.+module Web.Mackerel.Api.Invitation (createInvitation, revokeInvitation) where++import Data.Aeson (Value)+import qualified Data.HashMap.Lazy as HM+import Network.HTTP.Types (StdMethod(..))++import Web.Mackerel.Client+import Web.Mackerel.Internal.Api+import Web.Mackerel.Types.Invitation++createInvitation :: Client -> Invitation -> IO (Either ApiError Invitation)+createInvitation client invitation+  = request client POST "/api/v0/invitations" [] (Just invitation) (createHandler id)++revokeInvitation :: Client -> String -> IO (Either ApiError ())+revokeInvitation client email+  = request client POST "/api/v0/invitations/revoke" [] (Just (HM.singleton "email" email :: HM.HashMap String String)) (createHandler ((\_ -> ()) :: Value -> ()))
+ src/Web/Mackerel/Api/Metadata.hs view
@@ -0,0 +1,33 @@+{-# LANGUAGE OverloadedStrings, TemplateHaskell #-}+-- | Metadata API.+module Web.Mackerel.Api.Metadata (getMetadata, putMetadata, deleteMetadata, listMetadata) where++import Data.Aeson (Value)+import Data.Aeson.TH (deriveJSON)+import qualified Data.ByteString.Char8 as BS+import Data.Semigroup ((<>))+import Network.HTTP.Types (StdMethod(..))++import Web.Mackerel.Client+import Web.Mackerel.Internal.Api+import Web.Mackerel.Internal.TH+import Web.Mackerel.Types.Metadata++getMetadata :: Client -> String -> String -> IO (Either ApiError Value)+getMetadata client hostId namespace+  = request client GET ("/api/v0/hosts/" <> BS.pack hostId <> "/metadata/" <> BS.pack namespace) [] emptyBody (createHandler id)++putMetadata :: Client -> String -> String -> Value -> IO (Either ApiError ())+putMetadata client hostId namespace metadata+  = request client PUT ("/api/v0/hosts/" <> BS.pack hostId <> "/metadata/" <> BS.pack namespace) [] (Just metadata) (createHandler ((\_ -> ()) :: Value -> ()))++deleteMetadata :: Client -> String -> String -> IO (Either ApiError ())+deleteMetadata client hostId namespace+  = request client DELETE ("/api/v0/hosts/" <> BS.pack hostId <> "/metadata/" <> BS.pack namespace) [] emptyBody (createHandler ((\_ -> ()) :: Value -> ()))++data ListMetadataResponse = ListMetadataResponse { responseMetadata :: [Metadata] }+$(deriveJSON options ''ListMetadataResponse)++listMetadata :: Client -> String -> IO (Either ApiError [Metadata])+listMetadata client hostId+  = request client GET ("/api/v0/hosts/" <> BS.pack hostId <> "/metadata") [] emptyBody (createHandler responseMetadata)
src/Web/Mackerel/Types.hs view
@@ -4,6 +4,8 @@ import Web.Mackerel.Types.Dashboard as Types import Web.Mackerel.Types.GraphAnnotation as Types import Web.Mackerel.Types.Host as Types+import Web.Mackerel.Types.Invitation as Types+import Web.Mackerel.Types.Metadata as Types import Web.Mackerel.Types.Monitor as Types import Web.Mackerel.Types.Organization as Types import Web.Mackerel.Types.Role as Types
src/Web/Mackerel/Types/Dashboard.hs view
@@ -34,9 +34,7 @@     dashboardId :: DashboardId,     dashboardTitle :: String,     dashboardBodyMarkdown :: String,-    dashboardUrlPath :: String,-    dashboardCreatedAt :: Integer,-    dashboardUpdatedAt :: Integer+    dashboardUrlPath :: String   } deriving (Eq, Show)  $(deriveJSON options ''Dashboard)
+ src/Web/Mackerel/Types/Invitation.hs view
@@ -0,0 +1,43 @@+{-# LANGUAGE TemplateHaskell #-}+module Web.Mackerel.Types.Invitation where++import Data.Aeson+import qualified Data.Aeson as Aeson+import Data.Aeson.TH (deriveJSON)+import Data.Aeson.Types (typeMismatch)+import qualified Data.Text as Text++import Web.Mackerel.Internal.TH++data InvitationAuthority = InvitationAuthorityManager+                         | InvitationAuthorityCollaborator+                         | InvitationAuthorityViewer+                         deriving Eq++instance Show InvitationAuthority where+  show InvitationAuthorityManager = "manager"+  show InvitationAuthorityCollaborator = "collaborator"+  show InvitationAuthorityViewer = "viewer"++instance Read InvitationAuthority where+  readsPrec _ xs = [ (hs, drop (length str) xs) | (hs, str) <- pairs', take (length str) xs == str ]+    where pairs' = [(InvitationAuthorityManager, "manager"), (InvitationAuthorityCollaborator, "collaborator"), (InvitationAuthorityViewer, "viewer")]++instance FromJSON InvitationAuthority where+  parseJSON (Aeson.String txt)+    | str == "manager" = return InvitationAuthorityManager+    | str == "collaborator" = return InvitationAuthorityCollaborator+    | str == "viewer" = return InvitationAuthorityViewer+    where str = Text.unpack txt+  parseJSON o = typeMismatch "InvitationAuthority" o++instance ToJSON InvitationAuthority where+  toJSON method = toJSON (show method)++data Invitation+  = Invitation {+    invitationEmail :: String,+    invitationAuthority :: InvitationAuthority+  } deriving (Eq, Show)++$(deriveJSON options ''Invitation)
+ src/Web/Mackerel/Types/Metadata.hs view
@@ -0,0 +1,13 @@+{-# LANGUAGE TemplateHaskell #-}+module Web.Mackerel.Types.Metadata where++import Data.Aeson.TH (deriveJSON)++import Web.Mackerel.Internal.TH++data Metadata+  = Metadata {+    metadataNamespace :: String+  } deriving (Eq, Show)++$(deriveJSON options ''Metadata)
test/Types/DashboardSpec.hs view
@@ -16,9 +16,7 @@         dashboardId = DashboardId "abcde",         dashboardTitle = "This is a dashboard",         dashboardBodyMarkdown = "# Example\n[example](https://example.com)",-        dashboardUrlPath = "example",-        dashboardCreatedAt = 1483196400,-        dashboardUpdatedAt = 1483282800+        dashboardUrlPath = "example"       }    let json = [aesonQQ|@@ -26,9 +24,7 @@       "id": "abcde",       "title": "This is a dashboard",       "bodyMarkdown": "# Example\n[example](https://example.com)",-      "urlPath": "example",-      "createdAt": 1483196400,-      "updatedAt": 1483282800+      "urlPath": "example"     }   |] @@ -53,7 +49,7 @@     it "should reject an invalid json" $ do       decode "{}" `shouldBe` (Nothing :: Maybe Dashboard)       let (Object hm) = json-      forM_ ["id", "title", "bodyMarkdown", "urlPath", "createdAt", "updatedAt"] $ \key ->+      forM_ ["id", "title", "bodyMarkdown", "urlPath"] $ \key ->         decode (encode (Object (HM.delete key hm))) `shouldBe` (Nothing :: Maybe Dashboard)    describe "Dashboard ToJSON" $
+ test/Types/GraphAnnotationSpec.hs view
@@ -0,0 +1,49 @@+{-# LANGUAGE OverloadedStrings, QuasiQuotes #-}+module Types.GraphAnnotationSpec where++import Control.Monad (forM_)+import Data.Aeson (decode, encode, Value(..))+import Data.Aeson.QQ+import qualified Data.HashMap.Lazy as HM+import Test.Hspec++import Web.Mackerel.Types.GraphAnnotation++spec :: Spec+spec = do++  let graphAnnotation = GraphAnnotation {+        graphAnnotationId = Just $ GraphAnnotationId "abcde",+        graphAnnotationTitle = "Deploy application #123",+        graphAnnotationDescription = "Deploy link: https://example.com/123",+        graphAnnotationFrom = 1485000000,+        graphAnnotationTo = 1485000060,+        graphAnnotationService = "ExampleService",+        graphAnnotationRoles = Just [ "ExampleRole1", "ExampleRole2" ]+      }++  let json = [aesonQQ|+    {+      "id": "abcde",+      "title": "Deploy application #123",+      "description": "Deploy link: https://example.com/123",+      "from": 1485000000,+      "to": 1485000060,+      "service": "ExampleService",+      "roles": [ "ExampleRole1", "ExampleRole2" ]+    }+  |]++  describe "GraphAnnotation FromJSON" $ do+    it "should parse a json" $+      decode (encode json) `shouldBe` Just graphAnnotation++    it "should reject an invalid json" $ do+      decode "{}" `shouldBe` (Nothing :: Maybe GraphAnnotation)+      let (Object hm) = json+      forM_ ["title", "description", "from", "to", "service"] $ \key ->+        decode (encode (Object (HM.delete key hm))) `shouldBe` (Nothing :: Maybe GraphAnnotation)++  describe "GraphAnnotation ToJSON" $+    it "should encode into a json" $+      decode (encode graphAnnotation) `shouldBe` Just json
+ test/Types/InvitationSpec.hs view
@@ -0,0 +1,39 @@+{-# LANGUAGE OverloadedStrings, QuasiQuotes #-}+module Types.InvitationSpec where++import Control.Monad (forM_)+import Data.Aeson (decode, encode, Value(..))+import Data.Aeson.QQ+import qualified Data.HashMap.Lazy as HM+import Test.Hspec++import Web.Mackerel.Types.Invitation++spec :: Spec+spec = do++  let invitation' = Invitation {+        invitationEmail = "foobar@example.com",+        invitationAuthority = InvitationAuthorityManager+      }++  let json = [aesonQQ|+    {+      "email": "foobar@example.com",+      "authority": "manager"+    }+  |]++  describe "Invitation FromJSON" $ do+    it "should parse a json" $+      decode (encode json) `shouldBe` Just invitation'++    it "should reject an invalid json" $ do+      decode "{}" `shouldBe` (Nothing :: Maybe Invitation)+      let (Object hm) = json+      forM_ ["email", "authority"] $ \key ->+        decode (encode (Object (HM.delete key hm))) `shouldBe` (Nothing :: Maybe Invitation)++  describe "invitation ToJSON" $+    it "should encode into a json" $+      decode (encode invitation') `shouldBe` Just json
+ test/Types/MetadataSpec.hs view
@@ -0,0 +1,37 @@+{-# LANGUAGE OverloadedStrings, QuasiQuotes #-}+module Types.MetadataSpec where++import Control.Monad (forM_)+import Data.Aeson (decode, encode, Value(..))+import Data.Aeson.QQ+import qualified Data.HashMap.Lazy as HM+import Test.Hspec++import Web.Mackerel.Types.Metadata++spec :: Spec+spec = do++  let metadata' = Metadata {+        metadataNamespace = "foo-bar-namespace"+      }++  let json = [aesonQQ|+    {+      "namespace": "foo-bar-namespace"+    }+  |]++  describe "Metadata FromJSON" $ do+    it "should parse a json" $+      decode (encode json) `shouldBe` Just metadata'++    it "should reject an invalid json" $ do+      decode "{}" `shouldBe` (Nothing :: Maybe Metadata)+      let (Object hm) = json+      forM_ ["namespace"] $ \key ->+        decode (encode (Object (HM.delete key hm))) `shouldBe` (Nothing :: Maybe Metadata)++  describe "Metadata ToJSON" $+    it "should encode into a json" $+      decode (encode metadata') `shouldBe` Just json