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

zhmcclient / zhmccli / 2051610447 / 12

Source File

20.9
/zhmccli/_cmd_user_role.py
1
# Copyright 2021 IBM Corp. All Rights Reserved.
2
#
3
# Licensed under the Apache License, Version 2.0 (the "License");
4
# you may not use this file except in compliance with the License.
5
# You may obtain a copy of the License at
6
#
7
#    http://www.apache.org/licenses/LICENSE-2.0
8
#
9
# Unless required by applicable law or agreed to in writing, software
10
# distributed under the License is distributed on an "AS IS" BASIS,
11
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
# See the License for the specific language governing permissions and
13
# limitations under the License.
14

15
"""
1✔
16
Commands for HMC user role management.
17
"""
18

19
from __future__ import absolute_import
1✔
20
from __future__ import print_function
1✔
21

22
import re
1✔
23

24
import click
1✔
25

26
import zhmcclient
1✔
27
from .zhmccli import cli
1✔
28
from ._helper import print_properties, print_resources, abort_if_false, \
1✔
29
    options_to_properties, original_options, COMMAND_OPTIONS_METAVAR, \
30
    click_exception, add_options, LIST_OPTIONS, ObjectByUriCache
31

32

33
PERMISSION_OPTIONS = [
1✔
34
    click.option('--task', type=str, metavar='TASK', required=False,
35
                 help='Permission: Task permission to the task with the '
36
                 'specified name.'),
37
    click.option('--view-only', type=bool, required=False,
38
                 help='If --task was specified, indicates whether the task\'s '
39
                 'view-only version is subject of the permission. Only certain '
40
                 'tasks have a view-only version. Default: True.'),
41
    click.option('--class', type=str, metavar='CLASS', required=False,
42
                 help='Permission: Object permission to all objects of the '
43
                 'specified resource class (= value of "class" property).'),
44
    click.option('--group', type=str, metavar='GROUP', required=False,
45
                 help='Permission: Object permission to the group with the '
46
                 'specified name and optionally to its members.'),
47
    click.option('--include-members', type=bool, required=False,
48
                 help='If --group was specified, indicates whether the group '
49
                 'members are included in the permission. Default: False.'),
50
    click.option('--cpc', type=str, metavar='CPC', required=False,
51
                 help='Permission: Object permission to the CPC with the '
52
                 'specified name.'),
53
    click.option('--partition', type=str,
54
                 metavar='CPC PARTITION', nargs=2, required=False,
55
                 help='Permission: Object permission to the partition on the '
56
                 'CPC with the specified names.'),
57
    click.option('--lpar', type=str,
58
                 metavar='CPC LPAR', nargs=2, required=False,
59
                 help='Permission: Object permission to the LPAR on the CPC '
60
                 'with the specified names.'),
61
    click.option('--adapter', type=str,
62
                 metavar='CPC ADAPTER', nargs=2, required=False,
63
                 help='Permission: Object permission to the adapter on the CPC '
64
                 'with the specified names.'),
65
    click.option('--storage-group', type=str,
66
                 metavar='CPC STORAGEGROUP', nargs=2, required=False,
67
                 help='Permission: Object permission to the storage group '
68
                 'associated with the CPC with the specified names.'),
69
    click.option('--storage-group-template', type=str,
70
                 metavar='CPC STORAGEGROUPTEMPLATE', nargs=2, required=False,
71
                 help='Permission: Object permission to the storage group '
72
                 'template associated with the CPC with the specified names.'),
73
]
74

75

76
def find_user_role(cmd_ctx, console, user_role_name):
1✔
77
    """
78
    Find a user role by name and return its resource object.
79
    """
80
    try:
×
81
        user_role = console.user_roles.find(name=user_role_name)
×
82
    except zhmcclient.Error as exc:
×
83
        raise click_exception(exc, cmd_ctx.error_format)
×
84
    return user_role
×
85

86

87
def permission_str(obj_cache, permission_info):
1✔
88
    """
89
    Return a permission-info item as a string for displaying
90
    """
91
    obj = permission_info['permitted-object']
×
92
    obj_type = permission_info['permitted-object-type']
×
93
    if obj_type == 'object-class':
×
94
        perm_str = 'class {}'.format(obj)
×
95
    else:
96
        assert obj_type == 'object'
×
97
        if obj.startswith('/api/console/tasks/'):
×
98
            task = obj_cache.task_by_uri(obj)
×
99
            perm_str = "task '{}'".format(task.name)
×
100
        elif obj.startswith('/api/groups/'):
×
101
            # TODO: Display name, once zhmcclient.Group implemented
102
            # group = obj_cache.group_by_uri(obj)
103
            # perm_str = "group '{}'".format(group.name)
104
            perm_str = "group '{}'".format(obj)
×
105
        elif re.match(r'^/api/cpcs/[^/]+/adapters/[^/]+$', obj):
×
106
            adapter = obj_cache.adapter_by_uri(obj)
×
107
            cpc = adapter.manager.parent
×
108
            perm_str = "adapter '{}' on cpc '{}'". \
×
109
                format(adapter.name, cpc.name)
110
        elif re.match(r'^/api/cpcs/[^/]+/lpars/[^/]+$', obj):
×
111
            lpar = obj_cache.lpar_by_uri(obj)
×
112
            cpc = lpar.manager.parent
×
113
            perm_str = "lpar '{}' on cpc '{}'". \
×
114
                format(lpar.name, cpc.name)
115
        elif re.match(r'^/api/cpcs/[^/]+/partitions/[^/]+$', obj):
×
116
            partition = obj_cache.partition_by_uri(obj)
×
117
            cpc = partition.manager.parent
×
118
            perm_str = "partition '{}' on cpc '{}'". \
×
119
                format(partition.name, cpc.name)
120
        elif re.match(r'^/api/cpcs/[^/]+$', obj):
×
121
            cpc = obj_cache.cpc_by_uri(obj)
×
122
            perm_str = "cpc '{}'".format(cpc.name)
×
123
        elif re.match(r'^/api/storage-groups/[^/]+$', obj):
×
124
            storage_group = obj_cache.storage_group_by_uri(obj)
×
125
            cpc = storage_group.cpc
×
126
            perm_str = "storage group '{}' associated with cpc '{}'". \
×
127
                format(storage_group.name, cpc.name)
128
        elif re.match(r'^/api/storage-templates/[^/]+$', obj):
×
129
            # TODO: Display name, once zhmcclient list templates implemented
130
            # perm_str = "group '{}'".format(obj)
131
            # storage_template = obj_cache.storage_template_by_uri(obj)
132
            # cpc = storage_template.cpc
133
            # perm_str = "storage group template '{}' assoc. with cpc '{}'". \
134
            #     format(storage_template.name, cpc.name)
135
            perm_str = "storage group template '{}'".format(obj)
×
136
        else:
137
            perm_str = 'object {}'.format(obj)
×
138
    return perm_str
×
139

140

141
def permission_options_to_kwargs(cmd_ctx, client, options):
1✔
142
    """
143
    Convert the permission options to a kwargs dict of arguments for the
144
    respective zhmcclient methods.
145
    """
146
    opts = dict(options)
×
147
    kwargs = {}
×
148
    kwargs['include_members'] = options.pop('include_members')
×
149
    kwargs['view_only'] = options.pop('view_only')
×
150
    num_options = \
×
151
        bool(opts['task']) + \
152
        bool(opts['class']) + \
153
        bool(opts['group']) + \
154
        bool(opts['cpc']) + \
155
        bool(opts['partition']) + \
156
        bool(opts['adapter']) + \
157
        bool(opts['storage_group']) + \
158
        bool(opts['storage_group_template'])
159

160
    if num_options > 1:
×
161
        raise click.ClickException(
×
162
            "More than one permission option specified: {}".
163
            format(', '.join(opts.keys())))
164

165
    if opts['task']:
×
166
        raise NotImplementedError  # pylint: disable=no-else-raise
×
167
        # TODO: Implement once zhmccli task is implemented
168
        # # pylint: disable=import-outside-toplevel,cyclic-import
169
        # from ._cmd_task import find_task
170
        # task_name = opts['task']
171
        # task = find_task(cmd_ctx, client, task_name)
172
        # kwargs['permitted_object'] = task
173
    if opts['class']:
×
174
        class_name = opts['class']
×
175
        kwargs['permitted_object'] = class_name
×
176
    elif opts['group']:
×
177
        raise NotImplementedError  # pylint: disable=no-else-raise
×
178
        # TODO: Implement once zhmcclient.Group is implemented
179
        # # pylint: disable=import-outside-toplevel,cyclic-import
180
        # from ._cmd_group import find_group
181
        # group_name = opts['group']
182
        # group = find_group(cmd_ctx, client, group_name)
183
        # kwargs['permitted_object'] = group
184
    elif opts['cpc']:
×
185
        # pylint: disable=import-outside-toplevel,cyclic-import
186
        from ._cmd_cpc import find_cpc
×
187
        cpc_name = opts['cpc']
×
188
        cpc = find_cpc(cmd_ctx, client, cpc_name)
×
189
        kwargs['permitted_object'] = cpc
×
190
    elif opts['partition']:
×
191
        # pylint: disable=import-outside-toplevel,cyclic-import
192
        from ._cmd_partition import find_partition
×
193
        cpc_name, partition_name = opts['partition']
×
194
        partition = find_partition(cmd_ctx, client, cpc_name, partition_name)
×
195
        kwargs['permitted_object'] = partition
×
196
    elif opts['adapter']:
×
197
        # pylint: disable=import-outside-toplevel,cyclic-import
198
        from ._cmd_adapter import find_adapter
×
199
        cpc_name, adapter_name = opts['adapter']
×
200
        adapter = find_adapter(cmd_ctx, client, cpc_name, adapter_name)
×
201
        kwargs['permitted_object'] = adapter
×
202
    elif opts['storage_group']:
×
203
        # pylint: disable=import-outside-toplevel,cyclic-import
204
        from ._cmd_storagegroup import find_storagegroup
×
205
        cpc_name, stogrp_name = opts['storage_group']
×
206
        # TODO: Fix find_storagegroup() to take cpc_name
207
        stogrp = find_storagegroup(cmd_ctx, client, stogrp_name)
×
208
        kwargs['permitted_object'] = stogrp
×
209
    elif opts['storage_group_template']:
×
210
        raise NotImplementedError  # pylint: disable=no-else-raise
×
211
        # TODO: Implement once zhmccli storage-group-template is implemented
212
        # # pylint: disable=import-outside-toplevel,cyclic-import
213
        # from ._cmd_storagegrouptemplate import find_storagegrouptemplate
214
        # cpc_name, stogrptpl_name = opts['storage_group_template']
215
        # stogrptpl = find_storagegrouptemplate(
216
        #     cmd_ctx, client, cpc_name, stogrptpl_name)
217
        # kwargs['permitted_object'] = stogrptpl
218
    else:
219
        raise click.ClickException("No permission option specified.")
×
220

221
    return kwargs
×
222

223

224
@cli.group('userrole', options_metavar=COMMAND_OPTIONS_METAVAR)
1✔
225
def user_role_group():
226
    """
227
    Command group for managing HMC user roles.
228

229
    In addition to the command-specific options shown in this help text, the
230
    general options (see 'zhmc --help') can also be specified right after the
231
    'zhmc' command name.
232
    """
233

234

235
@user_role_group.command('list', options_metavar=COMMAND_OPTIONS_METAVAR)
1✔
236
@add_options(LIST_OPTIONS)
1✔
237
@click.option('--permissions', is_flag=True, required=False,
1✔
238
              help='Show additional properties for user role permissions.')
239
@click.pass_obj
1✔
240
def user_role_list(cmd_ctx, **options):
241
    """
242
    List the HMC user roles.
243

244
    In addition to the command-specific options shown in this help text, the
245
    general options (see 'zhmc --help') can also be specified right after the
246
    'zhmc' command name.
247
    """
248
    cmd_ctx.execute_cmd(lambda: cmd_user_role_list(cmd_ctx, options))
×
249

250

251
@user_role_group.command('show', options_metavar=COMMAND_OPTIONS_METAVAR)
1✔
252
@click.argument('USER_ROLE', type=str, metavar='USER_ROLE')
1✔
253
@click.pass_obj
1✔
254
def user_role_show(cmd_ctx, user_role):
255
    """
256
    Show the details of an HMC user role.
257

258
    In addition to the command-specific options shown in this help text, the
259
    general options (see 'zhmc --help') can also be specified right after the
260
    'zhmc' command name.
261
    """
262
    cmd_ctx.execute_cmd(lambda: cmd_user_role_show(cmd_ctx, user_role))
×
263

264

265
@user_role_group.command('create', options_metavar=COMMAND_OPTIONS_METAVAR)
1✔
266
@click.option('--name', type=str, required=True,
1✔
267
              help='The name of the new user role.')
268
@click.option('--description', type=str, required=False,
1✔
269
              help='The description of the new user role.')
270
@click.option('--associated-system-defined-user-role', type=str, required=False,
1✔
271
              help='The system-defined user role associated with the new '
272
              'user role. '
273
              'Default: Operator Tasks')
274
@click.option('--is-inheritance-enabled', type=bool, required=False,
1✔
275
              help='The indicator whether user role inheritance is enabled for '
276
              'the new user role. '
277
              'When enabled, if the user role permits access to a parent '
278
              'managed object, then all managed objects that are hosted by the '
279
              'parent managed object are also permitted by this role. '
280
              'Default: False')
281
@click.pass_obj
1✔
282
def user_role_create(cmd_ctx, **options):
283
    """
284
    Create a user-defined HMC user role.
285

286
    In addition to the command-specific options shown in this help text, the
287
    general options (see 'zhmc --help') can also be specified right after the
288
    'zhmc' command name.
289
    """
290
    cmd_ctx.execute_cmd(lambda: cmd_user_role_create(cmd_ctx, options))
×
291

292

293
@user_role_group.command('update', options_metavar=COMMAND_OPTIONS_METAVAR)
1✔
294
@click.argument('USER_ROLE', type=str, metavar='USER_ROLE')
1✔
295
@click.option('--description', type=str, required=False,
1✔
296
              help='The new description of the user role.')
297
@click.option('--associated-system-defined-user-role', type=str, required=False,
1✔
298
              help='The new system-defined user role associated with the '
299
              'user role.')
300
@click.option('--is-inheritance-enabled', type=bool, required=False,
1✔
301
              help='The new indicator whether user role inheritance is '
302
              'enabled for the user role. '
303
              'When enabled, if the user role permits access to a parent '
304
              'managed object, then all managed objects that are hosted by the '
305
              'parent managed object are also permitted by this role.')
306
@click.pass_obj
1✔
307
def user_role_update(cmd_ctx, user_role, **options):
308
    """
309
    Update the properties of an HMC user role.
310

311
    Note that HMC user roles cannot be renamed.
312

313
    Only the properties will be changed for which a corresponding option is
314
    specified, so the default for all options is not to change properties.
315

316
    In addition to the command-specific options shown in this help text, the
317
    general options (see 'zhmc --help') can also be specified right after the
318
    'zhmc' command name.
319
    """
320
    cmd_ctx.execute_cmd(lambda: cmd_user_role_update(
×
321
        cmd_ctx, user_role, options))
322

323

324
@user_role_group.command('delete', options_metavar=COMMAND_OPTIONS_METAVAR)
1✔
325
@click.argument('USER_ROLE', type=str, metavar='USER_ROLE')
1✔
326
@click.option('-y', '--yes', is_flag=True, callback=abort_if_false,
1✔
327
              expose_value=False,
328
              help='Skip prompt to confirm deletion of the user role.',
329
              prompt='Are you sure you want to delete this user role ?')
330
@click.pass_obj
1✔
331
def user_role_delete(cmd_ctx, user_role):
332
    """
333
    Delete a user-defined HMC user role.
334

335
    In addition to the command-specific options shown in this help text, the
336
    general options (see 'zhmc --help') can also be specified right after the
337
    'zhmc' command name.
338
    """
339
    cmd_ctx.execute_cmd(lambda: cmd_user_role_delete(cmd_ctx, user_role))
×
340

341

342
@user_role_group.command('add-permission',
1✔
343
                         options_metavar=COMMAND_OPTIONS_METAVAR)
344
@click.argument('USER_ROLE', type=str, metavar='USER_ROLE')
1✔
345
@add_options(PERMISSION_OPTIONS)
1✔
346
@click.pass_obj
1✔
347
def user_role_add_permission(cmd_ctx, user_role, **options):
348
    """
349
    Add a permission to a user-defined HMC user role.
350

351
    The permission is specified by exactly one of the permission options,
352
    and optionally the --view-only or --include-members options.
353

354
    In addition to the command-specific options shown in this help text, the
355
    general options (see 'zhmc --help') can also be specified right after the
356
    'zhmc' command name.
357
    """
358
    cmd_ctx.execute_cmd(lambda: cmd_user_role_add_permission(
×
359
        cmd_ctx, user_role, options))
360

361

362
@user_role_group.command('remove-permission',
1✔
363
                         options_metavar=COMMAND_OPTIONS_METAVAR)
364
@click.argument('USER_ROLE', type=str, metavar='USER_ROLE')
1✔
365
@add_options(PERMISSION_OPTIONS)
1✔
366
@click.pass_obj
1✔
367
def user_role_remove_permission(cmd_ctx, user_role, **options):
368
    """
369
    Remove a permission from a user-defined HMC user role.
370

371
    The permission is specified by exactly one of the permission options,
372
    and optionally the --view-only or --include-members options.
373

374
    In addition to the command-specific options shown in this help text, the
375
    general options (see 'zhmc --help') can also be specified right after the
376
    'zhmc' command name.
377
    """
378
    cmd_ctx.execute_cmd(lambda: cmd_user_role_remove_permission(
×
379
        cmd_ctx, user_role, options))
380

381

382
def cmd_user_role_list(cmd_ctx, options):
1✔
383
    # pylint: disable=missing-function-docstring
384

385
    client = zhmcclient.Client(cmd_ctx.session)
×
386
    console = client.consoles.console
×
387

388
    show_list = [
×
389
        'name',
390
    ]
391
    if not options['names_only']:
×
392
        show_list.extend([
×
393
            'type',
394
            'description',
395
        ])
396
    if options['uri']:
×
397
        show_list.extend([
×
398
            'object-uri',
399
        ])
400
    if options['permissions']:
×
401
        show_list.extend([
×
402
            'permissions',
403
            'is-inheritance-enabled',
404
        ])
405

406
    additions = {}
×
407
    additions['permissions'] = {}
×
408

409
    try:
×
410
        user_roles = console.user_roles.list(full_properties=False)
×
411
    except zhmcclient.Error as exc:
×
412
        raise click_exception(exc, cmd_ctx.error_format)
×
413

414
    if options['permissions']:
×
415
        obj_cache = ObjectByUriCache(cmd_ctx, client)
×
416
        for role in user_roles:
×
417
            permissions = []
×
418
            for item in role.get_property('permissions'):
×
419
                permissions.append(permission_str(obj_cache, item))
×
420
            additions['permissions'][role.uri] = permissions
×
421

422
    try:
×
423
        print_resources(cmd_ctx, user_roles, cmd_ctx.output_format, show_list,
×
424
                        additions, all=options['all'])
425
    except zhmcclient.Error as exc:
×
426
        raise click_exception(exc, cmd_ctx.error_format)
×
427

428

429
def cmd_user_role_show(cmd_ctx, user_role_name):
1✔
430
    # pylint: disable=missing-function-docstring
431

432
    client = zhmcclient.Client(cmd_ctx.session)
×
433
    console = client.consoles.console
×
434
    user_role = find_user_role(cmd_ctx, console, user_role_name)
×
435

436
    try:
×
437
        user_role.pull_full_properties()
×
438
    except zhmcclient.Error as exc:
×
439
        raise click_exception(exc, cmd_ctx.error_format)
×
440

441
    properties = dict(user_role.properties)
×
442

443
    # Replace property 'permissions' with artificial property
444

445
    obj_cache = ObjectByUriCache(cmd_ctx, client)
×
446
    permissions = []
×
447
    for item in user_role.properties['permissions']:
×
448
        permissions.append(permission_str(obj_cache, item))
×
449
    properties['permissions'] = permissions
×
450

451
    print_properties(cmd_ctx, properties, cmd_ctx.output_format)
×
452

453

454
def cmd_user_role_create(cmd_ctx, options):
1✔
455
    # pylint: disable=missing-function-docstring
456

457
    client = zhmcclient.Client(cmd_ctx.session)
×
458
    console = client.consoles.console
×
459

460
    org_options = original_options(options)
×
461

462
    name_map = {
×
463
        'associated-system-defined-user-role': None,
464
    }
465

466
    properties = options_to_properties(org_options, name_map)
×
467

468
    if org_options['associated-system-defined-user-role'] == '':
×
469
        properties['associated-system-defined-user-role-uri'] = None
×
470
    else:
471
        try:
×
472
            role = console.user_roles.find_by_name(
×
473
                org_options['associated-system-defined-user-role'])
474
        except zhmcclient.Error as exc:
×
475
            raise click_exception(exc, cmd_ctx.error_format)
×
476
        properties['associated-system-defined-user-role-uri'] = role.uri
×
477

478
    try:
×
479
        new_user_role = console.user_roles.create(properties)
×
480
    except zhmcclient.Error as exc:
×
481
        raise click_exception(exc, cmd_ctx.error_format)
×
482

483
    cmd_ctx.spinner.stop()
×
484
    click.echo("New user role '{u}' has been created.".
×
485
               format(u=new_user_role.properties['name']))
486

487

488
def cmd_user_role_update(cmd_ctx, user_role_name, options):
1✔
489
    # pylint: disable=missing-function-docstring
490

491
    client = zhmcclient.Client(cmd_ctx.session)
×
492
    console = client.consoles.console
×
493
    user_role = find_user_role(cmd_ctx, console, user_role_name)
×
494

495
    org_options = original_options(options)
×
496

497
    name_map = {
×
498
        'associated-system-defined-user-role': None,
499
    }
500

501
    properties = options_to_properties(org_options, name_map)
×
502

503
    if org_options['associated-system-defined-user-role'] == '':
×
504
        properties['associated-system-defined-user-role-uri'] = None
×
505
    else:
506
        try:
×
507
            role = console.user_roles.find_by_name(
×
508
                org_options['associated-system-defined-user-role'])
509
        except zhmcclient.Error as exc:
×
510
            raise click_exception(exc, cmd_ctx.error_format)
×
511
        properties['associated-system-defined-user-role-uri'] = role.uri
×
512

513
    if not properties:
×
514
        cmd_ctx.spinner.stop()
×
515
        click.echo("No properties specified for updating user role '{u}'.".
×
516
                   format(u=user_role_name))
517
        return
×
518

519
    try:
×
520
        user_role.update_properties(properties)
×
521
    except zhmcclient.Error as exc:
×
522
        raise click_exception(exc, cmd_ctx.error_format)
×
523

524
    cmd_ctx.spinner.stop()
×
525
    click.echo("User role '{u}' has been updated.".format(u=user_role_name))
×
526

527

528
def cmd_user_role_delete(cmd_ctx, user_role_name):
1✔
529
    # pylint: disable=missing-function-docstring
530

531
    client = zhmcclient.Client(cmd_ctx.session)
×
532
    console = client.consoles.console
×
533
    user_role = find_user_role(cmd_ctx, console, user_role_name)
×
534

535
    try:
×
536
        user_role.delete()
×
537
    except zhmcclient.Error as exc:
×
538
        raise click_exception(exc, cmd_ctx.error_format)
×
539

540
    cmd_ctx.spinner.stop()
×
541
    click.echo("User role '{u}' has been deleted.".format(u=user_role_name))
×
542

543

544
def cmd_user_role_add_permission(cmd_ctx, user_role_name, options):
1✔
545
    # pylint: disable=missing-function-docstring
546

547
    client = zhmcclient.Client(cmd_ctx.session)
×
548
    console = client.consoles.console
×
549
    user_role = find_user_role(cmd_ctx, console, user_role_name)
×
550

551
    kwargs = permission_options_to_kwargs(cmd_ctx, client, options)
×
552

553
    try:
×
554
        user_role.add_permission(**kwargs)
×
555
    except zhmcclient.Error as exc:
×
556
        raise click_exception(exc, cmd_ctx.error_format)
×
557

558
    cmd_ctx.spinner.stop()
×
559
    click.echo("The permission has been added to user role '{r}'.".
×
560
               format(r=user_role_name))
561

562

563
def cmd_user_role_remove_permission(cmd_ctx, user_role_name, options):
1✔
564
    # pylint: disable=missing-function-docstring
565

566
    client = zhmcclient.Client(cmd_ctx.session)
×
567
    console = client.consoles.console
×
568
    user_role = find_user_role(cmd_ctx, console, user_role_name)
×
569

570
    kwargs = permission_options_to_kwargs(cmd_ctx, client, options)
×
571

572
    try:
×
573
        user_role.remove_permission(**kwargs)
×
574
    except zhmcclient.Error as exc:
×
575
        raise click_exception(exc, cmd_ctx.error_format)
×
576

577
    cmd_ctx.spinner.stop()
×
578
    click.echo("The permission has been removed from user role '{r}'.".
×
579
               format(r=user_role_name))
  • Back to Build 2051610447
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

© 2025 Coveralls, Inc