smdev 0.3.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/lib/smdev/ecs_exec.rb +92 -0
  3. data/lib/smdev.rb +158 -121
  4. metadata +7 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3cb7ef8e326aefb0cec817caef086d1079b26404c1cc6d04ebc91c8db5ccf7b5
4
- data.tar.gz: 12b8cc2b5899723602ae6347c31f5cffb9ecf6026ebc39f595d7bc670abe0346
3
+ metadata.gz: 61964b5c32328c5e2265a32622cb85c366a70780eeaab4b95e154577942602b9
4
+ data.tar.gz: 39c56ddd43405021c465494bf439e174681e431146e59a808937f0c6592a2f97
5
5
  SHA512:
6
- metadata.gz: b8e0db249fa4c0f91eee94c4ba0408ee6ea7517a58d6c0b8e91b12f700786ee0a8e504b0fe05bf25b4ba76f7a03b4f5297d755648ae429ee071cc73c221967b7
7
- data.tar.gz: 0d31f663ac690004e11f3a3a05c45f995dc4f7c9cf51e5f193b08e73398dddfc36f5718c4602f3a053ed320a0c4892a82bae2be1a0434edc4e43c7cd68c4b105
6
+ metadata.gz: 54d844cb8292bea2cf364c473809f385bba2375d4bedede0927192c620e33bc685289831b1f7973a17a19d7b8471acfda9cf46de845367b7f2d2ab15ee3994e5
7
+ data.tar.gz: 123be6e3958715b82e1c0ae92c25e9a63f580ad0cbf55f43a2369ee1dbea782fe6d3b7dbb71e551ce4b66ef767ec817097ea0a8d6cd39ade8d3818c14482d13d
@@ -0,0 +1,92 @@
1
+ require 'open3'
2
+
3
+ module Smdev
4
+ module EcsExec
5
+ def self.ssh(options)
6
+ cluster_name = self.cluster_name(options)
7
+ return if cluster_name == nil
8
+ puts "Found cluster #{cluster_name}"
9
+
10
+ service_name = self.service_name(options, cluster_name)
11
+ return if service_name == nil
12
+ puts "Found service #{service_name}"
13
+
14
+ task_arn = self.task_arn(cluster_name, service_name)
15
+ puts "Found first task #{task_arn}"
16
+ command = options[:command]
17
+
18
+ execute_command_cmd = %W[
19
+ aws ecs execute-command
20
+ --cluster #{cluster_name}
21
+ --task #{task_arn}
22
+ --interactive
23
+ --command \"#{command}\"
24
+ ].join(' ')
25
+
26
+ puts "Running \"#{command}\""
27
+ exec(execute_command_cmd)
28
+ end
29
+
30
+ def self.cluster_name(options)
31
+ cluster = options[:cluster]
32
+ command = "aws ecs list-clusters | grep #{cluster}"
33
+ stdout, stderr, status = Open3.capture3(command)
34
+
35
+ if status.success?
36
+ match = stdout.match(/cluster\/([^"]+)/)
37
+ cluster_name = match[1] if match
38
+
39
+ return cluster_name
40
+ else
41
+ if stderr != ""
42
+ puts "Error executing command: #{stderr}"
43
+ else
44
+ puts "Could not find cluster whose name contains \"#{cluster}\""
45
+ end
46
+ end
47
+ end
48
+
49
+ def self.service_name(options, cluster_name)
50
+ service = options[:service]
51
+ command = "aws ecs list-services --cluster #{cluster_name} | grep #{service}"
52
+ stdout, stderr, status = Open3.capture3(command)
53
+
54
+ if status.success?
55
+ match = stdout.match(/#{cluster_name}\/([^"]+)/)
56
+ service_name = match[1] if match
57
+
58
+ return service_name
59
+ else
60
+ if stderr != ""
61
+ puts "Error executing command: #{stderr}"
62
+ else
63
+ puts "Could not find service whose name contains \"#{service}\""
64
+ end
65
+ end
66
+ end
67
+
68
+ def self.task_arn(cluster_name, service_name)
69
+ list_tasks_cmd = "aws ecs list-tasks --cluster #{cluster_name} --service-name #{service_name}"
70
+ stdout, stderr, status = Open3.capture3(list_tasks_cmd)
71
+
72
+ if status.success?
73
+ begin
74
+ tasks = JSON.parse(stdout)
75
+ task_arn = tasks['taskArns'][0]
76
+
77
+ if task_arn.nil? || task_arn.empty?
78
+ puts 'No task ARN found.'
79
+ exit 1
80
+ end
81
+ return task_arn
82
+ rescue JSON::ParserError
83
+ puts 'Error parsing JSON'
84
+ exit 1
85
+ end
86
+ else
87
+ puts "Error executing command: #{stderr}"
88
+ exit 1
89
+ end
90
+ end
91
+ end
92
+ end
data/lib/smdev.rb CHANGED
@@ -2,6 +2,7 @@
2
2
  require 'io/console'
3
3
  require 'octokit'
4
4
  require 'optparse'
5
+ require 'smdev/ecs_exec'
5
6
 
6
7
  module Smdev
7
8
  class CLI
@@ -9,7 +10,10 @@ module Smdev
9
10
  options = {}
10
11
  commands = ["local_app_setup : Install local requirements for application. (Rails Only Currently)\n",
11
12
  "system_install : Install Homebrew, Ruby, PostgreSQL, and Ruby on Rails\n",
12
- "checkout_repos : Checkout all repositories for StrongMind\n"]
13
+ "checkout_repos : Checkout all repositories for StrongMind\n",
14
+ "console : Open a rails console on ECS\n",
15
+ "ssh : Open a bash shell on ECS\n"
16
+ ]
13
17
 
14
18
  OptionParser.new do |opts|
15
19
  opts.banner = "Usage: smdev.rb [options] <command>"
@@ -22,133 +26,26 @@ module Smdev
22
26
  options[:https] = true
23
27
  end
24
28
 
25
- opts.on("-h", "--help", "Prints this help message") do
26
- puts opts
27
- puts "\nCommands:"
28
- commands.each { |cmd| puts " #{cmd}" }
29
- exit
29
+ opts.on("-r", "--cluster CLUSTER", "Lookup this cluster for the ECS execute (defaults to the name of your current folder)") do |cluster|
30
+ options[:cluster] = cluster
30
31
  end
31
32
 
32
- end.parse!
33
-
34
- def system_install
35
- puts "Installing Homebrew..."
36
- system({ 'SHELL' => '/bin/bash' }, '/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"')
37
- # system('/bin/bash', '-c', "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)")
38
-
39
- # Add Homebrew to PATH and run initialization script
40
- puts "adding homebrew to .zshrc"
41
- File.open("#{ENV['HOME']}/.zshrc", "a") do |file|
42
- file.write("\n")
43
- file.write('eval "$(/opt/homebrew/bin/brew shellenv)"')
44
- end
45
-
46
- # Update PATH to include Homebrew
47
- ENV['PATH'] = "#{ENV['HOME']}/.homebrew/bin:#{ENV['HOME']}/.homebrew/sbin:#{ENV['PATH']}"
48
-
49
- # Install PostgreSQL
50
- puts "Installing PostgreSQL..."
51
- system('brew', 'install', 'libpq')
52
-
53
- puts "Installing lib-pq..."
54
- system('brew', 'install', 'postgresql@15')
55
-
56
- # Install Code Climate
57
- puts "Preparing Code Climate Formulae..."
58
- system('brew', 'tap', 'codeclimate/formulae')
59
-
60
- puts "Installing Code Climate..."
61
- system('brew', 'install', 'codeclimate')
62
-
63
- # TODO: need to add the path & compiler flags
64
- # echo 'export PATH="/opt/homebrew/opt/libpq/bin:$PATH"' >> ~/.zshrc
65
- # export LDFLAGS="-L/opt/homebrew/opt/libpq/lib"
66
- # export CPPFLAGS="-I/opt/homebrew/opt/libpq/include"
67
-
68
- # Install RBenv
69
- puts "Installing RBenv..."
70
- system('brew', 'install', 'rbenv')
71
- puts "Initialize RBenv..."
72
- File.open("#{ENV['HOME']}/.zshrc", "a") do |file|
73
- file.write("\n")
74
- file.write('eval "$(rbenv init - zsh)"')
33
+ opts.on("-v", "--service SERVICE", "Lookup this service for the ECS execute (defaults to \"prod-worker\")") do |svc|
34
+ options[:service] = svc
75
35
  end
76
- # Load the contents of .zshrc into a string
77
- zshrc_contents = File.read(File.expand_path('~/.zshrc'))
78
-
79
- # Execute a new shell session with the .zshrc contents
80
- exec('zsh', '-c', zshrc_contents)
81
36
 
82
- # Install Ruby
83
- puts "Installing Ruby via RBenv..."
84
- system('rbenv', 'install', '3.2.2')
85
- puts "Making ruby 3.2.2 global ..."
86
- system('rbenv', 'global', '3.2.2')
87
-
88
- # Install Ruby on Rails
89
- puts "Installing Ruby on Rails..."
90
- system('sudo', 'gem', 'install', 'rails')
91
- end
92
- def checkout_repos(options)
93
- token = ENV['GITHUB_TOKEN']
94
- if token.nil?
95
- # Prompt the user for their GitHub personal access token
96
- print "GitHub personal access token: "
97
- token = STDIN.noecho(&:gets).chomp
98
- puts ""
99
- end
100
- # Authenticate with the GitHub API using the user's credentials
101
- client = Octokit::Client.new(access_token: token)
102
-
103
- # Specify the organization name
104
- org_name = "StrongMind"
105
-
106
- if options[:team]
107
- # A team name was provided as a command-line argument
108
- team_name = options[:team]
109
- # Get a list of all teams in the organization
110
- teams = client.organization_teams(org_name)
111
- # Find the team with the specified name
112
- team = teams.find { |t| t.name == team_name }
113
- if team.nil?
114
- puts "Error: Could not find team with name '#{team_name}' in organization '#{org_name}'"
115
- exit
116
- end
117
- # Get a list of all repositories in the organization that are assigned to the specified team
118
- #
119
- repos = client.org_repos(org_name, { :affiliation => 'organization_member', :team_id => team.id })
120
- puts "Team Name #{team_name} - Team ID: #{team.id}"
121
- else
122
- repos = []
123
- page_number = 1
124
- per_page = 100
125
- loop do
126
- repos_page = client.organization_repositories(org_name, { :affiliation => 'owner,organization_member', :per_page => per_page, :page => page_number })
127
- repos.concat(repos_page)
128
- break if repos_page.length < per_page
129
- page_number += 1
130
- end
131
-
132
- # # No team name was provided, so get a list of all teams in the organization
133
- # teams = client.organization_teams(org_name)
134
- # # Get a list of all repositories in the organization that are assigned to each team
135
- # repos = []
136
- # teams.each do |team|
137
- # team_repos = client.team_repos(team.id)
138
- # repos.concat(team_repos)
139
- # end
37
+ opts.on("-c", "--command COMMAND", "Set the command for the ECS execute (defaults to a bash shell when you use 'ssh' and rails console when you use 'console')") do |ecs_command|
38
+ options[:command] = ecs_command
140
39
  end
141
40
 
142
- # Clone each repository to a local directory
143
- repos.each do |repo|
144
- clone_url = repo.clone_url
145
- ssh_url = repo.ssh_url
146
- repo_name = repo.name
147
- url = options[:https] ? clone_url : ssh_url
148
- `git clone #{url} #{repo_name}`
41
+ opts.on("-h", "--help", "Prints this help message") do
42
+ puts opts
43
+ puts "\nCommands:"
44
+ commands.each { |cmd| puts " #{cmd}" }
45
+ exit
149
46
  end
150
47
 
151
- end
48
+ end.parse!
152
49
 
153
50
  command = args.shift
154
51
 
@@ -169,10 +66,150 @@ module Smdev
169
66
  system_install
170
67
  when "checkout_repos"
171
68
  checkout_repos(options)
69
+ when "console"
70
+ options[:command] = "rails c"
71
+ open_ssh(options)
72
+ when "ssh"
73
+ options[:command] ||= "/bin/sh"
74
+ open_ssh(options)
172
75
  else
173
76
  puts "Invalid command: #{command}. Use --help for a list of commands."
174
77
  end
175
78
 
176
79
  end
80
+
81
+ def system_install
82
+ puts "Installing Homebrew..."
83
+ system({ 'SHELL' => '/bin/bash' }, '/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"')
84
+ # system('/bin/bash', '-c', "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)")
85
+
86
+ # Add Homebrew to PATH and run initialization script
87
+ puts "adding homebrew to .zshrc"
88
+ File.open("#{ENV['HOME']}/.zshrc", "a") do |file|
89
+ file.write("\n")
90
+ file.write('eval "$(/opt/homebrew/bin/brew shellenv)"')
91
+ end
92
+
93
+ # Update PATH to include Homebrew
94
+ ENV['PATH'] = "#{ENV['HOME']}/.homebrew/bin:#{ENV['HOME']}/.homebrew/sbin:#{ENV['PATH']}"
95
+
96
+ # Install PostgreSQL
97
+ puts "Installing PostgreSQL..."
98
+ system('brew', 'install', 'libpq')
99
+
100
+ puts "Installing lib-pq..."
101
+ system('brew', 'install', 'postgresql@15')
102
+
103
+ # Install Code Climate
104
+ puts "Preparing Code Climate Formulae..."
105
+ system('brew', 'tap', 'codeclimate/formulae')
106
+
107
+ puts "Installing Code Climate..."
108
+ system('brew', 'install', 'codeclimate')
109
+
110
+ puts "Installing AWS CLI..."
111
+ system('brew', 'install', 'awscli')
112
+
113
+ puts "Installing AWS Session Manager Plugin..."
114
+ system('brew', 'install', '--cask', 'session-manager-plugin')
115
+
116
+ # TODO: need to add the path & compiler flags
117
+ # echo 'export PATH="/opt/homebrew/opt/libpq/bin:$PATH"' >> ~/.zshrc
118
+ # export LDFLAGS="-L/opt/homebrew/opt/libpq/lib"
119
+ # export CPPFLAGS="-I/opt/homebrew/opt/libpq/include"
120
+
121
+ # Install RBenv
122
+ puts "Installing RBenv..."
123
+ system('brew', 'install', 'rbenv')
124
+ puts "Initialize RBenv..."
125
+ File.open("#{ENV['HOME']}/.zshrc", "a") do |file|
126
+ file.write("\n")
127
+ file.write('eval "$(rbenv init - zsh)"')
128
+ end
129
+ # Load the contents of .zshrc into a string
130
+ zshrc_contents = File.read(File.expand_path('~/.zshrc'))
131
+
132
+ # Execute a new shell session with the .zshrc contents
133
+ exec('zsh', '-c', zshrc_contents)
134
+
135
+ # Install Ruby
136
+ puts "Installing Ruby via RBenv..."
137
+ system('rbenv', 'install', '3.2.2')
138
+ puts "Making ruby 3.2.2 global ..."
139
+ system('rbenv', 'global', '3.2.2')
140
+
141
+ # Install Ruby on Rails
142
+ puts "Installing Ruby on Rails..."
143
+ system('sudo', 'gem', 'install', 'rails')
144
+ end
145
+
146
+ def checkout_repos(options)
147
+ token = ENV['GITHUB_TOKEN']
148
+ if token.nil?
149
+ # Prompt the user for their GitHub personal access token
150
+ print "GitHub personal access token: "
151
+ token = STDIN.noecho(&:gets).chomp
152
+ puts ""
153
+ end
154
+ # Authenticate with the GitHub API using the user's credentials
155
+ client = Octokit::Client.new(access_token: token)
156
+
157
+ # Specify the organization name
158
+ org_name = "StrongMind"
159
+
160
+ if options[:team]
161
+ # A team name was provided as a command-line argument
162
+ team_name = options[:team]
163
+ # Get a list of all teams in the organization
164
+ teams = client.organization_teams(org_name)
165
+ # Find the team with the specified name
166
+ team = teams.find { |t| t.name == team_name }
167
+ if team.nil?
168
+ puts "Error: Could not find team with name '#{team_name}' in organization '#{org_name}'"
169
+ exit
170
+ end
171
+ # Get a list of all repositories in the organization that are assigned to the specified team
172
+ #
173
+ repos = client.org_repos(org_name, { :affiliation => 'organization_member', :team_id => team.id })
174
+ puts "Team Name #{team_name} - Team ID: #{team.id}"
175
+ else
176
+ repos = []
177
+ page_number = 1
178
+ per_page = 100
179
+ loop do
180
+ repos_page = client.organization_repositories(org_name, { :affiliation => 'owner,organization_member', :per_page => per_page, :page => page_number })
181
+ repos.concat(repos_page)
182
+ break if repos_page.length < per_page
183
+ page_number += 1
184
+ end
185
+
186
+ # # No team name was provided, so get a list of all teams in the organization
187
+ # teams = client.organization_teams(org_name)
188
+ # # Get a list of all repositories in the organization that are assigned to each team
189
+ # repos = []
190
+ # teams.each do |team|
191
+ # team_repos = client.team_repos(team.id)
192
+ # repos.concat(team_repos)
193
+ # end
194
+ end
195
+
196
+ # Clone each repository to a local directory
197
+ repos.each do |repo|
198
+ clone_url = repo.clone_url
199
+ ssh_url = repo.ssh_url
200
+ repo_name = repo.name
201
+ url = options[:https] ? clone_url : ssh_url
202
+ `git clone #{url} #{repo_name}`
203
+ end
204
+
205
+ end
206
+
207
+ private
208
+
209
+ def open_ssh(options)
210
+ options[:service] ||= "prod-worker"
211
+ options[:cluster] ||= Dir.pwd.split('/').last
212
+ Smdev::EcsExec.ssh(options)
213
+ end
177
214
  end
178
- end
215
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: smdev
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Derek Neighbors
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-09-11 00:00:00.000000000 Z
11
+ date: 2023-10-12 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: StrongMind Development Tool
14
14
  email: derek.neighbors@strongmind.com
@@ -19,11 +19,12 @@ extra_rdoc_files: []
19
19
  files:
20
20
  - bin/smdev
21
21
  - lib/smdev.rb
22
+ - lib/smdev/ecs_exec.rb
22
23
  homepage: https://github.com/StrongMind/Helpers/tree/main/smdev
23
24
  licenses:
24
25
  - MIT
25
26
  metadata: {}
26
- post_install_message:
27
+ post_install_message:
27
28
  rdoc_options: []
28
29
  require_paths:
29
30
  - lib
@@ -38,8 +39,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
38
39
  - !ruby/object:Gem::Version
39
40
  version: '0'
40
41
  requirements: []
41
- rubygems_version: 3.4.13
42
- signing_key:
42
+ rubygems_version: 3.3.5
43
+ signing_key:
43
44
  specification_version: 4
44
45
  summary: StrongMind Development Tool
45
46
  test_files: []