Class: SSM
- Inherits:
-
Object
- Object
- SSM
- Defined in:
- lib/sty/ssm.rb
Instance Method Summary collapse
- #all_ec2_instances ⇒ Object
- #all_ssm_details ⇒ Object
- #connect(args) ⇒ Object
- #ec2 ⇒ Object
- #extract_fields(inst) ⇒ Object
- #find(instances, names) ⇒ Object
- #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
Instance Method Details
#all_ec2_instances ⇒ Object
30 31 32 33 34 |
# File 'lib/sty/ssm.rb', line 30 def all_ec2_instances ec2.describe_instances.map do |page| page.reservations.map { |r| r.instances } end.flatten end |
#all_ssm_details ⇒ Object
36 37 38 39 40 |
# File 'lib/sty/ssm.rb', line 36 def all_ssm_details ssm.describe_instance_information.map do |page| page.instance_information_list end.flatten end |
#connect(args) ⇒ Object
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
# File 'lib/sty/ssm.rb', line 140 def connect(args) found = find(all_ec2_instances, args) if found.empty? puts "No instances found for search terms: #{args.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
22 23 24 |
# File 'lib/sty/ssm.rb', line 22 def ec2 @ec2 = @ec2 || Aws::EC2::Client.new(region: region) end |
#extract_fields(inst) ⇒ Object
61 62 63 |
# File 'lib/sty/ssm.rb', line 61 def extract_fields(inst) [instance_name(inst), instance_id(inst)] + instance_ips(inst) end |
#find(instances, names) ⇒ Object
99 100 101 102 103 104 105 |
# File 'lib/sty/ssm.rb', line 99 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
48 49 50 |
# File 'lib/sty/ssm.rb', line 48 def instance_id(instance) instance.instance_id end |
#instance_ips(instance) ⇒ Object
57 58 59 |
# File 'lib/sty/ssm.rb', line 57 def instance_ips(instance) instance.network_interfaces.map { |n| n.private_ip_address } end |
#instance_name(instance) ⇒ Object
52 53 54 55 |
# File 'lib/sty/ssm.rb', line 52 def instance_name(instance) name_tag = instance..select { |t| t.key == 'Name' }.first name_tag ? name_tag.value : "None" end |
#ping(instance) ⇒ Object
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/sty/ssm.rb', line 78 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
74 75 76 |
# File 'lib/sty/ssm.rb', line 74 def platform(instance) win?(instance) ? magenta("[Win] ") : "" end |
#prepare_regex(names) ⇒ Object
65 66 67 68 |
# File 'lib/sty/ssm.rb', line 65 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
107 108 109 110 111 112 |
# File 'lib/sty/ssm.rb', line 107 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
114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/sty/ssm.rb', line 114 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
18 19 20 |
# File 'lib/sty/ssm.rb', line 18 def region ENV['AWS_REGION'] || DEFAULT_REGION end |
#session_manager ⇒ Object
129 130 131 132 133 134 135 136 137 138 |
# File 'lib/sty/ssm.rb', line 129 def session_manager case when OS.mac? "#{dir}/bin/osx/session-manager-plugin" when OS.linux? "#{dir}/bin/linux/session-manager-plugin" else raise "The tool doesn't have binary for #{OS.host}" end end |
#ssm ⇒ Object
26 27 28 |
# File 'lib/sty/ssm.rb', line 26 def ssm @ssm = @ssm || Aws::SSM::Client.new(region: region) end |
#ssm_details ⇒ Object
42 43 44 45 46 |
# File 'lib/sty/ssm.rb', line 42 def ssm_details @ssm_details = @ssm_details || all_ssm_details.map do |i| [i.instance_id, i] end.to_h end |
#win?(instance) ⇒ Boolean
70 71 72 |
# File 'lib/sty/ssm.rb', line 70 def win?(instance) instance.platform =~ /windows/i end |