Added changes for classes and variables casing to be get exported and can be used in other places (#2675) (#38)

* Updating classes and variables so that they are exported and usable by other modules

* Updating missed debug statements to have case of client -> Client
diff --git a/whisk/client.go b/whisk/client.go
index 3d6b655..aea23ec 100644
--- a/whisk/client.go
+++ b/whisk/client.go
@@ -32,6 +32,7 @@
     "github.com/apache/incubator-openwhisk-client-go/wski18n"
     "strings"
     "time"
+    "regexp"
 )
 
 const (
@@ -80,6 +81,18 @@
     UserAgent   string
 }
 
+type ObfuscateSet struct {
+    Regex           string
+    Replacement     string
+}
+
+var DefaultObfuscateArr = []ObfuscateSet{
+    {
+        Regex: "\"[Pp]assword\":\\s*\".*\"",
+        Replacement: `"password": "******"`,
+    },
+}
+
 func NewClient(httpClient *http.Client, config_input *Config) (*Client, error) {
 
     var config *Config
@@ -253,7 +266,7 @@
 
 // bodyTruncator limits the size of Req/Resp Body for --verbose ONLY.
 // It returns truncated Req/Resp Body, reloaded io.ReadCloser and any errors.
-func bodyTruncator(body io.ReadCloser) (string, io.ReadCloser, error) {
+func BodyTruncator(body io.ReadCloser) (string, io.ReadCloser, error) {
     limit := 1000    // 1000 byte limit, anything over is truncated
 
     data, err := ioutil.ReadAll(body)
@@ -279,31 +292,15 @@
 // error if an API error has occurred.  If v implements the io.Writer
 // interface, the raw response body will be written to v, without attempting to
 // first decode it.
-func (c *Client) Do(req *http.Request, v interface{}, ExitWithErrorOnTimeout bool) (*http.Response, error) {
+func (c *Client) Do(req *http.Request, v interface{}, ExitWithErrorOnTimeout bool, secretToObfuscate ...ObfuscateSet) (*http.Response, error) {
     var err error
-    var truncatedBody string
+    var data []byte
+    secrets := append(DefaultObfuscateArr, secretToObfuscate...)
 
-    if IsVerbose() {
-        fmt.Println("REQUEST:")
-        fmt.Printf("[%s]\t%s\n", req.Method, req.URL)
-
-        if len(req.Header) > 0 {
-            fmt.Println("Req Headers")
-            PrintJSON(req.Header)
-        }
-
-        if req.Body != nil {
-            fmt.Println("Req Body")
-            if !IsDebug() {
-                if truncatedBody, req.Body, err = bodyTruncator(req.Body); err != nil {
-                    return nil, err
-                }
-                fmt.Println(truncatedBody)
-            } else {
-                fmt.Println(req.Body)
-            }
-            Debug(DbgInfo, "Req Body (ASCII quoted string):\n%+q\n", req.Body)
-        }
+    req, err = PrintRequestInfo(req, secrets...)
+    //Putting this based on previous code
+    if err != nil {
+        return nil, err
     }
 
     // Issue the request to the Whisk server endpoint
@@ -314,38 +311,9 @@
         return nil, werr
     }
 
-    // Don't "defer resp.Body.Close()" here because the body is reloaded to allow caller to
-    // do custom body parsing, such as handling per-route error responses.
-    Verbose("RESPONSE:")
-    Verbose("Got response with code %d\n", resp.StatusCode)
-
-    if (IsVerbose() && len(resp.Header) > 0) {
-        fmt.Println("Resp Headers")
-        PrintJSON(resp.Header)
-    }
-
-    // Read the response body
-    data, err := ioutil.ReadAll(resp.Body)
+    resp, data, err = PrintResponseInfo(resp, secrets...)
     if err != nil {
-        Debug(DbgError, "ioutil.ReadAll(resp.Body) error: %s\n", err)
-        werr := MakeWskError(err, EXIT_CODE_ERR_NETWORK, DISPLAY_MSG, NO_DISPLAY_USAGE)
-        return resp, werr
-    }
-
-    // Reload the response body to allow caller access to the body; otherwise,
-    // the caller will have any empty body to read
-    resp.Body = ioutil.NopCloser(bytes.NewBuffer(data))
-
-    Verbose("Response body size is %d bytes\n", len(data))
-
-    if !IsDebug() {
-        if truncatedBody, resp.Body, err = bodyTruncator(resp.Body); err != nil {
-            return nil, err
-        }
-        Verbose("Response body received:\n%s\n", truncatedBody)
-    } else {
-        Verbose("Response body received:\n%s\n", string(data))
-        Debug(DbgInfo, "Response body received (ASCII quoted string):\n%+q\n", string(data))
+        return resp, err
     }
 
     // With the HTTP response status code and the HTTP body contents,
@@ -413,6 +381,89 @@
     return resp, werr
 }
 
+func PrintRequestInfo(req *http.Request, secretToObfuscate ...ObfuscateSet) (*http.Request, error) {
+    var truncatedBody string
+    var err error
+    if IsVerbose() {
+        fmt.Println("REQUEST:")
+        fmt.Printf("[%s]\t%s\n", req.Method, req.URL)
+
+        if len(req.Header) > 0 {
+            fmt.Println("Req Headers")
+            PrintJSON(req.Header)
+        }
+
+        if req.Body != nil {
+            fmt.Println("Req Body")
+            // Since we're emptying out the reader, which is the req.Body, we have to reset it,
+            // but create some copies for our debug messages.
+            buffer, _ := ioutil.ReadAll(req.Body)
+            obfuscatedRequest := ObfuscateText(string(buffer), secretToObfuscate)
+            req.Body = ioutil.NopCloser(bytes.NewBuffer(buffer))
+
+            if !IsDebug() {
+                if truncatedBody, req.Body, err = BodyTruncator(ioutil.NopCloser(bytes.NewBuffer(buffer))); err != nil {
+                    return nil, err
+                }
+                fmt.Println(ObfuscateText(truncatedBody, secretToObfuscate))
+            } else {
+                fmt.Println(obfuscatedRequest)
+            }
+            Debug(DbgInfo, "Req Body (ASCII quoted string):\n%+q\n", obfuscatedRequest)
+        }
+    }
+    return req, nil
+}
+
+func PrintResponseInfo(resp *http.Response, secretToObfuscate ...ObfuscateSet) (*http.Response, []byte, error) {
+    var truncatedBody string
+    // Don't "defer resp.Body.Close()" here because the body is reloaded to allow caller to
+    // do custom body parsing, such as handling per-route error responses.
+    Verbose("RESPONSE:")
+    Verbose("Got response with code %d\n", resp.StatusCode)
+
+    if (IsVerbose() && len(resp.Header) > 0) {
+        fmt.Println("Resp Headers")
+        PrintJSON(resp.Header)
+    }
+
+    // Read the response body
+    data, err := ioutil.ReadAll(resp.Body)
+    if err != nil {
+        Debug(DbgError, "ioutil.ReadAll(resp.Body) error: %s\n", err)
+        werr := MakeWskError(err, EXIT_CODE_ERR_NETWORK, DISPLAY_MSG, NO_DISPLAY_USAGE)
+        resp.Body = ioutil.NopCloser(bytes.NewBuffer(data))
+        return resp, data, werr
+    }
+
+    // Reload the response body to allow caller access to the body; otherwise,
+    // the caller will have any empty body to read
+    resp.Body = ioutil.NopCloser(bytes.NewBuffer(data))
+
+    Verbose("Response body size is %d bytes\n", len(data))
+
+    if !IsDebug() {
+        if truncatedBody, resp.Body, err = BodyTruncator(ioutil.NopCloser(bytes.NewBuffer(data))); err != nil {
+            return nil, data, err
+        }
+        Verbose("Response body received:\n%s\n", ObfuscateText(truncatedBody, secretToObfuscate))
+    } else {
+        obfuscatedResponse := ObfuscateText(string(data), secretToObfuscate)
+        Verbose("Response body received:\n%s\n", obfuscatedResponse)
+        Debug(DbgInfo, "Response body received (ASCII quoted string):\n%+q\n", obfuscatedResponse)
+    }
+    return resp, data, err
+}
+
+func ObfuscateText(text string, replacements []ObfuscateSet) string {
+    obfuscated := text
+    for _, oSet := range replacements {
+        r, _ := regexp.Compile(oSet.Regex)
+        obfuscated = r.ReplaceAllString(obfuscated, oSet.Replacement)
+    }
+    return obfuscated
+}
+
 func parseErrorResponse(resp *http.Response, data []byte, v interface{}) (*http.Response, error) {
     Debug(DbgInfo, "HTTP failure %d + body\n", resp.StatusCode)