Commit c03a98d2 authored by John E. Vincent's avatar John E. Vincent

refactor of rundeck agent to use token auth

parent 37a15c11
...@@ -55,6 +55,8 @@ module Noah ...@@ -55,6 +55,8 @@ module Noah
begin begin
#self.instance_variable_get("@#{a}").send(:notify, e, m, @@watchers) #self.instance_variable_get("@#{a}").send(:notify, e, m, @@watchers)
x.notify(e, m, @@watchers.clone) x.notify(e, m, @@watchers.clone)
x.errback {|e| self.set_deferred_status(:fail, "Error in #{x.class.to_s}: #{e}")}
x.callback {|m| self.set_deferred_status(:success); iter.next}
iter.next iter.next
rescue Exception => e rescue Exception => e
@logger.error("#{agent.to_s} invocation failed with #{e.message}") @logger.error("#{agent.to_s} invocation failed with #{e.message}")
......
...@@ -22,7 +22,7 @@ module Noah::Agents ...@@ -22,7 +22,7 @@ module Noah::Agents
work!(ep, message) work!(ep, message)
iter.next iter.next
end end
logger.info("Dispatched message to #{worklist.size} #{self.class.to_s} endpoints") logger.info("Dispatched message to #{worklist.size} #{self.class.to_s} endpoints")
else else
logger.info("No work to do") logger.info("No work to do")
end end
......
...@@ -14,7 +14,7 @@ module Noah::Agents ...@@ -14,7 +14,7 @@ module Noah::Agents
logger.info("Message posted to #{ep} successfully") logger.info("Message posted to #{ep} successfully")
} }
http.errback { http.errback {
logger.error("Something went wrong with #{ep}") logger.debug("Error posting to #{ep}: #{http.response}.")
} }
end end
......
require File.join(File.dirname(__FILE__), 'base_agent') require File.join(File.dirname(__FILE__), 'base_agent')
require 'em-http/middleware/cookie_jar' require 'nokogiri'
require 'uri'
module Noah::Agents module Noah::Agents
class RunDeckAgent < Base class RunDeckAgent < Base
...@@ -8,31 +7,60 @@ module Noah::Agents ...@@ -8,31 +7,60 @@ module Noah::Agents
PREFIX = "rundeck://" PREFIX = "rundeck://"
NAME = self.class.to_s NAME = self.class.to_s
DEFAULT_CONCURRENCY = 50 DEFAULT_CONCURRENCY = 50
SUPPORTED_PATHS = ["refresh", "run"]
def work!(ep, message) def work!(ep, message)
logger.info("Sending message to (#{ep})") logger.info("Sending message to (#{ep})")
uri = URI.parse(ep) rd = rundeck_parser(ep)
credentials = {:j_username => uri.user, :j_password => uri.password} req = EM::HttpRequest.new(rd[:url], :connection_timeout => 2, :inactivity_timeout => 2)
EM::HttpRequest.use EM::Middleware::CookieJar http = req.send(:"#{rd[:http_method]}", :head => {"X-RunDeck-Auth-Token" => "#{rd[:token]}"})
conn = EM::HttpRequest.new("http://#{uri.host}:#{uri.port}/j_security_check")
http = conn.post :body => credentials
http.callback { http.callback {
logger.info("Logged in to RunDeck. Calling path") logger.info("Message posted to #{ep}")
conn2 = EM::HttpRequest.new("http://#{uri.host}:#{uri.port}#{uri.path}?#{uri.query}") rd_resp = rundeck_response(http.response)
exec = conn2.get http.fail("#{rd_resp[:message]}") if rd_resp[:status] == "error"
exec.callback {
logger.info("Successfully called #{ep}")
logger.info("Response from RunDeck:")
logger.info("#{exec.response}")
}
exec.errback {
logger.error("Something went wrong with #{ep}")
}
} }
http.errback { http.errback {
logger.error("Something went wrong with #{ep}") logger.error("Something went wrong with #{ep}: #{http.response}")
} }
end end
private
def rundeck_parser(endpoint)
rd = {}
logger.debug("Parsing endpoint: #{endpoint}")
begin
rduri = URI.parse(endpoint)
rescue URI::InvalidURIError
logger.error("Invalid callback destination")
end
rduri.user.nil? ? self.fail("Missing API Token") : rd[:token]=rduri.user
# valid paths are:
# "/refresh/<project_name>"
# or
# "/run/<job_id>"
rduri.path.split("/").size < 3 ? logger.error("Path must contain job number") : action=rduri.path.split("/")[1]
case action
when "run"
realpath = "api/1/job/#{rduri.path.split("/")[2]}/run"
rd[:http_method] = "get"
when "refresh"
realpath = "api/2/project/#{rduri.path.split("/")[2]}/resources/refresh"
rd[:http_method] = "post"
else
logger.error("I only handle jobs and refreshes for now. Sorry!")
end
rd[:url] = "http://#{rduri.host}:#{rduri.port}/#{realpath}"
logger.debug("Returning to work with params: #{rd.to_s}")
rd
end
def rundeck_response(response)
xml = Nokogiri::XML.parse(response)
keys = xml.xpath("//result").collect(&:keys).first
keys.member?("error") ? status="error" : status="success"
message = xml.xpath("//result").collect(&:text)
{:status => status, :message => message}
end
end end
end end
...@@ -5,6 +5,8 @@ module Noah ...@@ -5,6 +5,8 @@ module Noah
attribute :pattern attribute :pattern
attribute :endpoint attribute :endpoint
attribute :name attribute :name
counter :failures
index :pattern index :pattern
index :endpoint index :endpoint
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment