From 440821b136ca6aa9152d85b34b981c171b54cd50 Mon Sep 17 00:00:00 2001 From: "Joshua M. Boniface" Date: Fri, 5 Jun 2020 14:49:53 -0400 Subject: [PATCH] Refactor cluster validation into a command wrapper Instead of using group-based validation, which breaks the help context for subcommands, use a decorator to validate the cluster status for each command. The eager help option will then override this decorator for help commands, while enforcing it for others. --- client-cli/pvc.py | 202 ++++++++++++++++++++++++---------------------- 1 file changed, 106 insertions(+), 96 deletions(-) diff --git a/client-cli/pvc.py b/client-cli/pvc.py index cffda99e..45f8b9dc 100755 --- a/client-cli/pvc.py +++ b/client-cli/pvc.py @@ -36,6 +36,8 @@ import lxml.etree as etree from distutils.util import strtobool +from functools import wraps + import cli_lib.ansiprint as ansiprint import cli_lib.cluster as pvc_cluster import cli_lib.node as pvc_node @@ -327,6 +329,15 @@ def cluster_list(): ) ) +# Validate that the cluster is set for a given command +def cluster_req(function): + @wraps(function) + def validate_cluster(*args, **kwargs): + if config.get('badcfg', None): + click.echo('No cluster specified and no local pvcapid.yaml configuration found. Use "pvc cluster" to add a cluster API to connect to.') + exit(1) + return validate_cluster + ############################################################################### # pvc node @@ -336,10 +347,6 @@ def cli_node(): """ Manage the state of a node in the PVC cluster. """ - # Abort commands under this group if config is bad - if config.get('badcfg', None): - click.echo('No cluster specified and no local pvcapid.yaml configuration found. Use "pvc cluster" to add a cluster API to connect to.') - exit(1) ############################################################################### # pvc node secondary @@ -352,6 +359,7 @@ def cli_node(): '-w', '--wait', 'wait', is_flag=True, default=False, help='Wait for transition to complete before returning.' ) +@cluster_req def node_secondary(node, wait): """ Take NODE out of primary router mode. @@ -395,6 +403,7 @@ def node_secondary(node, wait): '-w', '--wait', 'wait', is_flag=True, default=False, help='Wait for transition to complete before returning.' ) +@cluster_req def node_primary(node, wait): """ Put NODE into primary router mode. @@ -438,6 +447,7 @@ def node_primary(node, wait): @click.argument( 'node', default=myhostname ) +@cluster_req def node_flush(node, wait): """ Take NODE out of active service and migrate away all VMs. If unspecified, defaults to this host. @@ -457,6 +467,7 @@ def node_flush(node, wait): '-w', '--wait', 'wait', is_flag=True, default=False, help='Wait for migrations to complete before returning.' ) +@cluster_req def node_ready(node, wait): """ Restore NODE to active service and migrate back all VMs. If unspecified, defaults to this host. @@ -492,6 +503,7 @@ def node_unflush(node, wait): '-l', '--long', 'long_output', is_flag=True, default=False, help='Display more detailed information.' ) +@cluster_req def node_info(node, long_output): """ Show information about node NODE. If unspecified, defaults to this host. @@ -509,6 +521,7 @@ def node_info(node, long_output): @click.argument( 'limit', default=None, required=False ) +@cluster_req def node_list(limit): """ List all nodes; optionally only match names matching regex LIMIT. @@ -527,10 +540,6 @@ def cli_vm(): """ Manage the state of a virtual machine in the PVC cluster. """ - # Abort commands under this group if config is bad - if config.get('badcfg', None): - click.echo('No cluster specified and no local pvcapid.yaml configuration found. Use "pvc cluster" to add a cluster API to connect to.') - exit(1) ############################################################################### # pvc vm define @@ -556,6 +565,7 @@ def cli_vm(): @click.argument( 'vmconfig', type=click.File() ) +@cluster_req def vm_define(vmconfig, target_node, node_limit, node_selector, node_autostart): """ Define a new virtual machine from Libvirt XML configuration file VMCONFIG. @@ -599,6 +609,7 @@ def vm_define(vmconfig, target_node, node_limit, node_selector, node_autostart): @click.argument( 'domain' ) +@cluster_req def vm_meta(domain, node_limit, node_selector, node_autostart, provisioner_profile): """ Modify the PVC metadata of existing virtual machine DOMAIN. At least one option to update must be specified. DOMAIN may be a UUID or name. @@ -711,6 +722,7 @@ def vm_modify(domain, cfgfile, editor, restart): is_flag=True, default=False, help='Confirm the removal' ) +@cluster_req def vm_undefine(domain, confirm_flag): """ Stop virtual machine DOMAIN and remove it database, preserving disks. DOMAIN may be a UUID or name. @@ -736,6 +748,7 @@ def vm_undefine(domain, confirm_flag): is_flag=True, default=False, help='Confirm the removal' ) +@cluster_req def vm_remove(domain, confirm_flag): """ Stop virtual machine DOMAIN and remove it, along with all disks,. DOMAIN may be a UUID or name. @@ -756,6 +769,7 @@ def vm_remove(domain, confirm_flag): @click.argument( 'domain' ) +@cluster_req def vm_start(domain): """ Start virtual machine DOMAIN on its configured node. DOMAIN may be a UUID or name. @@ -775,6 +789,7 @@ def vm_start(domain): '-w', '--wait', 'wait', is_flag=True, default=False, help='Wait for restart to complete before returning.' ) +@cluster_req def vm_restart(domain, wait): """ Restart running virtual machine DOMAIN. DOMAIN may be a UUID or name. @@ -794,6 +809,7 @@ def vm_restart(domain, wait): '-w', '--wait', 'wait', is_flag=True, default=False, help='Wait for shutdown to complete before returning.' ) +@cluster_req def vm_shutdown(domain, wait): """ Gracefully shut down virtual machine DOMAIN. DOMAIN may be a UUID or name. @@ -809,6 +825,7 @@ def vm_shutdown(domain, wait): @click.argument( 'domain' ) +@cluster_req def vm_stop(domain): """ Forcibly halt (destroy) running virtual machine DOMAIN. DOMAIN may be a UUID or name. @@ -824,6 +841,7 @@ def vm_stop(domain): @click.argument( 'domain' ) +@cluster_req def vm_disable(domain): """ Prevent stopped virtual machine DOMAIN from being counted towards cluster health status. DOMAIN may be a UUID or name. @@ -849,6 +867,7 @@ def vm_disable(domain): '-w', '--wait', 'wait', is_flag=True, default=False, help='Wait for migration to complete before returning.' ) +@cluster_req def vm_move(domain, target_node, wait): """ Permanently move virtual machine DOMAIN, via live migration if running and possible, to another node. DOMAIN may be a UUID or name. @@ -876,6 +895,7 @@ def vm_move(domain, target_node, wait): '-w', '--wait', 'wait', is_flag=True, default=False, help='Wait for migration to complete before returning.' ) +@cluster_req def vm_migrate(domain, target_node, force_migrate, wait): """ Temporarily migrate running virtual machine DOMAIN, via live migration if possible, to another node. DOMAIN may be a UUID or name. If DOMAIN is not running, it will be started on the target node. @@ -895,6 +915,7 @@ def vm_migrate(domain, target_node, force_migrate, wait): '-w', '--wait', 'wait', is_flag=True, default=False, help='Wait for migration to complete before returning.' ) +@cluster_req def vm_unmigrate(domain, wait): """ Restore previously migrated virtual machine DOMAIN, via live migration if possible, to its original node. DOMAIN may be a UUID or name. If DOMAIN is not running, it will be started on the target node. @@ -910,6 +931,7 @@ def vm_unmigrate(domain, wait): @click.argument( 'domain' ) +@cluster_req def vm_flush_locks(domain): """ Flush stale RBD locks for virtual machine DOMAIN. DOMAIN may be a UUID or name. DOMAIN must be in a stopped state before flushing locks. @@ -933,6 +955,7 @@ def vm_flush_locks(domain): '-f', '--follow', 'follow', is_flag=True, default=False, help='Follow the log buffer; output may be delayed by a few seconds relative to the live system. The --lines value defaults to 10 for the initial output.' ) +@cluster_req def vm_log(domain, lines, follow): """ Show console logs of virtual machine DOMAIN on its current node in a pager or continuously. DOMAIN may be a UUID or name. Note that migrating a VM to a different node will cause the log buffer to be overwritten by entries from the new node. @@ -957,6 +980,7 @@ def vm_log(domain, lines, follow): '-l', '--long', 'long_output', is_flag=True, default=False, help='Display more detailed information.' ) +@cluster_req def vm_info(domain, long_output): """ Show information about virtual machine DOMAIN. DOMAIN may be a UUID or name. @@ -974,6 +998,7 @@ def vm_info(domain, long_output): @click.argument( 'domain' ) +@cluster_req def vm_dump(domain): """ Dump the Libvirt XML definition of virtual machine DOMAIN to stdout. DOMAIN may be a UUID or name. @@ -1008,6 +1033,7 @@ def vm_dump(domain): '-r', '--raw', 'raw', is_flag=True, default=False, help='Display the raw list of VM names only.' ) +@cluster_req def vm_list(target_node, target_state, limit, raw): """ List all virtual machines; optionally only match names matching regex LIMIT. @@ -1028,10 +1054,6 @@ def cli_network(): """ Manage the state of a VXLAN network in the PVC cluster. """ - # Abort commands under this group if config is bad - if config.get('badcfg', None): - click.echo('No cluster specified and no local pvcapid.yaml configuration found. Use "pvc cluster" to add a cluster API to connect to.') - exit(1) ############################################################################### # pvc network add @@ -1097,6 +1119,7 @@ def cli_network(): @click.argument( 'vni' ) +@cluster_req def net_add(vni, description, nettype, domain, ip_network, ip_gateway, ip6_network, ip6_gateway, dhcp_flag, dhcp_start, dhcp_end, name_servers): """ Add a new virtual network with VXLAN identifier VNI. @@ -1179,6 +1202,7 @@ def net_add(vni, description, nettype, domain, ip_network, ip_gateway, ip6_netwo @click.argument( 'vni' ) +@cluster_req def net_modify(vni, description, domain, name_servers, ip6_network, ip6_gateway, ip4_network, ip4_gateway, dhcp_flag, dhcp_start, dhcp_end): """ Modify details of virtual network VNI. All fields optional; only specified fields will be updated. @@ -1202,6 +1226,7 @@ def net_modify(vni, description, domain, name_servers, ip6_network, ip6_gateway, is_flag=True, default=False, help='Confirm the removal' ) +@cluster_req def net_remove(net, confirm_flag): """ Remove an existing virtual network NET; NET must be a VNI. @@ -1229,6 +1254,7 @@ def net_remove(net, confirm_flag): '-l', '--long', 'long_output', is_flag=True, default=False, help='Display more detailed information.' ) +@cluster_req def net_info(vni, long_output): """ Show information about virtual network VNI. @@ -1246,6 +1272,7 @@ def net_info(vni, long_output): @click.argument( 'limit', default=None, required=False ) +@cluster_req def net_list(limit): """ List all virtual networks; optionally only match VNIs or Descriptions matching regex LIMIT. @@ -1264,10 +1291,6 @@ def net_dhcp(): """ Manage host IPv4 DHCP leases of a VXLAN network in the PVC cluster. """ - # Abort commands under this group if config is bad - if config.get('badcfg', None): - click.echo('No cluster specified and no local pvcapid.yaml configuration found. Use "pvc cluster" to add a cluster API to connect to.') - exit(1) ############################################################################### # pvc network dhcp add @@ -1285,6 +1308,7 @@ def net_dhcp(): @click.argument( 'macaddr' ) +@cluster_req def net_dhcp_add(net, ipaddr, macaddr, hostname): """ Add a new DHCP static reservation of IP address IPADDR with hostname HOSTNAME for MAC address MACADDR to virtual network NET; NET must be a VNI. @@ -1308,6 +1332,7 @@ def net_dhcp_add(net, ipaddr, macaddr, hostname): is_flag=True, default=False, help='Confirm the removal' ) +@cluster_req def net_dhcp_remove(net, macaddr, confirm_flag): """ Remove a DHCP lease for MACADDR from virtual network NET; NET must be a VNI. @@ -1335,6 +1360,7 @@ def net_dhcp_remove(net, macaddr, confirm_flag): '-s', '--static', 'only_static', is_flag=True, default=False, help='Show only static leases.' ) +@cluster_req def net_dhcp_list(net, limit, only_static): """ List all DHCP leases in virtual network NET; optionally only match elements matching regex LIMIT; NET must be a VNI. @@ -1353,10 +1379,6 @@ def net_acl(): """ Manage firewall ACLs of a VXLAN network in the PVC cluster. """ - # Abort commands under this group if config is bad - if config.get('badcfg', None): - click.echo('No cluster specified and no local pvcapid.yaml configuration found. Use "pvc cluster" to add a cluster API to connect to.') - exit(1) ############################################################################### # pvc network acl add @@ -1386,6 +1408,7 @@ def net_acl(): @click.argument( 'net' ) +@cluster_req def net_acl_add(net, direction, description, rule, order): """ Add a new NFT firewall rule to network NET; the rule is a literal NFT rule belonging to the forward table for the client network; NET must be a VNI. @@ -1423,6 +1446,7 @@ def net_acl_add(net, direction, description, rule, order): is_flag=True, default=False, help='Confirm the removal' ) +@cluster_req def net_acl_remove(net, rule, confirm_flag): """ Remove an NFT firewall rule RULE from network NET; RULE must be a description; NET must be a VNI. @@ -1454,6 +1478,7 @@ def net_acl_remove(net, rule, confirm_flag): @click.argument( 'limit', default=None, required=False ) +@cluster_req def net_acl_list(net, limit, direction): """ List all NFT firewall rules in network NET; optionally only match elements matching description regex LIMIT; NET can be either a VNI or description. @@ -1482,15 +1507,12 @@ def cli_storage(): """ Manage the storage of the PVC cluster. """ - # Abort commands under this group if config is bad - if config.get('badcfg', None): - click.echo('No cluster specified and no local pvcapid.yaml configuration found. Use "pvc cluster" to add a cluster API to connect to.') - exit(1) ############################################################################### # pvc storage status ############################################################################### @click.command(name='status', short_help='Show storage cluster status.') +@cluster_req def ceph_status(): """ Show detailed status of the storage cluster. @@ -1505,6 +1527,7 @@ def ceph_status(): # pvc storage util ############################################################################### @click.command(name='util', short_help='Show storage cluster utilization.') +@cluster_req def ceph_util(): """ Show utilization of the storage cluster. @@ -1523,10 +1546,6 @@ def ceph_osd(): """ Manage the Ceph OSDs of the PVC cluster. """ - # Abort commands under this group if config is bad - if config.get('badcfg', None): - click.echo('No cluster specified and no local pvcapid.yaml configuration found. Use "pvc cluster" to add a cluster API to connect to.') - exit(1) ############################################################################### # pvc storage osd add @@ -1548,6 +1567,7 @@ def ceph_osd(): is_flag=True, default=False, help='Confirm the removal' ) +@cluster_req def ceph_osd_add(node, device, weight, confirm_flag): """ Add a new Ceph OSD on node NODE with block device DEVICE. @@ -1573,6 +1593,7 @@ def ceph_osd_add(node, device, weight, confirm_flag): is_flag=True, default=False, help='Confirm the removal' ) +@cluster_req def ceph_osd_remove(osdid, confirm_flag): """ Remove a Ceph OSD with ID OSDID. @@ -1595,6 +1616,7 @@ def ceph_osd_remove(osdid, confirm_flag): @click.argument( 'osdid' ) +@cluster_req def ceph_osd_in(osdid): """ Set a Ceph OSD with ID OSDID online. @@ -1610,6 +1632,7 @@ def ceph_osd_in(osdid): @click.argument( 'osdid' ) +@cluster_req def ceph_osd_out(osdid): """ Set a Ceph OSD with ID OSDID offline. @@ -1625,6 +1648,7 @@ def ceph_osd_out(osdid): @click.argument( 'osd_property' ) +@cluster_req def ceph_osd_set(osd_property): """ Set a Ceph OSD property OSD_PROPERTY on the cluster. @@ -1644,6 +1668,7 @@ def ceph_osd_set(osd_property): @click.argument( 'osd_property' ) +@cluster_req def ceph_osd_unset(osd_property): """ Unset a Ceph OSD property OSD_PROPERTY on the cluster. @@ -1663,6 +1688,7 @@ def ceph_osd_unset(osd_property): @click.argument( 'limit', default=None, required=False ) +@cluster_req def ceph_osd_list(limit): """ List all Ceph OSDs; optionally only match elements matching ID regex LIMIT. @@ -1681,10 +1707,6 @@ def ceph_pool(): """ Manage the Ceph RBD pools of the PVC cluster. """ - # Abort commands under this group if config is bad - if config.get('badcfg', None): - click.echo('No cluster specified and no local pvcapid.yaml configuration found. Use "pvc cluster" to add a cluster API to connect to.') - exit(1) ############################################################################### # pvc storage pool add @@ -1704,6 +1726,7 @@ def ceph_pool(): comma, e.g. "copies=3,mincopies=2". The "copies" value specifies the total number of replicas and should not exceed the total number of nodes; the "mincopies" value specifies the minimum number of available copies to allow writes. For additional details please see the Cluster Architecture documentation. """ ) +@cluster_req def ceph_pool_add(name, pgs, replcfg): """ Add a new Ceph RBD pool with name NAME and PGS placement groups. @@ -1725,6 +1748,7 @@ def ceph_pool_add(name, pgs, replcfg): is_flag=True, default=False, help='Confirm the removal' ) +@cluster_req def ceph_pool_remove(name, confirm_flag): """ Remove a Ceph RBD pool with name NAME and all volumes on it. @@ -1747,6 +1771,7 @@ def ceph_pool_remove(name, confirm_flag): @click.argument( 'limit', default=None, required=False ) +@cluster_req def ceph_pool_list(limit): """ List all Ceph RBD pools; optionally only match elements matching name regex LIMIT. @@ -1765,10 +1790,6 @@ def ceph_volume(): """ Manage the Ceph RBD volumes of the PVC cluster. """ - # Abort commands under this group if config is bad - if config.get('badcfg', None): - click.echo('No cluster specified and no local pvcapid.yaml configuration found. Use "pvc cluster" to add a cluster API to connect to.') - exit(1) ############################################################################### # pvc storage volume add @@ -1783,6 +1804,7 @@ def ceph_volume(): @click.argument( 'size' ) +@cluster_req def ceph_volume_add(pool, name, size): """ Add a new Ceph RBD volume with name NAME and size SIZE [in human units, e.g. 1024M, 20G, etc.] to pool POOL. @@ -1809,6 +1831,7 @@ def ceph_volume_add(pool, name, size): default='raw', show_default=True, help='The format of the source image.' ) +@cluster_req def ceph_volume_upload(pool, name, image_format, image_file): """ Upload a disk image file IMAGE_FILE to the RBD volume NAME in pool POOL. @@ -1840,6 +1863,7 @@ def ceph_volume_upload(pool, name, image_format, image_file): is_flag=True, default=False, help='Confirm the removal' ) +@cluster_req def ceph_volume_remove(pool, name, confirm_flag): """ Remove a Ceph RBD volume with name NAME from pool POOL. @@ -1868,6 +1892,7 @@ def ceph_volume_remove(pool, name, confirm_flag): @click.argument( 'size' ) +@cluster_req def ceph_volume_resize(pool, name, size): """ Resize an existing Ceph RBD volume with name NAME in pool POOL to size SIZE [in human units, e.g. 1024M, 20G, etc.]. @@ -1888,6 +1913,7 @@ def ceph_volume_resize(pool, name, size): @click.argument( 'new_name' ) +@cluster_req def ceph_volume_rename(pool, name, new_name): """ Rename an existing Ceph RBD volume with name NAME in pool POOL to name NEW_NAME. @@ -1908,6 +1934,7 @@ def ceph_volume_rename(pool, name, new_name): @click.argument( 'new_name' ) +@cluster_req def ceph_volume_clone(pool, name, new_name): """ Clone a Ceph RBD volume with name NAME in pool POOL to name NEW_NAME in pool POOL. @@ -1927,6 +1954,7 @@ def ceph_volume_clone(pool, name, new_name): default=None, show_default=True, help='Show volumes from this pool only.' ) +@cluster_req def ceph_volume_list(limit, pool): """ List all Ceph RBD volumes; optionally only match elements matching name regex LIMIT. @@ -1945,10 +1973,6 @@ def ceph_volume_snapshot(): """ Manage the Ceph RBD volume snapshots of the PVC cluster. """ - # Abort commands under this group if config is bad - if config.get('badcfg', None): - click.echo('No cluster specified and no local pvcapid.yaml configuration found. Use "pvc cluster" to add a cluster API to connect to.') - exit(1) ############################################################################### # pvc storage volume snapshot add @@ -1963,6 +1987,7 @@ def ceph_volume_snapshot(): @click.argument( 'name' ) +@cluster_req def ceph_volume_snapshot_add(pool, volume, name): """ Add a snapshot with name NAME of Ceph RBD volume VOLUME in pool POOL. @@ -1987,6 +2012,7 @@ def ceph_volume_snapshot_add(pool, volume, name): @click.argument( 'new_name' ) +@cluster_req def ceph_volume_snapshot_rename(pool, volume, name, new_name): """ Rename an existing Ceph RBD volume snapshot with name NAME to name NEW_NAME for volume VOLUME in pool POOL. @@ -2012,6 +2038,7 @@ def ceph_volume_snapshot_rename(pool, volume, name, new_name): is_flag=True, default=False, help='Confirm the removal' ) +@cluster_req def ceph_volume_snapshot_remove(pool, volume, name, confirm_flag): """ Remove a Ceph RBD volume snapshot with name NAME from volume VOLUME in pool POOL. @@ -2044,6 +2071,7 @@ def ceph_volume_snapshot_remove(pool, volume, name, confirm_flag): default=None, show_default=True, help='Show snapshots from this volume only.' ) +@cluster_req def ceph_volume_snapshot_list(pool, volume, limit): """ List all Ceph RBD volume snapshots; optionally only match elements matching name regex LIMIT. @@ -2063,10 +2091,6 @@ def cli_provisioner(): """ Manage the PVC provisioner. """ - # Abort commands under this group if config is bad - if config.get('badcfg', None): - click.echo('No cluster specified and no local pvcapid.yaml configuration found. Use "pvc cluster" to add a cluster API to connect to.') - exit(1) ############################################################################### # pvc provisioner template @@ -2076,10 +2100,6 @@ def provisioner_template(): """ Manage the PVC provisioner template system. """ - # Abort commands under this group if config is bad - if config.get('badcfg', None): - click.echo('No cluster specified and no local pvcapid.yaml configuration found. Use "pvc cluster" to add a cluster API to connect to.') - exit(1) ############################################################################### @@ -2089,6 +2109,7 @@ def provisioner_template(): @click.argument( 'limit', default=None, required=False ) +@cluster_req def provisioner_template_list(limit): """ List all templates in the PVC cluster provisioner. @@ -2106,10 +2127,6 @@ def provisioner_template_system(): """ Manage the PVC provisioner system templates. """ - # Abort commands under this group if config is bad - if config.get('badcfg', None): - click.echo('No cluster specified and no local pvcapid.yaml configuration found. Use "pvc cluster" to add a cluster API to connect to.') - exit(1) ############################################################################### # pvc provisioner template system list @@ -2118,6 +2135,7 @@ def provisioner_template_system(): @click.argument( 'limit', default=None, required=False ) +@cluster_req def provisioner_template_system_list(limit): """ List all system templates in the PVC cluster provisioner. @@ -2175,6 +2193,7 @@ def provisioner_template_system_list(limit): is_flag=True, default=False, help='Autostart VM with their parent Node on first/next boot.' ) +@cluster_req def provisioner_template_system_add(name, vcpus, vram, serial, vnc, vnc_bind, node_limit, node_selector, node_autostart): """ Add a new system template NAME to the PVC cluster provisioner. @@ -2242,6 +2261,7 @@ def provisioner_template_system_add(name, vcpus, vram, serial, vnc, vnc_bind, no is_flag=True, default=None, help='Autostart VM with their parent Node on first/next boot.' ) +@cluster_req def provisioner_template_system_modify(name, vcpus, vram, serial, vnc, vnc_bind, node_limit, node_selector, node_autostart): """ Add a new system template NAME to the PVC cluster provisioner. @@ -2271,6 +2291,7 @@ def provisioner_template_system_modify(name, vcpus, vram, serial, vnc, vnc_bind, is_flag=True, default=False, help='Confirm the removal' ) +@cluster_req def provisioner_template_system_remove(name, confirm_flag): """ Remove system template NAME from the PVC cluster provisioner. @@ -2293,10 +2314,6 @@ def provisioner_template_network(): """ Manage the PVC provisioner network templates. """ - # Abort commands under this group if config is bad - if config.get('badcfg', None): - click.echo('No cluster specified and no local pvcapid.yaml configuration found. Use "pvc cluster" to add a cluster API to connect to.') - exit(1) ############################################################################### # pvc provisioner template network list @@ -2305,6 +2322,7 @@ def provisioner_template_network(): @click.argument( 'limit', default=None, required=False ) +@cluster_req def provisioner_template_network_list(limit): """ List all network templates in the PVC cluster provisioner. @@ -2326,6 +2344,7 @@ def provisioner_template_network_list(limit): default=None, help='Use this template for MAC addresses.' ) +@cluster_req def provisioner_template_network_add(name, mac_template): """ Add a new network template to the PVC cluster provisioner. @@ -2375,6 +2394,7 @@ def provisioner_template_network_add(name, mac_template): is_flag=True, default=False, help='Confirm the removal' ) +@cluster_req def provisioner_template_network_remove(name, confirm_flag): """ Remove network template MAME from the PVC cluster provisioner. @@ -2396,10 +2416,6 @@ def provisioner_template_network_vni(): """ Manage the network VNIs in PVC provisioner network templates. """ - # Abort commands under this group if config is bad - if config.get('badcfg', None): - click.echo('No cluster specified and no local pvcapid.yaml configuration found. Use "pvc cluster" to add a cluster API to connect to.') - exit(1) ############################################################################### # pvc provisioner template network vni add @@ -2411,6 +2427,7 @@ def provisioner_template_network_vni(): @click.argument( 'vni' ) +@cluster_req def provisioner_template_network_vni_add(name, vni): """ Add a new network VNI to network template NAME. @@ -2437,6 +2454,7 @@ def provisioner_template_network_vni_add(name, vni): is_flag=True, default=False, help='Confirm the removal' ) +@cluster_req def provisioner_template_network_vni_remove(name, vni, confirm_flag): """ Remove network VNI from network template NAME. @@ -2459,10 +2477,6 @@ def provisioner_template_storage(): """ Manage the PVC provisioner storage templates. """ - # Abort commands under this group if config is bad - if config.get('badcfg', None): - click.echo('No cluster specified and no local pvcapid.yaml configuration found. Use "pvc cluster" to add a cluster API to connect to.') - exit(1) ############################################################################### # pvc provisioner template storage list @@ -2471,6 +2485,7 @@ def provisioner_template_storage(): @click.argument( 'limit', default=None, required=False ) +@cluster_req def provisioner_template_storage_list(limit): """ List all storage templates in the PVC cluster provisioner. @@ -2487,6 +2502,7 @@ def provisioner_template_storage_list(limit): @click.argument( 'name' ) +@cluster_req def provisioner_template_storage_add(name): """ Add a new storage template to the PVC cluster provisioner. @@ -2509,6 +2525,7 @@ def provisioner_template_storage_add(name): is_flag=True, default=False, help='Confirm the removal' ) +@cluster_req def provisioner_template_storage_remove(name, confirm_flag): """ Remove storage template NAME from the PVC cluster provisioner. @@ -2530,10 +2547,6 @@ def provisioner_template_storage_disk(): """ Manage the disks in PVC provisioner storage templates. """ - # Abort commands under this group if config is bad - if config.get('badcfg', None): - click.echo('No cluster specified and no local pvcapid.yaml configuration found. Use "pvc cluster" to add a cluster API to connect to.') - exit(1) ############################################################################### # pvc provisioner template storage disk add @@ -2575,6 +2588,7 @@ def provisioner_template_storage_disk(): default=None, help='The target Linux mountpoint of the disk; requires a filesystem.' ) +@cluster_req def provisioner_template_storage_disk_add(name, disk, pool, source_volume, size, filesystem, fsargs, mountpoint): """ Add a new DISK to storage template NAME. @@ -2624,6 +2638,7 @@ def provisioner_template_storage_disk_add(name, disk, pool, source_volume, size, is_flag=True, default=False, help='Confirm the removal' ) +@cluster_req def provisioner_template_storage_disk_remove(name, disk, confirm_flag): """ Remove DISK from storage template NAME. @@ -2648,10 +2663,6 @@ def provisioner_userdata(): """ Manage userdata documents in the PVC provisioner. """ - # Abort commands under this group if config is bad - if config.get('badcfg', None): - click.echo('No cluster specified and no local pvcapid.yaml configuration found. Use "pvc cluster" to add a cluster API to connect to.') - exit(1) ############################################################################### # pvc provisioner userdata list @@ -2665,6 +2676,7 @@ def provisioner_userdata(): is_flag=True, default=False, help='Show all lines of the document instead of first 4.' ) +@cluster_req def provisioner_userdata_list(limit, full): """ List all userdata documents in the PVC cluster provisioner. @@ -2685,6 +2697,7 @@ def provisioner_userdata_list(limit, full): @click.argument( 'name' ) +@cluster_req def provisioner_userdata_show(name): """ Show the full contents of userdata document NAME. @@ -2702,6 +2715,7 @@ def provisioner_userdata_show(name): @click.argument( 'filename', type=click.File() ) +@cluster_req def provisioner_userdata_add(name, filename): """ Add a new userdata document NAME from file FILENAME. @@ -2732,6 +2746,7 @@ def provisioner_userdata_add(name, filename): @click.argument( 'filename', type=click.File(), default=None, required=False ) +@cluster_req def provisioner_userdata_modify(name, filename, editor): """ Modify existing userdata document NAME, either in-editor or with replacement FILE. @@ -2798,6 +2813,7 @@ def provisioner_userdata_modify(name, filename, editor): is_flag=True, default=False, help='Confirm the removal' ) +@cluster_req def provisioner_userdata_remove(name, confirm_flag): """ Remove userdata document NAME from the PVC cluster provisioner. @@ -2820,10 +2836,6 @@ def provisioner_script(): """ Manage scripts in the PVC provisioner. """ - # Abort commands under this group if config is bad - if config.get('badcfg', None): - click.echo('No cluster specified and no local pvcapid.yaml configuration found. Use "pvc cluster" to add a cluster API to connect to.') - exit(1) ############################################################################### # pvc provisioner script list @@ -2837,6 +2849,7 @@ def provisioner_script(): is_flag=True, default=False, help='Show all lines of the document instead of first 4.' ) +@cluster_req def provisioner_script_list(limit, full): """ List all scripts in the PVC cluster provisioner. @@ -2857,6 +2870,7 @@ def provisioner_script_list(limit, full): @click.argument( 'name' ) +@cluster_req def provisioner_script_show(name): """ Show the full contents of script document NAME. @@ -2874,6 +2888,7 @@ def provisioner_script_show(name): @click.argument( 'filename', type=click.File() ) +@cluster_req def provisioner_script_add(name, filename): """ Add a new script NAME from file FILENAME. @@ -2904,6 +2919,7 @@ def provisioner_script_add(name, filename): @click.argument( 'filename', type=click.File(), default=None, required=False ) +@cluster_req def provisioner_script_modify(name, filename, editor): """ Modify existing script NAME, either in-editor or with replacement FILE. @@ -2970,6 +2986,7 @@ def provisioner_script_modify(name, filename, editor): is_flag=True, default=False, help='Confirm the removal' ) +@cluster_req def provisioner_script_remove(name, confirm_flag): """ Remove script NAME from the PVC cluster provisioner. @@ -2993,10 +3010,6 @@ def provisioner_ova(): """ Manage ovas in the PVC provisioner. """ - # Abort commands under this group if config is bad - if config.get('badcfg', None): - click.echo('No cluster specified and no local pvcapid.yaml configuration found. Use "pvc cluster" to add a cluster API to connect to.') - exit(1) ############################################################################### # pvc provisioner ova list @@ -3005,6 +3018,7 @@ def provisioner_ova(): @click.argument( 'limit', default=None, required=False ) +@cluster_req def provisioner_ova_list(limit): """ List all OVA images in the PVC cluster provisioner. @@ -3029,6 +3043,7 @@ def provisioner_ova_list(limit): required=True, help='The storage pool for the OVA images.' ) +@cluster_req def provisioner_ova_upload(name, filename, pool): """ Upload a new OVA image NAME from FILENAME. @@ -3064,6 +3079,7 @@ def provisioner_ova_upload(name, filename, pool): is_flag=True, default=False, help='Confirm the removal' ) +@cluster_req def provisioner_ova_remove(name, confirm_flag): """ Remove OVA image NAME from the PVC cluster provisioner. @@ -3086,10 +3102,6 @@ def provisioner_profile(): """ Manage profiles in the PVC provisioner. """ - # Abort commands under this group if config is bad - if config.get('badcfg', None): - click.echo('No cluster specified and no local pvcapid.yaml configuration found. Use "pvc cluster" to add a cluster API to connect to.') - exit(1) ############################################################################### # pvc provisioner profile list @@ -3098,6 +3110,7 @@ def provisioner_profile(): @click.argument( 'limit', default=None, required=False ) +@cluster_req def provisioner_profile_list(limit): """ List all profiles in the PVC cluster provisioner. @@ -3149,6 +3162,7 @@ def provisioner_profile_list(limit): default=[], multiple=True, help='Additional argument to the script install() function in key=value format.' ) +@cluster_req def provisioner_profile_add(name, profile_type, system_template, network_template, storage_template, userdata, script, ova, script_args): """ Add a new provisioner profile NAME. @@ -3209,6 +3223,7 @@ def provisioner_profile_add(name, profile_type, system_template, network_templat default=None, multiple=True, help='Additional argument to the script install() function in key=value format.' ) +@cluster_req def provisioner_profile_modify(name, system_template, network_template, storage_template, userdata, script, delete_script_args, script_args): """ Modify existing provisioner profile NAME. @@ -3244,6 +3259,7 @@ def provisioner_profile_modify(name, system_template, network_template, storage_ is_flag=True, default=False, help='Confirm the removal' ) +@cluster_req def provisioner_profile_remove(name, confirm_flag): """ Remove profile NAME from the PVC cluster provisioner. @@ -3283,6 +3299,7 @@ def provisioner_profile_remove(name, confirm_flag): is_flag=True, default=False, help='Wait for provisioning to complete, showing progress' ) +@cluster_req def provisioner_create(name, profile, wait_flag, define_flag, start_flag): """ Create a new VM NAME with profile PROFILE. @@ -3355,6 +3372,7 @@ def provisioner_create(name, profile, wait_flag, define_flag, start_flag): @click.argument( 'job', required=False, default=None ) +@cluster_req def provisioner_status(job): """ Show status of provisioner job JOB or a list of jobs. @@ -3373,15 +3391,12 @@ def cli_maintenance(): """ Manage the maintenance mode of the PVC cluster. """ - # Abort commands under this group if config is bad - if config.get('badcfg', None): - click.echo('No cluster specified and no local pvcapid.yaml configuration found. Use "pvc cluster" to add a cluster API to connect to.') - exit(1) ############################################################################### # pvc maintenance on ############################################################################### @click.command(name='on', short_help='Enable cluster maintenance mode.') +@cluster_req def maintenance_on(): """ Enable maintenance mode on the PVC cluster. @@ -3393,6 +3408,7 @@ def maintenance_on(): # pvc maintenance off ############################################################################### @click.command(name='off', short_help='Disable cluster maintenance mode.') +@cluster_req def maintenance_off(): """ Disable maintenance mode on the PVC cluster. @@ -3410,14 +3426,11 @@ def maintenance_off(): type=click.Choice(['plain', 'json', 'json-pretty']), help='Output format of cluster status information.' ) +@cluster_req def status_cluster(oformat): """ Show basic information and health for the active PVC cluster. """ - # Abort commands under this group if config is bad - if config.get('badcfg', None): - click.echo('No cluster specified and no local pvcapid.yaml configuration found. Use "pvc cluster" to add a cluster API to connect to.') - exit(1) retcode, retdata = pvc_cluster.get_info(config) if retcode: @@ -3433,14 +3446,11 @@ def status_cluster(oformat): is_flag=True, default=False, help='Confirm the removal' ) +@cluster_req def init_cluster(confirm_flag): """ Perform initialization of a new PVC cluster. """ - # Abort commands under this group if config is bad - if config.get('badcfg', None): - click.echo('No cluster specified and no local pvcapid.yaml configuration found. Use "pvc cluster" to add a cluster API to connect to.') - exit(1) if not confirm_flag: try: