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,71 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Dpl
|
4
|
+
module Providers
|
5
|
+
class Anynines < Provider
|
6
|
+
register :anynines
|
7
|
+
|
8
|
+
status :alpha
|
9
|
+
|
10
|
+
description sq(<<-STR)
|
11
|
+
tbd
|
12
|
+
STR
|
13
|
+
|
14
|
+
env :anynines
|
15
|
+
|
16
|
+
opt '--username USER', 'anynines username', required: true
|
17
|
+
opt '--password PASS', 'anynines password', required: true, secret: true
|
18
|
+
opt '--organization ORG', 'anynines organization', required: true
|
19
|
+
opt '--space SPACE', 'anynines space', required: true
|
20
|
+
opt '--app_name APP', 'Application name'
|
21
|
+
opt '--buildpack PACK', 'Buildpack name or Git URL'
|
22
|
+
opt '--manifest FILE', 'Path to the manifest'
|
23
|
+
opt '--logout', default: true, internal: true
|
24
|
+
|
25
|
+
API = 'https://api.de.a9s.eu'
|
26
|
+
|
27
|
+
cmds install: 'test $(uname) = "Linux" && rel="linux64-binary" || rel="macosx64"; wget "https://cli.run.pivotal.io/stable?release=${rel}&source=github" -qO cf.tgz && tar -zxvf cf.tgz && rm cf.tgz',
|
28
|
+
api: './cf api %{url}',
|
29
|
+
login: './cf login -u %{username} -p %{password} -o %{organization} -s %{space}',
|
30
|
+
push: './cf push %{args}',
|
31
|
+
logout: './cf logout'
|
32
|
+
|
33
|
+
errs install: 'Failed to install CLI tools',
|
34
|
+
api: 'Failed to set api',
|
35
|
+
login: 'Failed to login',
|
36
|
+
target: 'Failed to target organization %{organization}, space %{space}',
|
37
|
+
push: 'Failed to push app',
|
38
|
+
logout: 'Failed to logout'
|
39
|
+
|
40
|
+
def install
|
41
|
+
shell :install
|
42
|
+
end
|
43
|
+
|
44
|
+
def login
|
45
|
+
shell :api
|
46
|
+
shell :login
|
47
|
+
end
|
48
|
+
|
49
|
+
def deploy
|
50
|
+
shell :push
|
51
|
+
end
|
52
|
+
|
53
|
+
def finish
|
54
|
+
shell :logout if logout?
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def url
|
60
|
+
API
|
61
|
+
end
|
62
|
+
|
63
|
+
def args
|
64
|
+
args = []
|
65
|
+
args << quote(app_name) if app_name?
|
66
|
+
args << "-f #{manifest}" if manifest?
|
67
|
+
args.join(' ')
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Dpl
|
4
|
+
module Providers
|
5
|
+
class AzureWebApps < Provider
|
6
|
+
register :azure_web_apps
|
7
|
+
|
8
|
+
status :alpha
|
9
|
+
|
10
|
+
full_name 'Azure Web Apps'
|
11
|
+
|
12
|
+
description sq(<<-STR)
|
13
|
+
tbd
|
14
|
+
STR
|
15
|
+
|
16
|
+
env :AZURE_WA
|
17
|
+
|
18
|
+
opt '--username NAME', 'Web App Deployment Username', required: true
|
19
|
+
opt '--password PASS', 'Web App Deployment Password', required: true, secret: true
|
20
|
+
opt '--site SITE', 'Web App name (e.g. myapp in myapp.azurewebsites.net)', required: true
|
21
|
+
opt '--slot SLOT', 'Slot name (if your app uses staging deployment)'
|
22
|
+
opt '--verbose', 'Print deployment output from Azure. Warning: If authentication fails, Git prints credentials in clear text. Correct credentials remain hidden.'
|
23
|
+
|
24
|
+
needs :git
|
25
|
+
|
26
|
+
cmds checkout: 'git checkout HEAD',
|
27
|
+
add: 'git add . --all --force',
|
28
|
+
commit: 'git commit -m "Cleanup commit"',
|
29
|
+
deploy: 'git push --force --quiet %{url} HEAD:refs/heads/master'
|
30
|
+
|
31
|
+
msgs commit: 'Committing changes to git',
|
32
|
+
deploy: 'Deploying to Azure Web App: %{site}'
|
33
|
+
|
34
|
+
errs push: 'Failed pushing to Azure Web Apps'
|
35
|
+
|
36
|
+
URL = 'https://%s:%s@%s.scm.azurewebsites.net:443/%s.git'
|
37
|
+
|
38
|
+
def setup
|
39
|
+
commit if git_dirty? && !cleanup?
|
40
|
+
end
|
41
|
+
|
42
|
+
def deploy
|
43
|
+
shell :deploy, silence: !verbose?
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def url
|
49
|
+
format(URL, username, password, target, site)
|
50
|
+
end
|
51
|
+
|
52
|
+
def target
|
53
|
+
slot || site
|
54
|
+
end
|
55
|
+
|
56
|
+
def commit
|
57
|
+
shell :checkout
|
58
|
+
shell :add
|
59
|
+
shell :commit
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,324 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'net/http'
|
4
|
+
require 'uri'
|
5
|
+
require 'find'
|
6
|
+
|
7
|
+
module Dpl
|
8
|
+
module Providers
|
9
|
+
class Bintray < Provider
|
10
|
+
register :bintray
|
11
|
+
|
12
|
+
status :stable
|
13
|
+
|
14
|
+
description sq(<<-STR)
|
15
|
+
tbd
|
16
|
+
STR
|
17
|
+
|
18
|
+
gem 'json'
|
19
|
+
|
20
|
+
env :bintray
|
21
|
+
|
22
|
+
opt '--user USER', 'Bintray user', required: true
|
23
|
+
opt '--key KEY', 'Bintray API key', required: true, secret: true
|
24
|
+
opt '--file FILE', 'Path to a descriptor file for the Bintray upload', required: true
|
25
|
+
opt '--passphrase PHRASE', 'Passphrase as configured on Bintray (if GPG signing is used)'
|
26
|
+
opt '--url URL', default: 'https://api.bintray.com', internal: true
|
27
|
+
|
28
|
+
msgs missing_file: 'Missing descriptor file: %{file}',
|
29
|
+
invalid_file: 'Failed to parse descriptor file %{file}',
|
30
|
+
create_package: 'Creating package %{package_name}',
|
31
|
+
package_attrs: 'Adding attributes for package %{package_name}',
|
32
|
+
create_version: 'Creating version %{version_name}',
|
33
|
+
version_attrs: 'Adding attributes for version %{version_name}',
|
34
|
+
upload_file: 'Uploading file %{source} to %{target}',
|
35
|
+
sign_version: 'Signing version %s passphrase',
|
36
|
+
publish_version: 'Publishing version %{version_name} of package %{package_name}',
|
37
|
+
missing_path: 'Path: %{path} does not exist.',
|
38
|
+
list_download: 'Listing %{path} in downloads',
|
39
|
+
retrying: '%{code} response from Bintray. It may take some time for a version to be published, retrying in %{pause} sec ... (%{count}/%{max})',
|
40
|
+
giveup_retries: 'Too many retries failed, giving up, something went wrong.',
|
41
|
+
unexpected_code: 'Unexpected HTTP response code %s while checking if the %s exists',
|
42
|
+
request_failed: '%s %s returned unexpected HTTP response code %s',
|
43
|
+
request_success: 'Bintray response: %s %s. %s'
|
44
|
+
|
45
|
+
PATHS = {
|
46
|
+
packages: '/packages/%{subject}/%{repo}',
|
47
|
+
package: '/packages/%{subject}/%{repo}/%{package_name}',
|
48
|
+
package_attrs: '/packages/%{subject}/%{repo}/%{package_name}/attributes',
|
49
|
+
versions: '/packages/%{subject}/%{repo}/%{package_name}/versions',
|
50
|
+
version: '/packages/%{subject}/%{repo}/%{package_name}/versions/%{version_name}',
|
51
|
+
version_attrs: '/packages/%{subject}/%{repo}/%{package_name}/versions/%{version_name}/attributes',
|
52
|
+
version_sign: '/gpg/%{subject}/%{repo}/%{package_name}/versions/%{version_name}',
|
53
|
+
version_publish: '/content/%{subject}/%{repo}/%{package_name}/%{version_name}/publish',
|
54
|
+
version_file: '/content/%{subject}/%{repo}/%{package_name}/%{version_name}/%{target}',
|
55
|
+
file_metadata: '/file_metadata/%{subject}/%{repo}/%{target}'
|
56
|
+
}.freeze
|
57
|
+
|
58
|
+
MAP = {
|
59
|
+
package: %i[name desc licenses labels vcs_url website_url
|
60
|
+
issue_tracker_url public_download_numbers public_stats],
|
61
|
+
version: %i[name desc released vcs_tag github_release_notes_file
|
62
|
+
github_use_tag_release_notes attributes]
|
63
|
+
}.freeze
|
64
|
+
|
65
|
+
def install
|
66
|
+
require 'json'
|
67
|
+
end
|
68
|
+
|
69
|
+
def validate
|
70
|
+
error :missing_file unless File.exist?(file)
|
71
|
+
# validate that the repo exists, and we have access
|
72
|
+
end
|
73
|
+
|
74
|
+
def deploy
|
75
|
+
create_package unless package_exists?
|
76
|
+
create_version unless version_exists?
|
77
|
+
upload_files
|
78
|
+
sign_version if sign_version?
|
79
|
+
publish_version && update_files if publish_version?
|
80
|
+
end
|
81
|
+
|
82
|
+
def package_exists?
|
83
|
+
exists?(:package)
|
84
|
+
end
|
85
|
+
|
86
|
+
def create_package
|
87
|
+
info :create_package
|
88
|
+
post(path(:packages), compact(only(package, *MAP[:package])))
|
89
|
+
return unless package_attrs
|
90
|
+
|
91
|
+
info :package_attrs
|
92
|
+
post(path(:package_attrs), package_attrs)
|
93
|
+
end
|
94
|
+
|
95
|
+
def version_exists?
|
96
|
+
exists?(:version)
|
97
|
+
end
|
98
|
+
|
99
|
+
def create_version
|
100
|
+
info :create_version
|
101
|
+
post(path(:versions), compact(only(version, *MAP[:version])))
|
102
|
+
return unless version_attrs
|
103
|
+
|
104
|
+
info :version_attrs
|
105
|
+
post(path(:version_attrs), version_attrs)
|
106
|
+
end
|
107
|
+
|
108
|
+
def upload_files
|
109
|
+
files.each do |file|
|
110
|
+
info :upload_file, source: file.source, target: file.target
|
111
|
+
put(path(:version_file, target: file.target), file.read, file.params)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def sign_version
|
116
|
+
body = compact(passphrase: passphrase)
|
117
|
+
info :sign_version, (passphrase? ? 'with' : 'without')
|
118
|
+
post(path(:version_sign), body)
|
119
|
+
end
|
120
|
+
|
121
|
+
def publish_version
|
122
|
+
info :publish_version
|
123
|
+
post(path(:version_publish))
|
124
|
+
end
|
125
|
+
|
126
|
+
def update_files
|
127
|
+
files.select(&:download).each do |file|
|
128
|
+
info :list_download, path: file.target
|
129
|
+
update_file(file)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def update_file(file)
|
134
|
+
retrying(max: 10, pause: 5) do
|
135
|
+
body = { list_in_downloads: file.download }.to_json
|
136
|
+
headers = { 'Content-Type': 'application/json' }
|
137
|
+
put(path(:file_metadata, target: file.target), body, {}, headers)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def retrying(opts)
|
142
|
+
1.upto(opts[:max]) do |count|
|
143
|
+
code = yield
|
144
|
+
return if code < 400
|
145
|
+
|
146
|
+
info :retrying, opts.merge(count: count, code: code)
|
147
|
+
sleep opts[:pause]
|
148
|
+
end
|
149
|
+
error :giveup_retries
|
150
|
+
end
|
151
|
+
|
152
|
+
def files
|
153
|
+
return {} unless files = descriptor[:files]
|
154
|
+
return @files if @files
|
155
|
+
|
156
|
+
keys = %i[path includePattern excludePattern uploadPattern matrixParams listInDownloads]
|
157
|
+
files = files.map { |file| file if file[:path] = path_for(file[:includePattern]) }
|
158
|
+
@files = files.compact.map { |file| find(*file.values_at(*keys)) }.flatten
|
159
|
+
end
|
160
|
+
|
161
|
+
def find(path, includes, excludes, uploads, params, download)
|
162
|
+
paths = Find.find(path).select { |path| File.file?(path) }
|
163
|
+
paths = paths.reject { |path| excluded?(path, excludes) }
|
164
|
+
paths = paths.map { |path| [path, path.match(/#{includes}/)] }
|
165
|
+
paths = paths.select(&:last)
|
166
|
+
paths.map { |path, match| Upload.new(path, fmt(uploads, match.captures), params, download) }
|
167
|
+
end
|
168
|
+
|
169
|
+
def fmt(pattern, captures)
|
170
|
+
captures.each.with_index.inject(pattern) do |pattern, (capture, ix)|
|
171
|
+
pattern.gsub("$#{ix + 1}", capture)
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
def excluded?(path, pattern)
|
176
|
+
!pattern.to_s.empty? && path.match(/#{pattern}/)
|
177
|
+
end
|
178
|
+
|
179
|
+
def path_for(str)
|
180
|
+
ix = str.index('(')
|
181
|
+
path = ix.to_i.zero? ? str : str[0, ix]
|
182
|
+
return path if File.exist?(path)
|
183
|
+
|
184
|
+
warn(:missing_path, path: path)
|
185
|
+
nil
|
186
|
+
end
|
187
|
+
|
188
|
+
def exists?(type)
|
189
|
+
case code = head(path(type), raise: false, silent: true)
|
190
|
+
when 200, 201 then true
|
191
|
+
when 404 then false
|
192
|
+
else error :unexpected_code, code, type
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
def head(path, opts = {})
|
197
|
+
req = Net::HTTP::Head.new(path)
|
198
|
+
req.basic_auth(user, key)
|
199
|
+
request(req, opts)
|
200
|
+
end
|
201
|
+
|
202
|
+
def post(path, body = nil)
|
203
|
+
req = Net::HTTP::Post.new(path)
|
204
|
+
req.add_field('Content-Type', 'application/json')
|
205
|
+
req.basic_auth(user, key)
|
206
|
+
req.body = JSON.dump(body) if body
|
207
|
+
request(req)
|
208
|
+
end
|
209
|
+
|
210
|
+
def put(path, body, params = {}, headers = {})
|
211
|
+
req = Net::HTTP::Put.new(append_params(path, params))
|
212
|
+
headers.each { |key, value| req.add_field(key.to_s, value) }
|
213
|
+
req.basic_auth(user, key)
|
214
|
+
req.body = body
|
215
|
+
request(req)
|
216
|
+
end
|
217
|
+
|
218
|
+
def request(req, opts = {})
|
219
|
+
res = http.request(req)
|
220
|
+
handle(req, res, opts)
|
221
|
+
res.code.to_i
|
222
|
+
end
|
223
|
+
|
224
|
+
def http
|
225
|
+
http = Net::HTTP.new(url.host, url.port)
|
226
|
+
http.use_ssl = true
|
227
|
+
http
|
228
|
+
end
|
229
|
+
|
230
|
+
def append_params(path, params)
|
231
|
+
[path, *Array(params).map { |pair| pair.join('=') }].join(';')
|
232
|
+
end
|
233
|
+
|
234
|
+
def handle(req, res, opts = { raise: true })
|
235
|
+
error :request_failed, req.method, req.uri, res.code if opts[:raise] && !success?(res.code)
|
236
|
+
info :request_success, res.code, res.message, parse(res)['message'] unless opts[:silent]
|
237
|
+
res.code.to_i
|
238
|
+
end
|
239
|
+
|
240
|
+
def success?(code)
|
241
|
+
code.to_s[0].to_i == 2
|
242
|
+
end
|
243
|
+
|
244
|
+
def descriptor
|
245
|
+
@descriptor ||= symbolize(JSON.parse(File.read(file)))
|
246
|
+
rescue StandardError
|
247
|
+
error :invalid_file
|
248
|
+
end
|
249
|
+
|
250
|
+
def url
|
251
|
+
@url ||= URI.parse(super || URL)
|
252
|
+
end
|
253
|
+
|
254
|
+
def package
|
255
|
+
descriptor[:package]
|
256
|
+
end
|
257
|
+
|
258
|
+
def package_name
|
259
|
+
package[:name]
|
260
|
+
end
|
261
|
+
|
262
|
+
def package_attrs
|
263
|
+
package[:attributes]
|
264
|
+
end
|
265
|
+
|
266
|
+
def subject
|
267
|
+
package[:subject]
|
268
|
+
end
|
269
|
+
|
270
|
+
def repo
|
271
|
+
package[:repo]
|
272
|
+
end
|
273
|
+
|
274
|
+
def version
|
275
|
+
descriptor[:version]
|
276
|
+
end
|
277
|
+
|
278
|
+
def version_name
|
279
|
+
version[:name]
|
280
|
+
end
|
281
|
+
|
282
|
+
def version_attrs
|
283
|
+
version[:attributes]
|
284
|
+
end
|
285
|
+
|
286
|
+
def sign_version?
|
287
|
+
version[:gpgSign]
|
288
|
+
end
|
289
|
+
|
290
|
+
def publish_version?
|
291
|
+
descriptor[:publish]
|
292
|
+
end
|
293
|
+
|
294
|
+
def path(resource, args = {})
|
295
|
+
interpolate(PATHS[resource], args, secure: true)
|
296
|
+
end
|
297
|
+
|
298
|
+
def parse(json)
|
299
|
+
hash = JSON.parse(json)
|
300
|
+
hash.is_a?(Hash) ? hash : {}
|
301
|
+
rescue StandardError
|
302
|
+
{}
|
303
|
+
end
|
304
|
+
|
305
|
+
def compact(hash)
|
306
|
+
hash.reject { |_, value| value.nil? }
|
307
|
+
end
|
308
|
+
|
309
|
+
def only(hash, *keys)
|
310
|
+
hash.select { |key, _| keys.include?(key) }
|
311
|
+
end
|
312
|
+
|
313
|
+
class Upload < Struct.new(:source, :target, :params, :download)
|
314
|
+
def read
|
315
|
+
IO.read(source)
|
316
|
+
end
|
317
|
+
|
318
|
+
def eql?(other)
|
319
|
+
source == other.source
|
320
|
+
end
|
321
|
+
end
|
322
|
+
end
|
323
|
+
end
|
324
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Dpl
|
4
|
+
module Providers
|
5
|
+
class Bluemixcloudfoundry < Provider
|
6
|
+
register :bluemixcloudfoundry
|
7
|
+
|
8
|
+
status :stable
|
9
|
+
|
10
|
+
full_name 'Bluemix Cloud Foundry'
|
11
|
+
|
12
|
+
description sq(<<-STR)
|
13
|
+
tbd
|
14
|
+
STR
|
15
|
+
|
16
|
+
env :cloudfoundry
|
17
|
+
|
18
|
+
opt '--username USER', 'Bluemix username', required: true
|
19
|
+
opt '--password PASS', 'Bluemix password', required: true, secret: true
|
20
|
+
opt '--organization ORG', 'Bluemix organization', required: true
|
21
|
+
opt '--space SPACE', 'Bluemix space', required: true
|
22
|
+
opt '--region REGION', 'Bluemix region', default: 'ng', enum: %w[ng eu-gb eu-de au-syd]
|
23
|
+
opt '--api URL', 'Bluemix api URL'
|
24
|
+
opt '--app_name APP', 'Application name'
|
25
|
+
opt '--buildpack PACK', 'Buildpack name or Git URL'
|
26
|
+
opt '--manifest FILE', 'Path to the manifest'
|
27
|
+
opt '--skip_ssl_validation', 'Skip SSL validation'
|
28
|
+
opt '--logout', default: true, internal: true
|
29
|
+
|
30
|
+
API = {
|
31
|
+
'ng': 'api.ng.bluemix.net',
|
32
|
+
'eu-gb': 'api.eu-gb.bluemix.net',
|
33
|
+
'eu-de': 'api.eu-de.bluemix.net',
|
34
|
+
'au-syd': 'api.au-syd.bluemix.net'
|
35
|
+
}.freeze
|
36
|
+
|
37
|
+
cmds install: 'test $(uname) = "Linux" && rel="linux64-binary" || rel="macosx64"; wget "https://cli.run.pivotal.io/stable?release=${rel}&source=github" -qO cf.tgz && tar -zxvf cf.tgz && rm cf.tgz',
|
38
|
+
api: './cf api %{api} %{skip_ssl_validation_opt}',
|
39
|
+
login: './cf login -u %{username} -p %{password}',
|
40
|
+
target: './cf target -o %{organization} -s %{space}',
|
41
|
+
push: './cf push %{push_args}',
|
42
|
+
logout: './cf logout'
|
43
|
+
|
44
|
+
errs install: 'Failed to install CLI tools',
|
45
|
+
api: 'Failed to set api %{api}',
|
46
|
+
login: 'Failed to login',
|
47
|
+
target: 'Failed to target organization %{organization}, space %{space}',
|
48
|
+
push: 'Failed to push app',
|
49
|
+
logout: 'Failed to logout'
|
50
|
+
|
51
|
+
msgs manifest_missing: 'Application must have a manifest.yml for unattended deployment'
|
52
|
+
|
53
|
+
def install
|
54
|
+
shell :install
|
55
|
+
end
|
56
|
+
|
57
|
+
def validate
|
58
|
+
error :manifest_missing if manifest? && manifest_missing?
|
59
|
+
end
|
60
|
+
|
61
|
+
def login
|
62
|
+
shell :api
|
63
|
+
shell :login
|
64
|
+
shell :target
|
65
|
+
end
|
66
|
+
|
67
|
+
def deploy
|
68
|
+
shell :push
|
69
|
+
end
|
70
|
+
|
71
|
+
def finish
|
72
|
+
shell :logout if logout?
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
def push_args
|
78
|
+
args = []
|
79
|
+
args << quote(app_name) if app_name?
|
80
|
+
args << "-f #{manifest}" if manifest?
|
81
|
+
args << "-b #{buildpack}" if buildpack?
|
82
|
+
args.join(' ')
|
83
|
+
end
|
84
|
+
|
85
|
+
def skip_ssl_validation_opt
|
86
|
+
'--skip-ssl-validation' if skip_ssl_validation?
|
87
|
+
end
|
88
|
+
|
89
|
+
def manifest_missing?
|
90
|
+
!File.exist?(manifest)
|
91
|
+
end
|
92
|
+
|
93
|
+
def api
|
94
|
+
super || API[region.to_sym]
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Dpl
|
4
|
+
module Providers
|
5
|
+
class Boxfuse < Provider
|
6
|
+
register :boxfuse
|
7
|
+
|
8
|
+
status :alpha
|
9
|
+
|
10
|
+
description sq(<<-STR)
|
11
|
+
tbd
|
12
|
+
STR
|
13
|
+
|
14
|
+
env :boxfuse
|
15
|
+
|
16
|
+
opt '--user USER', required: true
|
17
|
+
opt '--secret SECRET', required: true, secret: true
|
18
|
+
opt '--payload PAYLOAD'
|
19
|
+
opt '--app APP'
|
20
|
+
opt '--version VERSION'
|
21
|
+
opt '--env ENV'
|
22
|
+
opt '--config_file FILE', alias: :configfile, deprecated: :configfile
|
23
|
+
opt '--extra_args ARGS'
|
24
|
+
|
25
|
+
URL = 'https://files.boxfuse.com/com/boxfuse/client/boxfuse-commandline/1.33.0.1460/boxfuse-commandline-1.33.0.1460-linux-x64.tar.gz'
|
26
|
+
|
27
|
+
cmds install: 'curl -L %{URL} | tar xz',
|
28
|
+
deploy: 'boxfuse/boxfuse run %{deploy_opts}'
|
29
|
+
|
30
|
+
def validate
|
31
|
+
# TODO: check if the config file exists (it seems `boxfuse` doesn't)
|
32
|
+
end
|
33
|
+
|
34
|
+
def install
|
35
|
+
shell :install
|
36
|
+
end
|
37
|
+
|
38
|
+
def deploy
|
39
|
+
shell :deploy
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def deploy_opts
|
45
|
+
opts = [*opts_for(%i[user secret payload app env version], prefix: '-')]
|
46
|
+
opts << "-configfile=#{config_file}" if config_file?
|
47
|
+
opts << extra_args if extra_args?
|
48
|
+
opts.join(' ')
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Dpl
|
4
|
+
module Providers
|
5
|
+
class Cargo < Provider
|
6
|
+
register :cargo
|
7
|
+
|
8
|
+
status :stable
|
9
|
+
|
10
|
+
description sq(<<-STR)
|
11
|
+
tbd
|
12
|
+
STR
|
13
|
+
|
14
|
+
env :cargo
|
15
|
+
|
16
|
+
opt '--token TOKEN', 'Cargo registry API token', required: true, secret: true
|
17
|
+
opt '--allow_dirty', 'Allow publishing from a dirty git working directory'
|
18
|
+
|
19
|
+
cmds publish: 'cargo publish %{publish_opts}'
|
20
|
+
|
21
|
+
def deploy
|
22
|
+
shell :publish
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def publish_opts
|
28
|
+
opts_for(%i[token allow_dirty], dashed: true)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|