dpl-connect 1.8.43

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.
Files changed (105) hide show
  1. checksums.yaml +7 -0
  2. data/.coveralls.yml +1 -0
  3. data/.gitignore +8 -0
  4. data/.rspec +2 -0
  5. data/.travis.yml +36 -0
  6. data/Gemfile +100 -0
  7. data/LICENSE +22 -0
  8. data/README.md +934 -0
  9. data/Rakefile +1 -0
  10. data/TESTING.md +29 -0
  11. data/bin/dpl +5 -0
  12. data/dpl.gemspec +32 -0
  13. data/lib/dpl/cli.rb +66 -0
  14. data/lib/dpl/error.rb +3 -0
  15. data/lib/dpl/provider.rb +264 -0
  16. data/lib/dpl/provider/anynines.rb +13 -0
  17. data/lib/dpl/provider/appfog.rb +21 -0
  18. data/lib/dpl/provider/atlas.rb +108 -0
  19. data/lib/dpl/provider/azure_webapps.rb +48 -0
  20. data/lib/dpl/provider/bintray.rb +509 -0
  21. data/lib/dpl/provider/bitballoon.rb +22 -0
  22. data/lib/dpl/provider/bluemix_cloud_foundry.rb +23 -0
  23. data/lib/dpl/provider/boxfuse.rb +57 -0
  24. data/lib/dpl/provider/catalyze.rb +49 -0
  25. data/lib/dpl/provider/chef_supermarket.rb +85 -0
  26. data/lib/dpl/provider/cloud66.rb +38 -0
  27. data/lib/dpl/provider/cloud_files.rb +38 -0
  28. data/lib/dpl/provider/cloud_foundry.rb +43 -0
  29. data/lib/dpl/provider/code_deploy.rb +123 -0
  30. data/lib/dpl/provider/deis.rb +119 -0
  31. data/lib/dpl/provider/divshot.rb +23 -0
  32. data/lib/dpl/provider/elastic_beanstalk.rb +195 -0
  33. data/lib/dpl/provider/engine_yard.rb +90 -0
  34. data/lib/dpl/provider/firebase.rb +27 -0
  35. data/lib/dpl/provider/gae.rb +97 -0
  36. data/lib/dpl/provider/gcs.rb +59 -0
  37. data/lib/dpl/provider/hackage.rb +29 -0
  38. data/lib/dpl/provider/heroku.rb +18 -0
  39. data/lib/dpl/provider/heroku/api.rb +98 -0
  40. data/lib/dpl/provider/heroku/generic.rb +94 -0
  41. data/lib/dpl/provider/heroku/git.rb +28 -0
  42. data/lib/dpl/provider/lambda.rb +236 -0
  43. data/lib/dpl/provider/launchpad.rb +48 -0
  44. data/lib/dpl/provider/modulus.rb +23 -0
  45. data/lib/dpl/provider/npm.rb +64 -0
  46. data/lib/dpl/provider/openshift.rb +59 -0
  47. data/lib/dpl/provider/ops_works.rb +132 -0
  48. data/lib/dpl/provider/packagecloud.rb +144 -0
  49. data/lib/dpl/provider/pages.rb +79 -0
  50. data/lib/dpl/provider/puppet_forge.rb +43 -0
  51. data/lib/dpl/provider/pypi.rb +111 -0
  52. data/lib/dpl/provider/releases.rb +139 -0
  53. data/lib/dpl/provider/rubygems.rb +51 -0
  54. data/lib/dpl/provider/s3.rb +123 -0
  55. data/lib/dpl/provider/scalingo.rb +97 -0
  56. data/lib/dpl/provider/script.rb +29 -0
  57. data/lib/dpl/provider/surge.rb +33 -0
  58. data/lib/dpl/provider/testfairy.rb +190 -0
  59. data/lib/dpl/provider/transifex.rb +45 -0
  60. data/lib/dpl/version.rb +3 -0
  61. data/notes/engine_yard.md +1 -0
  62. data/notes/heroku.md +3 -0
  63. data/spec/cli_spec.rb +36 -0
  64. data/spec/provider/anynines_spec.rb +20 -0
  65. data/spec/provider/appfog_spec.rb +35 -0
  66. data/spec/provider/atlas_spec.rb +99 -0
  67. data/spec/provider/azure_webapps_spec.rb +95 -0
  68. data/spec/provider/bintray_spec.rb +259 -0
  69. data/spec/provider/bitballoon_spec.rb +32 -0
  70. data/spec/provider/bluemixcloudfoundry_spec.rb +23 -0
  71. data/spec/provider/boxfuse_spec.rb +16 -0
  72. data/spec/provider/catalyze_spec.rb +39 -0
  73. data/spec/provider/chef_supermarket_spec.rb +51 -0
  74. data/spec/provider/cloud66_spec.rb +44 -0
  75. data/spec/provider/cloud_files_spec.rb +88 -0
  76. data/spec/provider/cloudfoundry_spec.rb +71 -0
  77. data/spec/provider/code_deploy_spec.rb +360 -0
  78. data/spec/provider/deis_spec.rb +116 -0
  79. data/spec/provider/divshot_spec.rb +28 -0
  80. data/spec/provider/elastic_beanstalk_spec.rb +209 -0
  81. data/spec/provider/firebase_spec.rb +40 -0
  82. data/spec/provider/gae_spec.rb +26 -0
  83. data/spec/provider/gcs_spec.rb +115 -0
  84. data/spec/provider/hackage_spec.rb +47 -0
  85. data/spec/provider/heroku_spec.rb +357 -0
  86. data/spec/provider/lambda_spec.rb +432 -0
  87. data/spec/provider/launchpad_spec.rb +33 -0
  88. data/spec/provider/modulus_spec.rb +29 -0
  89. data/spec/provider/npm_spec.rb +95 -0
  90. data/spec/provider/openshift_spec.rb +91 -0
  91. data/spec/provider/ops_works_spec.rb +127 -0
  92. data/spec/provider/packagecloud_spec.rb +56 -0
  93. data/spec/provider/puppet_forge_spec.rb +60 -0
  94. data/spec/provider/pypi_spec.rb +103 -0
  95. data/spec/provider/releases_spec.rb +303 -0
  96. data/spec/provider/rubygems_spec.rb +106 -0
  97. data/spec/provider/s3_spec.rb +174 -0
  98. data/spec/provider/scalingo_spec.rb +64 -0
  99. data/spec/provider/script_spec.rb +26 -0
  100. data/spec/provider/surge_spec.rb +15 -0
  101. data/spec/provider/testfairy_spec.rb +86 -0
  102. data/spec/provider/transifex_spec.rb +110 -0
  103. data/spec/provider_spec.rb +210 -0
  104. data/spec/spec_helper.rb +20 -0
  105. metadata +279 -0
@@ -0,0 +1,48 @@
1
+ require 'net/http'
2
+ require 'net/https'
3
+
4
+ module DPL
5
+ class Provider
6
+ class Launchpad < Provider
7
+
8
+ def initialize(context, options)
9
+ super
10
+ @http = Net::HTTP.new('api.launchpad.net', 443)
11
+ @http.use_ssl = true
12
+ end
13
+
14
+ def check_auth
15
+ end
16
+
17
+ def needs_key?
18
+ false
19
+ end
20
+
21
+ def push_app
22
+ response = api_call('/1.0/' + options[:slug] + '/+code-import', {'ws.op' => 'requestImport'})
23
+ error('Deploy failed! Launchpad credentials invalid. ' + response.code.to_s) if response.code == '401'
24
+ error('Error: ' + response.code.to_s + ' ' + response.body) unless response.kind_of? Net::HTTPSuccess
25
+ end
26
+
27
+ private
28
+
29
+ def api_call(path, data)
30
+ req = Net::HTTP::Post.new(path)
31
+ req.set_form_data(data)
32
+ req['Authorization'] = authorization
33
+ return @http.request(req)
34
+ end
35
+
36
+ def authorization
37
+ return 'OAuth oauth_consumer_key="Travis%20Deploy", ' +
38
+ 'oauth_nonce="' + rand(36**32).to_s(36) + '",' +
39
+ 'oauth_signature="%26' + options[:oauth_token_secret] + '",' +
40
+ 'oauth_signature_method="PLAINTEXT",' +
41
+ 'oauth_timestamp="' + Time::now().to_i.to_s + '",' +
42
+ 'oauth_token="' + options[:oauth_token] + '",' +
43
+ 'oauth_version="1.0"'
44
+ end
45
+
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,23 @@
1
+ module DPL
2
+ class Provider
3
+ class Modulus < Provider
4
+ npm_g 'modulus'
5
+
6
+ def check_auth
7
+ raise Error, "must supply an api key" unless option(:api_key)
8
+ end
9
+
10
+ def check_app
11
+ raise Error, "must supply a project name" unless option(:project_name)
12
+ end
13
+
14
+ def needs_key?
15
+ false
16
+ end
17
+
18
+ def push_app
19
+ context.shell "env MODULUS_TOKEN=#{option(:api_key)} modulus deploy -p #{option(:project_name)}"
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,64 @@
1
+ require 'json'
2
+ require 'uri'
3
+
4
+ module DPL
5
+ class Provider
6
+ class NPM < Provider
7
+ NPMRC_FILE = '~/.npmrc'
8
+ DEFAULT_NPM_REGISTRY = 'registry.npmjs.org'
9
+
10
+ def needs_key?
11
+ false
12
+ end
13
+
14
+ def check_app
15
+ end
16
+
17
+ def setup_auth
18
+ file = File.open(File.expand_path(NPMRC_FILE), 'w')
19
+ file.puts(npmrc_file_content)
20
+ file.flush
21
+ end
22
+
23
+ def check_auth
24
+ setup_auth
25
+ log "Authenticated with email #{option(:email)}"
26
+ end
27
+
28
+ def push_app
29
+ log "NPM API key format changed recently. If your deployment fails, check your API key in ~/.npmrc."
30
+ log "http://docs.travis-ci.com/user/deployment/npm/"
31
+ log "#{NPMRC_FILE} size: #{File.size(File.expand_path(NPMRC_FILE))}"
32
+
33
+ command = "env NPM_API_KEY=#{option(:api_key)} npm publish"
34
+ command << " --tag #{option(:tag)}" if options[:tag]
35
+ context.shell "#{command}"
36
+ FileUtils.rm(File.expand_path(NPMRC_FILE))
37
+ end
38
+
39
+ def package_registry
40
+ if File.exists?('package.json')
41
+ data = JSON.parse(File.read('package.json'))
42
+ if data['publishConfig'] && data['publishConfig']['registry']
43
+ return URI(data['publishConfig']['registry']).host
44
+ end
45
+ end
46
+
47
+ DEFAULT_NPM_REGISTRY
48
+ end
49
+
50
+ def npmrc_file_content
51
+ log "NPM version: #{npm_version}"
52
+ if npm_version =~ /^1/
53
+ "_auth = ${NPM_API_KEY}\nemail = #{option(:email)}"
54
+ else
55
+ "//#{package_registry}/:_authToken=${NPM_API_KEY}"
56
+ end
57
+ end
58
+
59
+ def npm_version
60
+ `npm --version`
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,59 @@
1
+ module DPL
2
+ class Provider
3
+ class Openshift < Provider
4
+ requires 'httpclient', version: '~> 2.4.0'
5
+ requires 'net-ssh', load: 'net/ssh', version: '~> 2.9.2' # Anything higher requires Ruby 2.x
6
+ requires 'net-ssh-gateway', load: 'net/ssh/gateway', version: '~> 1.3.0' # 2.0.0 requires net-ssh 4.0.0
7
+ requires 'rhc'
8
+
9
+ def initialize(context, options)
10
+ super
11
+ @deployment_branch = options[:deployment_branch]
12
+ end
13
+
14
+ def api
15
+ @api ||= ::RHC::Rest::Client.new(:user => option(:user), :password => option(:password), :server => 'openshift.redhat.com')
16
+ end
17
+
18
+ def user
19
+ @user ||= api.user.login
20
+ end
21
+
22
+ def app
23
+ @app ||= api.find_application(option(:domain), option(:app))
24
+ end
25
+
26
+ def check_auth
27
+ log "authenticated as %s" % user
28
+ end
29
+
30
+ def check_app
31
+ log "found app #{app.name}"
32
+ end
33
+
34
+ def setup_key(file, type = nil)
35
+ specified_type, content, comment = File.read(file).split
36
+ api.add_key(option(:key_name), content, type || specified_type)
37
+ end
38
+
39
+ def remove_key
40
+ api.delete_key(option(:key_name))
41
+ end
42
+
43
+ def push_app
44
+ if @deployment_branch
45
+ log "deployment_branch detected: #{@deployment_branch}"
46
+ app.deployment_branch = @deployment_branch
47
+ context.shell "git push #{app.git_url} -f #{app.deployment_branch}"
48
+ else
49
+ context.shell "git push #{app.git_url} -f"
50
+ end
51
+ end
52
+
53
+ def restart
54
+ app.restart
55
+ end
56
+
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,132 @@
1
+ require 'timeout'
2
+
3
+ module DPL
4
+ class Provider
5
+ class OpsWorks < Provider
6
+ requires 'aws-sdk', version: '~> 2.0'
7
+ experimental 'AWS OpsWorks'
8
+
9
+ def opsworks
10
+ @opsworks ||= Aws::OpsWorks::Client.new(opsworks_options)
11
+ end
12
+
13
+ def opsworks_options
14
+ {
15
+ region: region || 'us-east-1',
16
+ credentials: ::Aws::Credentials.new(access_key_id, secret_access_key)
17
+ }
18
+ end
19
+
20
+ def needs_key?
21
+ false
22
+ end
23
+
24
+ def check_app
25
+
26
+ end
27
+
28
+ def region
29
+ options[:region] || context.env['AWS_DEFAULT_REGION']
30
+ end
31
+
32
+ def access_key_id
33
+ options[:access_key_id] || context.env['AWS_ACCESS_KEY_ID'] || raise(Error, "missing access_key_id")
34
+ end
35
+
36
+ def secret_access_key
37
+ options[:secret_access_key] || context.env['AWS_SECRET_ACCESS_KEY'] || raise(Error, "missing secret_access_key")
38
+ end
39
+
40
+ def check_auth
41
+ log "Logging in with Access Key: #{access_key_id[-4..-1].rjust(20, '*')}"
42
+ end
43
+
44
+ def custom_json
45
+ options[:custom_json] || {
46
+ deploy: {
47
+ ops_works_app[:shortname] => {
48
+ migrate: !!options[:migrate],
49
+ scm: {
50
+ revision: current_sha
51
+ }
52
+ }
53
+ }
54
+ }
55
+ end
56
+
57
+ def current_sha
58
+ @current_sha ||= `git rev-parse HEAD`.chomp
59
+ end
60
+
61
+ def ops_works_app
62
+ @ops_works_app ||= fetch_ops_works_app
63
+ end
64
+
65
+ def fetch_ops_works_app
66
+ data = opsworks.describe_apps(app_ids: [option(:app_id)])
67
+ unless data[:apps] && data[:apps].count == 1
68
+ raise Error, "App #{option(:app_id)} not found.", error.backtrace
69
+ end
70
+ data[:apps].first
71
+ end
72
+
73
+ def push_app
74
+ Timeout::timeout(600) do
75
+ create_deployment
76
+ end
77
+ rescue Timeout::Error
78
+ error 'Timeout: Could not finish deployment in 10 minutes.'
79
+ end
80
+
81
+ def create_deployment
82
+ deployment_config = {
83
+ stack_id: ops_works_app[:stack_id],
84
+ app_id: option(:app_id),
85
+ command: {name: 'deploy'},
86
+ comment: travis_deploy_comment,
87
+ custom_json: custom_json.to_json
88
+ }
89
+ if !options[:instance_ids].nil?
90
+ deployment_config[:instance_ids] = Array(option(:instance_ids))
91
+ end
92
+ if !options[:layer_ids].nil?
93
+ deployment_config[:layer_ids] = Array(option(:layer_ids))
94
+ end
95
+ log "creating deployment #{deployment_config.to_json}"
96
+ data = opsworks.create_deployment(deployment_config)
97
+ log "Deployment created: #{data[:deployment_id]}"
98
+ return unless options[:wait_until_deployed]
99
+ print "Deploying "
100
+ deployment = wait_until_deployed(data[:deployment_id])
101
+ print "\n"
102
+ if deployment[:status] == 'successful'
103
+ log "Deployment successful."
104
+ else
105
+ error "Deployment failed."
106
+ end
107
+ end
108
+
109
+ def wait_until_deployed(deployment_id)
110
+ deployment = nil
111
+ loop do
112
+ result = opsworks.describe_deployments(deployment_ids: [deployment_id])
113
+ deployment = result[:deployments].first
114
+ break unless deployment[:status] == "running"
115
+ print "."
116
+ sleep 5
117
+ end
118
+ deployment
119
+ end
120
+
121
+ def travis_deploy_comment
122
+ "Deploy build #{context.env['TRAVIS_BUILD_NUMBER'] || current_sha} via Travis CI"
123
+ end
124
+
125
+ def deploy
126
+ super
127
+ rescue Aws::Errors::ServiceError => error
128
+ raise Error, "Stopping Deploy, OpsWorks service error: #{error.message}", error.backtrace
129
+ end
130
+ end
131
+ end
132
+ end
@@ -0,0 +1,144 @@
1
+ module DPL
2
+ class Provider
3
+ class Packagecloud < Provider
4
+ requires 'json_pure', :version => '< 2.0', :load => 'json/pure'
5
+ requires 'packagecloud-ruby', :version => "1.0.5", :load => 'packagecloud'
6
+
7
+ def check_auth
8
+ setup_auth
9
+ begin
10
+ @client = ::Packagecloud::Client.new(@creds, "travis-ci")
11
+ rescue ::Packagecloud::UnauthenticatedException
12
+ error "Could not authenticate to https://packagecloud.io, please check credentials"
13
+ end
14
+ end
15
+
16
+ def needs_key?
17
+ false
18
+ end
19
+
20
+ def setup_auth
21
+ @username = option(:username)
22
+ @token = option(:token)
23
+ @repo = option(:repository)
24
+ @dist = option(:dist) if options[:dist]
25
+ @creds = ::Packagecloud::Credentials.new(@username, @token)
26
+ log "Logging into https://packagecloud.io with #{@username}:#{@token[-4..-1].rjust(20, '*')}"
27
+ end
28
+
29
+ def get_distro(query)
30
+ distro = nil
31
+ begin
32
+ distro = @client.find_distribution_id(query)
33
+ rescue ArgumentError => exception
34
+ error "Error: #{exception.message}"
35
+ end
36
+ if distro.nil?
37
+ error "Could not find distribution named #{query}"
38
+ end
39
+ distro
40
+ end
41
+
42
+ def is_supported_package?(filename)
43
+ ext = File.extname(filename).gsub!('.','')
44
+ ::Packagecloud::SUPPORTED_EXTENSIONS.include?(ext)
45
+ end
46
+
47
+ def dist_required?(filename)
48
+ ext = File.extname(filename).gsub!('.','')
49
+ if ext.nil?
50
+ error "filename: #{filename} has no extension!"
51
+ end
52
+ ["rpm", "deb", "dsc", "whl", "egg", "egg-info", "gz", "zip", "tar", "bz2", "z"].include?(ext.downcase)
53
+ end
54
+
55
+ def error_if_dist_required(filename)
56
+ if dist_required?(filename) && @dist.nil?
57
+ error "Distribution needed for rpm, deb, python, and dsc packages, example --dist='ubuntu/breezy'"
58
+ end
59
+ end
60
+
61
+ def is_source_package?(filename)
62
+ ext = File.extname(filename).gsub!('.','')
63
+ ext == 'dsc'
64
+ end
65
+
66
+ def get_source_files_for(orig_filename)
67
+ source_files = {}
68
+ glob_args = ["**/*"]
69
+ package = ::Packagecloud::Package.new(:file => orig_filename)
70
+ result = @client.package_contents(@repo, package, get_distro(@dist))
71
+ if result.succeeded
72
+ package_contents_files = result.response["files"].map { |x| x["filename"] }
73
+ Dir.chdir(options.fetch(:local_dir, Dir.pwd)) do
74
+ Dir.glob(*glob_args) do |filename|
75
+ unless File.directory?(filename)
76
+ basename = File.basename(filename)
77
+ if package_contents_files.include?(basename)
78
+ log "Found source fragment: #{basename} for #{orig_filename}"
79
+ source_files = source_files.merge({basename => open(filename)})
80
+ end
81
+ end
82
+ end
83
+ end
84
+ else
85
+ error "Error: #{result.response}"
86
+ end
87
+ source_files
88
+ end
89
+
90
+ def push_app
91
+ forced = options.fetch(:force, nil)
92
+ packages = []
93
+ glob_args = Array(options.fetch(:package_glob, '**/*'))
94
+ Dir.chdir(options.fetch(:local_dir, Dir.pwd)) do
95
+ Dir.glob(*glob_args) do |filename|
96
+ unless File.directory?(filename)
97
+ if is_supported_package?(filename)
98
+ log "Detected supported package: #{filename}"
99
+ error_if_dist_required(filename)
100
+ if is_source_package?(filename)
101
+ log "Processing source package: #{filename}"
102
+ source_files = get_source_files_for(filename)
103
+ packages << ::Packagecloud::Package.new(:file => filename, :source_files => source_files)
104
+ else
105
+ packages << ::Packagecloud::Package.new(:file => filename)
106
+ end
107
+ end
108
+ end
109
+ end
110
+ end
111
+
112
+ packages.each do |package|
113
+ if forced
114
+ log "Deleting package: #{package.filename}"
115
+ distro, distro_release = @dist.split("/")
116
+ result = @client.delete_package(@repo, distro, distro_release, package.filename)
117
+ if result.succeeded
118
+ log "Successfully deleted #{package.filename} on #{@dist}"
119
+ else
120
+ error "Error #{result.response}"
121
+ end
122
+ end
123
+ log "Pushing package: #{package.filename}"
124
+ if dist_required?(package.filename)
125
+ result = @client.put_package(@repo, package, get_distro(@dist))
126
+ else
127
+ result = @client.put_package(@repo, package)
128
+ end
129
+
130
+ if result.succeeded
131
+ log "Successfully pushed #{package.filename} to #{@username}/#{@repo}"
132
+ else
133
+ error "Error #{result.response}"
134
+ end
135
+ end
136
+ if packages.empty?
137
+ error "Error: No supported packages found! Perhaps try skip_cleanup: true"
138
+ end
139
+ end
140
+
141
+ end
142
+
143
+ end
144
+ end