ecl 1.0.0

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.
@@ -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: