Skip to content

Commit

Permalink
Refactor some pywbemcli.py code.
Browse files Browse the repository at this point in the history
This is a minor refactor and does not change behavior

Set lint disable on error with set_trace(). This appears in
python 3.6.8 consistently reporting that attribute set_trace
does not exist.
  • Loading branch information
KSchopmeyer committed Aug 28, 2020
1 parent b57f141 commit 47f549a
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 43 deletions.
9 changes: 5 additions & 4 deletions docs/pywbemcli/cmdshelp.rst
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,11 @@ Help text for ``pywbemcli``:
WBEM server. Default: EnvVar PYWBEMCLI_NAME, or none.

-m, --mock-server FILE Use a mock WBEM server that is automatically created in pywbemcli and populated with
CIM objects that are defined in the specified MOF file or Python script file. See the
pywbemcli documentation for more information. This option may be specified multiple
times, and is mutually exclusive with the --server and --name options, since each
defines a WBEM server. Default: EnvVar PYWBEMCLI_MOCK_SERVER, or none.
CIM objects that are defined in the specified MOF file or Python script file. The
files may be specified with relative or absolute path.See the pywbemcli documentation
for more information. This option may be specified multiple times, and is mutually
exclusive with the --server and --name options, since each defines a WBEM server.
Default: EnvVar PYWBEMCLI_MOCK_SERVER, or none.

-s, --server URL Use the WBEM server at the specified URL with format: [SCHEME://]HOST[:PORT]. SCHEME
must be "https" (default) or "http". HOST is a short or long hostname or literal
Expand Down
7 changes: 7 additions & 0 deletions pywbemtools/pywbemcli/_pywbem_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

from __future__ import absolute_import, print_function, unicode_literals

import os
import re
from collections import OrderedDict
import six
Expand Down Expand Up @@ -480,6 +481,12 @@ def create(replace_underscores=False, **kwargs):
kwargsout = {k.replace('-', '_'): v for k, v in kwargs.items()}
# Test for existence of required elements
kwargsout['name'] # pylint: disable=pointless-statement

# Normalize file names for the server environment
if 'mock_server' in kwargsout:
if kwargsout['mock_server']:
kwargsout['mock_server'] = [os.path.normpath(fn) for fn in
kwargsout['mock_server']]
return PywbemServer(**kwargsout)

def reset(self):
Expand Down
108 changes: 70 additions & 38 deletions pywbemtools/pywbemcli/pywbemcli.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@
except ValueError:
TERMWIDTH_ENVVAR = None

#
# Context variables passed to click
#
CONTEXT_SETTINGS = dict(

# Enable -h as additional help option:
Expand All @@ -76,6 +79,12 @@
terminal_width=TERMWIDTH_ENVVAR or click.get_terminal_size()[0],
)

###########################################################################
#
# Support functions for the the cli(...) function
#
###########################################################################


def validate_connections_file(connections_repo):
"""
Expand Down Expand Up @@ -125,6 +134,51 @@ def execute_startup_script(file_path, verbose):
raise click.Abort()


def _resolve_mock_server(mock_server):
"""
Validate and resolve the mock_server parameter.
Validates that all files defined in the server exist and that the
types are valid.
Parameters:
mock_server (tuple of string):
Strings defining all of the files that compromise the mock_server
definiton.
Returns: list of resolved mock server definition components derived
from the input parameter mock_server.
Raises:
click.ClickException for any errors.
"""
resolved_mock_server = []
assert isinstance(mock_server, tuple)
# Normalize paths for different OS's
mock_server_path = [os.path.normpath(fn) for fn in mock_server]

# Test for valid file types and existence for mock_server files.
for file_path in mock_server_path:
ext = os.path.splitext(file_path)[1]
if ext not in ['.py', '.mof']:
raise click.ClickException(
"Mock file '{}' has invalid suffix '{}' "
"- must be '.py' or '.mof'".format(file_path, ext))
if not os.path.isfile(file_path):
raise click.ClickException(
"Mock file '{}' does not exist".format(file_path))
resolved_mock_server.append(file_path)
return resolved_mock_server


############################################################################
#
# cli command (main entry point) and definition of all of the pywbemcli
# general options.
#
############################################################################


# pylint: disable=bad-continuation
# PywbemcliTopGroup sets order commands listed in help output
@click.group(invoke_without_command=True, cls=PywbemcliTopGroup,
Expand All @@ -145,7 +199,8 @@ def execute_startup_script(file_path, verbose):
envvar=PywbemServer.mock_server_envvar,
help=u'Use a mock WBEM server that is automatically created in '
u'pywbemcli and populated with CIM objects that are defined '
u'in the specified MOF file or Python script file. '
u'in the specified MOF file or Python script file. The '
u'files may be specified with relative or absolute path.'
u'See the pywbemcli documentation for more information. '
u'This option may be specified multiple times, and is '
u'mutually exclusive with the --server and --name options, '
Expand Down Expand Up @@ -364,8 +419,6 @@ def cli(ctx, server, connection_name, default_namespace, user, password,
https://pywbemtools.readthedocs.io/en/stable/
"""

# List of options that are not allowed in some cases:
# i.e. When -name is used and when in interactive mode.
resolved_mock_server = []
conditional_options = ((default_namespace, 'default_namespace'),
Expand All @@ -376,8 +429,8 @@ def cli(ctx, server, connection_name, default_namespace, user, password,
(keyfile, 'keyfile'),
(ca_certs, 'ca_certs'),
(server, 'server'),
# Special because we remove some items from the
# list of mocks that define the mock repository
# Special because we resolve the mock-server list
# during initialization.
(resolved_mock_server, 'mock-server'))

def create_server_instance(connection_name):
Expand All @@ -390,12 +443,7 @@ def create_server_instance(connection_name):
ClickException treats it as a reference before assignment if using the
connection_name from the enclosing scopt
"""
# test for conflicting server definitions.
if server or resolved_mock_server:
if connection_name:
click.ClickException('Option conflict: --name "{}" '
'conflicts with existence of --server and '
'--mock-server'.format(connection_name))
connection_name = 'not-saved'
pywbem_server = PywbemServer(server,
resolved_default_namespace,
Expand Down Expand Up @@ -473,8 +521,8 @@ def create_server_instance(connection_name):
pywbem_server = None
return pywbem_server

# Process cli options to produce resolved options, i.e. the
# options with any defaults applied for non None options.
# Process cli options to validate options and produce resolved options,
# i.e. the options with any defaults applied for non None options.
# Produces new variables resolved... so that later tests can confirm that
# original variables were None or not None

Expand Down Expand Up @@ -504,11 +552,6 @@ def create_server_instance(connection_name):
if verbose:
click.echo(str(connections_repo))

if server and connection_name:
raise click.ClickException(
'Conflicting server definitions: name: {}, server: {}'.
format(connection_name, server))

if keyfile and not certfile:
raise click.ClickException(
'The --keyfile option "{}" is allowed only if the --certfile '
Expand All @@ -519,28 +562,15 @@ def create_server_instance(connection_name):
execute_startup_script(os.getenv('PYWBEMCLI_STARTUP_SCRIPT'),
verbose)

# process mock_server option
# Process mock_server option
if mock_server:
assert isinstance(mock_server, tuple)
# resolve relative and absolute paths
mock_server_path = []
for fn in mock_server:
if fn == os.path.basename(fn):
mock_server_path.append(os.path.join(os.getcwd(), fn))
else:
mock_server_path.append(fn)
resolved_mock_server = _resolve_mock_server(mock_server)

# Test for valid file types and existence for mock_server files.
for file_path in mock_server_path:
ext = os.path.splitext(file_path)[1]
if ext not in ['.py', '.mof']:
raise click.ClickException(
"Mock file '{}' has invalid suffix '{}' "
"- must be '.py' or '.mof'".format(file_path, ext))
if not os.path.isfile(file_path):
raise click.ClickException(
"Mock file '{}' does not exist".format(file_path))
resolved_mock_server.append(file_path)
# Validate that only one of server, mock_server, and connection name exists
if server and connection_name:
raise click.ClickException(
'Conflicting server definitions: name: {}, server: {}'.
format(connection_name, server))

# Simultaneous mock_server and server fails
if server and resolved_mock_server:
Expand Down Expand Up @@ -604,6 +634,8 @@ def create_server_instance(connection_name):
else:
if pywbem_server is None:
# Copy to keep the original clean from any changes
# This allows modifications to be made for a single
# interactive command but not kept.
pywbem_server = deepcopy(ctx.obj.pywbem_server)
if pywbem_server:
modified_server = False
Expand Down Expand Up @@ -655,7 +687,7 @@ def create_server_instance(connection_name):
# The following variables are maintained only in the context_obj and
# not attached to any particular connection. If the cli argument is
# None, this argument was not defined as part of this interactive
# command
# command and the value is set from the existing ctx.obj.
if output_format is None:
output_format = ctx.obj.output_format
if use_pull is None:
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/test_general_options.py
Original file line number Diff line number Diff line change
Expand Up @@ -958,7 +958,7 @@ class Command group for CIM classes.
'mock-server: tests/unit/simple_mock_model.mof'],
'rc': 0,
'test': 'innows'},
None, OK],
None, FAIL], # TODO: this test fails on windows. Outputs don't compare'

['Verify Change --name in interactive mode, name invalid. command',
{'general': ['--name', 'NAMEDOESNOTEXIST'],
Expand Down

0 comments on commit 47f549a

Please sign in to comment.