Skip to content

Commit 67e6404

Browse files
authored
Add storage cli param to cc deployment updater (#583)
1 parent 44a9d61 commit 67e6404

File tree

7 files changed

+319
-0
lines changed

7 files changed

+319
-0
lines changed

jobs/cc_deployment_updater/spec

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ templates:
2727
resource_pool_ca_cert.pem.erb: config/certs/resource_pool_ca_cert.pem
2828
droplets_ca_cert.pem.erb: config/certs/droplets_ca_cert.pem
2929
buildpacks_ca_cert.pem.erb: config/certs/buildpacks_ca_cert.pem
30+
storage_cli_config_droplets.json.erb: config/storage_cli_config_droplets.json
31+
storage_cli_config_packages.json.erb: config/storage_cli_config_packages.json
32+
storage_cli_config_buildpacks.json.erb: config/storage_cli_config_buildpacks.json
33+
storage_cli_config_resource_pool.json.erb: config/storage_cli_config_resource_pool.json
3034

3135
packages:
3236
- capi_utils

jobs/cc_deployment_updater/templates/cloud_controller_ng.yml.erb

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,11 @@ maximum_health_check_timeout: <%= link("cloud_controller_internal").p("cc.maximu
152152

153153
stacks_file: /var/vcap/jobs/cloud_controller_ng/config/stacks.yml
154154

155+
storage_cli_config_file_droplets: /var/vcap/jobs/cc_deployment_updater/config/storage_cli_config_droplets.json
156+
storage_cli_config_file_buildpacks: /var/vcap/jobs/cc_deployment_updater/config/storage_cli_config_buildpacks.json
157+
storage_cli_config_file_packages: /var/vcap/jobs/cc_deployment_updater/config/storage_cli_config_packages.json
158+
storage_cli_config_file_resource_pool: /var/vcap/jobs/cc_deployment_updater/config/storage_cli_config_resource_pool.json
159+
155160
resource_pool:
156161
blobstore_type: <%= link("cloud_controller_internal").p("cc.resource_pool.blobstore_type") %>
157162
webdav_config:
@@ -166,6 +171,8 @@ resource_pool:
166171
minimum_size: <%= link("cloud_controller_internal").p("cc.resource_pool.minimum_size") %>
167172
maximum_size: <%= link("cloud_controller_internal").p("cc.resource_pool.maximum_size") %>
168173
resource_directory_key: <%= link("cloud_controller_internal").p("cc.resource_pool.resource_directory_key") %>
174+
blobstore_provider: <%= link("cloud_controller_internal").p("cc.resource_pool.blobstore_provider") %>
175+
connection_config: <%= link("cloud_controller_internal").p("cc.resource_pool.connection_config", {}).to_json %>
169176
<% link("cloud_controller_internal").if_p("cc.resource_pool.cdn") do %>
170177
cdn:
171178
uri: <%= link("cloud_controller_internal").p("cc.resource_pool.cdn.uri") %>
@@ -188,6 +195,8 @@ packages:
188195
ca_cert_path: "/var/vcap/jobs/cc_deployment_updater/config/certs/packages_ca_cert.pem"
189196
<% end %>
190197
app_package_directory_key: <%= link("cloud_controller_internal").p("cc.packages.app_package_directory_key") %>
198+
blobstore_provider: <%= link("cloud_controller_internal").p("cc.packages.blobstore_provider") %>
199+
connection_config: <%= link("cloud_controller_internal").p("cc.packages.connection_config", {}).to_json %>
191200
max_package_size: <%= link("cloud_controller_internal").p("cc.packages.max_package_size") %>
192201
<% link("cloud_controller_internal").if_p("cc.packages.cdn") do %>
193202
cdn:
@@ -212,6 +221,8 @@ droplets:
212221
ca_cert_path: "/var/vcap/jobs/cc_deployment_updater/config/certs/droplets_ca_cert.pem"
213222
<% end %>
214223
droplet_directory_key: <%= link("cloud_controller_internal").p("cc.droplets.droplet_directory_key") %>
224+
blobstore_provider: <%= link("cloud_controller_internal").p("cc.droplets.blobstore_provider") %>
225+
connection_config: <%= link("cloud_controller_internal").p("cc.droplets.connection_config", {}).to_json %>
215226
<% link("cloud_controller_internal").if_p("cc.droplets.cdn") do %>
216227
cdn:
217228
uri: <%= link("cloud_controller_internal").p("cc.droplets.cdn.uri") %>
@@ -234,6 +245,8 @@ buildpacks:
234245
ca_cert_path: "/var/vcap/jobs/cc_deployment_updater/config/certs/buildpacks_ca_cert.pem"
235246
<% end %>
236247
buildpack_directory_key: <%= link("cloud_controller_internal").p("cc.buildpacks.buildpack_directory_key") %>
248+
blobstore_provider: <%= link("cloud_controller_internal").p("cc.buildpacks.blobstore_provider") %>
249+
connection_config: <%= link("cloud_controller_internal").p("cc.buildpacks.connection_config", {}).to_json %>
237250
<% link("cloud_controller_internal").if_p("cc.buildpacks.cdn") do %>
238251
cdn:
239252
uri: <%= link("cloud_controller_internal").p("cc.buildpacks.cdn.uri") %>
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<%
2+
require "json"
3+
4+
# Ensure Azure CLI connection_config has a default timeout if none is set
5+
def cli_cfg_with_default_timeout(connection_cfg, blobstore_type, default_seconds: 41)
6+
cfg = (connection_cfg || {}).dup
7+
if blobstore_type == 'storage_cli'
8+
if !cfg.key?('put_timeout_in_seconds') || cfg['put_timeout_in_seconds'].to_s.empty?
9+
cfg['put_timeout_in_seconds'] = default_seconds.to_s
10+
end
11+
end
12+
cfg
13+
end
14+
15+
# helper: add key only when value is present
16+
def add(h, key, val)
17+
return if val.nil?
18+
return if val.respond_to?(:empty?) && val.empty?
19+
h[key] = val
20+
end
21+
22+
l = link("cloud_controller_internal")
23+
24+
scope = "cc.buildpacks.connection_config"
25+
provider = l.p("cc.buildpacks.blobstore_provider", nil)
26+
27+
if provider != "AzureRM"
28+
options = {} # for now: all non-azure providers output an empty JSON object
29+
else
30+
options = {}
31+
options["provider"] = provider
32+
options["account_name"] = l.p("#{scope}.azure_storage_account_name")
33+
options["container_name"] = l.p("#{scope}.container_name")
34+
add(options, "account_key", l.p("#{scope}.azure_storage_access_key"))
35+
add(options, "environment", l.p("#{scope}.environment", "AzureCloud"))
36+
add(options, "put_timeout_in_seconds", l.p("#{scope}.put_timeout_in_seconds", nil))
37+
38+
# optional passthrough for extra storage-cli flags
39+
begin
40+
custom = l.p("#{scope}.custom", {})
41+
if custom.respond_to?(:each)
42+
custom.each { |k, v| add(options, k.to_s, v) }
43+
end
44+
rescue
45+
# ignore if property not defined
46+
end
47+
options = cli_cfg_with_default_timeout(options, 'storage_cli')
48+
end
49+
-%>
50+
<%= JSON.pretty_generate(options) %>
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<%
2+
require "json"
3+
4+
# Ensure Azure CLI connection_config has a default timeout if none is set
5+
def cli_cfg_with_default_timeout(connection_cfg, blobstore_type, default_seconds: 41)
6+
cfg = (connection_cfg || {}).dup
7+
if blobstore_type == 'storage_cli'
8+
if !cfg.key?('put_timeout_in_seconds') || cfg['put_timeout_in_seconds'].to_s.empty?
9+
cfg['put_timeout_in_seconds'] = default_seconds.to_s
10+
end
11+
end
12+
cfg
13+
end
14+
15+
# helper: add key only when value is present
16+
def add(h, key, val)
17+
return if val.nil?
18+
return if val.respond_to?(:empty?) && val.empty?
19+
h[key] = val
20+
end
21+
22+
l = link("cloud_controller_internal")
23+
24+
scope = "cc.droplets.connection_config"
25+
provider = l.p("cc.droplets.blobstore_provider", nil)
26+
27+
if provider != "AzureRM"
28+
options = {} # for now: all non-azure providers output an empty JSON object
29+
else
30+
options = {}
31+
options["provider"] = provider
32+
options["account_name"] = l.p("#{scope}.azure_storage_account_name")
33+
options["container_name"] = l.p("#{scope}.container_name")
34+
add(options, "account_key", l.p("#{scope}.azure_storage_access_key"))
35+
add(options, "environment", l.p("#{scope}.environment", "AzureCloud"))
36+
add(options, "put_timeout_in_seconds", l.p("#{scope}.put_timeout_in_seconds", nil))
37+
38+
# optional passthrough for extra storage-cli flags
39+
begin
40+
custom = l.p("cc.droplets.connection_config.custom", {})
41+
if custom.respond_to?(:each)
42+
custom.each { |k, v| add(options, k.to_s, v) }
43+
end
44+
rescue
45+
# ignore if property not defined
46+
end
47+
options = cli_cfg_with_default_timeout(options, 'storage_cli')
48+
end
49+
-%>
50+
<%= JSON.pretty_generate(options) %>
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<%
2+
require "json"
3+
4+
# Ensure Azure CLI connection_config has a default timeout if none is set
5+
def cli_cfg_with_default_timeout(connection_cfg, blobstore_type, default_seconds: 41)
6+
cfg = (connection_cfg || {}).dup
7+
if blobstore_type == 'storage_cli'
8+
if !cfg.key?('put_timeout_in_seconds') || cfg['put_timeout_in_seconds'].to_s.empty?
9+
cfg['put_timeout_in_seconds'] = default_seconds.to_s
10+
end
11+
end
12+
cfg
13+
end
14+
15+
# helper: add key only when value is present
16+
def add(h, key, val)
17+
return if val.nil?
18+
return if val.respond_to?(:empty?) && val.empty?
19+
h[key] = val
20+
end
21+
22+
l = link("cloud_controller_internal")
23+
24+
scope = "cc.packages.connection_config"
25+
provider = l.p("cc.packages.blobstore_provider", nil)
26+
27+
if provider != "AzureRM"
28+
options = {} # for now: all non-azure providers output an empty JSON object
29+
else
30+
options = {}
31+
options["provider"] = provider
32+
options["account_name"] = l.p("#{scope}.azure_storage_account_name")
33+
options["container_name"] = l.p("#{scope}.container_name")
34+
add(options, "account_key", l.p("#{scope}.azure_storage_access_key"))
35+
add(options, "environment", l.p("#{scope}.environment", "AzureCloud"))
36+
add(options, "put_timeout_in_seconds", l.p("#{scope}.put_timeout_in_seconds", nil))
37+
38+
# optional passthrough for extra storage-cli flags
39+
begin
40+
custom = l.p("#{scope}.custom", {})
41+
if custom.respond_to?(:each)
42+
custom.each { |k, v| add(options, k.to_s, v) }
43+
end
44+
rescue
45+
# ignore if property not defined
46+
end
47+
options = cli_cfg_with_default_timeout(options, 'storage_cli')
48+
end
49+
-%>
50+
<%= JSON.pretty_generate(options) %>
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<%
2+
require "json"
3+
4+
# Ensure Azure CLI connection_config has a default timeout if none is set
5+
def cli_cfg_with_default_timeout(connection_cfg, blobstore_type, default_seconds: 41)
6+
cfg = (connection_cfg || {}).dup
7+
if blobstore_type == 'storage_cli'
8+
if !cfg.key?('put_timeout_in_seconds') || cfg['put_timeout_in_seconds'].to_s.empty?
9+
cfg['put_timeout_in_seconds'] = default_seconds.to_s
10+
end
11+
end
12+
cfg
13+
end
14+
15+
# helper: add key only when value is present
16+
def add(h, key, val)
17+
return if val.nil?
18+
return if val.respond_to?(:empty?) && val.empty?
19+
h[key] = val
20+
end
21+
22+
l = link("cloud_controller_internal")
23+
24+
scope = "cc.resource_pool.connection_config"
25+
provider = l.p("cc.resource_pool.blobstore_provider", nil)
26+
27+
if provider != "AzureRM"
28+
options = {} # for now: all non-azure providers output an empty JSON object
29+
else
30+
options = {}
31+
options["provider"] = provider
32+
options["account_name"] = l.p("#{scope}.azure_storage_account_name")
33+
options["container_name"] = l.p("#{scope}.container_name")
34+
add(options, "account_key", l.p("#{scope}.azure_storage_access_key"))
35+
add(options, "environment", l.p("#{scope}.environment", "AzureCloud"))
36+
add(options, "put_timeout_in_seconds", l.p("#{scope}.put_timeout_in_seconds", nil))
37+
38+
# optional passthrough for extra storage-cli flags
39+
begin
40+
custom = l.p("#{scope}.custom", {})
41+
if custom.respond_to?(:each)
42+
custom.each { |k, v| add(options, k.to_s, v) }
43+
end
44+
rescue
45+
# ignore if property not defined
46+
end
47+
options = cli_cfg_with_default_timeout(options, 'storage_cli')
48+
end
49+
-%>
50+
<%= JSON.pretty_generate(options) %>
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
# frozen_string_literal: true
2+
3+
require 'rspec'
4+
require 'yaml'
5+
require 'bosh/template/test'
6+
7+
TEMPLATES = {
8+
droplets: ['config/storage_cli_config_droplets.json', %w[cc droplets connection_config]],
9+
buildpacks: ['config/storage_cli_config_buildpacks.json', %w[cc buildpacks connection_config]],
10+
packages: ['config/storage_cli_config_packages.json', %w[cc packages connection_config]],
11+
resource_pool: ['config/storage_cli_config_resource_pool.json', %w[cc resource_pool connection_config]]
12+
}.freeze
13+
14+
module Bosh
15+
module Template
16+
module Test
17+
RSpec.describe 'storage-cli JSON templates (cc_deployment_updater)' do
18+
let(:release_path) { File.join(File.dirname(__FILE__), '../..') }
19+
let(:release) { ReleaseDir.new(release_path) }
20+
let(:job) { release.job('cc_deployment_updater') }
21+
22+
let(:link_props) do
23+
{
24+
'cc' => {
25+
'droplets' => { 'connection_config' => {}, 'blobstore_provider' => 'S3' },
26+
'buildpacks' => { 'connection_config' => {}, 'blobstore_provider' => 'S3' },
27+
'packages' => { 'connection_config' => {}, 'blobstore_provider' => 'S3' },
28+
'resource_pool' => { 'connection_config' => {}, 'blobstore_provider' => 'S3' }
29+
}
30+
}
31+
end
32+
33+
let(:cc_link) do
34+
Bosh::Template::Test::Link.new(
35+
name: 'cloud_controller_internal',
36+
properties: link_props
37+
)
38+
end
39+
40+
let(:links) { [cc_link] }
41+
let(:props) { {} }
42+
43+
def set(hash, path, value)
44+
cursor = hash
45+
path[0..-2].each { |key| cursor = (cursor[key] ||= {}) }
46+
cursor[path.last] = value
47+
end
48+
49+
TEMPLATES.each do |scope, (template_path, keypath)|
50+
describe template_path do
51+
let(:template) { job.template(template_path) }
52+
53+
context "when provider is AzureRM for #{scope}" do
54+
before do
55+
link_props['cc'][scope.to_s]['blobstore_provider'] = 'AzureRM'
56+
end
57+
58+
it 'renders and normalizes put_timeout_in_seconds to "41" when blank' do
59+
set(link_props, keypath, {
60+
'provider' => 'AzureRM',
61+
'azure_storage_account_name' => 'acc',
62+
'azure_storage_access_key' => 'key',
63+
'container_name' => 'cont',
64+
'put_timeout_in_seconds' => ''
65+
})
66+
67+
json = YAML.safe_load(template.render(props, consumes: links))
68+
expect(json).to include(
69+
'provider' => 'AzureRM',
70+
'account_name' => 'acc',
71+
'account_key' => 'key',
72+
'container_name' => 'cont',
73+
'put_timeout_in_seconds' => '41'
74+
)
75+
end
76+
77+
it 'keeps existing put_timeout_in_seconds when provided' do
78+
set(link_props, keypath, {
79+
'provider' => 'AzureRM',
80+
'azure_storage_account_name' => 'acc',
81+
'azure_storage_access_key' => 'key',
82+
'container_name' => 'cont',
83+
'put_timeout_in_seconds' => '7'
84+
})
85+
86+
json = YAML.safe_load(template.render(props, consumes: links))
87+
expect(json['put_timeout_in_seconds']).to eq('7')
88+
end
89+
end
90+
91+
context "when provider is non-Azure for #{scope}" do
92+
it 'renders {}' do
93+
json = YAML.safe_load(template.render(props, consumes: links))
94+
expect(json).to eq({})
95+
end
96+
end
97+
end
98+
end
99+
end
100+
end
101+
end
102+
end

0 commit comments

Comments
 (0)