Skip to content

Commit cebbc85

Browse files
Marc Paquettegeofffranks
authored andcommitted
Add bosh properties/templates for syncing ASG data into policy-server
Signed-off-by: Geoff Franks <[email protected]>
1 parent ac10a48 commit cebbc85

File tree

10 files changed

+218
-9
lines changed

10 files changed

+218
-9
lines changed

.ruby-version

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
3.0.2

Gemfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@ source 'https://rubygems.org'
33
group :test do
44
gem "nokogiri", ">= 1.10.8"
55
gem 'rspec'
6-
gem 'bosh-template'
6+
gem 'bosh-template', ">= 2.2.1"
77
gem 'solargraph'
88
end

Gemfile.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ GEM
33
specs:
44
ast (2.4.0)
55
backport (1.1.2)
6-
bosh-template (2.1.0)
6+
bosh-template (2.2.1)
77
semi_semantic (~> 1.2.0)
88
diff-lcs (1.3)
99
htmlentities (4.3.4)
@@ -64,7 +64,7 @@ PLATFORMS
6464
ruby
6565

6666
DEPENDENCIES
67-
bosh-template
67+
bosh-template (>= 2.2.1)
6868
nokogiri (>= 1.10.8)
6969
rspec
7070
solargraph

jobs/policy-server/spec

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ templates:
1212
uaa_ca.crt.erb: config/certs/uaa_ca.crt
1313
cc_ca.crt.erb: config/certs/cc_ca.crt
1414
database_ca.crt.erb: config/certs/database_ca.crt
15+
16+
locket_ca.crt.erb: config/certs/locket_ca.crt
17+
locket.crt.erb: config/certs/locket.crt
18+
locket.key.erb: config/certs/locket.key
1519

1620
post-start.erb: bin/post-start
1721
pre-start.erb: bin/pre-start
@@ -203,3 +207,24 @@ properties:
203207
allowed_cors_domains:
204208
description: "List of domains (including scheme) from which Cross-Origin requests will be accepted."
205209
default: []
210+
211+
asg_sync_enabled:
212+
description: "Enables syncing of ASG data from CAPI for use with dynamic ASGs in silk-release"
213+
default: true
214+
215+
asg_sync_interval:
216+
description: "Interval in seconds that policy-server will poll CAPI for ASG data. Requires asg_sync_enabled. Must be > 0"
217+
default: 60
218+
219+
locket_address:
220+
description: "Hostname and port of the Locket server. Must be set when asg_sync_enabled is set to true."
221+
default: "locket.service.cf.internal:8891"
222+
223+
locket_ca_cert:
224+
description: "The CA certificiate for the CA for Locket."
225+
226+
locket_client_cert:
227+
description: "The client certificate for Locket."
228+
229+
locket_client_key:
230+
description: "The private key for Locket."
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<% if p("asg_sync_enabled") %>
2+
<%= p("locket_client_cert") %>
3+
<% end %>
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<% if p("asg_sync_enabled") %>
2+
<%= p("locket_client_key") %>
3+
<% end %>
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<% if p("asg_sync_enabled") %>
2+
<%= p("locket_ca_cert") %>
3+
<% end %>

jobs/policy-server/templates/policy-server.json.erb

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,27 @@
6666
end
6767

6868
parse_ip(p('listen_ip'), 'listen_ip')
69+
70+
def asg_sync_interval
71+
# if p() is safe here since asg_sync_enabled + asg_sync_interval both have defaults and can't be nil
72+
if p('asg_sync_enabled')
73+
interval = p('asg_sync_interval')
74+
if interval.class == Integer and interval >= 1
75+
return interval
76+
end
77+
raise "asg_sync_interval must be an integer greater than 0"
78+
end
79+
end
80+
81+
def locket_address
82+
# if p() is safe here since asg_sync_enabled + locket_address both have defaults and can't be nil
83+
if p('asg_sync_enabled')
84+
if p('locket_address') =~ /^[a-z0-9.-]+:[0-9]+$/
85+
return p('locket_address')
86+
end
87+
raise 'asg_sync_enabled is true but the locket_address is invalid'
88+
end
89+
end
6990
%>
7091

7192
<%=
@@ -127,6 +148,14 @@
127148
'request_timeout' => 5,
128149
}
129150

151+
if p('asg_sync_enabled')
152+
toRender['asg_sync_interval'] = asg_sync_interval
153+
toRender['locket_address'] = locket_address
154+
toRender['locket_ca_cert_file'] = '/var/vcap/jobs/policy-server/config/certs/locket_ca.crt'
155+
toRender['locket_client_cert_file'] = '/var/vcap/jobs/policy-server/config/certs/locket.crt'
156+
toRender['locket_client_key_file'] = '/var/vcap/jobs/policy-server/config/certs/locket.key'
157+
end
158+
130159
JSON.pretty_generate(toRender)
131160
%>
132161
<% end %>

spec/bosh-dns-adapter/bosh_dns_adapter_spec.rb

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -118,16 +118,14 @@ module Bosh::Template::Test
118118
end
119119
end
120120

121-
# This test must be pended until this PR is merged and a new version of the
122-
# bosh-template gem is published:
123-
# https://github.com/cloudfoundry/bosh/pull/2116
124-
xdescribe 'when the optional vip_resolver_conn link is provided' do
121+
describe 'when the optional vip_resolver_conn link is provided' do
125122
let(:links_with_vip_resolver_conn) do
126123
links << Link.new(
127124
name: 'vip_resolver_conn',
128125
properties: {
129-
'listen_port_for_vip_resolver' => 1234
130-
}
126+
'listen_port_for_vip_resolver' => 1234,
127+
},
128+
address: 'copilot.bosh',
131129
)
132130
end
133131

spec/policy-server/policy_server_spec.rb

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ module Bosh::Template::Test
4848
'metron_port' => 6789,
4949
'log_level' => 'debug',
5050
'allowed_cors_domains' => ['some-cors-domain'],
51+
'locket_ca_cert' => 'the locket ca cert',
52+
'locket_client_cert' => 'the locket cert',
53+
'locket_client_key' => 'the locket key',
5154
}
5255
end
5356

@@ -172,6 +175,11 @@ module Bosh::Template::Test
172175
'allowed_cors_domains' => ['some-cors-domain'],
173176
'uaa_ca' => '/var/vcap/jobs/policy-server/config/certs/uaa_ca.crt',
174177
'request_timeout' => 5,
178+
'asg_sync_interval' => 60,
179+
'locket_address' => 'locket.service.cf.internal:8891',
180+
'locket_ca_cert_file' => '/var/vcap/jobs/policy-server/config/certs/locket_ca.crt',
181+
'locket_client_cert_file' => '/var/vcap/jobs/policy-server/config/certs/locket.crt',
182+
'locket_client_key_file' => '/var/vcap/jobs/policy-server/config/certs/locket.key',
175183
})
176184
end
177185

@@ -337,6 +345,145 @@ module Bosh::Template::Test
337345
JSON.parse(template.render(merged_manifest_properties))
338346
}.to raise_error('policy_cleanup_interval must be at least 1 minute')
339347
end
348+
349+
it 'raises an error when asg_sync_enabled is true and the asg_sync_interval is invalid' do
350+
intervals = [
351+
'notanumber',
352+
0,
353+
-1,
354+
1.3,
355+
0.5,
356+
true,
357+
-0,
358+
'1',
359+
'0',
360+
]
361+
merged_manifest_properties['asg_sync_enabled'] = true
362+
intervals.each do |interval|
363+
merged_manifest_properties['asg_sync_interval'] = interval
364+
expect {
365+
JSON.parse(template.render(merged_manifest_properties))
366+
}.to raise_error('asg_sync_interval must be an integer greater than 0')
367+
end
368+
end
369+
it 'raises an error when asg_sync_enabled is true and there is no locket_address defined' do
370+
addrs = [
371+
'',
372+
'my-site-without-port.com',
373+
'http://asdf.com',
374+
'http://asdf:1234',
375+
'asdf.com:badport',
376+
'me+you:1234',
377+
]
378+
merged_manifest_properties['asg_sync_enabled'] = true
379+
addrs.each do |addr|
380+
merged_manifest_properties['locket_address'] = addr
381+
expect {
382+
JSON.parse(template.render(merged_manifest_properties))
383+
}.to raise_error('asg_sync_enabled is true but the locket_address is invalid')
384+
end
385+
end
386+
it 'allows common domain name/ip addr combos for locket_address' do
387+
addrs = [
388+
'test.com:1234',
389+
'10.10.10.10:1234',
390+
'my-cool-site.com:1234',
391+
]
392+
merged_manifest_properties['asg_sync_enabled'] = true
393+
addrs.each do |addr|
394+
merged_manifest_properties['locket_address'] = addr
395+
expect {
396+
JSON.parse(template.render(merged_manifest_properties))
397+
}.to_not raise_error
398+
end
399+
end
400+
end
401+
describe 'locket.ca.crt' do
402+
let(:template) {job.template('config/certs/locket_ca.crt')}
403+
describe 'When the property exits' do
404+
it 'renders the locket cert' do
405+
cert = template.render(merged_manifest_properties)
406+
expect(cert.strip).to eq('the locket ca cert')
407+
end
408+
end
409+
410+
describe 'when the property doesn\'t exist' do
411+
before do
412+
merged_manifest_properties.delete('locket_ca_cert')
413+
end
414+
415+
it 'raises an error when asg_sync_enabled is true and there is no locket_ca_cert defined' do
416+
merged_manifest_properties['asg_sync_enabled'] = true
417+
expect {
418+
template.render(merged_manifest_properties)
419+
}.to raise_error Bosh::Template::UnknownProperty
420+
end
421+
422+
it 'raises and error when asg_sync_enabled is false and there is no locket_ca_cert defined' do
423+
merged_manifest_properties['asg_sync_enabled'] = false
424+
expect {
425+
template.render(merged_manifest_properties)
426+
}.to_not raise_error
427+
end
428+
end
429+
end
430+
describe 'locket.crt' do
431+
let(:template) {job.template('config/certs/locket.crt')}
432+
describe 'When the property exits' do
433+
it 'renders the locket cert' do
434+
cert = template.render(merged_manifest_properties)
435+
expect(cert.strip).to eq('the locket cert')
436+
end
437+
end
438+
439+
describe 'when the property doesn\'t exist' do
440+
before do
441+
merged_manifest_properties.delete('locket_client_cert')
442+
end
443+
444+
it 'raises an error when asg_sync_enabled is true and there is no locket_client defined' do
445+
merged_manifest_properties['asg_sync_enabled'] = true
446+
expect {
447+
template.render(merged_manifest_properties)
448+
}.to raise_error Bosh::Template::UnknownProperty
449+
end
450+
451+
it 'raises and error when asg_sync_enabled is false and there is no locket_client defined' do
452+
merged_manifest_properties['asg_sync_enabled'] = false
453+
expect {
454+
template.render(merged_manifest_properties)
455+
}.to_not raise_error
456+
end
457+
end
458+
end
459+
describe 'locket.key' do
460+
let(:template) {job.template('config/certs/locket.key')}
461+
describe 'When the property exits' do
462+
it 'renders the locket cert' do
463+
cert = template.render(merged_manifest_properties)
464+
expect(cert.strip).to eq('the locket key')
465+
end
466+
end
467+
468+
describe 'when the property doesn\'t exist' do
469+
before do
470+
merged_manifest_properties.delete('locket_client_key')
471+
end
472+
473+
it 'raises an error when asg_sync_enabled is true and there is no locket_client_key defined' do
474+
merged_manifest_properties['asg_sync_enabled'] = true
475+
expect {
476+
template.render(merged_manifest_properties)
477+
}.to raise_error Bosh::Template::UnknownProperty
478+
end
479+
480+
it 'raises and error when asg_sync_enabled is false and there is no locket_client_key defined' do
481+
merged_manifest_properties['asg_sync_enabled'] = false
482+
expect {
483+
template.render(merged_manifest_properties)
484+
}.to_not raise_error
485+
end
486+
end
340487
end
341488
end
342489
end

0 commit comments

Comments
 (0)