rollo 0.7.0 → 0.8.0.pre.1

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2018 Toby Clemson
3
+ Copyright (c) 2021 InfraBlocks Maintainers
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/Rakefile CHANGED
@@ -1,24 +1,148 @@
1
- require "rspec/core/rake_task"
1
+ # frozen_string_literal: true
2
2
 
3
- RSpec::Core::RakeTask.new(:spec)
3
+ require 'yaml'
4
+ require 'rake_circle_ci'
5
+ require 'rake_github'
6
+ require 'rake_ssh'
7
+ require 'rake_gpg'
8
+ require 'securerandom'
9
+ require 'rspec/core/rake_task'
10
+ require 'rubocop/rake_task'
4
11
 
5
- task :default => :spec
12
+ task default: %i[
13
+ library:fix
14
+ test:unit
15
+ ]
16
+
17
+ namespace :encryption do
18
+ namespace :directory do
19
+ desc 'Ensure CI secrets directory exists.'
20
+ task :ensure do
21
+ FileUtils.mkdir_p('config/secrets/ci')
22
+ end
23
+ end
24
+
25
+ namespace :passphrase do
26
+ desc 'Generate encryption passphrase used by CI.'
27
+ task generate: ['directory:ensure'] do
28
+ File.open('config/secrets/ci/encryption.passphrase', 'w') do |f|
29
+ f.write(SecureRandom.base64(36))
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+ namespace :keys do
36
+ namespace :deploy do
37
+ RakeSSH.define_key_tasks(
38
+ path: 'config/secrets/ci/',
39
+ comment: 'maintainers@infrablocks.io'
40
+ )
41
+ end
42
+
43
+ namespace :secrets do
44
+ namespace :gpg do
45
+ RakeGPG.define_generate_key_task(
46
+ output_directory: 'config/secrets/ci',
47
+ name_prefix: 'gpg',
48
+ owner_name: 'InfraBlocks Maintainers',
49
+ owner_email: 'maintainers@infrablocks.io',
50
+ owner_comment: 'rollo CI Key'
51
+ )
52
+ end
53
+
54
+ desc 'Generate key used by CI to access secrets.'
55
+ task generate: [:'gpg:generate']
56
+ end
57
+ end
58
+
59
+ namespace :secrets do
60
+ desc 'Regenerate all generatable secrets.'
61
+ task regenerate: %w[
62
+ encryption:passphrase:generate
63
+ keys:deploy:generate
64
+ keys:secrets:generate
65
+ ]
66
+ end
67
+
68
+ RuboCop::RakeTask.new
69
+
70
+ namespace :library do
71
+ desc 'Run all checks of the library'
72
+ task check: [:rubocop]
73
+
74
+ desc 'Attempt to automatically fix issues with the library'
75
+ task fix: [:'rubocop:auto_correct']
76
+ end
77
+
78
+ namespace :test do
79
+ RSpec::Core::RakeTask.new(:unit)
80
+ end
81
+
82
+ RakeCircleCI.define_project_tasks(
83
+ namespace: :circle_ci,
84
+ project_slug: 'github/infrablocks/rollo'
85
+ ) do |t|
86
+ circle_ci_config =
87
+ YAML.load_file('config/secrets/circle_ci/config.yaml')
88
+
89
+ t.api_token = circle_ci_config['circle_ci_api_token']
90
+ t.environment_variables = {
91
+ ENCRYPTION_PASSPHRASE:
92
+ File.read('config/secrets/ci/encryption.passphrase')
93
+ .chomp
94
+ }
95
+ t.checkout_keys = []
96
+ t.ssh_keys = [
97
+ {
98
+ hostname: 'github.com',
99
+ private_key: File.read('config/secrets/ci/ssh.private')
100
+ }
101
+ ]
102
+ end
103
+
104
+ RakeGithub.define_repository_tasks(
105
+ namespace: :github,
106
+ repository: 'infrablocks/rollo'
107
+ ) do |t|
108
+ github_config =
109
+ YAML.load_file('config/secrets/github/config.yaml')
110
+
111
+ t.access_token = github_config['github_personal_access_token']
112
+ t.deploy_keys = [
113
+ {
114
+ title: 'CircleCI',
115
+ public_key: File.read('config/secrets/ci/ssh.public')
116
+ }
117
+ ]
118
+ end
119
+
120
+ namespace :pipeline do
121
+ desc 'Prepare CircleCI Pipeline'
122
+ task prepare: %i[
123
+ circle_ci:project:follow
124
+ circle_ci:env_vars:ensure
125
+ circle_ci:checkout_keys:ensure
126
+ circle_ci:ssh_keys:ensure
127
+ github:deploy_keys:ensure
128
+ ]
129
+ end
6
130
 
7
131
  namespace :version do
8
- desc "Bump version for specified type (pre, major, minor patch)"
132
+ desc 'Bump version for specified type (pre, major, minor, patch)'
9
133
  task :bump, [:type] do |_, args|
10
134
  bump_version_for(args.type)
11
135
  end
12
136
  end
13
137
 
14
- desc "Release gem"
138
+ desc 'Release gem'
15
139
  task :release do
16
- sh "gem release --tag --push"
140
+ sh 'gem release --tag --push'
17
141
  end
18
142
 
19
143
  def bump_version_for(version_type)
20
- sh "gem bump --version #{version_type} " +
21
- "&& bundle install " +
22
- "&& export LAST_MESSAGE=\"$(git log -1 --pretty=%B)\" " +
23
- "&& git commit -a --amend -m \"${LAST_MESSAGE} [ci skip]\""
144
+ sh "gem bump --version #{version_type} " \
145
+ '&& bundle install ' \
146
+ '&& export LAST_MESSAGE="$(git log -1 --pretty=%B)" ' \
147
+ '&& git commit -a --amend -m "${LAST_MESSAGE} [ci skip]"'
24
148
  end
data/bin/console CHANGED
@@ -1,7 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
- require "bundler/setup"
4
- require "rollo"
4
+ require 'bundler/setup'
5
+ require 'rollo'
5
6
 
6
7
  # You can add fixtures and/or initialization code here to make experimenting
7
8
  # with your gem easier. You can also use a different console, if you like.
@@ -10,5 +11,5 @@ require "rollo"
10
11
  # require "pry"
11
12
  # Pry.start
12
13
 
13
- require "irb"
14
+ require 'irb'
14
15
  IRB.start(__FILE__)
data/lib/rollo.rb CHANGED
@@ -1,4 +1,6 @@
1
- require_relative "rollo/version"
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'rollo/version'
2
4
  require_relative 'rollo/commands'
3
5
 
4
6
  module Rollo
@@ -1 +1,3 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 'commands/main'
@@ -1,8 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'thor'
2
4
  require_relative '../model'
3
5
 
4
6
  module Rollo
5
7
  module Commands
8
+ # rubocop:disable Metrics/ClassLength
6
9
  class Hosts < Thor
7
10
  namespace :hosts
8
11
 
@@ -11,176 +14,219 @@ module Rollo
11
14
  end
12
15
 
13
16
  desc(
14
- 'expand REGION ASG_NAME ECS_CLUSTER_NAME',
15
- 'Expands the host cluster by one batch.')
17
+ 'expand REGION ASG_NAME ECS_CLUSTER_NAME',
18
+ 'Expands the host cluster by one batch.'
19
+ )
16
20
  method_option(
17
- :batch_size,
18
- aliases: '-b',
19
- type: :numeric,
20
- default: 3,
21
- desc: 'The number of hosts to add at a time.')
21
+ :batch_size,
22
+ aliases: '-b',
23
+ type: :numeric,
24
+ default: 3,
25
+ desc: 'The number of hosts to add at a time.'
26
+ )
27
+ # rubocop:disable Metrics/AbcSize
28
+ # rubocop:disable Metrics/MethodLength
22
29
  def expand(
23
- region, asg_name, _,
24
- host_cluster = nil)
30
+ region, asg_name, _,
31
+ host_cluster = nil
32
+ )
25
33
  batch_size = options[:batch_size]
26
34
 
27
- host_cluster = host_cluster ||
28
- Rollo::Model::HostCluster.new(asg_name, region)
35
+ host_cluster ||= Rollo::Model::HostCluster.new(asg_name, region)
29
36
 
30
37
  say("Increasing host cluster desired capacity by #{batch_size}...")
31
38
  with_padding do
32
39
  host_cluster.increase_capacity_by(batch_size) do |on|
33
40
  on.prepare do |current, target|
34
41
  say(
35
- "Changing desired capacity from #{current} to " +
36
- "#{target}...")
42
+ "Changing desired capacity from #{current} to " \
43
+ "#{target}..."
44
+ )
37
45
  end
38
46
  on.waiting_for_start do |attempt|
39
47
  say(
40
- 'Waiting for capacity change to start ' +
41
- "(attempt #{attempt})...")
48
+ 'Waiting for capacity change to start ' \
49
+ "(attempt #{attempt})..."
50
+ )
42
51
  end
43
52
  on.waiting_for_end do |attempt|
44
53
  say(
45
- 'Waiting for capacity change to complete ' +
46
- "(attempt #{attempt})...")
54
+ 'Waiting for capacity change to complete ' \
55
+ "(attempt #{attempt})..."
56
+ )
47
57
  end
48
58
  on.waiting_for_health do |attempt|
49
59
  say("Waiting for a healthy state (attempt #{attempt})")
50
60
  end
51
61
  end
52
62
  end
53
- say "Host cluster desired capacity increased, continuing..."
63
+ say 'Host cluster desired capacity increased, continuing...'
54
64
  end
55
65
 
66
+ # rubocop:enable Metrics/MethodLength
67
+ # rubocop:enable Metrics/AbcSize
68
+
56
69
  desc(
57
- 'contract REGION ASG_NAME ECS_CLUSTER_NAME',
58
- 'Contracts the host cluster by one batch')
70
+ 'contract REGION ASG_NAME ECS_CLUSTER_NAME',
71
+ 'Contracts the host cluster by one batch'
72
+ )
59
73
  method_option(
60
- :batch_size,
61
- aliases: '-b',
62
- type: :numeric,
63
- default: 3,
64
- desc: 'The number of hosts to remove at a time.')
74
+ :batch_size,
75
+ aliases: '-b',
76
+ type: :numeric,
77
+ default: 3,
78
+ desc: 'The number of hosts to remove at a time.'
79
+ )
80
+ # rubocop:disable Metrics/AbcSize
81
+ # rubocop:disable Metrics/MethodLength
65
82
  def contract(
66
- region, asg_name, ecs_cluster_name,
67
- host_cluster = nil, service_cluster = nil)
83
+ region, asg_name, ecs_cluster_name,
84
+ host_cluster = nil, service_cluster = nil
85
+ )
68
86
  batch_size = options[:batch_size]
69
87
 
70
- host_cluster = host_cluster ||
71
- Rollo::Model::HostCluster.new(asg_name, region)
72
- service_cluster = service_cluster ||
73
- Rollo::Model::ServiceCluster.new(ecs_cluster_name, region)
88
+ host_cluster ||= Rollo::Model::HostCluster.new(asg_name, region)
89
+ service_cluster ||= Rollo::Model::ServiceCluster.new(
90
+ ecs_cluster_name, region
91
+ )
74
92
 
75
93
  say("Decreasing host cluster desired capacity by #{batch_size}...")
94
+ # rubocop:disable Metrics/BlockLength
76
95
  with_padding do
77
96
  host_cluster.decrease_capacity_by(batch_size) do |on|
78
97
  on.prepare do |current, target|
79
98
  say(
80
- "Changing desired capacity from #{current} to " +
81
- "#{target}...")
99
+ "Changing desired capacity from #{current} to " \
100
+ "#{target}..."
101
+ )
82
102
  end
83
103
  on.waiting_for_start do |attempt|
84
104
  say(
85
- "Waiting for capacity change to start " +
86
- "(attempt #{attempt})...")
105
+ 'Waiting for capacity change to start ' \
106
+ "(attempt #{attempt})..."
107
+ )
87
108
  end
88
109
  on.waiting_for_end do |attempt|
89
110
  say(
90
- "Waiting for capacity change to complete " +
91
- "(attempt #{attempt})...")
111
+ 'Waiting for capacity change to complete ' \
112
+ "(attempt #{attempt})..."
113
+ )
92
114
  end
93
115
  on.waiting_for_health do |attempt|
94
116
  say(
95
- "Waiting for host cluster to reach healthy state " +
96
- "(attempt #{attempt})...")
117
+ 'Waiting for host cluster to reach healthy state ' \
118
+ "(attempt #{attempt})..."
119
+ )
97
120
  end
98
121
  end
99
- service_cluster.with_replica_services do |on|
100
- on.each_service do |service|
122
+ service_cluster.with_replica_services do |services|
123
+ services.each_service do |service|
101
124
  service.wait_for_service_health do |on|
102
125
  on.waiting_for_health do |attempt|
103
126
  say(
104
- "Waiting for service #{service.name} to reach a " +
105
- "steady state (attempt #{attempt})...")
127
+ "Waiting for service #{service.name} to reach a " \
128
+ "steady state (attempt #{attempt})..."
129
+ )
106
130
  end
107
131
  end
108
132
  end
109
133
  end
110
134
  end
111
- say "Host cluster desired capacity decreased, continuing..."
135
+ # rubocop:enable Metrics/BlockLength
136
+ say 'Host cluster desired capacity decreased, continuing...'
112
137
  end
113
138
 
139
+ # rubocop:enable Metrics/MethodLength
140
+ # rubocop:enable Metrics/AbcSize
141
+
114
142
  desc(
115
- 'terminate REGION ASG_NAME ECS_CLUSTER_NAME INSTANCE_IDS*',
116
- 'Terminates the specified hosts within the cluster.')
143
+ 'terminate REGION ASG_NAME ECS_CLUSTER_NAME INSTANCE_IDS*',
144
+ 'Terminates the specified hosts within the cluster.'
145
+ )
117
146
  method_option(
118
- :batch_size,
119
- aliases: '-b',
120
- type: :numeric,
121
- default: 3,
122
- desc: 'The number of hosts to add at a time.')
147
+ :batch_size,
148
+ aliases: '-b',
149
+ type: :numeric,
150
+ default: 3,
151
+ desc: 'The number of hosts to add at a time.'
152
+ )
123
153
  method_option(
124
- :startup_time,
125
- aliases: '-t',
126
- type: :numeric,
127
- default: 2,
128
- desc: 'The number of minutes to wait for services to start up.')
154
+ :startup_time,
155
+ aliases: '-t',
156
+ type: :numeric,
157
+ default: 2,
158
+ desc: 'The number of minutes to wait for services to start up.'
159
+ )
160
+ # rubocop:disable Metrics/MethodLength
161
+ # rubocop:disable Metrics/AbcSize
162
+ # rubocop:disable Metrics/ParameterLists
129
163
  def terminate(
130
- region, asg_name, ecs_cluster_name, instance_ids,
131
- host_cluster = nil, service_cluster = nil)
164
+ region, asg_name, ecs_cluster_name, instance_ids,
165
+ host_cluster = nil, service_cluster = nil
166
+ )
132
167
  batch_size = options[:batch_size]
133
168
 
134
169
  service_start_wait_minutes = options[:startup_time]
135
170
  service_start_wait_seconds = 60 * service_start_wait_minutes
136
171
 
137
- host_cluster = host_cluster ||
138
- Rollo::Model::HostCluster.new(asg_name, region)
139
- service_cluster = service_cluster ||
140
- Rollo::Model::ServiceCluster.new(ecs_cluster_name, region)
172
+ host_cluster ||= Rollo::Model::HostCluster.new(asg_name, region)
173
+ service_cluster ||= Rollo::Model::ServiceCluster.new(ecs_cluster_name,
174
+ region)
141
175
 
142
- hosts = host_cluster.hosts.select {|h| instance_ids.include?(h.id) }
176
+ hosts = host_cluster.hosts.select { |h| instance_ids.include?(h.id) }
143
177
  host_batches = hosts.each_slice(batch_size).to_a
144
178
 
145
179
  say(
146
- 'Terminating old hosts in host cluster in batches of ' +
147
- "#{batch_size}...")
180
+ 'Terminating old hosts in host cluster in batches of ' \
181
+ "#{batch_size}..."
182
+ )
183
+ # rubocop:disable Metrics/BlockLength
148
184
  with_padding do
149
185
  host_batches.each_with_index do |host_batch, index|
150
186
  say(
151
- "Batch #{index + 1} contains hosts: " +
152
- "\n\t\t[#{host_batch.map(&:id).join(",\n\t\t ")}]\n" +
153
- 'Terminating...')
187
+ "Batch #{index + 1} contains hosts: " \
188
+ "\n\t\t[#{host_batch.map(&:id).join(",\n\t\t ")}]\n" \
189
+ 'Terminating...'
190
+ )
154
191
  host_batch.each(&:terminate)
155
192
  host_cluster.wait_for_capacity_health do |on|
156
193
  on.waiting_for_health do |attempt|
157
194
  say(
158
- 'Waiting for host cluster to reach healthy state ' +
159
- "(attempt #{attempt})")
195
+ 'Waiting for host cluster to reach healthy state ' \
196
+ "(attempt #{attempt})"
197
+ )
160
198
  end
161
199
  end
162
- service_cluster.with_replica_services do |on|
163
- on.each_service do |service|
200
+ service_cluster.with_replica_services do |services|
201
+ services.each_service do |service|
164
202
  service.wait_for_service_health do |on|
165
203
  on.waiting_for_health do |attempt|
166
204
  say(
167
- "Waiting for service #{service.name} to reach a " +
168
- "steady state (attempt #{attempt})...")
205
+ "Waiting for service #{service.name} to reach a " \
206
+ "steady state (attempt #{attempt})..."
207
+ )
169
208
  end
170
209
  end
171
210
  end
172
211
  end
173
212
  say(
174
- "Waiting #{service_start_wait_minutes} minute(s) for " +
175
- 'services to finish starting...')
213
+ "Waiting #{service_start_wait_minutes} minute(s) for " \
214
+ 'services to finish starting...'
215
+ )
176
216
  sleep(service_start_wait_seconds)
177
217
  say(
178
- "Waited #{service_start_wait_minutes} minute(s). " +
179
- 'Continuing...')
218
+ "Waited #{service_start_wait_minutes} minute(s). " \
219
+ 'Continuing...'
220
+ )
180
221
  end
181
222
  end
182
-
223
+ # rubocop:enable Metrics/BlockLength
183
224
  end
225
+ # rubocop:enable Metrics/ParameterLists
226
+ # rubocop:enable Metrics/MethodLength
227
+ # rubocop:enable Metrics/AbcSize
184
228
  end
229
+
230
+ # rubocop:enable Metrics/ClassLength
185
231
  end
186
232
  end