contexto 0.3.1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ce4c997a2e9820433e6dc16ac7c257ec27ec32ce
4
- data.tar.gz: aac1141f316a5d6406be6f2b423f90a49fb25b78
3
+ metadata.gz: c9d853b62cb8229724967564e62e2859f8beca0f
4
+ data.tar.gz: c432ccfaa18265460d64091e55c4cb35576c4306
5
5
  SHA512:
6
- metadata.gz: eab75f11605d88c06fd809861fd5b292a920c92c4c26fb2569b5f7136a8551dfb43c79f3c568d37e255c6726e61ef0f7ca1a3b8b1bec2e3671b6cd0db1e246f2
7
- data.tar.gz: 4fb2fe0b173734ad9cf4eebf319907a75556a7813c077be4b9627ce451abee0a438d37ee69d434c3aa96c0d0d13c395a16446a0833d6f47b880147f47d9d315d
6
+ metadata.gz: 04c68752563ed98910f38857298457ab690a5e09f6bab7797409226747b9bf874c949a284c3f24bde25b3ffc56cff875bce93fd364f2f3d8b2bab264af22aa55
7
+ data.tar.gz: a52c31323a4499e5869f37f19195c67d72335b11c1290a2d6d900e2926354725219014cd6bbb9f0c098be2abe8a8df872d964059fc72a00f2f2929e7a9130a8b
data/README.md CHANGED
@@ -12,111 +12,60 @@ $ gem install contexto
12
12
 
13
13
  ## Usage
14
14
 
15
- Run the binary to check on the status of a cluster or service.
16
-
17
- ### Cluster
18
-
19
- ```shell
20
- $ contexto -c sandbox
21
-
22
- ** Contexto Contextualizes **
23
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
24
-
25
- Cluster sandbox
26
-
27
- ┏━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┓
28
- ┃ Name ┃ Status ┃ Instances ┃ Services ┃ RunningTasks ┃ PendingTasks ┃
29
- ┣━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━┫
30
- ┃ sandbox ┃ ACTIVE ┃ 4 ┃ 3 ┃ 3 ┃ 0 ┃
31
- ┗━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━┛
32
- ```
33
-
34
- ### Service
15
+ Run the binary to connect to a container in a specific cluster and
16
+ service.
35
17
 
36
18
  ```shell
37
- $ contexto -c sandbox -s backend-app
19
+ $ contexto
38
20
 
39
- ** Contexto Contextualizes **
40
21
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
41
-
42
- Cluster sandbox
43
-
44
- ┏━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┓
45
- ┃ Name ┃ Status ┃ Instances ┃ Services ┃ RunningTasks ┃ PendingTasks ┃
46
- ┣━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━┫
47
- ┃ sandbox ┃ ACTIVE ┃ 4 ┃ 3 ┃ 3 ┃ 0 ┃
48
- ┗━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━┛
49
-
50
- Service backend-app
51
-
52
- ┏━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┓
53
- ┃ Name ┃ Status ┃ Desired ┃ Running ┃ Pending ┃
54
- ┣━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━┫
55
- ┃ backend-app ┃ ACTIVE ┃ 1 ┃ 1 ┃ 0 ┃
56
- ┗━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━┛
57
-
58
- Containers
59
-
60
- ┏━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┓
61
- ┃ Container ┃ Status ┃ IP ┃
62
- ┣━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━┫
63
- ┃ sidekiq ┃ RUNNING ┃ 10.2.1.218 ┃
64
- ┣━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━┫
65
- ┃ app ┃ RUNNING ┃ 10.2.1.218 ┃
66
- ┗━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━┛
67
- ```
68
-
69
- ### SSH
70
-
71
- You can also get Contexto to connect via SSH to a Bash shell, or a Rails console.
72
-
73
- #### Bash shell on container
74
-
75
- To connect to a Bash shell in a specific container, specify the cluster, service and container and the `--type` flag.
76
-
77
- ```shell
78
- $ contexto -c sandbox -s backend-app -v app -t=bash
79
-
80
22
  ** Contexto Contextualizes **
81
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
82
- circleci@4e65666c9414:/usr/src/app$
83
- ```
84
-
85
- #### Rails console
86
-
87
- To connect to a Rails console, specify the cluster, service and container and the `--type` flag.
88
-
89
- ```shell
90
- $ contexto -c sandbox -s backend-app -v app --type=console
91
23
 
92
- ** Contexto Contextualizes **
93
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
24
+ Clusters :
25
+ 1. production
26
+ 2. sandbox
27
+ 3. nah
28
+ Please choose a cluster? 1
29
+
30
+ Services :
31
+ 1. backend-app
32
+ 2. starter-site
33
+ 3. backend-authn
34
+ 4. logspout
35
+ 5. wombat
36
+ 6. nah
37
+ Please choose a service? 1
94
38
 
95
- I, [2017-03-28T22:36:35.555604 #181] INFO -- sentry: ** [Raven] Raven 2.4.0 ready to catch errors
96
- Loading sandbox environment (Rails 5.0.1)
97
- irb(main):001:0>
39
+ Containers
40
+ ┏━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
41
+ ┃ Container ┃ Status ┃ IP ┃
42
+ ┣━━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━━┫
43
+ ┃ sidekiq ┃ RUNNING ┃ 10.1.2.25 ┃
44
+ ┣━━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━━┫
45
+ ┃ app ┃ RUNNING ┃ 10.1.2.25 ┃
46
+ ┗━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━┛
47
+
48
+ Containers :
49
+ 1. sidekiq
50
+ 2. app
51
+ 3. nah
52
+ Please choose a container? 1
53
+
54
+ Do you want to connect to container sidekiq? :
55
+ 1. console
56
+ 2. bash
57
+ 3. ssh
58
+ 4. nah
59
+ Please choose a connection type?
98
60
  ```
99
61
 
100
- #### Shell on Docker host
101
-
102
- You can get an SSH shell on the Docker host too using the `--type` task.
103
-
104
- ```shell
105
- $ contexto -c sandbox -s backend-app -v sidekiq --t=ssh
106
-
107
- ** Contexto Contextualizes **
108
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
109
-
110
- Last login: Sat Apr 1 18:58:38 2017 from ip-172-31-12-234.ec2.internal
62
+ You can get Contexto to connect via SSH to a Bash shell, or a Rails console.
111
63
 
112
- __| __| __|
113
- _| ( \__ \ Amazon ECS-Optimized Amazon Linux AMI 2016.09.f
114
- ____|\___|____/
64
+ You can also specify a cluster and service to take a shortcut to a
65
+ specific set of containers.
115
66
 
116
- For documentation visit, http://aws.amazon.com/documentation/ecs
117
- 9 package(s) needed for security, out of 19 available
118
- Run "sudo yum update" to apply all updates.
119
- [ec2-user@ip-10-2-1-221 ~]$
67
+ ```bash
68
+ $ contexto -c production -s backend-app
120
69
  ```
121
70
 
122
71
  ## Development
data/bin/contexto CHANGED
@@ -11,14 +11,11 @@ require 'English'
11
11
  $stderr.sync = true
12
12
 
13
13
  options = {}
14
- options[:connection_type] = false
15
14
 
16
15
  optparse = OptionParser.new do |opts|
17
16
  opts.banner = 'Usage: contexto [options]'
18
17
  opts.on('-c', '--cluster CLUSTER', 'Cluster') { |v| options[:cluster] = v }
19
18
  opts.on('-s', '--service SERVICE', 'Service') { |v| options[:service] = v }
20
- opts.on('-v', '--container CONTAINER', 'Container') { |v| options[:container] = v }
21
- opts.on('-t', "--type [TYPE]", [:console, :ssh, :bash], "Select connection type (console, ssh, bash)") { |v| options[:connection_type] = v }
22
19
  opts.on_tail("-h", "--help", "Show this message") do
23
20
  puts opts
24
21
  exit
@@ -27,8 +24,8 @@ end
27
24
 
28
25
  begin
29
26
  optparse.parse!
30
- if options[:connection_type] && !options[:container]
31
- raise OptionParser::MissingArgument.new("If you want to connect to a container you need to specify a container name.")
27
+ if options[:service] && !options[:cluster]
28
+ raise OptionParser::MissingArgument.new("If you want to connect to a service you need to specify a cluster name.")
32
29
  puts "\n"
33
30
  end
34
31
  rescue OptionParser::InvalidOption, OptionParser::InvalidArgument, OptionParser::MissingArgument
@@ -5,123 +5,73 @@ require 'highline'
5
5
  module Contexto
6
6
  # ECS class
7
7
  class Contextualize
8
- attr_reader :display, :cluster, :service, :container, :connection_type
8
+ attr_reader :display, :cluster, :service
9
9
 
10
10
  def initialize(params = {})
11
11
  @cluster = params.fetch(:cluster) if params[:cluster]
12
12
  @service = params.fetch(:service) if params[:service]
13
- @container = params.fetch(:container) if params[:container]
14
- @connection_type = params.fetch(:connection_type) if params[:connection_type]
15
13
  @display = Contexto::Display.new
16
14
  end
17
15
 
18
16
  def run
19
- show
20
- if (connection_type && container)
21
- connect_to_endpoint
22
- elsif container
23
- prompt_endpoint
24
- end
25
- end
26
-
27
- def show
28
- if !cluster
29
- show_clusters
30
- return
31
- elsif cluster
32
- show_cluster
33
- puts "\n"
34
- end
35
- if !service
36
- show_services
37
- return
38
- elsif service
39
- puts "\n"
40
- show_service
41
- end
42
- if !container
43
- show_tasks
44
- return
45
- elsif container
46
- puts "\n"
47
- show_tasks
17
+ if (cluster || service)
18
+ if (cluster && !service)
19
+ select_services(cluster)
20
+ elsif (cluster && service)
21
+ select_tasks(cluster, service)
22
+ end
23
+ else
24
+ select_clusters
48
25
  end
49
26
  end
50
27
 
51
- def connect
52
- task = describe_tasks
53
- ec2_instance_id = describe_container_instance(task[:container_instance_arn])
54
- Contexto::SSH.new(describe_instances(ec2_instance_id), cluster, service, container)
55
- end
56
-
57
- def connect_to_endpoint
58
- connnect.connection_type.to_sym
59
- return
28
+ def select_clusters
29
+ clusters = list_clusters
30
+ cli.choose do |menu|
31
+ puts "\n"
32
+ menu.header = "Clusters "
33
+ menu.prompt = "Please choose a cluster? "
34
+ clusters.each do |cluster|
35
+ c = esplit(cluster)
36
+ menu.choice(c) { select_services(c) }
37
+ end
38
+ menu.choice(:nah) { return }
39
+ end
60
40
  end
61
41
 
62
- def prompt_endpoint
63
- cli = HighLine.new
42
+ def select_services(cluster)
43
+ services = list_services(cluster)
64
44
  cli.choose do |menu|
65
45
  puts "\n"
66
- menu.header = "Do you want to connect to container #{container}'s? "
67
- menu.prompt = "Please choose a connection type? "
68
- menu.choice(:console) { connect.console }
69
- menu.choice(:bash) { connect.bash }
70
- menu.choice(:ssh) { connect.ssh }
46
+ menu.header = "Services "
47
+ menu.prompt = "Please choose a service? "
48
+ services.each do |service|
49
+ s = esplit(service)
50
+ menu.choice(s) { select_tasks(cluster, s) }
51
+ end
71
52
  menu.choice(:nah) { return }
72
53
  end
73
54
  end
74
55
 
75
- def show_clusters
76
- title = "Clusters"
77
- headings = %w(Name)
78
- clusters = list_clusters
79
- rows = []
80
- clusters.each do |cluster|
81
- rows << [cluster.split('/')[-1]]
82
- end
83
- @display.create_display(title, headings, rows)
84
- end
85
-
86
- def show_cluster
87
- title = "Cluster #{cluster}"
88
- headings = %w(Name Status Instances Services RunningTasks PendingTasks)
89
- cluster = describe_clusters
90
- rows = []
91
- rows << [cluster[:cluster_name], cluster[:status], cluster[:registered_container_instances_count], cluster[:active_services_count], cluster[:running_tasks_count], cluster[:pending_tasks_count]]
92
- @display.create_display(title, headings, rows)
93
- end
94
-
95
- def show_services
96
- title = "Services"
97
- headings = %w(Name)
98
- services = list_services
99
- rows = []
100
- services.each do |service|
101
- rows << [service.split('/')[-1]]
56
+ def select_tasks(cluster, service)
57
+ show_tasks(cluster, service)
58
+ task = describe_tasks(cluster, service)
59
+ containers = task[:containers]
60
+ cli.choose do |menu|
61
+ puts "\n"
62
+ menu.header = "Containers "
63
+ menu.prompt = "Please choose a container? "
64
+ containers.each do |container|
65
+ menu.choice(container[:name]) { prompt_endpoint(cluster, service, container[:name]) }
66
+ end
67
+ menu.choice(:nah) { return }
102
68
  end
103
- @display.create_display(title, headings, rows)
104
- end
105
-
106
- def show_service
107
- title = "Service #{service}"
108
- headings = %w(Name Status Desired Running Pending)
109
- service = describe_services
110
- rows = []
111
- rows << [service[:service_name], service[:status], service[:desired_count], service[:running_count], service[:pending_count]]
112
- @display.create_display(title, headings, rows)
113
- rescue Aws::ECS::Errors::ServiceNotFoundException
114
- puts 'Service not found'
115
69
  end
116
70
 
117
- def show_tasks
118
- task = describe_tasks
119
- if container
120
- containers = task[:containers].select { |c| c[:name] == container }
121
- else
122
- containers = task[:containers]
123
- end
124
- ec2_instance_id = describe_container_instance(task[:container_instance_arn])
71
+ def show_tasks(cluster, service)
72
+ task = describe_tasks(cluster, service)
73
+ containers = task[:containers]
74
+ ec2_instance_id = describe_container_instance(cluster, task[:container_instance_arn])
125
75
  title = 'Containers'
126
76
  headings = %w(Container Status IP)
127
77
  rows = []
@@ -131,6 +81,24 @@ module Contexto
131
81
  @display.create_display(title, headings, rows)
132
82
  end
133
83
 
84
+ def prompt_endpoint(cluster, service, container)
85
+ cli.choose do |menu|
86
+ puts "\n"
87
+ menu.header = "Do you want to connect to container #{container}? "
88
+ menu.prompt = "Please choose a connection type? "
89
+ menu.choice(:console) { connect(cluster, service, container).console }
90
+ menu.choice(:bash) { connect(cluster, service, container).bash }
91
+ menu.choice(:ssh) { connect(cluster, service, container).ssh }
92
+ menu.choice(:nah) { return }
93
+ end
94
+ end
95
+
96
+ def connect(cluster, service, container)
97
+ task = describe_tasks(cluster, service)
98
+ ec2_instance_id = describe_container_instance(cluster, task[:container_instance_arn])
99
+ Contexto::SSH.new(describe_instances(ec2_instance_id), cluster, service, container)
100
+ end
101
+
134
102
  def list_clusters
135
103
  resp = ecs_client.list_clusters
136
104
  resp.cluster_arns
@@ -145,7 +113,7 @@ module Contexto
145
113
  resp.clusters[0].to_h
146
114
  end
147
115
 
148
- def list_services
116
+ def list_services(cluster)
149
117
  resp = ecs_client.list_services(
150
118
  cluster: cluster
151
119
  )
@@ -162,15 +130,15 @@ module Contexto
162
130
  resp.services[0].to_h
163
131
  end
164
132
 
165
- def describe_tasks
133
+ def describe_tasks(cluster, service)
166
134
  resp = ecs_client.describe_tasks(
167
135
  cluster: cluster,
168
- tasks: [task_arn]
136
+ tasks: [task_arn(cluster, service)]
169
137
  )
170
138
  resp.tasks[0].to_h
171
139
  end
172
140
 
173
- def task_arn
141
+ def task_arn(cluster, service)
174
142
  resp = ecs_client.list_tasks(
175
143
  cluster: cluster,
176
144
  service_name: service
@@ -178,7 +146,7 @@ module Contexto
178
146
  resp.task_arns[0]
179
147
  end
180
148
 
181
- def describe_container_instance(container_instance_arn)
149
+ def describe_container_instance(cluster, container_instance_arn)
182
150
  resp = ecs_client.describe_container_instances(
183
151
  cluster: cluster,
184
152
  container_instances: [
@@ -195,6 +163,14 @@ module Contexto
195
163
  resp.reservations[0].instances[0].private_ip_address
196
164
  end
197
165
 
166
+ def esplit(name)
167
+ name.split('/')[-1]
168
+ end
169
+
170
+ def cli
171
+ HighLine.new
172
+ end
173
+
198
174
  def region_name
199
175
  ENV['AWS_REGION'] || 'us-east-1'
200
176
  end
@@ -1,4 +1,4 @@
1
1
  # Contexto version
2
2
  module Contexto
3
- VERSION = '0.3.1'.freeze
3
+ VERSION = '0.4.0'.freeze
4
4
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: contexto
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Turnbull