Skip to content

Commit

Permalink
marshal ExternalBuilders into yaml and use as strings in tests. Cover…
Browse files Browse the repository at this point in the history
… cases when value is a string(from env var) or a map(generic structure after unmarshal)

Signed-off-by: Vladyslav Kopaihorodskyi <vlad.kopaygorodsky@gmail.com>
  • Loading branch information
kopaygorodsky authored and denyeart committed Jul 26, 2022
1 parent cdc9051 commit 5f30d58
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 16 deletions.
30 changes: 25 additions & 5 deletions core/peer/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -276,21 +276,20 @@ func (c *Config) load() error {
}

c.ChaincodePull = viper.GetBool("chaincode.pull")
var externalBuilders []ExternalBuilder

if err := yaml.UnmarshalStrict([]byte(viper.GetString("chaincode.externalBuilders")), &externalBuilders); err != nil {
return errors.Wrap(err, "unmarshalling 'chaincode.externalBuilders' into yaml")
c.ExternalBuilders, err = getExternalBuildersConfig()
if err != nil {
return errors.Wrap(err, "getting external builders config")
}

c.ExternalBuilders = externalBuilders
for builderIndex, builder := range c.ExternalBuilders {
if builder.Path == "" {
return fmt.Errorf("invalid external builder configuration, path attribute missing in one or more builders")
}
if builder.Name == "" {
return fmt.Errorf("external builder at path %s has no name attribute", builder.Path)
}
if builder.Environment != nil && builder.PropagateEnvironment == nil {
if builder.Environment != nil && len(builder.PropagateEnvironment) == 0 {
c.ExternalBuilders[builderIndex].PropagateEnvironment = builder.Environment
}
}
Expand Down Expand Up @@ -477,3 +476,24 @@ func GetClientCertificate() (tls.Certificate, error) {
}
return cert, nil
}

// this method is needed because old viper (< 1.1.0) has bugs in automatic env option
func getExternalBuildersConfig() ([]ExternalBuilder, error) {
var externalBuilders []ExternalBuilder

if viper.IsSet("chaincode.externalBuilders") {
// when defined as an env var the value is string, then we need to parse it as a yaml string
if extBuildersString := viper.GetString("chaincode.externalBuilders"); extBuildersString != "" {
if err := yaml.UnmarshalStrict([]byte(extBuildersString), &externalBuilders); err != nil {
return nil, errors.Wrap(err, "unmarshalling 'chaincode.externalBuilders' into yaml")
}
} else {
// otherwise we expect it to be a map, core.yaml is unmarshalled into a generic struct map[string]interface and then mapstructure.Decode has to be used.
if err := viper.UnmarshalKey("chaincode.externalBuilders", &externalBuilders); err != nil {
return nil, err
}
}
}

return externalBuilders, nil
}
88 changes: 77 additions & 11 deletions core/peer/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package peer

import (
"crypto/tls"
"gopkg.in/yaml.v2"
"io/ioutil"
"net"
"os"
Expand Down Expand Up @@ -308,7 +309,19 @@ func TestGlobalConfig(t *testing.T) {
viper.Set("metrics.statsd.prefix", "testPrefix")

viper.Set("chaincode.pull", false)
viper.Set("chaincode.externalBuilders", "[{name: relative, path: relative/plugin_dir}, {name: absolute, path: /absolute/plugin_dir}]")

extBuildersConfig, err := yaml.Marshal([]ExternalBuilder{
{
Path: "relative/plugin_dir",
Name: "relative",
},
{
Path: "/absolute/plugin_dir",
Name: "absolute",
},
})
require.NoError(t, err)
viper.Set("chaincode.externalBuilders", extBuildersConfig)

coreConfig, err := GlobalConfig()
assert.NoError(t, err)
Expand Down Expand Up @@ -343,12 +356,16 @@ func TestGlobalConfig(t *testing.T) {
ChaincodePull: false,
ExternalBuilders: []ExternalBuilder{
{
Path: "relative/plugin_dir",
Name: "relative",
Path: "relative/plugin_dir",
Name: "relative",
PropagateEnvironment: []string{},
Environment: []string{},
},
{
Path: "/absolute/plugin_dir",
Name: "absolute",
Path: "/absolute/plugin_dir",
Name: "absolute",
PropagateEnvironment: []string{},
Environment: []string{},
},
},
OperationsListenAddress: "127.0.0.1:9443",
Expand Down Expand Up @@ -396,7 +413,26 @@ func TestGlobalConfigDefault(t *testing.T) {
func TestPropagateEnvironment(t *testing.T) {
defer viper.Reset()
viper.Set("peer.address", "localhost:8080")
viper.Set("chaincode.externalBuilders", "[{name: testName, environmentWhitelist: [KEY=VALUE], path: /testPath}, {name: testName, propagateEnvironment: [KEY=VALUE], path: /testPath}, {name: testName, environmentWhitelist: [KEY=VALUE], propagateEnvironment: [KEY=VALUE2], path: /testPath}]")
viper.Set("chaincode.externalBuilders", []ExternalBuilder{
{
Name: "testName",
Environment: []string{"KEY=VALUE"},
PropagateEnvironment: []string{},
Path: "/testPath",
},
{
Name: "testName",
PropagateEnvironment: []string{"KEY=VALUE"},
Environment: []string{},
Path: "/testPath",
},
{
Name: "testName",
Environment: []string{"KEY=VALUE"},
PropagateEnvironment: []string{"KEY=VALUE2"},
Path: "/testPath",
},
})
coreConfig, err := GlobalConfig()
assert.NoError(t, err)

Expand All @@ -416,6 +452,7 @@ func TestPropagateEnvironment(t *testing.T) {
{
Name: "testName",
PropagateEnvironment: []string{"KEY=VALUE"},
Environment: []string{},
Path: "/testPath",
},
{
Expand All @@ -432,7 +469,22 @@ func TestPropagateEnvironment(t *testing.T) {
func TestExternalBuilderConfigAsEnvVar(t *testing.T) {
defer viper.Reset()
viper.Set("peer.address", "localhost:8080")
viper.Set("chaincode.externalBuilders", "[{name: relative, path: relative/plugin_dir, propagateEnvironment: [ENVVAR_NAME_TO_PROPAGATE_FROM_PEER, GOPROXY]}, {name: absolute, path: /absolute/plugin_dir}]")
extBuildersConfig, err := yaml.Marshal([]ExternalBuilder{
{
Path: "relative/plugin_dir",
Name: "relative",
PropagateEnvironment: []string{"ENVVAR_NAME_TO_PROPAGATE_FROM_PEER", "GOPROXY"},
},
{
Path: "/absolute/plugin_dir",
Name: "absolute",
PropagateEnvironment: nil,
},
})
require.NoError(t, err)

viper.Set("chaincode.externalBuilders", extBuildersConfig)

coreConfig, err := GlobalConfig()
require.NoError(t, err)

Expand All @@ -441,26 +493,40 @@ func TestExternalBuilderConfigAsEnvVar(t *testing.T) {
Path: "relative/plugin_dir",
Name: "relative",
PropagateEnvironment: []string{"ENVVAR_NAME_TO_PROPAGATE_FROM_PEER", "GOPROXY"},
Environment: []string{},
},
{
Path: "/absolute/plugin_dir",
Name: "absolute",
Path: "/absolute/plugin_dir",
Name: "absolute",
PropagateEnvironment: []string{},
Environment: []string{},
},
}, coreConfig.ExternalBuilders)
}

func TestMissingExternalBuilderPath(t *testing.T) {
defer viper.Reset()
viper.Set("peer.address", "localhost:8080")
viper.Set("chaincode.externalBuilders", "[{name: testName}]")

viper.Set("chaincode.externalBuilders", []ExternalBuilder{
{
Name: "testName",
},
})
_, err := GlobalConfig()
assert.EqualError(t, err, "invalid external builder configuration, path attribute missing in one or more builders")
}

func TestMissingExternalBuilderName(t *testing.T) {
defer viper.Reset()
viper.Set("peer.address", "localhost:8080")
viper.Set("chaincode.externalBuilders", "[{path: relative/plugin_dir}]")

viper.Set("chaincode.externalBuilders", []ExternalBuilder{
{
Path: "relative/plugin_dir",
},
})

_, err := GlobalConfig()
assert.EqualError(t, err, "external builder at path relative/plugin_dir has no name attribute")
}

0 comments on commit 5f30d58

Please sign in to comment.