hpe3par_sdk 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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