opennebula-cli 5.8.5 → 5.9.80.pre
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.
- checksums.yaml +4 -4
- data/bin/oneacct +6 -0
- data/bin/oneacl +8 -1
- data/bin/onecluster +8 -1
- data/bin/onedatastore +8 -1
- data/bin/oneflow +28 -17
- data/bin/oneflow-template +6 -0
- data/bin/onegroup +6 -0
- data/bin/onehook +303 -0
- data/bin/onehost +9 -3
- data/bin/oneimage +16 -0
- data/bin/onemarket +6 -0
- data/bin/onemarketapp +6 -0
- data/bin/onesecgroup +6 -0
- data/bin/oneshowback +6 -0
- data/bin/onetemplate +6 -0
- data/bin/oneuser +11 -6
- data/bin/onevcenter +17 -3
- data/bin/onevdc +6 -0
- data/bin/onevm +18 -5
- data/bin/onevmgroup +6 -0
- data/bin/onevnet +19 -1
- data/bin/onevntemplate +6 -0
- data/bin/onevrouter +6 -0
- data/bin/onezone +6 -0
- data/lib/cli_helper.rb +589 -195
- data/lib/one_helper.rb +37 -2
- data/lib/one_helper/oneacl_helper.rb +99 -84
- data/lib/one_helper/onehook_helper.rb +250 -0
- data/lib/one_helper/onehost_helper.rb +200 -0
- data/lib/one_helper/oneimage_helper.rb +23 -0
- data/lib/one_helper/onesecgroup_helper.rb +2 -2
- data/lib/one_helper/oneuser_helper.rb +3 -3
- data/lib/one_helper/onevcenter_helper.rb +2 -1
- data/lib/one_helper/onevm_helper.rb +729 -599
- data/lib/one_helper/onevnet_helper.rb +24 -2
- data/lib/one_helper/onevrouter_helper.rb +1 -1
- metadata +9 -6
data/lib/one_helper.rb
CHANGED
@@ -397,6 +397,12 @@ EOT
|
|
397
397
|
:description => 'Show info extended (it only works with xml output)'
|
398
398
|
}
|
399
399
|
|
400
|
+
DECRYPT = {
|
401
|
+
:name => 'decrypt',
|
402
|
+
:large => '--decrypt',
|
403
|
+
:description => 'Get decrypted attributes'
|
404
|
+
}
|
405
|
+
|
400
406
|
TEMPLATE_OPTIONS_VM = [TEMPLATE_NAME_VM] + TEMPLATE_OPTIONS + [DRY]
|
401
407
|
|
402
408
|
CAPACITY_OPTIONS_VM = [TEMPLATE_OPTIONS[0], TEMPLATE_OPTIONS[1],
|
@@ -624,7 +630,7 @@ EOT
|
|
624
630
|
# ------- Rest of the pages in the pool, piped to pager --------
|
625
631
|
current = size
|
626
632
|
|
627
|
-
options[:
|
633
|
+
options[:no_header] = true
|
628
634
|
|
629
635
|
loop do
|
630
636
|
rc = pool.get_page(size, current, false)
|
@@ -792,10 +798,38 @@ EOT
|
|
792
798
|
return 0
|
793
799
|
end
|
794
800
|
|
801
|
+
# Check if a resource defined by attributes is referenced in pool
|
802
|
+
#
|
803
|
+
# @param pool pool to search in
|
804
|
+
# @param xpath xpath to search in pool
|
805
|
+
# @param resource_name name of the resource to search (e.g IMAGE)
|
806
|
+
# @attributes hash with resource attributes, must contains :id, :name
|
807
|
+
# and :uname
|
808
|
+
#
|
809
|
+
# atributes {uname => ..., name => ..., id => ...}
|
810
|
+
def check_orphan(pool, xpath, resource_name, attributes)
|
811
|
+
return false if attributes.empty?
|
812
|
+
|
813
|
+
return false unless pool["#{xpath}[#{resource_name}_ID = "\
|
814
|
+
"#{attributes[:id]}]"].nil?
|
815
|
+
|
816
|
+
return false unless pool["#{xpath}[#{resource_name} = "\
|
817
|
+
"'#{attributes[:name]}' and "\
|
818
|
+
"#{resource_name}_UNAME = "\
|
819
|
+
"'#{attributes[:uname]}']"].nil?
|
820
|
+
|
821
|
+
true
|
822
|
+
end
|
823
|
+
|
795
824
|
def show_resource(id, options)
|
796
825
|
resource = retrieve_resource(id)
|
797
826
|
|
798
|
-
|
827
|
+
if !options.key? :decrypt
|
828
|
+
rc = resource.info
|
829
|
+
else
|
830
|
+
rc = resource.info(true)
|
831
|
+
end
|
832
|
+
|
799
833
|
return -1, rc.message if OpenNebula.is_error?(rc)
|
800
834
|
|
801
835
|
if options[:xml]
|
@@ -1018,6 +1052,7 @@ EOT
|
|
1018
1052
|
|
1019
1053
|
pool = case poolname
|
1020
1054
|
when "HOST" then OpenNebula::HostPool.new(client)
|
1055
|
+
when "HOOK" then OpenNebula::HookPool.new(client)
|
1021
1056
|
when "GROUP" then OpenNebula::GroupPool.new(client)
|
1022
1057
|
when "USER" then OpenNebula::UserPool.new(client)
|
1023
1058
|
when "DATASTORE" then OpenNebula::DatastorePool.new(client)
|
@@ -16,129 +16,143 @@
|
|
16
16
|
|
17
17
|
require 'one_helper'
|
18
18
|
|
19
|
+
# Helper for oneacl command
|
19
20
|
class OneAclHelper < OpenNebulaHelper::OneHelper
|
21
|
+
|
20
22
|
def self.rname
|
21
|
-
|
23
|
+
'ACL'
|
22
24
|
end
|
23
25
|
|
24
26
|
def self.conf_file
|
25
|
-
|
27
|
+
'oneacl.yaml'
|
26
28
|
end
|
27
29
|
|
28
|
-
|
30
|
+
# rubocop:disable Lint/IneffectiveAccessModifier
|
31
|
+
private
|
29
32
|
|
30
|
-
|
31
|
-
if id
|
32
|
-
OpenNebula::Acl.new_with_id(id, @client)
|
33
|
-
else
|
34
|
-
xml = OpenNebula::Acl.build_xml
|
35
|
-
OpenNebula::Acl.new(xml, @client)
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
def factory_pool(filter)
|
40
|
-
OpenNebula::AclPool.new(@client)
|
41
|
-
end
|
42
|
-
|
43
|
-
# TODO check that @content[:resources_str] is valid
|
33
|
+
# TODO: check that @content[:resources_str] is valid
|
44
34
|
def self.resource_mask(str)
|
45
|
-
resource_type=str.split(
|
35
|
+
resource_type=str.split('/')[0]
|
46
36
|
|
47
|
-
mask =
|
37
|
+
mask = '------------------'
|
48
38
|
|
49
|
-
resource_type.split(
|
39
|
+
resource_type.split('+').each do |type|
|
50
40
|
case type
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
41
|
+
when 'VM'
|
42
|
+
mask[0] = 'V'
|
43
|
+
when 'HOST'
|
44
|
+
mask[1] = 'H'
|
45
|
+
when 'NET'
|
46
|
+
mask[2] = 'N'
|
47
|
+
when 'IMAGE'
|
48
|
+
mask[3] = 'I'
|
49
|
+
when 'USER'
|
50
|
+
mask[4] = 'U'
|
51
|
+
when 'TEMPLATE'
|
52
|
+
mask[5] = 'T'
|
53
|
+
when 'GROUP'
|
54
|
+
mask[6] = 'G'
|
55
|
+
when 'DATASTORE'
|
56
|
+
mask[7] = 'D'
|
57
|
+
when 'CLUSTER'
|
58
|
+
mask[8] = 'C'
|
59
|
+
when 'DOCUMENT'
|
60
|
+
mask[9] = 'O'
|
61
|
+
when 'ZONE'
|
62
|
+
mask[10] = 'Z'
|
63
|
+
when 'SECGROUP'
|
64
|
+
mask[11] = 'S'
|
65
|
+
when 'VDC'
|
66
|
+
mask[12] = 'v'
|
67
|
+
when 'VROUTER'
|
68
|
+
mask[13] = 'R'
|
69
|
+
when 'MARKETPLACE'
|
70
|
+
mask[14] = 'M'
|
71
|
+
when 'MARKETPLACEAPP'
|
72
|
+
mask[15] = 'A'
|
73
|
+
when 'VMGROUP'
|
74
|
+
mask[16] = 'P'
|
75
|
+
when 'VNTEMPLATE'
|
76
|
+
mask[17] = 't'
|
87
77
|
end
|
88
|
-
|
78
|
+
end
|
89
79
|
mask
|
90
80
|
end
|
91
81
|
|
92
|
-
# TODO check that @content[:resources_str] is valid
|
82
|
+
# TODO: check that @content[:resources_str] is valid
|
93
83
|
def self.right_mask(str)
|
94
|
-
mask =
|
84
|
+
mask = '----'
|
95
85
|
|
96
|
-
str.split(
|
86
|
+
str.split('+').each do |type|
|
97
87
|
case type
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
88
|
+
when 'USE'
|
89
|
+
mask[0] = 'u'
|
90
|
+
when 'MANAGE'
|
91
|
+
mask[1] = 'm'
|
92
|
+
when 'ADMIN'
|
93
|
+
mask[2] = 'a'
|
94
|
+
when 'CREATE'
|
95
|
+
mask[3] = 'c'
|
106
96
|
end
|
107
|
-
|
97
|
+
end
|
108
98
|
|
109
99
|
mask
|
110
100
|
end
|
111
101
|
|
112
|
-
def
|
102
|
+
def factory(id = nil)
|
103
|
+
if id
|
104
|
+
OpenNebula::Acl.new_with_id(id, @client)
|
105
|
+
else
|
106
|
+
xml = OpenNebula::Acl.build_xml
|
107
|
+
OpenNebula::Acl.new(xml, @client)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def factory_pool(_filter)
|
112
|
+
OpenNebula::AclPool.new(@client)
|
113
|
+
end
|
114
|
+
|
115
|
+
def format_pool(_options)
|
113
116
|
config_file = self.class.table_conf
|
114
117
|
|
115
118
|
table = CLIHelper::ShowTable.new(config_file, self) do
|
116
|
-
column :ID,
|
117
|
-
|
119
|
+
column :ID,
|
120
|
+
'Rule Identifier',
|
121
|
+
:size => 5 do |d|
|
118
122
|
d['ID']
|
119
123
|
end
|
120
124
|
|
121
|
-
column :USER,
|
122
|
-
|
123
|
-
|
125
|
+
column :USER,
|
126
|
+
'To which resource owner the rule applies to',
|
127
|
+
:size => 8 do |d|
|
128
|
+
d['STRING'].split(' ')[0]
|
124
129
|
end
|
125
130
|
|
126
|
-
column :RES_VHNIUTGDCOZSvRMAPt,
|
127
|
-
|
128
|
-
|
131
|
+
column :RES_VHNIUTGDCOZSvRMAPt,
|
132
|
+
'Resource to which the rule applies',
|
133
|
+
:size => 22 do |d|
|
134
|
+
OneAclHelper.resource_mask d['STRING'].split(' ')[1]
|
129
135
|
end
|
130
136
|
|
131
|
-
column :RID,
|
132
|
-
d['STRING'].split(
|
137
|
+
column :RID, 'Resource ID', :right, :size => 5 do |d|
|
138
|
+
d['STRING'].split(' ')[1].split('/')[1]
|
133
139
|
end
|
134
140
|
|
135
|
-
column :ZONE,
|
136
|
-
d['STRING'].split(
|
141
|
+
column :ZONE, 'Zone ID', :right, :size => 5 do |d|
|
142
|
+
d['STRING'].split(' ')[3]
|
137
143
|
end
|
138
144
|
|
139
145
|
column :OPE_UMAC,
|
140
|
-
|
141
|
-
|
146
|
+
'Operation to which the rule applies',
|
147
|
+
:size => 8 do |d|
|
148
|
+
OneAclHelper.right_mask d['STRING'].split(' ')[2]
|
149
|
+
end
|
150
|
+
|
151
|
+
column :STRING,
|
152
|
+
'ACL rule in string format',
|
153
|
+
:adjust => true,
|
154
|
+
:left => true do |d|
|
155
|
+
d['STRING']
|
142
156
|
end
|
143
157
|
|
144
158
|
default :ID, :USER, :RES_VHNIUTGDCOZSvRMAPt, :RID, :OPE_UMAC, :ZONE
|
@@ -146,5 +160,6 @@ private
|
|
146
160
|
|
147
161
|
table
|
148
162
|
end
|
163
|
+
# rubocop:enable Lint/IneffectiveAccessModifier
|
149
164
|
|
150
165
|
end
|
@@ -0,0 +1,250 @@
|
|
1
|
+
# -------------------------------------------------------------------------- #
|
2
|
+
# Copyright 2002-2019, OpenNebula Project, OpenNebula Systems #
|
3
|
+
# #
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
5
|
+
# not use this file except in compliance with the License. You may obtain #
|
6
|
+
# a copy of the License at #
|
7
|
+
# #
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0 #
|
9
|
+
# #
|
10
|
+
# Unless required by applicable law or agreed to in writing, software #
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS, #
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
|
13
|
+
# See the License for the specific language governing permissions and #
|
14
|
+
# limitations under the License. #
|
15
|
+
#--------------------------------------------------------------------------- #
|
16
|
+
|
17
|
+
require 'one_helper'
|
18
|
+
require 'rubygems'
|
19
|
+
|
20
|
+
# implements onehook command
|
21
|
+
class OneHookHelper < OpenNebulaHelper::OneHelper
|
22
|
+
|
23
|
+
def self.rname
|
24
|
+
'HOOK'
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.conf_file
|
28
|
+
'onehook.yaml'
|
29
|
+
end
|
30
|
+
|
31
|
+
# Get hook logs
|
32
|
+
#
|
33
|
+
# @param options [Object] CLI user options
|
34
|
+
def hook_logs(options)
|
35
|
+
options[:hook_id].nil? ? hook_id = -1 : hook_id = options[:hook_id]
|
36
|
+
|
37
|
+
if options.key? :success
|
38
|
+
rc = 1
|
39
|
+
elsif options.key? :error
|
40
|
+
rc = -1
|
41
|
+
else
|
42
|
+
rc = 0
|
43
|
+
end
|
44
|
+
|
45
|
+
if options[:since]
|
46
|
+
since_date = DateTime.parse(options[:since]).to_time.to_i
|
47
|
+
else
|
48
|
+
since_date = -1
|
49
|
+
end
|
50
|
+
|
51
|
+
if options[:until]
|
52
|
+
until_date = DateTime.parse(options[:until]).to_time.to_i
|
53
|
+
else
|
54
|
+
until_date = -1
|
55
|
+
end
|
56
|
+
|
57
|
+
hook_log = OpenNebula::HookLog.new(@client)
|
58
|
+
log_info = hook_log.info(since_date, until_date, hook_id, rc)
|
59
|
+
|
60
|
+
if OpenNebula.is_error?(log_info)
|
61
|
+
STDERR.puts(log_info.message)
|
62
|
+
exit(-1)
|
63
|
+
end
|
64
|
+
|
65
|
+
begin
|
66
|
+
exerc = [hook_log.to_hash['HOOKLOG']['HOOK_EXECUTION_RECORD']]
|
67
|
+
exerc = exerc.flatten.compact
|
68
|
+
rescue StandardError
|
69
|
+
exerc = nil
|
70
|
+
end
|
71
|
+
|
72
|
+
if !exerc.nil? && !exerc.empty? && (!options.key? :xml)
|
73
|
+
print_execution(exerc, false)
|
74
|
+
elsif options.key? :xml
|
75
|
+
puts hook_log.to_xml
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
private
|
80
|
+
|
81
|
+
def factory(id = nil)
|
82
|
+
if id
|
83
|
+
OpenNebula::Hook.new_with_id(id, @client)
|
84
|
+
else
|
85
|
+
xml = OpenNebula::Hook.build_xml
|
86
|
+
OpenNebula::Hook.new(xml, @client)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def factory_pool(_user_flag = -2)
|
91
|
+
OpenNebula::HookPool.new(@client)
|
92
|
+
end
|
93
|
+
|
94
|
+
def format_pool(_options)
|
95
|
+
config_file = self.class.table_conf
|
96
|
+
|
97
|
+
table = CLIHelper::ShowTable.new(config_file, self) do
|
98
|
+
column :ID, 'ONE identifier for the Hook', :size => 5 do |d|
|
99
|
+
d['ID']
|
100
|
+
end
|
101
|
+
|
102
|
+
column :NAME, 'Name of the Hook', :left, :size => 25 do |d|
|
103
|
+
d['NAME']
|
104
|
+
end
|
105
|
+
|
106
|
+
column :TYPE, 'Type of the Hook', :left, :size => 45 do |d|
|
107
|
+
d['TYPE']
|
108
|
+
end
|
109
|
+
|
110
|
+
default :ID, :NAME, :TYPE
|
111
|
+
end
|
112
|
+
|
113
|
+
table
|
114
|
+
end
|
115
|
+
|
116
|
+
# Function to print Execution Log records as sent by oned using:
|
117
|
+
# <HOOK_EXECUTION_RECORD>
|
118
|
+
# <HOOK_ID>
|
119
|
+
# <EXECUTION_ID>
|
120
|
+
# <TIMESTAMP>
|
121
|
+
# <ARGUMENTS>
|
122
|
+
# <EXECUTION_RESULT>
|
123
|
+
# <COMMAND>
|
124
|
+
# <STDIN>
|
125
|
+
# <STDOUT>
|
126
|
+
# <STDERR>
|
127
|
+
# <CODE>
|
128
|
+
# </EXECUTION_RESULT>
|
129
|
+
# </HOOK_EXECUTION_RECORD>
|
130
|
+
#
|
131
|
+
def print_execution(execs, header = true)
|
132
|
+
if header
|
133
|
+
puts
|
134
|
+
CLIHelper.print_header('EXECUTION LOG', false)
|
135
|
+
end
|
136
|
+
|
137
|
+
table = CLIHelper::ShowTable.new(nil, self) do
|
138
|
+
unless header
|
139
|
+
column :HOOK, 'Hook ID', :adjust => true do |d|
|
140
|
+
d['HOOK_ID']
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
column :ID, 'Execution ID', :adjust => true do |d|
|
145
|
+
d['EXECUTION_ID']
|
146
|
+
end
|
147
|
+
|
148
|
+
column :TIMESTAMP, 'Timestamp', :size => 15 do |d|
|
149
|
+
OpenNebulaHelper.time_to_str(d['TIMESTAMP'], false, true, false)
|
150
|
+
end
|
151
|
+
|
152
|
+
column :RC, 'Return code', :adjust => true do |d|
|
153
|
+
d['EXECUTION_RESULT']['CODE']
|
154
|
+
end
|
155
|
+
|
156
|
+
column :EXECUTION, 'Return code', :adjust => true do |d|
|
157
|
+
rc = d['EXECUTION_RESULT']['CODE'].to_i
|
158
|
+
|
159
|
+
if rc.zero?
|
160
|
+
'SUCCESS'
|
161
|
+
else
|
162
|
+
'ERROR'
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
default :HOOK, :ID, :TIMESTAMP, :RC, :EXECUTION
|
167
|
+
end
|
168
|
+
|
169
|
+
table.show(execs, :stat_column => :EXECUTION)
|
170
|
+
end
|
171
|
+
|
172
|
+
def format_resource(hook, options = {})
|
173
|
+
str = '%-18s: %-20s'
|
174
|
+
str_h1 = '%-80s'
|
175
|
+
|
176
|
+
level_lock = OpenNebulaHelper.level_lock_to_str(hook['LOCK/LOCKED'])
|
177
|
+
|
178
|
+
CLIHelper.print_header(str_h1 % "HOOK #{hook['ID']} INFORMATION")
|
179
|
+
puts format str, 'ID', hook.id.to_s
|
180
|
+
puts format str, 'NAME', hook.name
|
181
|
+
puts format str, 'TYPE', hook['TYPE']
|
182
|
+
puts format str, 'LOCK', level_lock
|
183
|
+
puts
|
184
|
+
|
185
|
+
if options[:execution]
|
186
|
+
xp = "//HOOK_EXECUTION_RECORD[EXECUTION_ID=#{options[:execution]}]"
|
187
|
+
er = hook.retrieve_xmlelements(xp)
|
188
|
+
er = er[0] if er
|
189
|
+
|
190
|
+
if !er
|
191
|
+
puts "Cannot find execution record #{options[:execution]}"
|
192
|
+
return
|
193
|
+
end
|
194
|
+
|
195
|
+
er = er.to_hash['HOOK_EXECUTION_RECORD']
|
196
|
+
|
197
|
+
CLIHelper.print_header(str_h1 % 'HOOK EXECUTION RECORD')
|
198
|
+
|
199
|
+
arguments = ''
|
200
|
+
|
201
|
+
if er['ARGUMENTS'].is_a? String
|
202
|
+
er['ARGUMENTS'].split.each do |arg|
|
203
|
+
if CLIHelper.base64?(arg)
|
204
|
+
arguments += Base64.decode64(arg)
|
205
|
+
else
|
206
|
+
arguments += arg
|
207
|
+
end
|
208
|
+
|
209
|
+
arguments += ' '
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
timestamp = OpenNebulaHelper.time_to_str(er['TIMESTAMP'])
|
214
|
+
puts format str, 'EXECUTION ID', er['EXECUTION_ID']
|
215
|
+
puts format str, 'TIMESTAMP', timestamp
|
216
|
+
puts format str, 'COMMAND', er['EXECUTION_RESULT']['COMMAND']
|
217
|
+
puts format str, 'ARGUMENTS', arguments
|
218
|
+
puts format str, 'EXIT CODE', er['EXECUTION_RESULT']['CODE']
|
219
|
+
|
220
|
+
stdout = er['EXECUTION_RESULT']['STDOUT']
|
221
|
+
stderr = er['EXECUTION_RESULT']['STDERR']
|
222
|
+
|
223
|
+
puts
|
224
|
+
CLIHelper.print_header(str_h1 % 'EXECUTION STDOUT')
|
225
|
+
puts Base64.decode64(stdout.to_s) unless stdout.to_s.empty?
|
226
|
+
|
227
|
+
puts
|
228
|
+
CLIHelper.print_header(str_h1 % 'EXECUTION STDERR')
|
229
|
+
puts Base64.decode64(stderr.to_s) unless stderr.to_s.empty?
|
230
|
+
|
231
|
+
puts
|
232
|
+
return
|
233
|
+
end
|
234
|
+
|
235
|
+
CLIHelper.print_header(str_h1 % 'HOOK TEMPLATE', false)
|
236
|
+
puts hook.template_str
|
237
|
+
|
238
|
+
begin
|
239
|
+
exerc = [hook.to_hash['HOOK']['HOOKLOG']['HOOK_EXECUTION_RECORD']]
|
240
|
+
exerc = exerc.flatten.compact
|
241
|
+
rescue StandardError
|
242
|
+
exerc = nil
|
243
|
+
end
|
244
|
+
|
245
|
+
print_execution(exerc) if exerc && !exerc.empty?
|
246
|
+
|
247
|
+
puts
|
248
|
+
end
|
249
|
+
|
250
|
+
end
|