Skip to content

Commit

Permalink
Merge pull request #3405 from cloudfoundry-incubator/envvars
Browse files Browse the repository at this point in the history
Envvars - updated PR with v2-master changes
  • Loading branch information
nwmac authored Feb 15, 2019
2 parents 7b34dc5 + 4ccfb34 commit 2e93487
Show file tree
Hide file tree
Showing 19 changed files with 264 additions and 246 deletions.
24 changes: 24 additions & 0 deletions Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions manifest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,9 @@ applications:
# Turn on backend debugging
# LOG_LEVEL: debug

# User provided services can also be used to set environment properties:
# env:
# CF_UPS_NAME: stratos-properties
# services:
# - stratos-properties
# cf create-user-provided-service stratos-properties -p '{"CF_CLIENT":"stratos","CF_CLIENT_SECRET":"xxxx"}'
108 changes: 41 additions & 67 deletions src/jetstream/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,12 @@ import (
"strconv"
"strings"

"github.com/govau/cf-common/env"
log "github.com/sirupsen/logrus"
)

const secretsDir = "/etc/secrets"

var loadedConfig map[string]string

// Load the given pointer to struct with values from the environment and the
// /etc/secrets/ directory.
//
Expand All @@ -37,7 +36,7 @@ var loadedConfig map[string]string
// The name will be given as defined to Getenv, and if that fails a lookup
// it's name is then munged to conform to the /etc/secrets filename structure
// and the file is attempted to be read.
func Load(intf interface{}) error {
func Load(intf interface{}, envLookup env.Lookup) error {
value := reflect.ValueOf(intf)

if value.Kind() != reflect.Ptr {
Expand All @@ -60,21 +59,18 @@ func Load(intf interface{}) error {
continue
}

if err := setFieldValue(value, field, tag); err != nil {
if err := setFieldValue(value, field, tag, envLookup); err != nil {
return err
}
}

return nil
}

func setFieldValue(value reflect.Value, field reflect.Value, tag string) error {
val, err := GetValue(tag)
if err != nil && !isNotFoundErr(err) {
return err
}
func setFieldValue(value reflect.Value, field reflect.Value, tag string, envLookup env.Lookup) error {
val, ok := envLookup(tag)

if len(val) == 0 {
if !ok {
return nil
}

Expand Down Expand Up @@ -133,49 +129,25 @@ func SetStructFieldValue(value reflect.Value, field reflect.Value, val string) e
return nil
}

// IsSet - is the specified config name set?
func IsSet(name string) bool {
_, err := GetValue(name)
return err == nil
}

// GetString - Get the string value for the named configuration property
func GetString(name string) string {
v, _ := GetValue(name)
return v
}

// GetValue tries to look up an env var of the given name and then
// tries to look up the secret file of the same
func GetValue(name string) (string, error) {
env := os.Getenv(name)
if len(env) == 0 {
env = loadedConfig[name]
}

if len(env) == 0 {
return readSecretFileTestHarness(name)
}

return env, nil
}

var readSecretFileTestHarness = readSecretFile

// readSecretFile reads a variable in the form HELLO_THERE from a file
// NewSecretsDirLookup - create a secret dir lookup
// reads a variable in the form HELLO_THERE from a file
// in /etc/secrets/hello-there
func readSecretFile(name string) (string, error) {
name = strings.ToLower(strings.Replace(name, "_", "-", -1))
filename := filepath.Join(secretsDir, name)

contents, err := ioutil.ReadFile(filename)
if os.IsNotExist(err) {
return "", notFoundErr(filename)
} else if err != nil {
return "", fmt.Errorf("failed to read secret file %q: %v", name, err)
func NewSecretsDirLookup(secretsDir string) env.Lookup {
return func(name string) (string, bool) {
name = strings.ToLower(strings.Replace(name, "_", "-", -1))
filename := filepath.Join(secretsDir, name)

if _, err := os.Stat(filename); err == nil {
contents, err := ioutil.ReadFile(filename)
if err != nil {
log.Warnf("Error reading secrets file: %s, %s", filename, err)
return "", false
}
return strings.TrimSpace(string(contents)), true
}
// File does not exist
return "", false
}

return strings.TrimSpace(string(contents)), nil
}

type notFoundErr string
Expand All @@ -192,18 +164,22 @@ func (n notFoundErr) Error() string {
return fmt.Sprintf("could not find secret file: %s", string(n))
}

// LoadConfigFile - Load the configuration values in the specified config file if it exists
func LoadConfigFile(path string) error {
// NewConfigFileLookup - Load the configuration values in the specified config file if it exists
func NewConfigFileLookup(path string) env.Lookup {

// Check if the config file exists
if _, err := os.Stat(path); err != nil {
return env.NoopLookup
}

file, err := os.Open(path)
if err != nil {
if !os.IsNotExist(err) {
log.Warn("Error reading configuraion file", err)
}
return err
log.Warn("Error reading configuration file, ignoring this file: ", err)
return env.NoopLookup
}
defer file.Close()

loadedConfig = make(map[string]string)
loadedConfig := make(map[string]string)
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := scanner.Text()
Expand All @@ -217,17 +193,15 @@ func LoadConfigFile(path string) error {
}
}

if err := scanner.Err(); err != nil {
log.Warn("Error reading configuration file", err)
return err
if scanner.Err() != nil {
// Error reading configuration file, ignoring this file
return env.NoopLookup
}

log.Infof("Loaded configuration from file: %s", path)

return nil
}

// SetConfigValue will update/set a value in the loaded configuration
func SetConfigValue(name, value string) {
loadedConfig[name] = value
return func(k string) (string, bool) {
v, ok := loadedConfig[k]
return v, ok
}
}
8 changes: 4 additions & 4 deletions src/jetstream/datastore/database_cf_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"strconv"
"strings"

"github.com/cloudfoundry-incubator/stratos/src/jetstream/config"
"github.com/govau/cf-common/env"
log "github.com/sirupsen/logrus"
)

Expand All @@ -27,13 +27,13 @@ type VCAPService struct {
}

// Discover cf db services via their 'uri' env var and apply settings to the DatabaseConfig objects
func ParseCFEnvs(db *DatabaseConfig) (bool, error) {
if config.IsSet(SERVICES_ENV) == false {
func ParseCFEnvs(db *DatabaseConfig, env *env.VarSet) (bool, error) {
if !env.IsSet(SERVICES_ENV) {
return false, nil
}

// Extract struts from VCAP_SERVICES env
vcapServicesStr := config.GetString(SERVICES_ENV)
vcapServicesStr := env.MustString(SERVICES_ENV)
var vcapServices map[string][]VCAPService
err := json.Unmarshal([]byte(vcapServicesStr), &vcapServices)
if err != nil {
Expand Down
16 changes: 8 additions & 8 deletions src/jetstream/datastore/datastore.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@ import (
"strings"
"time"

"github.com/cloudfoundry-incubator/stratos/src/jetstream/config"
"github.com/cloudfoundry-incubator/stratos/src/jetstream/repository/goose-db-version"

goosedbversion "github.com/cloudfoundry-incubator/stratos/src/jetstream/repository/goose-db-version"
"github.com/govau/cf-common/env"
log "github.com/sirupsen/logrus"

// Mysql driver
_ "github.com/go-sql-driver/mysql"
"github.com/kat-co/vala"

// Sqlite driver
_ "github.com/mattn/go-sqlite3"

Expand Down Expand Up @@ -133,7 +134,7 @@ func validateRequiredDatabaseParams(username, password, database, host string, p
}

// GetConnection returns a database connection to either PostgreSQL or SQLite
func GetConnection(dc DatabaseConfig) (*sql.DB, error) {
func GetConnection(dc DatabaseConfig, env *env.VarSet) (*sql.DB, error) {
log.Debug("GetConnection")

if dc.DatabaseProvider == PGSQL {
Expand All @@ -146,13 +147,12 @@ func GetConnection(dc DatabaseConfig) (*sql.DB, error) {
}

// SQL Lite
return GetSQLLiteConnection()
return GetSQLLiteConnection(env.MustBool("SQLITE_KEEP_DB"))
}

// GetSQLLiteConnection returns an SQLite DB Connection
func GetSQLLiteConnection() (*sql.DB, error) {

if !config.IsSet("SQLITE_KEEP_DB") {
func GetSQLLiteConnection(sqliteKeepDB bool) (*sql.DB, error) {
if !sqliteKeepDB {
os.Remove(SQLiteDatabaseFile)
}

Expand Down
14 changes: 7 additions & 7 deletions src/jetstream/diagnostics.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (

log "github.com/sirupsen/logrus"

"github.com/cloudfoundry-incubator/stratos/src/jetstream/config"
"github.com/cloudfoundry-incubator/stratos/src/jetstream/repository/goose-db-version"
"github.com/cloudfoundry-incubator/stratos/src/jetstream/repository/interfaces"
)
Expand Down Expand Up @@ -35,20 +34,21 @@ func (p *portalProxy) StoreDiagnostics() {
}

// Deployment information - when deployed via Helm
diagnostics.HelmName = config.GetString("HELM_NAME")
diagnostics.HelmRevision = config.GetString("HELM_REVISION")
diagnostics.HelmChartVersion = config.GetString("HELM_CHART_VERSION")
diagnostics.HelmLastModified = config.GetString("HELM_LAST_MODIFIED")

diagnostics.HelmName = p.Env().String("HELM_NAME", "")
diagnostics.HelmRevision = p.Env().String("HELM_REVISION", "")
diagnostics.HelmChartVersion = p.Env().String("HELM_CHART_VERSION", "")
diagnostics.HelmLastModified = p.Env().String("HELM_LAST_MODIFIED", "")

// Deployment type
switch {
case len(diagnostics.HelmName) > 0:
diagnostics.DeploymentType = "Kubernetes"
case p.Config.IsCloudFoundry:
diagnostics.DeploymentType = "Cloud Foundry"
case len(config.GetString("STRATOS_DEPLOYMENT_DOCKER")) > 0:
case len(p.Env().String("STRATOS_DEPLOYMENT_DOCKER", "")) > 0:
diagnostics.DeploymentType = "Docker"
case len(config.GetString("STRATOS_DEPLOYMENT_DOCKER_AIO")) > 0:
case len(p.Env().String("STRATOS_DEPLOYMENT_DOCKER_AIO", "")) > 0:
diagnostics.DeploymentType = "Docker All-in-One"
default:
diagnostics.DeploymentType = "Development"
Expand Down
Loading

0 comments on commit 2e93487

Please sign in to comment.