devth/yetibot

View on GitHub
src/yetibot/commands/aws/formatters.clj

Summary

Maintainability
Test Coverage
(ns yetibot.commands.aws.formatters
  (:require
    [clojure.spec.alpha :as s]
    [cognitect.aws.client.api :as aws]
    [yetibot.commands.aws.specs :as aws.spec]
    [yetibot.api.aws]))

(def iam-response-spec (partial aws/response-spec-key yetibot.api.aws/iam))

; AWS API response formatting utility function
(defmulti format-response
          "Returns a dispatch-value matching the operation that has been successfully invoked
          or has failed"
          (fn [response]
            (let [aws-type (:aws/type (meta response))]
              (cond
                (and (s/valid? (iam-response-spec :CreateGroup) response)
                     (= aws-type :aws.type/CreatedGroup)) ::IAMGroupCreated
                (and (s/valid? (iam-response-spec :CreateUser) response)
                     (= aws-type :aws.type/CreatedUser)) ::IAMUserCreated
                (and (s/valid? (iam-response-spec :GetGroup) response)
                     (= aws-type :aws.type/GetGroupResponse)) ::IAMGetGroupResponseReceived
                (and (s/valid? ::aws.spec/UserAddedToGroup response)
                     (= aws-type :aws.type/UserAddedToGroup)) ::IAMUserAddedToGroup
                (and (s/valid? ::aws.spec/UserRemovedFromGroup response)
                     (= aws-type :aws.type/UserRemovedFromGroup)) ::IAMUserRemovedFromGroup
                (and (s/valid? (iam-response-spec :ListGroups) response)
                     (= aws-type :aws.type/ListGroupsResponse)) ::IAMListGroupsResponseReceived
                (and (s/valid? ::aws.spec/UserDeleted response)
                     (= aws-type :aws.type/UserDeleted)) ::IAMUserDeleted
                (and (s/valid? (iam-response-spec :GetUser) response)
                     (= aws-type :aws.type/GetUserResponse)) ::IAMGetUserResponseReceived
                (and (s/valid? (iam-response-spec :ListUsers) response)
                     (= aws-type :aws.type/ListUsersResponse)) ::IAMListUsersResponseReceived
                (and (s/valid? ::aws.spec/GroupDeleted response)
                     (= aws-type :aws.type/GroupDeleted)) ::IAMGroupDeleted
                (and (s/valid? (iam-response-spec :ListPolicies) response)
                     (= aws-type :aws.type/ListPoliciesResponse)) ::IAMListPoliciesResponseReceived
                (and (s/valid? ::aws.spec/IAMUserPolicyAttached response)
                     (= aws-type :aws.type/UserPolicyAttached)) ::IAMUserPolicyAttached
                (and (s/valid? (iam-response-spec :ListAttachedUserPolicies) response)
                     (= aws-type :aws.type/ListAttachedUserPoliciesResponse)) ::IAMListAttachedUserPoliciesResponseReceived
                (and (s/valid? (iam-response-spec :CreateLoginProfile) response)
                     (= aws-type :aws.type/LoginProfileCreated)) ::IAMLoginProfileCreated
                (and (s/valid? ::aws.spec/LoginProfileUpdated response)
                     (= aws-type :aws.type/LoginProfileUpdated)) ::IAMLoginProfileUpdated
                (and (s/valid? (iam-response-spec :CreateAccessKey) response)
                     (= aws-type :aws.type/CreatedAccessKey)) ::IAMAccessKeyCreated
                (and (s/valid? (iam-response-spec :ListAccessKeys) response)
                     (= aws-type :aws.type/ListAccessKeysResponse)) ::IAMListAccessKeysResponseReceived
                (and (s/valid? ::aws.spec/AccessKeyDeleted response)
                     (= aws-type :aws.type/AccessKeyDeleted)) ::IAMAccessKeyDeleted
                :else ::error))))

(defmethod format-response ::error
  [response]
  {:result/error (get-in response [:ErrorResponse :Error :Message])})

(defmethod format-response ::IAMGroupCreated
  [{{:keys [Path GroupName GroupId Arn CreateDate]} :Group}]
  {:result/data  {:path Path, :group-name GroupName, :group-id GroupId, :arn Arn, :create-date CreateDate}
   :result/value (format "Group %s%s [Id=%s, Arn=%s] has been created successfully on %s"
                         Path GroupName GroupId Arn CreateDate)})

(defmethod format-response ::IAMUserCreated
  [{{:keys [Path UserName UserId Arn CreateDate]} :User}]
  {:result/data  {:path Path, :user-name UserName, :user-id UserId, :arn Arn, :create-date CreateDate}
   :result/value (format "User %s%s [Id=%s, Arn=%s] has been created successfully on %s"
                         Path UserName UserId Arn CreateDate)})

(defmethod format-response ::IAMUserAddedToGroup
  [response]
  (let [request-id (get-in response [:AddUserToGroupResponse :ResponseMetadata :RequestId])]
    {:result/data  {:request-id request-id}
     :result/value (format "User successfully added to group [RequestId=%s]"
                           request-id)}))

(defmethod format-response ::IAMUserRemovedFromGroup
  [response]
  (let [request-id (get-in response [:RemoveUserFromGroupResponse :ResponseMetadata :RequestId])]
    {:result/data  {:request-id request-id}
     :result/value (format "User successfully removed from group [RequestId=%s]"
                           request-id)}))

(defmethod format-response ::IAMUserDeleted
  [response]
  (let [request-id (get-in response [:DeleteUserResponse :ResponseMetadata :RequestId])]
    {:result/data  {:request-id request-id}
     :result/value (format "User successfully deleted [RequestId=%s]"
                           request-id)}))

(defmethod format-response ::IAMGroupDeleted
  [response]
  (let [request-id (get-in response [:DeleteGroupResponse :ResponseMetadata :RequestId])]
    {:result/data  {:request-id request-id}
     :result/value (format "Group successfully deleted [RequestId=%s]"
                           request-id)}))

(defmethod format-response ::IAMGetGroupResponseReceived
  [{:keys [Group Users]}]
  (let [{:keys [Path GroupName GroupId Arn CreateDate]} Group]
    {:result/data  {:path Path, :group-name GroupName, :group-id GroupId, :arn Arn, :create-date CreateDate, :users Users}
     :result/value (conj (map #(format "User : %s%s [UserId=%s, Arn=%s] - Created on %s"
                                       (:Path %) (:UserName %) (:UserId %) (:Arn %) (:CreateDate %))
                              Users)
                         (format "Group : %s%s\nGroupId : %s\nArn : %s\nCreateDate : %s\n\n"
                                 Path GroupName GroupId Arn CreateDate))}))

(defmethod format-response ::IAMListGroupsResponseReceived
  [{:keys [Groups]}]
  {:result/data  {:groups Groups}
   :result/value (map #(format "Group : %s%s\nGroupId : %s\nArn : %s\nCreateDate : %s\n"
                               (:Path %) (:GroupName %) (:GroupId %) (:Arn %) (:CreateDate %))
                      Groups)})

(defmethod format-response ::IAMGetUserResponseReceived
  [{:keys [User]}]
  (let [{:keys [Path UserName UserId Arn CreateDate]} User]
    {:result/data  {:path Path, :user-name UserName, :user-id UserId, :arn Arn, :create-date CreateDate}
     :result/value (format "User : %s%s [UserId=%s, Arn=%s] - Created on %s"
                           Path UserName UserId Arn CreateDate)}))

(defmethod format-response ::IAMListUsersResponseReceived
  [{:keys [Users]}]
  {:result/data  {:users Users}
   :result/value (map #(format "User : %s%s [UserId=%s, Arn=%s] - Created on %s"
                               (:Path %) (:UserName %) (:UserId %) (:Arn %) (:CreateDate %))
                      Users)})

(defmethod format-response ::IAMListPoliciesResponseReceived
  [{:keys [Policies]}]
  {:result/data  {:policies Policies}
   :result/value (map #(format "Policy name : %s%s [PolicyId=%s, Arn=%s] - Created on %s"
                               (:Path %) (:PolicyName %) (:PolicyId %) (:Arn %) (:CreateDate %))
                      Policies)})

(defmethod format-response ::IAMUserPolicyAttached
  [response]
  (let [request-id (get-in response [:AttachUserPolicyResponse :ResponseMetadata :RequestId])]
    {:result/data  {:request-id request-id}
     :result/value (format "User policy successfully attached [RequestId=%s]"
                           request-id)}))

(defmethod format-response ::IAMListAttachedUserPoliciesResponseReceived
  [{:keys [AttachedPolicies]}]
  {:result/data  {:attached-policies AttachedPolicies}
   :result/value (map #(format "Policy name : %s [Arn=%s]"
                               (:PolicyName %) (:PolicyArn %))
                      AttachedPolicies)})

(defmethod format-response ::IAMLoginProfileCreated
  [{:keys [LoginProfile]}]
  (let [user-name (:UserName LoginProfile)
        create-date (:CreateDate LoginProfile)]
    {:result/data  {:user-name user-name, :create-date create-date}
     :result/value (format "Login profile for %s, requiring password reset, successfully created on %s"
                           user-name create-date)}))

(defmethod format-response ::IAMLoginProfileUpdated
  [response]
  (let [request-id (get-in response [:UpdateLoginProfileResponse :ResponseMetadata :RequestId])]
    {:result/data  {:request-id request-id}
     :result/value (format "Login profile successfully updated [RequestId=%s]"
                           request-id)}))

(defmethod format-response ::IAMAccessKeyCreated
  [{{:keys [UserName AccessKeyId Status SecretAccessKey CreateDate]} :AccessKey}]
  {:result/data  {:user-name UserName, :access-key-id AccessKeyId, :status Status, :secret-access-key SecretAccessKey, :create-date CreateDate}
   :result/value (format "An access key for user %s has been successfully created on %s\nAWS Access Key ID : %s\nAWS Secret Access Key : %s\nStatus : %s\n"
                         UserName CreateDate AccessKeyId SecretAccessKey Status)})

(defmethod format-response ::IAMListAccessKeysResponseReceived
  [{:keys [AccessKeyMetadata]}]
  {:result/data  {:access-key-metadata AccessKeyMetadata}
   :result/value (map #(format "Access key ID : %s\nStatus : %s\nCreated on : %s\n"
                               (:AccessKeyId %) (:Status %) (:CreateDate %))
                      AccessKeyMetadata)})

(defmethod format-response ::IAMAccessKeyDeleted
  [response]
  (let [request-id (get-in response [:DeleteAccessKeyResponse :ResponseMetadata :RequestId])]
    {:result/data  {:request-id request-id}
     :result/value (format "Access Key successfully deleted [RequestId=%s]"
                           request-id)}))