travis_dpl_test 2.0.3.beta.4.ror
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +172 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/CONTRIBUTING.md +392 -0
- data/Gemfile +32 -0
- data/Gemfile.lock +611 -0
- data/LICENSE +19 -0
- data/README.md +2744 -0
- data/Rakefile +210 -0
- data/bin/dpl +11 -0
- data/config/transliterate.yml +733 -0
- data/dpl.gemspec +23 -0
- data/lib/dpl/assets/atlas/install +19 -0
- data/lib/dpl/assets/convox/install +11 -0
- data/lib/dpl/assets/dpl/README.erb.md +138 -0
- data/lib/dpl/assets/dpl/git_ssh +8 -0
- data/lib/dpl/assets/git/detect_private_key +8 -0
- data/lib/dpl/assets/hephy/filter_log +3 -0
- data/lib/dpl/assets/pypi/install +4 -0
- data/lib/dpl/assets/scalingo/install +6 -0
- data/lib/dpl/cli.rb +100 -0
- data/lib/dpl/ctx/bash.rb +549 -0
- data/lib/dpl/ctx/test.rb +255 -0
- data/lib/dpl/ctx.rb +4 -0
- data/lib/dpl/helper/assets.rb +38 -0
- data/lib/dpl/helper/cmd.rb +169 -0
- data/lib/dpl/helper/config_file.rb +49 -0
- data/lib/dpl/helper/cookbook_site_streaming_uploader.rb +249 -0
- data/lib/dpl/helper/env.rb +92 -0
- data/lib/dpl/helper/github.rb +22 -0
- data/lib/dpl/helper/interpolate.rb +160 -0
- data/lib/dpl/helper/memoize.rb +23 -0
- data/lib/dpl/helper/squiggle.rb +24 -0
- data/lib/dpl/helper/transliterate.rb +13 -0
- data/lib/dpl/helper/wrap.rb +11 -0
- data/lib/dpl/helper/zip.rb +71 -0
- data/lib/dpl/provider/dsl.rb +410 -0
- data/lib/dpl/provider/examples.rb +132 -0
- data/lib/dpl/provider/status.rb +61 -0
- data/lib/dpl/provider.rb +651 -0
- data/lib/dpl/providers/anynines.rb +71 -0
- data/lib/dpl/providers/azure_web_apps.rb +63 -0
- data/lib/dpl/providers/bintray.rb +324 -0
- data/lib/dpl/providers/bluemixcloudfoundry.rb +98 -0
- data/lib/dpl/providers/boxfuse.rb +52 -0
- data/lib/dpl/providers/cargo.rb +32 -0
- data/lib/dpl/providers/chef_supermarket.rb +132 -0
- data/lib/dpl/providers/cloud66.rb +46 -0
- data/lib/dpl/providers/cloudfiles.rb +62 -0
- data/lib/dpl/providers/cloudformation.rb +281 -0
- data/lib/dpl/providers/cloudfoundry.rb +89 -0
- data/lib/dpl/providers/codedeploy.rb +190 -0
- data/lib/dpl/providers/convox.rb +130 -0
- data/lib/dpl/providers/datica.rb +64 -0
- data/lib/dpl/providers/ecr.rb +129 -0
- data/lib/dpl/providers/elasticbeanstalk.rb +207 -0
- data/lib/dpl/providers/engineyard.rb +113 -0
- data/lib/dpl/providers/firebase.rb +45 -0
- data/lib/dpl/providers/flynn.rb +35 -0
- data/lib/dpl/providers/gae.rb +78 -0
- data/lib/dpl/providers/gcs.rb +132 -0
- data/lib/dpl/providers/git_push.rb +273 -0
- data/lib/dpl/providers/gleis.rb +74 -0
- data/lib/dpl/providers/hackage.rb +53 -0
- data/lib/dpl/providers/hephy.rb +107 -0
- data/lib/dpl/providers/heroku/api.rb +123 -0
- data/lib/dpl/providers/heroku/git.rb +54 -0
- data/lib/dpl/providers/heroku.rb +111 -0
- data/lib/dpl/providers/lambda.rb +211 -0
- data/lib/dpl/providers/launchpad.rb +80 -0
- data/lib/dpl/providers/netlify.rb +38 -0
- data/lib/dpl/providers/npm.rb +130 -0
- data/lib/dpl/providers/nuget.rb +41 -0
- data/lib/dpl/providers/openshift.rb +52 -0
- data/lib/dpl/providers/opsworks.rb +146 -0
- data/lib/dpl/providers/packagecloud.rb_ +194 -0
- data/lib/dpl/providers/pages/api.rb +106 -0
- data/lib/dpl/providers/pages/git.rb +262 -0
- data/lib/dpl/providers/pages.rb +18 -0
- data/lib/dpl/providers/puppetforge.rb +50 -0
- data/lib/dpl/providers/pypi.rb +125 -0
- data/lib/dpl/providers/releases.rb +234 -0
- data/lib/dpl/providers/rubygems.rb +97 -0
- data/lib/dpl/providers/s3.rb +251 -0
- data/lib/dpl/providers/scalingo.rb +69 -0
- data/lib/dpl/providers/script.rb +32 -0
- data/lib/dpl/providers/snap.rb +68 -0
- data/lib/dpl/providers/surge.rb +59 -0
- data/lib/dpl/providers/testfairy.rb +101 -0
- data/lib/dpl/providers/transifex.rb +72 -0
- data/lib/dpl/providers.rb +48 -0
- data/lib/dpl/string_ext.rb +23 -0
- data/lib/dpl/support/aws_sdk_patch.rb +26 -0
- data/lib/dpl/support/gems.rb +73 -0
- data/lib/dpl/support/gstore_patch.rb +8 -0
- data/lib/dpl/support/version.rb +84 -0
- data/lib/dpl/version.rb +5 -0
- data/lib/dpl.rb +23 -0
- data/status.json +237 -0
- metadata +161 -0
@@ -0,0 +1,190 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Dpl
|
4
|
+
module Providers
|
5
|
+
# split this up to CodeDeploy::Github and CodeDeploy::S3 using the
|
6
|
+
# revision_type, in order to make opts more strict
|
7
|
+
class Codedeploy < Provider
|
8
|
+
register :codedeploy
|
9
|
+
|
10
|
+
status :stable
|
11
|
+
|
12
|
+
full_name 'AWS Code Deploy'
|
13
|
+
|
14
|
+
description sq(<<-STR)
|
15
|
+
tbd
|
16
|
+
STR
|
17
|
+
|
18
|
+
gem 'aws-sdk-codedeploy', '~> 1.0'
|
19
|
+
gem 'aws-sdk-s3', '~> 1'
|
20
|
+
|
21
|
+
env :aws, :codedeploy
|
22
|
+
config '~/.aws/credentials', '~/.aws/config', prefix: 'aws'
|
23
|
+
|
24
|
+
opt '--access_key_id ID', 'AWS access key', required: true, secret: true
|
25
|
+
opt '--secret_access_key KEY', 'AWS secret access key', required: true, secret: true
|
26
|
+
opt '--application NAME', 'CodeDeploy application name', required: true
|
27
|
+
opt '--deployment_group GROUP', 'CodeDeploy deployment group name'
|
28
|
+
opt '--revision_type TYPE', 'CodeDeploy revision type', enum: %w[s3 github], downcase: true
|
29
|
+
opt '--commit_id SHA', 'Commit ID in case of GitHub'
|
30
|
+
opt '--repository NAME', 'Repository name in case of GitHub'
|
31
|
+
opt '--bucket NAME', 'S3 bucket in case of S3'
|
32
|
+
opt '--region REGION', 'AWS availability zone', default: 'us-east-1'
|
33
|
+
opt '--file_exists_behavior STR', 'How to handle files that already exist in a deployment target location', enum: %w[disallow overwrite retain], default: 'disallow'
|
34
|
+
opt '--wait_until_deployed', 'Wait until the deployment has finished'
|
35
|
+
opt '--bundle_type TYPE', 'Bundle type of the revision'
|
36
|
+
opt '--key KEY', 'S3 bucket key of the revision'
|
37
|
+
opt '--description DESCR', 'Description of the revision', interpolate: true
|
38
|
+
opt '--endpoint ENDPOINT', 'S3 endpoint url'
|
39
|
+
|
40
|
+
msgs login: 'Using Access Key: %{access_key_id}',
|
41
|
+
deploy_triggered: 'Deployment triggered: %s',
|
42
|
+
register_revision: 'Registering app revision with version=%s, etag=%s',
|
43
|
+
waiting_for_deploy: 'Waiting for the deployment to finish ',
|
44
|
+
finished_deploy: 'done: %s.',
|
45
|
+
description: 'Deploy build %{build_number} via Travis CI',
|
46
|
+
missing_bucket: 'Missing required bucket for S3 deployment',
|
47
|
+
missing_key: 'Missing required key for S3 deployment',
|
48
|
+
unknown_revision_type: 'Unknown revision type %p',
|
49
|
+
unknown_bundle_type: 'Unknown bundle type'
|
50
|
+
|
51
|
+
vars :build_number
|
52
|
+
|
53
|
+
def login
|
54
|
+
info :login
|
55
|
+
end
|
56
|
+
|
57
|
+
def deploy
|
58
|
+
register_revision if revision_info[:version]
|
59
|
+
id = create_deployment
|
60
|
+
info :deploy_triggered, id
|
61
|
+
wait_until_deployed(id) if wait_until_deployed?
|
62
|
+
rescue Aws::CodeDeploy::Errors::DeploymentLimitExceededException => e
|
63
|
+
error e.message
|
64
|
+
end
|
65
|
+
|
66
|
+
def register_revision
|
67
|
+
info :register_revision, revision_info[:version], revision_info[:e_tag]
|
68
|
+
code_deploy.register_application_revision(
|
69
|
+
revision:,
|
70
|
+
application_name: application,
|
71
|
+
description:
|
72
|
+
)
|
73
|
+
end
|
74
|
+
|
75
|
+
def create_deployment
|
76
|
+
deployment = code_deploy.create_deployment(
|
77
|
+
revision:,
|
78
|
+
application_name: application,
|
79
|
+
deployment_group_name: deployment_group,
|
80
|
+
description:,
|
81
|
+
file_exists_behavior: file_exists_behavior.upcase
|
82
|
+
)
|
83
|
+
deployment.deployment_id
|
84
|
+
end
|
85
|
+
|
86
|
+
def wait_until_deployed(id)
|
87
|
+
print :waiting_for_deploy
|
88
|
+
status = poll(id) until %w[Succeeded Failed Stopped].include?(status)
|
89
|
+
case status
|
90
|
+
when 'Succeeded'
|
91
|
+
info :finished_deploy, status
|
92
|
+
else
|
93
|
+
error :finished_deploy, status
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def poll(id)
|
98
|
+
sleep 5
|
99
|
+
print '.'
|
100
|
+
code_deploy.get_deployment(deployment_id: id)[:deployment_info][:status]
|
101
|
+
end
|
102
|
+
|
103
|
+
def revision_info
|
104
|
+
revision[:s3_location] || {}
|
105
|
+
end
|
106
|
+
|
107
|
+
def revision
|
108
|
+
@revision ||= case revision_type
|
109
|
+
when 's3' then s3_revision
|
110
|
+
when 'github' then github_revision
|
111
|
+
when nil then bucket? ? s3_revision : github_revision
|
112
|
+
else error :unknown_revision_type, revision_type
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def s3_revision
|
117
|
+
{
|
118
|
+
revision_type: 'S3',
|
119
|
+
s3_location: compact(
|
120
|
+
bucket:,
|
121
|
+
bundle_type:,
|
122
|
+
version: revision_version_info[:version_id],
|
123
|
+
e_tag: revision_version_info[:etag],
|
124
|
+
key:
|
125
|
+
)
|
126
|
+
}
|
127
|
+
end
|
128
|
+
|
129
|
+
def revision_version_info
|
130
|
+
s3.head_object(bucket:, key:)
|
131
|
+
rescue Aws::Errors::ServiceError => e
|
132
|
+
error e.message
|
133
|
+
end
|
134
|
+
|
135
|
+
def github_revision
|
136
|
+
{
|
137
|
+
revision_type: 'GitHub',
|
138
|
+
git_hub_location: {
|
139
|
+
commit_id:,
|
140
|
+
repository:
|
141
|
+
}
|
142
|
+
}
|
143
|
+
end
|
144
|
+
|
145
|
+
def commit_id
|
146
|
+
super || git_sha
|
147
|
+
end
|
148
|
+
|
149
|
+
def repository
|
150
|
+
super || ENV['TRAVIS_REPO_SLUG'] || File.basename(Dir.pwd)
|
151
|
+
end
|
152
|
+
|
153
|
+
def bucket
|
154
|
+
super || error(:missing_bucket)
|
155
|
+
end
|
156
|
+
|
157
|
+
def key
|
158
|
+
super || error(:missing_key)
|
159
|
+
end
|
160
|
+
|
161
|
+
def bundle_type
|
162
|
+
super || key =~ /\.(tar|tgz|zip)$/ && ::Regexp.last_match(1) || error(:unknown_bundle_type)
|
163
|
+
end
|
164
|
+
|
165
|
+
def description
|
166
|
+
interpolate(super || msg(:description), vars:)
|
167
|
+
end
|
168
|
+
|
169
|
+
def build_number
|
170
|
+
ENV['TRAVIS_BUILD_NUMBER']
|
171
|
+
end
|
172
|
+
|
173
|
+
def code_deploy
|
174
|
+
@code_deploy ||= Aws::CodeDeploy::Client.new(client_options)
|
175
|
+
end
|
176
|
+
|
177
|
+
def s3
|
178
|
+
@s3 ||= Aws::S3::Client.new(client_options)
|
179
|
+
end
|
180
|
+
|
181
|
+
def client_options
|
182
|
+
compact(region:, credentials:, endpoint:)
|
183
|
+
end
|
184
|
+
|
185
|
+
def credentials
|
186
|
+
Aws::Credentials.new(access_key_id, secret_access_key)
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
@@ -0,0 +1,130 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Dpl
|
4
|
+
module Providers
|
5
|
+
class Convox < Provider
|
6
|
+
register :convox
|
7
|
+
|
8
|
+
status :dev
|
9
|
+
|
10
|
+
description sq(<<-STR)
|
11
|
+
tbd
|
12
|
+
STR
|
13
|
+
|
14
|
+
gem 'json'
|
15
|
+
|
16
|
+
env :convox
|
17
|
+
|
18
|
+
# needs descriptions
|
19
|
+
opt '--host HOST', default: 'console.convox.com'
|
20
|
+
opt '--app APP', required: true
|
21
|
+
opt '--rack RACK', required: true
|
22
|
+
opt '--password PASS', required: true
|
23
|
+
opt '--install_url URL', default: 'https://convox.com/cli/linux/convox'
|
24
|
+
opt '--update_cli'
|
25
|
+
opt '--create'
|
26
|
+
opt '--promote', default: true
|
27
|
+
opt '--env_names VARS', type: :array, sep: ','
|
28
|
+
opt '--env VARS', type: :array
|
29
|
+
opt '--env_file FILE'
|
30
|
+
opt '--description STR'
|
31
|
+
opt '--generation NUM', type: :int, default: '2'
|
32
|
+
opt '--prepare CMDS', 'Run commands with convox cli available just before deployment', type: :array
|
33
|
+
|
34
|
+
# if app and rack are exported to the env, do they need to be passed to these commands?
|
35
|
+
cmds login: 'convox version --rack %{rack}',
|
36
|
+
validate: 'convox apps info --rack %{rack} --app %{app}',
|
37
|
+
create: 'convox apps create %{app} --generation %{generation} --rack %{rack} --wait',
|
38
|
+
update: 'convox update',
|
39
|
+
set_env: 'convox env set %{env} --rack %{rack} --app %{app} --replace',
|
40
|
+
build: 'convox build --rack %{rack} --app %{app} --id --description %{escaped_description}',
|
41
|
+
deploy: 'convox deploy --rack %{rack} --app %{app} --wait --id --description %{escaped_description}'
|
42
|
+
|
43
|
+
msgs create: 'Application %{app} does not exist on rack %{rack}. Creating it ...',
|
44
|
+
missing: 'Application %{app} does not exist on rack %{rack}.',
|
45
|
+
env_file: 'The given env_file does not exist.',
|
46
|
+
deploy: 'Building and promoting application ...',
|
47
|
+
build: 'Building application ...'
|
48
|
+
|
49
|
+
errs login: 'Login failed.'
|
50
|
+
|
51
|
+
def install
|
52
|
+
script :install
|
53
|
+
shell :update if update_cli?
|
54
|
+
export
|
55
|
+
end
|
56
|
+
|
57
|
+
def login
|
58
|
+
shell :login
|
59
|
+
end
|
60
|
+
|
61
|
+
def validate
|
62
|
+
shell :validate, assert: false and return
|
63
|
+
error :missing unless create?
|
64
|
+
shell :create
|
65
|
+
end
|
66
|
+
|
67
|
+
def prepare
|
68
|
+
Array(super).each do |cmd|
|
69
|
+
cmd.casecmp('restart').zero? ? restart : run_cmd(cmd)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def deploy
|
74
|
+
shell :set_env, echo: false unless env.empty?
|
75
|
+
shell promote? ? :deploy : :build, echo: false
|
76
|
+
end
|
77
|
+
|
78
|
+
def env_names
|
79
|
+
env = super || []
|
80
|
+
env = env.map { |str| "#{str}=#{ENV[str]}" }
|
81
|
+
env_file.concat(env)
|
82
|
+
end
|
83
|
+
|
84
|
+
def env
|
85
|
+
env = env_names.concat(super || [])
|
86
|
+
env.map { |str| escape(str) }.join(' ')
|
87
|
+
end
|
88
|
+
|
89
|
+
def env_file
|
90
|
+
return [] unless env_file?
|
91
|
+
|
92
|
+
error :env_file unless file?(super)
|
93
|
+
lines = read(super).split("\n").map(&:strip)
|
94
|
+
lines.reject(&:empty?)
|
95
|
+
end
|
96
|
+
|
97
|
+
def description
|
98
|
+
if description?
|
99
|
+
super
|
100
|
+
else
|
101
|
+
JSON.dump(
|
102
|
+
repo_slug:,
|
103
|
+
git_commit_sha: git_sha,
|
104
|
+
git_commit_message: git_commit_msg,
|
105
|
+
git_commit_author: git_author_name,
|
106
|
+
git_tag:,
|
107
|
+
branch: git_branch,
|
108
|
+
travis_build_id: ENV['TRAVIS_BUILD_ID'],
|
109
|
+
travis_build_number: ENV['TRAVIS_BUILD_NUMBER'],
|
110
|
+
pull_request: ENV['TRAVIS_PULL_REQUEST']
|
111
|
+
)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def export
|
116
|
+
env_vars.each { |key, value| ENV[key.to_s] = value.to_s }
|
117
|
+
end
|
118
|
+
|
119
|
+
def env_vars
|
120
|
+
{
|
121
|
+
CONVOX_HOST: host,
|
122
|
+
CONVOX_PASSWORD: password,
|
123
|
+
CONVOX_APP: app,
|
124
|
+
CONVOX_RACK: rack,
|
125
|
+
CONVOX_CLI: 'convox'
|
126
|
+
}
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Dpl
|
4
|
+
module Providers
|
5
|
+
class Datica < Provider
|
6
|
+
register :datica
|
7
|
+
|
8
|
+
status :dev
|
9
|
+
|
10
|
+
register :datica, :catalyze
|
11
|
+
|
12
|
+
description sq(<<-STR)
|
13
|
+
tbd
|
14
|
+
STR
|
15
|
+
|
16
|
+
env :datica, :catalyze
|
17
|
+
|
18
|
+
opt '--target TARGET', 'The git remote repository to deploy to', required: true
|
19
|
+
opt '--path PATH', 'Path to files to deploy', default: '.'
|
20
|
+
|
21
|
+
needs :git
|
22
|
+
|
23
|
+
cmds checkout: 'git checkout HEAD',
|
24
|
+
add: 'git add %{path} --all --force',
|
25
|
+
commit: 'git commit -m "%{message}" --quiet',
|
26
|
+
push: 'git push --force %{target} HEAD:master'
|
27
|
+
|
28
|
+
msgs commit: 'Committing build files for deployment',
|
29
|
+
push: 'Deploying to Datica: %{target}'
|
30
|
+
|
31
|
+
def setup
|
32
|
+
commit if git_dirty? && !cleanup?
|
33
|
+
end
|
34
|
+
|
35
|
+
def deploy
|
36
|
+
shell :push
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def commit
|
42
|
+
info :commit
|
43
|
+
shell :checkout
|
44
|
+
shell :add
|
45
|
+
shell :commit
|
46
|
+
end
|
47
|
+
|
48
|
+
def message
|
49
|
+
vars.empty? ? 'Local build' : 'Build #%s (%s) of %s@%s' % vars
|
50
|
+
end
|
51
|
+
|
52
|
+
VARS = %w[
|
53
|
+
TRAVIS_BUILD_NUMBER
|
54
|
+
TRAVIS_COMMIT
|
55
|
+
TRAVIS_REPO_SLUG
|
56
|
+
TRAVIS_BRANCH
|
57
|
+
].freeze
|
58
|
+
|
59
|
+
def vars
|
60
|
+
@vars ||= ENV.values_at(*VARS).compact
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,129 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Dpl
|
4
|
+
module Providers
|
5
|
+
class Ecr < Provider
|
6
|
+
status :alpha
|
7
|
+
|
8
|
+
full_name 'AWS ECR'
|
9
|
+
|
10
|
+
description sq(<<-STR)
|
11
|
+
tbd
|
12
|
+
STR
|
13
|
+
|
14
|
+
gem 'aws-sdk-ecr', '~> 1.0'
|
15
|
+
# gem 'docker-api', '~> 1.34'
|
16
|
+
gem 'json'
|
17
|
+
|
18
|
+
env :aws
|
19
|
+
|
20
|
+
opt '--access_key_id ID', 'AWS access key', required: true, secret: true
|
21
|
+
opt '--secret_access_key KEY', 'AWS secret access key', required: true, secret: true
|
22
|
+
opt '--account_id ID', 'AWS Account ID', note: 'Required if the repository is owned by a different account than the IAM user'
|
23
|
+
opt '--source SOURCE', 'Image to push', note: 'can be the id or the name and optional tag (e.g. mysql:5.6)', required: true
|
24
|
+
opt '--target TARGET', 'Comma separated list of partial repository names to push to', eg: 'image-one:tag,image-two', required: true
|
25
|
+
opt '--region REGION', 'Comma separated list of regions to push to', default: 'us-east-1'
|
26
|
+
|
27
|
+
msgs login: 'Using Access Key: %{access_key_id}',
|
28
|
+
auth_region: 'Authenticated with %{url}',
|
29
|
+
deploy: 'Pushing image %{source} to regions %{regions} as %{targets}',
|
30
|
+
image_pushed: 'Pushed image %{source} to region %{region} as %{target}'
|
31
|
+
|
32
|
+
cmds login: 'docker login -u %{user} -p %{pass} %{url}',
|
33
|
+
tag: 'docker tag %{source} %{url}/%{repo}:%{tag}',
|
34
|
+
push: 'docker push %{url}/%{repo}'
|
35
|
+
|
36
|
+
errs unknown_image: 'Image %{source} not found in the local Docker repository'
|
37
|
+
|
38
|
+
attr_reader :endpoints
|
39
|
+
|
40
|
+
def login
|
41
|
+
info :login
|
42
|
+
auth_regions
|
43
|
+
end
|
44
|
+
|
45
|
+
def validate
|
46
|
+
# TODO: validate the image exists locally
|
47
|
+
end
|
48
|
+
|
49
|
+
def deploy
|
50
|
+
info :deploy, regions: regions.join(', '), targets: targets.join(', ')
|
51
|
+
regions.product(targets).each do |region, target|
|
52
|
+
push(region, target)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def push(region, target)
|
59
|
+
url, repo, tag = endpoints[region], *target.split(':')
|
60
|
+
shell :tag, url:, repo:, tag: tag || 'latest'
|
61
|
+
shell(:push, url:, repo:)
|
62
|
+
info :image_pushed, region:, target:
|
63
|
+
end
|
64
|
+
|
65
|
+
def auth_regions
|
66
|
+
@endpoints = regions.map { |region| [region, auth_region(region)] }.to_h
|
67
|
+
end
|
68
|
+
|
69
|
+
def auth_region(region)
|
70
|
+
token = auth_token(region)
|
71
|
+
user, pass = parse_auth(token.authorization_token)
|
72
|
+
url = token.proxy_endpoint
|
73
|
+
shell :login, user:, pass:, url:, echo: false, silent: true
|
74
|
+
info(:auth_region, url:)
|
75
|
+
strip_protocol(url)
|
76
|
+
end
|
77
|
+
|
78
|
+
def auth_token(region)
|
79
|
+
ecr(region).get_authorization_token(registry_ids).authorization_data[0]
|
80
|
+
end
|
81
|
+
|
82
|
+
def registry_ids
|
83
|
+
account_id? ? { registry_ids: [account_id] } : {}
|
84
|
+
end
|
85
|
+
|
86
|
+
def regions
|
87
|
+
# not sure how this was meant to be normalized when being a YAML list
|
88
|
+
region.split(',')
|
89
|
+
end
|
90
|
+
|
91
|
+
def targets
|
92
|
+
# not sure how this was meant to be normalized when being a YAML list
|
93
|
+
target.split(',')
|
94
|
+
end
|
95
|
+
|
96
|
+
def creds
|
97
|
+
@creds ||= only(opts, :access_key_id, :secret_access_key)
|
98
|
+
end
|
99
|
+
|
100
|
+
def ecr(region)
|
101
|
+
Aws::ECR::Client.new(region:, **creds)
|
102
|
+
end
|
103
|
+
|
104
|
+
def parse_auth(str)
|
105
|
+
user, pass = Base64.decode64(str).split(':')
|
106
|
+
[user, pass.chomp]
|
107
|
+
end
|
108
|
+
|
109
|
+
def strip_protocol(url)
|
110
|
+
url.sub(%r{^https?://}, '')
|
111
|
+
end
|
112
|
+
|
113
|
+
def progress(events)
|
114
|
+
events.split("\r\n").each do |event|
|
115
|
+
event = JSON.parse(event)
|
116
|
+
if e = event['error']
|
117
|
+
error e
|
118
|
+
elsif %w[Preparing Pushing].include?(event['status'])
|
119
|
+
nil
|
120
|
+
elsif event['id']
|
121
|
+
info "#{event['status']} [#{event['id']}]"
|
122
|
+
elsif event['status']
|
123
|
+
info event['status']
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|