You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openwhisk.apache.org by mr...@apache.org on 2017/09/29 02:19:38 UTC
[incubator-openwhisk-client-go] branch master updated: Add the
support of certificate checking for secure mode (#39)
This is an automated email from the ASF dual-hosted git repository.
mrutkowski pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-openwhisk-client-go.git
The following commit(s) were added to refs/heads/master by this push:
new cef179c Add the support of certificate checking for secure mode (#39)
cef179c is described below
commit cef179c81f07f86413c720623995c17bd1bddd7d
Author: Vincent <sh...@us.ibm.com>
AuthorDate: Thu Sep 28 22:19:36 2017 -0400
Add the support of certificate checking for secure mode (#39)
---
whisk/client.go | 66 ++++++++++++++++++++++++++--------------
whisk/client_test.go | 59 ++++++++++++++++++++++++++++++-----
whisk/testUtils.go | 42 +++++++++++++++++++++++++
whisk/wskprops_test.go | 22 +-------------
wski18n/i18n_resources.go | 22 +++++++-------
wski18n/resources/en_US.all.json | 8 +++++
6 files changed, 158 insertions(+), 61 deletions(-)
diff --git a/whisk/client.go b/whisk/client.go
index aea23ec..8dfc454 100644
--- a/whisk/client.go
+++ b/whisk/client.go
@@ -113,28 +113,6 @@ func NewClient(httpClient *http.Client, config_input *Config) (*Client, error) {
}
}
- // Disable certificate checking in the dev environment if in insecure mode
- if config.Insecure {
- Debug(DbgInfo, "Disabling certificate checking.\n")
- var tlsConfig *tls.Config
- if config.Cert != "" && config.Key != "" {
- if cert, err := tls.LoadX509KeyPair(config.Cert, config.Key); err == nil {
- tlsConfig = &tls.Config{
- Certificates: []tls.Certificate{cert},
- InsecureSkipVerify: true,
- }
- }
- }else{
- tlsConfig = &tls.Config{
- InsecureSkipVerify: true,
- }
- }
-
- httpClient.Transport = &http.Transport{
- TLSClientConfig: tlsConfig,
- }
- }
-
var err error
var errStr = ""
if len(config.Host) == 0 {
@@ -153,6 +131,46 @@ func NewClient(httpClient *http.Client, config_input *Config) (*Client, error) {
return nil, werr
}
+ var tlsConfig *tls.Config
+ // Disable certificate checking in the environment for insecure mode
+ if config.Insecure {
+ Debug(DbgInfo, "Disabling certificate checking.\n")
+ tlsConfig = &tls.Config{
+ InsecureSkipVerify: true,
+ }
+ if config.Cert != "" && config.Key != "" {
+ if cert, err := ReadX509KeyPair(config.Cert, config.Key); err == nil {
+ tlsConfig = &tls.Config{
+ Certificates: []tls.Certificate{cert},
+ InsecureSkipVerify: true,
+ }
+ }
+ }
+ } else {
+ // Enable certificate checking in the environment for secure mode
+ if config.Cert != "" && config.Key != "" {
+ if cert, err := ReadX509KeyPair(config.Cert, config.Key); err == nil {
+ tlsConfig = &tls.Config{
+ Certificates: []tls.Certificate{cert},
+ }
+ } else {
+ errStr = wski18n.T("Unable to enable the certificate checking due to the reason: {{.err}}.\n",
+ map[string]interface{}{ "err": err })
+ }
+ } else {
+ errStr = wski18n.T("Unable to enable the certificate checking, because both of the certificate and the key are missing.\n")
+ }
+
+ if len(errStr) != 0 {
+ werr := MakeWskError(errors.New(errStr), EXIT_CODE_ERR_GENERAL, DISPLAY_MSG, NO_DISPLAY_USAGE)
+ return nil, werr
+ }
+ }
+
+ httpClient.Transport = &http.Transport{
+ TLSClientConfig: tlsConfig,
+ }
+
if len(config.Namespace) == 0 {
config.Namespace = "_"
}
@@ -183,6 +201,10 @@ func NewClient(httpClient *http.Client, config_input *Config) (*Client, error) {
return c, nil
}
+var ReadX509KeyPair = func(certFile, keyFile string) (tls.Certificate, error) {
+ return tls.LoadX509KeyPair(certFile, keyFile)
+}
+
///////////////////////////////
// Request/Utility Functions //
///////////////////////////////
diff --git a/whisk/client_test.go b/whisk/client_test.go
index 1b3e748..4425e71 100644
--- a/whisk/client_test.go
+++ b/whisk/client_test.go
@@ -25,6 +25,7 @@ import (
"net/http"
"fmt"
"net/url"
+ "crypto/tls"
)
const (
@@ -36,18 +37,20 @@ const (
FakeAuthKey = "dhajfhshfs:hjhfsjfdjfjsgfjs"
)
-func GetValidConfigTest() *Config {
+func GetValidConfigTest(insecure bool) *Config {
var config Config
config.Host = FakeHost
config.Namespace = FakeNamespace
config.AuthToken = FakeAuthKey
+ config.Insecure = insecure
return &config
}
-func GetInvalidConfigMissingApiHostTest() *Config {
+func GetInvalidConfigMissingApiHostTest(insecure bool) *Config {
var config Config
config.Namespace = FakeNamespace
config.AuthToken = FakeAuthKey
+ config.Insecure = insecure
return &config
}
@@ -60,19 +63,20 @@ func GetInvalidConfigMissingApiHostWithBaseURLTest() *Config {
return &config
}
-func GetValidConfigDiffApiHostAndBaseURLTest() *Config {
+func GetValidConfigDiffApiHostAndBaseURLTest(insecure bool) *Config {
var config Config
urlBase := fmt.Sprintf("https://%s/api", FakeHostDiff)
config.BaseURL, _ = url.Parse(urlBase)
config.Host = FakeHost
config.Namespace = FakeNamespace
config.AuthToken = FakeAuthKey
+ config.Insecure = insecure
return &config
}
-func TestNewClient(t *testing.T) {
+func TestNewClientDisablingCertificate(t *testing.T) {
// Test the use case to pass a valid config.
- config := GetValidConfigTest()
+ config := GetValidConfigTest(true)
client, err := NewClient(http.DefaultClient, config)
assert.Nil(t, err)
assert.NotNil(t, client)
@@ -82,7 +86,7 @@ func TestNewClient(t *testing.T) {
assert.Equal(t, FakeAuthKey, client.Config.AuthToken)
// Test the use case to pass an invalid config with a missing api host.
- config = GetInvalidConfigMissingApiHostTest()
+ config = GetInvalidConfigMissingApiHostTest(true)
client, err = NewClient(http.DefaultClient, config)
assert.NotNil(t, err)
assert.Contains(t, err.Error(), "Unable to create request URL, because OpenWhisk API host is missing")
@@ -96,7 +100,7 @@ func TestNewClient(t *testing.T) {
assert.Nil(t, client)
// Test the use case to pass a valid config with both the base and api host of different values.
- config = GetValidConfigDiffApiHostAndBaseURLTest()
+ config = GetValidConfigDiffApiHostAndBaseURLTest(true)
client, err = NewClient(http.DefaultClient, config)
assert.Nil(t, err)
assert.NotNil(t, client)
@@ -105,3 +109,44 @@ func TestNewClient(t *testing.T) {
assert.Equal(t, FakeBaseURLDiff, client.Config.BaseURL.String())
assert.Equal(t, FakeAuthKey, client.Config.AuthToken)
}
+
+func TestNewClientEnablingCertificate(t *testing.T) {
+ TEST_KEY_FILE := "TEST_KEY_FILE"
+ TEST_CERT_FILE := "TEST_CERT_FILE"
+
+ // Test the use case to pass a config in secure mode missing the cert and key files.
+ config := GetValidConfigTest(false)
+ _, err := NewClient(http.DefaultClient, config)
+ assert.NotNil(t, err)
+
+ // Test the use case to pass a config in secure mode with non-existing the cert and key files.
+ config = GetValidConfigTest(false)
+ config.Key = TEST_KEY_FILE
+ config.Cert = TEST_CERT_FILE
+ _, err = NewClient(http.DefaultClient, config)
+ assert.NotNil(t, err)
+
+ // Test the use case to pass a config in secure mode with invalid the cert and key files.
+ CreateFile([]string{ "testKey" }, TEST_KEY_FILE)
+ CreateFile([]string{ "testCert" }, TEST_CERT_FILE)
+ config = GetValidConfigTest(false)
+ config.Key = TEST_KEY_FILE
+ config.Cert = TEST_CERT_FILE
+ _, err = NewClient(http.DefaultClient, config)
+ assert.NotNil(t, err)
+
+ // Test the use case to pass a config in secure mode with valid the cert and key files.
+ oldReadX509KeyPair := ReadX509KeyPair
+ defer func () { ReadX509KeyPair = oldReadX509KeyPair }()
+ ReadX509KeyPair = func(certFile, keyFile string) (tls.Certificate, error) {
+ cert := tls.Certificate{}
+ return cert, nil
+ }
+ config = GetValidConfigTest(false)
+ config.Key = TEST_KEY_FILE
+ config.Cert = TEST_CERT_FILE
+ _, err = NewClient(http.DefaultClient, config)
+ assert.Nil(t, err)
+ DeleteFile(TEST_KEY_FILE)
+ DeleteFile(TEST_CERT_FILE)
+}
diff --git a/whisk/testUtils.go b/whisk/testUtils.go
new file mode 100644
index 0000000..60152fc
--- /dev/null
+++ b/whisk/testUtils.go
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package whisk
+
+import (
+ "os"
+ "fmt"
+ "bufio"
+)
+
+func CreateFile(lines []string, path string) error {
+ file, err := os.Create(path)
+ if err != nil {
+ return err
+ }
+ defer file.Close()
+
+ w := bufio.NewWriter(file)
+ for _, line := range lines {
+ fmt.Fprintln(w, line)
+ }
+ return w.Flush()
+}
+
+func DeleteFile(path string) error {
+ return os.Remove(path)
+}
diff --git a/whisk/wskprops_test.go b/whisk/wskprops_test.go
index ce2b890..eff7dbb 100644
--- a/whisk/wskprops_test.go
+++ b/whisk/wskprops_test.go
@@ -1,4 +1,4 @@
-//// +build unit
+// +build unit
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -23,8 +23,6 @@ import (
"testing"
"github.com/stretchr/testify/assert"
"os"
- "fmt"
- "bufio"
)
const (
@@ -142,24 +140,6 @@ func (pi FakePropertiesImp) GetPropsFromWhiskProperties() *Wskprops {
return &dep
}
-func CreateFile(lines []string, path string) error {
- file, err := os.Create(path)
- if err != nil {
- return err
- }
- defer file.Close()
-
- w := bufio.NewWriter(file)
- for _, line := range lines {
- fmt.Fprintln(w, line)
- }
- return w.Flush()
-}
-
-func DeleteFile(path string) error {
- return os.Remove(path)
-}
-
func TestGetPropsFromWhiskProperties(t *testing.T) {
lines := []string{ EXPECTED_TEST_AUTH_KEY }
CreateFile(lines, TEST_FILE)
diff --git a/wski18n/i18n_resources.go b/wski18n/i18n_resources.go
index 206cd63..df2cfa8 100644
--- a/wski18n/i18n_resources.go
+++ b/wski18n/i18n_resources.go
@@ -109,12 +109,12 @@ func wski18nResourcesDe_deAllJson() (*asset, error) {
return nil, err
}
- info := bindataFileInfo{name: "wski18n/resources/de_DE.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1506031186, 0)}
+ info := bindataFileInfo{name: "wski18n/resources/de_DE.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1500156160, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
-var _wski18nResourcesEn_usAllJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x98\x51\x6f\xdb\x36\x10\xc7\xdf\xfd\x29\x0e\x7a\x71\x06\xb8\xfa\x00\xdd\x53\xb0\x19\x73\xb0\xae\x31\x56\x67\x7d\x58\x86\x81\x16\xcf\xd6\x21\x12\xc9\x92\x94\x3d\xd7\xd0\x77\x1f\x48\xd9\xb5\xd7\x48\x96\x44\x2b\x59\x9e\x62\x30\xbc\xff\xfd\x78\x3c\x1e\x8f\xfa\x73\x04\xb0\x1f\x01\x00\x44\xc4\xa3\xf7\x10\x3d\x08\xb6\xcc\x10\xac\x04\xc6\x39\x68\x59\x58\x04\xa9\x2c\x49\x61\x60\xbc\xdf\xc7\x87\xdf\x65\x39\x8e [...]
+var _wski18nResourcesEn_usAllJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x58\x5f\x6f\xdb\x36\x10\x7f\xf7\xa7\x38\xf8\xc5\x19\xe0\xea\x03\x74\x4f\xc1\x66\xcc\xc1\xba\xc6\x58\x9d\xf5\x61\x19\x06\x5a\x3c\x47\x87\xc8\x3c\x95\xa4\x9c\xb9\x86\xbe\xfb\x70\x94\x5c\x67\x8d\x65\xfd\xb1\xda\xe5\xc9\x02\xcd\xfb\xdd\x8f\x77\xc7\xfb\xc3\x3f\x47\x00\xfb\x11\x00\xc0\x98\xf4\xf8\x2d\x8c\xef\x8c\x5a\xa5\x08\x9e\x41\x69\x0d\x96\x73\x8f\xc0\x99\x27\x36\x0e\x26\xfb\x7d\x54\x7d\x17\xc5\x64\x3c [...]
func wski18nResourcesEn_usAllJsonBytes() ([]byte, error) {
return bindataRead(
@@ -129,7 +129,7 @@ func wski18nResourcesEn_usAllJson() (*asset, error) {
return nil, err
}
- info := bindataFileInfo{name: "wski18n/resources/en_US.all.json", size: 6538, mode: os.FileMode(420), modTime: time.Unix(1506031828, 0)}
+ info := bindataFileInfo{name: "wski18n/resources/en_US.all.json", size: 6974, mode: os.FileMode(420), modTime: time.Unix(1506610567, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -149,7 +149,7 @@ func wski18nResourcesEs_esAllJson() (*asset, error) {
return nil, err
}
- info := bindataFileInfo{name: "wski18n/resources/es_ES.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1506031186, 0)}
+ info := bindataFileInfo{name: "wski18n/resources/es_ES.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1500156160, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -169,7 +169,7 @@ func wski18nResourcesFr_frAllJson() (*asset, error) {
return nil, err
}
- info := bindataFileInfo{name: "wski18n/resources/fr_FR.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1506031186, 0)}
+ info := bindataFileInfo{name: "wski18n/resources/fr_FR.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1500156160, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -189,7 +189,7 @@ func wski18nResourcesIt_itAllJson() (*asset, error) {
return nil, err
}
- info := bindataFileInfo{name: "wski18n/resources/it_IT.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1506031186, 0)}
+ info := bindataFileInfo{name: "wski18n/resources/it_IT.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1500156160, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -209,7 +209,7 @@ func wski18nResourcesJa_jaAllJson() (*asset, error) {
return nil, err
}
- info := bindataFileInfo{name: "wski18n/resources/ja_JA.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1506031186, 0)}
+ info := bindataFileInfo{name: "wski18n/resources/ja_JA.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1500156160, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -229,7 +229,7 @@ func wski18nResourcesKo_krAllJson() (*asset, error) {
return nil, err
}
- info := bindataFileInfo{name: "wski18n/resources/ko_KR.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1506031186, 0)}
+ info := bindataFileInfo{name: "wski18n/resources/ko_KR.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1500156160, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -249,7 +249,7 @@ func wski18nResourcesPt_brAllJson() (*asset, error) {
return nil, err
}
- info := bindataFileInfo{name: "wski18n/resources/pt_BR.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1506031186, 0)}
+ info := bindataFileInfo{name: "wski18n/resources/pt_BR.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1500156160, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -269,7 +269,7 @@ func wski18nResourcesZh_hansAllJson() (*asset, error) {
return nil, err
}
- info := bindataFileInfo{name: "wski18n/resources/zh_Hans.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1506031186, 0)}
+ info := bindataFileInfo{name: "wski18n/resources/zh_Hans.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1500156160, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -289,7 +289,7 @@ func wski18nResourcesZh_hantAllJson() (*asset, error) {
return nil, err
}
- info := bindataFileInfo{name: "wski18n/resources/zh_Hant.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1506031186, 0)}
+ info := bindataFileInfo{name: "wski18n/resources/zh_Hant.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1500156160, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
diff --git a/wski18n/resources/en_US.all.json b/wski18n/resources/en_US.all.json
index 775cf4f..bd878a1 100644
--- a/wski18n/resources/en_US.all.json
+++ b/wski18n/resources/en_US.all.json
@@ -140,6 +140,14 @@
"translation": "Unable to create request URL, because the api host '{{.host}}' is invalid: {{.err}}"
},
{
+ "id": "Unable to enable the certificate checking due to the reason: {{.err}}.\n",
+ "translation": "Unable to enable the certificate checking due to the reason: {{.err}}.\n"
+ },
+ {
+ "id": "Unable to enable the certificate checking, because both of the certificate and the key are missing.\n",
+ "translation": "Unable to enable the certificate checking, because both of the certificate and the key are missing.\n"
+ },
+ {
"id": "OpenWhisk API host is missing (Please configure WHISK_APIHOST in .wskprops under the system HOME directory.)",
"translation": "OpenWhisk API host is missing (Please configure WHISK_APIHOST in .wskprops under the system HOME directory.)"
},
--
To stop receiving notification emails like this one, please contact
['"commits@openwhisk.apache.org" <co...@openwhisk.apache.org>'].