class Snitcher::API::Client
Constants
- DEFAULT_ENDPOINT
Public Class Methods
Create a new API Client
for taling to Dead Man's Snitch's API.
@param key [String] API access key (available at
https://deadmanssnitch.com/account/keys).
@param [Hash] options advanced options for customizing the client @option options [String] :endpoint URL of the DMS API to connect to @option options [Float, Fixnum] :timeout number of seconds to wait at most
for a response from the API.
@example Creating a new Client
with an API key
client = Snitcher::API::Client.new("abc123") # => #<Snitcher::API::Client...>
@return [Snitcher::API::Client] New API Client
.
# File lib/snitcher/api/client.rb, line 31 def initialize(key, options = {}) endpoint = options[:endpoint] || DEFAULT_ENDPOINT @key = key @endpoint = URI.parse(endpoint).freeze @timeout = options.fetch(:timeout, 5.0) end
Public Instance Methods
Create a new Snitch.
@param [Hash] attributes The properties for the new Snitch @option attributes [String] :name The label used for the Snitch @option attributes [String] :interval How often the snitch is expected to
check-in. One of: "15_minute", "30_minute", "hourly", "daily", "weekly", or "monthly".
@option attributes [optional, String] :notes Additional information about
the Snitch. Useful to put instructions of investigating or fixing any errors.
@option attributes [optional, Array<String>] :tags List of labels to tag the
Snitch with.
@example Create a new Snitch
client.create_snitch({ name: "Daily Backups", interval: "hourly", notes: "On error check the print tray for paper jams", tags: [ "backups", "maintenance" ], }) # => #<Snitcher::API::Snitch:...>
@raise [Timeout::Error] if the API request took too long to execute. @raise [Snitcher::API::ResourceInvalidError] if the attributes are not valid
for a Snitch.
@raise [Snitcher::API::Error] if any other API errors occur.
@return [Snitcher::API::Snitch] the new Snitch.
# File lib/snitcher/api/client.rb, line 134 def create_snitch(attributes = {}) if interval = attributes.delete(:interval) type = attributes[:type] ||= {} type[:interval] ||= interval end response = post("/v1/snitches", attributes) Snitcher::API::Snitch.new(response) end
Deletes a Snitch.
@param token [String] The unique token of the Snitch to delete.
@example Delete a Snitch.
client.delete_snitch("c2354d53d2") # => { :message => "Response complete" }
@raise [Timeout::Error] if the API request took too long to execute. @raise [Snitcher::API::ResourceNotFoundError] if the Snitch does not exist. @raise [Snitcher::API::Error] if any other API errors occur.
@return [nil]
# File lib/snitcher/api/client.rb, line 280 def delete_snitch(token) token = CGI.escape(token) delete("/v1/snitches/#{token}") nil end
Pauses a Snitch if it can be paused. Snitches can only be paused if their status is currently “failing” or “errored”.
@param token [String] The unique token of the Snitch.
@example Pause a Snitch
client.pause_snitch("c2354d53d2") # => true
@raise [Timeout::Error] if the API request took too long to execute. @raise [Snitcher::API::ResourceNotFoundError] if the Snitch does not exist. @raise [Snitcher::API::Error] if any other API errors occur.
@return [nil]
# File lib/snitcher/api/client.rb, line 259 def pause_snitch(token) token = CGI.escape(token) post("/v1/snitches/#{token}/pause") nil end
Remove a tag from a Snitch.
@param token [String] The unique token of the Snitch. @param tag [String] The tag to remove from the Snitch.
@example Removing the “production” tag from a Snitch
client.remove_tag("c2354d53d2", "production") # => [ "critical" ]
@raise [Timeout::Error] if the API request took too long to execute. @raise [Snitcher::API::ResourceNotFoundError] if the Snitch does not exist. @raise [Snitcher::API::Error] if any other API errors occur.
@return [Array<String>] list of the remaining tags on the Snitch.
# File lib/snitcher/api/client.rb, line 238 def remove_tag(token, tag) token = CGI.escape(token) tag = CGI.escape(tag) delete("/v1/snitches/#{token}/tags/#{tag}") end
Get a single Snitch by it's unique token.
@param token [String] The unique token of the Snitch to get
@example Get the Snitch with token “c2354d53d2”
client.snitch("c2354d53d2") # => #<Snitcher::API:: @token="c2354d53d2" ...>
@raise [Timeout::Error] if the API request took too long to execute. @raise [Snitcher::API::ResourceNotFoundError] if a Snitch does not exist
with that token
@raise [Snitcher::API::Error] if any other API errors occur.
@return [Snitcher::API::Snitch] the Snitch
# File lib/snitcher/api/client.rb, line 98 def snitch(token) token = CGI.escape(token) payload = get("/v1/snitches/#{token}") Snitcher::API::Snitch.new(payload) end
Get the list snitches on the account
@param [Hash] filters @option filters [String, Array<String>] tags only return Snitches that are
tagged with _all_ of the given tags. For example, if a Snitch is tagged with "production" and "critical" it will be returned when filtering by "production", "critical", or ["production", "critical"] but not ["production", "backups"].
@example List the Snitches on an account
client.snitches # => [ #<Snitcher::API::Snitch:...>, #<Snitcher::API::Snitch:...> ]
@example List Snitches with a specific tag
client.snitches(tags: "production") # => [ #<Snitcher::API::Snitch:...>, #<Snitcher::API::Snitch:...> ]
@example List Snitches with multiple tags
client.snitches(tags: ["production", "critical"]) # => [ #<Snitcher::API::Snitch:...>, #<Snitcher::API::Snitch:...> ]
@raise [Timeout::Error] if the API request took too long to execute. @raise [Snitcher::API::Error] if any API errors occur.
@return [Array<Snitcher::API::Snitch>] the snitches on the account.
# File lib/snitcher/api/client.rb, line 64 def snitches(filters = {}) query = {} # Tags allow for labeling Snitches for better categorization. This allows # filtering by a set of tags. if tags = filters[:tags] tags = Array(tags).flatten query[:tags] = tags.map(&:strip).compact.uniq.join(",") end # JSON array of Snitch attributes response = get("/v1/snitches", query) # Convert the attributes hashes into Objects response.map! do |snitch| Snitcher::API::Snitch.new(snitch) end end
Update a snitch, identified by token, using passed-in values. Only changes those values included in the attributes hash; other attributes are not changed.
@param token [String] The unique token of the Snitch. @param [Hash] attributes the set of Snitch attributes to change.
@option attributes [String] :name The label used for the Snitch @option attributes [String] :interval How often the snitch is expected to
check-in. One of: "15_minute", "30_minute", "hourly", "daily", "weekly", or "monthly".
@option attributes [optional, String] :notes Additional information about
the Snitch. Useful to put instructions of investigating or fixing any errors.
@option attributes [optional, Array<String>, nil] :tags List of labels to
tag the Snitch with.
@example Update an existing Snitch
client.update_snitch("c2354d53d2", { name: "Monthly Backups", }) # => #<Snitcher::API::Snitch:...>
@example Setting Tags for a Snitch
client.update_snitch("c2354d53d2", tags: ["production", "backup"]) # => #<Snitcher::API::Snitch: @tags=["production", "backup"])
@example Removing Tags from a Snitch
client.update_snitch("c2354d53d2", tags: []) or client.update_snitch("c2354d53d2", tags: nil)
@raise [Timeout::Error] if the API request took too long to execute. @raise [Snitcher::API::ResourceInvalidError] if the changes are not valid. @raise [Snitcher::API::ResourceNotFoundError] if the Snitch does not exist. @raise [Snitcher::API::Error] if any other API errors occur.
Raise Timeout::Error if the API request times out
# File lib/snitcher/api/client.rb, line 182 def update_snitch(token, attributes = {}) if attributes.key?(:tags) attributes[:tags] = [attributes[:tags]].flatten.compact end # Expand the interval key to the full structure required by the API if interval = attributes.delete(:interval) type = attributes[:type] ||= {} type[:interval] ||= interval end token = CGI.escape(token) payload = patch("/v1/snitches/#{token}", attributes) Snitcher::API::Snitch.new(payload) end
Private Instance Methods
# File lib/snitcher/api/client.rb, line 369 def delete(path) request = Net::HTTP::Delete.new(path) execute_request(request) end
# File lib/snitcher/api/client.rb, line 325 def evaluate_response(response) case response when Net::HTTPNoContent nil when Net::HTTPSuccess JSON.parse(response.body) when Net::HTTPInternalServerError # InternalServerError does not have a parseable body as the error may not # be generated by the application itself. raise ::Snitcher::API::InternalServerError.new({ "type" => "internal_server_error", "error" => response.body, }) else error = JSON.parse(response.body) raise ::Snitcher::API::Error.new(error) end end
# File lib/snitcher/api/client.rb, line 297 def execute_request(request) http_options = { open_timeout: @timeout, read_timeout: @timeout, ssl_timeout: @timeout, use_ssl: @endpoint.scheme == "https", } Net::HTTP.start(@endpoint.host, @endpoint.port, http_options) do |http| request.basic_auth(@key, "") request["User-Agent"] = user_agent # All requests (with bodies) are made using JSON. if request.body request["Content-Type"] = "application/json" # Some trickery to allow pushing the JSON rendering down as far as # possible. if !request.body.is_a?(String) request.body = JSON.generate(request.body) end end response = http.request(request) evaluate_response(response) end end
# File lib/snitcher/api/client.rb, line 345 def get(path, query = {}) # Only add the query param if any valid filters were given. if query.any? path = "#{path}?#{URI.encode_www_form(query)}" end request = Net::HTTP::Get.new(path) execute_request(request) end
# File lib/snitcher/api/client.rb, line 362 def patch(path, data) request = Net::HTTP::Patch.new(path) request.body = data execute_request(request) end
# File lib/snitcher/api/client.rb, line 355 def post(path, data = nil) request = Net::HTTP::Post.new(path) request.body = data execute_request(request) end
# File lib/snitcher/api/client.rb, line 290 def user_agent # RUBY_ENGINE was not added until 1.9.3 engine = defined?(::RUBY_ENGINE) ? ::RUBY_ENGINE : "Ruby" "Snitcher; #{engine}/#{RUBY_VERSION}; #{RUBY_PLATFORM}; v#{::Snitcher::VERSION}" end