lib/rcs-db/frontend.rb
#
# Helper class to send push notification to the network controller
#
require 'net/http'
require 'rcs-common/trace'
module RCS
module DB
class Frontend
extend RCS::Tracer
def self.nc_push(object)
begin
# find a network controller in the status list
nc = ::Status.where({type: 'nc'}).any_in(status: [::Status::OK, ::Status::WARN]).first
if nc.nil?
trace(:error, "The rcs-controller component is not OK")
return false
end
trace(:info, "Frontend: Pushing configuration to #{object.respond_to?(:name) ? object.name : object}")
headers = {}
sig = ::Signature.where({scope: 'server'}).first
headers['X-Auth-Frontend'] = sig[:value]
# send the push request
http = Net::HTTP.new(nc.address, 80)
http.read_timeout = 500
headers['Content-type'] = 'application/json'
content = object.attributes.reject{ |name| name.to_s == '_grid' }.to_json
resp = http.send_request('PUSH', '/', content, headers)
return false unless resp.body == "OK"
rescue EOFError => e
trace :error, "Frontend NC PUSH (ignored): #{e.message}"
rescue Exception => e
trace :error, "Frontend NC PUSH: #{e.message}"
return false
end
return true
end
def self.proxy(method, proto, host, url, content = nil, headers = {})
begin
raise "no collector found" if ::Status.where({type: 'collector'}).any_in(status: [::Status::OK, ::Status::WARN]).count == 0
# request to one of the collectors
collector = ::Status.where({type: 'collector'}).any_in(status: [::Status::OK, ::Status::WARN]).sample
trace :debug, "Frontend: Proxying #{method} #{proto} #{host} #{url} to #{collector.name}"
sig = ::Signature.where({scope: 'server'}).first
headers['X-Auth-Frontend'] = sig[:value]
# send the push request
http = Net::HTTP.new(collector.address, 80)
http.send_request('PROXY', "/#{method}/#{proto}/#{host}#{url}", content, headers)
rescue Exception => e
trace :error, "Frontend Collector PROXY: #{e.message}"
raise "Cannot proxy the request"
end
end
def self.collector_put(filename, content, factory, user)
begin
raise "no collector found" if ::Status.where({type: 'collector'}).any_in(status: [::Status::OK, ::Status::WARN]).count == 0
saved = false
# put the file on every collector, we cannot know where it will be requested
::Status.where({type: 'collector'}).any_in(status: [::Status::OK, ::Status::WARN]).each do |collector|
next if collector.address.nil?
trace :info, "Frontend: Putting #{filename} to #{collector.name} (#{collector.address})"
headers = {}
sig = ::Signature.where({scope: 'server'}).first
headers['X-Auth-Frontend'] = sig[:value]
# send the request
http = Net::HTTP.new(collector.address, 80)
resp = http.request_put("/#{filename}", content, headers)
raise resp.body unless resp.body == "OK"
# save the filename in the public documents
unless saved
user = ::User.find(user)
::PublicDocument.create({name: File.basename(filename, '.*'),
user: user[:name],
factory: [factory[:_id]],
time: Time.now.getutc.to_i})
saved = true
end
end
rescue Exception => e
trace :error, "Frontend Collector PUT: #{e.message}"
raise "Cannot put file on collector: #{e.message}"
end
end
def self.collector_del(filename)
begin
raise "no collector found" if ::Status.where({type: 'collector'}).any_in(status: [::Status::OK, ::Status::WARN]).count == 0
# put the file on every collector, we cannot know where it will be requested
::Status.where({type: 'collector'}).any_in(status: [::Status::OK, ::Status::WARN]).each do |collector|
next if collector.address.nil?
trace :info, "Frontend: Deleting #{filename} from #{collector.name} (#{collector.address})"
headers = {}
sig = ::Signature.where({scope: 'server'}).first
headers['X-Auth-Frontend'] = sig[:value]
# send the request
http = Net::HTTP.new(collector.address, 80)
resp = http.send_request('DELETE', "/#{filename}", nil, headers)
raise "wrong response from collector" unless resp.body == "OK"
end
rescue Exception => e
trace :error, "Frontend Collector DELETE: #{e.message}"
raise "Cannot delete file from collector"
end
end
end
end #DB::
end #RCS::