CloudyScripts 1.10.44 → 2.11.45
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.
- data/Rakefile +1 -1
- data/lib/help/script_execution_state.rb +2 -1
- data/lib/help/state_transition_helper.rb +4 -4
- data/lib/help/v_cloud_api_handler.rb +155 -0
- data/lib/help/v_cloud_transition_helper.rb +58 -0
- data/lib/scripts/ec2/ami2_ebs_conversion.rb +3 -0
- data/lib/scripts/ec2/audit_via_ssh.rb +20 -11
- data/lib/scripts/ec2/copy_ami.rb +3 -0
- data/lib/scripts/ec2/download_snapshot.rb +3 -0
- data/lib/scripts/ec2/ec2_script.rb +1 -1
- data/lib/scripts/vCloud/open_port_checker_vm.rb +82 -0
- data/lib/scripts/vCloud/v_cloud_script.rb +110 -0
- metadata +10 -6
data/Rakefile
CHANGED
@@ -12,7 +12,7 @@ require 'rake/testtask'
|
|
12
12
|
|
13
13
|
spec = Gem::Specification.new do |s|
|
14
14
|
s.name = 'CloudyScripts'
|
15
|
-
s.version = '
|
15
|
+
s.version = '2.11.45'
|
16
16
|
s.has_rdoc = true
|
17
17
|
s.extra_rdoc_files = ['README.rdoc', 'LICENSE']
|
18
18
|
s.summary = 'Scripts to facilitate programming for infrastructure clouds.'
|
@@ -1,11 +1,12 @@
|
|
1
1
|
require "help/state_transition_helper"
|
2
|
+
require "help/v_cloud_transition_helper"
|
2
3
|
|
3
4
|
# Implements a little state-machine.
|
4
5
|
# Usage: for every state you need, extend this class.
|
5
6
|
# The method enter() must be implemented for every state you code and
|
6
7
|
# return another state.
|
7
8
|
class ScriptExecutionState
|
8
|
-
include StateTransitionHelper
|
9
|
+
include StateTransitionHelper, VCloudTransitionHelper
|
9
10
|
|
10
11
|
# context information for the state (hash)
|
11
12
|
attr_reader :context, :logger
|
@@ -637,7 +637,7 @@ module StateTransitionHelper
|
|
637
637
|
# Get root filesytem type
|
638
638
|
def get_root_partition_fs_type()
|
639
639
|
post_message("Retrieving '/' root partition filesystem type...")
|
640
|
-
@logger.debug "get root partition
|
640
|
+
@logger.debug "get root partition filesystem type"
|
641
641
|
# get root device and then its fs type
|
642
642
|
root_fs_type = remote_handler().get_root_fs_type()
|
643
643
|
@logger.debug "Found '#{root_fs_type}' as root filesystem type"
|
@@ -652,7 +652,7 @@ module StateTransitionHelper
|
|
652
652
|
# Get root filesytem type and label
|
653
653
|
def get_root_partition_fs_type_and_label()
|
654
654
|
post_message("Retrieving '/' root partition filesystem type and label...")
|
655
|
-
@logger.debug "get root partition
|
655
|
+
@logger.debug "get root partition filesystem type"
|
656
656
|
# get root device and then its fs type
|
657
657
|
root_fs_type = remote_handler().get_root_fs_type()
|
658
658
|
@logger.debug "Found '#{root_fs_type}' as root filesystem type"
|
@@ -681,7 +681,7 @@ module StateTransitionHelper
|
|
681
681
|
# Get partition filesytem type
|
682
682
|
def get_partition_fs_type(part)
|
683
683
|
post_message("Retrieving '#{part}' partition filesystem type...")
|
684
|
-
@logger.debug "get #{part} partition
|
684
|
+
@logger.debug "get #{part} partition filesystem type"
|
685
685
|
# get partition device and then its fs type
|
686
686
|
part_fs_type = remote_handler().get_partition_fs_type(part)
|
687
687
|
@logger.debug "Found '#{part_fs_type}' as filesystem type"
|
@@ -696,7 +696,7 @@ module StateTransitionHelper
|
|
696
696
|
# Get partition filesytem type and label
|
697
697
|
def get_partition_fs_type_and_label(part)
|
698
698
|
post_message("Retrieving '#{part}' partition filesystem type...")
|
699
|
-
@logger.debug "get #{part} partition
|
699
|
+
@logger.debug "get #{part} partition filesystem type"
|
700
700
|
# get partition device and then its fs type
|
701
701
|
part_fs_type = remote_handler().get_partition_fs_type(part)
|
702
702
|
@logger.debug "Found '#{part_fs_type}' as filesystem type"
|
@@ -0,0 +1,155 @@
|
|
1
|
+
require "base64"
|
2
|
+
require "xmlsimple"
|
3
|
+
|
4
|
+
class VCloudApiHandler
|
5
|
+
def initialize(username, password, url_endpoint, logger = Logger.new(STDOUT))
|
6
|
+
@username = username
|
7
|
+
@password = password
|
8
|
+
@url_endpoint = url_endpoint
|
9
|
+
@logger = logger
|
10
|
+
end
|
11
|
+
|
12
|
+
def versions
|
13
|
+
res = Net::HTTP.get "#{@url_endpoint}", '/api/versions'
|
14
|
+
return XmlSimple.xml_in(res)
|
15
|
+
end
|
16
|
+
|
17
|
+
def login
|
18
|
+
url = URI.parse("https://services.vcloudexpress.terremark.com/api/v0.8a-ext1.6/login")
|
19
|
+
req = Net::HTTP::Post.new(url.path)
|
20
|
+
req.basic_auth("#{@username}", "#{@password}")
|
21
|
+
req.add_field('Content-Length','0')
|
22
|
+
req.add_field('Content-Type', 'application/vdn.vmware.vCloud.orgList+xml')
|
23
|
+
@logger.debug "--- Request-Header:"
|
24
|
+
req.each_header do |key, name|
|
25
|
+
@logger.debug "#{key}: #{name}"
|
26
|
+
end
|
27
|
+
res = http_request(url, req)
|
28
|
+
@vcloud_token = res.get_fields("Set-Cookie")
|
29
|
+
xmlbody = XmlSimple.xml_in(res.body)
|
30
|
+
@organization_link = xmlbody["Org"].first["href"]
|
31
|
+
return xmlbody
|
32
|
+
end
|
33
|
+
|
34
|
+
def org
|
35
|
+
res = generic_get_request(@organization_link)
|
36
|
+
xmlbody = XmlSimple.xml_in(res.body)
|
37
|
+
xmlbody["Link"].each() {|info|
|
38
|
+
@logger.info "org: found info on #{info.inspect}"
|
39
|
+
case info['type']
|
40
|
+
when "application/vnd.vmware.vcloud.vdc+xml"
|
41
|
+
@vdc_link = info['href']
|
42
|
+
when "application/vnd.vmware.vcloud.catalog+xml"
|
43
|
+
@catalog_link = info['href']
|
44
|
+
when "application/vnd.vmware.vcloud.tasksList+xml"
|
45
|
+
@taskslist_link = info['href']
|
46
|
+
when "application/vnd.tmrk.vcloudExpress.keysList+xml"
|
47
|
+
@keyslist_link = info['href']
|
48
|
+
else
|
49
|
+
@logger.info "could not identify #{info['type']} for org"
|
50
|
+
end
|
51
|
+
}
|
52
|
+
return xmlbody
|
53
|
+
end
|
54
|
+
|
55
|
+
def vdc
|
56
|
+
@server_links = []
|
57
|
+
@network_links = []
|
58
|
+
res = generic_get_request(@vdc_link)
|
59
|
+
xmlbody = XmlSimple.xml_in(res.body)
|
60
|
+
xmlbody['ResourceEntities'].first['ResourceEntity'].each() do |info|
|
61
|
+
@logger.info "vdc: found info on #{info.inspect}"
|
62
|
+
case info['type']
|
63
|
+
when "application/vnd.vmware.vcloud.vApp+xml"
|
64
|
+
@server_links << info['href']
|
65
|
+
else
|
66
|
+
@logger.info "could not identify #{info['type']} for vdc"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
@logger.debug "@server_links = #{@server_links.inspect}"
|
70
|
+
xmlbody['AvailableNetworks'].first['Network'].each() do |info|
|
71
|
+
@logger.debug "vdc: found info on #{info.inspect}"
|
72
|
+
case info['type']
|
73
|
+
when "application/vnd.vmware.vcloud.network+xml"
|
74
|
+
@network_links << info['href']
|
75
|
+
else
|
76
|
+
@logger.info "could not identify #{info['type']} for vdc"
|
77
|
+
end
|
78
|
+
end
|
79
|
+
@logger.debug "@network_links = #{@network_links.inspect}"
|
80
|
+
end
|
81
|
+
|
82
|
+
def v_apps
|
83
|
+
@server_links.each() {|server_link|
|
84
|
+
generic_get_request(server_link)
|
85
|
+
}
|
86
|
+
end
|
87
|
+
|
88
|
+
def networks
|
89
|
+
@network_links.each() {|network_link|
|
90
|
+
generic_get_request(network_link)
|
91
|
+
}
|
92
|
+
end
|
93
|
+
|
94
|
+
def internet_services
|
95
|
+
@internet_services_link = "#{@vdc_link}/internetServices"
|
96
|
+
@internet_services_link.gsub!("api/v0.8a-ext1.6","api/extensions/v1.6")
|
97
|
+
res = generic_get_request(@internet_services_link)
|
98
|
+
xmlbody = XmlSimple.xml_in(res.body)
|
99
|
+
return xmlbody
|
100
|
+
end
|
101
|
+
|
102
|
+
def server_ip_address(server_ip)
|
103
|
+
server_link = "https://services.vcloudexpress.terremark.com/api/v0.8a-ext1.6/vapp/#{server_ip}"
|
104
|
+
res = generic_get_request(server_link)
|
105
|
+
xmlbody = XmlSimple.xml_in(res.body)
|
106
|
+
ip_address = xmlbody["NetworkConnectionSection"].first["NetworkConnection"].first["IpAddress"]
|
107
|
+
@logger.debug "Ip: #{ip_address}"
|
108
|
+
#"NetworkConnectionSection"=>[{"NetworkConnection"=>[{"IpAddress"=>["10.114.117.11"],
|
109
|
+
ip_address
|
110
|
+
end
|
111
|
+
|
112
|
+
def firewall_rules
|
113
|
+
|
114
|
+
end
|
115
|
+
|
116
|
+
#private
|
117
|
+
|
118
|
+
def generic_get_request(full_url)
|
119
|
+
raise Exception.new("no url") if full_url == nil
|
120
|
+
@logger.debug "generic request: url = #{full_url.inspect}"
|
121
|
+
url = URI.parse(full_url)
|
122
|
+
req = Net::HTTP::Get.new(url.path)
|
123
|
+
prepare_request(req)
|
124
|
+
return http_request(url, req)
|
125
|
+
end
|
126
|
+
|
127
|
+
def prepare_request(request)
|
128
|
+
raise Exception.new("no vcloud-token") if @vcloud_token == nil
|
129
|
+
request.add_field('Content-Length','0')
|
130
|
+
request.add_field('Content-Type', 'application/vdn.vmware.vCloud.orgList+xml')
|
131
|
+
request.add_field('Cookie', @vcloud_token)
|
132
|
+
|
133
|
+
@logger.debug "--- Request-Header:"
|
134
|
+
request.each_header do |key, name|
|
135
|
+
@logger.debug "#{key}: #{name}"
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def http_request(url, request)
|
140
|
+
http_session = Net::HTTP.new(url.host, url.port)
|
141
|
+
http_session.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
142
|
+
http_session.use_ssl = true
|
143
|
+
res = http_session.start {|http|
|
144
|
+
http.request(request)
|
145
|
+
}
|
146
|
+
|
147
|
+
@logger.debug "--- Response-Header:"
|
148
|
+
res.each_header do |key, name|
|
149
|
+
@logger.debug "#{key}: #{name}"
|
150
|
+
end
|
151
|
+
xmlbody = XmlSimple.xml_in(res.body)
|
152
|
+
@logger.debug "response-body: #{xmlbody.inspect}"
|
153
|
+
return res
|
154
|
+
end
|
155
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'net/scp'
|
2
|
+
|
3
|
+
# Contains methods that are used by the scripts in the state-machines. Since
|
4
|
+
# they are reused by different scripts, they are factored into this module
|
5
|
+
module VCloudTransitionHelper
|
6
|
+
|
7
|
+
def retrieve_ip_services
|
8
|
+
@context[:vcloud_internet_services] = []
|
9
|
+
vcloud_api_handler.login
|
10
|
+
vcloud_api_handler.org
|
11
|
+
vcloud_api_handler.vdc
|
12
|
+
res = vcloud_api_handler.internet_services
|
13
|
+
puts "retrieved: #{res.inspect}"
|
14
|
+
res['InternetService'].each() {|is|
|
15
|
+
port = is['Port'].first.to_i
|
16
|
+
ip = is['PublicIpAddress'].first['Name'].first #TODO: several IPs may be defined here?
|
17
|
+
id = is['PublicIpAddress'].first['Id'].first
|
18
|
+
@context[:vcloud_internet_services] << {:port => port, :ip => ip, :id => id}
|
19
|
+
}
|
20
|
+
end
|
21
|
+
|
22
|
+
protected
|
23
|
+
|
24
|
+
#setting/retrieving handlers
|
25
|
+
|
26
|
+
def remote_handler()
|
27
|
+
if @remote_handler == nil
|
28
|
+
if @context[:remote_command_handler] == nil
|
29
|
+
@context[:remote_command_handler] = RemoteCommandHandler.new
|
30
|
+
else
|
31
|
+
@remote_handler = @context[:remote_command_handler]
|
32
|
+
end
|
33
|
+
end
|
34
|
+
@remote_handler
|
35
|
+
end
|
36
|
+
|
37
|
+
def remote_handler=(remote_handler)
|
38
|
+
@remote_handler = remote_handler
|
39
|
+
end
|
40
|
+
|
41
|
+
def vcloud_api_handler()
|
42
|
+
if @vcloud_api_handler == nil
|
43
|
+
@vcloud_api_handler = @context[:vcloud_api_handler]
|
44
|
+
end
|
45
|
+
@vcloud_api_handler
|
46
|
+
end
|
47
|
+
|
48
|
+
def vcloud_api_handler=(vcloud_api_handler)
|
49
|
+
@vcloud_api_handler = vcloud_api_handler
|
50
|
+
end
|
51
|
+
|
52
|
+
def post_message(msg)
|
53
|
+
if @context[:script] != nil
|
54
|
+
@context[:script].post_message(msg)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
@@ -34,6 +34,9 @@ class Ami2EbsConversion < Ec2Script
|
|
34
34
|
if @input_params[:security_group_name] == nil
|
35
35
|
@input_params[:security_group_name] = "default"
|
36
36
|
end
|
37
|
+
if @input_params[:ami_id] == nil && !(@input_params[:ami_id] =~ /^ami-.*$/)
|
38
|
+
raise Exception.new("Invalid AMI ID specified: #{@input_params[:ami_id]}")
|
39
|
+
end
|
37
40
|
ec2_helper = Ec2Helper.new(@input_params[:ec2_api_handler])
|
38
41
|
if !ec2_helper.check_open_port(@input_params[:security_group_name], 22)
|
39
42
|
raise Exception.new("Port 22 must be opened for security group #{@input_params[:security_group_name]} to connect via SSH")
|
@@ -4,7 +4,6 @@ require "help/remote_command_handler"
|
|
4
4
|
require "help/ec2_helper"
|
5
5
|
require "audit/lib/audit"
|
6
6
|
require "AWS"
|
7
|
-
require 'pp'
|
8
7
|
|
9
8
|
# Audit an AMI or an instance via an SSH connection using a specific benchmark
|
10
9
|
#
|
@@ -42,6 +41,7 @@ class AuditViaSsh < Ec2Script
|
|
42
41
|
else
|
43
42
|
raise Exception.new("Invalid Audit '#{@input_params[:audit_type]}' specified")
|
44
43
|
end
|
44
|
+
|
45
45
|
ec2_helper = Ec2Helper.new(@input_params[:ec2_api_handler])
|
46
46
|
if !ec2_helper.check_open_port(@input_params[:sec_grp_name], 22)
|
47
47
|
raise Exception.new("Port 22 must be opened for security group 'default' to connect via SSH")
|
@@ -81,13 +81,21 @@ class AuditViaSsh < Ec2Script
|
|
81
81
|
@context[:instance_id] = instance_infos[0]
|
82
82
|
@context[:public_dns_name] = instance_infos[1]
|
83
83
|
@context[:tmp_dir] = tmp_dir
|
84
|
-
#puts "DEBUG: Audit Scripts"
|
85
|
-
#pp @context
|
86
84
|
|
87
85
|
Dir::mkdir(tmp_dir)
|
88
86
|
if FileTest::directory?(tmp_dir)
|
89
87
|
post_message("local temporary directory created")
|
90
88
|
end
|
89
|
+
|
90
|
+
if @context[:audit] == nil
|
91
|
+
@context[:audit] = Audit.new(:benchmark => @context[:benchmark_file], :attachment_dir => @context[:tmp_dir],
|
92
|
+
:connection_type => :ssh,
|
93
|
+
:connection_params => {:user => @context[:ssh_user],
|
94
|
+
:keys => @context[:ssh_key_file],
|
95
|
+
:host => @context[:public_dns_name],
|
96
|
+
:paranoid => false},
|
97
|
+
:logger => nil)
|
98
|
+
end
|
91
99
|
|
92
100
|
LaunchAuditViaSsh.new(@context)
|
93
101
|
end
|
@@ -96,20 +104,21 @@ class AuditViaSsh < Ec2Script
|
|
96
104
|
# Launch the audit via SSH
|
97
105
|
class LaunchAuditViaSsh < AuditViaSshState
|
98
106
|
def enter
|
99
|
-
audit =
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
107
|
+
audit = @context[:audit]
|
108
|
+
#audit = Audit.new(:benchmark => @context[:benchmark_file], :attachment_dir => @context[:tmp_dir],
|
109
|
+
# :connection_type => :ssh,
|
110
|
+
# :connection_params => {:user => @context[:ssh_user],
|
111
|
+
# :keys => @context[:ssh_key_file],
|
112
|
+
# :host => @context[:public_dns_name],
|
113
|
+
# :paranoid => false},
|
105
114
|
#:timeout => 120,
|
106
115
|
#:verbose => :warn},
|
107
|
-
|
116
|
+
# :logger => nil)
|
108
117
|
audit.start(false)
|
109
118
|
@context[:result][:audit_test] = []
|
110
119
|
audit.results.each() {|key, value|
|
111
120
|
if key =~ /^SSH_.*$/ || key =~ /^APACHE2_.*$/
|
112
|
-
|
121
|
+
puts "DEBUG: Key: #{key}, Result: #{value.result}, Desc: #{value.rule.description}"
|
113
122
|
@context[:result][:audit_test] << {:name => key, :desc => value.rule.description, :status => value.result}
|
114
123
|
post_message("== > Test #{key}: Status: #{value.result.eql?("pass") ? "OK" : "NOK"}\n Desc: #{value.rule.description}")
|
115
124
|
end
|
data/lib/scripts/ec2/copy_ami.rb
CHANGED
@@ -38,6 +38,9 @@ class CopyAmi < Ec2Script
|
|
38
38
|
end
|
39
39
|
|
40
40
|
def check_input_parameters()
|
41
|
+
if @input_params[:ami_id] == nil && !(@input_params[:ami_id] =~ /^ami-.*$/)
|
42
|
+
raise Exception.new("Invalid AMI ID specified: #{@input_params[:ami_id]}")
|
43
|
+
end
|
41
44
|
ec2_helper = Ec2Helper.new(@input_params[:ec2_api_handler])
|
42
45
|
if ec2_helper.ami_prop(@input_params[:ami_id], 'rootDeviceType') != "ebs"
|
43
46
|
raise Exception.new("must be an EBS type image")
|
@@ -41,6 +41,9 @@ class DownloadSnapshot < Ec2Script
|
|
41
41
|
if !ec2_helper.check_open_port(@input_params[:security_group_name], 22)
|
42
42
|
raise Exception.new("Port 22 must be opened for security group #{@input_params[:security_group_name]} to connect via SSH")
|
43
43
|
end
|
44
|
+
if !ec2_helper.check_open_port(@input_params[:security_group_name], 80)
|
45
|
+
raise Exception.new("Port 80 must be opened for security group #{@input_params[:security_group_name]} to make the download link work")
|
46
|
+
end
|
44
47
|
if @input_params[:source_device] == nil
|
45
48
|
@input_params[:source_device] = "/dev/sdj1"
|
46
49
|
end
|
@@ -21,7 +21,7 @@ class Ec2Script
|
|
21
21
|
@input_params[:result] = @result
|
22
22
|
@input_params.each() do |param_key, param_value|
|
23
23
|
if [:logger, :ec2_api_handler, :target_ec2_handler, :remote_command_handler,
|
24
|
-
:source_ssh_keydata, :target_ssh_keydata
|
24
|
+
:source_ssh_keydata, :target_ssh_keydata, :ssh_keydata
|
25
25
|
].include?(param_key.to_s.to_sym)
|
26
26
|
@logger.debug("INPUT PARAM #{param_key} is set [but not logged]")
|
27
27
|
else
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require "help/script_execution_state"
|
2
|
+
require "help/remote_command_handler"
|
3
|
+
require "scripts/vcloud/v_cloud_script"
|
4
|
+
|
5
|
+
# Identifies all open internet services and checks if
|
6
|
+
# there are actually used by a service. Note: this script depends
|
7
|
+
# on a propriatary version of the vCloud API implemented by Terremark.
|
8
|
+
#
|
9
|
+
|
10
|
+
class OpenPortCheckerVm < VCloudScript
|
11
|
+
# Input parameters
|
12
|
+
# * vcloud_api_handler => object that allows to access the vCloud service
|
13
|
+
def initialize(input_params)
|
14
|
+
super(input_params)
|
15
|
+
end
|
16
|
+
|
17
|
+
def check_input_parameters()
|
18
|
+
if @input_params[:vcloud_api_handler] == nil
|
19
|
+
raise Exception.new("no vCloud handler specified")
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def load_initial_state()
|
24
|
+
OpenPortCheckerState.load_state(@input_params)
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
# Here begins the state machine implementation
|
30
|
+
class OpenPortCheckerState < ScriptExecutionState
|
31
|
+
def self.load_state(context)
|
32
|
+
state = context[:initial_state] == nil ? RetrievingInternetServices.new(context) : context[:initial_state]
|
33
|
+
state
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
# Nothing done yet. Retrieve all internet services.
|
39
|
+
class RetrievingInternetServices < OpenPortCheckerState
|
40
|
+
def enter
|
41
|
+
retrieve_ip_services()
|
42
|
+
CheckingInternetServices.new(@context)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Got all internet services. Go through them and check the ports.
|
47
|
+
class CheckingInternetServices < OpenPortCheckerState
|
48
|
+
def enter
|
49
|
+
@context[:result][:port_checks] = []
|
50
|
+
@context[:vcloud_internet_services].each() do |is|
|
51
|
+
port = is[:port]
|
52
|
+
ip = is[:ip]
|
53
|
+
identifier = is[:id]
|
54
|
+
begin
|
55
|
+
result = @context[:remote_command_handler].is_port_open?(ip, port)
|
56
|
+
post_message("check port #{port} on IP #{ip} => #{result ? "successful" : "failed"}")
|
57
|
+
rescue Exception => e
|
58
|
+
@logger.warn("exception during executing port check: #{e}")
|
59
|
+
end
|
60
|
+
@context[:result][:port_checks] << {:ip => ip, :id => identifier,
|
61
|
+
:port => port, :success => result
|
62
|
+
}
|
63
|
+
end
|
64
|
+
AnalysisDone.new(@context)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# Nothing done yet. Retrieve all security groups
|
69
|
+
class AnalysisDone < OpenPortCheckerState
|
70
|
+
def enter
|
71
|
+
Done.new(@context)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# Script done.
|
76
|
+
class Done < OpenPortCheckerState
|
77
|
+
def done?
|
78
|
+
true
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
# Base class for any script for vCloud.
|
2
|
+
class VCloudScript
|
3
|
+
# Initialization. Common Input parameters:
|
4
|
+
# * vcloud_api_handler => used to connect to the API (needs user/password/api-url)
|
5
|
+
# * logger => allows to pass a ruby logger object used for logging (optional, default is a stdout logger with level WARN)
|
6
|
+
# Scripts may add specific key/value pairs.
|
7
|
+
def initialize(input_params)
|
8
|
+
@input_params = input_params
|
9
|
+
@state_change_listeners = []
|
10
|
+
@progress_message_listeners = []
|
11
|
+
if input_params[:logger] == nil
|
12
|
+
@logger = Logger.new(STDOUT)
|
13
|
+
@logger.level = Logger::WARN
|
14
|
+
input_params[:logger] = @logger
|
15
|
+
else
|
16
|
+
@logger = input_params[:logger]
|
17
|
+
end
|
18
|
+
@result = {:done => false, :failed => false}
|
19
|
+
@input_params[:result] = @result
|
20
|
+
@input_params.each() do |param_key, param_value|
|
21
|
+
if [:logger, :vcloud_api_handler, :target_ec2_handler, :remote_command_handler,
|
22
|
+
:source_ssh_keydata, :target_ssh_keydata, :ssh_keydata
|
23
|
+
].include?(param_key.to_s.to_sym)
|
24
|
+
@logger.debug("INPUT PARAM #{param_key} is set [but not logged]")
|
25
|
+
else
|
26
|
+
@logger.debug("INPUT PARAM #{param_key} = #{param_value.inspect}")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def register_state_change_listener(listener)
|
32
|
+
@state_change_listeners << listener
|
33
|
+
end
|
34
|
+
|
35
|
+
def register_progress_message_listener(listener)
|
36
|
+
@progress_message_listeners << listener
|
37
|
+
end
|
38
|
+
|
39
|
+
# Check input parameters (in @input_parameters object variable)
|
40
|
+
# and set default values.
|
41
|
+
# Abstract method to be implemented by extending classes.
|
42
|
+
def check_input_parameters()
|
43
|
+
raise Exception.new("check_input_parameters must be implemented")
|
44
|
+
end
|
45
|
+
|
46
|
+
# Load the initial state for the script.
|
47
|
+
# Abstract method to be implemented by extending classes.
|
48
|
+
def load_initial_state()
|
49
|
+
raise Exception.new("load_initial_state must be implemented")
|
50
|
+
end
|
51
|
+
|
52
|
+
# Executes the script.
|
53
|
+
def start_script()
|
54
|
+
# optional parameters and initialization
|
55
|
+
check_input_parameters()
|
56
|
+
@input_params[:script] = self
|
57
|
+
begin
|
58
|
+
current_state = load_initial_state()
|
59
|
+
@state_change_listeners.each() {|listener|
|
60
|
+
current_state.register_state_change_listener(listener)
|
61
|
+
}
|
62
|
+
end_state = current_state.start_state_machine()
|
63
|
+
if end_state.failed?
|
64
|
+
@result[:failed] = true
|
65
|
+
@result[:failure_reason] = current_state.end_state.failure_reason
|
66
|
+
@result[:end_state] = current_state.end_state
|
67
|
+
else
|
68
|
+
@result[:failed] = false
|
69
|
+
end
|
70
|
+
rescue Exception => e
|
71
|
+
@logger.warn "exception during execution: #{e}"
|
72
|
+
@logger.warn e.backtrace.join("\n")
|
73
|
+
err = e.to_s
|
74
|
+
err += " (in #{current_state.end_state.to_s})" unless current_state == nil
|
75
|
+
@result[:failed] = true
|
76
|
+
@result[:failure_reason] = err
|
77
|
+
@result[:end_state] = current_state.end_state unless current_state == nil
|
78
|
+
ensure
|
79
|
+
begin
|
80
|
+
@input_params[:remote_command_handler].disconnect
|
81
|
+
rescue Exception => e2
|
82
|
+
end
|
83
|
+
end
|
84
|
+
#
|
85
|
+
@result[:done] = true
|
86
|
+
end
|
87
|
+
|
88
|
+
|
89
|
+
# Return a hash of results. Common values are:
|
90
|
+
# * :done => is true when the script has terminated, otherwise false
|
91
|
+
# * :failed => is false when the script succeeded
|
92
|
+
# * :failure_reason => returns a failure reason (string)
|
93
|
+
# * :end_state => returns the state, in which the script terminated (#Help::ScriptExecutionState)
|
94
|
+
# Scripts may add specific key/value pairs.
|
95
|
+
# *
|
96
|
+
# Returns a hash with the following information:
|
97
|
+
# :done => if execution is done
|
98
|
+
#
|
99
|
+
def get_execution_result
|
100
|
+
@result
|
101
|
+
end
|
102
|
+
|
103
|
+
def post_message(message, level = Logger::DEBUG)
|
104
|
+
@progress_message_listeners.each() {|listener|
|
105
|
+
listener.new_message(message, level)
|
106
|
+
}
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
110
|
+
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: CloudyScripts
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 121
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
|
-
-
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version:
|
7
|
+
- 2
|
8
|
+
- 11
|
9
|
+
- 45
|
10
|
+
version: 2.11.45
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Matthias Jung
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-09-
|
18
|
+
date: 2011-09-16 00:00:00 +02:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -257,6 +257,8 @@ files:
|
|
257
257
|
- lib/help/script_execution_state.rb
|
258
258
|
- lib/help/state_change_listener.rb
|
259
259
|
- lib/help/state_transition_helper.rb
|
260
|
+
- lib/help/v_cloud_api_handler.rb
|
261
|
+
- lib/help/v_cloud_transition_helper.rb
|
260
262
|
- lib/scripts/ec2/ami2_ebs_conversion.rb
|
261
263
|
- lib/scripts/ec2/audit_via_ssh.rb
|
262
264
|
- lib/scripts/ec2/copy_ami.rb
|
@@ -268,6 +270,8 @@ files:
|
|
268
270
|
- lib/scripts/ec2/open_port_checker.rb
|
269
271
|
- lib/scripts/ec2/port_range_detector.rb
|
270
272
|
- lib/scripts/ec2/snapshot_optimization.rb
|
273
|
+
- lib/scripts/vCloud/open_port_checker_vm.rb
|
274
|
+
- lib/scripts/vCloud/v_cloud_script.rb
|
271
275
|
has_rdoc: true
|
272
276
|
homepage: http://elastic-security.com
|
273
277
|
licenses: []
|