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.
- checksums.yaml +7 -0
- data/.gitignore +11 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +20 -0
- data/Rakefile +1 -0
- data/bin/console +10 -0
- data/bin/setup +7 -0
- data/eclair.gemspec +29 -0
- data/exe/ecl +6 -0
- data/lib/eclair.rb +22 -0
- data/lib/eclair/cell.rb +101 -0
- data/lib/eclair/color.rb +19 -0
- data/lib/eclair/column.rb +52 -0
- data/lib/eclair/config.rb +68 -0
- data/lib/eclair/console.rb +56 -0
- data/lib/eclair/grid.rb +355 -0
- data/lib/eclair/group.rb +55 -0
- data/lib/eclair/helpers/aws_helper.rb +157 -0
- data/lib/eclair/helpers/benchmark_helper.rb +19 -0
- data/lib/eclair/helpers/common_helper.rb +24 -0
- data/lib/eclair/instance.rb +148 -0
- data/lib/eclair/less_viewer.rb +23 -0
- data/lib/eclair/matcher.rb +19 -0
- data/lib/eclair/version.rb +3 -0
- data/templates/eclrc.template +61 -0
- metadata +155 -0
@@ -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,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:
|