Revamp tag handling and display

Add an additional protected class, limit manipulation to one at a time,
and ensure future flexibility. Also makes display consistent with other
VM elements.
This commit is contained in:
2021-07-13 19:04:56 -04:00
parent 27f1758791
commit 9ea9ac3b8a
8 changed files with 432 additions and 62 deletions

View File

@ -892,6 +892,22 @@ class API_VM_Root(Resource):
migration_method:
type: string
description: The preferred migration method (live, shutdown, none)
tags:
type: array
description: The tag(s) of the VM
items:
type: object
id: VMTag
properties:
name:
type: string
description: The name of the tag
type:
type: string
description: The type of the tag (user, system)
protected:
type: boolean
description: Whether the tag is protected or not
description:
type: string
description: The description of the VM
@ -1107,7 +1123,8 @@ class API_VM_Root(Resource):
{'name': 'selector', 'choices': ('mem', 'vcpus', 'load', 'vms', 'none'), 'helptext': "A valid selector must be specified"},
{'name': 'autostart'},
{'name': 'migration_method', 'choices': ('live', 'shutdown', 'none'), 'helptext': "A valid migration_method must be specified"},
{'name': 'tags'},
{'name': 'user_tags', 'action': 'append'},
{'name': 'protected_tags', 'action': 'append'},
{'name': 'xml', 'required': True, 'helptext': "A Libvirt XML document must be specified"},
])
@Authenticator
@ -1160,10 +1177,17 @@ class API_VM_Root(Resource):
- shutdown
- none
- in: query
name: tags
name: user_tags
type: array
required: false
description: The tag(s) of the VM
description: The user tag(s) of the VM
items:
type: string
- in: query
name: protected_tags
type: array
required: false
description: The protected user tag(s) of the VM
items:
type: string
responses:
@ -1178,6 +1202,13 @@ class API_VM_Root(Resource):
type: object
id: Message
"""
user_tags = reqargs.get('user_tags', None)
if user_tags is None:
user_tags = []
protected_tags = reqargs.get('protected_tags', None)
if protected_tags is None:
protected_tags = []
return api_helper.vm_define(
reqargs.get('xml'),
reqargs.get('node', None),
@ -1185,7 +1216,8 @@ class API_VM_Root(Resource):
reqargs.get('selector', 'none'),
bool(strtobool(reqargs.get('autostart', 'false'))),
reqargs.get('migration_method', 'none'),
reqargs.get('tags', [])
user_tags,
protected_tags
)
@ -1220,7 +1252,8 @@ class API_VM_Element(Resource):
{'name': 'selector', 'choices': ('mem', 'vcpus', 'load', 'vms', 'none'), 'helptext': "A valid selector must be specified"},
{'name': 'autostart'},
{'name': 'migration_method', 'choices': ('live', 'shutdown', 'none'), 'helptext': "A valid migration_method must be specified"},
{'name': 'tags'},
{'name': 'user_tags', 'action': 'append'},
{'name': 'protected_tags', 'action': 'append'},
{'name': 'xml', 'required': True, 'helptext': "A Libvirt XML document must be specified"},
])
@Authenticator
@ -1276,10 +1309,17 @@ class API_VM_Element(Resource):
- shutdown
- none
- in: query
name: tags
name: user_tags
type: array
required: false
description: The tag(s) of the VM
description: The user tag(s) of the VM
items:
type: string
- in: query
name: protected_tags
type: array
required: false
description: The protected user tag(s) of the VM
items:
type: string
responses:
@ -1294,6 +1334,13 @@ class API_VM_Element(Resource):
type: object
id: Message
"""
user_tags = reqargs.get('user_tags', None)
if user_tags is None:
user_tags = []
protected_tags = reqargs.get('protected_tags', None)
if protected_tags is None:
protected_tags = []
return api_helper.vm_define(
reqargs.get('xml'),
reqargs.get('node', None),
@ -1301,7 +1348,8 @@ class API_VM_Element(Resource):
reqargs.get('selector', 'none'),
bool(strtobool(reqargs.get('autostart', 'false'))),
reqargs.get('migration_method', 'none'),
reqargs.get('tags', [])
user_tags,
protected_tags
)
@RequestParser([
@ -1529,7 +1577,8 @@ class API_VM_Tags(Resource):
type: array
description: The tag(s) of the VM
items:
type: string
type: object
id: VMTag
404:
description: VM not found
schema:
@ -1539,8 +1588,9 @@ class API_VM_Tags(Resource):
return api_helper.get_vm_tags(vm)
@RequestParser([
{'name': 'action', 'choices': ('add', 'remove', 'replace'), 'helptext': "A valid action must be specified"},
{'name': 'tags'},
{'name': 'action', 'choices': ('add', 'remove'), 'helptext': "A valid action must be specified"},
{'name': 'tag'},
{'name': 'protected'}
])
@Authenticator
def post(self, vm, reqargs):
@ -1554,18 +1604,21 @@ class API_VM_Tags(Resource):
name: action
type: string
required: true
description: The action to perform with the tags, either "add" to existing, "remove" from existing, or "replace" all existing
description: The action to perform with the tag
enum:
- add
- remove
- replace
- in: query
name: tags
type: array
name: tag
type: string
required: true
description: The list of text tags to add/remove/replace-with
items:
type: string
description: The text value of the tag
- in: query
name: protected
type: boolean
required: false
default: false
description: Set the protected state of the tag
responses:
200:
description: OK
@ -1583,10 +1636,11 @@ class API_VM_Tags(Resource):
type: object
id: Message
"""
return api_helper.update_vm_tags(
return api_helper.update_vm_tag(
vm,
reqargs.get('action'),
reqargs.get('tags')
reqargs.get('tag'),
reqargs.get('protected', False)
)

View File

@ -433,7 +433,7 @@ def vm_list(zkhandler, node=None, state=None, limit=None, is_fuzzy=True):
@ZKConnection(config)
def vm_define(zkhandler, xml, node, limit, selector, autostart, migration_method, tags=[]):
def vm_define(zkhandler, xml, node, limit, selector, autostart, migration_method, user_tags=[], protected_tags=[]):
"""
Define a VM from Libvirt XML in the PVC cluster.
"""
@ -444,6 +444,12 @@ def vm_define(zkhandler, xml, node, limit, selector, autostart, migration_method
except Exception as e:
return {'message': 'XML is malformed or incorrect: {}'.format(e)}, 400
tags = list()
for tag in user_tags:
tags.append({'name': tag, 'type': 'user', 'protected': False})
for tag in protected_tags:
tags.append({'name': tag, 'type': 'user', 'protected': True})
retflag, retdata = pvc_vm.define_vm(zkhandler, new_cfg, node, limit, selector, autostart, migration_method, profile=None, tags=tags)
if retflag:
@ -530,18 +536,18 @@ def get_vm_tags(zkhandler, vm):
@ZKConnection(config)
def update_vm_tags(zkhandler, vm, action, tags):
def update_vm_tag(zkhandler, vm, action, tag, protected=False):
"""
Update the tags of a VM.
Update a tag of a VM.
"""
if action not in ['add', 'remove', 'replace']:
return {"message": "Tag action must be one of 'add', 'remove', 'replace'."}, 400
if action not in ['add', 'remove']:
return {"message": "Tag action must be one of 'add', 'remove'."}, 400
dom_uuid = pvc_vm.getDomainUUID(zkhandler, vm)
if not dom_uuid:
return {"message": "VM not found."}, 404
retflag, retdata = pvc_vm.modify_vm_tags(zkhandler, vm, action, tags)
retflag, retdata = pvc_vm.modify_vm_tag(zkhandler, vm, action, tag, protected=protected)
if retflag:
retcode = 200