Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
A simple Ruby script to import users into PagerDuty from a CSV file
#!/usr/bin/env ruby
require 'rubygems'
require 'faraday'
require 'json'
require 'csv'
class PagerDutyAgent
attr_reader :requester_id
attr_reader :token
attr_reader :connection
def initialize(subdomain, token, requester_id)
@token = token
@requester_id = requester_id
@connection = Faraday.new(:url => "https://#{subdomain}.pagerduty.com",
:ssl => {:verify => false}) do |c|
c.request :url_encoded
c.adapter :net_http
end
end
def get(path, query = {})
response = connection.get(path, query,
{ 'Authorization' => "Token token=#{token}" })
raise "Error: #{response.body}" unless response.success?
JSON.parse(response.body)
end
def post(path, body = {})
body_json = JSON.generate(body)
response = connection.post(path, body_json,
{ 'Authorization' => "Token token=#{token}",
'Content-Type' => 'application/json'})
raise "Error: #{response.body}" unless response.success?
JSON.parse(response.body)
end
def add_user(name, email, role = "user")
request_body = {
:requester_id => requester_id,
:user => {
:name => name,
:email => email,
:role => role
}
}
post("/api/v1/users", request_body)
end
def add_contact(user_id, type, address, country_code, label)
request_body = {
:contact_method => {
:type => type,
:address => address,
:label => label
}
}
request_body[:contact_method][:country_code] = country_code if ["SMS", "phone"].include?(type)
post("/api/v1/users/#{user_id}/contact_methods", request_body)
end
def add_notification_rule(user_id, contact_method_id, delay_in_minutes)
request_body = {
:notification_rule => {
:start_delay_in_minutes => delay_in_minutes,
:contact_method_id => contact_method_id
}
}
post("/api/v1/users/#{user_id}/notification_rules", request_body)
end
def find_user_by_email(email)
get("/api/v1/users", :query => email)
end
def contact_methods(user_id)
get("/api/v1/users/#{user_id}/contact_methods")
end
end
class CSVImporter
Record = Struct.new(:name, :email, :country_code, :phone_number)
attr_reader :agent
attr_reader :csv_file
def initialize(agent, csv_file)
@agent = agent
@csv_file = csv_file
end
def import_user(record)
# Try to find an existing user
users = agent.find_user_by_email(record.email)
user = nil; user_id = nil
if users["users"].size > 0
user = users["users"][0]
user_id = user["id"]
puts "Found user: #{record.email}"
puts "Found contact methods: #{agent.contact_methods(user_id)}"
puts ""
else
puts "Adding user: #{record}"
user = agent.add_user(record.name, record.email)
user_id = user["user"]["id"]
puts "Added user with id: #{user_id}"
end
# Add user and email notification rule
["SMS", "phone"].each do |type|
add_contact_method(type, user_id, record)
end
rescue Exception => e
puts "Error adding user: #{record}, #{e}"
end
# type: phone, SMS, email
def add_contact_method(type, user_id, record)
puts "Adding #{type} notification"
contact_method = agent.add_contact(user_id, type,
record.phone_number, record.country_code, "Mobile")
contact_method_id = contact_method["contact_method"]["id"]
agent.add_notification_rule(user_id, contact_method_id, 0)
# Add retries for phone notification
if ["phone"].include?(type)
agent.add_notification_rule(user_id, contact_method_id, 3)
end
end
def import
CSV.foreach(csv_file) do |row|
import_user(row_to_record(row))
end
end
def row_to_record(row)
# NOTE: You may need to adjust this if the format of your row is different.
Record.new(row[0], row[1], row[2], row[3])
end
end
agent = PagerDutyAgent.new("<subdomain>", "<api-token>", "<account-owner-user-id>")
CSVImporter.new(agent, "path/to/csv/file.csv").import
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment