firespring_dev_commands 1.4.3.pre.alpha.1 → 1.5.0.pre.alpha.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cb403fd1ae12470807a778fbb3314f74b80a5f7d7c8fe0cf1ac28bab1d56d837
4
- data.tar.gz: ff65c1e27fe4f4d63f3d31f5817b552d5dd4c930b615fadb0403e178e30fa597
3
+ metadata.gz: ea3652c102b7a6ec3395c7b524db518655b574a6050d8f740f2c20daedf63aed
4
+ data.tar.gz: 162e4aa151f14b901b7fcfea1c2b8e3cb1b20ab3de2d9102d00a35b0754e5773
5
5
  SHA512:
6
- metadata.gz: 864a3659c6164459f8623f55e9d995cf77c09d03da85fe23c1b6e9f45e7dde3fe0982891b6e662b0b3942695a12f98d4ba4abe71eb3131e3f9898fa5afa146bd
7
- data.tar.gz: 323ed9adeba33220e791ef078c0e3c4390ed93cdc262b3c3aa18e9b103099bf2f57e727e1b1e412773f3c54cd734fda8b1304953b5bdc2bd1350ba4fdf7a58a4
6
+ metadata.gz: 724282fb3154de07595863a899f29b1ffeea0e5fda1d3d2aa5fb31fd3e17f57bfbc0e9baaf534c4a0e259b8b95b051ba05b6d7072d1cdd4bc544799f665e519a
7
+ data.tar.gz: b60bf002f396a052f0814838940dcb441d95c263a4001bdbdcd18878d0d1a8ee0b7f1a8b5b4026ce43664a92666ab93b23a27e0d9d765669f827171c377d4d3d
data/README.md CHANGED
@@ -11,7 +11,7 @@ gem 'firespring_dev_commands', '~> 0.0.1'
11
11
  * This is not common
12
12
  * It is mostly used for testing local changes before the gem is released
13
13
  ```
14
- gem 'firespring_dev_commands', path: '/path/to/firespring/dev-commands-ruby'
14
+ gem 'firespring_dev_commands', path: '/path/to/dev_commands'
15
15
  ```
16
16
 
17
17
  * Add the following to your Rakefile
@@ -3,13 +3,13 @@ module Dev
3
3
  # Class containing useful methods for interacting with the Aws account
4
4
  class Account
5
5
  # Config object for setting top level Aws account config options
6
- Config = Struct.new(:root, :children, :default, :registry, :ecr_registry_ids, :login_to_account_ecr_registry)
6
+ Config = Struct.new(:root, :children, :default, :registry, :default_login_role_name)
7
7
 
8
8
  # Instantiates a new top level config object if one hasn't already been created
9
9
  # Yields that config object to any given block
10
10
  # Returns the resulting config object
11
11
  def self.config
12
- @config ||= Config.new
12
+ @config ||= Config.new(default_login_role_name: Dev::Aws::DEFAULT_LOGIN_ROLE_NAME)
13
13
  yield(@config) if block_given?
14
14
  @config
15
15
  end
@@ -22,7 +22,7 @@ module Dev
22
22
  # The name of the file containing the Aws settings
23
23
  CONFIG_FILE = "#{Dev::Aws::CONFIG_DIR}/config".freeze
24
24
 
25
- attr_accessor :root, :children, :default, :registry, :ecr_registry_ids
25
+ attr_accessor :root, :children, :default, :registry
26
26
 
27
27
  # Instantiate an account object
28
28
  # Requires that root account and at least one child account have been configured
@@ -35,12 +35,7 @@ module Dev
35
35
  @root = self.class.config.root
36
36
  @children = self.class.config.children
37
37
  @default = self.class.config.default
38
-
39
- # Create the ecr registry list based off several possible configuration values
40
- @ecr_registry_ids = Array(self.class.config.ecr_registry_ids)
41
- @ecr_registry_ids << self.class.config.registry
42
- @ecr_registry_ids << Dev::Aws::Profile.new.current if self.class.config.login_to_account_ecr_registry
43
- @ecr_registry_ids = @ecr_registry_ids.flatten.compact.reject(&:empty?).uniq
38
+ @registry = self.class.config.registry
44
39
  end
45
40
 
46
41
  # Returns all configured account information objects
@@ -78,8 +73,13 @@ module Dev
78
73
  region_default = defaultini['region'] || ENV['AWS_DEFAULT_REGION'] || Dev::Aws::DEFAULT_REGION
79
74
  defaultini['region'] = Dev::Common.new.ask('Default region name', region_default)
80
75
 
81
- mfa_default = defaultini['mfa_serial'] || ENV['AWS_MFA_ARN'] || "arn:aws:iam::#{root}:mfa/#{ENV.fetch('USERNAME', nil)}"
82
- defaultini['mfa_serial'] = Dev::Common.new.ask('Default mfa arn', mfa_default)
76
+ # NOTE: We had an old config for "mfa_serial" which included the entire arn. We deprecated that config since
77
+ # it made it much more difficult to switch between different root accounts.
78
+ mfa_name_default = defaultini['mfa_serial']&.split(%r{mfa/})&.last || ENV['AWS_MFA_ARN']&.split(%r{mfa/})&.last || ENV.fetch('USERNAME', nil)
79
+ defaultini['mfa_serial_name'] = Dev::Common.new.ask('Default mfa name', mfa_name_default)
80
+ # TODO: Eventually, we should delete the mfa_serial entry from the config. Leaving it for now because some projects
81
+ # may be using older versions of the dev_commands library
82
+ # defaultini.delete('mfa_serial')
83
83
 
84
84
  session_name_default = defaultini['role_session_name'] || "#{ENV.fetch('USERNAME', nil)}_cli"
85
85
  defaultini['role_session_name'] = Dev::Common.new.ask('Default session name', session_name_default)
@@ -116,8 +116,13 @@ module Dev
116
116
  region_default = profileini['region'] || defaultini['region'] || ENV['AWS_DEFAULT_REGION'] || Dev::Aws::DEFAULT_REGION
117
117
  profileini['region'] = Dev::Common.new.ask('Default region name', region_default)
118
118
 
119
- role_default = profileini['role_arn'] || "arn:aws:iam::#{account}:role/ReadonlyAccessRole"
120
- profileini['role_arn'] = Dev::Common.new.ask('Default role arn', role_default)
119
+ # NOTE: We had an old config for "role_arn" which included the entire arn. We deprecated that config since
120
+ # it made it much more difficult to switch between different accounts.
121
+ role_name_default = profileini['role_name'] || profileini['role_arn']&.split(%r{role/})&.last || self.class.config.default_login_role_name
122
+ profileini['role_name'] = Dev::Common.new.ask('Default role name', role_name_default)
123
+ # TODO: Eventually, we should delete the role_arn entry from the config. Leaving it for now because some projects
124
+ # may be using older versions of the dev_commands library
125
+ # profileini.delete('role_arn')
121
126
 
122
127
  cfgini.write
123
128
  end
@@ -65,6 +65,8 @@ module Dev
65
65
  credini = IniFile.new(filename: "#{Dev::Aws::CONFIG_DIR}/credentials", default: 'default')
66
66
  defaultini = credini['default']
67
67
 
68
+ # TODO: Should we allow for multiple sets of base credentials? How do I use this for both FDP and SBF?
69
+
68
70
  access_key_default = defaultini['aws_access_key_id']
69
71
  defaultini['aws_access_key_id'] = Dev::Common.new.ask('AWS Access Key ID', access_key_default)
70
72
 
@@ -8,7 +8,7 @@ module Dev
8
8
  class Login
9
9
  # Main interface for logging in to an AWS account
10
10
  # If an account is not specified the user is given an account selection menu
11
- # If account registries have been configured, the user is also logged in to the docker registries
11
+ # If an account registry has been configured, the user is also logged in to the docker registry
12
12
  def login!(account = nil)
13
13
  # If more than one child account has been configured, have the user select the account they want to log in to
14
14
  account ||= Dev::Aws::Account.new.select
@@ -22,8 +22,8 @@ module Dev
22
22
  # Load credentials into the ENV for subprocesses
23
23
  Dev::Aws::Credentials.new.export!
24
24
 
25
- # Login in to all configured docker registries
26
- registry_logins!
25
+ # Login in to the docker registry if the user has configured one
26
+ registry_login! if Dev::Aws::Account.new.registry
27
27
  end
28
28
 
29
29
  # Authorize your local credentials
@@ -31,28 +31,32 @@ module Dev
31
31
  # Temporary credentials are written back to the credentials file
32
32
  def authorize!(account)
33
33
  # Make sure the account has been set up
34
- cfgini = IniFile.new(filename: "#{Dev::Aws::CONFIG_DIR}/config", default: 'default')
35
- unless cfgini.has_section?("profile #{account}")
36
- Dev::Aws::Account.new.write!(account)
37
- cfgini = IniFile.new(filename: "#{Dev::Aws::CONFIG_DIR}/config", default: 'default')
38
- end
34
+ cfgini = setup_cfgini
39
35
 
40
36
  defaultini = cfgini['default']
41
37
  profileini = cfgini["profile #{account}"]
42
38
 
43
- serial = profileini['mfa_serial'] || defaultini['mfa_serial']
44
- role = profileini['role_arn'] || defaultini['role_arn']
39
+ region = profileini['region'] || defaultini['region'] || Dev::Aws::DEFAULT_REGION
40
+
41
+ serial = profileini['mfa_serial_name'] || defaultini['mfa_serial_name']
42
+ serial = "arn:aws:iam::#{Dev::Aws::Account.new.roo.id}:mfa/#{serial}" if serial
43
+ serial ||= profileini['mfa_serial'] || defaultini['mfa_serial']
44
+
45
+ role = profileini['role_name'] || defaultini['role_name']
46
+ role = "arn:aws:iam::#{account}:role/#{role}" if role
47
+ role ||= profileini['role_arn'] || defaultini['role_arn']
48
+
45
49
  session_name = profileini['role_session_name'] || defaultini['role_session_name']
46
50
  session_duration = profileini['session_duration'] || defaultini['session_duration']
47
51
 
48
52
  puts
49
- puts " Logging in to #{account} as #{role}".light_yellow
53
+ puts " Logging in to #{account} in #{region} as #{role}".light_yellow
50
54
  puts
51
55
 
52
56
  code = ENV['AWS_TOKEN_CODE'] || Dev::Common.new.ask("Enter the MFA code for the #{ENV.fetch('USERNAME', '')} user serial #{serial}")
53
57
  raise 'MFA is required' unless code.to_s.strip
54
58
 
55
- sts = ::Aws::STS::Client.new(profile: 'default')
59
+ sts = ::Aws::STS::Client.new(profile: 'default', region: region)
56
60
  creds = sts.assume_role(
57
61
  serial_number: serial,
58
62
  role_arn: role,
@@ -65,19 +69,21 @@ module Dev
65
69
  Dev::Aws::Credentials.new.write!(account, creds)
66
70
  end
67
71
 
68
- # Authroizes the docker cli to pull/push images from the Aws container registry (e.g. if docker compose needs to pull an image)
69
- # Authroizes the docker ruby library to pull/push images from the Aws container registry
70
- def registry_logins!(registry_ids: Dev::Aws::Account.new.ecr_registry_ids, region: Dev::Aws::DEFAULT_REGION)
71
- return if registry_ids.empty?
72
-
73
- puts
74
- registry_ids.each { |id| registry_login!(registry_id: id, region: region) }
75
- puts
72
+ # Returns the config ini file
73
+ # Runs the setup for our current account if it's not already setup
74
+ def setup_cfgini
75
+ cfgini = IniFile.new(filename: "#{Dev::Aws::CONFIG_DIR}/config", default: 'default')
76
+ unless cfgini.has_section?("profile #{account}")
77
+ Dev::Aws::Account.new.write!(account)
78
+ cfgini = IniFile.new(filename: "#{Dev::Aws::CONFIG_DIR}/config", default: 'default')
79
+ end
80
+ cfgini
76
81
  end
77
82
 
78
83
  # Authroizes the docker cli to pull/push images from the Aws container registry (e.g. if docker compose needs to pull an image)
79
84
  # Authroizes the docker ruby library to pull/push images from the Aws container registry
80
- def registry_login!(registry_id: Dev::Aws::Account.new.registries, region: Dev::Aws::DEFAULT_REGION)
85
+ def registry_login!(registry_id: Dev::Aws::Account.new.registry, region: nil)
86
+ region ||= Dev::Aws::Credentials.new.logged_in_region || Dev::Aws::DEFAULT_REGION
81
87
  raise 'registry_id is required' if registry_id.to_s.strip.empty?
82
88
  raise 'region is required' if region.to_s.strip.empty?
83
89
 
@@ -92,25 +98,27 @@ module Dev
92
98
  # Authroizes the docker cli to pull/push images from the Aws container registry
93
99
  # (e.g. if docker compose needs to pull an image)
94
100
  # @deprecated Please use {Dev::Aws::Login#registry_login!} instead
95
- def docker_login!(registry_id: Dev::Aws::Account.new.registry, region: Dev::Aws::DEFAULT_REGION)
101
+ def docker_login!(registry_id: Dev::Aws::Account.new.registry, region: nil)
102
+ region ||= Dev::Aws::Credentials.new.logged_in_region || Dev::Aws::DEFAULT_REGION
96
103
  warn '[DEPRECATION] `Dev::Aws::Login#docker_login!` is deprecated. Please use `Dev::Aws::Login#registry_login!` instead.'
97
104
  docker_cli_login!(registry: "#{registry_id}.dkr.ecr.#{region}.amazonaws.com", region: region)
98
- puts
99
105
  end
100
106
 
101
107
  # Authroizes the docker cli to pull/push images from the Aws container registry
102
108
  # (e.g. if docker compose needs to pull an image)
103
109
  private def docker_cli_login!(registry:, region:)
104
- print(" Logging in to #{registry} in docker... ")
110
+ print(' Logging in to ECR in docker... ')
105
111
  login_cmd = "aws --profile=#{Dev::Aws::Profile.new.current} ecr --region=#{region} get-login-password"
106
112
  login_cmd << ' | '
107
113
  login_cmd << "docker login --password-stdin --username AWS #{registry}"
108
114
  Dev::Common.new.run_command([login_cmd])
115
+ puts
109
116
  end
110
117
 
111
118
  # Authroizes the docker ruby library to pull/push images from the Aws container registry
112
119
  # @deprecated Please use {Dev::Aws::Login#registry_login!} instead
113
- def ecr_login!(registry_id: Dev::Aws::Account.new.registry, region: Dev::Aws::DEFAULT_REGION)
120
+ def ecr_login!(registry_id: Dev::Aws::Account.new.registry, region: nil)
121
+ region ||= Dev::Aws::Credentials.new.logged_in_region || Dev::Aws::DEFAULT_REGION
114
122
  warn '[DEPRECATION] `Dev::Aws::Login#ecr_login!` is deprecated. Please use `Dev::Aws::Login#registry_login!` instead.'
115
123
  docker_lib_login!(registry_id: registry_id, region: region)
116
124
  end
@@ -50,6 +50,15 @@ module Dev
50
50
  puts " export AWS_SESSION_TOKEN=#{ENV.fetch('AWS_SESSION_TOKEN', nil)}"
51
51
  puts
52
52
  end
53
+
54
+ # Print the export commands for the current credentials
55
+ def export_info
56
+ Dev::Aws::Credentials.new.export!
57
+ puts "export AWS_DEFAULT_REGION=#{ENV.fetch('AWS_DEFAULT_REGION', nil)}"
58
+ puts "export AWS_ACCESS_KEY_ID=#{ENV.fetch('AWS_ACCESS_KEY_ID', nil)}"
59
+ puts "export AWS_SECRET_ACCESS_KEY=#{ENV.fetch('AWS_SECRET_ACCESS_KEY', nil)}"
60
+ puts "export AWS_SESSION_TOKEN=#{ENV.fetch('AWS_SESSION_TOKEN', nil)}"
61
+ end
53
62
  end
54
63
  end
55
64
  end
@@ -4,7 +4,10 @@ module Dev
4
4
  # The config dir for the user's AWS settings
5
5
  CONFIG_DIR = "#{Dir.home}/.aws".freeze
6
6
 
7
- # The default region used if none have been configured in the AWS settings
7
+ # The default region used if none has been configured in the AWS settings
8
8
  DEFAULT_REGION = 'us-east-1'.freeze
9
+
10
+ # The default role name used if none has been configured when logging in
11
+ DEFAULT_LOGIN_ROLE_NAME = 'ReadonlyAccessRole'.freeze
9
12
  end
10
13
  end
@@ -31,6 +31,20 @@ module Dev
31
31
  task profile: %w(init) do
32
32
  Dev::Aws::Profile.new.info
33
33
  end
34
+
35
+ namespace :profile do
36
+ desc 'Return the commands to export your AWS credentials into your environment'
37
+ task :export do
38
+ # Turn off all logging except for errors
39
+ LOG.level = Logger::ERROR
40
+
41
+ # Run the init
42
+ Rake::Task[:init].invoke
43
+
44
+ # Print the export info
45
+ Dev::Aws::Profile.new.export_info
46
+ end
47
+ end
34
48
  end
35
49
  end
36
50
  end
@@ -118,9 +118,9 @@ DEV_COMMANDS_TOP_LEVEL.instance_eval do
118
118
 
119
119
  # Define an empty _pre_down_hooks handler which can be overridden by the user
120
120
  task :_pre_down_hooks do
121
- # The user may define custom _pre_logs_hooks tasks to add any pre-logs actions the logs process
122
- # Define this process in the appropriate namespace to add them only to a specific logs
123
- # In that case it is recommended that you call the base _pre_logs_hooks as a dependency of that task
121
+ # The user may define custom _pre_down_hooks tasks to add any pre-down actions the down process
122
+ # Define this process in the appropriate namespace to add them only to a specific down
123
+ # In that case it is recommended that you call the base _pre_down_hooks as a dependency of that task
124
124
  end
125
125
 
126
126
  # Define an empty _post_down_hooks handler which can be overridden by the user
@@ -130,6 +130,20 @@ DEV_COMMANDS_TOP_LEVEL.instance_eval do
130
130
  # In that case it is recommended that you call the base _post_down_hooks as a dependency of that task
131
131
  end
132
132
 
133
+ # Define an empty _pre_stop_hooks handler which can be overridden by the user
134
+ task :_pre_stop_hooks do
135
+ # The user may define custom _pre_stop_hooks tasks to add any pre-stop actions the stop process
136
+ # Define this process in the appropriate namespace to add them only to a specific stop
137
+ # In that case it is recommended that you call the base _pre_stop_hooks as a dependency of that task
138
+ end
139
+
140
+ # Define an empty _post_stop_hooks handler which can be overridden by the user
141
+ task :_post_stop_hooks do
142
+ # The user may define custom _post_stop_hooks tasks to add any post-stop actions the stop process
143
+ # Define this process in the appropriate namespace to add them only to a specific stop
144
+ # In that case it is recommended that you call the base _post_stop_hooks as a dependency of that task
145
+ end
146
+
133
147
  # Define an empty _pre_reload_hooks handler which can be overridden by the user
134
148
  task :_pre_reload_hooks do
135
149
  # The user may define custom _pre_reload_hooks tasks to add any pre-reload actions the reload process
@@ -108,7 +108,7 @@ module Dev
108
108
  namespace application do
109
109
  return if exclude.include?(:down)
110
110
 
111
- desc "Stops the #{application} container"
111
+ desc "Shut down the #{application} container and remove associated resources"
112
112
  task down: %w(init_docker _pre_down_hooks) do
113
113
  LOG.debug "In #{application} down"
114
114
 
@@ -125,6 +125,25 @@ module Dev
125
125
  end
126
126
  end
127
127
 
128
+ # Create the rake task which runs a docker compose stop for the application name
129
+ def create_stop_task!
130
+ application = @name
131
+ exclude = @exclude
132
+
133
+ DEV_COMMANDS_TOP_LEVEL.instance_eval do
134
+ namespace application do
135
+ return if exclude.include?(:stop)
136
+
137
+ desc "Stops the #{application} container"
138
+ task stop: %w(init_docker _pre_stop_hooks) do
139
+ LOG.debug "In #{application} stop"
140
+ Dev::Docker::Compose.new(services: [application]).stop
141
+ Rake::Task[:_post_stop_hooks].execute
142
+ end
143
+ end
144
+ end
145
+ end
146
+
128
147
  # Create the rake task which stops, cleans, and starts the application
129
148
  def create_reload_task!
130
149
  application = @name
@@ -76,6 +76,30 @@ module Dev
76
76
  end
77
77
  end
78
78
 
79
+ # Create the rake task which stops all running containers
80
+ def create_stop_task!
81
+ exclude = @exclude
82
+
83
+ DEV_COMMANDS_TOP_LEVEL.instance_eval do
84
+ return if exclude.include?(:stop)
85
+
86
+ desc 'Stops all running containers'
87
+ task stop: %w(init_docker _pre_stop_hooks) do
88
+ LOG.debug('In base stop')
89
+
90
+ containers = ::Docker::Container.all(filters: {status: %w(restarting running)}.to_json)
91
+ containers.each do |container|
92
+ next if container&.info&.dig('Names')&.any? { |name| name.start_with?('/windows_tcp') }
93
+
94
+ LOG.info "Stopping container #{container.id[0, 12]}"
95
+ container.stop(timeout: 120)
96
+ end
97
+
98
+ Rake::Task[:_post_stop_hooks].execute
99
+ end
100
+ end
101
+ end
102
+
79
103
  # Create the rake task which runs a docker compose down followed by an up
80
104
  def create_reload_task!
81
105
  exclude = @exclude
@@ -6,6 +6,6 @@ module Dev
6
6
  # Use 'v.v.v.pre.alpha.v' for pre-release vesions
7
7
  # Use 'v.v.v.beta.v for beta versions
8
8
  # Use semantic versioning for any releases (https://semver.org/)
9
- VERSION = '1.4.3.pre.alpha.1'.freeze
9
+ VERSION = '1.5.0.pre.alpha.1'.freeze
10
10
  end
11
11
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: firespring_dev_commands
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.3.pre.alpha.1
4
+ version: 1.5.0.pre.alpha.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Firespring