Skip to content

Commit

Permalink
[FAB-7307]Config in []byte & embed cert in config
Browse files Browse the repository at this point in the history
        This change introduces 'ConfigBytes' and 'ConfigType' in the SDK
        options to allow loading configs from bytes array as opposed to
        from a file path. The function InitConfigFromBytes has been
        introduced in pkg/config/config.go to load the configs from the
        bytes array argument.

        Since viper needs to know the type of config being passed to it,
        'ConfigType' was added for this purpose.

        This change also introduces the embedding of certs/keys in the
        sdk's config directly as opposed to passing file path values in
        the configs. Embedded certs/keys should always be set under 'pem'
        fields while files will remain under 'path' fields. Look at
        test/fixtures/config/config_test_pem.yaml for a sample config with
        embedded certs/keys.

        Three new functions were added to the Config interface in
        api/apiconfig/configprovider.go to support CA server certs/keys.
        These three functions  are 'CAClientKeyPem', 'CAClientCertPem'
	and 'CAServerCertPems'. The client must decide if they want to
	use the Pem or the Path version of these functions and must set
	the config accordingly.

        The configs will load everything found in the byte array (or
        config file). If it has both 'pem' and 'path', then both will
        be loaded.

Change-Id: I858623b0aa98e1000ed3c86edb2e136a831933ed
Signed-off-by: Baha Shaaban <baha.shaaban@securekey.com>
  • Loading branch information
Baha Shaaban committed Dec 5, 2017
1 parent 9dad8ae commit f853354
Show file tree
Hide file tree
Showing 12 changed files with 886 additions and 25 deletions.
3 changes: 3 additions & 0 deletions api/apiconfig/configprovider.go
Expand Up @@ -15,8 +15,11 @@ import (
type Config interface {
Client() (*ClientConfig, error)
CAConfig(org string) (*CAConfig, error)
CAServerCertPems(org string) ([]string, error)
CAServerCertFiles(org string) ([]string, error)
CAClientKeyPem(org string) (string, error)
CAClientKeyFile(org string) (string, error)
CAClientCertPem(org string) (string, error)
CAClientCertFile(org string) (string, error)
TimeoutOrDefault(TimeoutType) time.Duration
MspID(org string) (string, error)
Expand Down
39 changes: 39 additions & 0 deletions api/apiconfig/mocks/mockconfig.gen.go

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

3 changes: 3 additions & 0 deletions api/apiconfig/network.go
Expand Up @@ -135,12 +135,15 @@ type TLSConfig struct {

// MutualTLSConfig Mutual TLS configurations
type MutualTLSConfig struct {
Pem []string
// Certfiles root certificates for TLS validation (Comma serparated path list)
Path string
// Client client TLS information
Client struct {
KeyPem string
// Keyfile client key path
Keyfile string
CertPem string
// Certfile client cert path
Certfile string
}
Expand Down
4 changes: 4 additions & 0 deletions def/fabapi/context/defprovider/sdk.go
Expand Up @@ -33,6 +33,10 @@ func NewDefaultProviderFactory() *DefaultProviderFactory {

// NewConfigProvider creates a Config using the SDK's default implementation
func (f *DefaultProviderFactory) NewConfigProvider(o opt.ConfigOpts, a opt.SDKOpts) (apiconfig.Config, error) {
// configBytes takes precedence over configFile
if a.ConfigBytes != nil && len(a.ConfigBytes) > 0 {
return configImpl.InitConfigFromBytes(a.ConfigBytes, a.ConfigType)
}
return configImpl.InitConfig(a.ConfigFile)
}

Expand Down
6 changes: 5 additions & 1 deletion def/fabapi/fabapi.go
Expand Up @@ -29,6 +29,8 @@ import (
type Options struct {
// Quick access options
ConfigFile string
ConfigByte []byte
ConfigType string

// Options for default providers
ConfigOpts opt.ConfigOpts
Expand Down Expand Up @@ -85,7 +87,9 @@ type ProviderInit interface {
func NewSDK(options Options) (*FabricSDK, error) {
// Construct SDK opts from the quick access options in setup
sdkOpts := opt.SDKOpts{
ConfigFile: options.ConfigFile,
ConfigFile: options.ConfigFile,
ConfigBytes: options.ConfigByte,
ConfigType: options.ConfigType,
}

sdk := FabricSDK{
Expand Down
65 changes: 65 additions & 0 deletions def/fabapi/fabapi_test.go
Expand Up @@ -7,6 +7,7 @@ SPDX-License-Identifier: Apache-2.0
package fabapi

import (
"os"
"testing"

"github.com/hyperledger/fabric-sdk-go/def/fabapi/opt"
Expand Down Expand Up @@ -190,3 +191,67 @@ func TestNewDefaultTwoValidSDK(t *testing.T) {
t.Fatalf("Failed to create new 'orgchannel' channel client: %s", err)
}
}

func TestNewDefaultSDKFromByte(t *testing.T) {
cBytes, err := loadConfigBytesFromFile(t, "../../test/fixtures/config/config_test.yaml")
if err != nil {
t.Fatalf("Failed to load sample bytes from File. Error: %s", err)
}
setup := Options{
ConfigByte: cBytes,
ConfigType: "yaml",
StateStoreOpts: opt.StateStoreOpts{
Path: "/tmp/state",
},
}

sdk, err := NewSDK(setup)
if err != nil {
t.Fatalf("Error initializing SDK: %s", err)
}

if sdk == nil {
t.Fatalf("SDK should not be empty when initialized")
}

setup = Options{
ConfigByte: cBytes,
ConfigType: "json",
StateStoreOpts: opt.StateStoreOpts{
Path: "/tmp/state",
},
}

defer func() {
if r := recover(); r == nil {
t.Errorf("The code did not panic")
}
}()

// new SDK expected to panic due to wrong config type which didn't load the configs
NewSDK(setup)

}

func loadConfigBytesFromFile(t *testing.T, filePath string) ([]byte, error) {
// read test config file into bytes array
f, err := os.Open(filePath)
if err != nil {
t.Fatalf("Failed to read config file. Error: %s", err)
}
defer f.Close()
fi, err := f.Stat()
if err != nil {
t.Fatalf("Failed to read config file stat. Error: %s", err)
}
s := fi.Size()
cBytes := make([]byte, s, s)
n, err := f.Read(cBytes)
if err != nil {
t.Fatalf("Failed to read test config for bytes array testing. Error: %s", err)
}
if n == 0 {
t.Fatalf("Failed to read test config for bytes array testing. Mock bytes array is empty")
}
return cBytes, err
}
6 changes: 6 additions & 0 deletions def/fabapi/opt/opt.go
Expand Up @@ -8,7 +8,13 @@ package opt

// SDKOpts provides bootstrap setup
type SDKOpts struct {
//ConfigFile to load from a predefined path
ConfigFile string
//ConfigBytes to load from an bytes array
ConfigBytes []byte
//ConfigType to specify the type of the config (mainly used with ConfigBytes as ConfigFile has a file extension to specify the type)
// valid values: yaml, json, etc.
ConfigType string
}

// ConfigOpts provides setup parameters for Config
Expand Down

0 comments on commit f853354

Please sign in to comment.