Allow CLI to set API host including protocol and port - this removes the hardcoded https dependence for the API base.
Add tests for using CLI with API host that specifies protocol and port. Enabled only for Python CLI as it fails with Go CLI - see issue #924.
Remove redundant required properties in Controller/Loadbalancer. Do not startup an actor system if the configuration is not valid. Allow controller to run without container.
Since errors are now printed to stderr, remove the colon which will appear out of place on stdout in CLI error message.
diff --git a/tools/cli/wsk b/tools/cli/wsk
index 2b0117c..75e350f 100755
--- a/tools/cli/wsk
+++ b/tools/cli/wsk
@@ -161,7 +161,7 @@
         if args.namespace:
             if args.apihost is not None:
                 props['apihost'] = args.apihost
-            url = 'https://%(apibase)s/namespaces/' % { 'apibase': apiBase(props) }
+            url = '%(apibase)s/namespaces/' % { 'apibase': apiBase(props) }
             if args.auth:
                 auth = args.auth
             else:
@@ -221,26 +221,26 @@
             print 'whisk CLI version\t%s' % props['clibuild']
         if args.all or args.apibuild:
             if props['apihost'] is not None:
-                url = 'https://%(apibase)s' % { 'apibase' : apiBase(props) }
+                url = '%(apibase)s' % { 'apibase' : apiBase(props) }
                 res = request('GET', url, verbose=args.verbose)
                 if res.status == httplib.OK:
                     result = json.loads(res.read())
                     print 'whisk API build\t\t%s' % result['build']
                 else:
-                    print 'whisk API build\t\tCannot determine API build:',
-                    return responseError(res, prefix=None)
+                    print 'whisk API build\t\tCannot determine API build',
+                    return responseError(res, prefix = None)
             else:
                 print 'whisk API build\t\tNone',
         if args.all or args.apibuildno:
             if props['apihost'] is not None:
-                url = 'https://%(apibase)s' % { 'apibase' : apiBase(props) }
+                url = '%(apibase)s' % { 'apibase' : apiBase(props) }
                 res = request('GET', url, verbose=args.verbose)
                 if res.status == httplib.OK:
                     result = json.loads(res.read())
                     print 'whisk API buildno\t%s' % result['buildno']
                 else:
-                    print 'whisk API build\t\tCannot determine API buildno:',
-                    return responseError(res, prefix=None)
+                    print 'whisk API build\t\tCannot determine API buildno',
+                    return responseError(res, prefix = None)
             else:
                 print 'whisk API buildno\t\tNone',
         return 0
diff --git a/tools/cli/wskaction.py b/tools/cli/wskaction.py
index 6571ead..486a743 100644
--- a/tools/cli/wskaction.py
+++ b/tools/cli/wskaction.py
@@ -132,7 +132,7 @@
     # invokes the action and returns HTTP response
     def doInvoke(self, args, props):
         namespace, pname = parseQName(args.name, props)
-        url = 'https://%(apibase)s/namespaces/%(namespace)s/actions/%(name)s?blocking=%(blocking)s&result=%(result)s' % {
+        url = '%(apibase)s/namespaces/%(namespace)s/actions/%(name)s?blocking=%(blocking)s&result=%(result)s' % {
             'apibase': apiBase(props),
             'namespace': urllib.quote(namespace),
             'name': self.getSafeName(pname),
diff --git a/tools/cli/wskactivation.py b/tools/cli/wskactivation.py
index ee44038..3caab3d 100644
--- a/tools/cli/wskactivation.py
+++ b/tools/cli/wskactivation.py
@@ -131,7 +131,7 @@
     def result(self, args, props):
         fqid = getQName(args.id, '_') # kludge: use default namespace unless explicitly specified
         namespace, aid = parseQName(fqid, props)
-        url = 'https://%(apibase)s/namespaces/%(namespace)s/activations/%(id)s/result' % {
+        url = '%(apibase)s/namespaces/%(namespace)s/activations/%(id)s/result' % {
            'apibase': apiBase(props),
            'namespace': urllib.quote(namespace),
            'id': aid
@@ -151,7 +151,7 @@
     def logs(self, args, props):
         fqid = getQName(args.id, '_') # kludge: use default namespace unless explicitly specified
         namespace, aid = parseQName(fqid, props)
-        url = 'https://%(apibase)s/namespaces/%(namespace)s/activations/%(id)s/logs' % {
+        url = '%(apibase)s/namespaces/%(namespace)s/activations/%(id)s/logs' % {
            'apibase': apiBase(props),
            'namespace': urllib.quote(namespace),
            'id': aid
@@ -182,7 +182,7 @@
     # return the result of a 'wsk activation list' call, an HTTPResponse
     def listCmd(self, args, props):
         namespace, pname = parseQName(args.name, props)
-        url = 'https://%(apibase)s/namespaces/%(namespace)s/activations?docs=%(full)s&skip=%(skip)s&limit=%(limit)s&%(filter)s' % {
+        url = '%(apibase)s/namespaces/%(namespace)s/activations?docs=%(full)s&skip=%(skip)s&limit=%(limit)s&%(filter)s' % {
             'apibase': apiBase(props),
             'namespace': urllib.quote(namespace),
             'collection': self.collection,
diff --git a/tools/cli/wskitem.py b/tools/cli/wskitem.py
index 788855f..289ef97 100644
--- a/tools/cli/wskitem.py
+++ b/tools/cli/wskitem.py
@@ -154,7 +154,7 @@
         namespace, pname = parseQName(args.name, props)
         if pname:
             pname = ('/%s' % pname) if pname.endswith('/') else '/%s/' % pname
-        url = 'https://%(apibase)s/namespaces/%(namespace)s/%(collection)s%(package)s?skip=%(skip)s&limit=%(limit)s%(public)s' % {
+        url = '%(apibase)s/namespaces/%(namespace)s/%(collection)s%(package)s?skip=%(skip)s&limit=%(limit)s%(public)s' % {
             'apibase': apiBase(props),
             'namespace': urllib.quote(namespace),
             'collection': self.collection,
@@ -178,7 +178,7 @@
     # returns the HTTP response for saving an item.
     def httpPut(self, args, props, update, payload):
         namespace, pname = parseQName(args.name, props)
-        url = 'https://%(apibase)s/namespaces/%(namespace)s/%(collection)s/%(name)s%(update)s' % {
+        url = '%(apibase)s/namespaces/%(namespace)s/%(collection)s/%(name)s%(update)s' % {
             'apibase': apiBase(props),
             'namespace': urllib.quote(namespace),
             'collection': self.collection,
@@ -202,7 +202,7 @@
         if pname is None or pname.strip() == '':
             print 'error: entity name missing, did you mean to list collection'
             sys.exit(2)
-        url = 'https://%(apibase)s/namespaces/%(namespace)s/%(collection)s/%(name)s' % {
+        url = '%(apibase)s/namespaces/%(namespace)s/%(collection)s/%(name)s' % {
             'apibase': apiBase(props),
             'namespace': urllib.quote(namespace),
             'collection': self.collection,
@@ -218,7 +218,7 @@
             return code
 
         namespace, pname = parseQName(args.name, props)
-        url = 'https://%(apibase)s/namespaces/%(namespace)s/%(collection)s/%(name)s' % {
+        url = '%(apibase)s/namespaces/%(namespace)s/%(collection)s/%(name)s' % {
             'apibase': apiBase(props),
             'namespace': urllib.quote(namespace),
             'collection': self.collection,
diff --git a/tools/cli/wsknamespace.py b/tools/cli/wsknamespace.py
index cba1704..a278b0f 100644
--- a/tools/cli/wsknamespace.py
+++ b/tools/cli/wsknamespace.py
@@ -47,7 +47,7 @@
             return self.listEntitiesInNamespace(args, props)
 
     def listNamespaces(self, args, props):
-        url = 'https://%(apibase)s/namespaces' % { 'apibase': apiBase(props) }
+        url = '%(apibase)s/namespaces' % { 'apibase': apiBase(props) }
         res = request('GET', url, auth=args.auth, verbose=args.verbose)
 
         if res.status == httplib.OK:
@@ -61,7 +61,7 @@
 
     def listEntitiesInNamespace(self, args, props):
         namespace, _ = parseQName(args.name, props)
-        url = 'https://%(apibase)s/namespaces/%(namespace)s' % { 'apibase': apiBase(props), 'namespace': urllib.quote(namespace) }
+        url = '%(apibase)s/namespaces/%(namespace)s' % { 'apibase': apiBase(props), 'namespace': urllib.quote(namespace) }
         res = request('GET', url, auth=args.auth, verbose=args.verbose)
 
         if res.status == httplib.OK:
diff --git a/tools/cli/wskpackage.py b/tools/cli/wskpackage.py
index cf20abe..713fe61 100644
--- a/tools/cli/wskpackage.py
+++ b/tools/cli/wskpackage.py
@@ -77,7 +77,7 @@
 
     def bind(self, args, props):
         namespace, pname = parseQName(args.name, props)
-        url = 'https://%(apibase)s/namespaces/%(namespace)s/packages/%(name)s' % {
+        url = '%(apibase)s/namespaces/%(namespace)s/packages/%(name)s' % {
             'apibase': apiBase(props),
             'namespace': urllib.quote(namespace),
             'name': self.getSafeName(pname)
@@ -106,7 +106,7 @@
 
     def refresh(self, args, props):
         namespace, _ = parseQName(args.name, props)
-        url = 'https://%(apibase)s/namespaces/%(namespace)s/packages/refresh' % {
+        url = '%(apibase)s/namespaces/%(namespace)s/packages/refresh' % {
             'apibase': apiBase(props),
             'namespace': urllib.quote(namespace)
         }
diff --git a/tools/cli/wskrule.py b/tools/cli/wskrule.py
index 8ac7f65..592c071 100644
--- a/tools/cli/wskrule.py
+++ b/tools/cli/wskrule.py
@@ -90,7 +90,7 @@
         namespace, pname = parseQName(args.name, props)
         desc = 'active' if enable else 'inactive'
         status = json.dumps({ 'status': desc })
-        url = 'https://%(apibase)s/namespaces/%(namespace)s/rules/%(name)s' % {
+        url = '%(apibase)s/namespaces/%(namespace)s/rules/%(name)s' % {
             'apibase': apiBase(props),
             'namespace': urllib.quote(namespace),
             'name': self.getSafeName(pname)
@@ -112,7 +112,7 @@
 
     def getState(self, args, props):
         namespace, pname = parseQName(args.name, props)
-        url = 'https://%(apibase)s/namespaces/%(namespace)s/rules/%(name)s' % {
+        url = '%(apibase)s/namespaces/%(namespace)s/rules/%(name)s' % {
             'apibase': apiBase(props),
             'namespace': urllib.quote(namespace),
             'name': self.getSafeName(pname)
diff --git a/tools/cli/wsksdk.py b/tools/cli/wsksdk.py
index 56ff666..71e2273 100644
--- a/tools/cli/wsksdk.py
+++ b/tools/cli/wsksdk.py
@@ -17,7 +17,7 @@
 import os
 import subprocess
 import httplib
-from wskutil import request
+from wskutil import hostBase, request
 
 #
 # 'wsk sdk' CLI
@@ -61,7 +61,7 @@
         if os.path.exists(blackboxDir):
             print('The path ' + blackboxDir + ' already exists.  Please delete it and retry.')
             return -1
-        url = 'https://%s/%s' % (props['apihost'], tarFile)
+        url = '%s/%s' % (hostBase(props), tarFile)
         try:
             res = request('GET', url)
             if res.status == httplib.OK:
@@ -83,14 +83,14 @@
         if os.path.exists(zipFile):
             print('The path ' + zipFile + ' already exists.  Please delete it and retry.')
             return -1
-        url = 'https://%s/%s' % (props['apihost'], zipFile)
+        url = '%s/%s' % (hostBase(props), zipFile)
         try:
             res = request('GET', url)
             if res.status == httplib.OK:
                 with open(zipFile, 'wb') as f:
                     f.write(res.read())
 
-        except IOError as e:
+        except IOError:
             print('Download of OpenWhisk iOS starter app failed.')
             return -1
         print('\nDownloaded OpenWhisk iOS starter app. Unzip ' + zipFile + ' and open the project in Xcode.')
diff --git a/tools/cli/wsktrigger.py b/tools/cli/wsktrigger.py
index cfd3441..b161262 100644
--- a/tools/cli/wsktrigger.py
+++ b/tools/cli/wsktrigger.py
@@ -82,7 +82,7 @@
 
     def fire(self, args, props):
         namespace, pname = parseQName(args.name, props)
-        url = 'https://%(apibase)s/namespaces/%(namespace)s/triggers/%(name)s' % {
+        url = '%(apibase)s/namespaces/%(namespace)s/triggers/%(name)s' % {
             'apibase': apiBase(props),
             'namespace': urllib.quote(namespace),
             'name': self.getSafeName(pname)
diff --git a/tools/cli/wskutil.py b/tools/cli/wskutil.py
index d4c26a4..1fa62fb 100644
--- a/tools/cli/wskutil.py
+++ b/tools/cli/wskutil.py
@@ -306,7 +306,15 @@
         namespace = namespace if namespace else resolveNamespace({})
         return '%s%s%s%s' % (delimiter, namespace, delimiter, qname)
 
-def apiBase(props):
+def hostBase(props):
     host = props['apihost']
+    url = urlparse(host)
+    if url.scheme is '':
+        return 'https://%s' % host
+    else:
+        return host
+
+def apiBase(props):
+    host = hostBase(props)
     version = props['apiversion']
     return '%s/api/%s' % (host, version)