dpl 1.8.17 → 1.8.18
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.
- checksums.yaml +4 -4
- data/.travis.yml +7 -3
- data/Gemfile +9 -2
- data/README.md +78 -30
- data/dpl.gemspec +1 -1
- data/lib/dpl/provider/appfog.rb +1 -0
- data/lib/dpl/provider/catalyze.rb +49 -0
- data/lib/dpl/provider/chef_supermarket.rb +2 -0
- data/lib/dpl/provider/deis.rb +1 -1
- data/lib/dpl/provider/exoscale.rb +100 -0
- data/lib/dpl/provider/openshift.rb +1 -0
- data/lib/dpl/provider/ops_works.rb +22 -18
- data/lib/dpl/provider/packagecloud.rb +1 -0
- data/lib/dpl/provider/puppet_forge.rb +1 -0
- data/lib/dpl/provider/s3.rb +2 -1
- data/lib/dpl/provider.rb +1 -0
- data/lib/dpl/version.rb +1 -1
- data/spec/provider/catalyze_spec.rb +39 -0
- data/spec/provider/deis_spec.rb +1 -1
- data/spec/provider/exoscale_spec.rb +191 -0
- data/spec/provider/ops_works_spec.rb +93 -57
- data/spec/spec_helper.rb +1 -0
- metadata +28 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b4fb4f547a3dc5586a67a2c85c345841cbbed212
|
|
4
|
+
data.tar.gz: d6258b907be13d012d916e4f40a4a6434806b4ac
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7eaf5e117543923831ea3cab7b21f2f93c5cc41ba33321937b79e9bd04bbc2d14b44cdf2754feefc957812f2487c85eea30ea95180d172fee53d8e02f65ca6ce
|
|
7
|
+
data.tar.gz: 689d6ad8a93a3f848df543b87d9e502bdd15e09a52ee1451b6df9c53b496a3a9a5a4948c366fc3735e7296c9ed15b727709f990c08bd98119de6f94080bcaab1
|
data/.travis.yml
CHANGED
|
@@ -2,18 +2,22 @@ language: ruby
|
|
|
2
2
|
rvm:
|
|
3
3
|
- 1.9.3
|
|
4
4
|
- 2.0.0
|
|
5
|
-
- 2.1.0
|
|
6
5
|
- 2.1.5
|
|
7
|
-
- "2.2"
|
|
6
|
+
- "2.2.5"
|
|
7
|
+
- "2.3.1"
|
|
8
8
|
|
|
9
9
|
matrix:
|
|
10
10
|
allow_failures:
|
|
11
|
-
- rvm: "2.2"
|
|
11
|
+
- rvm: "2.2.5"
|
|
12
|
+
- rvm: "2.3.1"
|
|
12
13
|
|
|
13
14
|
sudo: false
|
|
14
15
|
|
|
15
16
|
cache: bundler
|
|
16
17
|
|
|
18
|
+
script:
|
|
19
|
+
- bundle exec rake && gem build dpl.gemspec && gem install dpl-*.gem && dpl --provider=script --script='echo foo'
|
|
20
|
+
|
|
17
21
|
deploy:
|
|
18
22
|
provider: rubygems
|
|
19
23
|
api_key:
|
data/Gemfile
CHANGED
|
@@ -21,6 +21,7 @@ group :openshift do
|
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
group :appfog do
|
|
24
|
+
gem 'json_pure'
|
|
24
25
|
gem 'af'
|
|
25
26
|
end
|
|
26
27
|
|
|
@@ -39,7 +40,7 @@ end
|
|
|
39
40
|
|
|
40
41
|
group :lambda do
|
|
41
42
|
gem 'aws-sdk', '>= 2.0.18.pre'
|
|
42
|
-
gem 'rubyzip'
|
|
43
|
+
gem 'rubyzip', '~> 1.1'
|
|
43
44
|
end
|
|
44
45
|
|
|
45
46
|
group :cloud_files do
|
|
@@ -57,7 +58,7 @@ group :gcs do
|
|
|
57
58
|
end
|
|
58
59
|
|
|
59
60
|
group :elastic_beanstalk do
|
|
60
|
-
gem 'rubyzip'
|
|
61
|
+
gem 'rubyzip', '~> 1.1'
|
|
61
62
|
gem 'aws-sdk-v1'
|
|
62
63
|
end
|
|
63
64
|
|
|
@@ -67,11 +68,13 @@ group :bitballoon do
|
|
|
67
68
|
end
|
|
68
69
|
|
|
69
70
|
group :puppet_forge do
|
|
71
|
+
gem 'json_pure'
|
|
70
72
|
gem 'puppet'
|
|
71
73
|
gem 'puppet-blacksmith'
|
|
72
74
|
end
|
|
73
75
|
|
|
74
76
|
group :packagecloud do
|
|
77
|
+
gem 'json_pure'
|
|
75
78
|
gem 'packagecloud-ruby', '= 0.2.17'
|
|
76
79
|
end
|
|
77
80
|
|
|
@@ -86,3 +89,7 @@ end
|
|
|
86
89
|
group :deis do
|
|
87
90
|
gem 'git'
|
|
88
91
|
end
|
|
92
|
+
|
|
93
|
+
group :opsworks do
|
|
94
|
+
gem 'aws-sdk', '>= 2.0.18.pre'
|
|
95
|
+
end
|
data/README.md
CHANGED
|
@@ -11,18 +11,20 @@ Dpl supports the following providers:
|
|
|
11
11
|
* [AppFog](#appfog)
|
|
12
12
|
* [Atlas by HashiCorp](#atlas)
|
|
13
13
|
* [AWS CodeDeploy](#aws-codedeploy)
|
|
14
|
+
* [AWS Elastic Beanstalk](#elastic-beanstalk)
|
|
14
15
|
* [AWS OpsWorks](#opsworks)
|
|
15
16
|
* [Azure Web Apps](#azure-web-apps)
|
|
16
17
|
* [Bintray](#bintray)
|
|
17
18
|
* [BitBalloon](#bitballoon)
|
|
18
19
|
* [Boxfuse](#boxfuse)
|
|
20
|
+
* [Catalyze](#catalyze)
|
|
19
21
|
* [Chef Supermarket](#chef-supermarket)
|
|
20
22
|
* [Cloud 66](#cloud-66)
|
|
21
23
|
* [Cloud Foundry](#cloud-foundry)
|
|
22
24
|
* [Deis](#deis)
|
|
23
25
|
* [Divshot.io](#divshotio)
|
|
24
|
-
* [Elastic Beanstalk](#elastic-beanstalk)
|
|
25
26
|
* [Engine Yard](#engine-yard)
|
|
27
|
+
* [ExoScale](#exoscale)
|
|
26
28
|
* [Firebase](#firebase)
|
|
27
29
|
* [Github Releases](#github-releases)
|
|
28
30
|
* [Google App Engine (experimental)](#google-app-engine)
|
|
@@ -343,6 +345,30 @@ It is possible to set file-specific `Cache-Control` and `Expires` headers using
|
|
|
343
345
|
dpl --provider=s3 --access-key-id=<access-key-id> --secret-access-key=<secret-access-key> --bucket=<bucket> --detect-encoding --cache_control=max-age=99999 --expires="2012-12-21 00:00:00 -0000"
|
|
344
346
|
dpl --provider=s3 --access-key-id=<access-key-id> --secret-access-key=<secret-access-key> --bucket=<bucket> --region=us-west-2 --local-dir= BUILD --upload-dir=BUILDS
|
|
345
347
|
|
|
348
|
+
### Elastic Beanstalk:
|
|
349
|
+
|
|
350
|
+
#### Options:
|
|
351
|
+
|
|
352
|
+
* **access-key-id**: AWS Access Key ID. Can be obtained from [here](https://console.aws.amazon.com/iam/home?#security_credential).
|
|
353
|
+
* **secret-access-key**: AWS Secret Key. Can be obtained from [here](https://console.aws.amazon.com/iam/home?#security_credential).
|
|
354
|
+
* **region**: AWS Region the Elastic Beanstalk app is running in. Defaults to 'us-east-1'. Please be aware that this must match the region of the elastic beanstalk app.
|
|
355
|
+
* **app**: Elastic Beanstalk application name.
|
|
356
|
+
* **env**: Elastic Beanstalk environment name which will be updated.
|
|
357
|
+
* **zip_file**: The zip file that you want to deploy. _**Note:**_ you also need to use the `skip_cleanup` or the zip file you are trying to upload will be removed during cleanup.
|
|
358
|
+
* **bucket_name**: Bucket name to upload app to.
|
|
359
|
+
* **bucket_path**: Location within Bucket to upload app to.
|
|
360
|
+
* **only_create_app_version**: only create the app version, don't actually deploy it.
|
|
361
|
+
|
|
362
|
+
#### Environment variables:
|
|
363
|
+
|
|
364
|
+
* **ELASTIC_BEANSTALK_ENV**: Elastic Beanstalk environment name which will be updated. Is only used if `env` option is omitted.
|
|
365
|
+
* **ELASTIC_BEANSTALK_LABEL**: Label name of the new version.
|
|
366
|
+
* **ELASTIC_BEANSTALK_DESCRIPTION**: Description of the new version. Defaults to the last commit message.
|
|
367
|
+
|
|
368
|
+
#### Examples:
|
|
369
|
+
|
|
370
|
+
dpl --provider=elasticbeanstalk --access-key-id=<access-key-id> --secret-access-key="<secret-access-key>" --app="example-app-name" --env="example-app-environment" --region="us-west-2"
|
|
371
|
+
|
|
346
372
|
### OpsWorks:
|
|
347
373
|
|
|
348
374
|
#### Options:
|
|
@@ -350,9 +376,11 @@ It is possible to set file-specific `Cache-Control` and `Expires` headers using
|
|
|
350
376
|
* **access-key-id**: AWS Access Key ID. Can be obtained from [here](https://console.aws.amazon.com/iam/home?#security_credential).
|
|
351
377
|
* **secret-access-key**: AWS Secret Key. Can be obtained from [here](https://console.aws.amazon.com/iam/home?#security_credential).
|
|
352
378
|
* **app-id**: The app ID.
|
|
379
|
+
* **instance-ids**: An instance id. (Use this option multiple times to specify multiple instance ids. Default: [])
|
|
380
|
+
* **layer-ids**: A layer id. (Use this option multiple times to specify multiple layer ids. Default: [])
|
|
353
381
|
* **migrate**: Migrate the database. (Default: false)
|
|
354
382
|
* **wait-until-deployed**: Wait until the app is deployed and return the deployment status. (Default: false)
|
|
355
|
-
* **custom_json**: Override custom_json options. If using this, default configuration will be overriden. See the code [here](https://github.com/travis-ci/dpl/blob/master/lib/dpl/provider/ops_works.rb#
|
|
383
|
+
* **custom_json**: Override custom_json options. If using this, default configuration will be overriden. See the code [here](https://github.com/travis-ci/dpl/blob/master/lib/dpl/provider/ops_works.rb#L43). More about `custom_json` [here](http://docs.aws.amazon.com/opsworks/latest/userguide/workingcookbook-json.html).
|
|
356
384
|
|
|
357
385
|
#### Environment variables:
|
|
358
386
|
|
|
@@ -362,6 +390,7 @@ It is possible to set file-specific `Cache-Control` and `Expires` headers using
|
|
|
362
390
|
#### Examples:
|
|
363
391
|
|
|
364
392
|
dpl --provider=opsworks --access-key-id=<access-key-id> --secret-access-key=<secret-access-key> --app-id=<app-id> --migrate --wait-until-deployed
|
|
393
|
+
dpl --provider=opsworks --access-key-id=<access-key-id> --secret-access-key=<secret-access-key> --app-id=<app-id> --layer-ids=<layer-id>
|
|
365
394
|
|
|
366
395
|
### Anynines:
|
|
367
396
|
|
|
@@ -557,30 +586,6 @@ For accounts using two factor authentication, you have to use an oauth token as
|
|
|
557
586
|
dpl --provider=gcs --access-key-id=<access-key-id> --secret-access-key=<secret-access-key> --bucket=<bucket> --detect-encoding --cache_control=max-age=99999
|
|
558
587
|
dpl --provider=gcs --access-key-id=<access-key-id> --secret-access-key=<secret-access-key> --bucket=<bucket> --local-dir=BUILD --upload-dir=BUILDS
|
|
559
588
|
|
|
560
|
-
### Elastic Beanstalk:
|
|
561
|
-
|
|
562
|
-
#### Options:
|
|
563
|
-
|
|
564
|
-
* **access-key-id**: AWS Access Key ID. Can be obtained from [here](https://console.aws.amazon.com/iam/home?#security_credential).
|
|
565
|
-
* **secret-access-key**: AWS Secret Key. Can be obtained from [here](https://console.aws.amazon.com/iam/home?#security_credential).
|
|
566
|
-
* **region**: AWS Region the Elastic Beanstalk app is running in. Defaults to 'us-east-1'. Please be aware that this must match the region of the elastic beanstalk app.
|
|
567
|
-
* **app**: Elastic Beanstalk application name.
|
|
568
|
-
* **env**: Elastic Beanstalk environment name which will be updated.
|
|
569
|
-
* **zip_file**: The zip file that you want to deploy. _**Note:**_ you also need to use the `skip_cleanup` or the zip file you are trying to upload will be removed during cleanup.
|
|
570
|
-
* **bucket_name**: Bucket name to upload app to.
|
|
571
|
-
* **bucket_path**: Location within Bucket to upload app to.
|
|
572
|
-
* **only_create_app_version**: only create the app version, don't actually deploy it.
|
|
573
|
-
|
|
574
|
-
#### Environment variables:
|
|
575
|
-
|
|
576
|
-
* **ELASTIC_BEANSTALK_ENV**: Elastic Beanstalk environment name which will be updated. Is only used if `env` option is omitted.
|
|
577
|
-
* **ELASTIC_BEANSTALK_LABEL**: Label name of the new version.
|
|
578
|
-
* **ELASTIC_BEANSTALK_DESCRIPTION**: Description of the new version. Defaults to the last commit message.
|
|
579
|
-
|
|
580
|
-
#### Examples:
|
|
581
|
-
|
|
582
|
-
dpl --provider=elasticbeanstalk --access-key-id=<access-key-id> --secret-access-key="<secret-access-key>" --app="example-app-name" --env="example-app-environment" --region="us-west-2"
|
|
583
|
-
|
|
584
589
|
### BitBalloon:
|
|
585
590
|
|
|
586
591
|
#### Options:
|
|
@@ -622,6 +627,37 @@ For accounts using two factor authentication, you have to use an oauth token as
|
|
|
622
627
|
dpl --provider=packagecloud --username=packageuser --token=t0k3n --repository=myrepo --dist=ubuntu/precise
|
|
623
628
|
dpl --provider=packagecloud --username=packageuser --token=t0k3n --repository=myrepo --local-dir="${TRAVIS_BUILD_DIR}/pkgs" --dist=ubuntu/precise
|
|
624
629
|
|
|
630
|
+
### Catalyze:
|
|
631
|
+
|
|
632
|
+
#### Options:
|
|
633
|
+
|
|
634
|
+
* **target**: Required. The git remote repository to deploy to.
|
|
635
|
+
* **path**: Optional. If using the skip_cleanup option to deploy from current file state, you can optionally specify the pathspec for the files to deploy. If not specified then all files are deployed.
|
|
636
|
+
|
|
637
|
+
#### Examples:
|
|
638
|
+
|
|
639
|
+
dpl --provider=catalyze --target=ssh://git@git.catalyzeapps.com:2222/app1234.git
|
|
640
|
+
dpl --provider=catalyze --target=ssh://git@git.catalyzeapps.com:2222/app1234.git --skip_cleanup=true
|
|
641
|
+
dpl --provider=catalyze --target=ssh://git@git.catalyzeapps.com:2222/app1234.git --skip_cleanup=true --path=build
|
|
642
|
+
|
|
643
|
+
|
|
644
|
+
#### Setup:
|
|
645
|
+
|
|
646
|
+
1. Get the deployment target for Catalyze:
|
|
647
|
+
a. Make sure your catalyze environment is [associated](https://resources.catalyze.io/paas/paas-cli-reference/#associate).
|
|
648
|
+
b. Get the git remote by running ```git remote -v``` from within the associated repo.
|
|
649
|
+
2. Setup a deployment key to Catalyze for Travis CI:
|
|
650
|
+
a. Install the travis-ci cli.
|
|
651
|
+
b. Get the public SSH key for your travis project and save it to a file by running ```travis pubkey > travis.pub```
|
|
652
|
+
c. Add the key as a deploy key using the catalyze cli within the associated repo. For example: ```catalyze deploy-keys add travisci ./travis.pub code-1```
|
|
653
|
+
3. Setup Catalyze as a known host for Travis CI:
|
|
654
|
+
a. List your known hosts by running ```cat ~/.ssh/known_hosts```
|
|
655
|
+
b. Find and copy the line from known_hosts that includes the git remote found in step #1. It'll look something like "[git.catalyzeapps.com]:2222 ecdsa-sha2-nistp256 BBBB12abZmKlLXNo..."
|
|
656
|
+
c. Update your `before_deploy` step in `.travis.yml` to update the `known_hosts` file:
|
|
657
|
+
```
|
|
658
|
+
before_deploy: echo "[git.catalyzeapps.com]:2222 ecdsa-sha2-nistp256 BBBB12abZmKlLXNo..." >> ~/.ssh/known_hosts
|
|
659
|
+
```
|
|
660
|
+
|
|
625
661
|
### Chef Supermarket:
|
|
626
662
|
|
|
627
663
|
#### Options:
|
|
@@ -741,6 +777,18 @@ and your testers can start testing your app.
|
|
|
741
777
|
|
|
742
778
|
dpl --provider=codedeploy --access-key-id=<aws access key> --secret_access_key=<aws secret access key> --application=<application name> --deployment_group=<deployment group> --revision_type=<s3/github> --commit_id=<commit ID> --repository=<repo name> --region=<AWS availability zone> --wait-until-deployed=<true>
|
|
743
779
|
|
|
780
|
+
### ExoScale:
|
|
781
|
+
|
|
782
|
+
#### Options:
|
|
783
|
+
|
|
784
|
+
* **email**: ExoScale email or Organization ID.
|
|
785
|
+
* **password**: ExoScale password.
|
|
786
|
+
* **deployment**: ExoScale Deployment. Follows the format "APP_NAME/DEP_NAME".
|
|
787
|
+
|
|
788
|
+
#### Examples:
|
|
789
|
+
|
|
790
|
+
dpl --provider=exoscale --email=<email> --password<password> --deployment=`APP_NAME/DEP_NAME`
|
|
791
|
+
|
|
744
792
|
### Scalingo:
|
|
745
793
|
|
|
746
794
|
#### Options:
|
|
@@ -818,7 +866,7 @@ In order to use this provider, please make sure you have the [App Engine Admin A
|
|
|
818
866
|
#### Examples:
|
|
819
867
|
|
|
820
868
|
dpl --provider=firebase --token=<token> --project=<project>
|
|
821
|
-
|
|
869
|
+
|
|
822
870
|
|
|
823
871
|
|
|
824
872
|
### Surge.sh
|
|
@@ -826,9 +874,9 @@ In order to use this provider, please make sure you have the [App Engine Admin A
|
|
|
826
874
|
#### Options:
|
|
827
875
|
|
|
828
876
|
* **project** Path to project folder relative to repo root. Defaults to repo root if not set.
|
|
829
|
-
* **domain** Domain to publish to. Can be omitted if domain is set in the `CNAME` file in the project folder.
|
|
877
|
+
* **domain** Domain to publish to. Can be omitted if domain is set in the `CNAME` file in the project folder.
|
|
878
|
+
|
|
830
879
|
|
|
831
|
-
|
|
832
880
|
#### Environment variables:
|
|
833
881
|
|
|
834
882
|
* **SURGE_LOGIN**: Set it to the email address you use with Surge
|
|
@@ -836,4 +884,4 @@ In order to use this provider, please make sure you have the [App Engine Admin A
|
|
|
836
884
|
|
|
837
885
|
#### Example:
|
|
838
886
|
dpl --provider=surge --project=<project-path> --domain=<domain-name>
|
|
839
|
-
|
|
887
|
+
|
data/dpl.gemspec
CHANGED
|
@@ -20,9 +20,9 @@ Gem::Specification.new do |s|
|
|
|
20
20
|
s.add_development_dependency 'rspec-its'
|
|
21
21
|
s.add_development_dependency 'rake'
|
|
22
22
|
s.add_development_dependency 'json', '1.8.1'
|
|
23
|
+
s.add_development_dependency 'tins', '~> 1.6.0', '>= 1.6.0'
|
|
23
24
|
s.add_development_dependency 'coveralls'
|
|
24
25
|
|
|
25
|
-
|
|
26
26
|
# prereleases from Travis CI
|
|
27
27
|
if ENV['CI']
|
|
28
28
|
digits = s.version.to_s.split '.'
|
data/lib/dpl/provider/appfog.rb
CHANGED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
module DPL
|
|
2
|
+
class Provider
|
|
3
|
+
class Catalyze < Provider
|
|
4
|
+
def config
|
|
5
|
+
{
|
|
6
|
+
# the git repository to deploy to
|
|
7
|
+
"target" => options[:target] || context.env['CATALYZE_TARGET'],
|
|
8
|
+
# the pathspec for files to add to git for deployment e.g. your build directory. defaults to all files.
|
|
9
|
+
"path" => options[:path] || context.env['CATALYZE_PATH'] || '.'
|
|
10
|
+
}
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def needs_key?
|
|
14
|
+
false
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def check_app
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def check_auth
|
|
21
|
+
error "Missing Catalyze target" unless config['target']
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def push_app
|
|
25
|
+
log "Deploying to Catalyze '#{config['target']}'"
|
|
26
|
+
|
|
27
|
+
if options[:skip_cleanup]
|
|
28
|
+
# create commit message
|
|
29
|
+
build_num = context.env["TRAVIS_BUILD_NUMBER"]
|
|
30
|
+
commit = context.env["TRAVIS_COMMIT"]
|
|
31
|
+
repo_slug = context.env["TRAVIS_REPO_SLUG"]
|
|
32
|
+
branch = context.env["TRAVIS_BRANCH"]
|
|
33
|
+
if build_num && commit && repo_slug && branch
|
|
34
|
+
commit_message = "Build ##{build_num} (#{commit}) of #{repo_slug}@#{branch}"
|
|
35
|
+
else
|
|
36
|
+
commit_message = "Local build"
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
log "Using build files for deployment"
|
|
40
|
+
context.shell "git checkout HEAD"
|
|
41
|
+
context.shell "git add #{config["path"]} --all --force"
|
|
42
|
+
context.shell "git commit -m \"#{commit_message}\" --quiet"
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
context.shell "git push --force #{config['target']} HEAD:master"
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -6,6 +6,8 @@ module DPL
|
|
|
6
6
|
# https://github.com/opscode/chef/blob/11.16.4/lib/chef/knife/cookbook_site_share.rb
|
|
7
7
|
|
|
8
8
|
# Compatibility with ruby 1.9
|
|
9
|
+
requires 'rack', version: '< 2.0'
|
|
10
|
+
requires 'mime-types', version: '~> 1.16'
|
|
9
11
|
requires 'chef', version: '< 12.0'
|
|
10
12
|
requires 'chef', load: 'chef/config'
|
|
11
13
|
requires 'chef', load: 'chef/cookbook_loader'
|
data/lib/dpl/provider/deis.rb
CHANGED
|
@@ -81,7 +81,7 @@ module DPL
|
|
|
81
81
|
end
|
|
82
82
|
|
|
83
83
|
def push_app
|
|
84
|
-
unless context.shell "git push #{verbose_flag} deis HEAD:refs/heads/master -f 2>&1 | tr -dc '[:alnum:][:space:][:punct:]' | sed -E 's/remote: (\\[1G)+//' | sed 's/\\[K$//'"
|
|
84
|
+
unless context.shell "git push #{verbose_flag} deis HEAD:refs/heads/master -f 2>&1 | tr -dc '[:alnum:][:space:][:punct:]' | sed -E 's/remote: (\\[1G)+//' | sed 's/\\[K$//'; exit ${PIPESTATUS[1]}"
|
|
85
85
|
error 'Deploying application failed.'
|
|
86
86
|
end
|
|
87
87
|
end
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
require 'json'
|
|
2
|
+
require 'net/http'
|
|
3
|
+
require 'net/https'
|
|
4
|
+
|
|
5
|
+
module DPL
|
|
6
|
+
class Provider
|
|
7
|
+
class ExoScale < Provider
|
|
8
|
+
attr_accessor :app_name
|
|
9
|
+
attr_accessor :dep_name
|
|
10
|
+
|
|
11
|
+
def initialize(context, options)
|
|
12
|
+
super
|
|
13
|
+
option(:email) && option(:password) && option(:deployment)
|
|
14
|
+
@app_name, @dep_name = options[:deployment].split('/')
|
|
15
|
+
|
|
16
|
+
@http = Net::HTTP.new('api.app.exo.io', 443)
|
|
17
|
+
@http.use_ssl = true
|
|
18
|
+
|
|
19
|
+
@tokenHttp = Net::HTTP.new('portal.exoscale.ch', 443)
|
|
20
|
+
@tokenHttp.use_ssl = true
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def check_auth
|
|
24
|
+
headers_with_token
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def check_app
|
|
28
|
+
response = api_call('GET', "/app/#{ app_name }/deployment/#{ dep_name }")
|
|
29
|
+
error('application check failed') if response.code != '200'
|
|
30
|
+
@repository = JSON.parse(response.body)["branch"]
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def setup_key(file)
|
|
34
|
+
data = { 'key' => File.read(file).chomp }
|
|
35
|
+
response = api_call('POST', "/user/#{ user['username'] }/key", JSON.dump(data))
|
|
36
|
+
error('adding key failed') if response.code != '200'
|
|
37
|
+
key = JSON.parse response.body
|
|
38
|
+
@ssh_key_id = key['key_id']
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def remove_key
|
|
42
|
+
response = api_call('DELETE', "/user/#{ user['username']}/key/#{ @ssh_key_id }")
|
|
43
|
+
error('key removal failed') if response.code != '204'
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def push_app
|
|
47
|
+
branch = (dep_name == 'default') ? 'master' : dep_name
|
|
48
|
+
context.shell "git push #{ @repository } HEAD:#{ branch } -f"
|
|
49
|
+
deploy_app
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
private
|
|
53
|
+
|
|
54
|
+
def get_token
|
|
55
|
+
request = Net::HTTP::Post.new '/api/apps/token'
|
|
56
|
+
request.basic_auth options[:email], options[:password]
|
|
57
|
+
response = @tokenHttp.request(request)
|
|
58
|
+
error('authorization failed') if response.code != '200'
|
|
59
|
+
return JSON.parse response.body
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def headers_with_token(options = {})
|
|
63
|
+
@token = get_token if options[:new_token] || @token.nil?
|
|
64
|
+
return {
|
|
65
|
+
'Authorization' => %Q|cc_auth_token="#{ @token['token'] }"|,
|
|
66
|
+
'Content-Type' => 'application/json'
|
|
67
|
+
}
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def get_headers
|
|
71
|
+
headers = headers_with_token
|
|
72
|
+
response = api_call('GET', '/user/', nil, headers)
|
|
73
|
+
return headers if response.code == '200'
|
|
74
|
+
|
|
75
|
+
return headers_with_token :new_token => true
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def api_call(method, path, data = nil, headers = nil)
|
|
79
|
+
return @http.send_request(method, path, data, headers || get_headers)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def deploy_app
|
|
83
|
+
data = {'version' => -1}
|
|
84
|
+
response = api_call('PUT', "/app/#{ app_name }/deployment/#{ dep_name }", JSON.dump(data))
|
|
85
|
+
error('deployment failed - the deployment is already deploying') if response.code != '200'
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def user
|
|
89
|
+
if @user.nil?
|
|
90
|
+
response = api_call('GET', '/user/')
|
|
91
|
+
error('can not find the user') if response.code != '200'
|
|
92
|
+
users = JSON.parse response.body
|
|
93
|
+
@user = users[0]
|
|
94
|
+
end
|
|
95
|
+
return @user
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
@@ -3,15 +3,18 @@ require 'timeout'
|
|
|
3
3
|
module DPL
|
|
4
4
|
class Provider
|
|
5
5
|
class OpsWorks < Provider
|
|
6
|
-
requires 'aws-sdk
|
|
6
|
+
requires 'aws-sdk', version: '~> 2'
|
|
7
7
|
experimental 'AWS OpsWorks'
|
|
8
8
|
|
|
9
|
-
def
|
|
10
|
-
@
|
|
9
|
+
def opsworks
|
|
10
|
+
@opsworks ||= Aws::OpsWorks::Client.new(opsworks_options)
|
|
11
11
|
end
|
|
12
12
|
|
|
13
|
-
def
|
|
14
|
-
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
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 =
|
|
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
|
|
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
|
data/lib/dpl/provider/s3.rb
CHANGED
|
@@ -52,7 +52,8 @@ module DPL
|
|
|
52
52
|
opts[:expires] = get_option_value_by_filename(options[:expires], filename) if options[:expires]
|
|
53
53
|
unless File.directory?(filename)
|
|
54
54
|
log "uploading #{filename.inspect} with #{opts.inspect}"
|
|
55
|
-
api.bucket(option(:bucket)).object(upload_path(filename)).upload_file(filename, opts)
|
|
55
|
+
result = api.bucket(option(:bucket)).object(upload_path(filename)).upload_file(filename, opts)
|
|
56
|
+
warn "error while uploading #{filename.inspect}" unless result
|
|
56
57
|
end
|
|
57
58
|
end
|
|
58
59
|
end
|
data/lib/dpl/provider.rb
CHANGED
|
@@ -13,6 +13,7 @@ module DPL
|
|
|
13
13
|
autoload :Bintray, 'dpl/provider/bintray'
|
|
14
14
|
autoload :BitBalloon, 'dpl/provider/bitballoon'
|
|
15
15
|
autoload :Boxfuse, 'dpl/provider/boxfuse'
|
|
16
|
+
autoload :Catalyze, 'dpl/provider/catalyze'
|
|
16
17
|
autoload :ChefSupermarket, 'dpl/provider/chef_supermarket'
|
|
17
18
|
autoload :Cloud66, 'dpl/provider/cloud66'
|
|
18
19
|
autoload :CloudFiles, 'dpl/provider/cloud_files'
|
data/lib/dpl/version.rb
CHANGED
|
@@ -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
|
data/spec/provider/deis_spec.rb
CHANGED
|
@@ -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
|
+
"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[1]}"
|
|
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
|
|
@@ -1,91 +1,127 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
|
-
require 'aws-sdk
|
|
2
|
+
require 'aws-sdk'
|
|
3
3
|
require 'dpl/provider'
|
|
4
4
|
require 'dpl/provider/ops_works'
|
|
5
5
|
|
|
6
6
|
describe DPL::Provider::OpsWorks do
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
subject :provider do
|
|
9
|
+
described_class.new(DummyContext.new, :access_key_id => 'qwertyuiopasdfghjklz', :secret_access_key => 'qwertyuiopasdfghjklzqwertyuiopasdfghjklz')
|
|
10
10
|
end
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
describe '#opsworks_options' do
|
|
13
|
+
context 'without region' do
|
|
14
|
+
example do
|
|
15
|
+
options = provider.opsworks_options
|
|
16
|
+
expect(options[:region]).to eq('us-east-1')
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
context 'with region' do
|
|
21
|
+
example do
|
|
22
|
+
region = 'us-west-1'
|
|
23
|
+
provider.options.update(:region => region)
|
|
24
|
+
options = provider.opsworks_options
|
|
25
|
+
expect(options[:region]).to eq(region)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
14
28
|
end
|
|
15
29
|
|
|
16
30
|
describe "#check_auth" do
|
|
17
31
|
example do
|
|
18
|
-
expect(provider).to receive(:setup_auth)
|
|
19
32
|
expect(provider).to receive(:log).with('Logging in with Access Key: ****************jklz')
|
|
20
33
|
provider.check_auth
|
|
21
34
|
end
|
|
22
35
|
end
|
|
23
36
|
|
|
24
|
-
describe "#setup_auth" do
|
|
25
|
-
example do
|
|
26
|
-
expect(AWS).to receive(:config).with(:access_key_id => 'qwertyuiopasdfghjklz', :secret_access_key => 'qwertyuiopasdfghjklzqwertyuiopasdfghjklz').once.and_call_original
|
|
27
|
-
provider.setup_auth
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
|
|
31
37
|
describe "#needs_key?" do
|
|
32
38
|
example do
|
|
33
39
|
expect(provider.needs_key?).to eq(false)
|
|
34
40
|
end
|
|
35
41
|
end
|
|
36
42
|
|
|
37
|
-
describe
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
expect(provider).to receive(:current_sha).and_return('sha')
|
|
42
|
-
expect(provider.api).to receive(:client).and_return(client)
|
|
43
|
-
expect(provider.context.env).to receive(:[]).with('TRAVIS_BUILD_NUMBER').and_return('123')
|
|
44
|
-
end
|
|
43
|
+
describe DPL::Provider::OpsWorks do
|
|
44
|
+
access_key_id = 'someaccesskey'
|
|
45
|
+
secret_access_key = 'somesecretaccesskey'
|
|
46
|
+
region = 'us-east-1'
|
|
45
47
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
expect(client).to receive(:create_deployment).with(
|
|
52
|
-
stack_id: 'stack-id', app_id: 'app-id', command: {name: 'deploy'}, comment: 'Deploy build 123 via Travis CI', custom_json: custom_json
|
|
53
|
-
).and_return({})
|
|
54
|
-
provider.push_app
|
|
55
|
-
end
|
|
48
|
+
client_options = {
|
|
49
|
+
stub_responses: true,
|
|
50
|
+
region: region,
|
|
51
|
+
credentials: Aws::Credentials.new(access_key_id, secret_access_key)
|
|
52
|
+
}
|
|
56
53
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
stack_id: 'stack-id', app_id: 'app-id', command: {name: 'deploy'}, comment: 'Deploy build 123 via Travis CI', custom_json: custom_json_with_migrate
|
|
63
|
-
).and_return({})
|
|
64
|
-
provider.push_app
|
|
54
|
+
subject :provider do
|
|
55
|
+
described_class.new(DummyContext.new, {
|
|
56
|
+
access_key_id: access_key_id,
|
|
57
|
+
secret_access_key: secret_access_key
|
|
58
|
+
})
|
|
65
59
|
end
|
|
66
60
|
|
|
67
|
-
|
|
68
|
-
provider.
|
|
69
|
-
expect(client).to receive(:describe_apps).with(app_ids: ['app-id']).and_return({apps: [ops_works_app]})
|
|
70
|
-
expect(client).to receive(:create_deployment).and_return({deployment_id: 'deployment_id'})
|
|
71
|
-
expect(client).to receive(:describe_deployments).with({deployment_ids: ['deployment_id']}).and_return({deployments: [status: 'running']}, {deployments: [status: 'successful']})
|
|
72
|
-
provider.push_app
|
|
61
|
+
before :each do
|
|
62
|
+
expect(provider).to receive(:opsworks_options).and_return(client_options)
|
|
73
63
|
end
|
|
74
64
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
).and_return({})
|
|
81
|
-
provider.push_app
|
|
65
|
+
describe '#opsworks' do
|
|
66
|
+
example do
|
|
67
|
+
expect(Aws::OpsWorks::Client).to receive(:new).with(client_options).once
|
|
68
|
+
provider.opsworks
|
|
69
|
+
end
|
|
82
70
|
end
|
|
83
|
-
end
|
|
84
71
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
72
|
+
describe "#push_app" do
|
|
73
|
+
let(:client) { provider.opsworks }
|
|
74
|
+
let(:ops_works_app) { {shortname: 'app', stack_id: 'stack-id'} }
|
|
75
|
+
before do
|
|
76
|
+
expect(provider).to receive(:current_sha).and_return('sha')
|
|
77
|
+
expect(provider.context.env).to receive(:[]).with('TRAVIS_BUILD_NUMBER').and_return('123')
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
let(:custom_json) { "{\"deploy\":{\"app\":{\"migrate\":false,\"scm\":{\"revision\":\"sha\"}}}}" }
|
|
81
|
+
example 'without :migrate option' do
|
|
82
|
+
provider.options.update(app_id: 'app-id')
|
|
83
|
+
expect(client).to receive(:describe_apps).with(app_ids: ['app-id']).and_return({apps: [ops_works_app]})
|
|
84
|
+
expect(client).to receive(:create_deployment).with(
|
|
85
|
+
stack_id: 'stack-id', app_id: 'app-id', command: {name: 'deploy'}, comment: 'Deploy build 123 via Travis CI', custom_json: custom_json
|
|
86
|
+
).and_return({})
|
|
87
|
+
provider.push_app
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
let(:custom_json_with_migrate) { "{\"deploy\":{\"app\":{\"migrate\":true,\"scm\":{\"revision\":\"sha\"}}}}" }
|
|
91
|
+
example 'with :migrate option' do
|
|
92
|
+
provider.options.update(app_id: 'app-id', migrate: true)
|
|
93
|
+
expect(client).to receive(:describe_apps).with(app_ids: ['app-id']).and_return({apps: [ops_works_app]})
|
|
94
|
+
expect(client).to receive(:create_deployment).with(
|
|
95
|
+
stack_id: 'stack-id', app_id: 'app-id', command: {name: 'deploy'}, comment: 'Deploy build 123 via Travis CI', custom_json: custom_json_with_migrate
|
|
96
|
+
).and_return({})
|
|
97
|
+
provider.push_app
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
example 'with :wait_until_deployed' do
|
|
101
|
+
provider.options.update(app_id: 'app-id', wait_until_deployed: true)
|
|
102
|
+
expect(client).to receive(:describe_apps).with(app_ids: ['app-id']).and_return({apps: [ops_works_app]})
|
|
103
|
+
expect(client).to receive(:create_deployment).and_return({deployment_id: 'deployment_id'})
|
|
104
|
+
expect(client).to receive(:describe_deployments).with({deployment_ids: ['deployment_id']}).and_return({deployments: [status: 'running']}, {deployments: [status: 'successful']})
|
|
105
|
+
provider.push_app
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
example 'with :instance-ids' do
|
|
109
|
+
provider.options.update(app_id: 'app-id', instance_ids: ['instance-id'])
|
|
110
|
+
expect(client).to receive(:describe_apps).with(app_ids: ['app-id']).and_return({apps: [ops_works_app]})
|
|
111
|
+
expect(client).to receive(:create_deployment).with(
|
|
112
|
+
stack_id: 'stack-id', app_id: 'app-id', instance_ids:['instance-id'], command: {name: 'deploy'}, comment: 'Deploy build 123 via Travis CI', custom_json: custom_json
|
|
113
|
+
).and_return({})
|
|
114
|
+
provider.push_app
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
example 'with :layer-ids' do
|
|
118
|
+
provider.options.update(app_id: 'app-id', layer_ids: ['layer-id'])
|
|
119
|
+
expect(client).to receive(:describe_apps).with(app_ids: ['app-id']).and_return({apps: [ops_works_app]})
|
|
120
|
+
expect(client).to receive(:create_deployment).with(
|
|
121
|
+
stack_id: 'stack-id', app_id: 'app-id', layer_ids:['layer-id'], command: {name: 'deploy'}, comment: 'Deploy build 123 via Travis CI', custom_json: custom_json
|
|
122
|
+
).and_return({})
|
|
123
|
+
provider.push_app
|
|
124
|
+
end
|
|
89
125
|
end
|
|
90
126
|
end
|
|
91
127
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: dpl
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.8.
|
|
4
|
+
version: 1.8.18
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Konstantin Haase
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2016-
|
|
11
|
+
date: 2016-08-08 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rspec
|
|
@@ -66,6 +66,26 @@ dependencies:
|
|
|
66
66
|
- - '='
|
|
67
67
|
- !ruby/object:Gem::Version
|
|
68
68
|
version: 1.8.1
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: tins
|
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - "~>"
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: 1.6.0
|
|
76
|
+
- - ">="
|
|
77
|
+
- !ruby/object:Gem::Version
|
|
78
|
+
version: 1.6.0
|
|
79
|
+
type: :development
|
|
80
|
+
prerelease: false
|
|
81
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
82
|
+
requirements:
|
|
83
|
+
- - "~>"
|
|
84
|
+
- !ruby/object:Gem::Version
|
|
85
|
+
version: 1.6.0
|
|
86
|
+
- - ">="
|
|
87
|
+
- !ruby/object:Gem::Version
|
|
88
|
+
version: 1.6.0
|
|
69
89
|
- !ruby/object:Gem::Dependency
|
|
70
90
|
name: coveralls
|
|
71
91
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -108,6 +128,7 @@ files:
|
|
|
108
128
|
- lib/dpl/provider/bintray.rb
|
|
109
129
|
- lib/dpl/provider/bitballoon.rb
|
|
110
130
|
- lib/dpl/provider/boxfuse.rb
|
|
131
|
+
- lib/dpl/provider/catalyze.rb
|
|
111
132
|
- lib/dpl/provider/chef_supermarket.rb
|
|
112
133
|
- lib/dpl/provider/cloud66.rb
|
|
113
134
|
- lib/dpl/provider/cloud_files.rb
|
|
@@ -117,6 +138,7 @@ files:
|
|
|
117
138
|
- lib/dpl/provider/divshot.rb
|
|
118
139
|
- lib/dpl/provider/elastic_beanstalk.rb
|
|
119
140
|
- lib/dpl/provider/engine_yard.rb
|
|
141
|
+
- lib/dpl/provider/exoscale.rb
|
|
120
142
|
- lib/dpl/provider/firebase.rb
|
|
121
143
|
- lib/dpl/provider/gae.rb
|
|
122
144
|
- lib/dpl/provider/gcs.rb
|
|
@@ -156,6 +178,7 @@ files:
|
|
|
156
178
|
- spec/provider/bintray_spec.rb
|
|
157
179
|
- spec/provider/bitballoon_spec.rb
|
|
158
180
|
- spec/provider/boxfuse_spec.rb
|
|
181
|
+
- spec/provider/catalyze_spec.rb
|
|
159
182
|
- spec/provider/chef_supermarket_spec.rb
|
|
160
183
|
- spec/provider/cloud66_spec.rb
|
|
161
184
|
- spec/provider/cloud_files_spec.rb
|
|
@@ -164,6 +187,7 @@ files:
|
|
|
164
187
|
- spec/provider/deis_spec.rb
|
|
165
188
|
- spec/provider/divshot_spec.rb
|
|
166
189
|
- spec/provider/elastic_beanstalk_spec.rb
|
|
190
|
+
- spec/provider/exoscale_spec.rb
|
|
167
191
|
- spec/provider/firebase_spec.rb
|
|
168
192
|
- spec/provider/gae_spec.rb
|
|
169
193
|
- spec/provider/gcs_spec.rb
|
|
@@ -223,6 +247,7 @@ test_files:
|
|
|
223
247
|
- spec/provider/bintray_spec.rb
|
|
224
248
|
- spec/provider/bitballoon_spec.rb
|
|
225
249
|
- spec/provider/boxfuse_spec.rb
|
|
250
|
+
- spec/provider/catalyze_spec.rb
|
|
226
251
|
- spec/provider/chef_supermarket_spec.rb
|
|
227
252
|
- spec/provider/cloud66_spec.rb
|
|
228
253
|
- spec/provider/cloud_files_spec.rb
|
|
@@ -231,6 +256,7 @@ test_files:
|
|
|
231
256
|
- spec/provider/deis_spec.rb
|
|
232
257
|
- spec/provider/divshot_spec.rb
|
|
233
258
|
- spec/provider/elastic_beanstalk_spec.rb
|
|
259
|
+
- spec/provider/exoscale_spec.rb
|
|
234
260
|
- spec/provider/firebase_spec.rb
|
|
235
261
|
- spec/provider/gae_spec.rb
|
|
236
262
|
- spec/provider/gcs_spec.rb
|