From 1e461181dd2d1cf1ee6990ac3d13f52ba55d77e6 Mon Sep 17 00:00:00 2001 From: Alan Moran Date: Wed, 21 Aug 2024 11:49:20 +0200 Subject: [PATCH] WIP --- Makefile | 6 +- ci/autoscaler/pipeline.yml | 4 +- ci/autoscaler/scripts/deploy-apps.sh | 28 +++ .../scripts/deploy-multiapps-controller.sh | 1 - operations/use-cf-services.yml | 8 +- src/autoscaler/Makefile | 10 +- src/autoscaler/build-extension-file.sh | 59 ++++++ src/autoscaler/example.mtaext | 10 - src/autoscaler/helpers/cf.go | 25 --- src/autoscaler/metricsforwarder/Makefile | 52 ----- .../metricsforwarder/config/config.go | 78 ++++---- .../metricsforwarder/config/config_test.go | 181 ++++++++++++------ .../metricsforwarder/default_config.json | 39 ++++ src/autoscaler/mta.yaml | 15 +- 14 files changed, 316 insertions(+), 200 deletions(-) create mode 100755 src/autoscaler/build-extension-file.sh delete mode 100644 src/autoscaler/example.mtaext delete mode 100644 src/autoscaler/helpers/cf.go create mode 100644 src/autoscaler/metricsforwarder/default_config.json diff --git a/Makefile b/Makefile index 32c9f1e019..7d0ef2115b 100644 --- a/Makefile +++ b/Makefile @@ -453,5 +453,7 @@ go-get-u: $(addsuffix .go-get-u,$(go_modules)) go get -u ./... -mta-deploy: - @make --directory='./src/autoscaler' mta-deploy +deploy-apps: + echo " - deploying apps" + DEBUG="${DEBUG}" ${CI_DIR}/autoscaler/scripts/deploy-apps.sh + diff --git a/ci/autoscaler/pipeline.yml b/ci/autoscaler/pipeline.yml index afb7141a8b..574e4dfa1f 100644 --- a/ci/autoscaler/pipeline.yml +++ b/ci/autoscaler/pipeline.yml @@ -101,8 +101,6 @@ resources: private_key: ((autoscaler-deploy-key-private)) branch: ((branch_name)) fetch_tags: true - paths: - - ci - name: app-autoscaler-release type: git @@ -338,7 +336,7 @@ jobs: - in_parallel: - get: bbl-state - get: app-autoscaler-release - passed: [unit-tests, integration-tests] + # passed: [unit-tests, integration-tests] trigger: true - get: ci - task: make-prerelease diff --git a/ci/autoscaler/scripts/deploy-apps.sh b/ci/autoscaler/scripts/deploy-apps.sh index 1c69188f10..5dc7d31804 100755 --- a/ci/autoscaler/scripts/deploy-apps.sh +++ b/ci/autoscaler/scripts/deploy-apps.sh @@ -6,6 +6,31 @@ script_dir=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) source "${script_dir}/common.sh" source "${script_dir}/vars.source.sh" +pushd "${bbl_state_path}" > /dev/null + eval "$(bbl print-env)" +popd > /dev/null + +function fetch_certs() { + pushd "${autoscaler_dir}/src/autoscaler" > /dev/null + mkdir -p build/assets/certs/policy_db build/assets/certs/storedprocedure_db build/assets/certs/syslog_client + + echo "Pulling policy db certs..." + credhub get -n /bosh-autoscaler/${deployment_name}/postgres_server --key ca --quiet > build/assets/certs/policy_db/ca.crt + credhub get -n /bosh-autoscaler/${deployment_name}/postgres_server --key certificate --quiet > build/assets/certs/policy_db/crt + credhub get -n /bosh-autoscaler/${deployment_name}/postgres_server --key private_key --quiet > build/assets/certs/policy_db/key + + echo "Pulling storeprocedure db certs ..." + credhub get -n /bosh-autoscaler/${deployment_name}/postgres_server --key ca --quiet > build/assets/certs/storedprocedure_db/ca.crt + credhub get -n /bosh-autoscaler/${deployment_name}/postgres_server --key certificate --quiet > build/assets/certs/storedprocedure_db/crt + credhub get -n /bosh-autoscaler/${deployment_name}/postgres_server --key private_key --quiet > build/assets/certs/storedprocedure_db/key + + echo "Pulling syslog-client certs..." + credhub get -n /bosh-autoscaler/cf/syslog_agent_log_cache_tls --key ca --quiet > build/assets/certs/syslog_client/ca.crt + credhub get -n /bosh-autoscaler/cf/syslog_agent_log_cache_tls --key certificate --quiet > build/assets/certs/syslog_client/client.crt + credhub get -n /bosh-autoscaler/cf/syslog_agent_log_cache_tls --key private_key --quiet > build/assets/certs/syslog_client/client.key + popd > /dev/null +} + function deploy() { log "Deploying autoscaler apps for bosh deployment '${deployment_name}' " pushd "${autoscaler_dir}/src/autoscaler" > /dev/null @@ -13,7 +38,10 @@ function deploy() { popd > /dev/null } + + bosh_login cf_login cf_target "${autoscaler_org}" "${autoscaler_space}" +fetch_certs deploy diff --git a/ci/infrastructure/scripts/deploy-multiapps-controller.sh b/ci/infrastructure/scripts/deploy-multiapps-controller.sh index 3483a44c8a..56d471ca9e 100755 --- a/ci/infrastructure/scripts/deploy-multiapps-controller.sh +++ b/ci/infrastructure/scripts/deploy-multiapps-controller.sh @@ -23,7 +23,6 @@ function deploy_multiapps_controller() { mv multiapps-controller-web-war/*.war . pushd multiapps-controller-web-manifest cf push -f ./*.yml "${app_name}" - popd } diff --git a/operations/use-cf-services.yml b/operations/use-cf-services.yml index c56d25d284..20b3829767 100644 --- a/operations/use-cf-services.yml +++ b/operations/use-cf-services.yml @@ -4,11 +4,6 @@ host: ((metricsforwarder_host)) mtls_host: ((metricsforwarder_host)) -# Set the same port for metricsforwarder and healthenpoint routes -- type: replace - path: /instance_groups/name=metricsforwarder/jobs/name=route_registrar/properties/route_registrar/routes/name=autoscaler_metricsforwarder_health/port - value: 6201 - ## add router tcp route for postgres - type: replace path: /instance_groups/name=postgres/jobs/- @@ -53,3 +48,6 @@ - type: replace path: /variables/name=postgres_client/options/alternative_names/- value: ((deployment_name))-postgres.tcp.((system_domain)) + +- type: remove + path: /instance_groups/name=metricsforwarder diff --git a/src/autoscaler/Makefile b/src/autoscaler/Makefile index b29f66ddab..3ae18eeef3 100644 --- a/src/autoscaler/Makefile +++ b/src/autoscaler/Makefile @@ -12,7 +12,7 @@ PACKAGE_DIRS = $(shell go list './...' | grep --invert-match --regexp='/vendor/' DB_HOST ?= localhost DBURL ?= "postgres://postgres:postgres@${DB_HOST}/autoscaler?sslmode=disable" -METRICSFORWARDER_APPNAME ?= "metricsforwarder" +MAKEFILE_DIR := $(dir $(lastword $(MAKEFILE_LIST))) EXTENSION_FILE := $(shell mktemp) export GOWORK=off @@ -154,14 +154,11 @@ clean: .PHONY: mta-deploy mta-deploy: mta-build build-extension-file $(MAKE) -f metricsforwarder/Makefile set-security-group - $(MAKE) -f metricsforwarder/Makefile stop-metricsforwarder-vm @echo "Deploying with extension file: $(EXTENSION_FILE)" - @cf deploy mta_archives/*.mtar -f -e $(EXTENSION_FILE) + @cf deploy mta_archives/*.mtar -f --delete-services -e $(EXTENSION_FILE) build-extension-file: - cp example.mtaext $(EXTENSION_FILE); - sed -i "s/APP_NAME/$(METRICSFORWARDER_APPNAME)/g" $(EXTENSION_FILE); - echo "EXTENSION_FILE: $(EXTENSION_FILE)" + $(MAKEFILE_DIR)/build-extension-file.sh > $(EXTENSION_FILE); mta-logs: rm -rf mta-* @@ -170,7 +167,6 @@ mta-logs: .PHONY: mta-build mta-build: mta-build-clean cf-build - $(MAKE) -f metricsforwarder/Makefile fetch-config mbt build mta-build-clean: diff --git a/src/autoscaler/build-extension-file.sh b/src/autoscaler/build-extension-file.sh new file mode 100755 index 0000000000..de2c9528dd --- /dev/null +++ b/src/autoscaler/build-extension-file.sh @@ -0,0 +1,59 @@ +#!/usr/bin/env bash + +set -e + +if [ -z "${DEPLOYMENT_NAME}" ]; then + echo "DEPLOYMENT_NAME is not set" + exit 1 +fi + +export SYSTEM_DOMAIN="autoscaler.app-runtime-interfaces.ci.cloudfoundry.org" +export POSTGRES_ADDRESS="${DEPLOYMENT_NAME}-postgres.tcp.${SYSTEM_DOMAIN}" +export POLICY_DB_PASSWORD="$(credhub get -n /bosh-autoscaler/${DEPLOYMENT_NAME}/database_password --quiet)" +export STOREPROCEDURE_DB_PASSWORD="$(credhub get -n /bosh-autoscaler/${DEPLOYMENT_NAME}/database_password --quiet)" +export METRICSFORWARDER_HEALTH_PASSWORD="$(credhub get -n /bosh-autoscaler/${DEPLOYMENT_NAME}/autoscaler_metricsforwarder_health_password --quiet)" +export METRICSFORWARDER_APPNAME="${METRICSFORWARDER_APPNAME:-"${DEPLOYMENT_NAME}-metricsforwarder"}" +export POSTGRES_EXTERNAL_PORT="${PR_NUMBER:-5432}" + + +if [ -z "${PR_NUMBER}" ]; then + echo "PR_NUMBER is not set" + exit 1 +fi + + +if [ -z "${SYSTEM_DOMAIN}" ]; then + echo "SYSTEM_DOMAIN is not set" + exit 1 +fi + +if [ -z "${POSTGRES_ADDRESS}" ]; then + echo "POSTGRES_ADDRESS is not set" + exit 1 +fi + +echo ' +ID: development +extends: com.github.cloudfoundry.app-autoscaler-release +version: 1.0.0 +_schema-version: 3.3.0 + +modules: + - name: metricsforwarder + parameters: + routes: + - route: '${METRICSFORWARDER_APPNAME}'.${default-domain} + +resources: +- name: config + parameters: + config: + metricsforwarder: + health: + password: "'"${METRICSFORWARDER_HEALTH_PASSWORD}"'" + db: + policy_db: + url: "postgres://postgres:'"${POLICY_DB_PASSWORD}@${POSTGRES_ADDRESS}:${POSTGRES_EXTERNAL_PORT}"'/autoscaler?application_name=metricsforwarder&sslmode=verify-full&sslrootcert=/home/vcap/app/assets/certs/policy_db/ca.crt&sslcert=/home/vcap/app/assets/certs/policy_db/crt&sslkey=/home/vcap/app/assets/certs/policy_db/key" + storedprocedure_db: + url: "postgres://postgres:STOREPROCEDURE_DB_PASSWORD@$POSTGRES_ADDRESS:POSTGRES_EXTERNAL_PORT/autoscaler?application_name=metricsforwarder&sslmode=verify-full&sslrootcert=/home/vcap/app/assets/certs/storedprocedure_db/ca.crt&sslcert=/home/vcap/app/assets/certs/storedprocedure_db/crt&sslkey=/home/vcap/app/assets/certs/storedprocedure_db/key" +' diff --git a/src/autoscaler/example.mtaext b/src/autoscaler/example.mtaext deleted file mode 100644 index 134038a347..0000000000 --- a/src/autoscaler/example.mtaext +++ /dev/null @@ -1,10 +0,0 @@ -_schema-version: 3.3.0 -ID: development -extends: com.github.cloudfoundry.app-autoscaler-release -version: 1.0.0 - -modules: - - name: metricsforwarder - parameters: - routes: - - route: APP_NAME.${default-domain} diff --git a/src/autoscaler/helpers/cf.go b/src/autoscaler/helpers/cf.go deleted file mode 100644 index 6d37d2cad7..0000000000 --- a/src/autoscaler/helpers/cf.go +++ /dev/null @@ -1,25 +0,0 @@ -package helpers - -import ( - "encoding/json" - "fmt" -) - -func GetDbURLFromVcap(vcapServices string, dbType string) (string, error) { - var vcap map[string][]struct { - Credentials map[string]interface{} `json:"credentials"` - } - - err := json.Unmarshal([]byte(vcapServices), &vcap) - if err != nil { - return "", err - } - - creds := vcap[dbType][0].Credentials - if creds == nil { - return "", fmt.Errorf("credentials not found for %s", dbType) - } - - dbURL := creds["uri"].(string) - return dbURL, nil -} diff --git a/src/autoscaler/metricsforwarder/Makefile b/src/autoscaler/metricsforwarder/Makefile index 5b69047ef2..1d3b9f9d95 100644 --- a/src/autoscaler/metricsforwarder/Makefile +++ b/src/autoscaler/metricsforwarder/Makefile @@ -1,46 +1,4 @@ -PR_NUMBER ?= $(shell gh pr view --json number --jq '.number') -DEPLOYMENT_NAME ?= autoscaler-$(PR_NUMBER) -SYSTEM_DOMAIN ?=autoscaler.app-runtime-interfaces.ci.cloudfoundry.org -METIRCSFORWARDER_VM := $(shell bosh -d $(DEPLOYMENT_NAME) vms --json | jq '.Tables | .[] | .Rows | .[] | select(.instance|test("metricsforwarder")) | .instance') -POSTGRES_ADDRESS := $(DEPLOYMENT_NAME)-postgres.tcp.$(SYSTEM_DOMAIN) -LOG_CACHE_IP := $(shell bosh -d cf vms --json | jq -r '.Tables | .[] | .Rows | .[] | select(.instance|test("log-cache")) | .ips' ) MAKEFILE_DIR := $(dir $(lastword $(MAKEFILE_LIST))) -POSTGRES_EXTERNAL_PORT := $(or $(PR_NUMBER),5432) - - -.PHONY: fetch-config -fetch-config: start-metricsforwarder-vm - # how to define variables in deployment name - mkdir -p build/assets/certs/policy_db build/assets/certs/storedprocedure_db build/assets/certs/syslog_client - - echo "POSTGRES ADDRESS: $(POSTGRES_ADDRESS)" - echo "LOG_CACHE IP: $(LOG_CACHE_IP)" - - @echo "Pulling metricforwarder config from $(METIRCSFORWARDER_VM)..." - bosh -d $(DEPLOYMENT_NAME) scp $(METIRCSFORWARDER_VM):/var/vcap/jobs/metricsforwarder/config/metricsforwarder.yml build/assets/metricsforwarder.yml - - @echo "Pulling policy db certs from $(METIRCSFORWARDER_VM)..." - bosh -d $(DEPLOYMENT_NAME) scp $(METIRCSFORWARDER_VM):/var/vcap/jobs/metricsforwarder/config/certs/policy_db/ca.crt build/assets/certs/policy_db/. - bosh -d $(DEPLOYMENT_NAME) scp $(METIRCSFORWARDER_VM):/var/vcap/jobs/metricsforwarder/config/certs/policy_db/crt build/assets/certs/policy_db/. - bosh -d $(DEPLOYMENT_NAME) scp $(METIRCSFORWARDER_VM):/var/vcap/jobs/metricsforwarder/config/certs/policy_db/key build/assets/certs/policy_db/. - - @echo "Pulling storeprocedure db certs from $(METIRCSFORWARDER_VM)..." - bosh -d $(DEPLOYMENT_NAME) scp $(METIRCSFORWARDER_VM):/var/vcap/jobs/metricsforwarder/config/certs/storedprocedure_db/ca.crt build/assets/certs/storedprocedure_db/. - bosh -d $(DEPLOYMENT_NAME) scp $(METIRCSFORWARDER_VM):/var/vcap/jobs/metricsforwarder/config/certs/storedprocedure_db/crt build/assets/certs/storedprocedure_db/. - bosh -d $(DEPLOYMENT_NAME) scp $(METIRCSFORWARDER_VM):/var/vcap/jobs/metricsforwarder/config/certs/storedprocedure_db/key build/assets/certs/storedprocedure_db/. - - @echo "Pulling syslog-client certs from $(METIRCSFORWARDER_VM)..." - bosh -d $(DEPLOYMENT_NAME) scp $(METIRCSFORWARDER_VM):/var/vcap/jobs/metricsforwarder/config/certs/syslog_client/ca.crt build/assets/certs/syslog_client/. - bosh -d $(DEPLOYMENT_NAME) scp $(METIRCSFORWARDER_VM):/var/vcap/jobs/metricsforwarder/config/certs/syslog_client/client.crt build/assets/certs/syslog_client/. - bosh -d $(DEPLOYMENT_NAME) scp $(METIRCSFORWARDER_VM):/var/vcap/jobs/metricsforwarder/config/certs/syslog_client/client.key build/assets/certs/syslog_client/. - - @echo "Build metricsforwarder config yaml" - cp build/assets/metricsforwarder.yml build/metricsforwarder.yml - - sed -i'' -e 's|\/var\/vcap\/jobs\/metricsforwarder\/config|\/home\/vcap\/app/assets|g' build/metricsforwarder.yml - sed -i'' -e 's|$(DEPLOYMENT_NAME).autoscalerpostgres.service.cf.internal:5432|$(POSTGRES_ADDRESS):$(POSTGRES_EXTERNAL_PORT)|g' build/metricsforwarder.yml - - PHONY: set-security-group set-security-group: @@ -49,13 +7,3 @@ set-security-group: cf create-security-group metricsforwarder $(MAKEFILE_DIR)/security-group.json cf bind-security-group metricsforwarder $(ORG) - -PHONY: start-metricsforwarder-vm -start-metricsforwarder-vm: - bosh -d $(DEPLOYMENT_NAME) -n start $(METIRCSFORWARDER_VM) - -PHONY: stop-metricsforwarder-vm -stop-metricsforwarder-vm: - bosh -d $(DEPLOYMENT_NAME) -n stop $(METIRCSFORWARDER_VM) - - diff --git a/src/autoscaler/metricsforwarder/config/config.go b/src/autoscaler/metricsforwarder/config/config.go index 127ef173a0..7b46734a14 100644 --- a/src/autoscaler/metricsforwarder/config/config.go +++ b/src/autoscaler/metricsforwarder/config/config.go @@ -4,6 +4,7 @@ import ( "encoding/json" "errors" "fmt" + "net/url" "os" "time" @@ -25,6 +26,7 @@ var ErrReadYaml = errors.New("failed to read config file") var ErrReadJson = errors.New("failed to read vcap_services json") var ErrReadEnvironment = errors.New("failed to read environment variables") var ErrReadVCAPEnvironment = errors.New("failed to read VCAP environment variables") +var ErrMetricsforwarderConfigNotFound = errors.New("Configuration error: metricsforwarder config service not found") const ( DefaultMetronAddress = "127.0.0.1:3458" @@ -102,6 +104,10 @@ func decodeYamlFile(filepath string, c *Config) error { func readConfigFromVCAP(appEnv *cfenv.App, c *Config) error { configVcapService, err := appEnv.Services.WithName("config") + if err != nil { + return fmt.Errorf("%w: %w", ErrMetricsforwarderConfigNotFound, err) + } + data := configVcapService.Credentials["metricsforwarder"] rawJSON, err := json.Marshal(data) @@ -152,14 +158,14 @@ func LoadConfig(filepath string) (*Config, error) { conf.Server.Port = appEnv.Port - err = readDbFromVCAP(appEnv, &conf) + err = readConfigFromVCAP(appEnv, &conf) if err != nil { - return &conf, err + return nil, err } - err = readConfigFromVCAP(appEnv, &conf) + err = readDbFromVCAP(appEnv, &conf) if err != nil { - return nil, err + return &conf, err } } @@ -213,13 +219,10 @@ func (c *Config) Validate() error { return nil } func readDbFromVCAP(appEnv *cfenv.App, c *Config) error { - if c.Db != nil { - return nil - } - dbServices, err := appEnv.Services.WithTag("relational") if err != nil { - return fmt.Errorf("failed to get db service with relational tag") + fmt.Printf("failed to get db service with relational tag: %s\n", err.Error()) + return nil } if len(dbServices) != 1 { @@ -237,36 +240,47 @@ func readDbFromVCAP(appEnv *cfenv.App, c *Config) error { c.Db = make(map[string]db.DatabaseConfig) } - c.Db[db.PolicyDb] = db.DatabaseConfig{ - URL: dbURI, + dbURL, err := url.Parse(dbURI) + if err != nil { + return err } - //dbURL, err := url.Parse(dbURI) - //if err != nil { - // return nil, err - //} + parameters, err := url.ParseQuery(dbURL.RawQuery) + if err != nil { + return err + } - //parameters, err := url.ParseQuery(dbURL.RawQuery) - //if err != nil { - // return nil, err - //} + err = materializeConnectionParameter(dbService, ¶meters, "client_cert", "sslcert") + if err != nil { + return err + } - //err = materializeConnectionParameter(dbService, parameters, "client_cert", "sslcert") - //if err != nil { - // return nil, err - //} + err = materializeConnectionParameter(dbService, ¶meters, "client_key", "sslkey") + if err != nil { + return err + } - //err = materializeConnectionParameter(dbService, parameters, "client_key", "sslkey") - //if err != nil { - // return nil, err - //} + err = materializeConnectionParameter(dbService, ¶meters, "server_ca", "sslrootcert") + if err != nil { + return err + } - //err = materializeConnectionParameter(dbService, parameters, "server_ca", "sslrootcert") - //if err != nil { - // return nil, err - //} + dbURL.RawQuery = parameters.Encode() - //dbURL.RawQuery = parameters.Encode() + c.Db[db.PolicyDb] = db.DatabaseConfig{ + URL: dbURL.String(), + } + return nil +} +func materializeConnectionParameter(dbService cfenv.Service, parameters *url.Values, bindingProperty string, connectionParameter string) error { + if propertyValue, hasProperty := dbService.CredentialString(bindingProperty); hasProperty { + propertyFile := "/tmp/" + bindingProperty + "." + connectionParameter + err := os.WriteFile(propertyFile, []byte(propertyValue), 0600) + if err != nil { + return err + } + parameters.Set(connectionParameter, propertyFile) + } return nil } diff --git a/src/autoscaler/metricsforwarder/config/config_test.go b/src/autoscaler/metricsforwarder/config/config_test.go index 06a445fba4..1844689d65 100644 --- a/src/autoscaler/metricsforwarder/config/config_test.go +++ b/src/autoscaler/metricsforwarder/config/config_test.go @@ -1,6 +1,9 @@ package config_test import ( + "encoding/json" + "io/ioutil" + "net/url" "os" "time" @@ -33,6 +36,7 @@ var _ = Describe("Config", func() { ) Describe("LoadConfig", func() { + When("config is read from env", func() { var vcapServicesJson string var port string @@ -53,75 +57,124 @@ var _ = Describe("Config", func() { When("PORT env variable is set to a number ", func() { BeforeEach(func() { - vcapServicesJson = "{}" + vcapServicesJson = `{ "user-provided": [ { "name": "config" } ] }` port = "3333" }) It("sets env variable over config file", func() { + Expect(err).NotTo(HaveOccurred()) Expect(conf.Server.Port).To(Equal(3333)) }) }) - When("VCAP_SERVICES has service config", func() { + When("VCAP_SERVICES is empty", func() { + BeforeEach(func() { + vcapServicesJson = "{}" + }) + + It("should error with config service not found", func() { + Expect(err).To(MatchError(MatchRegexp("Configuration error: metricsforwarder config service not found"))) + }) + }) + + When("VCAP_SERVICES has policy db service", func() { + When("VCAP_SERVICES has policy db service with uri", func() { + BeforeEach(func() { + vcapServicesJson = getDbVcapServices(map[string]string{ + "uri": "postgres://foo:bar@postgres.example.com:5432/policy_db", + }) + }) + + It("loads the db config from VCAP_SERVICES", func() { + expectedDbConfig := db.DatabaseConfig{ + URL: "postgres://foo:bar@postgres.example.com:5432/policy_db", + } + + Expect(err).NotTo(HaveOccurred()) + Expect(conf.Db[db.PolicyDb]).To(Equal(expectedDbConfig)) + }) + }) + + Describe("when uri is wrong", func() { + BeforeEach(func() { + vcapServicesJson = getDbVcapServices(map[string]string{ + "uri": "http://example.com/path\x00with/invalid/character", + }) + }) + + It("errors", func() { + Expect(err).To(HaveOccurred()) + }) + }) + + Describe("when certificates are set", func() { + var expectedClientCertContent = "client-cert-content" + var expectedClientKeyContent = "client-key-content" + var expectedServerCaContent = "server-ca-content" + + BeforeEach(func() { + vcapServicesJson = getDbVcapServices(map[string]string{ + "uri": "postgres://foo:bar@postgres.example.com:5432/policy_db", + "client_cert": expectedClientCertContent, + "client_key": expectedClientKeyContent, + "server_ca": expectedServerCaContent, + }) + }) + + It("writes certs to /tmp and assigns them to the DB config", func() { + Expect(err).NotTo(HaveOccurred()) + parsedURL, err := url.Parse(conf.Db[db.PolicyDb].URL) + Expect(err).NotTo(HaveOccurred()) + queryParams := parsedURL.Query() + + assertCertFile := func(certType, expectedContent string) { + certPath := queryParams.Get(certType) + Expect(certPath).NotTo(BeEmpty(), "expected %s to be set in the db URL", certType) + actualContent, err := ioutil.ReadFile(certPath) + Expect(err).NotTo(HaveOccurred()) + Expect(string(actualContent)).To(Equal(expectedContent)) + } + + assertCertFile("sslcert", expectedClientCertContent) + assertCertFile("sslkey", expectedClientKeyContent) + assertCertFile("sslrootcert", expectedServerCaContent) + }) + + AfterEach(func() { + os.Remove("/tmp/client_cert.sslcert") + os.Remove("/tmp/client_key.sslkey") + os.Remove("/tmp/server_ca.sslrootcert") + }) + }) + }) + + When("VCAP_SERVICES has metricsforwarder config", func() { BeforeEach(func() { - // VCAP_SERVICES={"user-provided":[ - //{"label":"user-provided", - // "name":"config", - // "tags":[], - // "instance_guid":"444c838e-17d9-429d-a1ea-660904db9841", - // "instance_name":"config", - // "binding_guid":"2cb523a1-773a-4fa4-ba05-3a76cc488ff7", - // "binding_name":null, - // "credentials":{ - // "db":null, - // "logging":{"level":"info"}, - // "policy_poller_interval":"60s", - // "rate_limit":{"max_amount":10,"valid_duration":"1s"}, - // "syslog":{ - // "port":6067, - // "server_address":"log-cache.service.cf.internal", - // "tls":{"ca_file":"/var/vcap/jobs/metricsforwarder/config/certs/syslog_client/ca.crt","cert_file":"/var/vcap/jobs/metricsforwarder/config/certs/syslog_client/client.crt","key_file":"/var/vcap/jobs/metricsforwarder/config/certs/syslog_client/client.key"} - // }, - // } - //}, - // "syslog_drain_url":null, - // "volume_mounts":[]}]} - // vcapServicesJson = `{ "user-provided": [ { "label":"user-provided", "name": "config", "credentials": { - "metricsforwarder": { - "cache_cleanup_interval":"10h", - "cache_ttl":"90s", - "cred_helper_impl": "default", - "health":{"password":"health-password","username":"health-user"}, - "logging": { - "level": "debug" - }, - "loggregator": { - "metron_address": "metron-vcap-addrs:3457", - "tls": { - "ca_file": "../testcerts/ca.crt", - "cert_file": "../testcerts/client.crt", - "key_file": "../testcerts/client.key" + "metricsforwarder": { + "cache_cleanup_interval":"10h", + "cache_ttl":"90s", + "cred_helper_impl": "default", + "health":{"password":"health-password","username":"health-user"}, + "logging": { + "level": "debug" + }, + "loggregator": { + "metron_address": "metron-vcap-addrs:3457", + "tls": { + "ca_file": "../testcerts/ca.crt", + "cert_file": "../testcerts/client.crt", + "key_file": "../testcerts/client.key" + } } } } - } - }], - "autoscaler": [ { - "name": "policy_db", - "label": "postgres", - "credentials": { - "uri":"postgres://foo:bar@postgres.example.com:5432/policy_db" - }, - "syslog_drain_url": "", - "tags": ["postgres","postgresql","relational"] - } - ] - }` // #nosec G101 + } + ]}` // #nosec G101 }) It("loads the config from VCAP_SERVICES", func() { @@ -130,15 +183,6 @@ var _ = Describe("Config", func() { Expect(conf.LoggregatorConfig.MetronAddress).To(Equal("metron-vcap-addrs:3457")) Expect(conf.CacheTTL).To(Equal(90 * time.Second)) }) - - It("loads the db config from VCAP_SERVICES", func() { - expectedDbConfig := db.DatabaseConfig{ - URL: "postgres://foo:bar@postgres.example.com:5432/policy_db", - } - - Expect(err).NotTo(HaveOccurred()) - Expect(conf.Db[db.PolicyDb]).To(Equal(expectedDbConfig)) - }) }) }) @@ -390,3 +434,18 @@ health: }) }) }) + +func getDbVcapServices(creds map[string]string) string { + credentials, err := json.Marshal(creds) + Expect(err).NotTo(HaveOccurred()) + return `{ + "user-provided": [ { "name": "config", "credentials": { "metricsforwarder": { } }}], + "autoscaler": [ { + "name": "policy_db", + "label": "postgres", + "credentials": ` + string(credentials) + `, + "syslog_drain_url": "", + "tags": ["postgres","postgresql","relational"] + } + ]}` // #nosec G101 +} diff --git a/src/autoscaler/metricsforwarder/default_config.json b/src/autoscaler/metricsforwarder/default_config.json new file mode 100644 index 0000000000..26167e46e4 --- /dev/null +++ b/src/autoscaler/metricsforwarder/default_config.json @@ -0,0 +1,39 @@ +{ + "metricsforwarder": { + "cache_cleanup_interval": "6h", + "cache_ttl": "900s", + "cred_helper_impl": "default", + "health": { + "username": "metricsforwarder" + }, + "logging": { + "level": "debug" + }, + "syslog": { + "server_address": "log-cache.service.cf.internal", + "port": 6067, + "tls": { + "ca_file": "/home/vcap/app/assets/certs/syslog_client/ca.crt", + "cert_file": "/home/vcap/app/assets/certs/syslog_client/client.crt", + "key_file": "/home/vcap/app/assets/certs/syslog_client/client.key" + } + }, + "db": { + "policy_db": { + "max_open_connections": 100, + "max_idle_connections": 10, + "connection_max_lifetime": "60s" + }, + "storedprocedure_db": { + "max_open_connections": 20, + "max_idle_connections": 10, + "connection_max_lifetime": "60s" + } + }, + "policy_poller_interval": "60s", + "rate_limit": { + "valid_duration": "1s", + "max_amount": 10 + } + } +} diff --git a/src/autoscaler/mta.yaml b/src/autoscaler/mta.yaml index eff830b6c9..8b8391caad 100644 --- a/src/autoscaler/mta.yaml +++ b/src/autoscaler/mta.yaml @@ -9,10 +9,21 @@ modules: - name: metricsforwarder type: binary path: build + requires: + - name: config parameters: memory: 1G disk-quota: 1G - instances: 1 + instances: 2 stack: cflinuxfs4 - command: ./metricsforwarder -c metricsforwarder.yml + command: ./metricsforwarder routes: + +resources: +- name: config + type: org.cloudfoundry.user-provided-service + parameters: + path: metricsforwarder/default_config.json + + +