Skip to content

Instantly share code, notes, and snippets.

@jderrett
Last active August 30, 2017 19:05
Show Gist options
  • Save jderrett/53cf070e0cfafd9c6fa9 to your computer and use it in GitHub Desktop.
Save jderrett/53cf070e0cfafd9c6fa9 to your computer and use it in GitHub Desktop.
Copy a Librato Space from one account to another (or same account)
require 'faraday'
require 'faraday_middleware'
require 'json'
require 'pry'
class SpacesApi
LIBRATO_API = 'https://metrics-api.librato.com'
LIBRATO_API_VERSION = 'v1'
ENDPOINT = [LIBRATO_API, LIBRATO_API_VERSION].join('/')
attr_accessor :username
def initialize(username, api_key)
@username = username
@conn = Faraday.new(ENDPOINT) do |f|
f.request :json
f.response :json
f.adapter Faraday.default_adapter
f.basic_auth username, api_key
end
end
class Space
attr_accessor :id, :payload, :name, :charts
def initialize(attrs)
@id = attrs['id']
@payload = attrs
@name = attrs['name']
@charts = attrs['charts']
end
def chart_ids
charts.map {|i| i['id']}
end
end # class Space
def conn
@conn
end
def get_entity(entity_path, entity_id)
resp = conn.get("#{entity_path}/#{entity_id}")
resp.status == 200 ? resp.body : (raise resp.inspect)
end
def get_space(space_id)
Space.new(get_entity('spaces', space_id))
end
def get_chart(space_id, chart_id)
get_entity("spaces/#{space_id}/charts", chart_id)
end
def find_space(name)
resp = conn.get('spaces')
if resp.status == 200
if space = resp.body['spaces'].detect {|d| d['name'] == name}
get_space(space['id'])
end
else
raise resp.inspect
end
end
def create_space(name)
resp = conn.post do |req|
req.url 'spaces'
req.body = {name: name}.to_json
end
if resp.success?
Space.new(resp.body)
else
raise resp.body
end
end
# Clean ids out of the chart payload so we can post to another account
# Not even sure this is necessary - the API may just take it and discard the ids?
def get_chart_dupe(space_id, chart_id)
get_chart(space_id, chart_id).tap do |c|
c.delete('id')
c['streams'].each {|s| s.delete('id')}
end
end
def create_chart(space_id, payload)
conn.post do |req|
req.url "spaces/#{space_id}/charts"
req.body = payload.to_json
end
end
end # SpacesApi
# Script starts here
user1 = ENV['LIBRATO_USER']
api_key1 = ENV['LIBRATO_TOKEN']
# You can use the same account, or another account
user2 = ENV['LIBRATO_USER_2'] || ENV['LIBRATO_USER']
api_key2 = ENV['LIBRATO_TOKEN_2'] || ENV['LIBRATO_TOKEN']
space_name = 'Weather'
prefix = ''
suffix = ' (copy)'
new_space_name = prefix + space_name + suffix
source_api = SpacesApi.new(user1, api_key1)
dest_api = SpacesApi.new(user2, api_key2)
source_space = source_api.find_space(space_name)
if dest_api.find_space(new_space_name)
puts "Space #{new_space_name} already exists in #{dest_api.username}! Stopping."
exit
end
# Create destination space
puts "About to create space #{new_space_name}"
new_space = dest_api.create_space(new_space_name)
# Copy charts
dest_chart_ids = []
source_space.chart_ids.each do |chart_id|
# Grab source chart duplicate
payload = source_api.get_chart_dupe(source_space.id, chart_id)
# Create destination chart
puts "Creating #{payload['name']} of type #{payload['type']} in #{dest_api.username}..."
resp = dest_api.create_chart(new_space.id, payload)
if resp.success?
new_chart_id = resp.body['id']
dest_chart_ids << new_chart_id
puts "Created #{new_chart_id}"
else
puts resp.status
puts resp.body
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment