Class: Ssm
- Inherits:
-
Object
- Object
- Ssm
- Defined in:
- lib/sty/ssm.rb
Constant Summary collapse
- MINIMAL_AGENT_VERSION =
'2.3.612.0'- DEFAULT_REGION =
'ap-southeast-2'- SSM_PLUGIN =
"/usr/local/bin/session-manager-plugin"
Instance Method Summary collapse
- #all_ec2_instances ⇒ Object
- #all_ssm_details ⇒ Object
- #connect(search) ⇒ Object
- #ec2 ⇒ Object
- #extract_fields(inst) ⇒ Object
- #find(instances, names) ⇒ Object
-
#initialize ⇒ Ssm
constructor
A new instance of Ssm.
- #instance_id(instance) ⇒ Object
- #instance_ips(instance) ⇒ Object
- #instance_name(instance) ⇒ Object
- #ping(instance) ⇒ Object
- #platform(instance) ⇒ Object
- #prepare_regex(names) ⇒ Object
- #print_refine_instances(instances, type) ⇒ Object
- #refine(found) ⇒ Object
- #region ⇒ Object
- #session_manager ⇒ Object
- #ssm ⇒ Object
- #ssm_details ⇒ Object
- #win?(instance) ⇒ Boolean
Constructor Details
#initialize ⇒ Ssm
Returns a new instance of Ssm.
11 12 13 14 15 |
# File 'lib/sty/ssm.rb', line 11 def initialize require 'aws-sdk-ec2' require 'aws-sdk-ssm' Aws.config.update(:http_proxy => ENV['https_proxy']) end |
Instance Method Details
#all_ec2_instances ⇒ Object
29 30 31 32 33 |
# File 'lib/sty/ssm.rb', line 29 def all_ec2_instances ec2.describe_instances.map do |page| page.reservations.map { |r| r.instances } end.flatten end |
#all_ssm_details ⇒ Object
35 36 37 38 39 |
# File 'lib/sty/ssm.rb', line 35 def all_ssm_details ssm.describe_instance_information.map do |page| page.instance_information_list end.flatten end |
#connect(search) ⇒ Object
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 |
# File 'lib/sty/ssm.rb', line 138 def connect(search) found = find(all_ec2_instances, search) if found.empty? puts "No instances found for search terms: #{search.join(', ')}" exit 1 end target = refine(found) {|found| print_refine_instances(found, 'target')} begin resp = ssm.start_session(target: instance_id(target)) rescue Exception => e puts red("ERROR! Unable to start session") puts white(e.) exit 1 end mappings = {session_id: 'SessionId', token_value: 'TokenValue', stream_url: 'StreamUrl'} reqest_str = resp.to_h.map {|k, v| [mappings[k], v] }.to_h.to_json exec "#{session_manager} \'#{reqest_str}\' ap-southeast-2 StartSession" end |
#ec2 ⇒ Object
21 22 23 |
# File 'lib/sty/ssm.rb', line 21 def ec2 @ec2 = @ec2 || Aws::EC2::Client.new(region: region) end |
#extract_fields(inst) ⇒ Object
60 61 62 |
# File 'lib/sty/ssm.rb', line 60 def extract_fields(inst) [instance_name(inst), instance_id(inst)] + instance_ips(inst) end |
#find(instances, names) ⇒ Object
98 99 100 101 102 103 104 |
# File 'lib/sty/ssm.rb', line 98 def find(instances, names) re = prepare_regex(names) instances.select do |i| i.state.name == 'running' && extract_fields(i).any? { |f| re.all? { |r| f =~ r } } end.sort{|a,b| instance_name(a) <=> instance_name(b)} end |
#instance_id(instance) ⇒ Object
47 48 49 |
# File 'lib/sty/ssm.rb', line 47 def instance_id(instance) instance.instance_id end |
#instance_ips(instance) ⇒ Object
56 57 58 |
# File 'lib/sty/ssm.rb', line 56 def instance_ips(instance) instance.network_interfaces.map { |n| n.private_ip_address } end |
#instance_name(instance) ⇒ Object
51 52 53 54 |
# File 'lib/sty/ssm.rb', line 51 def instance_name(instance) name_tag = instance..select { |t| t.key == 'Name' }.first name_tag ? name_tag.value : "None" end |
#ping(instance) ⇒ Object
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/sty/ssm.rb', line 77 def ping(instance) #binding.pry status = ssm_details[instance_id(instance)]&.ping_status || 'Unavailable' version_str = ssm_details[instance_id(instance)]&.agent_version version = Gem::Version.new(version_str || '0') reference_version = Gem::Version.new(MINIMAL_AGENT_VERSION) old_version = version < reference_version result = "[#{status}#{old_version ? ', old agent' : ''}]" case when status == 'Online' && !old_version green(result) when status == 'Online' && old_version yellow(result) else red(result) end end |
#platform(instance) ⇒ Object
73 74 75 |
# File 'lib/sty/ssm.rb', line 73 def platform(instance) win?(instance) ? magenta("[Win] ") : "" end |
#prepare_regex(names) ⇒ Object
64 65 66 67 |
# File 'lib/sty/ssm.rb', line 64 def prepare_regex(names) names = ['.'] if names.empty? names.map { |n| Regexp.new(Regexp.quote(n), Regexp::IGNORECASE) } end |
#print_refine_instances(instances, type) ⇒ Object
106 107 108 109 110 111 |
# File 'lib/sty/ssm.rb', line 106 def print_refine_instances(instances, type) puts "Please refine #{type} instance:" instances.each_with_index do |inst, idx| puts "#{idx}: #{instance_id(inst)} #{ping(inst)} [#{instance_name(inst)}] #{platform(inst)}(#{instance_ips(inst).join(', ')}) " end end |
#refine(found) ⇒ Object
113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/sty/ssm.rb', line 113 def refine(found) if found.size > 1 refine = nil loop do yield(found) refine = Integer(STDIN.gets.chomp) rescue false break if refine && refine < found.size end target = found[refine] else target = found.first end target end |
#region ⇒ Object
17 18 19 |
# File 'lib/sty/ssm.rb', line 17 def region ENV['AWS_REGION'] || DEFAULT_REGION end |
#session_manager ⇒ Object
129 130 131 132 133 134 135 136 |
# File 'lib/sty/ssm.rb', line 129 def session_manager unless Pathname.new(SSM_PLUGIN).exist? puts red("SSM plugin is not found: #{SSM_PLUGIN}.") puts white("You must have SSM plugin to continue.\nSee: https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-working-with-install-plugin.html") exit 1 end SSM_PLUGIN end |
#ssm ⇒ Object
25 26 27 |
# File 'lib/sty/ssm.rb', line 25 def ssm @ssm = @ssm || Aws::SSM::Client.new(region: region) end |
#ssm_details ⇒ Object
41 42 43 44 45 |
# File 'lib/sty/ssm.rb', line 41 def ssm_details @ssm_details = @ssm_details || all_ssm_details.map do |i| [i.instance_id, i] end.to_h end |
#win?(instance) ⇒ Boolean
69 70 71 |
# File 'lib/sty/ssm.rb', line 69 def win?(instance) instance.platform =~ /windows/i end |