foreman/lib/proxy_api.rb @ 80e8e5b2
0f29f96e | Ohad Levy | require "rest_client"
|
|
require "json"
|
|||
require "uri"
|
|||
a6f4f5f7 | Ohad Levy | require 'net'
|
|
0f29f96e | Ohad Levy | ||
module ProxyAPI
|
|||
class Resource
|
|||
attr_reader :url, :user, :password
|
|||
def initialize(args)
|
|||
455f5d2b | Paul Kelly | raise("Must provide a protocol and host when initialising a smart-proxy connection") unless (url =~ /^http/)
|
|
a87f8f9f | Paul Kelly | ||
98445b00 | Ohad Levy | # Each request is limited to 60 seconds
|
|
34c3a262 | Ohad Levy | connect_params = {:timeout => 60, :open_timeout => 10, :headers => { :accept => :json }}
|
|
455f5d2b | Paul Kelly | ||
# We authenticate only if we are using SSL
|
|||
if url.match(/^https/i)
|
|||
76607ed5 | Ohad Levy | cert = Setting[:ssl_certificate]
|
|
ca_cert = Setting[:ssl_ca_file]
|
|||
f1a9b611 | Paul Kelly | hostprivkey = Setting[:ssl_priv_key]
|
|
455f5d2b | Paul Kelly | ||
# Use update rather than merge! as this is not rails dependent
|
|||
connect_params.update(
|
|||
:ssl_client_cert => OpenSSL::X509::Certificate.new(File.read(cert)),
|
|||
:ssl_client_key => OpenSSL::PKey::RSA.new(File.read(hostprivkey)),
|
|||
:ssl_ca_file => ca_cert,
|
|||
:verify_ssl => OpenSSL::SSL::VERIFY_PEER
|
|||
a6db0470 | Paul Kelly | ) unless Rails.env == "test"
|
|
455f5d2b | Paul Kelly | end
|
|
@resource = RestClient::Resource.new(url, connect_params)
|
|||
0f29f96e | Ohad Levy | end
|
|
def logger; RAILS_DEFAULT_LOGGER; end
|
|||
private
|
|||
# Decodes the JSON response if no HTTP error has been detected
|
|||
455f5d2b | Paul Kelly | # If an HTTP error is received then the error message is saves into @error
|
|
0f29f96e | Ohad Levy | # Returns: Response, if the operation is GET, or true for POST, PUT and DELETE.
|
|
# OR: false if a HTTP error is detected
|
|||
# TODO: add error message handling
|
|||
def parse response
|
|||
if response and response.code >= 200 and response.code < 300
|
|||
return response.body.size > 2 ? JSON.parse(response.body) : true
|
|||
else
|
|||
false
|
|||
end
|
|||
rescue => e
|
|||
e85584bf | Paul Kelly | logger.warn "Failed to parse response: #{response} -> #{e}"
|
|
455f5d2b | Paul Kelly | false
|
|
0f29f96e | Ohad Levy | end
|
|
# Perform GET operation on the supplied path
|
|||
def get path = nil
|
|||
2755ebe9 | Paul Kelly | # This ensures that an extra "/" is not generated
|
|
if path
|
|||
@resource[URI.escape(path)].get
|
|||
else
|
|||
@resource.get
|
|||
end
|
|||
0f29f96e | Ohad Levy | end
|
|
# Perform POST operation with the supplied payload on the supplied path
|
|||
def post payload, path
|
|||
path ||= ""
|
|||
@resource[path].post payload
|
|||
end
|
|||
# Perform PUT operation with the supplied payload on the supplied path
|
|||
def put payload, path
|
|||
path ||= ""
|
|||
@resource[path].put payload
|
|||
end
|
|||
# Perform DELETE operation on the supplied path
|
|||
def delete path
|
|||
@resource[path].delete
|
|||
end
|
|||
36f93e4d | Ohad Levy | end
|
|
class Puppetca < Resource
|
|||
def initialize args
|
|||
@url = args[:url] + "/puppet/ca"
|
|||
super args
|
|||
end
|
|||
2a0cffd3 | Ohad Levy | def autosign
|
|
result = parse(get "autosign")
|
|||
result == true ? [] : result
|
|||
end
|
|||
36f93e4d | Ohad Levy | def set_autosign certname
|
|
parse(post("", "autosign/#{certname}"))
|
|||
end
|
|||
def del_autosign certname
|
|||
parse(delete("autosign/#{certname}"))
|
|||
rescue RestClient::ResourceNotFound
|
|||
# entry doesn't exists anyway
|
|||
true
|
|||
end
|
|||
0f29f96e | Ohad Levy | ||
635a02c9 | Ohad Levy | def sign_certificate certname
|
|
parse(post("", certname))
|
|||
end
|
|||
36f93e4d | Ohad Levy | def del_certificate certname
|
|
parse(delete("#{certname}"))
|
|||
rescue RestClient::ResourceNotFound
|
|||
# entry doesn't exists anyway
|
|||
true
|
|||
end
|
|||
2a0cffd3 | Ohad Levy | ||
def all
|
|||
parse(get)
|
|||
end
|
|||
0f29f96e | Ohad Levy | end
|
|
2755ebe9 | Paul Kelly | class Features < Resource
|
|
def initialize args
|
|||
a87f8f9f | Paul Kelly | @url = args[:url] + "/features"
|
|
2755ebe9 | Paul Kelly | super args
|
|
end
|
|||
def features
|
|||
parse get
|
|||
end
|
|||
end
|
|||
0f29f96e | Ohad Levy | class DHCP < Resource
|
|
def initialize args
|
|||
a87f8f9f | Paul Kelly | @url = args[:url] + "/dhcp"
|
|
0f29f96e | Ohad Levy | super args
|
|
end
|
|||
# Retrieve the Server's subnets
|
|||
# Returns: Array of Hashes or false
|
|||
# Example [{"network":"192.168.11.0","netmask":"255.255.255.0"},{"network":"192.168.122.0","netmask":"255.255.255.0"}]
|
|||
def subnets
|
|||
parse get
|
|||
end
|
|||
def subnet subnet
|
|||
parse get(subnet)
|
|||
end
|
|||
def unused_ip subnet
|
|||
parse get("#{subnet}/unused_ip")
|
|||
end
|
|||
# Retrieves a DHCP entry
|
|||
# [+subnet+] : String in dotted decimal format
|
|||
# [+mac+] : String in coloned sextuplet format
|
|||
# Returns : Hash or false
|
|||
def record subnet, mac
|
|||
a6f4f5f7 | Ohad Levy | response = parse(get("#{subnet}/#{mac}"))
|
|
0c3e15d2 | Ohad Levy | attrs = response.merge(:network => subnet, :proxy => self)
|
|
if response.keys.grep(/Sun/i).empty?
|
|||
Net::DHCP::Record.new attrs
|
|||
80e8e5b2 | Ohad Levy | else
|
|
Net::DHCP::SparcRecord.new attrs
|
|||
0c3e15d2 | Ohad Levy | end
|
|
672f931d | Paul Kelly | rescue RestClient::ResourceNotFound
|
|
0c3e15d2 | Ohad Levy | nil
|
|
0f29f96e | Ohad Levy | end
|
|
# Sets a DHCP entry
|
|||
# [+subnet+] : String in dotted decimal format
|
|||
# [+mac+] : String in coloned sextuplet format
|
|||
# [+args+] : Hash containing DHCP values. The :mac key is taken from the mac parameter
|
|||
# Returns : Boolean status
|
|||
def set subnet, args
|
|||
raise "Must define a subnet" if subnet.empty?
|
|||
raise "Must provide arguments" unless args.is_a?(Hash)
|
|||
parse(post(args, subnet.to_s))
|
|||
end
|
|||
# Deletes a DHCP entry
|
|||
# [+subnet+] : String in dotted decimal format
|
|||
# [+mac+] : String in coloned sextuplet format
|
|||
# Returns : Boolean status
|
|||
def delete subnet, mac
|
|||
parse super("#{subnet}/#{mac}")
|
|||
rescue RestClient::ResourceNotFound
|
|||
# entry doesn't exists anyway
|
|||
return true
|
|||
end
|
|||
end
|
|||
class DNS < Resource
|
|||
def initialize args
|
|||
a87f8f9f | Paul Kelly | @url = args[:url] + "/dns"
|
|
0f29f96e | Ohad Levy | super args
|
|
end
|
|||
# Sets a DNS entry
|
|||
# [+fqdn+] : String containing the FQDN of the host
|
|||
# [+args+] : Hash containing :value and :type: The :fqdn key is taken from the fqdn parameter
|
|||
# Returns : Boolean status
|
|||
def set args
|
|||
parse post(args, "")
|
|||
end
|
|||
# Deletes a DNS entry
|
|||
# [+key+] : String containing either a FQDN or a dotted quad plus .in-addr.arpa.
|
|||
# Returns : Boolean status
|
|||
def delete key
|
|||
parse(super("#{key}"))
|
|||
rescue RestClient::ResourceNotFound
|
|||
# entry doesn't exists anyway
|
|||
return true
|
|||
end
|
|||
end
|
|||
class TFTP < Resource
|
|||
def initialize args
|
|||
a6db0470 | Paul Kelly | @url = args[:url] + "/tftp"
|
|
@variant = args[:variant]
|
|||
0f29f96e | Ohad Levy | super args
|
|
end
|
|||
# Creates a TFTP boot entry
|
|||
a6db0470 | Paul Kelly | # [+mac+] : MAC address
|
|
0f29f96e | Ohad Levy | # [+args+] : Hash containing
|
|
a6db0470 | Paul Kelly | # :pxeconfig => String containing the configuration
|
|
0f29f96e | Ohad Levy | # Returns : Boolean status
|
|
def set mac, args
|
|||
a6db0470 | Paul Kelly | parse(post(args, "#{@variant}/#{mac}"))
|
|
0f29f96e | Ohad Levy | end
|
|
# Deletes a TFTP boot entry
|
|||
# [+mac+] : String in coloned sextuplet format
|
|||
# Returns : Boolean status
|
|||
def delete mac
|
|||
a6db0470 | Paul Kelly | parse(super("#{@variant}/#{mac}"))
|
|
0f29f96e | Ohad Levy | end
|
|
# Requests that the proxy download the bootfile from the media's source
|
|||
# [+args+] : Hash containing
|
|||
# :prefix => String containing the location within the TFTP tree to store the file
|
|||
# :path => String containing the URL of the file to download
|
|||
# Returns : Boolean status
|
|||
def fetch_boot_file args
|
|||
parse(post(args, "fetch_boot_file"))
|
|||
end
|
|||
# returns the TFTP boot server for this proxy
|
|||
def bootServer
|
|||
17ae1ec8 | Ohad Levy | response = parse get("serverName")
|
|
if response and response["serverName"] and !response["serverName"].blank?
|
|||
return response["serverName"]
|
|||
end
|
|||
false
|
|||
a6f4f5f7 | Ohad Levy | rescue RestClient::ResourceNotFound
|
|
nil
|
|||
0f29f96e | Ohad Levy | end
|
|
218bd6e0 | Justin Sherrill | ||
# Create a default pxe menu
|
|||
# [+args+] : Hash containing
|
|||
# :menu => String containing the menu text
|
|||
# Returns : Boolean status
|
|||
def create_default args
|
|||
parse(post(args, "create_default"))
|
|||
end
|
|||
0f29f96e | Ohad Levy | end
|
|
end
|