Class: Puppet::Transport::Powerstore
- Inherits:
-
Object
- Object
- Puppet::Transport::Powerstore
- Defined in:
- lib/puppet/transport/powerstore.rb
Overview
The main connection class to a Device endpoint
Instance Attribute Summary collapse
-
#connection_info ⇒ Object
readonly
Returns the value of attribute connection_info.
Instance Method Summary collapse
- #add_keys_to_request(request, hash) ⇒ Object
- #authenticate(_path_params, _query_params, _header_params, _body_params) ⇒ Object
- #call_op(path_params, query_params, header_params, body_params, operation_path, operation_verb, parent_consumes) ⇒ Object
- #close(_context) ⇒ Object
-
#facts(_context) ⇒ Object
FIXME: facts not implemented.
-
#initialize(_context, connection_info) ⇒ Powerstore
constructor
A new instance of Powerstore.
-
#to_query(hash) ⇒ Object
Shared methods.
- #verify(context) ⇒ Object
Constructor Details
#initialize(_context, connection_info) ⇒ Powerstore
Returns a new instance of Powerstore.
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
# File 'lib/puppet/transport/powerstore.rb', line 9 def initialize(_context, connection_info) connection_info[:schema] ||= 'https' connection_info[:port] ||= 443 connection_info[:base_path] ||= '/api/rest' @connection_info = connection_info @auth_headers = {} # TODO: Add additional validation for connection_info # port = connection_info[:port].nil? ? 443 : connection_info[:port] # Puppet.debug "Trying to connect to #{connection_info[:host]}:#{port} as user #{connection_info[:user]}" # NOTE: the authentication header only needs to be sent in the first request # subsequent requests are authenticated using the persistent cookie returned from the first request # see https://www.dellemc.com/en-us/collaterals/unauth/technical-guides-support-information/products/storage/docu69331.pdf # page 44: Connecting and authenticating end |
Instance Attribute Details
#connection_info ⇒ Object (readonly)
Returns the value of attribute connection_info.
7 8 9 |
# File 'lib/puppet/transport/powerstore.rb', line 7 def connection_info @connection_info end |
Instance Method Details
#add_keys_to_request(request, hash) ⇒ Object
58 59 60 61 |
# File 'lib/puppet/transport/powerstore.rb', line 58 def add_keys_to_request(request, hash) hash.each { |x, v| request[x] = v } if hash @auth_headers.each { |x, v| request[x] = v } if @auth_headers end |
#authenticate(_path_params, _query_params, _header_params, _body_params) ⇒ Object
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/puppet/transport/powerstore.rb', line 35 def authenticate(_path_params, _query_params, _header_params, _body_params) return true if connection_info[:auth] == 'none' uri_string = "#{connection_info[:schema]}://#{connection_info[:host]}:#{connection_info[:port]}#{connection_info[:base_path]}/appliance" uri = URI(uri_string) req = Net::HTTP::Get.new(uri) req.basic_auth @connection_info[:user], connection_info[:password].unwrap http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = uri.scheme == 'https' http.verify_mode = OpenSSL::SSL::VERIFY_NONE http.start begin response = http.request req # Net::HTTPResponse object @auth_headers['DELL-EMC-TOKEN'] = response['DELL-EMC-TOKEN'] || 'auth_token' @auth_headers['Cookie'] = response['Set-Cookie'] || 'auth_cookie' true rescue StandardError => e STDOUT.print({ _error: e.to_h }.to_json) false end end |
#call_op(path_params, query_params, header_params, body_params, operation_path, operation_verb, parent_consumes) ⇒ Object
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/puppet/transport/powerstore.rb', line 63 def call_op(path_params, query_params, header_params, body_params, operation_path, operation_verb, parent_consumes) uri_string = "#{connection_info[:schema]}://#{connection_info[:host]}:#{connection_info[:port]}#{connection_info[:base_path]}#{operation_path}" % path_params if !query_params['query_string'].nil? uri_string = uri_string + '?' + query_params['query_string'] else if operation_verb == 'Get' # && operation_path.include?('query') query_params['select'] = '*' end uri_string = uri_string + '?' + to_query(query_params) unless query_params.empty? end header_params['Content-Type'] = parent_consumes # FIXME: this always requests the first 2000 pages of results, might be better to implement dynamic pagination based on 206 HTTP return code. header_params['Range'] = '0-2000' verify_mode = OpenSSL::SSL::VERIFY_NONE return unless authenticate(path_params, query_params, header_params, body_params) Puppet.info('Authentication succeeded') uri = URI(uri_string) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = uri.scheme == 'https' http.verify_mode = verify_mode if operation_verb == 'Get' req = Net::HTTP::Get.new(uri) elsif operation_verb == 'Put' req = Net::HTTP::Put.new(uri) elsif operation_verb == 'Patch' req = Net::HTTP::Patch.new(uri) elsif operation_verb == 'Delete' req = Net::HTTP::Delete.new(uri) elsif operation_verb == 'Post' req = Net::HTTP::Post.new(uri) end add_keys_to_request(req, header_params) if operation_verb != 'Get' && body_params req.body = body_params.key?('file_content') ? body_params['file_content'] : body_params.to_json end Puppet.debug("URI is (#{operation_verb}) #{uri}, body is #{body_params}, query params are #{query_params}, headers are #{header_params}") http.start do response = http.request req # Net::HTTPResponse object Puppet.debug("response code is #{response.code} and body is #{response.body}") success = response.is_a? Net::HTTPSuccess Puppet.info("Called (#{operation_verb}) endpoint at #{uri}, success was #{success}") return response unless response.code == '206' # we received a partial response body = [] loop do body += JSON.parse(response.body) m = response['content-range'].match %r{(?<from>\d+)-(?<to>\d+)/(?<total>\d+)} range_to = m['to'].to_i range_total = m['total'].to_i break if range_to + 1 >= range_total req['Range'] = "#{range_to + 1}-#{range_to + 2000}" response = http.request req end response.body = body.to_json return response end end |
#close(_context) ⇒ Object
136 137 138 139 |
# File 'lib/puppet/transport/powerstore.rb', line 136 def close(_context) # FIXME: not implemented # Close connection, free up resources end |
#facts(_context) ⇒ Object
FIXME: facts not implemented
125 126 127 128 129 |
# File 'lib/puppet/transport/powerstore.rb', line 125 def facts(_context) { 'fact1' => 'value1', } end |
#to_query(hash) ⇒ Object
Shared methods
27 28 29 30 31 32 33 |
# File 'lib/puppet/transport/powerstore.rb', line 27 def to_query(hash) if hash return_value = hash.map { |x, v| "#{x}=#{v}" }.reduce { |x, v| "#{x}&#{v}" } return return_value unless return_value.nil? end '' end |
#verify(context) ⇒ Object
131 132 133 134 |
# File 'lib/puppet/transport/powerstore.rb', line 131 def verify(context) # FIXME: not implemented # Test that transport can talk to the remote target end |