diff --git a/examples/deployment/operations/kafka.yml b/examples/deployment/operations/kafka.yml index d94ca5939..f7c147ae6 100644 --- a/examples/deployment/operations/kafka.yml +++ b/examples/deployment/operations/kafka.yml @@ -13,9 +13,9 @@ - name: ((service_release)) version: ((service_release_version)) jobs: [kafka_server, zookeeper_server] - stemcell: - os: ((meta.stemcell.os)) - version: "((meta.stemcell.version))" + stemcells: + - os: ((meta.stemcell.os)) + version: "((meta.stemcell.version))" - type: replace path: /instance_groups/name=broker/jobs/- diff --git a/examples/deployment/operations/redis.yml b/examples/deployment/operations/redis.yml index 674a2f702..da6c6e52b 100644 --- a/examples/deployment/operations/redis.yml +++ b/examples/deployment/operations/redis.yml @@ -25,9 +25,10 @@ - name: ((service_release)) version: ((service_release_version)) jobs: [redis-server, health-check, cleanup-data] - stemcell: - os: ((meta.stemcell.os)) + stemcells: + - os: ((meta.stemcell.os)) version: "((meta.stemcell.version))" + alias: default - type: replace path: /instance_groups/name=broker/jobs/- diff --git a/examples/kafka-example-service-adapter-release b/examples/kafka-example-service-adapter-release index 323e0a6de..16ac15df2 160000 --- a/examples/kafka-example-service-adapter-release +++ b/examples/kafka-example-service-adapter-release @@ -1 +1 @@ -Subproject commit 323e0a6deecf4affb22aedcb5b99eb0a8f1a1bf8 +Subproject commit 16ac15df283650f9d587379d9f9c2417e92677c8 diff --git a/examples/redis-example-service-adapter-release b/examples/redis-example-service-adapter-release index 4869e5ccf..7d87f485a 160000 --- a/examples/redis-example-service-adapter-release +++ b/examples/redis-example-service-adapter-release @@ -1 +1 @@ -Subproject commit 4869e5ccfe12504a84a521853686a983c465d4f5 +Subproject commit 7d87f485a8ee0bee45f41000054aeb803649adce diff --git a/jobs/broker/spec b/jobs/broker/spec index 2d09dd329..3fbae86c5 100644 --- a/jobs/broker/spec +++ b/jobs/broker/spec @@ -194,6 +194,13 @@ properties: service_deployment.releases: description: releases to deploy for each instance + service_deployment.stemcells: + description: stemcells to deploy for each instance + default: [] + example: + - os: ubuntu + version: 1234 + service_deployment.stemcell.os: description: stemcell OS to use for every job in the service deployment diff --git a/jobs/broker/templates/broker.yml.erb b/jobs/broker/templates/broker.yml.erb index ac38da4cd..ff8a81622 100644 --- a/jobs/broker/templates/broker.yml.erb +++ b/jobs/broker/templates/broker.yml.erb @@ -65,10 +65,33 @@ def validate_releases(service_deployment) end end -def validate_stemcell(service_deployment) +def prepare_stemcells(service_deployment) + legacy_stemcell = service_deployment['stemcell'] + legacy_os = service_deployment['stemcell']['os'] || nil # nil + legacy_version = service_deployment['stemcell']['version'] || nil # 12334 + + if !service_deployment['stemcells'].empty? && !legacy_os.nil? && !legacy_version.nil? then + raise 'You cannot configure both "stemcell" and "stemcells" in broker.service_deployment.' + end + + if !legacy_os.nil? || !legacy_version.nil? then + service_deployment['stemcells'] << legacy_stemcell + end + service_deployment['stemcell'] = nil + + if service_deployment['stemcells'].empty? then + raise 'Invalid service_deployment config - at least one stemcell must be specified' + end + + service_deployment['stemcells'].each do |stemcell| + validate_stemcell stemcell + end +end + +def validate_stemcell(stemcell) required_stemcell_keys = %w{os version} - validate_config(service_deployment['stemcell'], required_stemcell_keys, "Invalid service_deployment.stemcell config - must specify ") - if service_deployment['stemcell']['version'] =~ /latest$/ + validate_config(stemcell, required_stemcell_keys, "Invalid service_deployment stemcell config - must specify ") + if stemcell['version'] =~ /latest$/ raise "You must configure the exact release and stemcell versions in broker.service_deployment. " + "ODB requires exact versions to detect pending changes as part of the 'cf update-service' workflow. For example, latest and 3112.latest are not supported." end @@ -151,7 +174,7 @@ end service_deployment = p('service_deployment') validate_releases(service_deployment) -validate_stemcell(service_deployment) +prepare_stemcells(service_deployment) if p('disable_cf_startup_checks') global_limit = service_catalog.dig('global_quotas', 'service_instance_limit') @@ -346,7 +369,7 @@ config = { "bosh" => bosh_config, "cf" => cf_config, "service_adapter" => p('service_adapter'), - "service_deployment" => p('service_deployment'), + "service_deployment" => service_deployment, "service_catalog" => service_catalog, "bosh_credhub" => p('bosh_credhub_api') }.merge(credhub_config).merge(service_instances_api_config) diff --git a/spec/broker_config_template_spec.rb b/spec/broker_config_template_spec.rb index da0201e56..12183205f 100644 --- a/spec/broker_config_template_spec.rb +++ b/spec/broker_config_template_spec.rb @@ -808,33 +808,129 @@ end end - context 'when no stemcell os is configured' do + describe '"stemcells" property' do + let(:manifest_file) { File.open 'spec/fixtures/valid-mandatory-broker-config.yml' } + + it "is included in the configuration" do + obj = YAML.load(rendered_template) + expect(obj['service_deployment']['stemcells']).to eq([{"os"=>"ubuntu-trusty", "version"=>1234, "alias"=>"default"}]) + end + + context 'when "stemcell" is also configured' do + let(:manifest_file) do + generate_test_manifest do |yaml| + yaml['instance_groups'][0]['jobs'][0]['properties']['service_deployment']['stemcell'] = { + 'os' => 'ubuntu-trusty','version' => 1234 + } + yaml + end + end + + it 'raises an error' do + expect { rendered_template }.to( + raise_error(RuntimeError, 'You cannot configure both "stemcell" and "stemcells" in broker.service_deployment.') + ) + end + end + + context 'when one of the stemcells does not configure OS' do + let(:manifest_file) do + generate_test_manifest do |yaml| + yaml['instance_groups'][0]['jobs'][0]['properties']['service_deployment']['stemcells'][0]['os'] = nil + yaml + end + end + + it 'raises an error' do + expect { rendered_template }.to( + raise_error(RuntimeError, 'Invalid service_deployment stemcell config - must specify os') + ) + end + end + + context 'when one of the stemcells does not configure version' do + let(:manifest_file) do + generate_test_manifest do |yaml| + yaml['instance_groups'][0]['jobs'][0]['properties']['service_deployment']['stemcells'][0]['version'] = nil + yaml + end + end + + it 'raises an error' do + expect { rendered_template }.to( + raise_error(RuntimeError, 'Invalid service_deployment stemcell config - must specify version') + ) + end + end + end + + context 'when neither "stemcell" nor "stemcells" is configured' do let(:manifest_file) do generate_test_manifest do |yaml| - yaml['instance_groups'][0]['jobs'][0]['properties']['service_deployment']['stemcell']['os'] = nil + yaml['instance_groups'][0]['jobs'][0]['properties']['service_deployment']['stemcells'] = nil yaml end end it 'raises an error' do expect { rendered_template }.to( - raise_error(RuntimeError, 'Invalid service_deployment.stemcell config - must specify os') + raise_error(RuntimeError, 'Invalid service_deployment config - at least one stemcell must be specified') ) end end - context 'when no stemcell version is configured' do + describe 'deprecated "stemcell" property' do let(:manifest_file) do generate_test_manifest do |yaml| - yaml['instance_groups'][0]['jobs'][0]['properties']['service_deployment']['stemcell']['version'] = nil + yaml['instance_groups'][0]['jobs'][0]['properties']['service_deployment']['stemcells'] = [] + yaml['instance_groups'][0]['jobs'][0]['properties']['service_deployment']['stemcell'] = { + 'os' => 'ubuntu-trusty', 'version' => 2311 + } yaml end end - it 'raises an error' do - expect { rendered_template }.to( - raise_error(RuntimeError, 'Invalid service_deployment.stemcell config - must specify version') - ) + + it 'generates the config with "stemcells"' do + obj = YAML.load(rendered_template) + expect(obj['service_deployment']['stemcells']).to eq([{"os"=>"ubuntu-trusty", "version"=>2311}]) + expect(obj['service_deployment']['stemcell']).to be_nil + end + + context 'when no stemcell os is configured' do + let(:manifest_file) do + generate_test_manifest do |yaml| + yaml['instance_groups'][0]['jobs'][0]['properties']['service_deployment']['stemcells'] = [] + yaml['instance_groups'][0]['jobs'][0]['properties']['service_deployment']['stemcell'] = { + 'os' => nil, 'version' => 2311 + } + yaml + end + end + + it 'raises an error' do + expect { rendered_template }.to( + raise_error(RuntimeError, 'Invalid service_deployment stemcell config - must specify os') + ) + end + end + + context 'when no stemcell version is configured' do + let(:manifest_file) do + generate_test_manifest do |yaml| + yaml['instance_groups'][0]['jobs'][0]['properties']['service_deployment']['stemcells'] = [] + yaml['instance_groups'][0]['jobs'][0]['properties']['service_deployment']['stemcell'] = { + 'os' => 'ubuntu-xenial', 'version' => nil + } + yaml + end + end + + it 'raises an error' do + expect { rendered_template }.to( + raise_error(RuntimeError, 'Invalid service_deployment stemcell config - must specify version') + ) + end end end @@ -873,7 +969,7 @@ context 'when a stemcell version is latest' do let(:manifest_file) do generate_test_manifest do |yaml| - yaml['instance_groups'][0]['jobs'][0]['properties']['service_deployment']['stemcell']['version'] = 'latest' + yaml['instance_groups'][0]['jobs'][0]['properties']['service_deployment']['stemcells'] = [{'version' => 'latest', 'os' => 'ubuntu-trusty'}] yaml end end @@ -889,7 +985,7 @@ context 'when a stemcell version is n.latest' do let(:manifest_file) do generate_test_manifest do |yaml| - yaml['instance_groups'][0]['jobs'][0]['properties']['service_deployment']['stemcell']['version'] = '22.latest' + yaml['instance_groups'][0]['jobs'][0]['properties']['service_deployment']['stemcells'][0]['version'] = '22.latest' yaml end end diff --git a/spec/fixtures/valid-mandatory-broker-config.yml b/spec/fixtures/valid-mandatory-broker-config.yml index 1ad03699a..f3866e7da 100644 --- a/spec/fixtures/valid-mandatory-broker-config.yml +++ b/spec/fixtures/valid-mandatory-broker-config.yml @@ -22,9 +22,10 @@ instance_groups: - name: a-release version: 1234 jobs: [job-1] - stemcell: - os: ubuntu-trusty - version: 1234 + stemcells: + - os: ubuntu-trusty + version: 1234 + alias: default service_catalog: id: some-id service_name: some-name diff --git a/src/github.com/pivotal-cf/on-demand-service-broker b/src/github.com/pivotal-cf/on-demand-service-broker index 443b8ccea..76983d93d 160000 --- a/src/github.com/pivotal-cf/on-demand-service-broker +++ b/src/github.com/pivotal-cf/on-demand-service-broker @@ -1 +1 @@ -Subproject commit 443b8ccea65ac723f0efa1ac87da4550601aec87 +Subproject commit 76983d93de19a9ba35056e18f2d6a9c0b046f803 diff --git a/src/github.com/pivotal-cf/on-demand-services-sdk b/src/github.com/pivotal-cf/on-demand-services-sdk index be5e27c28..f88592e96 160000 --- a/src/github.com/pivotal-cf/on-demand-services-sdk +++ b/src/github.com/pivotal-cf/on-demand-services-sdk @@ -1 +1 @@ -Subproject commit be5e27c28dfc8366f69ab48d7fc1e6c05e897101 +Subproject commit f88592e968ebb3a327d5689ed6772268a2c0fcfc