Skip to content

Commit

Permalink
Refactor metricsforwarder config loading and enhance DB URL customiz…
Browse files Browse the repository at this point in the history
…ation

 - Implement parsing and customization of the stored procedure DB URL with configurable username and password.
 - Move the TLS config materialization for the syslog-client outside of the conditional block.
 - Update tests to reflect changes in config loading and to test new DB URL customization logic.
 - Add username and password fields to the StoredProcedureConfig struct.
  • Loading branch information
bonzofenix committed Sep 18, 2024
1 parent ede42ac commit e753aa7
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 12 deletions.
29 changes: 25 additions & 4 deletions src/autoscaler/metricsforwarder/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ package config
import (
"errors"
"fmt"
"net/url"
"os"
"strings"
"time"

"code.cloudfoundry.org/app-autoscaler/src/autoscaler/configutil"
Expand Down Expand Up @@ -158,17 +160,36 @@ func LoadConfig(filepath string, vcapReader configutil.VCAPConfigurationReader)
if !ok {
conf.Db[db.StoredProcedureDb] = db.DatabaseConfig{}
}

currentStoredProcedureDb.URL, err = vcapReader.MaterializeDBFromService(db.StoredProcedureDb)
if err != nil {
return &conf, err
}

dbURL, err := url.Parse(currentStoredProcedureDb.URL)
if err != nil {
return &conf, err
}

if conf.StoredProcedureConfig != nil {
if conf.StoredProcedureConfig.Username != "" {
currentStoredProcedureDb.URL = strings.Replace(currentStoredProcedureDb.URL, dbURL.User.Username(), conf.StoredProcedureConfig.Username, 1)
}

if conf.StoredProcedureConfig.Password != "" {
bindingPassword, _ := dbURL.User.Password()
currentStoredProcedureDb.URL = strings.Replace(currentStoredProcedureDb.URL, bindingPassword, conf.StoredProcedureConfig.Password, 1)
}
}

conf.Db[db.StoredProcedureDb] = currentStoredProcedureDb
}

conf.SyslogConfig.TLS, err = vcapReader.MaterializeTLSConfigFromService("syslog-client")
if err != nil {
return &conf, err
}
}

conf.SyslogConfig.TLS, err = vcapReader.MaterializeTLSConfigFromService("syslog-client")
if err != nil {
return &conf, err
}

return &conf, nil
Expand Down
39 changes: 31 additions & 8 deletions src/autoscaler/metricsforwarder/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ var _ = Describe("Config", func() {

When("VCAP_SERVICES has relational db service bind to app for policy db", func() {
BeforeEach(func() {
mockVCAPConfigurationReader.GetServiceCredentialContentReturns(getVcapConfigWithCredImplementation("default"), nil)
mockVCAPConfigurationReader.GetServiceCredentialContentReturns([]byte(`{ "cred_helper_impl": "default" }`), nil) // #nosec G101
expectedDbUrl = "postgres://foo:[email protected]:5432/policy_db?sslcert=%2Ftmp%2Fclient_cert.sslcert&sslkey=%2Ftmp%2Fclient_key.sslkey&sslrootcert=%2Ftmp%2Fserver_ca.sslrootcert" // #nosec G101
})

Expand All @@ -108,7 +108,7 @@ var _ = Describe("Config", func() {

When("storedProcedure_db service is provided and cred_helper_impl is stored_procedure", func() {
BeforeEach(func() {
mockVCAPConfigurationReader.GetServiceCredentialContentReturns(getVcapConfigWithCredImplementation("stored_procedure"), nil)
mockVCAPConfigurationReader.GetServiceCredentialContentReturns([]byte(`{ "cred_helper_impl": "stored_procedure" }`), nil) // #nosec G101
expectedDbUrl = "postgres://foo:[email protected]:5432/policy_db?sslcert=%2Ftmp%2Fclient_cert.sslcert&sslkey=%2Ftmp%2Fclient_key.sslkey&sslrootcert=%2Ftmp%2Fserver_ca.sslrootcert" // #nosec G101
})

Expand All @@ -121,11 +121,39 @@ var _ = Describe("Config", func() {
actualDbName := mockVCAPConfigurationReader.MaterializeDBFromServiceArgsForCall(1)
Expect(actualDbName).To(Equal(db.StoredProcedureDb))
})

When("storedProcedure_db config has username and password", func() {
var storedProcedureUsername, storedProcedurePassword string

BeforeEach(func() {
storedProcedureUsername = "storedProcedureUsername"
storedProcedurePassword = "storedProcedurePassword"

mockVCAPConfigurationReader.GetServiceCredentialContentReturns([]byte(
`{ "cred_helper_impl": "stored_procedure",
"stored_procedure_binding_credential_config": {
"username": "`+storedProcedureUsername+`",
"password": "`+storedProcedurePassword+`"
},
}`),
nil,
) // #nosec G101
})

It("should prioritize the username and password from the config", func() {
// url should include the username and password from the config
Expect(err).NotTo(HaveOccurred())
_, storeProcedureFound := conf.Db[db.StoredProcedureDb]
Expect(storeProcedureFound).To(BeTrue())
Expect(conf.Db[db.StoredProcedureDb].URL).To(ContainSubstring(fmt.Sprintf("%s:%s", storedProcedureUsername, storedProcedurePassword)))
})
})
})

When("storedProcedure_db service is provided and cred_helper_impl is default", func() {
BeforeEach(func() {
mockVCAPConfigurationReader.GetServiceCredentialContentReturns(getVcapConfigWithCredImplementation("default"), nil)
mockVCAPConfigurationReader.GetServiceCredentialContentReturns([]byte(
`{ "cred_helper_impl": "default" }`), nil) // #nosec G101
expectedDbUrl = "postgres://foo:[email protected]:5432/policy_db?sslcert=%2Ftmp%2Fclient_cert.sslcert&sslkey=%2Ftmp%2Fclient_key.sslkey&sslrootcert=%2Ftmp%2Fserver_ca.sslrootcert" // #nosec G101
})

Expand All @@ -138,7 +166,6 @@ var _ = Describe("Config", func() {

When("VCAP_SERVICES has metricsforwarder config", func() {
BeforeEach(func() {

mockVCAPConfigurationReader.GetServiceCredentialContentReturns([]byte(` {
"cache_cleanup_interval":"10h",
"cache_ttl":"90s",
Expand Down Expand Up @@ -414,7 +441,3 @@ health:
})
})
})

func getVcapConfigWithCredImplementation(credHelperImplementation string) []byte {
return []byte(`{ "cred_helper_impl": "` + credHelperImplementation + `" }`) // #nosec G101
}
2 changes: 2 additions & 0 deletions src/autoscaler/models/stored_procedure.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,6 @@ type StoredProcedureConfig struct {
DropBindingCredentialProcedureName string `yaml:"drop_binding_credential_procedure_name"`
DropAllBindingCredentialProcedureName string `yaml:"drop_all_binding_credential_procedure_name"`
ValidateBindingCredentialProcedureName string `yaml:"validate_binding_credential_procedure_name"`
Username string `yaml:"username"`
Password string `yaml:"password"`
}

0 comments on commit e753aa7

Please sign in to comment.