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

pywbem / pywbemtools / 3774328075

pending completion
3774328075

push

github

Andreas Maier
Checking of missing reqs and display of pkg dep tree; Updated pip/setuptools/wheel

5840 of 6283 relevant lines covered (92.95%)

11.84 hits per line

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

95.27
/pywbemtools/pywbemcli/_cmd_instance.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
"""
13✔
17
Click Command definition for the instance command group which includes
18
cmds for get, enumerate, list of instance.
19

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

23
from __future__ import absolute_import, print_function
13✔
24

25
import six
13✔
26

27
import click
13✔
28

29
from pywbem import CIMInstanceName, CIMClassName, Error, CIMError, \
13✔
30
    CIM_ERR_NOT_FOUND
31

32
from .pywbemcli import cli
13✔
33
from ._common import pick_instance, resolve_propertylist, create_ciminstance, \
13✔
34
    filter_namelist, verify_operation, process_invokemethod, \
35
    pywbem_error_exception, parse_kv_pair
36

37
from ._display_cimobjects import display_cim_objects
13✔
38

39
from ._common_options import propertylist_option, names_only_option, \
13✔
40
    include_classorigin_instance_option, namespace_option, summary_option, \
41
    verify_option, multiple_namespaces_option_dflt_all, \
42
    multiple_namespaces_option_dflt_conn, class_filter_options, \
43
    object_order_option
44

45
from ._cimvalueformatter import mof_escaped
13✔
46

47
from ._association_shrub import AssociationShrub
13✔
48

49
from .config import DEFAULT_QUERY_LANGUAGE
13✔
50
from ._common_cmd_functions import get_namespaces, enumerate_classes_filtered, \
13✔
51
    ResultsHandler
52
from .._click_extensions import PywbemtoolsGroup, PywbemtoolsCommand, \
13✔
53
    CMD_OPTS_TXT, GENERAL_OPTS_TXT, SUBCMD_HELP_TXT
54
from .._options import add_options, help_option, validate_required_arg
13✔
55
from .._output_formatting import validate_output_format, format_table, \
13✔
56
    warning_msg
57

58
#
59
#   Common option definitions for instance group
60
#
61

62
# NOTE: A number of the options use double-dash as the short form.  In those
63
# cases, a third definition of the options without the double-dash defines
64
# the corresponding option name, ex. 'include_qualifiers'. It should be
65
# defined with underscore and not dash
66

67
# Issue 224 - Exception in prompt-toolkit with python 2.7. Caused because
68
# with prompt-toolkit 2 + the completer requires unicode and click_repl not
69
# passing help as unicode in options as unicode
70
# NOTE: Insure that all option help attributes are unicode to get around this
71
#       issue
72

73

74
# This is instance-only because the default is False for include-qualifiers
75
# on instances but True on classes
76
include_qualifiers_get_option = [              # pylint: disable=invalid-name
13✔
77
    click.option('--iq', '--include-qualifiers', 'include_qualifiers',
78
                 is_flag=True, required=False,
79
                 help=u'Include qualifiers in the returned instance. '
80
                      u'Not all servers return qualifiers on instances. '
81
                      u'Default: Do not include qualifiers.')]
82

83
include_qualifiers_list_option = [              # pylint: disable=invalid-name
13✔
84
    click.option('--iq', '--include-qualifiers', 'include_qualifiers',
85
                 is_flag=True, required=False,
86
                 help=u'When traditional operations are used, include '
87
                      u'qualifiers in the returned instances. '
88
                      u'Some servers may ignore this option. '
89
                      u'By default, and when pull operations are used, '
90
                      u'qualifiers will never be included.')]
91

92
# specific to instance because DeepInheritance differs between class and
93
# instance operations.
94
deep_inheritance_enum_option = [              # pylint: disable=invalid-name
13✔
95
    click.option('--di', '--deep-inheritance', 'deep_inheritance',
96
                 is_flag=True, required=False,
97
                 help=u'Include subclass properties in the returned '
98
                      u'instances. '
99
                      u'Default: Do not include subclass properties.')]
100

101
local_only_get_option = [              # pylint: disable=invalid-name
13✔
102
    click.option('--lo', '--local-only', 'local_only', is_flag=True,
103
                 required=False,
104
                 help=u'Do not include superclass properties in the returned '
105
                      u'instance. '
106
                      u'Some servers may ignore this option. '
107
                      u'Default: Include superclass properties.')]
108

109
local_only_list_option = [              # pylint: disable=invalid-name
13✔
110
    click.option('--lo', '--local-only', 'local_only', is_flag=True,
111
                 required=False,
112
                 help=u'When traditional operations are used, do not include '
113
                      u'superclass properties in the returned instances. '
114
                      u'Some servers may ignore this option. '
115
                      u'By default, and when pull operations are used, '
116
                      u'superclass properties will always be included.')]
117

118
property_create_option = [              # pylint: disable=invalid-name
13✔
119
    click.option('-p', '--property', type=str, metavar='PROPERTYNAME=VALUE',
120
                 required=False, multiple=True,
121
                 help=u'Initial property value for the new instance. '
122
                      u'May be specified multiple times. '
123
                      u'Array property values are specified as a '
124
                      u'comma-separated list; embedded instances are not '
125
                      u'supported. '
126
                      u'Default: No initial properties provided.')]
127

128
property_modify_option = [              # pylint: disable=invalid-name
13✔
129
    click.option('-p', '--property', type=str, metavar='PROPERTYNAME=VALUE',
130
                 required=False, multiple=True,
131
                 help=u'Property to be modified, with its new value. '
132
                      u'May be specified once for each property to be '
133
                      u'modified. '
134
                      u'Array property values are specified as a '
135
                      u'comma-separated list; embedded instances are not '
136
                      u'supported. '
137
                      u'Default: No properties modified.')]
138

139
keybinding_key_option = [              # pylint: disable=invalid-name
13✔
140
    click.option('-k', '--key', type=str, metavar='KEYNAME=VALUE',
141
                 required=False, multiple=True,
142
                 help=u'Value for a key in keybinding of CIM instance name. '
143
                      u'May be specified multiple times. '
144
                      u'Allows defining keys without the issues of quotes. '
145
                      u'Default: No keybindings provided.')]
146

147
filter_query_language_option = [              # pylint: disable=invalid-name
13✔
148
    click.option('--fql', '--filter-query-language', 'filter_query_language',
149
                 type=str, metavar='QUERY-LANGUAGE', default=None,
150
                 help=u'The filter query language to be used with '
151
                      u'--filter-query. '
152
                      u'Default: DMTF:FQL.')]
153

154
filter_query_option = [              # pylint: disable=invalid-name
13✔
155
    click.option('--fq', '--filter-query', 'filter_query', type=str,
156
                 metavar='QUERY-STRING', default=None,
157
                 help=u'When pull operations are used, filter the instances in '
158
                      u'the result via a filter query. '
159
                      u'By default, and when traditional operations are used, '
160
                      u'no such filtering takes place.')]
161

162
help_instancename_option = [              # pylint: disable=invalid-name
13✔
163
    click.option('--hi', '--help-instancename', 'help_instancename',
164
                 is_flag=True, required=False, is_eager=True,
165
                 help=u'Show help message for specifying INSTANCENAME '
166
                      u'including use of the --key and --namespace options.')]
167

168
show_null_option = [              # pylint: disable=invalid-name
13✔
169
    click.option('--show-null', 'show_null', is_flag=True, required=False,
170
                 help=u'In the TABLE output formats, show properties with no '
171
                      u'value (i.e. Null) in all of the instances to be '
172
                      u'displayed. Otherwise only properties at least '
173
                      u'one instance has a non-Null property are displayed')]
174

175

176
##########################################################################
177
#
178
#   Click command group and command definitions
179
#   These decorated functions implement the commands, arguments, and
180
#
181
###########################################################################
182

183

184
@cli.group('instance', cls=PywbemtoolsGroup, options_metavar=GENERAL_OPTS_TXT,
13✔
185
           subcommand_metavar=SUBCMD_HELP_TXT)
186
@add_options(help_option)
13✔
187
def instance_group():
4✔
188
    """
189
    Command group for CIM instances.
190

191
    This command group defines commands to inspect instances, to invoke
192
    methods on instances, and to create and delete instances.
193

194
    Modification of instances is not currently supported.
195

196
    In addition to the command-specific options shown in this help text, the
197
    general options (see 'pywbemcli --help') can also be specified before the
198
    'instance' keyword.
199
    """
200
    pass  # pylint: disable=unnecessary-pass
13✔
201

202

203
@instance_group.command('enumerate', cls=PywbemtoolsCommand,
13✔
204
                        options_metavar=CMD_OPTS_TXT)
205
@click.argument('classname', type=str, metavar='CLASSNAME', required=True)
13✔
206
@add_options(local_only_list_option)
13✔
207
@add_options(deep_inheritance_enum_option)
13✔
208
@add_options(include_qualifiers_list_option)
13✔
209
@add_options(include_classorigin_instance_option)
13✔
210
@add_options(propertylist_option)
13✔
211
@add_options(multiple_namespaces_option_dflt_conn)
13✔
212
@add_options(names_only_option)
13✔
213
@add_options(summary_option)
13✔
214
@add_options(filter_query_option)
13✔
215
@add_options(filter_query_language_option)
13✔
216
@add_options(show_null_option)
13✔
217
@add_options(object_order_option)
13✔
218
@add_options(help_option)
13✔
219
@click.pass_obj
13✔
220
def instance_enumerate(context, classname, **options):
4✔
221
    """
222
    List the instances of a class.
223

224
    Enumerate the CIM instances of the specified class (CLASSNAME argument),
225
    including instances of subclasses in the specified CIM namespace(s)
226
    (--namespace option), and display the returned instances, or instance paths
227
    if --names-only was specified. If no namespace was specified, the default
228
    namespace of the connection is used.
229

230
    The instances to be retrieved can be filtered by the --filter-query option.
231

232
    The --local-only, --deep-inheritance, --include-qualifiers,
233
    --include-classorigin, and --propertylist options determine which parts
234
    are included in each retrieved instance.
235

236
    The --names-only option can be used to show only the instance paths.
237

238
    In the output, the instances and instance paths will be formatted as
239
    defined by the --output-format general option. Table formats on instances
240
    will be replaced with MOF format.
241
    """
242
    context.execute_cmd(
13✔
243
        lambda: cmd_instance_enumerate(context, classname, options))
244

245

246
@instance_group.command('get', cls=PywbemtoolsCommand,
13✔
247
                        options_metavar=CMD_OPTS_TXT)
248
@click.argument('instancename', type=str, metavar='INSTANCENAME',
13✔
249
                required=False)
250
@add_options(local_only_get_option)
13✔
251
@add_options(include_qualifiers_get_option)
13✔
252
@add_options(include_classorigin_instance_option)
13✔
253
@add_options(propertylist_option)
13✔
254
@add_options(keybinding_key_option)
13✔
255
@add_options(multiple_namespaces_option_dflt_conn)
13✔
256
@add_options(object_order_option)
13✔
257
@add_options(help_instancename_option)
13✔
258
@add_options(show_null_option)
13✔
259
@add_options(help_option)
13✔
260
@click.pass_obj
13✔
261
def instance_get(context, instancename, **options):
4✔
262
    """
263
    Get an instance of a class.
264

265
    For information on how to specify the instance using INSTANCENAME and the
266
    --key and --namespace options, invoke with --help-instancename.
267

268
    The --local-only, --include-qualifiers, --include-classorigin, and
269
    --propertylist options determine which parts are included in the retrieved
270
    instance.
271

272
    In the output, the instance will formatted as defined by the
273
    --output-format general option.
274
    """
275
    if options['help_instancename']:
13✔
276
        show_help_instancename()
13✔
277
        return
13✔
278
    validate_required_arg(instancename, 'INSTANCENAME')
13✔
279
    context.execute_cmd(
13✔
280
        lambda: cmd_instance_get(context, instancename, options))
281

282

283
@instance_group.command('delete', cls=PywbemtoolsCommand,
13✔
284
                        options_metavar=CMD_OPTS_TXT)
285
@click.argument('instancename', type=str, metavar='INSTANCENAME',
13✔
286
                required=False)
287
@add_options(keybinding_key_option)
13✔
288
@add_options(namespace_option)
13✔
289
@add_options(help_instancename_option)
13✔
290
@add_options(help_option)
13✔
291
@click.pass_obj
13✔
292
def instance_delete(context, instancename, **options):
4✔
293
    """
294
    Delete an instance of a class.
295

296
    WARNING: Deletion of instances will cause the removal of corresponding
297
    resources in the managed environment (i.e. in the real world). Some
298
    instances may not be deletable.
299

300
    For information on how to specify the instance using INSTANCENAME and the
301
    --key and --namespace options, invoke with --help-instancename.
302
    """
303
    if options['help_instancename']:
13✔
304
        show_help_instancename()
13✔
305
        return
13✔
306
    validate_required_arg(instancename, 'INSTANCENAME')
13✔
307
    context.execute_cmd(
13✔
308
        lambda: cmd_instance_delete(context, instancename, options))
309

310

311
@instance_group.command('create', cls=PywbemtoolsCommand,
13✔
312
                        options_metavar=CMD_OPTS_TXT)
313
@click.argument('classname', type=str, metavar='CLASSNAME', required=True)
13✔
314
@add_options(property_create_option)
13✔
315
@add_options(verify_option)
13✔
316
@add_options(namespace_option)
13✔
317
@add_options(help_option)
13✔
318
@click.pass_obj
13✔
319
def instance_create(context, classname, **options):
4✔
320
    """
321
    Create an instance of a class in a namespace.
322

323
    Create a CIM instance of the specified creation class (CLASSNAME
324
    argument) in the specified CIM namespace (--namespace option), with
325
    the specified properties (--property options) and display the CIM instance
326
    path of the created instance. If no namespace was specified, the default
327
    namespace of the connection is used.
328

329
    The properties to be initialized and their new values are specified using
330
    the --property option, which may be specified multiple times.
331

332
    Pywbemcli retrieves the class definition from the server in order to
333
    verify that the specified properties are consistent with the property
334
    characteristics in the class definition.
335

336
    Example:
337

338
      pywbemcli instance create CIM_blah -P id=3 -P arr="bla bla",foo
339
    """
340
    context.execute_cmd(
13✔
341
        lambda: cmd_instance_create(context, classname, options))
342

343

344
@instance_group.command('modify', cls=PywbemtoolsCommand,
13✔
345
                        options_metavar=CMD_OPTS_TXT)
346
@click.argument('instancename', type=str, metavar='INSTANCENAME',
13✔
347
                required=False)
348
@add_options(property_modify_option)
13✔
349
@click.option('--pl', '--propertylist', 'propertylist', multiple=True, type=str,
13✔
350
              default=None, required=False, metavar='PROPERTYLIST',
351
              help=u'Reduce the properties to be modified (as per '
352
              u'--property) to a specific property list. '
353
              u'Multiple properties may be specified with either a '
354
              u'comma-separated list or by using the option multiple '
355
              u'times. The empty string will cause no properties to '
356
              u'be modified. '
357
              u'Default: Do not reduce the properties to be modified.')
358
@add_options(verify_option)
13✔
359
@add_options(keybinding_key_option)
13✔
360
@add_options(namespace_option)
13✔
361
@add_options(help_instancename_option)
13✔
362
@add_options(help_option)
13✔
363
@click.pass_obj
13✔
364
def instance_modify(context, instancename, **options):
4✔
365
    """
366
    Modify properties of an instance.
367

368
    For information on how to specify the instance using INSTANCENAME and the
369
    --key and --namespace options, invoke with --help-instancename.
370

371
    The properties to be modified and their new values are specified using the
372
    --property option, which may be specified multiple times.
373

374
    The --propertylist option allows restricting the set of properties to be
375
    modified. Given that the set of properties to be modified is already
376
    determined by the specified --property options, it does not need to be
377
    specified.
378

379
    Example:
380

381
      pywbemcli instance modify CIM_blah.fred=3 -P id=3 -P arr="bla bla",foo
382
    """
383
    if options['help_instancename']:
13✔
384
        show_help_instancename()
13✔
385
        return
13✔
386
    validate_required_arg(instancename, 'INSTANCENAME')
13✔
387
    context.execute_cmd(
13✔
388
        lambda: cmd_instance_modify(context, instancename, options))
389

390

391
@instance_group.command('associators', cls=PywbemtoolsCommand,
13✔
392
                        options_metavar=CMD_OPTS_TXT)
393
@click.argument('instancename', type=str, metavar='INSTANCENAME',
13✔
394
                required=False)
395
@click.option('--ac', '--assoc-class', 'assoc_class', type=str, required=False,
13✔
396
              metavar='CLASSNAME',
397
              help=u'Filter the result set by association class name. '
398
                   u'Subclasses of the specified class also match.')
399
@click.option('--rc', '--result-class', 'result_class', type=str,
13✔
400
              required=False, metavar='CLASSNAME',
401
              help=u'Filter the result set by result class name. '
402
                   u'Subclasses of the specified class also match.')
403
@click.option('-r', '--role', type=str, required=False,
13✔
404
              metavar='PROPERTYNAME',
405
              help=u'Filter the result set by source end role name.')
406
@click.option('--rr', '--result-role', 'result_role', type=str, required=False,
13✔
407
              metavar='PROPERTYNAME',
408
              help=u'Filter the result set by far end role name.')
409
@add_options(include_qualifiers_list_option)
13✔
410
@add_options(include_classorigin_instance_option)
13✔
411
@add_options(propertylist_option)
13✔
412
@add_options(names_only_option)
13✔
413
@add_options(keybinding_key_option)
13✔
414
@add_options(multiple_namespaces_option_dflt_conn)
13✔
415
@add_options(summary_option)
13✔
416
@add_options(filter_query_option)
13✔
417
@add_options(filter_query_language_option)
13✔
418
@add_options(show_null_option)
13✔
419
@add_options(help_instancename_option)
13✔
420
@add_options(object_order_option)
13✔
421
@add_options(help_option)
13✔
422
@click.pass_obj
13✔
423
def instance_associators(context, instancename, **options):
4✔
424
    """
425
    List the instances associated with an instance.
426

427
    List the CIM instances that are associated with the specified CIM instance,
428
    and display the returned instances, or instance paths if --names-only was
429
    specified.
430

431
    For information on how to specify the instance using INSTANCENAME and the
432
    --key and --namespace options, invoke with --help-instancename.
433

434
    The instances to be retrieved can be filtered by the --filter-query,
435
    --role, --result-role, --assoc-class, and --result-class options.
436

437
    The --include-qualifiers, --include-classorigin, and --propertylist options
438
    determine which parts are included in each retrieved instance.
439

440
    The --names-only option can be used to show only the instance paths.
441

442
    In the output, the instances and instance paths will be formatted as
443
    defined by the --output-format general option. Table formats on instances
444
    will be replaced with MOF format.
445
    """
446
    if options['help_instancename']:
13✔
447
        show_help_instancename()
13✔
448
        return
13✔
449
    validate_required_arg(instancename, 'INSTANCENAME')
13✔
450
    context.execute_cmd(
13✔
451
        lambda: cmd_instance_associators(context, instancename, options))
452

453

454
@instance_group.command('references', cls=PywbemtoolsCommand,
13✔
455
                        options_metavar=CMD_OPTS_TXT)
456
@click.argument('instancename', type=str, metavar='INSTANCENAME',
13✔
457
                required=False)
458
@click.option('--rc', '--result-class', 'result_class', type=str,
13✔
459
              required=False, metavar='CLASSNAME',
460
              help=u'Filter the result set by result class name. '
461
                   u'Subclasses of the specified class also match.')
462
@click.option('-r', '--role', type=str, required=False, metavar='PROPERTYNAME',
13✔
463
              help=u'Filter the result set by source end role name.')
464
@add_options(include_qualifiers_list_option)
13✔
465
@add_options(include_classorigin_instance_option)
13✔
466
@add_options(propertylist_option)
13✔
467
@add_options(names_only_option)
13✔
468
@add_options(keybinding_key_option)
13✔
469
@add_options(multiple_namespaces_option_dflt_conn)
13✔
470
@add_options(summary_option)
13✔
471
@add_options(filter_query_option)
13✔
472
@add_options(show_null_option)
13✔
473
@add_options(filter_query_language_option)
13✔
474
@add_options(help_instancename_option)
13✔
475
@add_options(object_order_option)
13✔
476
@add_options(help_option)
13✔
477
@click.pass_obj
13✔
478
def instance_references(context, instancename, **options):
4✔
479
    """
480
    List the instances referencing an instance.
481

482
    List the CIM (association) instances that reference the specified CIM
483
    instance, and display the returned instances, or instance paths if
484
    --names-only was specified.
485

486
    For information on how to specify the instance using INSTANCENAME and the
487
    --key and --namespace options, invoke with --help-instancename.
488

489
    The instances to be retrieved can be filtered by the --filter-query, --role
490
    and --result-class options.
491

492
    The --include-qualifiers, --include-classorigin, and --propertylist options
493
    determine which parts are included in each retrieved instance.
494

495
    The --names-only option can be used to show only the instance paths.
496

497
    In the output, the instances and instance paths will be formatted as
498
    defined by the --output-format general option. Table formats on instances
499
    will be replaced with MOF format.
500
    """
501
    if options['help_instancename']:
13✔
502
        show_help_instancename()
13✔
503
        return
13✔
504
    validate_required_arg(instancename, 'INSTANCENAME')
13✔
505
    # pylint: disable=line-too-long
506
    context.execute_cmd(lambda: cmd_instance_references(context, instancename, options))  # noqa: E501
13✔
507

508

509
@instance_group.command('invokemethod', cls=PywbemtoolsCommand,
13✔
510
                        options_metavar=CMD_OPTS_TXT)
511
@click.argument('instancename', type=str, metavar='INSTANCENAME',
13✔
512
                required=False)
513
@click.argument('methodname', type=str, metavar='METHODNAME', required=False)
13✔
514
@click.option('-p', '--parameter', type=str, metavar='PARAMETERNAME=VALUE',
13✔
515
              required=False, multiple=True,
516
              help=u'Specify a method input parameter with its value. '
517
                   u'May be specified multiple times. '
518
                   u'Array property values are specified as a comma-separated '
519
                   u'list; embedded instances are not supported. '
520
                   u'Default: No input parameters.')
521
@add_options(keybinding_key_option)
13✔
522
@add_options(namespace_option)
13✔
523
@add_options(help_instancename_option)
13✔
524
@add_options(help_option)
13✔
525
@click.pass_obj
13✔
526
def instance_invokemethod(context, instancename, methodname, **options):
4✔
527
    """
528
    Invoke a method on an instance.
529

530
    Invoke a CIM method (METHODNAME argument) on a CIM instance with the
531
    specified input parameters (--parameter options), and display the method
532
    return value and output parameters.
533

534
    For information on how to specify the instance using INSTANCENAME and the
535
    --key and --namespace options, invoke with --help-instancename.
536

537
    The method input parameters are specified using the --parameter option,
538
    which may be specified multiple times.
539

540
    Pywbemcli retrieves the class definition of the creation class of the
541
    instance from the server in order to verify that the specified input
542
    parameters are consistent with the parameter characteristics in the method
543
    definition.
544

545
    Use the 'class invokemethod' command to invoke CIM methods on CIM classes.
546

547
    Example:
548

549
      pywbemcli -n myconn instance invokemethod CIM_x.id='hi" methodx -p id=3
550
    """
551
    if options['help_instancename']:
13✔
552
        show_help_instancename()
13✔
553
        return
13✔
554
    validate_required_arg(instancename, 'INSTANCENAME')
13✔
555
    validate_required_arg(methodname, 'METHODNAME')
13✔
556
    # pylint: disable=line-too-long
557
    context.execute_cmd(lambda: cmd_instance_invokemethod(context, instancename, methodname, options))  # noqa: E501
13✔
558

559

560
@instance_group.command('query', cls=PywbemtoolsCommand,
13✔
561
                        options_metavar=CMD_OPTS_TXT)
562
@click.argument('query', type=str, required=True, metavar='QUERY-STRING')
13✔
563
@click.option('--ql', '--query-language', 'query_language', type=str,
13✔
564
              metavar='QUERY-LANGUAGE', default=DEFAULT_QUERY_LANGUAGE,
565
              help=u'The query language to be used with --query. '
566
              u'Default: {default}.'.
567
              format(default=DEFAULT_QUERY_LANGUAGE))
568
@add_options(namespace_option)
13✔
569
@add_options(summary_option)
13✔
570
@add_options(help_option)
13✔
571
@click.pass_obj
13✔
572
def instance_query(context, query, **options):
4✔
573
    """
574
    Execute a query on instances in a namespace.
575

576
    Execute the specified query (QUERY_STRING argument) in the specified CIM
577
    namespace (--namespace option), and display the returned instances. If no
578
    namespace was specified, the default namespace of the connection is used.
579

580
    In the output, the instances will formatted as defined by the
581
    --output-format general option.
582
    """
583
    context.execute_cmd(lambda: cmd_instance_query(context, query, options))
13✔
584

585

586
@instance_group.command('count', cls=PywbemtoolsCommand,
13✔
587
                        options_metavar=CMD_OPTS_TXT)
588
@click.argument('classname', type=str, metavar='CLASSNAME-GLOB',
13✔
589
                required=False)
590
@add_options(multiple_namespaces_option_dflt_all)
13✔
591
@click.option('-s', '--sort', is_flag=True, required=False,
13✔
592
              help=u'Sort by instance count. Otherwise sorted by class name.')
593
@click.option('--ignore-class', type=str,
13✔
594
              multiple=True,
595
              metavar='CLASSNAME',
596
              help=u"Class names of classes to be ignored (not counted). "
597
                   u"Allows counting instances in servers where instance "
598
                   u"retrieval may cause a CIMError or Error exception "
599
                   u"on some classes. CIM errors on particular "
600
                   u"classes are ignored. Error exceptions cause scan to stop "
601
                   u"and remaining classes status shown as 'not scanned'. "
602
                   u"Multiple class names are allowed (one per option or "
603
                   u"comma-separated).")
604
@add_options(class_filter_options)
13✔
605
@add_options(help_option)
13✔
606
@click.pass_obj
13✔
607
def instance_count(context, classname, **options):
4✔
608
    """
609
    Count the instances of each class with matching class name.
610

611
    Display the count of instances of each CIM class whose class name
612
    matches the specified wildcard expression (CLASSNAME-GLOB) in all CIM
613
    namespaces of the WBEM server, or in the specified namespaces
614
    (--namespace option).  This differs from instance enumerate, etc. in that
615
    it counts the instances specifically for the classname of each instance
616
    returned, not including subclasses.
617

618
    The CLASSNAME-GLOB argument is a wildcard expression that is matched on
619
    class names case insensitively.
620
    The special characters from Unix file name wildcarding are supported
621
    ('*' to match zero or more characters, '?' to match a single character,
622
    and '[]' to match character ranges). To avoid shell expansion of wildcard
623
    characters, the CLASSNAME-GLOB argument should be put in quotes.
624

625
    If CLASSNAME-GLOB is not specified, then all classes in the specified
626
    namespaces are counted (same as when specifying CLASSNAME-GLOB as "*").
627

628
    For example, "pywbem_*" returns classes whose name begins with "PyWBEM_",
629
    "pywbem_", etc. "*system*" returns classes whose names include the case
630
    insensitive string "system".
631

632
    If a CIMError occurs on any enumerate, it is flagged with a warning message
633
    and the search for instances continues.  If an Error exception occurs
634
    (ex. Connection error) the scan is terminated under the assumption
635
    that the server may have failed and the remaining items are shown as
636
    "Not scanned".
637

638
    This command can take a long time to execute since it potentially
639
    enumerates all instance names for all classes in all namespaces.
640
    """
641
    context.execute_cmd(lambda: cmd_instance_count(context, classname, options))
13✔
642

643

644
@instance_group.command('shrub', cls=PywbemtoolsCommand,
13✔
645
                        options_metavar=CMD_OPTS_TXT)
646
@click.argument('instancename', type=str, metavar='INSTANCENAME',
13✔
647
                required=False)
648
@click.option('--ac', '--assoc-class', 'assoc_class', type=str, required=False,
13✔
649
              metavar='CLASSNAME',
650
              help=u'Filter the result set by association class name. '
651
                   'Subclasses of the specified class also match.')
652
@click.option('--rc', '--result-class', 'result_class', type=str,
13✔
653
              required=False, metavar='CLASSNAME',
654
              help=u'Filter the result set by result class name. '
655
                   u'Subclasses of the specified class also match.')
656
@click.option('-r', '--role', type=str, required=False,
13✔
657
              metavar='PROPERTYNAME',
658
              help=u'Filter the result set by source end role name.')
659
@click.option('--rr', '--result-role', 'result_role', type=str, required=False,
13✔
660
              metavar='PROPERTYNAME',
661
              help=u'Filter the result set by far end role name.')
662
@add_options(keybinding_key_option)
13✔
663
@add_options(namespace_option)
13✔
664
@add_options(summary_option)
13✔
665
@click.option('-f', '--fullpath', default=False, is_flag=True,
13✔
666
              help=u'Normally the instance paths in the tree views are '
667
                   u'by hiding some keys with ~ to make the tree simpler '
668
                   u'to read. This includes keys that have the same value '
669
                   u'for all instances and the "CreationClassName" key.  When'
670
                   'this option is used the full instance paths are displayed.')
671
@add_options(help_instancename_option)
13✔
672
@add_options(help_option)
13✔
673
@click.pass_obj
13✔
674
def instance_shrub(context, instancename, **options):
4✔
675
    """
676
    Show the association shrub for INSTANCENAME.
677

678
    The shrub is a view of all of the instance association relationships for
679
    a defined INSTANCENAME showing the various components that are part of
680
    the association including Role, AssocClasse,ResultRole, And ResultClas
681

682
    The default view is a tree view from the INSTANCENAME to associated
683
    instances.
684

685
    Displays the shrub of association components for the association source
686
    instance defined by INSTANCENAME.
687

688
    For information on how to specify the instance using INSTANCENAME and the
689
    --key and --namespace options, invoke with --help-instancename.
690

691
    Normally the association information is displayed as a tree but it
692
    may also be displayed as a table or as one of the object formats (ex. MOF)
693
    of all instances that are part of the shrub if one of the cim object
694
    formats is selected with the global output_format parameter.
695

696
    Results are formatted as defined by the output format global option.
697
    """
698
    if options['help_instancename']:
13✔
699
        show_help_instancename()
13✔
700
        return
13✔
701
    validate_required_arg(instancename, 'INSTANCENAME')
13✔
702
    # pylint: disable=line-too-long
703
    context.execute_cmd(lambda: cmd_instance_shrub(context, instancename, options))  # noqa: E501
13✔
704

705

706
####################################################################
707
#
708
#  Common functions for cmd_instance processing
709
#
710
####################################################################
711

712

713
def show_help_instancename():
13✔
714
    """
715
    Show the help message on how to specify an instance using INSTANCENAME
716
    and the --key and --namespace options.
717
    """
718
    # Note: This help text has a fixed width since it is too complex to
719
    # dynamically render it to a given width.
720
    click.echo("""
13✔
721
An instance path is specified using the INSTANCENAME argument and optionally the
722
--key and --namespace options. It can be specified in three ways:
723

724
1. By specifying the instance path as an untyped WBEM URI in the INSTANCENAME
725
   argument. In this case, the keybindings of the instance are specified in the
726
   WBEM URI, and the --key option must not be used.
727

728
   String typed keybindings in WBEM URIs are using double quotes, so the
729
   processing of special characters by the shell (such as backslashes and
730
   quotes) needs to be considered.
731

732
   The CIM namespace of the instance can be specified in the WBEM URI, or using
733
   the --namespace option, or otherwise the default namespace of the connection
734
   will be used.
735

736
   If present, the scheme and host components in the WBEM URI will be ignored.
737

738
   Examples (for a shell such as 'bash'):
739

740
     cimv2/test:TST_Person.FirstName=\\"Albert\\",LastName=\\"Einstein\\"
741
     TST_Foo.ID=42 --namespace cimv2/test
742
     TST_Foo.ID=42                     # default namespace of connection is used
743
     TST_Foo.IntegerKey=42
744
     TST_Foo.BooleanKey=true
745
     TST_Foo.StringKey=\\"text\\"        # shell processes escapes
746
     'TST_Foo.StringKey="text"'        # shell processes outer squotes
747
     'TST_Foo.StringKey="42"'          # shell processes outer squotes
748
     'TST_Foo.StringKey="true"'        # shell processes outer squotes
749
     "TST_Foo.StringKey=\\"it's\\""      # shell proc. outer dquotes and escapes
750
     'TST_Foo.StringKey="1.75\\""'      # shell processes outer squotes
751
     'TST_Foo.StringKey="a b"'         # shell processes outer squotes
752
     'CIM_SubProfile.Main="CIM_RegisteredProfile.InstanceID=\\"acme.1\\"",
753
       Sub="CIM_RegisteredProfile.InstanceID=\\"acme.2\\""'
754

755
2. By specifying the class path of the creation class of the instance as an
756
   untyped WBEM URI in the INSTANCENAME argument and by using the --key option
757
   to specify the keybindings of the instance.
758

759
   This approach reduces the use of double quotes compared to the first
760
   approach and eliminates it for the most common cases, but the processing of
761
   special characters by the shell still needs to be considered.
762

763
   The --key option can be specified multiple times, once for each key of the
764
   instance name. The argument of the --key option has a NAME=VALUE format,
765
   where NAME is the name of the key property and VALUE is its value. The
766
   string/numeric/boolean type needed for creating a keybinding is determined
767
   automatically from VALUE. Valid integer numbers are interpreted as a numeric
768
   type, the strings "true" and "false" in any lexical case are interpreted as
769
   a boolean type, and anything else is interpreted as a string type. Starting
770
   and ending VALUE with double quotes forces interpretation as a string type;
771
   in that case double quotes and backslashes inside of the double quotes need
772
   to be backslash-escaped. This is useful for strings that have a numeric
773
   value, or the string values "true" or "false".
774

775
   The CIM namespace of the instance can be specified in the WBEM URI, or using
776
   the --namespace option, or otherwise the default namespace of the connection
777
   will be used.
778

779
   If present, the scheme and host components in the WBEM URI will be ignored.
780

781
   Examples (for a shell such as 'bash'):
782

783
     cimv2/test:TST_Person --key FirstName=Albert --key LastName=Einstein
784
     TST_Foo --namespace cimv2/test --key ID=42
785
     TST_Foo --key ID=42               # default namespace of connection is used
786
     TST_Foo --key IntegerKey=42
787
     TST_Foo --key BooleanKey=true
788
     TST_Foo --key StringKey=text
789
     TST_Foo --key StringKey=\\"42\\"    # shell processes escapes
790
     TST_Foo --key StringKey=\\"true\\"  # shell processes escapes
791
     TST_Foo --key "StringKey=it's"    # shell processes outer dquotes
792
     TST_Foo --key 'StringKey=1.75"'   # shell processes outer squotes
793
     TST_Foo --key "StringKey=a b"     # shell processes outer dquotes
794
     TST_Foo --key StringKey="a b"     # shell processes outer dquotes
795
     TST_Foo --key StringKey=a\\ b      # shell processes escapes
796
     CIM_SubProfile --key Main='CIM_RegisteredProfile.InstanceID="acme.1"'
797
       --key Sub='CIM_RegisteredProfile.InstanceID="acme.2"'
798

799
3. By specifying the class path of the creation class of the instance as an
800
   untyped WBEM URI in the INSTANCENAME argument, followed by a wildcard
801
   indicator ".?". In this case, the --key option must not be used. The
802
   instances of the specified class are displayed and the user is prompted for
803
   an index number to select an instance.
804

805
   The CIM namespace of the instance can be specified in the WBEM URI, or using
806
   the --namespace option, or otherwise the default namespace of the connection
807
   will be used.
808

809
   If present, the scheme and host components in the WBEM URI will be ignored.
810

811
   Example command:
812

813
     $ pywbemcli instance get cimv2/test:TST_Person.?
814
     Pick Instance name to process
815
     0: cimv2/test:TST_Person.FirstName="Albert",LastName="Einstein"
816
     1: cimv2/test:TST_Person.FirstName="Marie",LastName="Curie"
817
     Input integer between 0 and 1 or Ctrl-C to exit selection: _
818
""")
819

820

821
def get_instancename(context, instancename, options, default_all_ns=False):
13✔
822
    """
823
    Common function to construct a CIMInstanceName object from the
824
    INSTANCENAME argument and the --key and --namespace options specified
825
    in the command line.
826

827
    The keybindings of the returned CIM instance path(s) must be specified in
828
    exactly one of these ways:
829

830
    * If the keybindings component in the instance name string is "?"
831
      (e.g. "CIM_Foo.?"), the instances of that class are listed and the user
832
      is prompted to pick instance name. If multiple namespaces are specified
833
      in the "--namespaces" option the instances in all requested namespaces
834
      are listed for the user to pick one.
835

836
    * If the "key" option is non-empty, the so specified key values are used as
837
      keybindings for the returned instance path, and the instancename string
838
      is interpreted as a class WBEM URI.
839

840
    * If the instance name string specifies keybindings, these keybindings
841
      are used to define the instance name to return.
842

843
    The namespace of the returned CIM instance path must be specified in
844
    exactly one of these ways:
845

846
    * If the instance name string specifies a namespace, it is used.
847

848
    * If the "--namespace" option is non-empty, it is used. If the "--namespace"
849
      option is a list, the request is to return instance names in any of the
850
      namespaces.
851

852
    * Otherwise, the default namespace of the connection in the context is used.
853

854
    Parameters:
855

856
      context (:class:`'~pywbemtools._context_obj.ContextObj`):
857
        The Click context object.
858

859
      instancename (:term:`string`):
860
        The INSTANCENAME argument from the command line.
861

862
      options (dict):
863
        Command-specific options from the command line (including "-key" and
864
        "--namespace" if specified).
865

866
      default_all_ns (:class:`py:bool`)
867
        If True, the default is to return all namespaces.  Otherwise the
868
        default is to return None.
869

870
    Returns:
871

872
      :class:`~pywbem.CIMInstanceName`: CIM instance path. It is never None.
873
      Namespace included in instance name ONLY if it is in the parameter
874
      instance name or multiple namespaces were specified with "--namespace".
875

876
    Raises:
877

878
      ClickException: Various reasons.
879
    """
880
    conn = context.pywbem_server.conn
13✔
881

882
    def validate_namespace_option(class_path):
13✔
883
        """Validate either namespace in instance or --namespace but not both"""
884
        if class_path.namespace:
13✔
885
            if options['namespace']:
13✔
886
                raise click.ClickException(
13✔
887
                    "Using --namespace option: {} conflicts with specifying "
888
                    "namespace in INSTANCENAME: {}".format(options['namespace'],
889
                                                           instancename))
890

891
    # If option is a tuple, expand option to get list of all namespaces
892
    # defined. Option may be multiple uses of the option and/or comma-separated
893
    # string for any option value
894
    if isinstance(options['namespace'], tuple):
13✔
895
        ns_names = get_namespaces(context, options['namespace'],
13✔
896
                                  default_all_ns=default_all_ns)
897
    else:
898
        ns_names = options['namespace']
13✔
899

900
    # Process the 3 exclusive cmd option (".?", --key option, instance name )
901
    if instancename.endswith(".?"):
13✔
902
        if options['key']:
13✔
903
            raise click.ClickException(
13✔
904
                "Using the --key option conflicts with specifying a "
905
                "wildcard keybinding in INSTANCENAME: {}".
906
                format(instancename))
907

908
        class_uri = instancename[:-2]
13✔
909
        try:
13✔
910
            class_path = CIMClassName.from_wbem_uri(class_uri)
13✔
911
        except ValueError as exc:
13✔
912
            raise click.ClickException(str(exc))
13✔
913

914
        validate_namespace_option(class_path)
13✔
915

916
        try:
13✔
917
            # User picks one instance.  returned instance path includes
918
            # namespace.
919
            instance_path = pick_instance(
13✔
920
                context, class_path.classname, ns_names)
921
            # Reset the namespace in instance name if multiple namespaces
922
            if instance_path:
13✔
923
                if ns_names:
13✔
924
                    instance_path.namespace = None
13✔
925
        except ValueError as exc:
13✔
926
            raise click.ClickException(str(exc))
×
927

928
    # if --key option exists.
929
    elif options['key']:
13✔
930
        # Transform the --key option values into WBEM URI keybinding strings
931
        kb_strs = []
13✔
932
        for kv in options['key']:
13✔
933
            key, value = parse_kv_pair(kv)
13✔
934
            if value is None:
13✔
935
                raise click.ClickException(
13✔
936
                    "VALUE in --key option argument is missing: {}".format(kv))
937
            try:
13✔
938
                int(value)
13✔
939
                is_int = True
13✔
940
            except (ValueError, TypeError):
13✔
941
                is_int = False
13✔
942
            if value is None:
13✔
943
                # There is no official NULL representation in WBEM URI
944
                kb_value = ''
×
945
            elif is_int:
13✔
946
                # integer - use without quotes
947
                kb_value = value
13✔
948
            elif value.upper() in ('TRUE', 'FALSE'):
13✔
949
                # boolean - use the upper cased string without quotes
950
                kb_value = value.upper()
13✔
951
            elif value.startswith('"') and value.endswith('"'):
13✔
952
                # string - the value between the double quotes is assumed to
953
                # already be backslash-escaped, at the minimum for double
954
                # quotes and backslashes.
955
                kb_value = value
13✔
956
            else:
957
                # string - double quotes and escaping is added
958
                # Note that a keybinding value in a WBEM URI only requires
959
                # the minimal escaping for MOF string literals, i.e. double
960
                # quotes and backslashes. However, we escape all control chars,
961
                # double quotes, and single quotes, to ensure that there are no
962
                # unprintable characters, and no quotes that might interfere
963
                # with the shell.
964
                kb_value = '"{}"'.format(mof_escaped(value))
13✔
965

966
            kb_strs.append("{}={}".format(key, kb_value))
13✔
967

968
        # We perform an extra verification that instance name was a class
969
        # path to get a more understandable error message if it is not,
970
        # compared to leaving that to CIMInstanceName.from_wbem_uri().
971
        try:
13✔
972
            CIMClassName.from_wbem_uri(instancename)
13✔
973
        except ValueError as exc:
13✔
974
            raise click.ClickException(str(exc))
13✔
975

976
        instancename_kb = "{}.{}".format(instancename, ','.join(kb_strs))
13✔
977

978
        try:
13✔
979
            instance_path = CIMInstanceName.from_wbem_uri(instancename_kb)
13✔
980
            validate_namespace_option(instance_path)
13✔
981
        except ValueError as exc:
13✔
982
            raise click.ClickException(str(exc))
13✔
983

984
    else:  # else for not options['key']] or ".?", i.e. full key in inst path
985
        try:
13✔
986
            instance_path = CIMInstanceName.from_wbem_uri(instancename)
13✔
987
            validate_namespace_option(instance_path)
13✔
988
        except ValueError as exc:
13✔
989
            raise click.ClickException(str(exc))
13✔
990

991
    if instance_path is None:
13✔
992
        raise click.ClickException(
13✔
993
            "No instance paths found for instancename {0}".format(instancename))
994

995
    # Set namespace into path if ns_names not set
996
    if not instance_path.namespace:
13✔
997
        if not ns_names:
13✔
998
            instance_path.namespace = options.get('namespace') or \
13✔
999
                conn.default_namespace
1000
        if isinstance(ns_names, six.string_types):
13✔
1001
            instance_path.namespace = ns_names
13✔
1002

1003
    return instance_path
13✔
1004

1005

1006
####################################################################
1007
#
1008
#  cmd_instance_<action> processors
1009
#
1010
####################################################################
1011

1012

1013
def cmd_instance_get(context, instancename, options):
13✔
1014
    """
1015
    Get and display an instance of a CIM Class.
1016

1017
    Gets the instance defined by instancename argument in the namespaces defined
1018
    and displays in output format defined.  If multiple namespaces are defined
1019
    this method may get multiple instances.
1020

1021
    If the wildcard key is used (CLASSNAME.?), pywbemcli presents a list of
1022
    instances to the console from which one can be picked to get from the
1023
    server and display.
1024
    """
1025
    conn = context.pywbem_server.conn
13✔
1026
    output_fmt = validate_output_format(context.output_format, ['CIM', 'TABLE'])
13✔
1027

1028
    # Returns list of namespaces from namespace option
1029
    instancepath = get_instancename(context, instancename, options)
13✔
1030

1031
    property_list = resolve_propertylist(options['propertylist'])
13✔
1032

1033
    results = ResultsHandler(context, options, output_fmt, "instance",
13✔
1034
                             instancepath, instpath=instancepath)
1035

1036
    for ns in results:
13✔
1037
        try:
13✔
1038
            instancepath.namespace = ns
13✔
1039
            results.add(conn.GetInstance(
13✔
1040
                instancepath,
1041
                LocalOnly=options['local_only'],
1042
                IncludeQualifiers=options['include_qualifiers'],
1043
                IncludeClassOrigin=options['include_classorigin'],
1044
                PropertyList=property_list))
1045

1046
        except CIMError as ce:
13✔
1047
            # Process error and continue or generate exception
1048
            results.handle_exception(ns, ce)
13✔
1049
            continue
13✔
1050

1051
        except Error as er:
13✔
1052
            raise pywbem_error_exception(er)
13✔
1053

1054
    results.display()
13✔
1055

1056

1057
def cmd_instance_delete(context, instancename, options):
13✔
1058
    """
1059
        If option interactive is set, get instances of the class defined
1060
        by instance name and allow the user to select the instance to
1061
        delete. This method allows only a single namespace.
1062

1063
        Otherwise attempt to delete the instance defined by instancename
1064
    """
1065
    conn = context.pywbem_server.conn
13✔
1066

1067
    instancepath = get_instancename(context, instancename, options)
13✔
1068

1069
    try:
13✔
1070
        conn.DeleteInstance(instancepath)
13✔
1071

1072
        if context.verbose:
13✔
1073
            context.spinner_stop()
13✔
1074
            click.echo('Deleted instance {}'.format(instancepath))
13✔
1075

1076
    except Error as er:
13✔
1077
        raise pywbem_error_exception(er)
13✔
1078

1079

1080
def cmd_instance_create(context, classname, options):
13✔
1081
    """
1082
       Create an instance and submit to wbemserver.
1083
       If successful, this operation returns the new instance name. Otherwise
1084
       it raises an exception
1085
    """
1086
    conn = context.pywbem_server.conn
13✔
1087
    ns = options['namespace'] or conn.default_namespace
13✔
1088
    try:
13✔
1089
        class_ = conn.GetClass(
13✔
1090
            classname, namespace=ns, LocalOnly=False)
1091
    except CIMError as ce:
13✔
1092
        if ce.status_code == CIM_ERR_NOT_FOUND:
13✔
1093
            raise click.ClickException(
13✔
1094
                'CIMClass: "{}" does not exist in namespace "{}" in WEB '
1095
                'server: {}.'.
1096
                format(classname, ns, conn))
1097
        raise pywbem_error_exception(ce)
13✔
1098

1099
    except Error as er:
13✔
1100
        raise pywbem_error_exception(er)
13✔
1101

1102
    properties = options['property']
13✔
1103

1104
    # properties is a tuple of name,value pairs
1105
    new_inst = create_ciminstance(class_, properties)
13✔
1106

1107
    if options['verify']:
13✔
1108
        context.spinner_stop()
13✔
1109
        click.echo(new_inst.tomof())
13✔
1110
        if not verify_operation("Execute CreateInstance", msg=True):
13✔
1111
            return
13✔
1112
    try:
13✔
1113
        name = conn.CreateInstance(new_inst, namespace=ns)
13✔
1114

1115
        context.spinner_stop()
13✔
1116
        click.echo('{}'.format(name))
13✔
1117
    except Error as er:
×
1118
        raise click.ClickException(
×
1119
            'Server Error creating instance in namespace {}. Exception: '
1120
            '{}: {}'.
1121
            format(ns, er.__class__.__name__, er))
1122

1123

1124
def cmd_instance_modify(context, instancename, options):
13✔
1125
    """
1126
    Build an instance defined by the options and submit to wbemserver
1127
    as a ModifyInstance method.
1128

1129
    This method allows only a single namespace.
1130

1131
    In order to make a correct instance, this method first gets the
1132
    corresponding class and uses that as the template for creating the intance.
1133
    The class provides property names, types, array flags, etc. to assure
1134
    that the instance is correctly built.
1135

1136
    If successful, this operation returns nothing.
1137
    """
1138
    conn = context.pywbem_server.conn
13✔
1139
    instancepath = get_instancename(context, instancename, options)
13✔
1140

1141
    ns = options['namespace'] or conn.default_namespace
13✔
1142

1143
    try:
13✔
1144
        class_ = conn.GetClass(
13✔
1145
            instancepath.classname, namespace=ns, LocalOnly=False)
1146
    except CIMError as ce:
13✔
1147
        if ce.status_code == CIM_ERR_NOT_FOUND:
13✔
1148
            raise click.ClickException(
13✔
1149
                'CIMClass: {!r} does not exist in WEB server: {}'
1150
                .format(instancepath.classname, conn.url))
1151

1152
        raise pywbem_error_exception(ce)
13✔
1153
    except Error as er:
13✔
1154
        raise pywbem_error_exception(er)
13✔
1155

1156
    property_list = resolve_propertylist(options['propertylist'])
13✔
1157

1158
    # properties is a tuple of name,value pairs
1159
    modified_inst = create_ciminstance(class_, options['property'])
13✔
1160

1161
    modified_inst.path = instancepath
13✔
1162

1163
    if options['verify']:
13✔
1164
        context.spinner_stop()
13✔
1165
        click.echo(modified_inst.tomof())
13✔
1166
        if not verify_operation("Execute ModifyInstance", msg=True):
13✔
1167
            return
13✔
1168

1169
    try:
13✔
1170
        conn.ModifyInstance(modified_inst, PropertyList=property_list)
13✔
1171
        if context.verbose:
13✔
1172
            context.spinner_stop()
13✔
1173
            click.echo('Modified instance {}'.format(instancepath))
13✔
1174
    except Error as er:
13✔
1175
        raise click.ClickException('Server Error modifying instance {} '
13✔
1176
                                   'in namespace {}. Exception: {}: {}'.format
1177
                                   (instancepath, ns, er.__class__.__name__,
1178
                                    er))
1179

1180

1181
def cmd_instance_invokemethod(context, instancename, methodname,
13✔
1182
                              options):
1183
    """
1184
    Create an instance and submit to wbemserver
1185
    """
1186
    instancepath = get_instancename(context, instancename, options)
13✔
1187

1188
    try:
13✔
1189
        process_invokemethod(context, instancepath, methodname,
13✔
1190
                             options['namespace'], options['parameter'])
1191
    except Error as er:
13✔
1192
        raise pywbem_error_exception(er)
13✔
1193

1194

1195
def get_filterquerylanguage(options):
13✔
1196
    """
1197
    Get the filterquery language based on what is in the filterquery option
1198
    and the filterquerylanguage options.
1199
    If filterquery exists but filterquerylanguage does not, use DMTF as
1200
    the filter query language.
1201
    if filterquery does not exist but filterquerylanguage does, just return it
1202
    """
1203
    if options['filter_query']:
13✔
1204
        fql = options['filter_query_language'] or 'DMTF:FQL'
13✔
1205
    else:
1206
        fql = options['filter_query_language']
13✔
1207
    return fql
13✔
1208

1209

1210
def enumerate_instances(conn, context, options, namespace, classname,
13✔
1211
                        property_list, return_original_err=False):
1212
    """
1213
    Internal method.
1214

1215
    Issue the command to enumerate either the paths or instances for the
1216
    namespace defined by the namespace parameter.
1217

1218
    If the return_original_err is True, reraise any  Error or CIMError
1219
    exception.
1220
    """
1221
    try:
13✔
1222
        if options['names_only']:
13✔
1223
            return conn.PyWbemcliEnumerateInstancePaths(
13✔
1224
                ClassName=classname,
1225
                namespace=namespace,
1226
                FilterQuery=options['filter_query'],
1227
                FilterQueryLanguage=get_filterquerylanguage(options),
1228
                MaxObjectCount=context.pywbem_server.pull_max_cnt)
1229

1230
        return conn.PyWbemcliEnumerateInstances(
13✔
1231
            ClassName=classname,
1232
            namespace=namespace,
1233
            LocalOnly=options['local_only'],
1234
            IncludeQualifiers=options['include_qualifiers'],
1235
            DeepInheritance=options['deep_inheritance'],
1236
            IncludeClassOrigin=options['include_classorigin'],
1237
            FilterQuery=options['filter_query'],
1238
            FilterQueryLanguage=get_filterquerylanguage(options),
1239
            MaxObjectCount=context.pywbem_server.pull_max_cnt,
1240
            PropertyList=property_list)
1241

1242
    except Error as er:
13✔
1243
        # Return either the original exception or the ClickException.
1244
        if return_original_err:
13✔
1245
            raise er
13✔
1246
        raise pywbem_error_exception(er)
×
1247

1248
    # Exception from Enumerate and the FilterQuery.  This exception would
1249
    # apply  to all namespaces so just terminate.
1250
    except ValueError as ve:
13✔
1251
        raise click.ClickException(
13✔
1252
            'Instance enumerate failed because FilterQuery not allowed with '
1253
            'traditional EnumerateInstance. --use-pull: {}. Exception: {}: {}'
1254
            .format(context.pywbem_server.use_pull, ve.__class__.__name__, ve))
1255

1256

1257
def cmd_instance_enumerate(context, classname, options):
13✔
1258
    """
1259
    Enumerate CIM instances or CIM instance names
1260

1261
    Returns:
1262
        list of objects retrieved.
1263

1264
    """
1265
    conn = context.pywbem_server.conn
13✔
1266
    output_fmt = validate_output_format(context.output_format, ['CIM', 'TABLE'])
13✔
1267

1268
    property_list = resolve_propertylist(options['propertylist'])
13✔
1269

1270
    results = ResultsHandler(context, options, output_fmt, "class", classname,
13✔
1271
                             property_list=property_list)
1272

1273
    for ns in results:
13✔
1274
        try:
13✔
1275
            results.add(enumerate_instances(conn, context, options, ns,
13✔
1276
                                            classname, property_list,
1277
                                            return_original_err=True))
1278

1279
        except CIMError as ce:
13✔
1280
            # Process error and continue or generate exception
1281
            results.handle_exception(ns, ce)
13✔
1282
            continue
13✔
1283

1284
        except Error as er:
13✔
1285
            raise pywbem_error_exception(er)
13✔
1286

1287
    results.display()
13✔
1288

1289

1290
def cmd_instance_references(context, instancename, options):
13✔
1291
    """Execute the references request operation to get references for
1292
       the classname defined. This may be either interactive or if the
1293
       interactive option is set or use the instancename directly.
1294

1295
       This method allows multiple namespaces
1296

1297
       If the interactive option is selected, the instancename MUST BE
1298
       a classname.
1299
    """
1300
    conn = context.pywbem_server.conn
13✔
1301
    output_fmt = validate_output_format(context.output_format, ['CIM', 'TABLE'])
13✔
1302

1303
    instancepath = get_instancename(context, instancename, options)
13✔
1304

1305
    property_list = resolve_propertylist(options['propertylist'])
13✔
1306

1307
    results = ResultsHandler(context, options, output_fmt, "instance",
13✔
1308
                             instancepath, instpath=instancepath,
1309
                             property_list=property_list)
1310

1311
    for ns in results:
13✔
1312
        try:
13✔
1313
            instancepath.namespace = ns
13✔
1314
            if options['names_only']:
13✔
1315
                results.add(conn.PyWbemcliReferenceInstancePaths(
13✔
1316
                    instancepath,
1317
                    ResultClass=options['result_class'],
1318
                    Role=options['role'],
1319
                    FilterQuery=options['filter_query'],
1320
                    FilterQueryLanguage=get_filterquerylanguage(options),
1321
                    MaxObjectCount=context.pywbem_server.pull_max_cnt))
1322
            else:
1323
                results.add(conn.PyWbemcliReferenceInstances(
13✔
1324
                    instancepath,
1325
                    ResultClass=options['result_class'],
1326
                    Role=options['role'],
1327
                    IncludeQualifiers=options['include_qualifiers'],
1328
                    IncludeClassOrigin=options['include_classorigin'],
1329
                    FilterQuery=options['filter_query'],
1330
                    FilterQueryLanguage=get_filterquerylanguage(options),
1331
                    MaxObjectCount=context.pywbem_server.pull_max_cnt,
1332
                    PropertyList=property_list))
1333

1334
        except CIMError as ce:
13✔
1335
            # Process error and continue or generate exception
1336
            results.handle_exception(ns, ce)
13✔
1337
            continue
×
1338

1339
        except Error as er:
13✔
1340
            raise pywbem_error_exception(er)
13✔
1341

1342
        except ValueError as ve:
13✔
1343
            raise click.ClickException(
13✔
1344
                'Instance references failed because FilterQuery not allowed '
1345
                'with traditional References. --use-pull {}. Exception: {}: {}'
1346
                .format(context.pywbem_server.use_pull, ve.__class__.__name__,
1347
                        ve))
1348
    results.display()
13✔
1349

1350

1351
def cmd_instance_associators(context, instancename, options):
13✔
1352
    """
1353
    Execute the references request operation to get references for
1354
    the classname defined.
1355

1356
    This method allows multiple namespaces.
1357
    """
1358
    conn = context.pywbem_server.conn
13✔
1359
    output_fmt = validate_output_format(context.output_format, ['CIM', 'TABLE'])
13✔
1360

1361
    instancepath = get_instancename(context, instancename, options)
13✔
1362

1363
    property_list = resolve_propertylist(options['propertylist'])
13✔
1364

1365
    results = ResultsHandler(context, options, output_fmt, "class",
13✔
1366
                             instancepath, instpath=instancepath,
1367
                             property_list=property_list)
1368

1369
    for ns in results:
13✔
1370
        try:
13✔
1371
            instancepath.namespace = ns
13✔
1372
            if options['names_only']:
13✔
1373
                results.add(conn.PyWbemcliAssociatorInstancePaths(
13✔
1374
                    instancepath,
1375
                    AssocClass=options['assoc_class'],
1376
                    Role=options['role'],
1377
                    ResultClass=options['result_class'],
1378
                    ResultRole=options['result_role'],
1379
                    FilterQuery=options['filter_query'],
1380
                    FilterQueryLanguage=get_filterquerylanguage(options),
1381
                    MaxObjectCount=context.pywbem_server.pull_max_cnt))
1382
            else:
1383
                results.add(conn.PyWbemcliAssociatorInstances(
13✔
1384
                    instancepath,
1385
                    AssocClass=options['assoc_class'],
1386
                    Role=options['role'],
1387
                    ResultClass=options['result_class'],
1388
                    ResultRole=options['result_role'],
1389
                    IncludeQualifiers=options['include_qualifiers'],
1390
                    IncludeClassOrigin=options['include_classorigin'],
1391
                    FilterQuery=options['filter_query'],
1392
                    FilterQueryLanguage=get_filterquerylanguage(options),
1393
                    MaxObjectCount=context.pywbem_server.pull_max_cnt,
1394
                    PropertyList=property_list))
1395

1396
        except CIMError as ce:
13✔
1397
            # Process error and continue or generate exception
1398
            results.handle_exception(ns, ce)
13✔
1399
            continue
13✔
1400

1401
        except Error as er:
13✔
1402
            raise pywbem_error_exception(er)
13✔
1403

1404
        except ValueError as ve:
13✔
1405
            raise click.ClickException(
13✔
1406
                'Instance associators failed because FilterQuery not allowed '
1407
                'with traditional Associators. --use-pull: {}. Exception: {}: '
1408
                '{}'
1409
                .format(context.pywbem_server.use_pull, ve.__class__.__name__,
1410
                        ve))
1411

1412
    results.display()
13✔
1413

1414

1415
def cmd_instance_count(context, classname, options):
13✔
1416
    """
1417
    Get the number of instances of each class in the namespace
1418
    """
1419
    conn = context.pywbem_server.conn
13✔
1420
    output_fmt = validate_output_format(context.output_format, 'TABLE')
13✔
1421

1422
    class_ignore_list = []
13✔
1423
    for cls in options['ignore_class']:
13✔
1424
        if ',' in cls:
13✔
1425
            class_ignore_list.extend(cls.split(','))
13✔
1426
        else:
1427
            class_ignore_list.append(cls)
13✔
1428

1429
    # Differs from class find because the classname is optional.
1430
    # If None, select all
1431
    if classname is None:
13✔
1432
        classname = '*'
13✔
1433

1434
    # Create list of namespaces from the option or from all namespaces
1435
    # default_rtn forces
1436
    ns_names = get_namespaces(context, options['namespace'],
13✔
1437
                              default_all_ns=True)
1438

1439
    ns_cln_tuples = []  # a list of tuples of namespace, classname
13✔
1440
    for namespace in ns_names:
13✔
1441
        # Get all classes in Namespace
1442
        try:
13✔
1443
            # Set cmd options that are required for this command.
1444
            # 1. Always use deep_inheritance
1445
            # 2. Set namespace to each namespace in loop
1446
            options['deep_inheritance'] = True
13✔
1447
            options['names_only'] = True
13✔
1448

1449
            classnames = enumerate_classes_filtered(context, namespace, None,
13✔
1450
                                                    options)
1451
        except Error as er:
13✔
1452
            raise pywbem_error_exception(er)
13✔
1453

1454
        if classnames:
13✔
1455
            classlist = filter_namelist(classname, classnames, ignore_case=True)
13✔
1456
            cl_tup = [(namespace, cln) for cln in classlist]
13✔
1457
            ns_cln_tuples.extend(cl_tup)
13✔
1458

1459
    # Sort since normal output for this command is  namespace, classname
1460
    # alphabetic order.
1461
    ns_cln_tuples.sort(key=lambda tup: (tup[0], tup[1]))
13✔
1462

1463
    display_data = []
13✔
1464
    error = 0
13✔
1465
    # Scan all of the class/namespace tuples to get count of instances
1466
    # of each class.
1467
    for tup in ns_cln_tuples:
13✔
1468
        ns = tup[0]
13✔
1469
        cln = tup[1]
13✔
1470
        if cln in class_ignore_list:
13✔
1471
            display_tuple = (ns, cln, "ignored")
13✔
1472
            display_data.append(display_tuple)
13✔
1473
            continue
13✔
1474
        # If an error has occurred, just display the remaining items with
1475
        # Not scanned msg.
1476
        if error:
13✔
1477
            display_tuple = (ns, cln, "Not scanned")
×
1478
            display_data.append(display_tuple)
×
1479
            continue
×
1480
        # Try block allows issues where enumerate does not properly execute
1481
        # The totals may be wrong but at least it gets what it can.
1482
        # This accounts for issues with some servers where there
1483
        # are providers that return errors from the enumerate.
1484
        inst_names = None
13✔
1485
        try:
13✔
1486
            inst_names = conn.EnumerateInstanceNames(cln, namespace=ns)
13✔
1487
        except CIMError as ce:
×
1488
            warning_msg("Server CIMError {0} with namepace={1}, class={2}. "
×
1489
                        "Continuing scan."
1490
                        .format(ce, ns, cln))
1491
            display_tuple = (ns, cln, "CIMError {}".format(ce.status_code))
×
1492
            display_data.append(display_tuple)
×
1493
            continue
×
1494
        # Error exception cause termination of the connection. Add this
1495
        # item to the display with Server Fail message instead of count
1496
        except Error as er:
×
1497
            error = er
×
1498
            warning_msg("Server Error {0} with namepace={1}, class={2}. "
×
1499
                        "Terminating scan."
1500
                        .format(er, ns, cln))
1501
            display_tuple = (ns, cln, "Server Fail")
×
1502
            display_data.append(display_tuple)
×
1503
            continue
×
1504

1505
        # Sum the number of instances with the defined classname.
1506
        # this counts only classes with that specific classname and not
1507
        # subclasses
1508
        if inst_names:
13✔
1509
            count = sum(1 for inst_name in inst_names
13✔
1510
                        if (inst_name.classname.lower() == cln.lower()))
1511
            # Display only non-zero elements
1512
            if count:
13✔
1513
                display_tuple = (ns, cln, count)
13✔
1514
                display_data.append(display_tuple)
13✔
1515

1516
    # Post scan processing
1517
    # If sort set, re-sort by count size
1518
    if options['sort']:
13✔
1519
        display_data.sort(key=lambda x: x[2])
13✔
1520

1521
    headers = ['Namespace', 'Class', 'count']
13✔
1522
    rows = []
13✔
1523
    if display_data:
13✔
1524
        for item in display_data:
13✔
1525
            rows.append([item[0], item[1], item[2]])
13✔
1526

1527
    context.spinner_stop()
13✔
1528
    click.echo(format_table(rows, headers,
13✔
1529
                            title='Count of instances per class',
1530
                            table_format=output_fmt))
1531
    if error:
13✔
1532
        raise click.ClickException(
×
1533
            "Server Error {0} at namespace={1}, class:{2}. Scan incomplete."
1534
            .format(error, ns, cln))
1535

1536

1537
def cmd_instance_query(context, query, options):
13✔
1538
    """
1539
    Execute the query defined by the inputs.
1540

1541
    This commands creates a Query request based on the command input variables
1542
    and options and outputs the result in either CIM or TABLE format.
1543
    """
1544
    conn = context.pywbem_server.conn
13✔
1545
    output_fmt = validate_output_format(context.output_format, ['CIM', 'TABLE'])
13✔
1546

1547
    try:
13✔
1548
        results = conn.PyWbemcliQueryInstances(
13✔
1549
            options['query_language'],
1550
            query,
1551
            namespace=options['namespace'],
1552
            MaxObjectCount=context.pywbem_server.pull_max_cnt)
1553

1554
        display_cim_objects(
×
1555
            context, results, output_fmt, summary=options['summary'])
1556

1557
    except Error as er:
13✔
1558
        raise pywbem_error_exception(er)
13✔
1559

1560

1561
def cmd_instance_shrub(context, instancename, options):
13✔
1562
    """
1563
    Display the association information defined by instancename as a tree
1564
    showing the various steps to get through the roles, references, etc. to
1565
    return the names of associated instances.
1566
    """
1567
    conn = context.pywbem_server.conn
13✔
1568

1569
    # ns_names = get_namespaces(context, options['namespace'], default_rtn=None)
1570
    instancepath = get_instancename(context, instancename, options)
13✔
1571

1572
    try:
13✔
1573

1574
        # Collect the data for the shrub
1575
        shrub = AssociationShrub(conn, instancepath,
13✔
1576
                                 Role=options['role'],
1577
                                 AssocClass=options['assoc_class'],
1578
                                 ResultRole=options['result_role'],
1579
                                 ResultClass=options['result_class'],
1580
                                 verbose=context.verbose,
1581
                                 fullpath=options['fullpath'])
1582

1583
        # display the shrub
1584
        context.spinner_stop()
13✔
1585
        shrub.display_shrub(context.output_format, options['summary'])
13✔
1586
    except Error as er:
×
1587
        raise pywbem_error_exception(er)
×
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