dpl 1.8.18.travis.1472.4 → 1.8.21

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.
@@ -3,15 +3,18 @@ require 'timeout'
3
3
  module DPL
4
4
  class Provider
5
5
  class OpsWorks < Provider
6
- requires 'aws-sdk-v1'
6
+ requires 'aws-sdk', version: '~> 2'
7
7
  experimental 'AWS OpsWorks'
8
8
 
9
- def api
10
- @api ||= AWS::OpsWorks.new
9
+ def opsworks
10
+ @opsworks ||= Aws::OpsWorks::Client.new(opsworks_options)
11
11
  end
12
12
 
13
- def client
14
- @client ||= api.client
13
+ def opsworks_options
14
+ {
15
+ region: region || 'us-east-1',
16
+ credentials: ::Aws::Credentials.new(access_key_id, secret_access_key)
17
+ }
15
18
  end
16
19
 
17
20
  def needs_key?
@@ -22,6 +25,10 @@ module DPL
22
25
 
23
26
  end
24
27
 
28
+ def region
29
+ options[:region] || context.env['AWS_DEFAULT_REGION']
30
+ end
31
+
25
32
  def access_key_id
26
33
  options[:access_key_id] || context.env['AWS_ACCESS_KEY_ID'] || raise(Error, "missing access_key_id")
27
34
  end
@@ -30,13 +37,8 @@ module DPL
30
37
  options[:secret_access_key] || context.env['AWS_SECRET_ACCESS_KEY'] || raise(Error, "missing secret_access_key")
31
38
  end
32
39
 
33
- def setup_auth
34
- AWS.config(access_key_id: access_key_id, secret_access_key: secret_access_key)
35
- end
36
-
37
40
  def check_auth
38
- setup_auth
39
- log "Logging in with Access Key: #{option(:access_key_id)[-4..-1].rjust(20, '*')}"
41
+ log "Logging in with Access Key: #{access_key_id[-4..-1].rjust(20, '*')}"
40
42
  end
41
43
 
42
44
  def custom_json
@@ -61,7 +63,7 @@ module DPL
61
63
  end
62
64
 
63
65
  def fetch_ops_works_app
64
- data = client.describe_apps(app_ids: [option(:app_id)])
66
+ data = opsworks.describe_apps(app_ids: [option(:app_id)])
65
67
  unless data[:apps] && data[:apps].count == 1
66
68
  raise Error, "App #{option(:app_id)} not found.", error.backtrace
67
69
  end
@@ -87,7 +89,11 @@ module DPL
87
89
  if !options[:instance_ids].nil?
88
90
  deployment_config[:instance_ids] = Array(option(:instance_ids))
89
91
  end
90
- data = client.create_deployment(deployment_config)
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)
91
97
  log "Deployment created: #{data[:deployment_id]}"
92
98
  return unless options[:wait_until_deployed]
93
99
  print "Deploying "
@@ -103,7 +109,7 @@ module DPL
103
109
  def wait_until_deployed(deployment_id)
104
110
  deployment = nil
105
111
  loop do
106
- result = client.describe_deployments(deployment_ids: [deployment_id])
112
+ result = opsworks.describe_deployments(deployment_ids: [deployment_id])
107
113
  deployment = result[:deployments].first
108
114
  break unless deployment[:status] == "running"
109
115
  print "."
@@ -118,10 +124,8 @@ module DPL
118
124
 
119
125
  def deploy
120
126
  super
121
- rescue AWS::Errors::ClientError => error
122
- raise Error, "Stopping Deploy, OpsWorks error: #{error.message}", error.backtrace
123
- rescue AWS::Errors::ServerError => error
124
- raise Error, "Stopping Deploy, OpsWorks server error: #{error.message}", error.backtrace
127
+ rescue Aws::Errors::ServiceError => error
128
+ raise Error, "Stopping Deploy, OpsWorks service error: #{error.message}", error.backtrace
125
129
  end
126
130
  end
127
131
  end
@@ -1,6 +1,7 @@
1
1
  module DPL
2
2
  class Provider
3
3
  class Packagecloud < Provider
4
+ requires 'json_pure', :version => '< 2.0', :load => 'json/pure'
4
5
  requires 'packagecloud-ruby', :version => "0.2.17", :load => 'packagecloud'
5
6
 
6
7
  def check_auth
@@ -3,6 +3,7 @@ module DPL
3
3
  class PuppetForge < Provider
4
4
  require 'pathname'
5
5
 
6
+ requires 'json_pure', :version => '< 2.0', :load => 'json/pure'
6
7
  requires 'puppet', :load => 'puppet/face'
7
8
  requires 'puppet-blacksmith', :load => 'puppet_blacksmith'
8
9
 
@@ -50,9 +50,11 @@ module DPL
50
50
  opts[:cache_control] = get_option_value_by_filename(options[:cache_control], filename) if options[:cache_control]
51
51
  opts[:acl] = options[:acl].gsub(/_/, '-') if options[:acl]
52
52
  opts[:expires] = get_option_value_by_filename(options[:expires], filename) if options[:expires]
53
+ opts[:storage_class] = options[:storage_class] if options[:storage_class]
53
54
  unless File.directory?(filename)
54
55
  log "uploading #{filename.inspect} with #{opts.inspect}"
55
- api.bucket(option(:bucket)).object(upload_path(filename)).upload_file(filename, opts)
56
+ result = api.bucket(option(:bucket)).object(upload_path(filename)).upload_file(filename, opts)
57
+ warn "error while uploading #{filename.inspect}" unless result
56
58
  end
57
59
  end
58
60
  end
data/lib/dpl/provider.rb CHANGED
@@ -1,7 +1,6 @@
1
1
  require 'dpl/error'
2
2
  require 'dpl/version'
3
3
  require 'fileutils'
4
- require 'json/pure'
5
4
 
6
5
  module DPL
7
6
  class Provider
@@ -14,6 +13,7 @@ module DPL
14
13
  autoload :Bintray, 'dpl/provider/bintray'
15
14
  autoload :BitBalloon, 'dpl/provider/bitballoon'
16
15
  autoload :Boxfuse, 'dpl/provider/boxfuse'
16
+ autoload :Catalyze, 'dpl/provider/catalyze'
17
17
  autoload :ChefSupermarket, 'dpl/provider/chef_supermarket'
18
18
  autoload :Cloud66, 'dpl/provider/cloud66'
19
19
  autoload :CloudFiles, 'dpl/provider/cloud_files'
data/lib/dpl/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module DPL
2
- VERSION = '1.8.17'
2
+ VERSION = '1.8.21'
3
3
  end
@@ -0,0 +1,95 @@
1
+ require 'spec_helper'
2
+ require 'dpl/provider/anynines'
3
+
4
+
5
+ describe DPL::Provider::AzureWebApps do
6
+ subject :provider do
7
+ described_class.new(DummyContext.new,
8
+ :username => 'myUsername',
9
+ :password => 'myPassword',
10
+ :site => 'myWebsite',
11
+ :slot => 'mySlot')
12
+ end
13
+
14
+ subject :provider_without_slot do
15
+ described_class.new(DummyContext.new,
16
+ :username => 'myUsername',
17
+ :password => 'myPassword',
18
+ :site => 'myWebsite')
19
+ end
20
+
21
+
22
+ describe "#git_target" do
23
+ example "With slot" do
24
+ expect(provider.git_target).to eq('https://myUsername:myPassword@mySlot.scm.azurewebsites.net:443/myWebsite.git')
25
+ end
26
+
27
+ example "Without slot" do
28
+ expect(provider_without_slot.git_target).to eq('https://myUsername:myPassword@myWebsite.scm.azurewebsites.net:443/myWebsite.git')
29
+ end
30
+ end
31
+
32
+ describe "#needs_key?" do
33
+ example do
34
+ expect(provider.needs_key?).to eq(false)
35
+ end
36
+ end
37
+
38
+ describe "#check_auth" do
39
+ example "Without credentials" do
40
+ provider.options.update(:username => nil)
41
+ provider.options.update(:password => nil)
42
+ provider.options.update(:site => nil)
43
+ expect{provider.check_auth}.to raise_error(DPL::Error, 'missing Azure Git Deployment username')
44
+ end
45
+
46
+ example "Without username" do
47
+ provider.options.update(:username => nil)
48
+ expect{provider.check_auth}.to raise_error(DPL::Error, 'missing Azure Git Deployment username')
49
+ end
50
+
51
+ example "Without password" do
52
+ provider.options.update(:password => nil)
53
+ expect{provider.check_auth}.to raise_error(DPL::Error, 'missing Azure Git Deployment password')
54
+ end
55
+
56
+ example "Without WebApp name" do
57
+ provider.options.update(:site => nil)
58
+ expect{provider.check_auth}.to raise_error(DPL::Error, 'missing Azure Web App name')
59
+ end
60
+ end
61
+
62
+ describe "push_app" do
63
+ example "skip cleanup" do
64
+ provider.options.update(:skip_cleanup => true)
65
+ provider.options.update(:verbose => false)
66
+ expect(provider.context).to receive(:shell).with('git checkout HEAD')
67
+ expect(provider.context).to receive(:shell).with('git add . --all --force')
68
+ expect(provider.context).to receive(:shell).with('git commit -m "Skip Cleanup Commit"')
69
+ expect(provider.context).to receive(:shell).with('git push --force --quiet https://myUsername:myPassword@mySlot.scm.azurewebsites.net:443/myWebsite.git HEAD:refs/heads/master > /dev/null 2>&1')
70
+ provider.push_app
71
+ end
72
+
73
+ example "Dont skip cleanup" do
74
+ provider.options.update(:skip_cleanup => false)
75
+ provider.options.update(:verbose => false)
76
+ expect(provider.context).to receive(:shell).with('git push --force --quiet https://myUsername:myPassword@mySlot.scm.azurewebsites.net:443/myWebsite.git HEAD:refs/heads/master > /dev/null 2>&1')
77
+ provider.push_app
78
+ end
79
+
80
+ example "Verbose" do
81
+ provider.options.update(:skip_cleanup => false)
82
+ provider.options.update(:verbose => true)
83
+ expect(provider.context).to receive(:shell).with('git push --force --quiet https://myUsername:myPassword@mySlot.scm.azurewebsites.net:443/myWebsite.git HEAD:refs/heads/master')
84
+ provider.push_app
85
+ end
86
+
87
+ example "Not verbose" do
88
+ provider.options.update(:skip_cleanup => false)
89
+ provider.options.update(:verbose => false)
90
+ expect(provider.context).to receive(:shell).with('git push --force --quiet https://myUsername:myPassword@mySlot.scm.azurewebsites.net:443/myWebsite.git HEAD:refs/heads/master > /dev/null 2>&1')
91
+ provider.push_app
92
+ end
93
+ end
94
+
95
+ end
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+ require 'dpl/provider/catalyze'
3
+
4
+ describe DPL::Provider::Catalyze do
5
+ subject :provider do
6
+ described_class.new(DummyContext.new, :target => 'test-target', :path => 'test-path')
7
+ end
8
+
9
+ describe "#check_auth" do
10
+ it 'should require a target' do
11
+ provider.options.update(:target => nil)
12
+ expect{ provider.check_auth }.to raise_error("Missing Catalyze target")
13
+ end
14
+ end
15
+
16
+ describe "#push_app" do
17
+ it 'should push the current branch to the target' do
18
+ expect(provider.context).to receive(:shell).with("git push --force test-target HEAD:master")
19
+ provider.push_app
20
+ end
21
+ it 'should add and commit local build files if skip_cleanup is true' do
22
+ provider.options.update(:skip_cleanup => true)
23
+ expect(provider.context).to receive(:shell).with("git checkout HEAD")
24
+ expect(provider.context).to receive(:shell).with("git add test-path --all --force")
25
+ expect(provider.context).to receive(:shell).with("git commit -m \"Local build\" --quiet")
26
+ expect(provider.context).to receive(:shell).with("git push --force test-target HEAD:master")
27
+ provider.push_app
28
+ end
29
+ it 'should use a path of "." if the path is not specified' do
30
+ provider.options.update(:path => nil)
31
+ provider.options.update(:skip_cleanup => true)
32
+ expect(provider.context).to receive(:shell).with("git checkout HEAD")
33
+ expect(provider.context).to receive(:shell).with("git add . --all --force")
34
+ expect(provider.context).to receive(:shell).with("git commit -m \"Local build\" --quiet")
35
+ expect(provider.context).to receive(:shell).with("git push --force test-target HEAD:master")
36
+ provider.push_app
37
+ end
38
+ end
39
+ end
@@ -15,7 +15,7 @@ describe DPL::Provider::CloudFoundry do
15
15
  example do
16
16
  expect(provider.context).to receive(:shell).with('wget \'https://cli.run.pivotal.io/stable?release=linux64-binary&source=github\' -qO cf-linux-amd64.tgz && tar -zxvf cf-linux-amd64.tgz && rm cf-linux-amd64.tgz')
17
17
  expect(provider.context).to receive(:shell).with('./cf api api.run.awesome.io --skip-ssl-validation')
18
- expect(provider.context).to receive(:shell).with('./cf login --u mallomar --p myreallyawesomepassword --o myorg --s outer')
18
+ expect(provider.context).to receive(:shell).with('./cf login -u mallomar -p myreallyawesomepassword -o myorg -s outer')
19
19
  provider.check_auth
20
20
  end
21
21
  end
@@ -98,7 +98,7 @@ describe DPL::Provider::Deis do
98
98
  describe "#push_app" do
99
99
  example do
100
100
  expect(provider.context).to receive(:shell).with(
101
- "git push deis HEAD:refs/heads/master -f 2>&1 | tr -dc '[:alnum:][:space:][:punct:]' | sed -E 's/remote: (\\[1G)+//' | sed 's/\\[K$//'"
101
+ "bash -c 'git push deis HEAD:refs/heads/master -f 2>&1 | tr -dc \"[:alnum:][:space:][:punct:]\" | sed -E \"s/remote: (\\[1G)+//\" | sed \"s/\\[K$//\"; exit ${PIPESTATUS[0]}'"
102
102
  ).and_return(true)
103
103
  provider.push_app
104
104
  end
@@ -0,0 +1,191 @@
1
+ require 'spec_helper'
2
+ require 'dpl/provider/exoscale'
3
+
4
+ describe DPL::Provider::ExoScale do
5
+ subject :provider do
6
+ described_class.new(DummyContext.new, :deployment => 'foo_app/default', :email => 'foo@test.com', :password => 'password')
7
+ end
8
+
9
+ its(:app_name) { should == 'foo_app' }
10
+ its(:dep_name) { should == 'default' }
11
+
12
+ its(:needs_key?) { should be true }
13
+
14
+ describe 'constructor' do
15
+ it 'with wrong arguments' do
16
+ expect {
17
+ described_class.new(DummyContext.new, :foo_dep => 'foo_app/default', :email => 'foo@test.com', :password => 'password')
18
+ }.to raise_error(DPL::Error)
19
+ end
20
+ end
21
+
22
+ it '#check_auth should call #headers_with_token' do
23
+ expect(provider).to receive(:headers_with_token)
24
+ provider.check_auth
25
+ end
26
+
27
+ describe '#check_app' do
28
+ it 'on deployment found' do
29
+ expect(provider).to receive(:api_call).and_return double(
30
+ :code => '200',
31
+ :body => '{"branch":"foo_repo.git"}'
32
+ )
33
+ expect(provider.instance_variable_get(:@repository)).to be_nil
34
+ provider.check_app
35
+ expect(provider.instance_variable_get(:@repository)).to eq('foo_repo.git')
36
+ end
37
+
38
+ it 'on deployment not found' do
39
+ expect(provider).to receive(:api_call).and_return double(:code => '410')
40
+ expect { provider.check_app }.to raise_error(DPL::Error)
41
+ end
42
+ end
43
+
44
+ describe '#setup_key' do
45
+ before do
46
+ expect(File).to receive(:read).with('file').and_return('foo_key')
47
+ expect(provider).to receive(:user).and_return({ 'username' => 'foo_user' })
48
+ end
49
+
50
+ it 'on api success' do
51
+ expect(provider).to receive(:api_call).with('POST', '/user/foo_user/key', '{"key":"foo_key"}').and_return double(
52
+ :code => '200',
53
+ :body => '{ "key": "foo_key", "key_id": "foo_key_id"}'
54
+ )
55
+
56
+ expect(provider.instance_variable_get(:@ssh_key_id)).to be_nil
57
+ provider.setup_key 'file'
58
+ expect(provider.instance_variable_get(:@ssh_key_id)).to eq('foo_key_id')
59
+ end
60
+
61
+ it 'on api failure' do
62
+ expect(provider).to receive(:api_call).with('POST', '/user/foo_user/key', '{"key":"foo_key"}').and_return double(:code => '401')
63
+
64
+ expect { provider.setup_key 'file' }.to raise_error(DPL::Error)
65
+ end
66
+ end
67
+
68
+ describe '#remove_key' do
69
+ before do
70
+ provider.instance_variable_set(:@ssh_key_id, 'foo_key_id')
71
+ expect(provider).to receive(:user).and_return({ 'username' => 'foo_user' })
72
+ end
73
+
74
+ it 'on api success' do
75
+ expect(provider).to receive(:api_call).with('DELETE', '/user/foo_user/key/foo_key_id').and_return double(:code => '204')
76
+ provider.remove_key
77
+ end
78
+
79
+ it 'on api failure' do
80
+ expect(provider).to receive(:api_call).with('DELETE', '/user/foo_user/key/foo_key_id').and_return double(:code => '410')
81
+ expect { provider.remove_key }.to raise_error(DPL::Error)
82
+ end
83
+ end
84
+
85
+ it '#push_app shuld deploy the app' do
86
+ provider.instance_variable_set(:@repository, 'foo_repo.git')
87
+ context = double(:shell)
88
+ expect(context).to receive(:shell).with("git push foo_repo.git HEAD:master -f")
89
+ expect(provider).to receive(:context).and_return context
90
+ expect(provider).to receive(:deploy_app)
91
+
92
+ provider.push_app
93
+ end
94
+
95
+ describe 'private method' do
96
+ describe '#get_token' do
97
+ it 'on api success' do
98
+ request = double()
99
+ expect(request).to receive(:basic_auth).with('foo@test.com', 'password')
100
+ expect(Net::HTTP::Post).to receive(:new).with('/api/apps/token').and_return request
101
+
102
+ expect(provider.instance_variable_get(:@tokenHttp)).to receive(:request).and_return double(
103
+ :code => '200',
104
+ :body => '{ "token": "foo_token"}'
105
+ )
106
+
107
+ expect(provider.instance_eval { get_token }).to eq({ 'token' => 'foo_token' })
108
+ end
109
+
110
+ it 'on api failure' do
111
+ expect(provider.instance_variable_get(:@tokenHttp)).to receive(:request).and_return double(:code => '401')
112
+
113
+ expect do
114
+ provider.instance_eval { get_token }
115
+ end.to raise_error(DPL::Error)
116
+ end
117
+ end
118
+
119
+ it '#headers_with_token should return headers' do
120
+ expect(provider).to receive(:get_token).and_return({ 'token' => 'foo_token' })
121
+ expected_return = {
122
+ 'Authorization' => 'cc_auth_token="foo_token"',
123
+ 'Content-Type' => 'application/json'
124
+ }
125
+
126
+ expect(provider.instance_eval { headers_with_token }).to eq(expected_return)
127
+ end
128
+
129
+ describe '#get_headers' do
130
+ let(:expected_args) { [ 'GET', '/user/', nil, {'foo' => 'headers'} ] }
131
+
132
+ before do
133
+ expect(provider).to receive(:headers_with_token).and_return({ 'foo' => 'headers' })
134
+ end
135
+
136
+ it 'on token valid' do
137
+ expect(provider).to receive(:api_call).with(*expected_args).and_return double(:code => '200')
138
+ expect(provider.instance_eval { get_headers }).to eq({ 'foo' => 'headers' })
139
+ end
140
+
141
+ it 'on token expired' do
142
+ expect(provider).to receive(:api_call).with(*expected_args).and_return double(:code => '401')
143
+ expect(provider).to receive(:headers_with_token).with({ :new_token => true})
144
+
145
+ provider.instance_eval { get_headers }
146
+ end
147
+ end
148
+
149
+ it '#api_call should send request' do
150
+ expected_args = [ "foo_method", "foo_path", "\"foo\":\"data\"", {"foo"=>"headers"} ]
151
+ expect(provider.instance_variable_get(:@http)).to receive(:send_request).with(*expected_args)
152
+
153
+ provider.instance_eval do
154
+ api_call('foo_method', 'foo_path', '"foo":"data"', { 'foo' => 'headers'})
155
+ end
156
+ end
157
+
158
+ describe '#deploy_app' do
159
+ it 'on api success' do
160
+ expect(provider).to receive(:api_call).with('PUT', '/app/foo_app/deployment/default', '{"version":-1}').and_return double(:code => '200')
161
+ provider.instance_eval { deploy_app }
162
+ end
163
+
164
+ it 'on api failure' do
165
+ expect(provider).to receive(:api_call).with('PUT', '/app/foo_app/deployment/default', '{"version":-1}').and_return double(:code => '410')
166
+ expect do
167
+ provider.instance_eval { deploy_app }
168
+ end.to raise_error(DPL::Error)
169
+ end
170
+ end
171
+
172
+ describe '#user' do
173
+ it 'on api success' do
174
+ expect(provider).to receive(:api_call).with('GET', '/user/').and_return double(
175
+ :code => '200',
176
+ :body => '["foo_user"]'
177
+ )
178
+
179
+ expect(provider.instance_eval { user }).to eq('foo_user')
180
+ end
181
+
182
+ it 'on api failure' do
183
+ expect(provider).to receive(:api_call).with('GET', '/user/').and_return double(:code => '410')
184
+
185
+ expect do
186
+ provider.instance_eval { user }
187
+ end.to raise_error(DPL::Error)
188
+ end
189
+ end
190
+ end
191
+ end
@@ -22,7 +22,7 @@ describe DPL::Provider::Firebase do
22
22
  describe "#push_app" do
23
23
  it 'should include the project specified' do
24
24
  provider.options.update(:project => 'myapp-dev')
25
- expect(provider.context).to receive(:shell).with("firebase deploy --non-interactive -f myapp-dev --token 'abc123'")
25
+ expect(provider.context).to receive(:shell).with("firebase deploy --non-interactive --project myapp-dev --token 'abc123'")
26
26
  provider.push_app
27
27
  end
28
28