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: []
         |