bosh-workspace 0.9.2 → 0.9.3
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/bosh-workspace.gemspec +5 -4
- data/lib/bosh/cli/commands/deployment_patch.rb +0 -1
- data/lib/bosh/cli/commands/prepare.rb +12 -11
- data/lib/bosh/workspace.rb +4 -3
- data/lib/bosh/workspace/credentials.rb +12 -5
- data/lib/bosh/workspace/git_credentials_provider.rb +80 -0
- data/lib/bosh/workspace/{git_remote_url.rb → helpers/git_protocol_helper.rb} +4 -8
- data/lib/bosh/workspace/helpers/project_deployment_helper.rb +10 -2
- data/lib/bosh/workspace/helpers/release_helper.rb +33 -7
- data/lib/bosh/workspace/manifest_builder.rb +6 -8
- data/lib/bosh/workspace/merge_tool.rb +73 -0
- data/lib/bosh/workspace/project_deployment.rb +20 -5
- data/lib/bosh/workspace/release.rb +103 -67
- data/lib/bosh/workspace/schemas/credentials.rb +22 -0
- data/lib/bosh/workspace/schemas/project_deployment.rb +14 -1
- data/lib/bosh/workspace/version.rb +1 -1
- data/spec/assets/bin/spruce +0 -0
- data/spec/assets/manifests-repo/deployments/foo.yml +1 -0
- data/spec/assets/manifests-repo/stubs/foo.yml +4 -0
- data/spec/commands/prepare_spec.rb +39 -12
- data/spec/credentials_spec.rb +8 -0
- data/spec/git_credentials_provider_spec.rb +82 -0
- data/spec/{git_remote_url_spec.rb → helpers/git_protocol_helper_spec.rb} +10 -11
- data/spec/helpers/project_deployment_helper_spec.rb +12 -1
- data/spec/helpers/release_helper_spec.rb +157 -73
- data/spec/manifest_builder_spec.rb +6 -5
- data/spec/merge_tool_spec.rb +98 -0
- data/spec/project_deployment_spec.rb +43 -1
- data/spec/release_spec.rb +369 -354
- data/spec/rugged_spec.rb +64 -0
- data/spec/schemas/credentials_spec.rb +22 -5
- data/spec/spec_helper.rb +1 -0
- metadata +35 -15
- data/lib/bosh/workspace/helpers/git_credentials_helper.rb +0 -111
- data/lib/bosh/workspace/helpers/spiff_helper.rb +0 -34
- data/spec/helpers/git_credentials_helper_spec.rb +0 -190
- data/spec/helpers/spiff_helper_spec.rb +0 -68
data/spec/credentials_spec.rb
CHANGED
@@ -23,6 +23,14 @@ module Bosh::Workspace
|
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
|
+
describe '#url_protocols' do
|
27
|
+
it "returns credentials when found multiple times" do
|
28
|
+
expect(subject).to receive(:git_protocol_from_url)
|
29
|
+
.with('foo').and_return(:https)
|
30
|
+
expect(subject.url_protocols).to eq('foo' => :https)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
26
34
|
describe '#perform_validation' do
|
27
35
|
context "valid" do
|
28
36
|
it "validates" do
|
@@ -0,0 +1,82 @@
|
|
1
|
+
module Bosh::Workspace
|
2
|
+
describe GitCredentialsProvider do
|
3
|
+
let!(:credentials_provider) { GitCredentialsProvider.new(file) }
|
4
|
+
let(:file) { "credentials_file" }
|
5
|
+
let(:file_exist) { true }
|
6
|
+
let(:valid) { true }
|
7
|
+
let(:url_protocols) { [] }
|
8
|
+
let(:url) { 'http://foo.com/bar.git' }
|
9
|
+
let(:user) { nil }
|
10
|
+
let(:result) { nil }
|
11
|
+
let(:allowed_types) { [:plain_text] }
|
12
|
+
let(:credentials) do
|
13
|
+
instance_double "Bosh::Workspace::Credentials",
|
14
|
+
:valid? => valid, url_protocols: url_protocols
|
15
|
+
end
|
16
|
+
|
17
|
+
subject { credentials_provider.callback.call url, user, allowed_types }
|
18
|
+
|
19
|
+
before do
|
20
|
+
allow(Credentials).to receive(:new).and_return(credentials)
|
21
|
+
allow(File).to receive(:exist?).and_return(file_exist)
|
22
|
+
allow(credentials).to receive(:find_by_url).with(url).and_return(result)
|
23
|
+
end
|
24
|
+
|
25
|
+
describe '#callback' do
|
26
|
+
context "with sshkey" do
|
27
|
+
let(:user) { 'git' }
|
28
|
+
let(:result) { { private_key: 'barkey' } }
|
29
|
+
let(:allowed_types) { [:ssh_key] }
|
30
|
+
|
31
|
+
it 'returns Rugged sshkey credentials' do
|
32
|
+
expect(Rugged::Credentials::SshKey).to receive(:new) do |args|
|
33
|
+
expect(args[:username]).to eq user
|
34
|
+
expect(IO.read(args[:privatekey])).to eq('barkey')
|
35
|
+
end; subject
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context "with username/password" do
|
40
|
+
let(:result) { { username: user, password: 'barpw' } }
|
41
|
+
let(:allowed_types) { [:plain_text] }
|
42
|
+
|
43
|
+
it 'returns Rugged user password credentials' do
|
44
|
+
expect(Rugged::Credentials::UserPassword).to receive(:new) do |args|
|
45
|
+
expect(args[:username]).to eq user
|
46
|
+
expect(args[:password]).to eq 'barpw'
|
47
|
+
end; subject
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context "without credentials file" do
|
52
|
+
let(:file_exist) { false }
|
53
|
+
it 'raises an error' do
|
54
|
+
expect{ subject }.to raise_error /credentials file does not exist/i
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
context "with invalid credentials file" do
|
59
|
+
let(:valid) { false }
|
60
|
+
before { expect(credentials).to receive(:errors) { ['foo error'] } }
|
61
|
+
it 'raises an error' do
|
62
|
+
expect{ subject }.to raise_error /is not valid/i
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
context "without credentials for given url" do
|
67
|
+
let(:result) { nil }
|
68
|
+
it 'raises an error' do
|
69
|
+
expect{ subject }.to raise_error /no credentials found/i
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
context "without protocol support" do
|
74
|
+
let(:url_protocols) { {"https://foo.com" => :https } }
|
75
|
+
before { expect(Rugged).to receive(:features).and_return([]) }
|
76
|
+
it 'raises an error' do
|
77
|
+
expect{ subject }.to raise_error /requires https support/i
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -1,38 +1,37 @@
|
|
1
1
|
module Bosh::Workspace
|
2
|
-
describe
|
3
|
-
|
4
|
-
|
2
|
+
describe GitProtocolHelper do
|
3
|
+
include GitProtocolHelper
|
4
|
+
describe '#git_protocol_from_url' do
|
5
|
+
subject { git_protocol_from_url(url) }
|
5
6
|
|
6
7
|
context 'git protocol' do
|
7
8
|
let(:url) { "git://example.com/foo" }
|
8
|
-
|
9
|
+
it { is_expected.to eq(:git) }
|
9
10
|
end
|
10
11
|
|
11
12
|
context 'https protocol' do
|
12
13
|
let(:url) { "https://example.com/foo" }
|
13
|
-
|
14
|
+
it { is_expected.to eq(:https) }
|
14
15
|
end
|
15
16
|
|
16
17
|
context 'http protocol' do
|
17
18
|
let(:url) { "http://example.com/foo" }
|
18
|
-
|
19
|
+
it { is_expected.to eq(:http) }
|
19
20
|
end
|
20
21
|
|
21
22
|
context 'ssh protocol style 1' do
|
22
23
|
let(:url) { "foo@example.com:foo" }
|
23
|
-
|
24
|
+
it { is_expected.to eq(:ssh) }
|
24
25
|
end
|
25
26
|
|
26
27
|
context 'ssh protocol style 2' do
|
27
28
|
let(:url) { "ssh://foo@example.com/foo" }
|
28
|
-
|
29
|
+
it { is_expected.to eq(:ssh) }
|
29
30
|
end
|
30
31
|
|
31
32
|
context 'unsupported protocol' do
|
32
33
|
let(:url) { "foo://foo@example.com/foo" }
|
33
|
-
it
|
34
|
-
expect { subject.protocol() }.to raise_error /unsupported protocol/i
|
35
|
-
end
|
34
|
+
it { is_expected.to eq(nil) }
|
36
35
|
end
|
37
36
|
end
|
38
37
|
end
|
@@ -23,7 +23,7 @@ describe Bosh::Workspace::ProjectDeploymentHelper do
|
|
23
23
|
describe "project_deployment?" do
|
24
24
|
subject { project_deployment_helper.project_deployment? }
|
25
25
|
let(:project_deployment_helper) { ProjectDeploymentHelperTester.new(director, deployment) }
|
26
|
-
let(:deployment) { File.join
|
26
|
+
let(:deployment) { File.join(work_dir, deployment_path) }
|
27
27
|
|
28
28
|
context "deployment" do
|
29
29
|
context "without associated project deployment" do
|
@@ -206,4 +206,15 @@ describe Bosh::Workspace::ProjectDeploymentHelper do
|
|
206
206
|
end
|
207
207
|
end
|
208
208
|
end
|
209
|
+
|
210
|
+
describe "#offline!" do
|
211
|
+
it "enforces offline mode" do
|
212
|
+
subject.offline!
|
213
|
+
expect(subject.offline?).to eq(true)
|
214
|
+
end
|
215
|
+
|
216
|
+
it "defaults to online" do
|
217
|
+
expect(subject.offline?).to eq(nil)
|
218
|
+
end
|
219
|
+
end
|
209
220
|
end
|
@@ -1,92 +1,176 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
module Bosh::Workspace
|
2
|
+
describe ReleaseHelper do
|
3
|
+
class ReleaseHelperTester
|
4
|
+
include ReleaseHelper
|
4
5
|
|
5
|
-
|
6
|
+
attr_reader :director, :work_dir
|
6
7
|
|
7
|
-
|
8
|
-
|
9
|
-
|
8
|
+
def initialize(director, work_dir)
|
9
|
+
@director = director
|
10
|
+
@work_dir = work_dir
|
11
|
+
end
|
10
12
|
end
|
11
|
-
end
|
12
|
-
|
13
|
-
subject { release_helper }
|
14
|
-
let(:release_helper) { ReleaseHelperTester.new(director, work_dir) }
|
15
|
-
let(:director) { instance_double('Bosh::Cli::Client::Director') }
|
16
|
-
let(:work_dir) { asset_dir("manifests-repo") }
|
17
13
|
|
18
|
-
|
19
|
-
let(:
|
20
|
-
|
21
|
-
|
14
|
+
subject { release_helper }
|
15
|
+
let(:release_helper) { ReleaseHelperTester.new(director, work_dir) }
|
16
|
+
let(:director) { instance_double('Bosh::Cli::Client::Director') }
|
17
|
+
let(:work_dir) { asset_dir("manifests-repo") }
|
22
18
|
|
23
|
-
|
24
|
-
|
25
|
-
.and_return(release_cmd)
|
19
|
+
def expect_option(subject, *args)
|
20
|
+
expect(subject).to receive(:add_option).with(*args)
|
26
21
|
end
|
27
22
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
23
|
+
context "with upload release command" do
|
24
|
+
let(:upload_release_cmd) do
|
25
|
+
instance_double "Bosh::Cli::Command::Release::UploadRelease"
|
26
|
+
end
|
27
|
+
|
28
|
+
before do
|
29
|
+
allow(Bosh::Cli::Command::Release::UploadRelease)
|
30
|
+
.to receive(:new).and_return(upload_release_cmd)
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "#release_upload_from_url" do
|
34
|
+
let(:url) { "http://example.com/release.tgz" }
|
35
|
+
subject { release_helper.release_upload_from_url(url) }
|
36
|
+
|
37
|
+
it "uploads release" do
|
38
|
+
expect(upload_release_cmd).to receive(:upload).with(url)
|
39
|
+
subject
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "#release_upload" do
|
44
|
+
let(:manifest) { "foo-1.yml" }
|
45
|
+
let(:tarball) { "foo-1.tgz" }
|
46
|
+
let(:release_dir) { "foo-release" }
|
47
|
+
let(:exist) { true }
|
48
|
+
let(:create_release_cmd) do
|
49
|
+
instance_double("Bosh::Cli::Command::Release::CreateRelease")
|
50
|
+
end
|
51
|
+
|
52
|
+
subject { release_helper.release_upload(manifest, release_dir) }
|
53
|
+
|
54
|
+
before do
|
55
|
+
allow(Bosh::Cli::Command::Release::CreateRelease)
|
56
|
+
.to receive(:new).and_return(create_release_cmd)
|
57
|
+
allow(File).to receive(:exist?).with(tarball).and_return(exist)
|
58
|
+
end
|
59
|
+
|
60
|
+
context "when offline" do
|
61
|
+
before { release_helper.offline! }
|
62
|
+
|
63
|
+
context "with final release tarball" do
|
64
|
+
it "uploads final release" do
|
65
|
+
expect(upload_release_cmd).to receive(:upload).with(tarball)
|
66
|
+
subject
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context "without final release tarball" do
|
71
|
+
let(:exist) { false }
|
72
|
+
it "raises an error" do
|
73
|
+
expect{subject}.to raise_error /tarball missing.+#{tarball}/
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
context "when online" do
|
79
|
+
context "with final release tarball" do
|
80
|
+
it "uploads final release" do
|
81
|
+
expect(upload_release_cmd).to receive(:upload).with(tarball)
|
82
|
+
subject
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
context "without final release tarball" do
|
87
|
+
let(:exist) { false }
|
88
|
+
it "creates and uploads final release" do
|
89
|
+
expect_option(create_release_cmd, :with_tarball, true)
|
90
|
+
expect_option(create_release_cmd, :dir, release_dir)
|
91
|
+
expect(create_release_cmd).to receive(:create).with(manifest)
|
92
|
+
expect(upload_release_cmd).to receive(:upload).with(tarball)
|
93
|
+
subject
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
34
98
|
end
|
35
|
-
end
|
36
99
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
100
|
+
describe "#release_uploaded?" do
|
101
|
+
let(:releases) { { "versions" => %w(1 2 3) } }
|
102
|
+
subject { release_helper.release_uploaded?("foo", version) }
|
103
|
+
before do
|
104
|
+
expect(director).to receive(:get_release)
|
105
|
+
.with("foo").and_return(releases)
|
106
|
+
end
|
107
|
+
|
108
|
+
context "release exists" do
|
109
|
+
let(:version) { 2 }
|
110
|
+
it { should be true }
|
111
|
+
end
|
112
|
+
|
113
|
+
context "release not found" do
|
114
|
+
let(:version) { "8" }
|
115
|
+
it { should be false }
|
116
|
+
end
|
43
117
|
end
|
44
118
|
|
45
|
-
|
46
|
-
let(:
|
47
|
-
|
48
|
-
end
|
119
|
+
describe "#release_dir" do
|
120
|
+
let(:releases_dir) { File.join(work_dir, ".releases") }
|
121
|
+
subject { release_helper.releases_dir }
|
49
122
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
end
|
55
|
-
|
56
|
-
describe "#release_dir" do
|
57
|
-
let(:releases_dir) { File.join(work_dir, ".releases") }
|
58
|
-
subject { release_helper.releases_dir }
|
59
|
-
|
60
|
-
before do
|
61
|
-
expect(FileUtils).to receive(:mkdir_p).once
|
62
|
-
.with(releases_dir).and_return([releases_dir])
|
63
|
-
end
|
64
|
-
|
65
|
-
it { should eq releases_dir }
|
66
|
-
|
67
|
-
it "memoizes" do
|
68
|
-
subject
|
69
|
-
expect(subject).to eq releases_dir
|
70
|
-
end
|
71
|
-
end
|
123
|
+
before do
|
124
|
+
expect(FileUtils).to receive(:mkdir_p).once
|
125
|
+
.with(releases_dir).and_return([releases_dir])
|
126
|
+
end
|
72
127
|
|
73
|
-
|
74
|
-
subject { release_helper.project_deployment_releases }
|
75
|
-
let(:release) { instance_double("Bosh::Workspace::Release") }
|
76
|
-
let(:release_data) { { name: "foo" } }
|
77
|
-
let(:releases) { [release_data, release_data] }
|
128
|
+
it { should eq releases_dir }
|
78
129
|
|
79
|
-
|
80
|
-
|
81
|
-
.to
|
82
|
-
|
130
|
+
it "memoizes" do
|
131
|
+
subject
|
132
|
+
expect(subject).to eq releases_dir
|
133
|
+
end
|
83
134
|
end
|
84
135
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
136
|
+
describe "#project_deployment_releases" do
|
137
|
+
subject { release_helper.project_deployment_releases }
|
138
|
+
let(:release) { instance_double("Bosh::Workspace::Release") }
|
139
|
+
let(:release_data) { { name: "foo" } }
|
140
|
+
let(:releases) { [release_data, release_data] }
|
141
|
+
let(:options) { { offline: offline } }
|
142
|
+
let(:offline) { nil }
|
143
|
+
let(:credentials_provider) do
|
144
|
+
instance_double('Bosh::Workspace::GitCredentialsProvider',
|
145
|
+
callback: :callback)
|
146
|
+
end
|
147
|
+
|
148
|
+
before do
|
149
|
+
expect(release_helper)
|
150
|
+
.to receive_message_chain("project_deployment.releases")
|
151
|
+
.and_return(releases)
|
152
|
+
expect(GitCredentialsProvider).to receive(:new).with(/.credentials.yml/)
|
153
|
+
.and_return(credentials_provider)
|
154
|
+
end
|
155
|
+
|
156
|
+
it "inits releases" do
|
157
|
+
expect(Release).to receive(:new).twice
|
158
|
+
.with(release_data, /\/.releases/, :callback, options)
|
159
|
+
.and_return(release)
|
160
|
+
expect(subject).to eq [release, release]
|
161
|
+
end
|
162
|
+
|
163
|
+
context "when offline" do
|
164
|
+
before { release_helper.offline! }
|
165
|
+
let(:offline) { true }
|
166
|
+
|
167
|
+
it "inits releases" do
|
168
|
+
expect(Release).to receive(:new).twice
|
169
|
+
.with(release_data, /\/.releases/, :callback, options)
|
170
|
+
.and_return(release)
|
171
|
+
expect(subject).to eq [release, release]
|
172
|
+
end
|
173
|
+
end
|
90
174
|
end
|
91
175
|
end
|
92
176
|
end
|
@@ -2,7 +2,8 @@ describe Bosh::Workspace::ManifestBuilder do
|
|
2
2
|
let(:project_deployment) { instance_double("Bosh::Workspace::Project_Deployment",
|
3
3
|
name: "bar",
|
4
4
|
templates: ["foo.yml"],
|
5
|
-
merged_file: ".deployments/foo.yml"
|
5
|
+
merged_file: ".deployments/foo.yml",
|
6
|
+
merge_tool: Bosh::Workspace::MergeTool.new)
|
6
7
|
}
|
7
8
|
let(:work_dir) { asset_dir("manifests-repo") }
|
8
9
|
|
@@ -20,7 +21,7 @@ describe Bosh::Workspace::ManifestBuilder do
|
|
20
21
|
end
|
21
22
|
|
22
23
|
describe "#merge_templates" do
|
23
|
-
subject { Bosh::Workspace::ManifestBuilder.new
|
24
|
+
subject { Bosh::Workspace::ManifestBuilder.new(project_deployment, work_dir) }
|
24
25
|
|
25
26
|
before do
|
26
27
|
allow(File).to receive(:exists?).with(/templates\//)
|
@@ -30,7 +31,7 @@ describe Bosh::Workspace::ManifestBuilder do
|
|
30
31
|
context "missing template" do
|
31
32
|
let(:template_exists) { false }
|
32
33
|
it "raises error" do
|
33
|
-
expect{ subject.merge_templates }.to raise_error(/does not exist/)
|
34
|
+
expect { subject.merge_templates }.to raise_error(/does not exist/)
|
34
35
|
end
|
35
36
|
end
|
36
37
|
|
@@ -47,14 +48,14 @@ describe Bosh::Workspace::ManifestBuilder do
|
|
47
48
|
context "no hidden dirs" do
|
48
49
|
let(:dir_exists) { false }
|
49
50
|
it "creates hidden dirs" do
|
50
|
-
expect(subject).to receive(:
|
51
|
+
expect(subject.merge_tool).to receive(:merge)
|
51
52
|
expect(Dir).to receive(:mkdir).with(/.stubs/)
|
52
53
|
subject.merge_templates
|
53
54
|
end
|
54
55
|
end
|
55
56
|
|
56
57
|
it "generates manifest with spiff" do
|
57
|
-
|
58
|
+
expect(subject.merge_tool).to receive(:merge) do |args|
|
58
59
|
if args.is_a?(Array)
|
59
60
|
expect(args.first).to match(/\/templates\/.+yml/)
|
60
61
|
expect(args.last).to match(/\.stubs\/.+yml/)
|