bosh-workspace 0.9.0.rc3 → 0.9.0.rc4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 51bf8a5f27e3c24ee4ef726151e656ddd79a15e6
4
- data.tar.gz: 1b12be1ab651f544abe8ed1ec01346425ecd8c8d
3
+ metadata.gz: 7a974316196c63756eb13d118715adee4cb23a54
4
+ data.tar.gz: f683bafb845d0d1f6fe837f0c99d3d9508c9d445
5
5
  SHA512:
6
- metadata.gz: f6a551fbb230b60f22a2fe19bbe304faca18751e7934591de500d0f1c092e2d83f05f300c456d3107acff5e2a69096c52cca95d778fc9f0bc2d1393a12b31015
7
- data.tar.gz: f7a83e2266fcbbac54d2794ad391ddc66fa478a20cba79b0e047086cd52cb8c582896d1e36e2e4fa1789bf9fd6aca1c6f3286ad72317c31d1781f48476ac48cf
6
+ metadata.gz: 94646d03fe1942ca890a41f1e43487d6f7fedcecb6fb16605f48d6fd34abbc78d3771bf6d5cc9750066ca5a4cbd6804d25d9bb736a7b7e4d111a47c7a2168df9
7
+ data.tar.gz: d88d409fdc34da7cc2b8bcf3112f89fd9e0a7871512e33a7f6f8f85f512b678a263dcd51051032bc2bdac9c437b835483d54fae58d3c703c942bc5ab8eeb2c6d
data/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  # Bosh workspace
2
- [![Build Status](https://img.shields.io/travis/cloudfoundry-incubator/bosh-workspace/master.svg?style=flat-square)](https://travis-ci.org/cloudfoundry-incubator/bosh-workspace) [![Test Coverage](https://img.shields.io/codeclimate/coverage/github/rkoster/bosh-workspace.svg?style=flat-square)](https://codeclimate.com/github/rkoster/bosh-workspace) [![Code Climate](https://img.shields.io/codeclimate/github/rkoster/bosh-workspace.svg?style=flat-square)](https://codeclimate.com/github/rkoster/bosh-workspace) [![Dependency Status](https://img.shields.io/gemnasium/cloudfoundry-incubator/bosh-workspace.svg?style=flat-square)](https://gemnasium.com/cloudfoundry-incubator/bosh-workspace)
2
+ [![Build Status](https://img.shields.io/travis/cloudfoundry-incubator/bosh-workspace/master.svg?style=flat-square)](https://travis-ci.org/cloudfoundry-incubator/bosh-workspace) [![Test Coverage](https://img.shields.io/codeclimate/coverage/github/rkoster/bosh-workspace.svg?style=flat-square)](https://codeclimate.com/github/rkoster/bosh-workspace) [![Code Climate](https://img.shields.io/codeclimate/github/rkoster/bosh-workspace.svg?style=flat-square)](https://codeclimate.com/github/rkoster/bosh-workspace) [![Dependency Status](https://img.shields.io/gemnasium/cloudfoundry-incubator/bosh-workspace.svg?style=flat-square)](https://gemnasium.com/cloudfoundry-incubator/bosh-workspace) [![Stories in Ready](https://img.shields.io/badge/tracker-waffle.io-blue.svg?style=flat-square)](https://waffle.io/cloudfoundry-incubator/bosh-workspace)
3
3
 
4
4
 
5
5
  This is a `bosh` cli plugin for creating reproducible and upgradable deployments.
@@ -95,6 +95,35 @@ git add . && git commit -m "Added cf-warden deployment"
95
95
  Congratulations you should now have a running Cloud Foundry.
96
96
  For further reference on how to start using it go to the [bosh-lite documentation](https://github.com/cloudfoundry/bosh-lite#try-your-cloud-foundry-deployment).
97
97
 
98
+ ### Using private boshreleases
99
+ When using a boshrelease from a location which requires authentication
100
+ a `.credentials.yml` file is required, located at the root of your boshworkspace.
101
+ Two types of authentication are supported: `username/password` and `sshkey`.
102
+
103
+ Example `.credentials.yml` file:
104
+ ```yaml
105
+ - url: https://github.com/example/top-secret-boshrelease.git
106
+ username: foo
107
+ password: bar
108
+ - url: ssh://git@github.com/example/super-secret-boshrelease.git
109
+ private_key: |
110
+ -----BEGIN RSA PRIVATE KEY-----
111
+ MIICXAIBAAKBgQDHFr+KICms+tuT1OXJwhCUmR2dKVy7psa8xzElSyzqx7oJyfJ1
112
+ JZyOzToj9T5SfTIq396agbHJWVfYphNahvZ/7uMXqHxf+ZH9BL1gk9Y6kCnbM5R6
113
+ 0gfwjyW1/dQPjOzn9N394zd2FJoFHwdq9Qs0wBugspULZVNRxq7veq/fzwIDAQAB
114
+ AoGBAJ8dRTQFhIllbHx4GLbpTQsWXJ6w4hZvskJKCLM/o8R4n+0W45pQ1xEiYKdA
115
+ Z/DRcnjltylRImBD8XuLL8iYOQSZXNMb1h3g5/UGbUXLmCgQLOUUlnYt34QOQm+0
116
+ KvUqfMSFBbKMsYBAoQmNdTHBaz3dZa8ON9hh/f5TT8u0OWNRAkEA5opzsIXv+52J
117
+ duc1VGyX3SwlxiE2dStW8wZqGiuLH142n6MKnkLU4ctNLiclw6BZePXFZYIK+AkE
118
+ xQ+k16je5QJBAN0TIKMPWIbbHVr5rkdUqOyezlFFWYOwnMmw/BKa1d3zp54VP/P8
119
+ +5aQ2d4sMoKEOfdWH7UqMe3FszfYFvSu5KMCQFMYeFaaEEP7Jn8rGzfQ5HQd44ek
120
+ lQJqmq6CE2BXbY/i34FuvPcKU70HEEygY6Y9d8J3o6zQ0K9SYNu+pcXt4lkCQA3h
121
+ jJQQe5uEGJTExqed7jllQ0khFJzLMx0K6tj0NeeIzAaGCQz13oo2sCdeGRHO4aDh
122
+ HH6Qlq/6UOV5wP8+GAcCQFgRCcB+hrje8hfEEefHcFpyKH+5g1Eu1k0mLrxK2zd+
123
+ 4SlotYRHgPCEubokb2S1zfZDWIXW3HmggnGgM949TlY=
124
+ -----END RSA PRIVATE KEY-----
125
+ ```
126
+
98
127
  ## Experimental
99
128
  ### dns support
100
129
  Dns support can be enabled by adding a `domain_name` property to your deployment.
data/Rakefile CHANGED
@@ -1,5 +1,56 @@
1
1
  require "bundler/gem_tasks"
2
2
  require "rspec/core/rake_task"
3
+ require "archive/zip"
4
+ require "rugged"
3
5
 
4
6
  task :default => :spec
5
7
  RSpec::Core::RakeTask.new
8
+
9
+ namespace :git_assets do
10
+ desc "Extract git assets used in specs to tmp/git_assets"
11
+ task :extract do
12
+ FileUtils.rm_rf(tmp_workdir) if File.exist?(tmp_workdir)
13
+ git_spec_assets.each do |name, file|
14
+ target = File.join(tmp_workdir, name)
15
+ Dir.mktmpdir(name) do |tmp_dir|
16
+ Archive::Zip.extract(file, tmp_dir)
17
+ Rugged::Repository.clone_at(tmp_dir, target)
18
+ end
19
+ puts "Extracted #{name}.zip"
20
+ end
21
+ puts "All git assets have been extracted into: #{tmp_workdir}"
22
+ end
23
+
24
+ desc "Update git assets with changes made in tmp/git_assets"
25
+ task :update do
26
+ tmp_workdirs.each do |name, dir|
27
+ archive = File.join(git_spec_assets_dir, "#{name}.zip")
28
+ Archive::Zip.archive(archive, dir)
29
+ puts "Updated #{name}.zip"
30
+ end
31
+ end
32
+
33
+ def tmp_workdir
34
+ File.join(project_root, "tmp/git_assets")
35
+ end
36
+
37
+ def tmp_workdirs
38
+ Dir["#{tmp_workdir}/*"].map do |file|
39
+ [ File.basename(file, ".*"), File.join(file, ".git") ]
40
+ end.to_h
41
+ end
42
+
43
+ def git_spec_assets_dir
44
+ File.join(project_root, "spec/assets")
45
+ end
46
+
47
+ def git_spec_assets
48
+ Dir[File.join(git_spec_assets_dir, "/*repo*.zip")].map do |file|
49
+ [ File.basename(file, ".*"), file ]
50
+ end.to_h
51
+ end
52
+
53
+ def project_root
54
+ File.dirname(__FILE__)
55
+ end
56
+ end
@@ -28,4 +28,5 @@ require "bosh/workspace/project_deployment"
28
28
  require "bosh/workspace/stub_file"
29
29
  require "bosh/workspace/deployment_patch"
30
30
  require "bosh/workspace/credentials"
31
+ require "bosh/workspace/git_remote_url"
31
32
  require "bosh/workspace/version"
@@ -0,0 +1,22 @@
1
+ module Bosh::Workspace
2
+ class GitRemoteUrl
3
+ def initialize(url)
4
+ @url = url
5
+ end
6
+
7
+ def protocol()
8
+ case @url
9
+ when /^git:/
10
+ return :git
11
+ when /^https:/
12
+ return :https
13
+ when /^http:/
14
+ return :http
15
+ when /(@.+:|^ssh:)/
16
+ return :ssh
17
+ else
18
+ raise "Unsupported protocol for remote git url: #{@url}"
19
+ end
20
+ end
21
+ end
22
+ end
@@ -16,11 +16,13 @@ module Bosh::Workspace
16
16
  def fetch_and_checkout(repo)
17
17
  url = repo.remotes['origin'].url
18
18
  repo.fetch('origin', REFSPEC, connection_options_for(repo, url))
19
- repo.checkout 'refs/remotes/origin/HEAD', strategy: :force
19
+ commit = repo.references['refs/remotes/origin/HEAD'].resolve.target_id
20
+ repo.checkout commit, strategy: :force
20
21
  end
21
22
 
22
23
  def connection_options_for(repo, url)
23
24
  return {} if check_connection(repo, url)
25
+ validate_url_protocol_support!(url)
24
26
 
25
27
  options = { credentials: require_credetials_for(url) }
26
28
  unless check_connection(repo, url, options)
@@ -67,6 +69,19 @@ module Bosh::Workspace
67
69
  end
68
70
  end
69
71
 
72
+ def validate_url_protocol_support!(url)
73
+ protocol = GitRemoteUrl.new(url).protocol
74
+ case protocol
75
+ when :git
76
+ err("Somthing is wrong, the git protocol does not support authentication")
77
+ when :https, :ssh
78
+ unless Rugged.features.include? protocol
79
+ say("Please reinstall Rugged gem with #{protocol} support: http://git.io/veiyJ")
80
+ err("Rugged requires #{protocol} support for: #{url}")
81
+ end
82
+ end
83
+ end
84
+
70
85
  def git_credentials_file
71
86
  File.join work_dir, '.credentials.yml'
72
87
  end
@@ -5,6 +5,7 @@ module Bosh::Workspace
5
5
  def initialize(release, releases_dir)
6
6
  @name = release["name"]
7
7
  @ref = release["ref"]
8
+ @path = release["path"]
8
9
  @spec_version = release["version"].to_s
9
10
  @git_url = release["git"]
10
11
  @repo_dir = File.join(releases_dir, @name)
@@ -46,7 +47,8 @@ module Bosh::Workspace
46
47
  end
47
48
 
48
49
  def releases_dir
49
- new_style_repo ? "releases/#{@name}" : "releases"
50
+ dir = new_style_repo ? "releases/#{@name}" : "releases"
51
+ @path ? File.join(@path, dir) : dir
50
52
  end
51
53
 
52
54
  def releases_tree
@@ -4,10 +4,11 @@ module Bosh::Workspace
4
4
  def validate(object)
5
5
  Membrane::SchemaParser.parse do
6
6
  [{
7
- "name" => String,
8
- "version" => ReleaseVersion.new,
9
- optional("ref") => enum(String),
10
- optional("git") => String,
7
+ "name" => String,
8
+ "version" => ReleaseVersion.new,
9
+ optional("path") => enum(String),
10
+ optional("ref") => enum(String),
11
+ optional("git") => String,
11
12
  }]
12
13
  end.validate object
13
14
  end
@@ -1,5 +1,5 @@
1
1
  module Bosh
2
2
  module Manifests
3
- VERSION = "0.9.0.rc3"
3
+ VERSION = "0.9.0.rc4"
4
4
  end
5
5
  end
@@ -0,0 +1,39 @@
1
+ module Bosh::Workspace
2
+ describe GitRemoteUrl do
3
+ describe '.protocol' do
4
+ subject { GitRemoteUrl.new(url) }
5
+
6
+ context 'git protocol' do
7
+ let(:url) { "git://example.com/foo" }
8
+ its(:protocol) { is_expected.to eq(:git) }
9
+ end
10
+
11
+ context 'https protocol' do
12
+ let(:url) { "https://example.com/foo" }
13
+ its(:protocol) { is_expected.to eq(:https) }
14
+ end
15
+
16
+ context 'http protocol' do
17
+ let(:url) { "http://example.com/foo" }
18
+ its(:protocol) { is_expected.to eq(:http) }
19
+ end
20
+
21
+ context 'ssh protocol style 1' do
22
+ let(:url) { "foo@example.com:foo" }
23
+ its(:protocol) { is_expected.to eq(:ssh) }
24
+ end
25
+
26
+ context 'ssh protocol style 2' do
27
+ let(:url) { "ssh://foo@example.com/foo" }
28
+ its(:protocol) { is_expected.to eq(:ssh) }
29
+ end
30
+
31
+ context 'unsupported protocol' do
32
+ let(:url) { "foo://foo@example.com/foo" }
33
+ it 'raises' do
34
+ expect { subject.protocol() }.to raise_error /unsupported protocol/i
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -15,6 +15,8 @@ module Bosh::Workspace
15
15
  let(:dir) { File.join(work_dir, '.releases', 'foo') }
16
16
  let(:repo) { instance_double 'Rugged::Repository' }
17
17
  let(:remote) { instance_double 'Rugged::Remote', url: url }
18
+ let(:protocol) { :http }
19
+ let(:git_url) { instance_double 'GitRemoteURL', protocol: protocol }
18
20
 
19
21
  before do
20
22
  allow(Rugged::Repository).to receive(:new).with(dir).and_return(repo)
@@ -22,9 +24,12 @@ module Bosh::Workspace
22
24
  allow(repo).to receive_message_chain("remotes.[]").and_return(remote)
23
25
  allow(repo).to receive_message_chain("remotes.create_anonymous")
24
26
  .with(url).and_return(remote)
27
+ allow(repo).to receive_message_chain("references.[].resolve.target_id")
28
+ .and_return(:commit_id)
25
29
  allow(remote).to receive(:check_connection).with(:fetch, Hash)
26
30
  .and_return(!auth_required, credentials_auth_valid)
27
- allow(repo).to receive(:checkout).with(/origin\/HEAD/, strategy: :force)
31
+ allow(repo).to receive(:checkout).with(:commit_id, strategy: :force)
32
+ allow(GitRemoteUrl).to receive(:new).and_return(git_url)
28
33
  end
29
34
 
30
35
  def expect_no_credentials
@@ -95,6 +100,26 @@ module Bosh::Workspace
95
100
  .with(url).and_return(creds_hash)
96
101
  end
97
102
 
103
+ context "without supported protocol" do
104
+ before do
105
+ expect(Rugged).to receive(:features).and_return([])
106
+ end
107
+
108
+ let(:protocol) { :https }
109
+
110
+ it "raises" do
111
+ expect { subject }.to raise_error /rugged requires https/i
112
+ end
113
+ end
114
+
115
+ context "with git protocol" do
116
+ let(:protocol) { :git }
117
+
118
+ it "raises" do
119
+ expect { subject }.to raise_error /not support authentication/i
120
+ end
121
+ end
122
+
98
123
  context "with sshkey" do
99
124
  let(:creds_hash) { { private_key: "foobarkey" } }
100
125
 
data/spec/release_spec.rb CHANGED
@@ -18,7 +18,6 @@ describe Bosh::Workspace::Release do
18
18
 
19
19
  describe "#update_repo" do
20
20
  subject do
21
- # puts `cd #{File.join(releases_dir, name)} && git checkout origin/HEAD && git log`
22
21
  Dir[File.join(releases_dir, name, "releases/**/foo*.yml")].to_s
23
22
  end
24
23
 
@@ -258,4 +257,41 @@ describe Bosh::Workspace::Release do
258
257
  its(:version) { should eq version.to_s }
259
258
  end
260
259
  end
260
+
261
+ context "given a release which is located in a subfolder" do
262
+ let(:repo) { extracted_asset_dir("foo", "foo-boshrelease-repo-subdir.zip") }
263
+ let(:release_data) do
264
+ { "name" => name, "version" => version, "git" => repo, "path" => "release" }
265
+ end
266
+
267
+ describe "#update_repo" do
268
+ subject do
269
+ Dir[File.join(releases_dir, name, "release/releases/**/*.yml")].to_s
270
+ end
271
+
272
+ context "latest version" do
273
+ before { release.update_repo }
274
+
275
+ let(:version) { "latest" }
276
+
277
+ it "checks out repo" do
278
+ expect(subject).to match(/release\/releases\/foo-12.yml/)
279
+ end
280
+ end
281
+ end
282
+
283
+ describe "attributes" do
284
+ let(:version) { "12" }
285
+ subject { release }
286
+ its(:name) { should eq name }
287
+ its(:git_url) { should eq repo }
288
+ its(:repo_dir) { should match(/\/#{name}$/) }
289
+ its(:manifest) { should match "release/releases/#{name}-#{version}.yml$" }
290
+ its(:name_version) { should eq "#{name}/#{version}" }
291
+ its(:version) { should eq version }
292
+ its(:manifest_file) do
293
+ should match(/\/release\/releases\/#{name}-#{version}.yml$/)
294
+ end
295
+ end
296
+ end
261
297
  end
@@ -1,7 +1,13 @@
1
1
  module Bosh::Workspace::Schemas
2
2
  describe Releases do
3
3
  let(:release) do
4
- {"name" => "foo", "version" => 1, "ref" => "cec3ec1", "git" => "example.com/git.git"}
4
+ {
5
+ "name" => "foo",
6
+ "version" => 1,
7
+ "path" => "release",
8
+ "ref" => "cec3ec1",
9
+ "git" => "example.com/git.git"
10
+ }
5
11
  end
6
12
 
7
13
  subject { Releases.new.validate(releases) }
@@ -32,5 +38,10 @@ module Bosh::Workspace::Schemas
32
38
  let(:releases) { [release.delete_if { |k| k == "git" }] }
33
39
  it { expect { subject }.to_not raise_error }
34
40
  end
41
+
42
+ context "optional git" do
43
+ let(:releases) { [release.delete_if { |k| k == "path" }] }
44
+ it { expect { subject }.to_not raise_error }
45
+ end
35
46
  end
36
47
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bosh-workspace
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0.rc3
4
+ version: 0.9.0.rc4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ruben Koster
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-04-01 00:00:00.000000000 Z
11
+ date: 2015-04-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bosh_cli
@@ -188,6 +188,7 @@ files:
188
188
  - lib/bosh/workspace.rb
189
189
  - lib/bosh/workspace/credentials.rb
190
190
  - lib/bosh/workspace/deployment_patch.rb
191
+ - lib/bosh/workspace/git_remote_url.rb
191
192
  - lib/bosh/workspace/helpers/dns_helper.rb
192
193
  - lib/bosh/workspace/helpers/git_credentials_helper.rb
193
194
  - lib/bosh/workspace/helpers/project_deployment_helper.rb
@@ -218,6 +219,7 @@ files:
218
219
  - spec/assets/dns/properties.yml
219
220
  - spec/assets/empty-manifests-repo/.keep
220
221
  - spec/assets/foo-boshrelease-repo-new-structure.zip
222
+ - spec/assets/foo-boshrelease-repo-subdir.zip
221
223
  - spec/assets/foo-boshrelease-repo-updated.zip
222
224
  - spec/assets/foo-boshrelease-repo.zip
223
225
  - spec/assets/foo-boshworkspace.zip
@@ -230,6 +232,7 @@ files:
230
232
  - spec/commands/project_deployment_spec.rb
231
233
  - spec/credentials_spec.rb
232
234
  - spec/deployment_patch_spec.rb
235
+ - spec/git_remote_url_spec.rb
233
236
  - spec/helpers/dns_helper_spec.rb
234
237
  - spec/helpers/git_credentials_helper_spec.rb
235
238
  - spec/helpers/project_deployment_helper_spec.rb
@@ -285,6 +288,7 @@ test_files:
285
288
  - spec/assets/dns/properties.yml
286
289
  - spec/assets/empty-manifests-repo/.keep
287
290
  - spec/assets/foo-boshrelease-repo-new-structure.zip
291
+ - spec/assets/foo-boshrelease-repo-subdir.zip
288
292
  - spec/assets/foo-boshrelease-repo-updated.zip
289
293
  - spec/assets/foo-boshrelease-repo.zip
290
294
  - spec/assets/foo-boshworkspace.zip
@@ -297,6 +301,7 @@ test_files:
297
301
  - spec/commands/project_deployment_spec.rb
298
302
  - spec/credentials_spec.rb
299
303
  - spec/deployment_patch_spec.rb
304
+ - spec/git_remote_url_spec.rb
300
305
  - spec/helpers/dns_helper_spec.rb
301
306
  - spec/helpers/git_credentials_helper_spec.rb
302
307
  - spec/helpers/project_deployment_helper_spec.rb