hpe3par_sdk 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,86 @@
1
+ # (c) Copyright 2016-2017 Hewlett Packard Enterprise Development LP
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software distributed
8
+ # under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9
+ # CONDITIONS OF ANY KIND, either express or implied. See the License for the
10
+ # specific language governing permissions and limitations under the License.
11
+
12
+ module Hpe3parSdk
13
+ #defined at the Module level. Can be accessed by all classes in the module
14
+ class << self
15
+ attr_accessor :logger
16
+ end
17
+
18
+ @logger = nil
19
+
20
+
21
+ class MultiLog
22
+ attr_reader :level
23
+
24
+ def initialize(args={})
25
+ @level = args[:level] || Logger::Severity::DEBUG
26
+ @loggers = []
27
+
28
+ Array(args[:loggers]).each { |logger| add_logger(logger) }
29
+ end
30
+
31
+ def add_logger(logger)
32
+ logger.level = level
33
+ logger.progname = 'ruby-3parclient'
34
+ @loggers << logger
35
+ end
36
+
37
+ def level=(level)
38
+ @level = level
39
+ @loggers.each { |logger| logger.level = level }
40
+ end
41
+
42
+ def close
43
+ @loggers.map(&:close)
44
+ end
45
+
46
+ def add(level, *args)
47
+ @loggers.each { |logger| logger.add(level, args) }
48
+ end
49
+
50
+ Logger::Severity.constants.each do |level|
51
+ define_method(level.downcase) do |*args|
52
+ @loggers.each { |logger| logger.send(level.downcase, args) }
53
+ end
54
+
55
+ define_method("#{ level.downcase }?".to_sym) do
56
+ @level <= Logger::Severity.const_get(level)
57
+ end
58
+ end
59
+ end
60
+
61
+ class CustomFormatter < Logger::Formatter #:nodoc:
62
+ def call(severity, datetime, progname, msg)
63
+ # msg2str is the internal helper that handles different msgs correctly
64
+ date_format = datetime.strftime('%Y-%m-%d %H:%M:%S%z')
65
+ "[#{date_format} ##{Process.pid}] [#{progname}] #{severity} -- : "+ msg.join($/) + "#{$/}"
66
+ end
67
+ end
68
+
69
+ class CustomHTTPFormatter #:nodoc:
70
+ attr_accessor :level, :logger, :current_time
71
+
72
+ def initialize(logger, level)
73
+ @logger = logger
74
+ @level = level.to_sym
75
+ end
76
+
77
+ def format(request, response)
78
+ http_method = request.http_method.name.split("::").last.upcase
79
+ path = request.path.to_s
80
+ content_length = response.respond_to?(:headers) ? response.headers['Content-Length'] : response['Content-Length']
81
+ @logger.send @level, "[#{response.code} #{http_method} #{path} #{content_length || '-'} ]"
82
+ end
83
+ end
84
+
85
+
86
+ end
@@ -0,0 +1,62 @@
1
+ # (c) Copyright 2016-2017 Hewlett Packard Enterprise Development LP
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software distributed
8
+ # under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9
+ # CONDITIONS OF ANY KIND, either express or implied. See the License for the
10
+ # specific language governing permissions and limitations under the License.
11
+
12
+ require_relative 'util'
13
+ require_relative 'constants'
14
+ require_relative 'exceptions'
15
+
16
+ module Hpe3parSdk
17
+ # Port Manager Rest API methods
18
+ class PortManager
19
+ def initialize(http)
20
+ @http = http
21
+ @ports_uri = '/ports'
22
+ end
23
+
24
+ def get_ports
25
+ ports_list = []
26
+ response = @http.get(@ports_uri)
27
+ response[1]['members'].each do |port|
28
+ ports_list.push(Port.new(port))
29
+ end
30
+ ports_list
31
+ end
32
+
33
+ def get_fc_ports(state)
34
+ get_protocol_ports(PortProtocol::FC, state)
35
+ end
36
+
37
+ def get_iscsi_ports(state)
38
+ get_protocol_ports(PortProtocol::ISCSI, state)
39
+ end
40
+
41
+ def get_ip_ports(state)
42
+ get_protocol_ports(PortProtocol::IP, state)
43
+ end
44
+
45
+ def get_protocol_ports(protocol, state = nil)
46
+ return_ports = []
47
+ ports = get_ports
48
+ if ports
49
+ ports.each do |port|
50
+ if port.protocol == protocol
51
+ if state.nil?
52
+ return_ports.push(port)
53
+ elsif port.linkState == state
54
+ return_ports.push(port)
55
+ end
56
+ end
57
+ end
58
+ end
59
+ return_ports
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,64 @@
1
+ # (c) Copyright 2016-2017 Hewlett Packard Enterprise Development LP
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software distributed
8
+ # under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9
+ # CONDITIONS OF ANY KIND, either express or implied. See the License for the
10
+ # specific language governing permissions and limitations under the License.
11
+
12
+ require_relative 'util'
13
+ require_relative 'exceptions'
14
+
15
+ module Hpe3parSdk
16
+ class QOSManager
17
+ def initialize(http)
18
+ @http = http
19
+ end
20
+
21
+ def query_qos_rules
22
+ response = @http.get('/qos')
23
+ qos_members = []
24
+ response[1]['members'].each do |qos_member|
25
+ qos_members.push(QoSRule.new(qos_member))
26
+ end
27
+ qos_members
28
+ end
29
+
30
+ def query_qos_rule(target_name, target_type)
31
+ response = @http.get("/qos/#{target_type}:#{target_name}")
32
+ QoSRule.new(response[1])
33
+ end
34
+
35
+ def qos_rule_exists?(target_name, target_type)
36
+ begin
37
+ query_qos_rule(target_name, target_type)
38
+ return true
39
+ rescue Hpe3parSdk::HTTPNotFound => ex
40
+ return false
41
+ end
42
+ end
43
+
44
+ def create_qos_rules(target_name, qos_rules, target_type)
45
+ info = { 'name' => target_name,
46
+ 'type' => target_type }
47
+
48
+ info = Util.merge_hash(info, qos_rules)
49
+
50
+ response = @http.post('/qos', body: info)
51
+ response[1]
52
+ end
53
+
54
+ def modify_qos_rules(target_name, qos_rules, target_type)
55
+ response = @http.put("/qos/#{target_type}:#{target_name}", body: qos_rules)
56
+ response
57
+ end
58
+
59
+ def delete_qos_rules(target_name, target_type)
60
+ response = @http.delete("/qos/#{target_type}:#{target_name}")
61
+ response[1]
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,46 @@
1
+ # (c) Copyright 2016-2017 Hewlett Packard Enterprise Development LP
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software distributed
8
+ # under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9
+ # CONDITIONS OF ANY KIND, either express or implied. See the License for the
10
+ # specific language governing permissions and limitations under the License.
11
+
12
+ require 'net/ssh'
13
+ require_relative 'exceptions'
14
+ require 'logger'
15
+ require_relative 'multi_log'
16
+
17
+ module Hpe3parSdk
18
+ class SSH
19
+
20
+ attr_accessor :ip, :username, :password, :port, :conn_timeout, :privatekey, :http_log_debug, :logger
21
+
22
+ def initialize(ip, username, password, port=nil, conn_timeout=nil, privatekey=nil)
23
+ @ip = ip
24
+ @username = username
25
+ @password = password
26
+ @port = port
27
+ @conn_timeout = conn_timeout
28
+ @privatekey = privatekey
29
+ @http_log_debug = http_log_debug
30
+ end
31
+
32
+ def run(command)
33
+ begin
34
+ ssh = Net::SSH.start(@ip, @username, :password => @password)
35
+ cmd = "#{command} -csvtable -nohdtot"
36
+ Hpe3parSdk.logger.debug("Sending SSH command [#{cmd}]")
37
+ stdout, stederr = ssh.exec!(cmd)
38
+ ssh.close()
39
+ stdout
40
+ rescue Hpe3parSdk::HPE3PARException => ex
41
+ Hpe3parSdk.logger.error("(#{__method__}) #{ex.message}")
42
+ end
43
+ end
44
+ end
45
+ end
46
+
@@ -0,0 +1,98 @@
1
+ # (c) Copyright 2016-2017 Hewlett Packard Enterprise Development LP
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software distributed
8
+ # under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9
+ # CONDITIONS OF ANY KIND, either express or implied. See the License for the
10
+ # specific language governing permissions and limitations under the License.
11
+
12
+ require_relative 'exceptions'
13
+ require_relative 'models'
14
+
15
+ module Hpe3parSdk
16
+ # Task Manager Rest API methods
17
+ class TaskManager
18
+ def initialize(http)
19
+ @http = http
20
+ end
21
+
22
+ def get_all_tasks
23
+ tasks = Array[]
24
+ response = @http.get('/tasks')
25
+ response[1]['members'].each do |member|
26
+ tasks.push(Task.new(member))
27
+ end
28
+ tasks
29
+ end
30
+
31
+ def get_task(task_id)
32
+ if task_id.is_a? Integer
33
+ response = @http.get("/tasks/#{task_id}")
34
+ Task.new(response[1])
35
+ else
36
+ raise Hpe3parSdk::HTTPBadRequest.new(
37
+ nil, "Task id '#{task_id}' is not of type integer"
38
+ )
39
+ end
40
+ end
41
+
42
+ def cancel_task(task_id)
43
+ if task_id.is_a? Integer
44
+ _body = Hash.new
45
+ _body['action'] = Hpe3parSdk::TaskAction::CANCEL_TASK
46
+ @http.put("/tasks/#{task_id}", body: _body)
47
+ else
48
+ raise HPE3PARException.new(
49
+ nil, "Task id #{task_id} is not of type integer"
50
+ )
51
+ end
52
+ end
53
+
54
+ def wait_for_task_to_end(task_id, poll_rate_secs)
55
+ _wait_for_task_to_end_loop(task_id, poll_rate_secs)
56
+ end
57
+
58
+ def _wait_for_task_to_end_loop(task_id, poll_rate_secs)
59
+ task = get_task(task_id)
60
+
61
+ while task != nil do #loop begin
62
+ state = task.status
63
+ if state == Hpe3parSdk::TaskStatus::DONE
64
+ break
65
+ end
66
+
67
+ if state == Hpe3parSdk::TaskStatus::CANCELLED
68
+ Hpe3parSdk.logger.info("Task #{task.task_id} was CANCELLED!!!")
69
+ break
70
+ end
71
+
72
+ if state == Hpe3parSdk::TaskStatus::FAILED
73
+ msg = "Task '#{task.task_id}' has FAILED!!!"
74
+ Hpe3parSdk.logger.info(msg)
75
+ raise Hpe3parSdk::HPE3PARException.new(message: msg)
76
+ end
77
+
78
+ if state == Hpe3parSdk::TaskStatus::ACTIVE
79
+ sleep(poll_rate_secs)
80
+ task = get_task(task.task_id);
81
+ Hpe3parSdk.logger
82
+ .info("Polling task #{task.task_id} current status: #{Hpe3parSdk::TaskStatus.get_string(task.status)}")
83
+ end
84
+
85
+ end #loop end
86
+
87
+ #Return the Task Result
88
+ if task != nil && task.status != nil && task.status == 'DONE'
89
+ return true
90
+
91
+ else
92
+ return false
93
+ end
94
+
95
+ end
96
+
97
+ end
98
+ end
@@ -0,0 +1,15 @@
1
+ # (c) Copyright 2016-2017 Hewlett Packard Enterprise Development LP
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software distributed
8
+ # under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9
+ # CONDITIONS OF ANY KIND, either express or implied. See the License for the
10
+ # specific language governing permissions and limitations under the License.
11
+
12
+ module Hpe3parSdk
13
+ class TCL_Parser
14
+ end
15
+ end
@@ -0,0 +1,30 @@
1
+ # (c) Copyright 2016-2017 Hewlett Packard Enterprise Development LP
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software distributed
8
+ # under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9
+ # CONDITIONS OF ANY KIND, either express or implied. See the License for the
10
+ # specific language governing permissions and limitations under the License.
11
+
12
+ module Hpe3parSdk
13
+ class Util
14
+ def self.merge_hash(hash1, hash2)
15
+ raise TypeError, 'hash1 is not a hash' unless hash1.class == Hash
16
+ raise TypeError, 'hash2 is not a hash' unless hash2.class == Hash
17
+
18
+ hash3 = hash2.merge(hash1)
19
+ hash3
20
+ end
21
+
22
+ def self.log_exception(exception, caller_location)
23
+ formatted_stack_trace = exception.backtrace
24
+ .map { |line| "\t\tfrom #{line}" }
25
+ .join($/)
26
+ err_msg = "(#{caller_location}) #{exception}#{$/} #{formatted_stack_trace}"
27
+ Hpe3parSdk.logger.error(err_msg)
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,14 @@
1
+ # (c) Copyright 2016-2017 Hewlett Packard Enterprise Development LP
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software distributed
8
+ # under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9
+ # CONDITIONS OF ANY KIND, either express or implied. See the License for the
10
+ # specific language governing permissions and limitations under the License.
11
+
12
+ module Hpe3parSdk
13
+ VERSION = '1.0.0'.freeze
14
+ end
@@ -0,0 +1,119 @@
1
+ # (c) Copyright 2016-2017 Hewlett Packard Enterprise Development LP
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software distributed
8
+ # under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9
+ # CONDITIONS OF ANY KIND, either express or implied. See the License for the
10
+ # specific language governing permissions and limitations under the License.
11
+
12
+ require_relative 'util'
13
+ require_relative 'exceptions'
14
+
15
+ module Hpe3parSdk
16
+ class VlunManager
17
+ def initialize(http, vlun_query_supported = false)
18
+ @http = http
19
+ @vlun_query_supported = vlun_query_supported
20
+ end
21
+
22
+ def create_vlun(volume_name, host_name, lun, port_pos, no_vcn, override_lower_priority, auto)
23
+ info = {}
24
+ info['volumeName'] = volume_name
25
+ info['lun'] = lun unless lun.nil?
26
+ info['hostname'] = host_name if host_name
27
+ info['portPos'] = port_pos if port_pos
28
+ info['noVcn'] = no_vcn if no_vcn
29
+ if override_lower_priority
30
+ info['overrideLowerPriority'] = override_lower_priority
31
+ end
32
+ if auto
33
+ info['autoLun'] = true
34
+ info['maxAutoLun'] = 0
35
+ info['lun'] = 0
36
+ end
37
+ response = @http.post('/vluns', body: info)
38
+ if response[0]
39
+ location = response[0]['location'].gsub!('/api/v1/vluns/', '')
40
+ return location
41
+ else
42
+ return nil
43
+ end
44
+ end
45
+
46
+ def vlun_exists?(volume_name, lunid, hostname, port)
47
+ begin
48
+ vlun_id = ''
49
+ if volume_name
50
+ vlun_id = volume_name
51
+ end
52
+ if lunid
53
+ vlun_id = vlun_id + ",#{lunid}"
54
+ end
55
+ if hostname
56
+ vlun_id = vlun_id + ',' + hostname
57
+ end
58
+ if port
59
+ if hostname.nil?
60
+ vlun_id = vlun_id + ","
61
+ end
62
+ vlun_id = vlun_id + ',' + "#{port[:node].to_s}:#{port[:slot].to_s}:#{port[:cardPort].to_s}"
63
+ end
64
+ if (volume_name.nil? or volume_name.empty?) or lunid.nil? and (hostname.nil? or port.nil?)
65
+ raise HPE3PARException.new(nil, "Some or all parameters are missing : volume_name, lunid, hostname or port")
66
+ end
67
+
68
+ @http.get("/vluns/#{vlun_id}")
69
+ return true
70
+ rescue Hpe3parSdk::HTTPNotFound => ex
71
+ return false
72
+ end
73
+ end
74
+
75
+ def delete_vlun(volume_name, lun_id, host_name, port)
76
+ vlun = "#{volume_name},#{lun_id}"
77
+ vlun += ",#{host_name}" if host_name
78
+ if port
79
+ vlun += "," if host_name.nil?
80
+ vlun += ",#{port[:node]}:#{port[:slot]}:#{port[:cardPort]}"
81
+ end
82
+ response, body = @http.delete("/vluns/#{vlun}")
83
+ end
84
+
85
+ def get_vluns
86
+ response = @http.get('/vluns')
87
+ vluns_list=[]
88
+ response[1]['members'].each do |vlun_member|
89
+ vluns_list.push(VLUN.new(vlun_member))
90
+ end
91
+ vluns_list
92
+ end
93
+
94
+ def get_vlun(volume_name)
95
+ # This condition if true is untested
96
+ if volume_name.nil? || volume_name.strip.empty?
97
+ raise HPE3PARException.new(nil, "Invalid volume name #{volume_name}")
98
+ end
99
+ if @vlun_query_supported
100
+ query = %("volumeName EQ #{volume_name}")
101
+ response, body = @http.get("/vluns?query=#{query}")
102
+ # Return the first VLUN found for the volume.
103
+ if body.key?('members') && !body['members'].empty?
104
+ return VLUN.new(body['members'][0])
105
+ else
106
+ raise HTTPNotFound.new(nil, "No VLUNs for volumeName #{volume_name} found", nil, 404)
107
+ end
108
+ else
109
+ vluns = get_vluns
110
+ if vluns
111
+ vluns.each do |vlun|
112
+ return vlun if vlun.volume_name == volume_name
113
+ end
114
+ end
115
+ raise HTTPNotFound.new(nil, 'Vlun doesnt exist', nil, 404)
116
+ end
117
+ end
118
+ end
119
+ end