Skip to content

Instantly share code, notes, and snippets.

@mnaser
Created August 10, 2016 21:15
Show Gist options
  • Select an option

  • Save mnaser/5802d7b3cefc47103c3166b7199637d4 to your computer and use it in GitHub Desktop.

Select an option

Save mnaser/5802d7b3cefc47103c3166b7199637d4 to your computer and use it in GitHub Desktop.
OpenStack API checks for Sensu. You can use TENANT_ID in url and it will automatically replace by tenant ID (useful for nova)
#!/opt/sensu/embedded/bin/ruby
require 'sensu-plugin/check/cli'
require 'net/http'
require 'json'
class CheckOpenStackAPI < Sensu::Plugin::Check::CLI
option :auth_url,
short: '-a AUTH-URL',
long: '--auth-url AUTH-URL',
default: 'http://localhost:5000'
option :username,
short: '-user USERNAME',
long: '--username USERNAME',
default: 'sensu'
option :password,
short: '-p PASSWORD',
long: '--password PASSWORD'
option :tenant,
short: '-t TENANT',
long: '--tenant-name TENANT',
default: 'sensu'
option :url,
short: '-url URL',
long: '--url URL'
option :does_not_contain,
short: '-v DNC',
long: '--does-not-contain DNC'
def run
unknown 'No password provided' unless config[:password]
unknown 'No URL specified' unless config[:url]
# Get token from Keystone
auth_uri = URI.parse(config[:auth_url])
request = Net::HTTP::Post.new('/v3/auth/tokens', initheader={'Content-Type' => 'application/json'})
request.body = {
auth: {
identity: {
methods: ['password'],
password: {
user: {
name: config[:username],
domain: {id: 'default'},
password: config[:password]
}
}
},
scope: {
project: {
name: config[:tenant],
domain: {id: 'default'}
}
}
}
}.to_json
response = Net::HTTP.new(auth_uri.hostname, auth_uri.port).start { |http| http.request(request) }
warning "Failed to generate token from Keystone" if response.code != "201"
data = JSON.parse(response.body)
token = response['X-Subject-Token']
tenant_id = data['token']['project']['id']
# Make request to service
url = config[:url].sub('TENANT_ID', tenant_id)
uri = URI.parse(url)
request = Net::HTTP::Get.new(uri, initheader={'X-Auth-Token' => token})
response = Net::HTTP.new(uri.hostname, uri.port).start { |http| http.request(request) }
code = Integer(response.code)
size = response.body.nil? ? '0' : response.body.size
# Check if we have a does_not_contain
if config[:does_not_contain] then
if code >= 200 and code < 400 then
ok "#{response.code}, #{size} bytes, no #{config[:does_not_contain]} in response" unless response.body.include? config[:does_not_contain]
critical "response contains #{config[:does_not_contain]}"
end
critical response.code
else
ok "#{response.code}, #{size} bytes" if code >= 200 and code < 400
critical response.code
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment