ecl 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,19 @@
1
+ require "benchmark"
2
+
3
+ module Eclair
4
+ module BenchmarkHelper
5
+ def benchmark(name, &blk)
6
+ result = nil
7
+ if ENV['BM']
8
+ bm = Benchmark.measure do
9
+ result = blk.call
10
+ end
11
+ STDERR.puts "Elasped Time for #{name}:"
12
+ STDERR.puts bm
13
+ result
14
+ else
15
+ blk.call
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,24 @@
1
+ module Eclair
2
+ module CommonHelper
3
+ include Curses
4
+
5
+ def self.included(base)
6
+ base.extend(ClassMethods)
7
+ end
8
+
9
+ module ClassMethods
10
+ def array_accessor name
11
+ methods = [:[], :each, :count, :index, :each_with_index, :all?, :find, :empty?]
12
+ methods.each do |method_name|
13
+ define_method method_name do |*args, &blk|
14
+ self.send(name).send(method_name, *args, &blk)
15
+ end
16
+ end
17
+ end
18
+ end
19
+
20
+ def config
21
+ Eclair.config
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,148 @@
1
+ module Eclair
2
+ class Instance < Cell
3
+ def initialize instance_id, column = nil
4
+ super
5
+ @instance_id = instance_id
6
+ @column = column
7
+ end
8
+
9
+ def x
10
+ column.x
11
+ end
12
+
13
+ def y
14
+ column.index(self)
15
+ end
16
+
17
+ def name
18
+ begin
19
+ nametag = object.tags.find{|t| t.key == "Name"}
20
+ nametag ? nametag.value : "noname"
21
+ rescue
22
+ "terminated"
23
+ end
24
+ end
25
+
26
+ def color
27
+ if [48, 80].include?(state[:code])
28
+ super(*config.disabled_color)
29
+ else
30
+ super(*config.instance_color)
31
+ end
32
+ end
33
+
34
+ def format
35
+ " - #{name} [#{launched_at}] #{select_indicator}"
36
+ end
37
+
38
+ def hostname
39
+ object.send(config.ssh_hostname)
40
+ end
41
+
42
+ def image **options
43
+ Aws.images(**options).find{|i| i.image_id == object.image_id}
44
+ end
45
+
46
+ def security_groups **options
47
+ if Aws.security_groups?
48
+ object.security_groups.map{|instance_sg|
49
+ Aws.security_groups(**options).find{|sg| sg.group_id == instance_sg.group_id }
50
+ }.compact
51
+ else
52
+ nil
53
+ end
54
+ end
55
+
56
+ def routes
57
+ if Aws.dns_records?
58
+ Aws.dns_records.select do |record|
59
+ values = record.resource_records.map(&:value)
60
+ !values.grep(private_dns_name).empty? ||
61
+ !values.grep(public_dns_name).empty? ||
62
+ !values.grep(private_ip_address).empty? ||
63
+ !values.grep(public_ip_address).empty?
64
+ end
65
+ else
66
+ nil
67
+ end
68
+ end
69
+
70
+ def username
71
+ config.ssh_username.call(image(force: true))
72
+ end
73
+
74
+ def ssh_cmd
75
+ cmd = config.ssh_ports.map{ |port|
76
+ "ssh #{config.ssh_options} -p#{port} #{username}@#{hostname}"
77
+ }.join(" || ")
78
+
79
+ "echo Attaching to #{name}: #{username}@#{hostname} && (#{cmd})"
80
+ end
81
+
82
+ def connectable?
83
+ hostname && ![48, 80].include?(state[:code])
84
+ end
85
+
86
+ def running?
87
+ hostname && state[:code] == 16
88
+ end
89
+
90
+ def launched_at
91
+ diff = Time.now - launch_time
92
+ {
93
+ "year" => 31557600,
94
+ "month" => 2592000,
95
+ "day" => 86400,
96
+ "hour" => 3600,
97
+ "minute" => 60,
98
+ "second" => 1
99
+ }.each do |unit,v|
100
+ if diff >= v
101
+ value = (diff/v).to_i
102
+ return "#{value} #{unit}#{value > 1 ? "s" : ""}"
103
+ end
104
+ end
105
+ "now"
106
+ end
107
+
108
+ def digest_tags
109
+ tags.map{|t| "#{t[:key]}: #{t[:value]}"}.join("/")
110
+ end
111
+
112
+ def digest_routes
113
+ if Aws.dns_records?
114
+ routes.map(&:name).join(" ")
115
+ else
116
+ "Fetching DNS records from Route53..."
117
+ end
118
+ end
119
+
120
+ def header
121
+ ["#{name} (#{instance_id}) [#{state[:name]}] #{hostname}",
122
+ "launched at #{launch_time.to_time}",
123
+ "#{digest_routes}"]
124
+ end
125
+
126
+ def info
127
+ to_merge = {}
128
+
129
+ if routes
130
+ to_merge[:routes] = routes.map(&:to_h)
131
+ else
132
+ to_merge[:routes] = "Fetching DNS records from Route53..."
133
+ end
134
+
135
+ if image
136
+ to_merge[:image] = image.to_h
137
+ else
138
+ to_merge[:image] = "Fetching Image data from EC2..."
139
+ end
140
+
141
+ object.to_h.merge(to_merge)
142
+ end
143
+
144
+ def object
145
+ Aws.instance_map[@instance_id]
146
+ end
147
+ end
148
+ end
@@ -0,0 +1,23 @@
1
+ module Eclair
2
+ module LessViewer
3
+ extend self
4
+ class ColorPP < ::PP
5
+ def self.pp(obj, out = $>, width = 79)
6
+ q = ColorPP.new(out, width)
7
+ q.guard_inspect_key { q.pp obj }
8
+ q.flush
9
+ out << "\n"
10
+ end
11
+
12
+ def text(str, width = str.length)
13
+ super(CodeRay.scan(str, :ruby).term, width)
14
+ end
15
+ end
16
+
17
+ def show obj
18
+ IO.popen("less -R -C", "w") do |f|
19
+ ColorPP.pp(obj, f)
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,19 @@
1
+ module Eclair
2
+ class Matcher
3
+ def initialize query
4
+ @regex = Regexp.new(query.each_char.map{|c| "(#{c}".join(".*?"))
5
+ end
6
+
7
+ def match str
8
+ str.match @regex
9
+ end
10
+
11
+ def find
12
+ end
13
+
14
+ def score a, b
15
+ end
16
+
17
+ end
18
+ end
19
+
@@ -0,0 +1,3 @@
1
+ module Eclair
2
+ VERSION = "1.0.0"
3
+ end
@@ -0,0 +1,61 @@
1
+ Eclair.configure do |config|
2
+ # aws_region - region to connect aws.
3
+ # This overrides AWS_REGION environment variable, so you can comment out this line if you set this in environment variable.
4
+ config.aws_region = "ap-northeast-1"
5
+
6
+ # columns - Number of columns in eclair.
7
+ config.columns = 4
8
+
9
+ # ssh_username - Function to find username from image
10
+ # You can access response data extracted from EC2::Client#describe_images API call
11
+ # https://docs.aws.amazon.com/AWSRubySDK/latest/AWS/EC2/Client.html#describe_images-instance_method
12
+ config.ssh_username = lambda do |image|
13
+ case image.name
14
+ when /ubuntu/
15
+ "ubuntu"
16
+ else
17
+ "ec2-user"
18
+ end
19
+ end
20
+
21
+ # group_by - Function to determine group from instance
22
+ # Make a function that returns group name from instance data
23
+ # You can access response data extracted from EC2::Client#describe_images API call
24
+ # https://docs.aws.amazon.com/AWSRubySDK/latest/AWS/EC2/Client.html#describe_images-instance_method
25
+
26
+ # If you want to group instances by security group, uncomment example below. (default option)
27
+ # config.group_by = lambda do |instance|
28
+ # if instance.security_groups.first
29
+ # instance.security_groups.first.group_name
30
+ # else
31
+ # "no_group"
32
+ # end
33
+ # end
34
+
35
+ # If you want to group instances by name, uncomment and edit example below.
36
+ # config.group_by = lambda do |instance|
37
+ # nametag = instance.tags.find{|t| t.key == "Name"}
38
+ # return "Noname" unless nametag
39
+ # case nametag.value
40
+ # when /^production/
41
+ # "production servers"
42
+ # when /^test/
43
+ # "test servers"
44
+ # end
45
+ # end
46
+
47
+ # If you do not want to group instances, uncomment below line.
48
+ # config.group_by = nil
49
+
50
+ # ssh_ports - Port numbers to try ssh.
51
+ # Eclair will try to ssh specified ports in order with ConnectTimeout below.
52
+ config.ssh_ports = [22]
53
+
54
+ # ssh_options - Options passed to ssh.
55
+ # ConnectTimeout should exist when you want to connect to multiple ports.
56
+ config.ssh_options = "-o ConnectTimeout=1 -o StrictHostKeyChecking=no"
57
+
58
+ # ssh_hostname - Hostname to use for ssh.
59
+ # You can choose from :public_dns_name, :public_ip_address, :private_dns_name, :private_ip_address
60
+ config.ssh_hostname = :public_ip_address
61
+ end
metadata ADDED
@@ -0,0 +1,155 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ecl
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Devsisters
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2015-08-14 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.10'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.10'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: aws-sdk
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '='
46
+ - !ruby/object:Gem::Version
47
+ version: 2.1.8
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '='
53
+ - !ruby/object:Gem::Version
54
+ version: 2.1.8
55
+ - !ruby/object:Gem::Dependency
56
+ name: curses
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: pry
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '0.10'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '0.10'
83
+ - !ruby/object:Gem::Dependency
84
+ name: ruby-string-match-scorer
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '0.1'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '0.1'
97
+ description: Simple ssh helper for Amazon EC2
98
+ email:
99
+ - se@devsisters.com
100
+ executables:
101
+ - ecl
102
+ extensions: []
103
+ extra_rdoc_files: []
104
+ files:
105
+ - ".gitignore"
106
+ - Gemfile
107
+ - LICENSE.txt
108
+ - README.md
109
+ - Rakefile
110
+ - bin/console
111
+ - bin/setup
112
+ - eclair.gemspec
113
+ - exe/ecl
114
+ - lib/eclair.rb
115
+ - lib/eclair/cell.rb
116
+ - lib/eclair/color.rb
117
+ - lib/eclair/column.rb
118
+ - lib/eclair/config.rb
119
+ - lib/eclair/console.rb
120
+ - lib/eclair/grid.rb
121
+ - lib/eclair/group.rb
122
+ - lib/eclair/helpers/aws_helper.rb
123
+ - lib/eclair/helpers/benchmark_helper.rb
124
+ - lib/eclair/helpers/common_helper.rb
125
+ - lib/eclair/instance.rb
126
+ - lib/eclair/less_viewer.rb
127
+ - lib/eclair/matcher.rb
128
+ - lib/eclair/version.rb
129
+ - templates/eclrc.template
130
+ homepage: https://github.com/devsisters/eclair
131
+ licenses:
132
+ - MIT
133
+ metadata: {}
134
+ post_install_message:
135
+ rdoc_options: []
136
+ require_paths:
137
+ - lib
138
+ required_ruby_version: !ruby/object:Gem::Requirement
139
+ requirements:
140
+ - - ">="
141
+ - !ruby/object:Gem::Version
142
+ version: '0'
143
+ required_rubygems_version: !ruby/object:Gem::Requirement
144
+ requirements:
145
+ - - ">="
146
+ - !ruby/object:Gem::Version
147
+ version: '0'
148
+ requirements: []
149
+ rubyforge_project:
150
+ rubygems_version: 2.4.8
151
+ signing_key:
152
+ specification_version: 4
153
+ summary: EC2 ssh helper
154
+ test_files: []
155
+ has_rdoc: