Skip to content

Commit

Permalink
Merge pull request thecodeteam#1 from sushilrai/scaleio_discovery
Browse files Browse the repository at this point in the history
LUD-62 ScaleIO puppet model to support discover and inventory of scaleIO cluster and node
  • Loading branch information
gavin-scott authored Feb 13, 2018
2 parents c962dab + 5ed455d commit c35167b
Show file tree
Hide file tree
Showing 2 changed files with 194 additions and 0 deletions.
124 changes: 124 additions & 0 deletions bin/discovery.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
#!/opt/puppet/bin/ruby

require "trollop"
require "json"
require "timeout"
require "pathname"

puppet_dir = File.join(Pathname.new(__FILE__).parent.parent,'lib','puppet')
require "%s/scaleio/transport" % [puppet_dir]

@opts = Trollop::options do
opt :server, "ScaleIO gateway", :type => :string, :required => true
opt :port, "ScaleIO gateway port", :default => 443
opt :username, "ScaleIO gateway username", :type => :string, :required => true
opt :password, "ScaleIO gateway password", :type => :string, :default => ENV["PASSWORD"], :required => true
opt :timeout, "ScaleIO gateway connection timeout", :type => :integer, :default => 300, :required => false
opt :output, "Location of the file where facts file needs to be created", :type => :string, :required => false
end

def collect_scaleio_facts
facts = {}
facts[:scaleio_systems] = scaleio_systems
scaleio_systems.each do |scaleio_system|
facts[scaleio_system["id"]] = {:sds => [], :sdc => [], :protection_domains => []}
facts[scaleio_system["id"]][:sds] = scaleio_sds(scaleio_system)
facts[scaleio_system["id"]][:sdc] = scaleio_sdc(scaleio_system)
facts[scaleio_system["id"]][:protection_domains] = protection_domains(scaleio_system)
facts[scaleio_system["id"]][:volumes] = scaleio_volumes(scaleio_system)
facts[scaleio_system["id"]][:fault_sets] = scaleio_faultsets(scaleio_system)
facts[scaleio_system["id"]][:protection_domains].each do |protection_domain|
facts[scaleio_system["id"]][protection_domain["id"]] ||= {}
facts[scaleio_system["id"]][protection_domain["id"]][:storage_pools] = storage_pools(scaleio_system, protection_domain)
facts[scaleio_system["id"]][protection_domain["id"]][:storage_pools].each do |storage_pool|
facts[scaleio_system["id"]][protection_domain["id"]][storage_pool["id"]] ||= {}
facts[scaleio_system["id"]][protection_domain["id"]][storage_pool["id"]][:disks] = disks(storage_pool)
end
end
end
facts
end

def scaleio_systems
url = transport.get_url("/api/types/System/instances")
transport.post_request(url, {}, "get") || []
end

def scaleio_sds(scaleio_system)
sds_url = "/api/types/Sds/instances?systemId=%s" % [scaleio_system["id"]]
url = transport.get_url(sds_url)
transport.post_request(url, {}, "get") || []
end

def scaleio_sdc(scaleio_system)
sdc_url = "/api/types/Sdc/instances?systemId=%s" % [scaleio_system["id"]]
url = transport.get_url(sdc_url)
transport.post_request(url, {}, "get") || []
end

def protection_domains(scaleio_system)
pd_url = "/api/types/ProtectionDomain/instances?systemId=%s" % [scaleio_system["id"]]
url = transport.get_url(pd_url)
transport.post_request(url, {}, "get") || []
end

def storage_pools(scaleio_system, protection_domain)
sp_url = "/api/types/StoragePool/instances?systemId=%s&protectiondomainId=%s" % [scaleio_system["id"], protection_domain["id"]]
url = transport.get_url(sp_url)
transport.post_request(url, {}, "get") || []
end

def disks(storage_pool)
sp_url = "/api/types/Device/instances?storagepoolId=%s" % [storage_pool["id"]]
url = transport.get_url(sp_url)
transport.post_request(url, {}, "get") || []
end

def scaleio_volumes(scaleio_system)
volume_url = "/api/types/Volume/instances?systemId=%s" % [scaleio_system["id"]]
url = transport.get_url(volume_url)
transport.post_request(url, {}, "get") || []
end

def scaleio_faultsets(scaleio_system)
faultset_url = "/api/types/FaultSet/instances?systemId=%s" % [scaleio_system["id"]]
url = transport.get_url(faultset_url)
transport.post_request(url, {}, "get") || []
end

def transport
@transport ||= Puppet::ScaleIO::Transport.new(@opts)
end

def scaleio_cookie
@scaleio_cookie ||= transport.get_scaleio_cookie
end

facts = {}
begin
Timeout.timeout(@opts[:timeout]) do
facts = collect_scaleio_facts.to_json
end
rescue Timeout::Error
puts "Timed out trying to gather ScaleIO Inventory"
exit 1
rescue Exception => e
puts "#{e}\n#{e.backtrace.join("\n")}"
exit 1
else
if facts.empty?
puts "Could not get updated facts"
exit 1
else
puts "Successfully gathered inventory."
if @opts[:output]
File.write(@opts[:output], JSON.pretty_generate(JSON.parse(facts)))
else
results ||= {}
scaleio_cache = "/opt/Dell/ASM/cache"
Dir.mkdir(scaleio_cache) unless Dir.exists? scaleio_cache
file_path = File.join(scaleio_cache, "#{opts[:server]}.json")
File.write(file_path, results) unless results.empty?
end
end
end
70 changes: 70 additions & 0 deletions lib/puppet/scaleio/transport.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
require "net/https"
require "rest-client"
require "cgi"
require "json"

require "puppet"

module Puppet
module ScaleIO
class Transport
attr_accessor :host, :port, :user, :password, :scaleio_cookie

def initialize(opts)
self.user = opts[:username]
self.host = opts[:server]
self.password = opts[:password]
self.port = opts[:port] || 443
end

def cgi_escape(value)
CGI.escape(value)
end

def get_scaleio_cookie
return @scaleio_cookie unless @scaleio_cookie.nil?

response = ""
url = "https://%s:%s@%s:%s/api/login" % [cgi_escape(self.user),
cgi_escape(self.password),
self.host,
self.port]

begin
response = RestClient::Request.execute(
:url => url,
:method => :get,
:verify_ssl => false ,
:payload => '{}',
:headers => {:content_type => :json,
:accept => :json })
rescue => ex
Puppet.error "Failed to get cookie from ScaleIO Gateway with error %s" % [ex.message]
end
@scaleio_cookie = response.strip.tr('""', '')
end

def get_url(end_point)
return "https://%s:%s@%s:%s/%s" % [self.user, self.get_scaleio_cookie, self.host, self.port, end_point]
end

def post_request(url, payload, method)
response = RestClient::Request.execute(:url => url,
:method => method.to_sym,
:verify_ssl => false,
:payload => payload,
:headers => headers
)
JSON.parse(response)
end

def headers
{
:content_type => :json,
:accept => :json,
'Cookie' => self.scaleio_cookie || get_scaleio_cookie
}
end
end
end
end

0 comments on commit c35167b

Please sign in to comment.