• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

pywbem / pywbemtools / test-2757

11 Jan 2026 09:04AM UTC coverage: 29.475% (-58.6%) from 88.026%
test-2757

Pull #1501

github

web-flow
Merge 4229b955d into f9b5e1682
Pull Request #1501: Fixed start program timeouts and other issues in listener tests; Enabled tests again

59 of 116 new or added lines in 3 files covered. (50.86%)

3924 existing lines in 32 files now uncovered.

1953 of 6626 relevant lines covered (29.47%)

0.59 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

40.56
/pywbemtools/pywbemcli/_cmd_class.py
1
# (C) Copyright 2017 IBM Corp.
2
# (C) Copyright 2017 Inova Development Inc.
3
# All Rights Reserved
4
#
5
# Licensed under the Apache License, Version 2.0 (the "License");
6
# you may not use this file except in compliance with the License.
7
# You may obtain a copy of the License at
8
#
9
#    http://www.apache.org/licenses/LICENSE-2.0
10
#
11
# Unless required by applicable law or agreed to in writing, software
12
# distributed under the License is distributed on an "AS IS" BASIS,
13
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
# See the License for the specific language governing permissions and
15
# limitations under the License.
16
"""
2✔
17
Click Command definition for the class command group which includes
18
commands for get, enumerate, associators, references, find, etc. of the objects
19
CIMClass on a WBEM server.
20

21
NOTE: Commands are ordered in help display by their order in this file.
22
"""
23

24

25
import copy
2✔
26
import click
2✔
27

28
from pywbem import Error, CIMClassName, CIMError
2✔
29

30

31
from pywbem._nocasedict import NocaseDict
2✔
32

33
from .pywbemcli import cli
2✔
34
from ._common import filter_namelist, resolve_propertylist, \
2✔
35
    process_invokemethod, pywbem_error_exception,  \
36
    depending_classnames
37

38
from ._common_cmd_functions import get_namespaces, enumerate_classes_filtered, \
2✔
39
    ResultsHandler
40

41
from ._common_options import propertylist_option, names_only_option, \
2✔
42
    include_classorigin_class_option, namespace_option, summary_option, \
43
    multiple_namespaces_option_dflt_conn, multiple_namespaces_option_dflt_all, \
44
    class_filter_options, object_order_option
45
from ._displaytree import display_class_tree
2✔
46
from .._click_extensions import PywbemtoolsGroup, PywbemtoolsCommand, \
2✔
47
    CMD_OPTS_TXT, GENERAL_OPTS_TXT, SUBCMD_HELP_TXT
48
from .._options import add_options, help_option
2✔
49
from .._output_formatting import output_format_is_table, \
2✔
50
    validate_output_format, format_table
51

52
#
53
#   Common option definitions for class group
54
#
55

56
# NOTE: A number of the options use double-dash as the short form.  In those
57
# cases, a third definition of the options without the double-dash defines
58
# the corresponding option name, ex. 'include_qualifiers'. It should be
59
# defined with underscore and not dash
60

61
no_qualifiers_class_option = [              # pylint: disable=invalid-name
2✔
62
    click.option('--nq', '--no-qualifiers', 'no_qualifiers', is_flag=True,
63
                 default=False,
64
                 help='Do not include qualifiers in the returned class(es). '
65
                      'Default: Include qualifiers.')]
66

67
deep_inheritance_class_option = [              # pylint: disable=invalid-name
2✔
68
    click.option('--di', '--deep-inheritance', 'deep_inheritance', is_flag=True,
69
                 default=False,
70
                 help='Include the complete subclass hierarchy of the '
71
                      'requested classes in the result set. '
72
                      'Default: Do not include subclasses.')]
73

74
local_only_class_option = [              # pylint: disable=invalid-name
2✔
75
    click.option('--lo', '--local-only', 'local_only', is_flag=True,
76
                 default=False,
77
                 help='Do not include superclass properties and methods in '
78
                      'the returned class(es). '
79
                      'Default: Include superclass properties and methods.')]
80

81

82
##########################################################################
83
#
84
#   Click command group and command definitions
85
#   These decorated functions implement the commands, arguments, and
86
#   options for the top-level class command group
87
#
88
###########################################################################
89

90
@cli.group('class', cls=PywbemtoolsGroup, options_metavar=GENERAL_OPTS_TXT,
2✔
91
           subcommand_metavar=SUBCMD_HELP_TXT)
92
@add_options(help_option)
2✔
93
def class_group():
2✔
94
    """
95
    Command group for CIM classes.
96

97
    This command group defines commands to inspect classes, invoke
98
    methods on classes, delete classes.
99

100
    Creation and modification of classes is not currently supported.
101

102
    In addition to the command-specific options shown in this help text, the
103
    general options (see 'pywbemcli --help') can also be specified before the
104
    'class' keyword.
105
    """
UNCOV
106
    pass  # pylint: disable=unnecessary-pass
×
107

108

109
@class_group.command('enumerate', cls=PywbemtoolsCommand,
2✔
110
                     options_metavar=CMD_OPTS_TXT)
111
@click.argument('classname', type=str, metavar='CLASSNAME', required=False)
2✔
112
@add_options(deep_inheritance_class_option)
2✔
113
@add_options(local_only_class_option)
2✔
114
@add_options(no_qualifiers_class_option)
2✔
115
@add_options(include_classorigin_class_option)
2✔
116
@add_options(names_only_option)
2✔
117
@add_options(multiple_namespaces_option_dflt_conn)
2✔
118
@add_options(summary_option)
2✔
119
@add_options(class_filter_options)
2✔
120
@add_options(object_order_option)
2✔
121
@add_options(help_option)
2✔
122
@click.pass_obj
2✔
123
def class_enumerate(context, classname, **options):
2✔
124
    """
125
    List top classes or subclasses of a class in namespace(s).
126

127
    Enumerate CIM classes starting either at the top of the class hierarchy
128
    in the specified CIM namespace (--namespace option), or at the specified
129
    class (CLASSNAME argument) in the specified namespace. If no namespace was
130
    specified, the default namespace of the connection is used.
131

132
    The --local-only, --include-classorigin, and --no-qualifiers options
133
    determine which parts are included in each retrieved class.
134

135
    The --deep-inheritance option defines whether or not the complete subclass
136
    hierarchy of the classes is retrieved.
137

138
    The --names-only option can be used to show only the class paths.
139

140
    In the output, the classes and class paths will be formatted as defined
141
    by the --output-format general option. Table formats on classes will be
142
    replaced with MOF format.
143

144
    Examples:
145

146
      pywbemcli -n myconn class enumerate -n interop
147

148
      pywbemcli -n myconn class enumerate CIM_Foo -n interop
149
    """
UNCOV
150
    context.execute_cmd(
×
151
        lambda: cmd_class_enumerate(context, classname, options))
152

153

154
@class_group.command('get', cls=PywbemtoolsCommand,
2✔
155
                     options_metavar=CMD_OPTS_TXT)
156
@click.argument('classname', type=str, metavar='CLASSNAME', required=True,)
2✔
157
@add_options(local_only_class_option)
2✔
158
@add_options(no_qualifiers_class_option)
2✔
159
@add_options(include_classorigin_class_option)
2✔
160
@add_options(propertylist_option)
2✔
161
@add_options(multiple_namespaces_option_dflt_conn)
2✔
162
@add_options(help_option)
2✔
163
@click.pass_obj
2✔
164
def class_get(context, classname, **options):
2✔
165
    """
166
    Get a class.
167

168
    Get a CIM class (CLASSNAME argument) in a CIM namespace (--namespace
169
    option). If no namespace was specified, the default namespace of the
170
    connection is used.
171

172
    The --local-only, --include-classorigin, --no-qualifiers, and
173
    --propertylist options determine which parts are included in each retrieved
174
    class.
175

176
    In the output, the class will be formatted as defined by the
177
    --output-format general option. Table formats are replaced with MOF
178
    format.
179

180
    Example:
181

182
      pywbemcli -n myconn class get CIM_Foo -n interop
183
    """
UNCOV
184
    context.execute_cmd(lambda: cmd_class_get(context, classname, options))
×
185

186

187
@class_group.command('delete', cls=PywbemtoolsCommand,
2✔
188
                     options_metavar=CMD_OPTS_TXT)
189
@click.argument('classname', type=str, metavar='CLASSNAME', required=True,)
2✔
190
@click.option('--include-instances', is_flag=True, default=False,
2✔
191
              help='Delete any instances of the class as well. '
192
                   'WARNING: Deletion of instances will cause the removal '
193
                   'of corresponding resources in the managed environment '
194
                   '(i.e. in the real world).'
195
                   'Default: Reject command if the class has any instances.')
196
@click.option('--dry-run', is_flag=True, required=False,
2✔
197
              help='Enable dry-run mode: Do not actually delete the objects, '
198
                   'but display what would be done.')
199
@add_options(namespace_option)
2✔
200
@add_options(help_option)
2✔
201
@click.pass_obj
2✔
202
def class_delete(context, classname, **options):
2✔
203
    """
204
    Delete a class.
205

206
    Delete a CIM class (CLASSNAME argument) in a CIM namespace (--namespace
207
    option). If no namespace was specified, the default namespace of the
208
    connection is used.
209

210
    If the class has instances, the command is rejected, unless the
211
    --include-instances option is specified, in which case the instances
212
    are also deleted.
213

214
    If other classes in that namespace depend on the class to be deleted, the
215
    command is rejected. Dependencies considered for this purpose are
216
    subclasses, referencing classes and embedding classes (EmbeddedInstance
217
    qualifier only).
218

219
    WARNING: Deletion of instances will cause the removal of corresponding
220
    resources in the managed environment (i.e. in the real world). Some
221
    instances may not be deletable.
222

223
    WARNING: Deleting classes can cause damage to the server: It can impact
224
    instance providers and other components in the server. Use this
225
    command with caution.
226

227
    Many WBEM servers may not allow this operation or may severely limit the
228
    conditions under which a class can be deleted from the server.
229

230
    Example:
231

232
      pywbemcli -n myconn class delete CIM_Foo -n interop
233
    """
UNCOV
234
    context.execute_cmd(lambda: cmd_class_delete(context, classname, options))
×
235

236

237
@class_group.command('invokemethod', cls=PywbemtoolsCommand,
2✔
238
                     options_metavar=CMD_OPTS_TXT)
239
@click.argument('classname', type=str, metavar='CLASSNAME', required=True,)
2✔
240
@click.argument('methodname', type=str, metavar='METHODNAME', required=True)
2✔
241
@click.option('-p', '--parameter', type=str, metavar='PARAMETERNAME=VALUE',
2✔
242
              required=False, multiple=True,
243
              help='Specify a method input parameter with its value. '
244
                   'May be specified multiple times. '
245
                   'Default: No input parameters.')
246
@add_options(namespace_option)
2✔
247
@add_options(help_option)
2✔
248
@click.pass_obj
2✔
249
def class_invokemethod(context, classname, methodname, **options):
2✔
250
    """
251
    Invoke a method on a class.
252

253
    Invoke a static CIM method (METHODNAME argument) on a CIM class (CLASSNAME
254
    argument) in a CIM namespace (--namespace option), and display the method
255
    return value and output parameters. If no namespace was specified, the
256
    default namespace of the connection is used.
257

258
    The method input parameters are specified using the --parameter option,
259
    which may be specified multiple times.
260

261
    Pywbemcli retrieves the class definition from the server in order to
262
    verify that the specified input parameters are consistent with the
263
    parameter characteristics in the method definition.
264

265
    Use the 'instance invokemethod' command to invoke CIM methods on CIM
266
    instances.
267

268
    Example:
269

270
      pywbemcli -n myconn class invokemethod CIM_Foo methodx -p p1=9 -p p2=Fred
271
    """
UNCOV
272
    context.execute_cmd(
×
273
        lambda: cmd_class_invokemethod(context, classname, methodname, options))
274

275

276
@class_group.command('references', cls=PywbemtoolsCommand,
2✔
277
                     options_metavar=CMD_OPTS_TXT)
278
@click.argument('classname', type=str, metavar='CLASSNAME', required=True)
2✔
279
@click.option('--rc', '--result-class', 'result_class', type=str,
2✔
280
              required=False, metavar='CLASSNAME',
281
              help='Filter the result set by result class name. '
282
                   'Subclasses of the specified class also match.')
283
@click.option('-r', '--role', type=str, required=False,
2✔
284
              metavar='PROPERTYNAME',
285
              help='Filter the result set by source end role name.')
286
@add_options(no_qualifiers_class_option)
2✔
287
@add_options(include_classorigin_class_option)
2✔
288
@add_options(propertylist_option)
2✔
289
@add_options(names_only_option)
2✔
290
@add_options(multiple_namespaces_option_dflt_conn)
2✔
291
@add_options(object_order_option)
2✔
292
@add_options(summary_option)
2✔
293
@add_options(help_option)
2✔
294
@click.pass_obj
2✔
295
def class_references(context, classname, **options):
2✔
296
    """
297
    List the classes referencing a class.
298

299
    List the CIM (association) classes that reference the specified class
300
    (CLASSNAME argument) in the specified CIM namespace
301
    (--namespace option). If no namespace was specified, the default namespace
302
    of the connection is used.
303

304
    The classes to be retrieved can be filtered by the --role and
305
    --result-class options.
306

307
    The --include-classorigin, --no-qualifiers, and --propertylist options
308
    determine which parts are included in each retrieved class.
309

310
    The --names-only option can be used to show only the class paths.
311

312
    In the output, the classes and class paths will be formatted as defined
313
    by the --output-format general option. Table formats on classes will be
314
    replaced with MOF format.
315

316
    Examples:
317

318
      pywbemcli -n myconn class references CIM_Foo -n interop
319
    """
UNCOV
320
    context.execute_cmd(
×
321
        lambda: cmd_class_references(context, classname, options))
322

323

324
@class_group.command('associators', cls=PywbemtoolsCommand,
2✔
325
                     options_metavar=CMD_OPTS_TXT)
326
@click.argument('classname', type=str, metavar='CLASSNAME', required=True)
2✔
327
@click.option('--ac', '--assoc-class', 'assoc_class', type=str, required=False,
2✔
328
              metavar='CLASSNAME',
329
              help='Filter the result set by association class name. '
330
                   'Subclasses of the specified class also match.')
331
@click.option('--rc', '--result-class', 'result_class', type=str,
2✔
332
              required=False, metavar='CLASSNAME',
333
              help='Filter the result set by result class name. '
334
                   'Subclasses of the specified class also match.')
335
@click.option('-r', '--role', type=str, required=False,
2✔
336
              metavar='PROPERTYNAME',
337
              help='Filter the result set by source end role name.')
338
@click.option('--rr', '--result-role', 'result_role', type=str, required=False,
2✔
339
              metavar='PROPERTYNAME',
340
              help='Filter the result set by far end role name.')
341
@add_options(no_qualifiers_class_option)
2✔
342
@add_options(include_classorigin_class_option)
2✔
343
@add_options(propertylist_option)
2✔
344
@add_options(names_only_option)
2✔
345
@add_options(multiple_namespaces_option_dflt_conn)
2✔
346
@add_options(object_order_option)
2✔
347
@add_options(summary_option)
2✔
348
@add_options(help_option)
2✔
349
@click.pass_obj
2✔
350
def class_associators(context, classname, **options):
2✔
351
    """
352
    List the classes associated with a class.
353

354
    List the CIM classes that are associated with the specified class
355
    (CLASSNAME argument) in the specified CIM namespace
356
    (--namespace option). If no namespace was specified, the default namespace
357
    of the connection is used.
358

359
    The classes to be retrieved can be filtered by the --role, --result-role,
360
    --assoc-class, and --result-class options.
361

362
    The --include-classorigin, --no-qualifiers, and --propertylist options
363
    determine which parts are included in each retrieved class.
364

365
    The --names-only option can be used to show only the class paths.
366

367
    In the output, the classes and class paths will be formatted as defined
368
    by the --output-format general option. Table formats on classes will be
369
    replaced with MOF format.
370

371
    Examples:
372

373
      pywbemcli -n myconn class associators CIM_Foo -n interop
374
    """
UNCOV
375
    context.execute_cmd(
×
376
        lambda: cmd_class_associators(context, classname, options))
377

378

379
@class_group.command('find', cls=PywbemtoolsCommand,
2✔
380
                     options_metavar=CMD_OPTS_TXT)
381
@click.argument('classname-glob', type=str, metavar='CLASSNAME-GLOB',
2✔
382
                required=True)
383
@add_options(multiple_namespaces_option_dflt_all)
2✔
384
@click.option('-s', '--sort', is_flag=True, required=False,
2✔
385
              help='Sort by namespace. Default is to sort by classname')
386
@add_options(class_filter_options)
2✔
387
@add_options(help_option)
2✔
388
@click.pass_obj
2✔
389
def class_find(context, classname_glob, **options):
2✔
390
    """
391
    List the classes with matching class names on the server.
392

393
    Find the CIM classes whose class name matches the specified wildcard
394
    expression (CLASSNAME-GLOB argument) in all CIM namespaces of the
395
    WBEM server, or in the specified namespace (--namespace option).
396

397
    The CLASSNAME-GLOB argument is a wildcard expression that is matched on
398
    class names case insensitively.
399
    The special characters from Unix file name wildcarding are supported
400
    ('*' to match zero or more characters, '?' to match a single character,
401
    and '[]' to match character ranges). To avoid shell expansion of wildcard
402
    characters, the CLASSNAME-GLOB argument should be put in quotes.
403

404
    For example, "pywbem_*" returns classes whose name begins with "PyWBEM_",
405
    "pywbem_", etc. "*system*" returns classes whose names include the case
406
    insensitive string "system".
407

408
    In the output, the classes will be formatted as defined by the
409
    --output-format general option if it specifies table output. Otherwise
410
    the classes will be in the form "NAMESPACE:CLASSNAME".
411

412
    Examples:
413

414
      pywbemcli -n myconn class find "CIM_*System*" -n interop
415

416
      pywbemcli -n myconn class find *Foo*
417
    """
418

UNCOV
419
    context.execute_cmd(
×
420
        lambda: cmd_class_find(context, classname_glob, options))
421

422

423
@class_group.command('tree', cls=PywbemtoolsCommand,
2✔
424
                     options_metavar=CMD_OPTS_TXT)
425
@click.argument('classname', type=str, metavar='CLASSNAME', required=False)
2✔
426
@click.option('-s', '--superclasses', is_flag=True, default=False,
2✔
427
              help='Show the superclass hierarchy. '
428
                   'Default: Show the subclass hierarchy.')
429
@click.option('-d', '--detail', is_flag=True, default=False,
2✔
430
              help='Show details about the class: the Version, '
431
                   ' Association, Indication, and Abstact qualifiers.')
432
@add_options(namespace_option)
2✔
433
@add_options(help_option)
2✔
434
@click.pass_obj
2✔
435
def class_tree(context, classname, **options):
2✔
436
    """
437
    Show the subclass or superclass hierarchy for a class.
438

439
    List the subclass or superclass hierarchy of a CIM class (CLASSNAME
440
    argument) or CIM namespace (--namespace option):
441

442
    - If CLASSNAME is omitted, the complete class hierarchy of the specified
443
      namespace is retrieved.
444

445
    - If CLASSNAME is specified but not --superclasses, the class and its
446
      subclass hierarchy in the specified namespace are retrieved.
447

448
    - If CLASSNAME and --superclasses are specified, the class and its
449
      superclass ancestry up to the top-level class in the specified namespace
450
      are retrieved.
451

452
    If no namespace was specified, the default namespace of the connection is
453
    used.
454

455
    The class hierarchy will formatted as a ASCII graphical tree; the
456
    --output-format general option is ignored.
457

458
    The --detail options to display extra information about each class
459
    including:
460

461
    -  The Version qualifier value if the class includes a version
462
       qualifier. This is normally a string with 3 integers
463

464
    -  Information about each class type (Association, Indication, Abstract)
465

466
    Examples:
467

468
      # Display the complete class hierarchy from the interop namespace
469
      pywbemcli -n myconn class tree -n interop
470

471
      # Display CIM_Foo an its subclasses from the namespace interop
472
      pywbemcli -n myconn class tree CIM_Foo -n interop
473

474
      # Display CIM_Foo and its superclasses from interop
475
      pywbemcli -n myconn class tree CIM_Foo -s -n interop
476

477
    """
UNCOV
478
    context.execute_cmd(lambda: cmd_class_tree(context, classname, options))
×
479

480

481
####################################################################
482
#
483
#  Common functions for cmd_class processing
484
#  This includes functions used by the command action functions
485
#  in this module and possibly other modules
486
#
487
#  get_namespaces, enumerate_classes_filtered, and handle_multi_ns_exc
488
#  are called from the instance and qualifier command processors.
489
#
490
####################################################################
491

492

493
def get_classnames_in_namespaces(context, options, namespaces, classname_glob):
2✔
494
    """
495
    Get the classnames of all classes in the namespaces parameter that
496
    matches the classname_glob pattern.
497

498
    Parameters:
499

500
      context :
501
        Context object for the command
502

503
      options (python dictionary)
504
        Options dictionary for the command executiong
505

506
      namespaces (list of strings):
507
        List of the namespaces from which namespace names are to be retrieved.
508

509
      classname_glob ((:term: `string`))
510
        A string that may contain GLOB characters which serves as the
511
        filter
512

513
    Returns:
514
        NocaseDict where the keys are namespace names and the value for
515
        each key is the list of classnames that match the glob patter  in
516
        each namespace in namespaces
517

518
    """
519

520
    # Dictionary key is namespaces, value is list of classes
UNCOV
521
    names_dict = NocaseDict()
×
UNCOV
522
    if namespaces:
×
523
        # Use di True, and names_only build options to get all names
524
        # Create deep copy to insure no changes to original dict
UNCOV
525
        options_tmp = copy.deepcopy(options)
×
UNCOV
526
        options_tmp['deep_inheritance'] = True
×
UNCOV
527
        options_tmp['names_only'] = True
×
UNCOV
528
        try:
×
UNCOV
529
            for ns in namespaces:
×
530
                # Enumerate filtered for classnames and add to dictionary
531
                # of returns for each namespace
UNCOV
532
                classnames = enumerate_classes_filtered(context, ns, None,
×
533
                                                        options_tmp)
UNCOV
534
                names_dict[ns] = filter_namelist(classname_glob, classnames)
×
UNCOV
535
        except Error as er:
×
UNCOV
536
            raise pywbem_error_exception(er)
×
537

UNCOV
538
    return names_dict
×
539

540

541
def get_format_group(context, options):
2✔
542
    """
543
    Define the format groups allowed based on the options. This is particular
544
    to the class commands, largely because we do not have a table format
545
    for enumerate, get, associators, or references unless options such as
546
    summary, or names_only are set.
547
    """
548

549
    # Summary always output as TABLE
UNCOV
550
    if 'summary' in options and options['summary']:
×
551

552
        # This accounts for the fact that the results of a summary can be
553
        # either table or simply a string output
UNCOV
554
        if context.output_format and \
×
555
                output_format_is_table(context.output_format):
UNCOV
556
            return ['TABLE']
×
557

558
        # Temporary hack. We need another format group, i.e. txt or str
559
        # That displays in non-structured manner. Or drop this output
560
        # completely.
UNCOV
561
        return ['CIM']
×
562

563
    # Names_only may be output as Table or as CIM Object.
UNCOV
564
    if 'names_only' in options and options['names_only']:
×
UNCOV
565
        return ['CIM', 'TABLE']
×
566

567
    # otherwise only CIM allowed today.
UNCOV
568
    return ['CIM']
×
569

570

571
#####################################################################
572
#
573
#  Command functions for each of the commands in the class group
574
#
575
#####################################################################
576

577

578
def cmd_class_get(context, classname, options):
2✔
579
    """
580
    Get the class defined by the argument.
581

582
    Gets the class defined by CLASSNAME from the WBEM server and displays
583
    the class. If the class cannot be found, the server returns a CIMError
584
    exception.
585
    """
UNCOV
586
    conn = context.pywbem_server.conn
×
UNCOV
587
    format_group = get_format_group(context, options)
×
UNCOV
588
    output_format = validate_output_format(context.output_format, format_group)
×
589

UNCOV
590
    results = ResultsHandler(context, options, output_format, "class",
×
591
                             classname)
592

UNCOV
593
    for ns in results:
×
UNCOV
594
        try:
×
UNCOV
595
            results.add(conn.GetClass(
×
596
                classname,
597
                namespace=ns,
598
                LocalOnly=options['local_only'],
599
                IncludeQualifiers=not options['no_qualifiers'],
600
                IncludeClassOrigin=options['include_classorigin'],
601
                PropertyList=resolve_propertylist(options['propertylist'])))
602

UNCOV
603
        except CIMError as ce:
×
604
            # Process error and continue or generate exception
UNCOV
605
            results.handle_exception(ns, ce)
×
UNCOV
606
            continue
×
607

UNCOV
608
        except Error as er:
×
UNCOV
609
            raise pywbem_error_exception(er)
×
610

UNCOV
611
    results.display()
×
612

613

614
def cmd_class_invokemethod(context, classname, methodname, options):
2✔
615
    """
616
    Create an instance and submit to a WBEM server
617
    """
618

UNCOV
619
    try:
×
UNCOV
620
        cln = CIMClassName(classname, namespace=options['namespace'])
×
UNCOV
621
        process_invokemethod(context, cln, methodname, options['namespace'],
×
622
                             options['parameter'])
UNCOV
623
    except Error as er:
×
UNCOV
624
        raise pywbem_error_exception(er)
×
625

626

627
def cmd_class_enumerate(context, classname, options):
2✔
628
    """
629
        Enumerate the classes returning a list of classes from the WBEM server.
630
        That match the qualifier filter options
631
    """
UNCOV
632
    format_group = get_format_group(context, options)
×
UNCOV
633
    output_format = validate_output_format(context.output_format, format_group)
×
634

UNCOV
635
    results = ResultsHandler(context, options, output_format, "class",
×
636
                             classname)
637

UNCOV
638
    for ns in results:
×
UNCOV
639
        try:
×
UNCOV
640
            results.add(enumerate_classes_filtered(
×
641
                context, ns, classname, options))
642

UNCOV
643
        except CIMError as ce:
×
644
            # Process error and continue or generate exception
UNCOV
645
            results.handle_exception(ns, ce)
×
UNCOV
646
            continue
×
647

UNCOV
648
        except Error as er:
×
UNCOV
649
            raise pywbem_error_exception(er)
×
650

UNCOV
651
    results.display()
×
652

653

654
def cmd_class_references(context, classname, options):
2✔
655
    """
656
    Execute the references request operation to get references for
657
    the classname defined
658
    """
UNCOV
659
    conn = context.pywbem_server.conn
×
UNCOV
660
    format_group = get_format_group(context, options)
×
UNCOV
661
    output_format = validate_output_format(context.output_format, format_group)
×
662

UNCOV
663
    results = ResultsHandler(context, options, output_format, "class",
×
664
                             classname)
665

UNCOV
666
    for ns in results:
×
UNCOV
667
        try:
×
UNCOV
668
            cln = CIMClassName(classname, namespace=ns)
×
UNCOV
669
            if options['names_only']:
×
UNCOV
670
                results.add(conn.ReferenceNames(
×
671
                    cln,
672
                    ResultClass=options['result_class'],
673
                    Role=options['role']))
674
            else:
UNCOV
675
                results.add(conn.References(
×
676
                    cln,
677
                    ResultClass=options['result_class'],
678
                    Role=options['role'],
679
                    IncludeQualifiers=not options['no_qualifiers'],
680
                    IncludeClassOrigin=options['include_classorigin'],
681
                    PropertyList=resolve_propertylist(options['propertylist'])))
682

UNCOV
683
        except CIMError as ce:
×
684
            # Process error and continue or generate exception
UNCOV
685
            results.handle_exception(ns, ce)
×
UNCOV
686
            continue
×
687

UNCOV
688
        except Error as er:
×
UNCOV
689
            raise pywbem_error_exception(er)
×
690

UNCOV
691
    results.display()
×
692

693

694
def cmd_class_associators(context, classname, options):
2✔
695
    """
696
    Execute the references request operation to get references for
697
    the classname defined
698
    """
UNCOV
699
    conn = context.pywbem_server.conn
×
700

UNCOV
701
    format_group = get_format_group(context, options)
×
UNCOV
702
    output_format = validate_output_format(context.output_format, format_group)
×
703

UNCOV
704
    results = ResultsHandler(context, options, output_format, "class",
×
705
                             classname)
706

UNCOV
707
    for ns in results:
×
UNCOV
708
        try:
×
UNCOV
709
            cln = CIMClassName(classname, namespace=ns)
×
UNCOV
710
            if options['names_only']:
×
UNCOV
711
                results.add(conn.AssociatorNames(
×
712
                    cln,
713
                    AssocClass=options['assoc_class'],
714
                    Role=options['role'],
715
                    ResultClass=options['result_class'],
716
                    ResultRole=options['result_role']))
717
            else:
UNCOV
718
                results.add(conn.Associators(
×
719
                    cln,
720
                    AssocClass=options['assoc_class'],
721
                    Role=options['role'],
722
                    ResultClass=options['result_class'],
723
                    ResultRole=options['result_role'],
724
                    IncludeQualifiers=not options['no_qualifiers'],
725
                    IncludeClassOrigin=options['include_classorigin'],
726
                    PropertyList=resolve_propertylist(options['propertylist'])))
727

UNCOV
728
        except CIMError as ce:
×
729
            # Process error and continue or generate exception
UNCOV
730
            results.handle_exception(ns, ce)
×
UNCOV
731
            continue
×
732

UNCOV
733
        except Error as er:
×
UNCOV
734
            raise pywbem_error_exception(er)
×
735

UNCOV
736
    results.display()
×
737

738

739
def cmd_class_find(context, classname_glob, options):
2✔
740
    """
741
    Execute the command for enumerate classes, filter the results based on the
742
    option and display the result. The result is a list of classes/namespaces
743
    """
744

UNCOV
745
    output_format = validate_output_format(context.output_format, 'TABLE')
×
746

UNCOV
747
    context.spinner_stop()
×
UNCOV
748
    namespaces = get_namespaces(context, options['namespace'],
×
749
                                default_all_ns=True)
750

UNCOV
751
    try:
×
752
        # Define sort by namespace name if --sort, or  othersise by count
UNCOV
753
        sort_col = 0 if options['sort'] else 1
×
754

UNCOV
755
        names_dict = get_classnames_in_namespaces(context, options, namespaces,
×
756
                                                  classname_glob)
757

UNCOV
758
        context.spinner_stop()
×
759

760
        # If summary set, generate output of only count of classes for
761
        # each namespace
UNCOV
762
        if 'summary' in options and options['summary']:
×
763
            rows = [[ns, len(names_dict[ns])] for ns in names_dict]
×
764
            rows.sort(key=lambda x: x[sort_col])
×
765

766
            if output_format_is_table(context.output_format):
×
767
                headers = ['Namespace', 'Class count']
×
768
                click.echo(format_table(
×
769
                    rows,
770
                    headers,
771
                    title=f'Find class counts {classname_glob}',
772
                    table_format=output_format))
773
            else:
774
                for ns, count in rows:
×
775
                    click.echo(f'  {ns}: {count}')
×
776
            return
×
777

778
        # Not summary. Build rows of namespace, classname for each namespace
779
        # and sort by names if --sort set
UNCOV
780
        rows = []
×
UNCOV
781
        for ns_name in names_dict:
×
UNCOV
782
            ns_rows = [[ns_name, name] for name in names_dict[ns_name]]
×
783
            # sort by classname if sort option defined, else by namespace
UNCOV
784
            ns_rows.sort(key=lambda x: x[sort_col])
×
UNCOV
785
            rows.extend(ns_rows)
×
786

UNCOV
787
        context.spinner_stop()
×
788

UNCOV
789
        if output_format_is_table(context.output_format):
×
UNCOV
790
            headers = ['Namespace', 'Classname']
×
UNCOV
791
            click.echo(
×
792
                format_table(rows, headers,
793
                             title=f'Find class {classname_glob}',
794
                             table_format=output_format))
795
        else:
796
            # Display function to display classnames returned with
797
            # their namespaces in the form <namespace>:<classname>
UNCOV
798
            for row in rows:
×
UNCOV
799
                click.echo(f'  {row[0]}: {row[1]}')
×
800

UNCOV
801
    except Error as er:
×
802
        raise pywbem_error_exception(er)
×
803

804

805
def get_class_hierarchy(conn, classname, namespace, superclasses=None):
2✔
806
    """
807
    Get the class hierarchy from the server, either the superclasses
808
    associated or subclasses with classname .  If getting subclasses
809
    the classname parameter may be None which requests that the complete
810
    class hiearchy be retrieved.
811

812
      Parameters:
813
        conn (:class:`~pywbem.WBEMConnection` or subclass):
814
            Current connection to a WBEM server.
815

816
        classname(:term:`string):
817
            classname if the tree is to be initiated from
818
            within the class hiearchy. May be None
819

820
        namespace(:term:`string):
821
          Namespace to use to acquire classes from WBEM server
822

823
        superclasses (:class:`py:bool`):
824
            If `True` display the superclasses of classname. If not True
825
            display the subclasses. The default is None (display subclasses).
826

827
      Returns:
828
        tuple of  classes, classnames where
829
          classes (list of :class:`~pywbem.CIMClass`): that are either the
830
          superclasses or the subclasses of classname.
831

832
      Raises:
833
        CIM_Error:
834
    """
835

UNCOV
836
    try:
×
UNCOV
837
        if superclasses:
×
838
            # classname must exist for superclass tree
UNCOV
839
            assert classname is not None
×
840

841
            # get the superclasses into a list
UNCOV
842
            klass = conn.GetClass(classname, namespace=namespace)
×
UNCOV
843
            classes = []
×
UNCOV
844
            classes.append(klass)
×
UNCOV
845
            while klass.superclass:
×
UNCOV
846
                klass = conn.GetClass(klass.superclass, namespace=namespace)
×
UNCOV
847
                classes.append(klass)
×
848
        else:
849
            # get the subclass hierarchy either complete or starting at the
850
            # optional CLASSNAME. Gets minimum data from server to define
851
            # class, superclass data
UNCOV
852
            classes = conn.EnumerateClasses(ClassName=classname,
×
853
                                            namespace=namespace,
854
                                            LocalOnly=True,
855
                                            IncludeQualifiers=True,
856
                                            DeepInheritance=True)
857

UNCOV
858
    except Error as er:
×
UNCOV
859
        raise pywbem_error_exception(er)
×
860

UNCOV
861
    return classes
×
862

863

864
def cmd_class_tree(context, classname, options):
2✔
865
    """
866
    Execute the command to display graphical tree of either superclasses or
867
    subclasses of classname. If classname is None, display tree starting from
868
    the class hierarchy root.
869
    Tree is displayed on the console as a left-justified tree using the
870
    asciitree library.
871
    The --superclasses option determines if the superclass tree or the
872
    subclass tree is displayed.
873
    """
UNCOV
874
    conn = context.pywbem_server.conn
×
875

UNCOV
876
    superclasses = options['superclasses']
×
877

878
    # Classname must exist as starting point for superclass tree.
UNCOV
879
    if superclasses and classname is None:
×
UNCOV
880
        raise click.ClickException('CLASSNAME argument required for '
×
881
                                   '--superclasses option')
882

UNCOV
883
    classes = get_class_hierarchy(conn, classname, options['namespace'],
×
884
                                  superclasses)
885

886
    # If showing superclasses, set classname to None for the display
887
    # to add the 'root' as top class.
UNCOV
888
    if superclasses:
×
UNCOV
889
        classname = None
×
890

891
    # Display the list of classes as a tree. The classname is the top
892
    # of the tree.
UNCOV
893
    context.spinner_stop()
×
UNCOV
894
    display_class_tree(classes, classname, show_detail=options['detail'])
×
895

896

897
def cmd_class_delete(context, classname, options):
2✔
898
    """Delete a class from the WBEM server repository"""
UNCOV
899
    conn = context.pywbem_server.conn
×
900

UNCOV
901
    include_instances = options['include_instances']
×
UNCOV
902
    dry_run = options['dry_run']
×
UNCOV
903
    dry_run_prefix = "Dry run: " if dry_run else ""
×
904

UNCOV
905
    namespace = options['namespace'] or conn.default_namespace
×
906

UNCOV
907
    try:
×
UNCOV
908
        instnames = conn.EnumerateInstanceNames(
×
909
            ClassName=classname, namespace=namespace)
UNCOV
910
    except Error as exc:
×
UNCOV
911
        raise pywbem_error_exception(
×
912
            exc,
913
            f"Cannot enumerate instance names of class {classname} in "
914
            f"namespace {namespace}")
915

UNCOV
916
    if instnames and not include_instances:
×
UNCOV
917
        raise click.ClickException(
×
918
            f"Cannot delete class {classname} because it has "
919
            f"{len(instnames)} instances")
920

UNCOV
921
    depending_cln_list = depending_classnames(
×
922
        classname, namespace, conn)
923

UNCOV
924
    if depending_cln_list:
×
UNCOV
925
        raise click.ClickException(
×
926
            f"Cannot delete class {classname} because these classes "
927
            f"depend on it: {', '.join(depending_cln_list)}")
928

UNCOV
929
    context.spinner_stop()
×
UNCOV
930
    if include_instances:
×
UNCOV
931
        for instname in instnames:
×
UNCOV
932
            if not dry_run:
×
UNCOV
933
                try:
×
UNCOV
934
                    conn.DeleteInstance(instname)
×
UNCOV
935
                except Error as exc:
×
UNCOV
936
                    raise pywbem_error_exception(
×
937
                        exc, f"Cannot delete instance {instname}")
UNCOV
938
            click.echo(f'{dry_run_prefix}Deleted instance {instname}')
×
939

UNCOV
940
    if not dry_run:
×
UNCOV
941
        try:
×
UNCOV
942
            conn.DeleteClass(classname)
×
943
        except Error as exc:
×
944
            raise pywbem_error_exception(
×
945
                exc,
946
                f"Cannot delete class {classname} in namespace {namespace}")
UNCOV
947
    click.echo(f'{dry_run_prefix}Deleted class {classname}')
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc