diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000000..6af6ff9eb5 --- /dev/null +++ b/Gemfile @@ -0,0 +1,8 @@ +source 'https://rubygems.org' + +group :test do + gem 'bosh-template' + gem 'rspec' + gem 'rubocop' +end + diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 0000000000..78c692aaa6 --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,54 @@ +GEM + remote: https://rubygems.org/ + specs: + ast (2.4.2) + bosh-template (2.3.0) + semi_semantic (~> 1.2.0) + diff-lcs (1.3) + json (2.6.2) + parallel (1.22.1) + parser (3.1.2.1) + ast (~> 2.4.1) + rainbow (3.1.1) + regexp_parser (2.6.0) + rexml (3.2.5) + rspec (3.6.0) + rspec-core (~> 3.6.0) + rspec-expectations (~> 3.6.0) + rspec-mocks (~> 3.6.0) + rspec-core (3.6.0) + rspec-support (~> 3.6.0) + rspec-expectations (3.6.0) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.6.0) + rspec-mocks (3.6.0) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.6.0) + rspec-support (3.6.0) + rubocop (1.38.0) + json (~> 2.3) + parallel (~> 1.10) + parser (>= 3.1.2.1) + rainbow (>= 2.2.2, < 4.0) + regexp_parser (>= 1.8, < 3.0) + rexml (>= 3.2.5, < 4.0) + rubocop-ast (>= 1.23.0, < 2.0) + ruby-progressbar (~> 1.7) + unicode-display_width (>= 1.4.0, < 3.0) + rubocop-ast (1.23.0) + parser (>= 3.1.1.0) + ruby-progressbar (1.11.0) + semi_semantic (1.2.0) + unicode-display_width (2.3.0) + +PLATFORMS + ruby + +DEPENDENCIES + bosh-template + rspec + rubocop + +BUNDLED WITH + 2.3.22 + diff --git a/jobs/auctioneer/spec b/jobs/auctioneer/spec index ae685ceb96..1fac489363 100644 --- a/jobs/auctioneer/spec +++ b/jobs/auctioneer/spec @@ -88,6 +88,12 @@ properties: diego.auctioneer.locket.api_location: description: "Hostname and port of the Locket server. When set, the auctioneer attempts to claim a lock from the Locket API." default: locket.service.cf.internal:8891 + diego.auctioneer.locket.client_keepalive_time: + description: "Period in seconds after which the locket gRPC client sends keepalive ping requests to the locket server it is connected to." + default: 10 + diego.auctioneer.locket.client_keepalive_timeout: + description: "Timeout in seconds to receive a response to the keepalive ping. If a response is not received within this time, the locket client will reconnect to another server." + default: 22 locks.locket.enabled: description: When set, the auctioneer attempts to claim a lock from the Locket API. diff --git a/jobs/auctioneer/templates/auctioneer.json.erb b/jobs/auctioneer/templates/auctioneer.json.erb index 2c4dda17b3..ce32d4ac90 100644 --- a/jobs/auctioneer/templates/auctioneer.json.erb +++ b/jobs/auctioneer/templates/auctioneer.json.erb @@ -73,6 +73,18 @@ config[:locket_client_key_file] = "#{conf_dir}/certs/bbs/client.key" end + if_p("diego.auctioneer.locket.client_keepalive_time") do |value| + config[:locket_client_keepalive_time] = value + end + + if_p("diego.auctioneer.locket.client_keepalive_timeout") do |value| + config[:locket_client_keepalive_timeout] = value + end + + if config[:locket_client_keepalive_time] > config[:locket_client_keepalive_timeout] + raise "The locket client keepalive time property should not be larger than the timeout" + end + config[:loggregator]={} config[:loggregator][:loggregator_use_v2_api] = p("loggregator.use_v2_api") if p("loggregator.use_v2_api") == true diff --git a/jobs/bbs/spec b/jobs/bbs/spec index b6f1040c28..9204a8d4cb 100644 --- a/jobs/bbs/spec +++ b/jobs/bbs/spec @@ -140,6 +140,12 @@ properties: diego.bbs.locket.api_location: description: "Hostname and port of the Locket server. When set, the BBS attempts to claim a lock from the Locket API and will detect Diego cells registered with the Locket API." default: locket.service.cf.internal:8891 + diego.bbs.locket.client_keepalive_time: + description: "Period in seconds after which the locket gRPC client sends keepalive ping requests to the locket server it is connected to." + default: 10 + diego.bbs.locket.client_keepalive_timeout: + description: "Timeout in seconds to receive a response to the keepalive ping. If a response is not received within this time, the locket client will reconnect to another server." + default: 22 limits.open_files: description: Maximum number of files (including sockets) the BBS process may have open. diff --git a/jobs/bbs/templates/bbs.json.erb b/jobs/bbs/templates/bbs.json.erb index cd860f98f0..fded3010af 100644 --- a/jobs/bbs/templates/bbs.json.erb +++ b/jobs/bbs/templates/bbs.json.erb @@ -168,6 +168,18 @@ config[:locket_client_key_file] = "#{conf_dir}/certs/server.key" end + if_p("diego.bbs.locket.client_keepalive_time") do |value| + config[:locket_client_keepalive_time] = value + end + + if_p("diego.bbs.locket.client_keepalive_timeout") do |value| + config[:locket_client_keepalive_timeout] = value + end + + if config[:locket_client_keepalive_time] > config[:locket_client_keepalive_timeout] + raise "The locket client keepalive time property should not be larger than the timeout" + end + config[:loggregator]={} config[:loggregator][:loggregator_use_v2_api] = p("loggregator.use_v2_api") if p("loggregator.use_v2_api") == true diff --git a/jobs/rep/spec b/jobs/rep/spec index df7bd7c494..1383b67c0f 100644 --- a/jobs/rep/spec +++ b/jobs/rep/spec @@ -217,6 +217,12 @@ properties: diego.rep.locket.api_location: description: "Hostname and port of the Locket server. When set, the cell rep will establish its cell registration in the Locket API." default: locket.service.cf.internal:8891 + diego.rep.locket.client_keepalive_time: + description: "Period in seconds after which the locket gRPC client sends keepalive ping requests to the locket server it is connected to." + default: 10 + diego.rep.locket.client_keepalive_timeout: + description: "Timeout in seconds to receive a response to the keepalive ping. If a response is not received within this time, the locket client will reconnect to another server." + default: 22 enable_declarative_healthcheck: description: "When set, enables the rep to prefer the LRP CheckDefinition to healthcheck instances over the Monitor action. Requires Garden-Runc v1.10.0+" diff --git a/jobs/rep/templates/rep.json.erb b/jobs/rep/templates/rep.json.erb index a8d5b28fca..b68170ec93 100644 --- a/jobs/rep/templates/rep.json.erb +++ b/jobs/rep/templates/rep.json.erb @@ -157,6 +157,18 @@ config[:locket_address] = value end + if_p("diego.rep.locket.client_keepalive_time") do |value| + config[:locket_client_keepalive_time] = value + end + + if_p("diego.rep.locket.client_keepalive_timeout") do |value| + config[:locket_client_keepalive_timeout] = value + end + + if config[:locket_client_keepalive_time] > config[:locket_client_keepalive_timeout] + raise "The locket client keepalive time property should not be larger than the timeout" + end + config[:locket_ca_cert_file] = "#{conf_dir}/certs/tls_ca.crt" config[:locket_client_cert_file] = "#{conf_dir}/certs/tls.crt" config[:locket_client_key_file] = "#{conf_dir}/certs/tls.key" diff --git a/jobs/rep_windows/spec b/jobs/rep_windows/spec index 4fc4504bf0..023d76f185 100644 --- a/jobs/rep_windows/spec +++ b/jobs/rep_windows/spec @@ -227,7 +227,13 @@ properties: diego.rep.locket.api_location: description: "Hostname and port of the locket server" default: locket.service.cf.internal:8891 - + diego.rep.locket.client_keepalive_time: + description: "Period in seconds after which the locket gRPC client sends keepalive ping requests to the locket server it is connected to." + default: 10 + diego.rep.locket.client_keepalive_timeout: + description: "Timeout in seconds to receive a response to the keepalive ping. If a response is not received within this time, the locket client will reconnect to another server." + default: 22 + enable_declarative_healthcheck: description: "When set, enables the rep to prefer the LRP CheckDefinition to healthcheck instances over the Monitor action." default: false diff --git a/jobs/rep_windows/templates/rep.json.erb b/jobs/rep_windows/templates/rep.json.erb index 01c64a2649..788e57cf4a 100644 --- a/jobs/rep_windows/templates/rep.json.erb +++ b/jobs/rep_windows/templates/rep.json.erb @@ -157,6 +157,18 @@ config[:locket_address] = value end + if_p("diego.rep.locket.client_keepalive_time") do |value| + config[:locket_client_keepalive_time] = value + end + + if_p("diego.rep.locket.client_keepalive_timeout") do |value| + config[:locket_client_keepalive_timeout] = value + end + + if config[:locket_client_keepalive_time] > config[:locket_client_keepalive_timeout] + raise "The locket client keepalive time property should not be larger than the timeout" + end + config[:locket_ca_cert_file] = "#{conf_dir}/certs/tls_ca.crt" config[:locket_client_cert_file] = "#{conf_dir}/certs/tls.crt" config[:locket_client_key_file] = "#{conf_dir}/certs/tls.key" diff --git a/scripts/docker-shell b/scripts/docker-shell index 063c22cb45..e54b1adc8d 100755 --- a/scripts/docker-shell +++ b/scripts/docker-shell @@ -18,7 +18,6 @@ else exit 1 fi - docker run \ --rm \ -it \ diff --git a/scripts/docker-test-setup.sh b/scripts/docker-test-setup.sh index 16b4d51fa1..00c51dd420 100755 --- a/scripts/docker-test-setup.sh +++ b/scripts/docker-test-setup.sh @@ -15,7 +15,6 @@ if ! [ $(type -P "ginkgo") ]; then mv /root/go/bin/ginkgo /usr/local/bin/ginkgo fi - if ! [ $(type -P "nats-server") ]; then BIN_DIR="${DIEGO_RELEASE_DIR}/bin" mkdir -p "${BIN_DIR}" diff --git a/scripts/run-all-tests-in-docker.sh b/scripts/run-all-tests-in-docker.sh new file mode 100755 index 0000000000..4746d86ae2 --- /dev/null +++ b/scripts/run-all-tests-in-docker.sh @@ -0,0 +1,7 @@ +#!/bin/bash +set -u + +SCRIPT_PATH="$(cd "$(dirname "${0}")" && pwd)" + +. "${SCRIPT_PATH}/run-template-tests-in-docker.sh" +. "${SCRIPT_PATH}/docker-test" diff --git a/scripts/run-template-tests-in-docker.sh b/scripts/run-template-tests-in-docker.sh new file mode 100755 index 0000000000..8407f06517 --- /dev/null +++ b/scripts/run-template-tests-in-docker.sh @@ -0,0 +1,19 @@ +#!/bin/bash +set -u + +ROOT_DIR_PATH="$(cd $(dirname $0)/.. && pwd)" +cd "${ROOT_DIR_PATH}" + +echo "Running template tests" + +docker run \ + --rm \ + -it \ + --privileged \ + -v "${PWD}:/diego-release" \ + --cap-add ALL \ + -w /diego-release \ + "cloudfoundry/tas-runtime-build" \ + /diego-release/scripts/template-tests "$@" + +echo "Done executing template tests" \ No newline at end of file diff --git a/scripts/template-tests b/scripts/template-tests new file mode 100755 index 0000000000..e47afb9b9e --- /dev/null +++ b/scripts/template-tests @@ -0,0 +1,9 @@ +#!/bin/bash -exu + +ROOT_DIR_PATH="$(cd $(dirname $0)/.. && pwd)" + +pushd "${ROOT_DIR_PATH}" > /dev/null + bundle install + bundle exec rspec spec + rubocop spec +popd > /dev/null \ No newline at end of file diff --git a/spec/auctioneer_template_spec.rb b/spec/auctioneer_template_spec.rb new file mode 100644 index 0000000000..5c0eec9af6 --- /dev/null +++ b/spec/auctioneer_template_spec.rb @@ -0,0 +1,65 @@ +# frozen_string_literal: true + +# rubocop: disable Metrics/BlockLength +require 'rspec' +require 'json' +require 'bosh/template/test' + +describe 'auctioneer' do + let(:release_path) { File.join(File.dirname(__FILE__), '..') } + let(:release) { Bosh::Template::Test::ReleaseDir.new(release_path) } + let(:job) { release.job('auctioneer') } + + describe 'auctioneer.json.erb' do + let(:deployment_manifest_fragment) do + { + 'bpm' => { + 'enabled' => 'true' + }, + 'diego' => { + 'auctioneer' => { + 'bbs' => { + 'ca_cert' => 'CA CERTS', + 'client_cert' => 'CLIENT CERT', + 'client_key' => 'CLIENT KEY' + }, + 'bin_pack_first_fit_weight' => 0, + 'ca_cert' => 'CA CERT', + 'locket' => { + 'client_keepalive_time' => 10, + 'client_keepalive_timeout' => 22 + }, + 'rep' => { + 'ca_cert' => 'CA CERT', + 'client_cert' => 'CLIENT CERT', + 'client_key' => 'CLIENT KEY', + 'require_tls' => 'true' + }, + 'server_cert' => 'SERVER CERT', + 'server_key' => 'SERVER KEY', + 'skip_consul_lock' => 'true' + } + }, + 'enable_consul_service_registration' => 'false', + 'loggregator' => 'LOGGREGATOR PROPS', + 'logging' => { + 'format' => { + 'timestamp' => 'rfc3339' + } + } + } + end + + let(:template) { job.template('config/auctioneer.json') } + let(:rendered_template) { template.render(deployment_manifest_fragment) } + + context 'check if locket keepalive time is bigger than the timeout' do + it 'fails if the keepalive time is bigger than timeout' do + deployment_manifest_fragment['diego']['auctioneer']['locket']['client_keepalive_time'] = 23 + expect do + rendered_template + end.to raise_error(/The locket client keepalive time property should not be larger than the timeout/) + end + end + end +end diff --git a/spec/bbs_template_spec.rb b/spec/bbs_template_spec.rb new file mode 100644 index 0000000000..ca0b19d5bc --- /dev/null +++ b/spec/bbs_template_spec.rb @@ -0,0 +1,85 @@ +# frozen_string_literal: true + +# rubocop: disable Metrics/BlockLength +require 'rspec' +require 'json' +require 'bosh/template/test' + +describe 'bbs' do + let(:release_path) { File.join(File.dirname(__FILE__), '..') } + let(:release) { Bosh::Template::Test::ReleaseDir.new(release_path) } + let(:job) { release.job('bbs') } + + describe 'bbs.json.erb' do + let(:deployment_manifest_fragment) do + { + 'bpm' => { + 'enabled' => 'true' + }, + 'diego' => { + 'bbs' => { + 'active_key_label' => 'ACTIVE KEY', + 'detect_consul_cell_registrations' => 'false', + 'encryption_keys' => [ + 'label' => 'KEY LABEL', + 'passphrase' => 'PASSPHRASE' + ], + 'sql' => { + 'db_host' => 'sql-db.service.cf.internal', + 'db_port' => 3306, + 'db_schema' => 'diego', + 'db_username' => 'diego', + 'db_password' => 'DB PASSWORD', + 'db_driver' => 'mysql', + 'ca_cert' => 'CA CERT', + 'require_ssl' => true + }, + 'ca_cert' => 'CA CERT', + 'auctioneer' => { + 'ca_cert' => 'CA CERT', + 'client_cert' => 'CLIENT CERT', + 'client_key' => 'CLIENT KEY' + }, + 'locket' => { + 'client_keepalive_time' => 10, + 'client_keepalive_timeout' => 22 + }, + 'server_cert' => 'SERVER CERT', + 'server_key' => 'SERVER KEY', + 'skip_consul_lock' => 'true', + 'rep' => { + 'require_tls' => 'true', + 'ca_cert' => 'CA CERT', + 'client_cert' => 'CLIENT CERT', + 'client_key' => 'CLIENT KEY' + } + }, + 'enable_consul_service_registration' => 'false', + 'loggregator' => { + 'use_v2_api' => 'true', + 'ca_cert' => 'CA CERT', + 'client_cert' => 'CLIENT CERT', + 'client_key' => 'CLIENT KEY' + }, + 'logging' => { + 'format' => { + 'timestamp' => 'rfc3339' + } + } + } + } + end + + let(:template) { job.template('config/bbs.json') } + let(:rendered_template) { template.render(deployment_manifest_fragment) } + + context 'check if locket keepalive time is bigger than the timeout' do + it 'fails if the keepalive time is bigger than timeout' do + deployment_manifest_fragment['diego']['bbs']['locket']['client_keepalive_time'] = 23 + expect do + rendered_template + end.to raise_error(/The locket client keepalive time property should not be larger than the timeout/) + end + end + end +end diff --git a/spec/rep_template_spec.rb b/spec/rep_template_spec.rb new file mode 100644 index 0000000000..b8672e9846 --- /dev/null +++ b/spec/rep_template_spec.rb @@ -0,0 +1,82 @@ +# frozen_string_literal: true + +# rubocop: disable Metrics/BlockLength +require 'rspec' +require 'json' +require 'bosh/template/test' + +describe 'rep' do + let(:release_path) { File.join(File.dirname(__FILE__), '..') } + let(:release) { Bosh::Template::Test::ReleaseDir.new(release_path) } + let(:job) { release.job('rep') } + + describe 'rep.json.erb' do + let(:deployment_manifest_fragment) do + { + 'bpm' => { + 'enabled' => 'true' + }, + 'diego' => { + 'executor' => { + 'instance_identity_ca_cert' => 'CA CERT', + 'instance_identity_key' => 'CA KEY' + }, + 'rep' => { + 'locket' => { + 'client_keepalive_time' => 10, + 'client_keepalive_timeout' => 22 + }, + 'preloaded_rootfses' => %w[ + cflinuxfs3 + cflinuxfs4 + ] + } + }, + 'containers' => { + 'proxy' => { + 'enabled' => 'true', + 'require_and_verify_client_certificates' => 'true', + 'trusted_ca_certificates' => [ + 'GOROUTER CA', + 'SSH PROXY CA' + ], + 'verify_subject_alt_name' => [ + 'gorouter.service.cf.internal', + 'ssh-proxy.service.cf.internal' + ] + }, + 'trusted_ca_certificate' => [ + 'DIEGO INSTANCE CA', + 'CREDHUB CA', + 'UAA CA' + ] + }, + 'enable_consul_service_registration' => 'false', + 'enable_declarative_healthcheck' => 'true', + 'loggregator' => 'LOGREGATOR PROPS', + 'tls' => { + 'ca_cert' => 'CA CERT', + 'cert' => 'CERT', + 'key' => 'KEY' + }, + 'logging' => { + 'format' => { + 'timestamp' => 'rfc3339' + } + } + } + end + + let(:template) { job.template('config/rep.json') } + let(:rendered_template) { template.render(deployment_manifest_fragment) } + + context 'check if locket keepalive time is bigger than the timeout' do + it 'fails if the keepalive time is bigger than timeout' do + deployment_manifest_fragment['diego']['rep']['locket']['client_keepalive_time'] = 23 + expect do + rendered_template + end.to raise_error(/The locket client keepalive time property should not be larger than the timeout/) + end + end + end +end