Repository: softlayer/softlayer-python
Pull request #654 (2015-12-02 00:18:02)

CLI Usability Tweeks
* **Removes global `--debug` option in favor of `--verbose` | `-v`.** -v can be specified multiple times to increase verbosity. For example, `-vvv` will the same as `--debug=3`
* Removes global `--timings` option
* Renames global `--fixtures` option to `--demo`
* Adds more diagnostics whenever the verbose (-v) flag is set including the info that was displayed with `--timings`
* Converts to using lowercase name/value for tables instead of upper-case since lower-case is generally preferred for this tool at the moment
* Shows default values for many CLI options

sudorandom: The new pylint errors will be solved by #655

Patch:
diff --git a/SoftLayer/CLI/cdn/detail.py b/SoftLayer/CLI/cdn/detail.py
index 45e5c221..509db536 100644
--- a/SoftLayer/CLI/cdn/detail.py
+++ b/SoftLayer/CLI/cdn/detail.py
@@ -17,9 +17,9 @@ def cli(env, account_id):
     manager = SoftLayer.CDNManager(env.client)
     account = manager.get_account(account_id)
 
-    table = formatting.KeyValueTable(['Name', 'Value'])
-    table.align['Name'] = 'r'
-    table.align['Value'] = 'l'
+    table = formatting.KeyValueTable(['name', 'value'])
+    table.align['name'] = 'r'
+    table.align['value'] = 'l'
 
     table.add_row(['id', account['id']])
     table.add_row(['account_name', account['cdnAccountName']])
diff --git a/SoftLayer/CLI/cdn/origin_add.py b/SoftLayer/CLI/cdn/origin_add.py
index aa233ecd..51d789da 100644
--- a/SoftLayer/CLI/cdn/origin_add.py
+++ b/SoftLayer/CLI/cdn/origin_add.py
@@ -14,7 +14,8 @@
 @click.argument('content_url')
 @click.option('--type',
               help='The media type for this mapping (http, flash, wm, ...)',
-              default='http')
+              default='http',
+              show_default=True)
 @click.option('--cname',
               help='An optional CNAME to attach to the mapping')
 @environment.pass_env
diff --git a/SoftLayer/CLI/config/__init__.py b/SoftLayer/CLI/config/__init__.py
index c6b6b316..fc1cca2b 100644
--- a/SoftLayer/CLI/config/__init__.py
+++ b/SoftLayer/CLI/config/__init__.py
@@ -42,9 +42,9 @@ def get_settings_from_client(client):
 
 def config_table(settings):
     """Returns a config table."""
-    table = formatting.KeyValueTable(['Name', 'Value'])
-    table.align['Name'] = 'r'
-    table.align['Value'] = 'l'
+    table = formatting.KeyValueTable(['name', 'value'])
+    table.align['name'] = 'r'
+    table.align['value'] = 'l'
     table.add_row(['Username', settings['username'] or 'not set'])
     table.add_row(['API Key', settings['api_key'] or 'not set'])
     table.add_row(['Endpoint URL', settings['endpoint_url'] or 'not set'])
diff --git a/SoftLayer/CLI/core.py b/SoftLayer/CLI/core.py
index d92b19d6..e8545aaf 100644
--- a/SoftLayer/CLI/core.py
+++ b/SoftLayer/CLI/core.py
@@ -7,7 +7,9 @@
 """
 from __future__ import print_function
 import logging
+import os
 import sys
+import time
 import types
 
 import click
@@ -16,10 +18,12 @@
 from SoftLayer.CLI import environment
 from SoftLayer.CLI import exceptions
 from SoftLayer.CLI import formatting
+from SoftLayer import consts
 
 # pylint: disable=too-many-public-methods, broad-except, unused-argument
 # pylint: disable=redefined-builtin, super-init-not-called
 
+START_TIME = time.time()
 DEBUG_LOGGING_MAP = {
     0: logging.CRITICAL,
     1: logging.WARNING,
@@ -73,27 +77,20 @@ def get_command(self, ctx, name):
                                'auto_envvar_prefix': 'SLCLI'})
 @click.option('--format',
               default=DEFAULT_FORMAT,
+              show_default=True,
               help="Output format",
               type=click.Choice(VALID_FORMATS))
 @click.option('--config', '-C',
               required=False,
               default=click.get_app_dir('softlayer', force_posix=True),
+              show_default=True,
               help="Config file location",
               type=click.Path(resolve_path=True))
-@click.option('--debug',
-              required=False,
-              default=None,
-              help="Sets the debug noise level",
-              type=click.Choice(sorted([str(key) for key
-                                        in DEBUG_LOGGING_MAP.keys()])))
 @click.option('--verbose', '-v',
-              help="Sets the debug noise level",
+              help="Sets the debug noise level, specify multiple times "
+                   "for more verbosity.",
               type=click.IntRange(0, 3, clamp=True),
               count=True)
-@click.option('--timings',
-              required=False,
-              is_flag=True,
-              help="Time each API call and display after results")
 @click.option('--proxy',
               required=False,
               help="HTTP[S] proxy to be use to make API calls")
@@ -101,29 +98,23 @@ def get_command(self, ctx, name):
               is_flag=True,
               required=False,
               help="Confirm all prompt actions")
-@click.option('--fixtures / --no-fixtures',
-              envvar='SL_FIXTURES',
+@click.option('--demo / --no-demo',
               is_flag=True,
               required=False,
-              help="Use fixtures instead of actually making API calls")
+              help="Use demo data instead of actually making API calls")
 @click.version_option(prog_name="slcli (SoftLayer Command-line)")
 @environment.pass_env
 def cli(env,
         format='table',
         config=None,
-        debug=0,
         verbose=0,
         proxy=None,
         really=False,
-        fixtures=False,
+        demo=False,
         **kwargs):
     """Main click CLI entry-point."""
 
-    # Set logging level
-    if debug is not None:
-        verbose = int(debug)
-
-    if verbose:
+    if verbose > 0:
         logger = logging.getLogger()
         logger.addHandler(logging.StreamHandler())
         logger.setLevel(DEBUG_LOGGING_MAP.get(verbose, logging.DEBUG))
@@ -134,7 +125,7 @@ def cli(env,
     env.format = format
     if env.client is None:
         # Environment can be passed in explicitly. This is used for testing
-        if fixtures:
+        if demo:
             client = SoftLayer.BaseClient(
                 transport=SoftLayer.FixtureTransport(),
                 auth=None,
@@ -147,23 +138,33 @@ def cli(env,
             )
         env.client = client
 
+    env.vars['_start'] = time.time()
     env.vars['_timings'] = SoftLayer.TimingTransport(env.client.transport)
     env.client.transport = env.vars['_timings']
 
 
 @cli.resultcallback()
 @environment.pass_env
-def output_result(env, timings=False, *args, **kwargs):
-    """Outputs the results returned by the CLI and also outputs timings."""
-
-    if timings and env.vars.get('_timings'):
-        timing_table = formatting.Table(['service', 'method', 'time'])
-
-        calls = env.vars['_timings'].get_last_calls()
-        for call, _, duration in calls:
-            timing_table.add_row([call.service, call.method, duration])
-
-        env.err(env.fmt(timing_table))
+def output_diagnostics(env, verbose=0, **kwargs):
+    """Output diagnostic information."""
+
+    if verbose > 0:
+        diagnostic_table = formatting.Table(['name', 'value'])
+        diagnostic_table.add_row(['execution_time',
+                                  '%fs' % (time.time() - START_TIME)])
+
+        api_call_value = []
+        for call, _, duration in env.vars['_timings'].get_last_calls():
+            api_call_value.append(
+                "%s::%s (%fs)" % (call.service, call.method, duration))
+
+        diagnostic_table.add_row(['api_calls', api_call_value])
+        diagnostic_table.add_row(['version', consts.USER_AGENT])
+        diagnostic_table.add_row(['python_version', sys.version])
+        diagnostic_table.add_row(['library_location',
+                                  os.path.dirname(SoftLayer.__file__)])
+
+        env.err(env.fmt(diagnostic_table))
 
 
 def main(reraise_exceptions=False, **kwargs):
diff --git a/SoftLayer/CLI/dns/record_add.py b/SoftLayer/CLI/dns/record_add.py
index 79a04fec..fbf8213b 100644
--- a/SoftLayer/CLI/dns/record_add.py
+++ b/SoftLayer/CLI/dns/record_add.py
@@ -17,6 +17,7 @@
 @click.option('--ttl',
               type=click.INT,
               default=7200,
+              show_default=True,
               help='TTL value in seconds, such as 86400')
 @environment.pass_env
 def cli(env, zone, record, type, data, ttl):
diff --git a/SoftLayer/CLI/formatting.py b/SoftLayer/CLI/formatting.py
index 51083e3c..15b97199 100644
--- a/SoftLayer/CLI/formatting.py
+++ b/SoftLayer/CLI/formatting.py
@@ -371,9 +371,9 @@ def iter_to_table(value):
 def _format_dict(result):
     """Format dictionary responses into key-value table."""
 
-    table = KeyValueTable(['Name', 'Value'])
-    table.align['Name'] = 'r'
-    table.align['Value'] = 'l'
+    table = KeyValueTable(['name', 'value'])
+    table.align['name'] = 'r'
+    table.align['value'] = 'l'
 
     for key, value in result.items():
         value = iter_to_table(value)
@@ -391,7 +391,7 @@ def _format_list(result):
     if isinstance(result[0], dict):
         return _format_list_objects(result)
 
-    table = Table(["Value"])
+    table = Table(['value'])
     for item in result:
         table.add_row([iter_to_table(item)])
     return table
diff --git a/SoftLayer/CLI/image/detail.py b/SoftLayer/CLI/image/detail.py
index cd2e2d8c..5bba1bea 100644
--- a/SoftLayer/CLI/image/detail.py
+++ b/SoftLayer/CLI/image/detail.py
@@ -28,9 +28,9 @@ def cli(env, identifier):
         if child.get('datacenter'):
             datacenters.append(utils.lookup(child, 'datacenter', 'name'))
 
-    table = formatting.KeyValueTable(['Name', 'Value'])
-    table.align['Name'] = 'r'
-    table.align['Value'] = 'l'
+    table = formatting.KeyValueTable(['name', 'value'])
+    table.align['name'] = 'r'
+    table.align['value'] = 'l'
 
     table.add_row(['id', image['id']])
     table.add_row(['global_identifier',
diff --git a/SoftLayer/CLI/image/import.py b/SoftLayer/CLI/image/import.py
index 7416bb70..03ec25ac 100644
--- a/SoftLayer/CLI/image/import.py
+++ b/SoftLayer/CLI/image/import.py
@@ -12,9 +12,11 @@
 @click.command()
 @click.argument('name')
 @click.argument('uri')
-@click.option('--note', default="",
+@click.option('--note',
+              default="",
               help="The note to be applied to the imported template")
-@click.option('--os-code', default="",
+@click.option('--os-code',
+              default="",
               help="The referenceCode of the operating system software"
                    " description for the imported VHD")
 @environment.pass_env
diff --git a/SoftLayer/CLI/iscsi/detail.py b/SoftLayer/CLI/iscsi/detail.py
index 22cd0da8..6ad43327 100644
--- a/SoftLayer/CLI/iscsi/detail.py
+++ b/SoftLayer/CLI/iscsi/detail.py
@@ -25,9 +25,9 @@ def cli(env, identifier, password):
     result = iscsi_mgr.get_iscsi(iscsi_id)
     result = utils.NestedDict(result)
 
-    table = formatting.KeyValueTable(['Name', 'Value'])
-    table.align['Name'] = 'r'
-    table.align['Value'] = 'l'
+    table = formatting.KeyValueTable(['name', 'value'])
+    table.align['name'] = 'r'
+    table.align['value'] = 'l'
 
     table.add_row(['id', result['id']])
     table.add_row(['serviceResourceName', result['serviceResourceName']])
diff --git a/SoftLayer/CLI/loadbal/detail.py b/SoftLayer/CLI/loadbal/detail.py
index a1d2d2ef..833f545b 100644
--- a/SoftLayer/CLI/loadbal/detail.py
+++ b/SoftLayer/CLI/loadbal/detail.py
@@ -20,9 +20,9 @@ def cli(env, identifier):
 
     load_balancer = mgr.get_local_lb(loadbal_id)
 
-    table = formatting.KeyValueTable(['Name', 'Value'])
-    table.align['Name'] = 'l'
-    table.align['Value'] = 'l'
+    table = formatting.KeyValueTable(['name', 'value'])
+    table.align['name'] = 'l'
+    table.align['value'] = 'l'
     table.add_row(['General properties', '----------'])
     table.add_row([' ID', 'local:%s' % load_balancer['id']])
     table.add_row([' IP Address', load_balancer['ipAddress']['ipAddress']])
diff --git a/SoftLayer/CLI/metadata.py b/SoftLayer/CLI/metadata.py
index f85c7aa4..1d25ee38 100644
--- a/SoftLayer/CLI/metadata.py
+++ b/SoftLayer/CLI/metadata.py
@@ -72,8 +72,8 @@ def get_network():
         network = network_func()
 
         table = formatting.KeyValueTable(['name', 'value'])
-        table.align['Name'] = 'r'
-        table.align['Value'] = 'l'
+        table.align['name'] = 'r'
+        table.align['value'] = 'l'
         table.add_row(['mac addresses',
                        formatting.listing(network['mac_addresses'],
                                           separator=',')])
diff --git a/SoftLayer/CLI/mq/queue_add.py b/SoftLayer/CLI/mq/queue_add.py
index f54b4f52..59452711 100644
--- a/SoftLayer/CLI/mq/queue_add.py
+++ b/SoftLayer/CLI/mq/queue_add.py
@@ -19,11 +19,13 @@
 @click.option('--visibility-interval',
               type=click.INT,
               default=30,
+              show_default=True,
               help="Time in seconds that messages will re-appear after being "
                    "popped")
 @click.option('--expiration',
               type=click.INT,
               default=604800,
+              show_default=True,
               help="Time in seconds that messages will live")
 @helpers.multi_option('--tag', '-g', help="Tags to add to the queue")
 @environment.pass_env
diff --git a/SoftLayer/CLI/mq/queue_edit.py b/SoftLayer/CLI/mq/queue_edit.py
index b19c2c07..1f97788b 100644
--- a/SoftLayer/CLI/mq/queue_edit.py
+++ b/SoftLayer/CLI/mq/queue_edit.py
@@ -19,11 +19,13 @@
 @click.option('--visibility-interval',
               type=click.INT,
               default=30,
+              show_default=True,
               help="Time in seconds that messages will re-appear after being "
                    "popped")
 @click.option('--expiration',
               type=click.INT,
               default=604800,
+              show_default=True,
               help="Time in seconds that messages will live")
 @helpers.multi_option('--tag', '-g', help="Tags to add to the queue")
 @environment.pass_env
diff --git a/SoftLayer/CLI/mq/queue_pop.py b/SoftLayer/CLI/mq/queue_pop.py
index c2db94c3..1d81e9ea 100644
--- a/SoftLayer/CLI/mq/queue_pop.py
+++ b/SoftLayer/CLI/mq/queue_pop.py
@@ -13,6 +13,7 @@
 @click.argument('queue-name')
 @click.option('--count',
               default=1,
+              show_default=True,
               type=click.INT,
               help="Count of messages to pop")
 @click.option('--delete-after',
diff --git a/SoftLayer/CLI/mq/topic_add.py b/SoftLayer/CLI/mq/topic_add.py
index 88e66d2b..0b48874c 100644
--- a/SoftLayer/CLI/mq/topic_add.py
+++ b/SoftLayer/CLI/mq/topic_add.py
@@ -19,11 +19,13 @@
 @click.option('--visibility-interval',
               type=click.INT,
               default=30,
+              show_default=True,
               help="Time in seconds that messages will re-appear after being "
                    "popped")
 @click.option('--expiration',
               type=click.INT,
               default=604800,
+              show_default=True,
               help="Time in seconds that messages will live")
 @helpers.multi_option('--tag', '-g', help="Tags to add to the topic")
 @environment.pass_env
diff --git a/SoftLayer/CLI/rwhois/show.py b/SoftLayer/CLI/rwhois/show.py
index 63caa611..9e862b0f 100644
--- a/SoftLayer/CLI/rwhois/show.py
+++ b/SoftLayer/CLI/rwhois/show.py
@@ -16,9 +16,9 @@ def cli(env):
     mgr = SoftLayer.NetworkManager(env.client)
     result = mgr.get_rwhois()
 
-    table = formatting.KeyValueTable(['Name', 'Value'])
-    table.align['Name'] = 'r'
-    table.align['Value'] = 'l'
+    table = formatting.KeyValueTable(['name', 'value'])
+    table.align['name'] = 'r'
+    table.align['value'] = 'l'
     table.add_row(['Name', result['firstName'] + ' ' + result['lastName']])
     table.add_row(['Company', result['companyName']])
     table.add_row(['Abuse Email', result['abuseEmail']])
diff --git a/SoftLayer/CLI/server/create.py b/SoftLayer/CLI/server/create.py
index 633b834c..dcd53565 100644
--- a/SoftLayer/CLI/server/create.py
+++ b/SoftLayer/CLI/server/create.py
@@ -38,6 +38,7 @@
 @click.option('--billing',
               type=click.Choice(['hourly', 'monthly']),
               default='hourly',
+              show_default=True,
               help="Billing rate")
 @click.option('--postinstall', '-i', help="Post-install script to download")
 @helpers.multi_option('--key', '-k',
diff --git a/SoftLayer/CLI/server/detail.py b/SoftLayer/CLI/server/detail.py
index 9c1e5b0e..012c5df5 100644
--- a/SoftLayer/CLI/server/detail.py
+++ b/SoftLayer/CLI/server/detail.py
@@ -24,9 +24,9 @@ def cli(env, identifier, passwords, price):
 
     hardware = SoftLayer.HardwareManager(env.client)
 
-    table = formatting.KeyValueTable(['Name', 'Value'])
-    table.align['Name'] = 'r'
-    table.align['Value'] = 'l'
+    table = formatting.KeyValueTable(['name', 'value'])
+    table.align['name'] = 'r'
+    table.align['value'] = 'l'
 
     hardware_id = helpers.resolve_id(hardware.resolve_ids,
                                      identifier,
diff --git a/SoftLayer/CLI/server/list.py b/SoftLayer/CLI/server/list.py
index 9b27d719..92abddf7 100644
--- a/SoftLayer/CLI/server/list.py
+++ b/SoftLayer/CLI/server/list.py
@@ -52,12 +52,15 @@
 @click.option('--memory', '-m', help='Filter by memory in gigabytes')
 @click.option('--network', '-n', help='Filter by network port speed in Mbps')
 @helpers.multi_option('--tag', help='Filter by tags')
-@click.option('--sortby', help='Column to sort by', default='hostname')
+@click.option('--sortby', help='Column to sort by',
+              default='hostname',
+              show_default=True)
 @click.option('--columns',
               callback=column_helper.get_formatter(COLUMNS),
-              help='Columns to display. Options: %s'
+              help='Columns to display. [options: %s]'
               % ', '.join(column.name for column in COLUMNS),
-              default=','.join(DEFAULT_COLUMNS))
+              default=','.join(DEFAULT_COLUMNS),
+              show_default=True)
 @environment.pass_env
 def cli(env, sortby, cpu, domain, datacenter, hostname, memory, network, tag,
         columns):
diff --git a/SoftLayer/CLI/sshkey/print.py b/SoftLayer/CLI/sshkey/print.py
index 4697353e..2bcdcd3b 100644
--- a/SoftLayer/CLI/sshkey/print.py
+++ b/SoftLayer/CLI/sshkey/print.py
@@ -29,7 +29,7 @@ def cli(env, identifier, out_file):
         with open(path.expanduser(out_file), 'w') as pub_file:
             pub_file.write(key['key'])
 
-    table = formatting.KeyValueTable(['Name', 'Value'])
+    table = formatting.KeyValueTable(['name', 'value'])
     table.add_row(['id', key['id']])
     table.add_row(['label', key.get('label')])
     table.add_row(['notes', key.get('notes', '-')])
diff --git a/SoftLayer/CLI/ssl/list.py b/SoftLayer/CLI/ssl/list.py
index 07483bd3..b07dd96c 100644
--- a/SoftLayer/CLI/ssl/list.py
+++ b/SoftLayer/CLI/ssl/list.py
@@ -11,6 +11,7 @@
 @click.command()
 @click.option('--status',
               default="all",
+              show_default=True,
               type=click.Choice(['all', 'valid', 'expired']),
               help="Show certificates with this status")
 @click.option('--sortby',
diff --git a/SoftLayer/CLI/subnet/detail.py b/SoftLayer/CLI/subnet/detail.py
index b353bfdf..cfc0dadb 100644
--- a/SoftLayer/CLI/subnet/detail.py
+++ b/SoftLayer/CLI/subnet/detail.py
@@ -26,9 +26,9 @@ def cli(env, identifier, no_vs, no_hardware):
                                    name='subnet')
     subnet = mgr.get_subnet(subnet_id)
 
-    table = formatting.KeyValueTable(['Name', 'Value'])
-    table.align['Name'] = 'r'
-    table.align['Value'] = 'l'
+    table = formatting.KeyValueTable(['name', 'value'])
+    table.align['name'] = 'r'
+    table.align['value'] = 'l'
 
     table.add_row(['id', subnet['id']])
     table.add_row(['identifier',
diff --git a/SoftLayer/CLI/subnet/lookup.py b/SoftLayer/CLI/subnet/lookup.py
index 0268caab..57dacb8d 100644
--- a/SoftLayer/CLI/subnet/lookup.py
+++ b/SoftLayer/CLI/subnet/lookup.py
@@ -22,16 +22,16 @@ def cli(env, ip_address):
     if not addr_info:
         raise exceptions.CLIAbort('Not found')
 
-    table = formatting.KeyValueTable(['Name', 'Value'])
-    table.align['Name'] = 'r'
-    table.align['Value'] = 'l'
+    table = formatting.KeyValueTable(['name', 'value'])
+    table.align['name'] = 'r'
+    table.align['value'] = 'l'
 
     table.add_row(['id', addr_info['id']])
     table.add_row(['ip', addr_info['ipAddress']])
 
-    subnet_table = formatting.KeyValueTable(['Name', 'Value'])
-    subnet_table.align['Name'] = 'r'
-    subnet_table.align['Value'] = 'l'
+    subnet_table = formatting.KeyValueTable(['name', 'value'])
+    subnet_table.align['name'] = 'r'
+    subnet_table.align['value'] = 'l'
     subnet_table.add_row(['id', addr_info['subnet']['id']])
     subnet_table.add_row(['identifier',
                           '%s/%s' % (addr_info['subnet']['networkIdentifier'],
@@ -44,9 +44,9 @@ def cli(env, ip_address):
     table.add_row(['subnet', subnet_table])
 
     if addr_info.get('virtualGuest') or addr_info.get('hardware'):
-        device_table = formatting.KeyValueTable(['Name', 'Value'])
-        device_table.align['Name'] = 'r'
-        device_table.align['Value'] = 'l'
+        device_table = formatting.KeyValueTable(['name', 'value'])
+        device_table.align['name'] = 'r'
+        device_table.align['value'] = 'l'
         if addr_info.get('virtualGuest'):
             device = addr_info['virtualGuest']
             device_type = 'vs'
diff --git a/SoftLayer/CLI/summary.py b/SoftLayer/CLI/summary.py
index 9e0d59f2..f39481d9 100644
--- a/SoftLayer/CLI/summary.py
+++ b/SoftLayer/CLI/summary.py
@@ -12,6 +12,7 @@
 @click.option('--sortby',
               help='Column to sort by',
               default='datacenter',
+              show_default=True,
               type=click.Choice(['datacenter',
                                  'hardware',
                                  'virtual_servers',
diff --git a/SoftLayer/CLI/ticket/__init__.py b/SoftLayer/CLI/ticket/__init__.py
index 4759b5e0..e5f711d9 100644
--- a/SoftLayer/CLI/ticket/__init__.py
+++ b/SoftLayer/CLI/ticket/__init__.py
@@ -18,9 +18,9 @@ def get_ticket_results(mgr, ticket_id, update_count=1):
     """
     ticket = mgr.get_ticket(ticket_id)
 
-    table = formatting.KeyValueTable(['Name', 'Value'])
-    table.align['Name'] = 'r'
-    table.align['Value'] = 'l'
+    table = formatting.KeyValueTable(['name', 'value'])
+    table.align['name'] = 'r'
+    table.align['value'] = 'l'
 
     table.add_row(['id', ticket['id']])
     table.add_row(['title', ticket['title']])
diff --git a/SoftLayer/CLI/ticket/detail.py b/SoftLayer/CLI/ticket/detail.py
index 6d45de0e..b31c7e0c 100644
--- a/SoftLayer/CLI/ticket/detail.py
+++ b/SoftLayer/CLI/ticket/detail.py
@@ -11,7 +11,11 @@
 
 @click.command()
 @click.argument('identifier')
-@click.option('--count', type=click.INT, help="Number of updates", default=10)
+@click.option('--count',
+              type=click.INT,
+              help="Number of updates",
+              show_default=True,
+              default=10)
 @environment.pass_env
 def cli(env, identifier, count):
     """Get details for a ticket."""
diff --git a/SoftLayer/CLI/virt/capture.py b/SoftLayer/CLI/virt/capture.py
index b116d61d..84697497 100644
--- a/SoftLayer/CLI/virt/capture.py
+++ b/SoftLayer/CLI/virt/capture.py
@@ -25,9 +25,9 @@ def cli(env, identifier, name, all, note):
 
     capture = vsi.capture(vs_id, name, all, note)
 
-    table = formatting.KeyValueTable(['Name', 'Value'])
-    table.align['Name'] = 'r'
-    table.align['Value'] = 'l'
+    table = formatting.KeyValueTable(['name', 'value'])
+    table.align['name'] = 'r'
+    table.align['value'] = 'l'
 
     table.add_row(['vs_id', capture['guestId']])
     table.add_row(['date', capture['createDate'][:10]])
diff --git a/SoftLayer/CLI/virt/create.py b/SoftLayer/CLI/virt/create.py
index f81ed32f..189eb53f 100644
--- a/SoftLayer/CLI/virt/create.py
+++ b/SoftLayer/CLI/virt/create.py
@@ -149,6 +149,7 @@ def _parse_create_args(client, args):
 @click.option('--billing',
               type=click.Choice(['hourly', 'monthly']),
               default='hourly',
+              show_default=True,
               help="Billing rate")
 @click.option('--dedicated/--public',
               is_flag=True,
diff --git a/SoftLayer/CLI/virt/create_options.py b/SoftLayer/CLI/virt/create_options.py
index 4b2feb7a..41b7a164 100644
--- a/SoftLayer/CLI/virt/create_options.py
+++ b/SoftLayer/CLI/virt/create_options.py
@@ -18,9 +18,9 @@ def cli(env):
     vsi = SoftLayer.VSManager(env.client)
     result = vsi.get_create_options()
 
-    table = formatting.KeyValueTable(['Name', 'Value'])
-    table.align['Name'] = 'r'
-    table.align['Value'] = 'l'
+    table = formatting.KeyValueTable(['name', 'value'])
+    table.align['name'] = 'r'
+    table.align['value'] = 'l'
 
     # Datacenters
     datacenters = [dc['template']['datacenter']['name']
diff --git a/SoftLayer/CLI/virt/detail.py b/SoftLayer/CLI/virt/detail.py
index c681d8a5..957cce83 100644
--- a/SoftLayer/CLI/virt/detail.py
+++ b/SoftLayer/CLI/virt/detail.py
@@ -21,9 +21,9 @@ def cli(env, identifier, passwords=False, price=False):
     """Get details for a virtual server."""
 
     vsi = SoftLayer.VSManager(env.client)
-    table = formatting.KeyValueTable(['Name', 'Value'])
-    table.align['Name'] = 'r'
-    table.align['Value'] = 'l'
+    table = formatting.KeyValueTable(['name', 'value'])
+    table.align['name'] = 'r'
+    table.align['value'] = 'l'
 
     vs_id = helpers.resolve_id(vsi.resolve_ids, identifier, 'VS')
     result = vsi.get_instance(vs_id)
diff --git a/SoftLayer/CLI/virt/dns.py b/SoftLayer/CLI/virt/dns.py
index e5e0fdc7..bd17df60 100644
--- a/SoftLayer/CLI/virt/dns.py
+++ b/SoftLayer/CLI/virt/dns.py
@@ -21,6 +21,7 @@
 @click.option('--ptr', is_flag=True, help="Sync the PTR record for the host")
 @click.option('--ttl',
               default=7200,
+              show_default=True,
               type=click.INT,
               help="Sets the TTL for the A and/or PTR records")
 @environment.pass_env
diff --git a/SoftLayer/CLI/virt/list.py b/SoftLayer/CLI/virt/list.py
index 81164211..b2cd64f6 100644
--- a/SoftLayer/CLI/virt/list.py
+++ b/SoftLayer/CLI/virt/list.py
@@ -52,12 +52,16 @@
 @click.option('--hourly', is_flag=True, help='Show only hourly instances')
 @click.option('--monthly', is_flag=True, help='Show only monthly instances')
 @helpers.multi_option('--tag', help='Filter by tags')
-@click.option('--sortby', help='Column to sort by', default='hostname')
+@click.option('--sortby',
+              help='Column to sort by',
+              default='hostname',
+              show_default=True)
 @click.option('--columns',
               callback=column_helper.get_formatter(COLUMNS),
-              help='Columns to display. Options: %s'
+              help='Columns to display. [options: %s]'
               % ', '.join(column.name for column in COLUMNS),
-              default=','.join(DEFAULT_COLUMNS))
+              default=','.join(DEFAULT_COLUMNS),
+              show_default=True)
 @environment.pass_env
 def cli(env, sortby, cpu, domain, datacenter, hostname, memory, network,
         hourly, monthly, tag, columns):
diff --git a/SoftLayer/CLI/virt/ready.py b/SoftLayer/CLI/virt/ready.py
index 8c708dc4..1be2e1b4 100644
--- a/SoftLayer/CLI/virt/ready.py
+++ b/SoftLayer/CLI/virt/ready.py
@@ -11,7 +11,11 @@
 
 @click.command()
 @click.argument('identifier')
-@click.option('--wait', default=0, type=click.INT, help="Name of the image")
+@click.option('--wait',
+              default=0,
+              show_default=True,
+              type=click.INT,
+              help="Name of the image")
 @environment.pass_env
 def cli(env, identifier, wait):
     """Check if a virtual server is ready."""
diff --git a/SoftLayer/CLI/vlan/detail.py b/SoftLayer/CLI/vlan/detail.py
index 14782b09..6a8056fe 100644
--- a/SoftLayer/CLI/vlan/detail.py
+++ b/SoftLayer/CLI/vlan/detail.py
@@ -26,9 +26,9 @@ def cli(env, identifier, no_vs, no_hardware):
     vlan_id = helpers.resolve_id(mgr.resolve_vlan_ids, identifier, 'VLAN')
     vlan = mgr.get_vlan(vlan_id)
 
-    table = formatting.KeyValueTable(['Name', 'Value'])
-    table.align['Name'] = 'r'
-    table.align['Value'] = 'l'
+    table = formatting.KeyValueTable(['name', 'value'])
+    table.align['name'] = 'r'
+    table.align['value'] = 'l'
 
     table.add_row(['id', vlan['id']])
     table.add_row(['number', vlan['vlanNumber']])
@@ -40,9 +40,9 @@ def cli(env, identifier, no_vs, no_hardware):
                    'Yes' if vlan['firewallInterfaces'] else 'No'])
     subnets = []
     for subnet in vlan['subnets']:
-        subnet_table = formatting.KeyValueTable(['Name', 'Value'])
-        subnet_table.align['Name'] = 'r'
-        subnet_table.align['Value'] = 'l'
+        subnet_table = formatting.KeyValueTable(['name', 'value'])
+        subnet_table.align['name'] = 'r'
+        subnet_table.align['value'] = 'l'
         subnet_table.add_row(['id', subnet['id']])
         subnet_table.add_row(['identifier', subnet['networkIdentifier']])
         subnet_table.add_row(['netmask', subnet['netmask']])


Test patch:
diff --git a/SoftLayer/testing/__init__.py b/SoftLayer/testing/__init__.py
index 328a6fcf..1bd6c47f 100644
--- a/SoftLayer/testing/__init__.py
+++ b/SoftLayer/testing/__init__.py
@@ -162,7 +162,7 @@ def run_command(self,
         args = args or []
 
         if fixtures is True:
-            args.insert(0, '--fixtures')
+            args.insert(0, '--demo')
         args.insert(0, '--format=%s' % fmt)
 
         runner = testing.CliRunner()
diff --git a/tests/CLI/core_tests.py b/tests/CLI/core_tests.py
index ee281339..75e4a07c 100644
--- a/tests/CLI/core_tests.py
+++ b/tests/CLI/core_tests.py
@@ -27,14 +27,6 @@ def test_load_all(self):
                 if ex.code != 0:
                     self.fail("Non-zero exit code for command: %s" % path)
 
-    def test_debug_max(self):
-        with mock.patch('logging.getLogger') as log_mock:
-            result = self.run_command(['--debug=3', 'vs', 'list'])
-
-            self.assertEqual(result.exit_code, 0)
-            log_mock().addHandler.assert_called_with(mock.ANY)
-            log_mock().setLevel.assert_called_with(logging.DEBUG)
-
     def test_verbose_max(self):
         with mock.patch('logging.getLogger') as log_mock:
             result = self.run_command(['-vvv', 'vs', 'list'])
@@ -50,13 +42,16 @@ def test_build_client(self):
         self.assertEqual(result.exit_code, 0)
         self.assertIsNotNone(env.client)
 
-    def test_timings(self):
-        result = self.run_command(['--timings', 'vs', 'list'])
+    def test_diagnostics(self):
+        result = self.run_command(['-v', 'vs', 'list'])
 
         self.assertEqual(result.exit_code, 0)
-        self.assertIn('"method": "getVirtualGuests"', result.output)
-        self.assertIn('"service": "SoftLayer_Account"', result.output)
-        self.assertIn('"time":', result.output)
+        self.assertIn('SoftLayer_Account::getVirtualGuests', result.output)
+        self.assertIn('"execution_time"', result.output)
+        self.assertIn('"api_calls"', result.output)
+        self.assertIn('"version"', result.output)
+        self.assertIn('"python_version"', result.output)
+        self.assertIn('"library_location"', result.output)
 
 
 class CoreMainTests(testing.TestCase):
diff --git a/tests/CLI/helper_tests.py b/tests/CLI/helper_tests.py
index b2fb49fa..59b41d92 100644
--- a/tests/CLI/helper_tests.py
+++ b/tests/CLI/helper_tests.py
@@ -423,7 +423,7 @@ def test_format_api_dict(self):
         result = formatting._format_dict({'key': 'value'})
 
         self.assertIsInstance(result, formatting.Table)
-        self.assertEqual(result.columns, ['Name', 'Value'])
+        self.assertEqual(result.columns, ['name', 'value'])
         self.assertEqual(result.rows, [['key', 'value']])
 
     def test_format_api_list(self):
@@ -437,5 +437,5 @@ def test_format_api_list_non_objects(self):
         result = formatting._format_list(['a', 'b', 'c'])
 
         self.assertIsInstance(result, formatting.Table)
-        self.assertEqual(result.columns, ['Value'])
+        self.assertEqual(result.columns, ['value'])
         self.assertEqual(result.rows, [['a'], ['b'], ['c']])
diff --git a/tests/CLI/modules/call_api_tests.py b/tests/CLI/modules/call_api_tests.py
index 13dda3c3..14164efa 100644
--- a/tests/CLI/modules/call_api_tests.py
+++ b/tests/CLI/modules/call_api_tests.py
@@ -61,7 +61,7 @@ def test_object_table(self):
         self.assertEqual(result.exit_code, 0)
         # NOTE(kmcdonald): Order is not guaranteed
         self.assertIn(":........:........:", result.output)
-        self.assertIn(":   Name : Value  :", result.output)
+        self.assertIn(":   name : value  :", result.output)
         self.assertIn(":    int : 10     :", result.output)
         self.assertIn(":   None : None   :", result.output)
         self.assertIn(":  float : 1.0    :", result.output)