diff --git a/client-common/common.py b/client-common/common.py index e8064069..586e4b9a 100644 --- a/client-common/common.py +++ b/client-common/common.py @@ -58,7 +58,7 @@ def stopZKConnection(zk_conn): # def getDomainXML(zk_conn, dom_uuid): try: - xml = zk_conn.get('/domains/%s/xml' % dom_uuid)[0].decode('ascii') + xml = zkhandler.readdata(zk_conn, '/domains/{}/xml'.format(dom_uuid)) except: return None @@ -171,7 +171,7 @@ def getDomainControllers(parsed_xml): # def verifyNode(zk_conn, node): try: - zk_conn.get('/nodes/{}'.format(node)) + zkhandler.readdata('/nodes/{}'.format(node)) return True except: return False @@ -205,16 +205,16 @@ def getPrimaryNode(zk_conn): # def getNodes(zk_conn, dom_uuid): valid_node_list = [] - full_node_list = zk_conn.get_children('/nodes') + full_node_list = zkhandler.list_children(zk_conn, '/nodes') try: - current_node = zk_conn.get('/domains/{}/node'.format(dom_uuid))[0].decode('ascii') + current_node = zkhandler.readdata(zk_conn, '/domains/{}/node'.format(dom_uuid)) except: current_node = None for node in full_node_list: - daemon_state = zk_conn.get('/nodes/{}/daemonstate'.format(node))[0].decode('ascii') - domain_state = zk_conn.get('/nodes/{}/domainstate'.format(node))[0].decode('ascii') + daemon_state = zkhandler.readdata(zk_conn, '/nodes/{}/daemonstate'.format(node)) + domain_state = zkhandler.readdata(zk_conn, '/nodes/{}/domainstate'.format(node)) if node == current_node: continue diff --git a/client-common/network.py b/client-common/network.py index 8abd2deb..67da4ae6 100644 --- a/client-common/network.py +++ b/client-common/network.py @@ -43,11 +43,11 @@ import client_lib.common as common # def getClusterNetworkList(zk_conn): # Get a list of VNIs by listing the children of /networks - vni_list = zk_conn.get_children('/networks') + vni_list = zkhandler.readdata(zk_conn, '/networks') description_list = [] # For each VNI, get the corresponding description from the data for vni in vni_list: - description_list.append(zk_conn.get('/networks/{}'.format(vni))[0].decode('ascii')) + description_list.append(zkhandler.readdata(zk_conn, '/networks/{}')) return vni_list, description_list def searchClusterByVNI(zk_conn, vni): @@ -194,7 +194,7 @@ def formatNetworkInformation(zk_conn, vni, long_output): for line in dhcp_reservations_string.split('\n'): ainformation.append(line) - firewall_rules = zk_conn.get_children('/networks/{}/firewall_rules'.format(vni)) + firewall_rules = zkhandler.list_children(zk_conn, '/networks/{}/firewall_rules'.format(vni)) if firewall_rules: ainformation.append('') ainformation.append('{}Network firewall rules:{}'.format(ansiprint.bold(), ansiprint.end())) @@ -511,7 +511,7 @@ def add_network(zk_conn, vni, description, domain, ip_network, ip_gateway, dhcp_ return False, 'ERROR: DHCP start and end addresses are required for a DHCP-enabled network.' # Check if a network with this VNI or description already exists - if zk_conn.exists('/networks/{}'.format(vni)): + if zkhandler.exists(zk_conn, '/networks/{}'.format(vni)): return False, 'ERROR: A network with VNI {} already exists!'.format(vni) for network in zkhandler.listchildren(zk_conn, '/networks'): network_description = zkhandler.readdata(zk_conn, '/networks/{}'.format(network)) @@ -538,7 +538,6 @@ def add_network(zk_conn, vni, description, domain, ip_network, ip_gateway, dhcp_ def modify_network(zk_conn, vni, **parameters): # Add the new network to Zookeeper - transaction = zk_conn.transaction() zk_data = {} if parameters['description'] != None: zk_data.update({'/networks/{}'.format(vni): parameters['description']}) @@ -567,10 +566,7 @@ def remove_network(zk_conn, network): return False, 'ERROR: Could not find network "{}" in the cluster!'.format(network) # Delete the configuration - try: - zk_conn.delete('/networks/{}'.format(vni), recursive=True) - except: - pass + zkhandler.deletekey(zk_conn, '/networks/{}'.format(vni)) return True, 'Network "{}" removed successfully!'.format(description) @@ -590,7 +586,7 @@ def add_dhcp_reservation(zk_conn, network, ipaddress, macaddress, hostname): if not isValidIP(ipaddress): return False, 'ERROR: IP address "{}" is not valid!'.format(macaddress) - if zk_conn.exists('/networks/{}/dhcp_reservations/{}'.format(net_vni, macaddress)): + if zkhandler.exists(zk_conn, '/networks/{}/dhcp_reservations/{}'.format(net_vni, macaddress)): return False, 'ERROR: A reservation with MAC "{}" already exists!'.format(macaddress) # Add the new static lease to ZK @@ -626,7 +622,7 @@ def remove_dhcp_reservation(zk_conn, network, reservation): # Remove the entry from zookeeper try: - zk_conn.delete('/networks/{}/dhcp_reservations/{}'.format(net_vni, match_description), recursive=True) + zkhandler.deletekey(zk_conn, '/networks/{}/dhcp_reservations/{}'.format(net_vni, match_description)) except: return False, 'ERROR: Failed to write to Zookeeper!' @@ -644,7 +640,7 @@ def add_acl(zk_conn, network, direction, description, rule, order): else: direction = "out" - if zk_conn.exists('/networks/{}/firewall_rules/{}/{}'.format(net_vni, direction, description)): + if zkhandler.exists(zk_conn, '/networks/{}/firewall_rules/{}/{}'.format(net_vni, direction, description)): return False, 'ERROR: A rule with description "{}" already exists!'.format(description) # Handle reordering @@ -713,7 +709,7 @@ def remove_acl(zk_conn, network, rule, direction): # Remove the entry from zookeeper try: - zk_conn.delete('/networks/{}/firewall_rules/{}/{}'.format(net_vni, direction, match_description), recursive=True) + zkhandler.deletekey(zk_conn, '/networks/{}/firewall_rules/{}/{}'.format(net_vni, direction, match_description)) except Exception as e: return False, 'ERROR: Failed to write to Zookeeper! Exception: "{}".'.format(e) @@ -747,7 +743,7 @@ def get_info(zk_conn, network, long_output): def get_list(zk_conn, limit): net_list = [] - full_net_list = zk_conn.get_children('/networks') + full_net_list = zkhandler.list_children(zk_conn, '/networks') for net in full_net_list: description = zkhandler.readdata(zk_conn, '/networks/{}'.format(net)) diff --git a/client-common/node.py b/client-common/node.py index 1b86c2b6..c09b4e54 100644 --- a/client-common/node.py +++ b/client-common/node.py @@ -215,7 +215,7 @@ def get_info(zk_conn, node, long_output): def get_list(zk_conn, limit): # Match our limit node_list = [] - full_node_list = zk_conn.get_children('/nodes') + full_node_list = zkhandler.list_children(zk_conn, '/nodes') for node in full_node_list: if limit != None: try: diff --git a/client-common/vm.py b/client-common/vm.py index d09a619f..6c954868 100644 --- a/client-common/vm.py +++ b/client-common/vm.py @@ -43,9 +43,9 @@ import client_lib.common as common def getInformationFromXML(zk_conn, uuid, long_output): # Obtain the contents of the XML from Zookeeper try: - dstate = zk_conn.get('/domains/{}/state'.format(uuid))[0].decode('ascii') - dnode = zk_conn.get('/domains/{}/node'.format(uuid))[0].decode('ascii') - dlastnode = zk_conn.get('/domains/{}/lastnode'.format(uuid))[0].decode('ascii') + dstate = zkhandler.readdata(zk_conn, '/domains/{}/state'.format(uuid)) + dnode = zkhandler.readdata(zk_conn, '/domains/{}/node'.format(uuid)) + dlastnode = zkhandler.readdata(zk_conn, '/domains/{}/lastnode'.format(uuid)) except: return None @@ -142,11 +142,11 @@ def getInformationFromXML(zk_conn, uuid, long_output): # def getClusterDomainList(zk_conn): # Get a list of UUIDs by listing the children of /domains - uuid_list = zk_conn.get_children('/domains') + uuid_list = zkhandler.listchildren(zk_conn, '/domains') name_list = [] # For each UUID, get the corresponding name from the data for uuid in uuid_list: - name_list.append(zk_conn.get('/domains/%s' % uuid)[0].decode('ascii')) + name_list.append(zkhandler.readdata(zk_conn, '/domains/%s' % uuid)) return uuid_list, name_list def searchClusterByUUID(zk_conn, uuid): @@ -216,14 +216,14 @@ def define_vm(zk_conn, config_data, target_node, selector): common.verifyNode(zk_conn, target_node) # Add the new domain to Zookeeper - transaction = zk_conn.transaction() - transaction.create('/domains/{}'.format(dom_uuid), dom_name.encode('ascii')) - transaction.create('/domains/{}/state'.format(dom_uuid), 'stop'.encode('ascii')) - transaction.create('/domains/{}/node'.format(dom_uuid), target_node.encode('ascii')) - transaction.create('/domains/{}/lastnode'.format(dom_uuid), ''.encode('ascii')) - transaction.create('/domains/{}/failedreason'.format(dom_uuid), ''.encode('ascii')) - transaction.create('/domains/{}/xml'.format(dom_uuid), config_data.encode('ascii')) - results = transaction.commit() + zkhandler.writedata(zk_conn, { + '/domains/{}'.format(dom_uuid): dom_name, + '/domains/{}/state'.format(dom_uuid): 'stop', + '/domains/{}/node'.format(dom_uuid): target_node, + '/domains/{}/lastnode'.format(dom_uuid): '', + '/domains/{}/failedreason'.format(dom_uuid): '', + '/domains/{}/xml'.format(dom_uuid): config_data + }) return True, '' @@ -234,12 +234,13 @@ def modify_vm(zk_conn, domain, restart, new_vm_config): dom_name = getDomainName(zk_conn, domain) # Add the modified config to Zookeeper - transaction = zk_conn.transaction() - transaction.set_data('/domains/{}'.format(dom_uuid), dom_name.encode('ascii')) - transaction.set_data('/domains/{}/xml'.format(dom_uuid), new_vm_config.encode('ascii')) + zk_data = { + '/domains/{}'.format(dom_uuid): dom_name, + '/domains/{}/xml'.format(dom_uuid): new_vm_config + } if restart == True: - transaction.set_data('/domains/{}/state'.format(dom_uuid), 'restart'.encode('ascii')) - results = transaction.commit() + zk_data.update({'/domains/{}/state'.format(dom_uuid): 'restart'}) + zkhandler.writedata(zk_conn, zk_data) return True, '' @@ -252,13 +253,11 @@ def undefine_vm(zk_conn, domain): # Shut down the VM try: - current_vm_state = zk_conn.get('/domains/{}/state'.format(dom_uuid))[0].decode('ascii') + current_vm_state = zkhandler.readdata(zk_conn, '/domains/{}/state'.format(dom_uuid)) if current_vm_state != 'stop': click.echo('Forcibly stopping VM "{}".'.format(dom_uuid)) # Set the domain into stop mode - transaction = zk_conn.transaction() - transaction.set_data('/domains/{}/state'.format(dom_uuid), 'stop'.encode('ascii')) - transaction.commit() + zkhandler.writedata(zk_conn, {'/domains/{}/state'.format(dom_uuid): 'stop'}) # Wait for 3 seconds to allow state to flow to all nodes click.echo('Waiting for cluster to update.') @@ -269,7 +268,7 @@ def undefine_vm(zk_conn, domain): # Gracefully terminate the class instances try: click.echo('Deleting VM "{}" from nodes.'.format(dom_uuid)) - zk_conn.set('/domains/{}/state'.format(dom_uuid), 'delete'.encode('ascii')) + zkhandler.writedata(zk_conn, {'/domains/{}/state'.format(dom_uuid): 'delete'}) time.sleep(5) except: pass @@ -277,7 +276,7 @@ def undefine_vm(zk_conn, domain): # Delete the configurations try: click.echo('Undefining VM "{}".'.format(dom_uuid)) - zk_conn.delete('/domains/{}'.format(dom_uuid), recursive=True) + zkhandler.deletekey(zk_conn, '/domains/{}') except: pass @@ -292,7 +291,7 @@ def start_vm(zk_conn, domain): # Set the VM to start click.echo('Starting VM "{}".'.format(dom_uuid)) - zk_conn.set('/domains/%s/state' % dom_uuid, 'start'.encode('ascii')) + zkhandler.writedata(zk_conn, {'/domains/{}/state'.format(dom_uuid): 'start'}) return True, '' @@ -304,14 +303,14 @@ def restart_vm(zk_conn, domain): return False, 'ERROR: Could not find VM "{}" in the cluster!'.format(domain) # Get state and verify we're OK to proceed - current_state = zk_conn.get('/domains/{}/state'.format(dom_uuid))[0].decode('ascii') + current_state = zkhandler.readdata(zk_conn, '/domains/{}/state'.format(dom_uuid)) if current_state != 'start': common.stopZKConnection(zk_conn) return False, 'ERROR: VM "{}" is not in "start" state!'.format(dom_uuid) # Set the VM to start click.echo('Restarting VM "{}".'.format(dom_uuid)) - zk_conn.set('/domains/%s/state' % dom_uuid, 'restart'.encode('ascii')) + zkhandler.writedata(zk_conn, {'/domains/{}/state'.format(dom_uuid): 'restart'}) return True, '' @@ -322,14 +321,14 @@ def shutdown_vm(zk_conn, domain): return False, 'ERROR: Could not find VM "{}" in the cluster!'.format(domain) # Get state and verify we're OK to proceed - current_state = zk_conn.get('/domains/{}/state'.format(dom_uuid))[0].decode('ascii') + current_state = zkhandler.readdata(zk_conn, '/domains/{}/state'.format(dom_uuid)) if current_state != 'start': common.stopZKConnection(zk_conn) return False, 'ERROR: VM "{}" is not in "start" state!'.format(dom_uuid) # Set the VM to shutdown click.echo('Shutting down VM "{}".'.format(dom_uuid)) - zk_conn.set('/domains/%s/state' % dom_uuid, 'shutdown'.encode('ascii')) + zkhandler.writedata(zk_conn, {'/domains/{}/state'.format(dom_uuid): 'shutdown'}) return True, '' @@ -341,14 +340,14 @@ def stop_vm(zk_conn, domain): return False, 'ERROR: Could not find VM "{}" in the cluster!'.format(domain) # Get state and verify we're OK to proceed - current_state = zk_conn.get('/domains/{}/state'.format(dom_uuid))[0].decode('ascii') + current_state = zkhandler.readdata(zk_conn, '/domains/{}/state'.format(dom_uuid)) if current_state != 'start': common.stopZKConnection(zk_conn) return False, 'ERROR: VM "{}" is not in "start" state!'.format(dom_uuid) # Set the VM to start click.echo('Forcibly stopping VM "{}".'.format(dom_uuid)) - zk_conn.set('/domains/%s/state' % dom_uuid, 'stop'.encode('ascii')) + zkhandler.writedata(zk_conn, {'/domains/{}/state'.format(dom_uuid): 'stop'}) return True, '' @@ -359,7 +358,7 @@ def move_vm(zk_conn, domain, target_node, selector): common.stopZKConnection(zk_conn) return False, 'ERROR: Could not find VM "{}" in the cluster!'.format(domain) - current_node = zk_conn.get('/domains/{}/node'.format(dom_uuid))[0].decode('ascii') + current_node = zkhandler.readdata(zk_conn, '/domains/{}/node'.format(dom_uuid)) if target_node == None: target_node = common.findTargetNode(zk_conn, selector, dom_uuid) @@ -371,20 +370,20 @@ def move_vm(zk_conn, domain, target_node, selector): # Verify node is valid common.verifyNode(zk_conn, target_node) - current_vm_state = zk_conn.get('/domains/{}/state'.format(dom_uuid))[0].decode('ascii') + current_vm_state = zkhandler.readdata(zk_conn, '/domains/{}/state'.format(dom_uuid)) if current_vm_state == 'start': click.echo('Permanently migrating VM "{}" to node "{}".'.format(dom_uuid, target_node)) - transaction = zk_conn.transaction() - transaction.set_data('/domains/{}/state'.format(dom_uuid), 'migrate'.encode('ascii')) - transaction.set_data('/domains/{}/node'.format(dom_uuid), target_node.encode('ascii')) - transaction.set_data('/domains/{}/lastnode'.format(dom_uuid), ''.encode('ascii')) - transaction.commit() + zkhandler.writedata(zk_conn, { + '/domains/{}/state'.format(dom_uuid): 'migrate', + '/domains/{}/node'.format(dom_uuid): target_node, + '/domains/{}/lastnode'.format(dom_uuid): '' + }) else: click.echo('Permanently moving VM "{}" to node "{}".'.format(dom_uuid, target_node)) - transaction = zk_conn.transaction() - transaction.set_data('/domains/{}/node'.format(dom_uuid), target_node.encode('ascii')) - transaction.set_data('/domains/{}/lastnode'.format(dom_uuid), ''.encode('ascii')) - transaction.commit() + zkhandler.writedata(zk_conn, { + '/domains/{}/node'.format(dom_uuid): target_node, + '/domains/{}/lastnode'.format(dom_uuid): '' + }) return True, '' @@ -396,14 +395,14 @@ def migrate_vm(zk_conn, domain, target_node, selector, force_migrate): return False, 'ERROR: Could not find VM "{}" in the cluster!'.format(domain) # Get state and verify we're OK to proceed - current_state = zk_conn.get('/domains/{}/state'.format(dom_uuid))[0].decode('ascii') + current_state = zkhandler.readdata(zk_conn, '/domains/{}/state'.format(dom_uuid)) if current_state != 'start': target_state = 'start' else: target_state = 'migrate' - current_node = zk_conn.get('/domains/{}/node'.format(dom_uuid))[0].decode('ascii') - last_node = zk_conn.get('/domains/{}/lastnode'.format(dom_uuid))[0].decode('ascii') + current_node = zkhandler.readdata(zk_conn, '/domains/{}/node'.format(dom_uuid)) + last_node = zkhandler.readdata(zk_conn, '/domains/{}/lastnode'.format(dom_uuid)) if last_node != '' and force_migrate != True: click.echo('ERROR: VM "{}" has been previously migrated.'.format(dom_uuid)) @@ -424,11 +423,11 @@ def migrate_vm(zk_conn, domain, target_node, selector, force_migrate): common.verifyNode(zk_conn, target_node) click.echo('Migrating VM "{}" to node "{}".'.format(dom_uuid, target_node)) - transaction = zk_conn.transaction() - transaction.set_data('/domains/{}/state'.format(dom_uuid), target_state.encode('ascii')) - transaction.set_data('/domains/{}/node'.format(dom_uuid), target_node.encode('ascii')) - transaction.set_data('/domains/{}/lastnode'.format(dom_uuid), current_node.encode('ascii')) - transaction.commit() + zkhandler.writedata(zk_conn, { + '/domains/{}/state'.format(dom_uuid): 'migrate', + '/domains/{}/node'.format(dom_uuid): target_node, + '/domains/{}/lastnode'.format(dom_uuid): current_node + }) return True, '' @@ -440,24 +439,24 @@ def unmigrate_vm(zk_conn, domain): return False, 'ERROR: Could not find VM "{}" in the cluster!'.format(domain) # Get state and verify we're OK to proceed - current_state = zk_conn.get('/domains/{}/state'.format(dom_uuid))[0].decode('ascii') + current_state = zkhandler.readdata(zk_conn, '/domains/{}/state'.format(dom_uuid)) if current_state != 'start': target_state = 'start' else: target_state = 'migrate' - target_node = zk_conn.get('/domains/{}/lastnode'.format(dom_uuid))[0].decode('ascii') + target_node = zkhandler.readdata(zk_conn, '/domains/{}/lastnode'.format(dom_uuid)) if target_node == '': common.stopZKConnection(zk_conn) return False, 'ERROR: VM "{}" has not been previously migrated.'.format(dom_uuid) click.echo('Unmigrating VM "{}" back to node "{}".'.format(dom_uuid, target_node)) - transaction = zk_conn.transaction() - transaction.set_data('/domains/{}/state'.format(dom_uuid), target_state.encode('ascii')) - transaction.set_data('/domains/{}/node'.format(dom_uuid), target_node.encode('ascii')) - transaction.set_data('/domains/{}/lastnode'.format(dom_uuid), ''.encode('ascii')) - transaction.commit() + zkhandler.writedata(zk_conn, { + '/domains/{}/state'.format(dom_uuid): target_state, + '/domains/{}/node'.format(dom_uuid): target_node, + '/domains/{}/lastnode'.format(dom_uuid): '' + }) return True, '' @@ -473,7 +472,7 @@ def get_info(zk_conn, domain, long_output): click.echo(information) # Get a failure reason if applicable - failedreason = zk_conn.get('/domains/{}/failedreason'.format(dom_uuid))[0].decode('ascii') + failedreason = zkhandler.readdata(zk_conn, '/domains/{}/failedreason'.format(dom_uuid)) if failedreason != '': click.echo('') click.echo('{}Failure reason:{} {}'.format(ansiprint.purple(), ansiprint.end(), failedreason)) @@ -487,7 +486,7 @@ def get_list(zk_conn, node, limit): # Verify node is valid common.verifyNode(zk_conn, node) - full_vm_list = zk_conn.get_children('/domains') + full_vm_list = zkhandler.listchildren(zk_conn, '/domains') vm_list = [] vm_list_output = [] @@ -540,8 +539,8 @@ def get_list(zk_conn, node, limit): # Gather information for printing for vm in vm_list: - vm_state[vm] = zk_conn.get('/domains/{}/state'.format(vm))[0].decode('ascii') - vm_lastnode = zk_conn.get('/domains/{}/lastnode'.format(vm))[0].decode('ascii') + vm_state[vm] = zkhandler.readdata(zk_conn, '/domains/{}/state'.format(vm)) + vm_lastnode = zkhandler.readdata(zk_conn, '/domains/{}/lastnode'.format(vm)) if vm_lastnode != '': vm_migrated[vm] = 'from {}'.format(vm_lastnode) else: diff --git a/client-common/zkhandler.py b/client-common/zkhandler.py index 62470577..69099f2f 100644 --- a/client-common/zkhandler.py +++ b/client-common/zkhandler.py @@ -36,6 +36,13 @@ def listchildren(zk_conn, key): children = zk_conn.get_children(key) return children +# Delete key function +def deletekey(zk_conn, key, recursive=True): + try: + zk_conn.delete(key, recursive=recursive) + except: + pass + # Data read function def readdata(zk_conn, key): data_raw = zk_conn.get(key)