def info(aDict): """Function docstring for info TBD Args: - ip (required) - id (required) - op (optional) Output: """ from zdcp.core.common import DB ret = {} with DB() as db: if aDict.get('op') == 'lookup': pdu = Device(aDict['ip']) slotl = pdu.get_slot_names() slotn = len(slotl) args = { 'slots': slotn, '0_slot_id': slotl[0][0], '0_slot_name': slotl[0][1] } if slotn == 2: args.update({ '1_slot_id': slotl[1][0], '1_slot_name': slotl[1][1] }) db.update_dict('pdu_info', args, "device_id = %(id)s" % aDict) ret['found'] = (db.do( "SELECT * FROM pdu_info WHERE device_id = '%(id)s'" % aDict) > 0) if ret['found']: ret['data'] = db.get_row() else: db.do("INSERT INTO pdu_info SET device_id = %(id)s, slots = 1" % aDict) ret['data'] = { 'slots': 1, '0_slot_id': 0, '0_slot_name': '', '1_slot_id': 1, '1_slot_name': '' } return ret
def network_list(aDict): """Lists networks Args: Output: - networks. List of: -- id -- netasc -- gateway -- description -- network -- mask """ ret = {} with DB() as db: ret['count'] = db.do("SELECT ipam_networks.id, CONCAT(INET_NTOA(network),'/',mask) AS netasc, INET_NTOA(gateway) AS gateway, description, mask, network, server FROM ipam_networks LEFT JOIN servers ON ipam_networks.server_id = servers.id ORDER by network") ret['networks'] = db.get_rows() return ret
def contrail_uuid(aDict): """Function docstring for uuid_info TBD Args: - token (required) - uuid (required) Output: """ with DB() as db: db.do("SELECT node FROM openstack_tokens WHERE token = '%s'"%aDict['token']) data = db.get_row() controller = Device(data['node'],aDict['token']) try: res = controller.call("8082","id-to-fqname",args={'uuid':aDict['uuid']},method='POST') if res.get('result','OK') == 'OK': ret = controller.call("8082","%s/%s"%(res['data']['type'],aDict['uuid']))['data'] except Exception as e: ret = e[0] return ret
def vm_resources(aDict): """Function docstring for vm_resources TBD Args: - token (required) Output: """ ret = {} with DB() as db: db.do("SELECT node,id FROM openstack_tokens WHERE token = '%s'"%(aDict['token'])) data = db.get_row() db.do("SELECT service,service_port,service_url FROM openstack_services WHERE id = '%s'"%(data['id'])) services = db.get_dict('service') controller = Device(data['node'],aDict['token']) ret['flavors'] = controller.call(services['nova']['service_port'],services['nova']['service_url'] + "flavors/detail?sort_key=name")['data']['flavors'] ret['images'] = controller.call(services['glance']['service_port'],services['glance']['service_url'] + "v2/images?sort=name:asc")['data']['images'] ret['networks'] = controller.call(services['neutron']['service_port'],services['neutron']['service_url'] + "v2.0/networks?sort_key=name")['data']['networks'] return ret
def contrail_vm_interfaces(aDict): """Function docstring for contrail_vm_interfaces TBD Args: - token (required) - vm (required) Output: """ ret = {'vm':aDict['vm'],'interfaces':[]} with DB() as db: db.do("SELECT node, service_port, service_url FROM openstack_tokens LEFT JOIN openstack_services ON openstack_tokens.id = openstack_services.id WHERE openstack_tokens.token = '%s' AND service = 'contrail'"%(aDict['token'])) data = db.get_row() controller = Device(data['node'],aDict['token']) vmis = controller.call(data['service_port'],data['service_url'] + "virtual-machine/%s"%aDict['vm'])['data']['virtual-machine']['virtual_machine_interface_back_refs'] for vmi in vmis: vmi = controller.href(vmi['href'])['data']['virtual-machine-interface'] iip = controller.href(vmi['instance_ip_back_refs'][0]['href'])['data']['instance-ip'] ret['interfaces'].append({'uuid':vmi['uuid'],'ip_address':iip['instance_ip_address'],'virtual_network':iip['virtual_network_refs'][0]['to'][2]}) return ret
def interface_link(aDict): """Function docstring for interface_link. Link two device interfaces simultaneously to each other, remove old interfaces before (unless multipoint) Args: - a_id (required) - b_id (required) Output: """ ret = {'a': {}, 'b': {}} with DB() as db: sql_clear = "UPDATE device_interfaces SET peer_interface = NULL WHERE peer_interface = %s AND multipoint = 0" sql_set = "UPDATE device_interfaces SET peer_interface = %s WHERE id = %s AND multipoint = 0" ret['a']['clear'] = db.do(sql_clear % (aDict['a_id'])) ret['b']['clear'] = db.do(sql_clear % (aDict['b_id'])) ret['a']['set'] = (db.do(sql_set % (aDict['b_id'], aDict['a_id'])) == 1) ret['b']['set'] = (db.do(sql_set % (aDict['a_id'], aDict['b_id'])) == 1) return ret
def address_find(aDict): """Function docstring for address_find TBD Args: - network_id (required) - consecutive (optional) Output: """ from struct import pack from socket import inet_ntoa def GL_int2ip(addr): return inet_ntoa(pack("!I", addr)) consecutive = int(aDict.get('consecutive',1)) with DB() as db: db.do("SELECT network, INET_NTOA(network) as netasc, mask FROM ipam_networks WHERE id = %(network_id)s"%aDict) net = db.get_row() db.do("SELECT ip FROM ipam_addresses WHERE network_id = %(network_id)s"%aDict) iplist = db.get_dict('ip') network = int(net.get('network')) start = None ret = { 'network':net['netasc'] } for ip in range(network + 1, network + 2**(32-int(net.get('mask')))-1): if iplist.get(ip): start = None elif not start: count = consecutive if count > 1: start = ip else: ret['ip'] = GL_int2ip(ip) break else: if count == 2: ret['start'] = GL_int2ip(start) ret['end'] = GL_int2ip(start + consecutive - 1) break else: count = count - 1 return ret
def node_mapping(aDict): """Node mapping translates between nodes and devices and provide the same info, it depends on the device existing or node having mapped a device (else 'found' is false) Args: - id (optional required) - node (optional required) Output: - found. boolean - id. device id - node. node name - hostname. device hostname - ip. device ip - domain. Device domain name - webpage """ with DB() as db: if aDict.get('id'): found = (db.do( "SELECT hostname, INET_NTOA(ia.ip) as ip, domains.name AS domain, webpage FROM devices LEFT JOIN ipam_addresses AS ia ON ia.id = devices.ipam_id LEFT JOIN domains ON domains.id = devices.a_dom_id WHERE devices.id = %s" % aDict['id']) > 0) ret = db.get_row() if found else {} ret['found'] = (db.do( "SELECT node FROM nodes WHERE device_id = %s" % aDict['id']) > 0) ret['node'] = db.get_val('node') if ret['found'] else None ret['id'] = int(aDict['id']) else: found = (db.do("SELECT device_id FROM nodes WHERE node = '%s'" % aDict['node']) > 0) ret = { 'id': db.get_val('device_id') if found else None, 'node': aDict['node'], 'found': False } if ret['id']: ret['found'] = (db.do( "SELECT hostname, INET_NTOA(ia.ip) as ip, domains.name AS domain, webpage FROM devices LEFT JOIN ipam_addresses AS ia ON ia.id = devices.ipam_id LEFT JOIN domains ON domains.id = devices.a_dom_id WHERE devices.id = %s" % ret['id']) > 0) ret.update(db.get_row()) return ret
def address_allocate(aDict): """ Function allocate IP relative a specific network. Args: - ip (required) - network_id (required) Output: - valid (boolean) Indicates valid within network - success (boolean) - id. Id of address """ ret = {'success':False} with DB() as db: ret['valid'] = (db.do("SELECT network FROM ipam_networks WHERE id = %(network_id)s AND INET_ATON('%(ip)s') > network AND INET_ATON('%(ip)s') < (network + POW(2,(32-mask))-1)"%aDict) == 1) if ret['valid']: try: ret['success'] = (db.do("INSERT INTO ipam_addresses(ip,network_id) VALUES(INET_ATON('%(ip)s'),%(network_id)s)"%aDict) == 1) ret['id']= db.get_last_id() if ret['success'] else None except: pass return ret
def settings_info(aDict): """Function docstring for settings_info TBD Args: - node (required) - id (required) - op (optional) - description (cond required) - section (cond required) - value (cond required) - parameter (cond required) Output: """ ret = {} args = aDict id = args.pop('id', 'new') op = args.pop('op', None) with DB() as db: if op == 'update' and not (aDict['section'] == 'system' or aDict['section'] == 'nodes'): if not id == 'new': ret['update'] = db.update_dict('settings', args, "id=%s" % id) else: ret['update'] = db.insert_dict('settings', args) id = db.get_last_id() if ret['update'] > 0 else 'new' if not id == 'new': ret['found'] = (db.do( "SELECT * FROM settings WHERE id = '%s'" % id) > 0) ret['data'] = db.get_row() else: ret['data'] = { 'id': 'new', 'value': 'Unknown', 'section': aDict.get('section', 'Unknown'), 'parameter': 'Unknown', 'description': 'Unknown' } return ret
def node_info(aDict): """Function docstring for node_info TBD Args: - id (required) - op (optional) Output: """ ret = {} args = aDict id = args.pop('id', 'new') op = args.pop('op', None) args.pop('hostname', None) try: args['device_id'] = int(args.get('device_id')) except: args['device_id'] = 'NULL' with DB() as db: if op == 'update': if not id == 'new': ret['update'] = db.update_dict('nodes', args, 'id=%s' % id) else: ret['update'] = db.insert_dict('nodes', args) id = db.get_last_id() if ret['update'] > 0 else 'new' if not id == 'new': ret['found'] = (db.do( "SELECT nodes.*, devices.hostname FROM nodes LEFT JOIN devices ON devices.id = nodes.device_id WHERE nodes.id = '%s'" % id) > 0) ret['data'] = db.get_row() else: ret['data'] = { 'id': 'new', 'node': 'Unknown', 'url': 'Unknown', 'device_id': None, 'hostname': None } return ret
def users_info(aDict): """Function docstring for users_info TBD Args: - id (required) - op (optional) - name (optional) - view_public (optional) - menulist (optional) - alias (optional) - email (optional) Output: """ ret = {} args = aDict id = args.pop('id', 'new') op = args.pop('op', None) with DB() as db: if op == 'update': if not id == 'new': ret['update'] = db.update_dict('users', args, "id=%s" % id) else: ret['update'] = db.insert_dict('users', args) id = db.get_last_id() if ret['update'] > 0 else 'new' if not id == 'new': ret['found'] = (db.do( "SELECT users.* FROM users WHERE id = '%s'" % id) > 0) ret['data'] = db.get_row() else: ret['data'] = { 'id': 'new', 'name': 'Unknown', 'alias': 'Unknown', 'email': 'Unknown', 'view_public': '0', 'menulist': 'default' } return ret
def contrail_interfaces(aDict): """Function docstring for contrail_interfaces TBD Args: - token (required) - virtual_network (required) Output: """ ret = {'virtual-network':aDict['virtual_network'],'ip_addresses':[]} with DB() as db: db.do("SELECT node, service_port, service_url FROM openstack_tokens LEFT JOIN openstack_services ON openstack_tokens.id = openstack_services.id WHERE openstack_tokens.token = '%s' AND service = 'contrail'"%(aDict['token'])) data = db.get_row() controller = Device(data['node'],aDict['token']) res = controller.call(data['service_port'],data['service_url'] + "virtual-network/%s"%aDict['virtual_network']) vn = res['data']['virtual-network'] fqdn = vn['fq_name'] fqdn.reverse() ret['fqdn'] = ".".join(fqdn) ret['name'] = vn['name'] for ip in vn.get('instance_ip_back_refs',[]): iip = controller.href(ip['href'])['data']['instance-ip'] vmi = controller.href(iip['virtual_machine_interface_refs'][0]['href'])['data']['virtual-machine-interface'] record = {'ip_address':iip['instance_ip_address'],'mac_address':vmi['virtual_machine_interface_mac_addresses']['mac_address'][0]} if vmi.get('virtual_machine_refs'): record['vm_uuid'] = vmi['virtual_machine_refs'][0]['uuid'] if vmi.get('virtual_machine_interface_bindings'): host = vmi['virtual_machine_interface_bindings']['key_value_pair'] for kvp in host: if kvp['key'] == 'host_id': record['vm_binding'] = kvp['value'] break if vmi.get('logical_interface_back_refs'): li = vmi['logical_interface_back_refs'][0] record['logical_interface'] = li['to'][1] + "-" + li['to'][3] record['logical_interface_uuid'] = li['uuid'] if vmi.get('virtual_machine_interface_device_owner'): record['vm_interface_owner'] = vmi['virtual_machine_interface_device_owner'] ret['ip_addresses'].append(record) return ret
def address_realloc(aDict): """ Function re allocate address ID to a new IP within the same or a new network. Args: - id (required) - ip (required) - network_id (required) Output: - valid (boolean) - available (boolean) - success (boolean) """ ret = {'success':False,'valid':False,'available':False} with DB() as db: ret['valid'] = (db.do("SELECT network FROM ipam_networks WHERE id = '%(network_id)s AND INET_ATON('%(ip)s') > network AND INET_ATON('%(ip)s') < (network + POW(2,(32-mask))-1)"%aDict) == 1) if ret['valid']: ret['available'] = (db.do("SELECT id FROM ipam_addresses WHERE ip = INET_ATON('%(ip)s') AND network_id = %(network_id)s"%aDict) == 0) if ret['available']: ret['success'] = (db.do("UPDATE ipam_addresses SET ip = INET_ATON('%(ip)s'), network_id = %(network_id)s WHERE id = %(id)s"%aDict) == 1) return ret
def record_device_delete(aDict): """Function docstring for record_device_delete TBD Args: - a_id (optional) - id/0 - ptr_id (optional) - id/0 - a_domain_id (optional required) - ptr_domain_id (optional required) Output: """ ret = {'A':0,'PTR':0} with DB() as db: for tp in ['a','ptr']: domain_id = aDict.get('%s_domain_id'%tp) id = str(aDict.get('%s_id'%tp,'0')) if domain_id > 0 and id != '0': db.do("SELECT foreign_id, server, node FROM domains LEFT JOIN servers ON domains.server_id = servers.id WHERE domains.id = '%s'"%(domain_id)) infra = db.get_row() args = {'id':id,'domain_id':infra['foreign_id']} ret[tp.upper()] = node_call(infra['node'],infra['server'],'record_delete',args)['deleted'] return ret
def update(aDict): """Function docstring for update TBD Args: - device_id (required) - user_id (required) - op (required) Output: """ ret = {'op': aDict['op']} if aDict['op'] == 'reserve': sql = "INSERT INTO reservations (device_id,user_id) VALUES('%(device_id)s','%(user_id)s')" elif aDict['op'] == 'drop': sql = "DELETE FROM reservations WHERE device_id = '%(device_id)s' AND user_id = '%(user_id)s'" elif aDict['op'] == 'extend': sql = "UPDATE reservations SET time_start = NOW() WHERE device_id = '%(device_id)s' AND user_id = '%(user_id)s'" with DB() as db: ret['update'] = db.do(sql % aDict) db.do("SELECT alias FROM users WHERE id = '%(user_id)s'" % aDict) ret['alias'] = db.get_val('alias') return ret
def call(aDict): """Function docstring for call. Basically creates a controller instance and send a (nested) rest_call. Args: - node (required) - token (required) - service (required) - call (required) - arguments (optional) - method (optional) Output: """ with DB() as db: db.do("SELECT node, service_port, service_url FROM openstack_tokens LEFT JOIN openstack_services ON openstack_tokens.id = openstack_services.id WHERE openstack_tokens.token = '%s' AND service = '%s'"%(aDict['token'], aDict['service'])) data = db.get_row() controller = Device(data['node'],aDict['token']) try: ret = controller.call(data['service_port'], data['service_url'] + aDict.get('call',''), aDict.get('arguments'), aDict.get('method')) ret['result'] = 'OK' if not ret.get('result') else ret.get('result') except Exception as e: ret = e[0] return ret
def activities_list(aDict): """ Function docstring for activities_list. TBD Args: - start (optional) - mode (optional), 'basic' (default)/'full' Output: """ ret = {'start': aDict.get('start', 0)} ret['end'] = int(ret['start']) + 50 ret['mode'] = aDict.get('mode', 'basic') if ret['mode'] == 'full': select = "activities.id, activities.event" else: select = "activities.id" with DB() as db: db.do( "SELECT %s, activity_types.type AS type, DATE_FORMAT(date_time,'%%H:%%i') AS time, DATE_FORMAT(date_time, '%%Y-%%m-%%d') AS date, alias AS user FROM activities LEFT JOIN activity_types ON activities.type_id = activity_types.id LEFT JOIN users ON users.id = activities.user_id ORDER BY date_time DESC LIMIT %s, %s" % (select, ret['start'], ret['end'])) ret['data'] = db.get_rows() return ret
def record_info(aDict): """NO OP if new, else show device id info Args: - op (optional) - id (required) - domain_id (required) - name (optional) - content (optional) - type (optional) Output: """ ret = {} if aDict['id'] == 'new': ret = {'found':False, 'data':{'id':0,'domain_id':0,'name':aDict.get('name','no_record'),'content':aDict.get('content','no_record'),'type':aDict.get('type','A'),'ttl':'3600' }} else: from zdcp.core.common import DB with DB() as db: ret['found'] = (db.do("SELECT devices.id, 0 AS domain_id, CONCAT(hostname,'.local') AS name, INET_NTOA(ia.ip) AS content, 'A' AS type, 3600 AS ttl FROM devices LEFT JOIN ipam_addresses AS ia ON ia.id = devices.ipam_id WHERE devices.a_dom_id = 0 AND devices.id = %s"%aDict['id']) > 0) ret['data'] = db.get_row() return ret
def server_macs(aDict): """Function returns all MACs for devices belonging to networks beloning to particular server Args: - id (required) Output: """ ret = {} def GL_int2mac(aInt): return ':'.join( s.encode('hex') for s in str(hex(aInt))[2:].zfill(12).decode('hex')).lower() with DB() as db: ret['count'] = db.do( "SELECT devices.id, hostname, mac, name AS domain, INET_NTOA(ia.ip) AS ip, ia.network_id AS network FROM devices LEFT JOIN domains ON domains.id = devices.a_dom_id LEFT JOIN ipam_addresses AS ia ON ia.id = devices.ipam_id LEFT JOIN ipam_networks ON ipam_networks.id = ia.network_id WHERE mac > 0 AND ipam_networks.server_id = %s" % aDict['id']) ret['data'] = db.get_rows() for row in ret['data']: row['mac'] = GL_int2mac(row['mac']) return ret
def record_list(aDict): """Function docstring for record_list TBD Args: - type (optional) - domain_id (required), <B>use cached one</B> Output: """ args = aDict with DB() as db: if aDict.get('domain_id'): db.do("SELECT foreign_id, server, node FROM servers LEFT JOIN domains ON domains.server_id = servers.id WHERE domains.id = %s"%aDict['domain_id']) infra = db.get_row() args['domain_id'] = infra['foreign_id'] else: # Strictly internal use - this one fetch all records for consistency check id = aDict.pop('server_id','0') db.do("SELECT server, node FROM servers WHERE id = %s"%id) infra = db.get_row() ret = node_call(infra['node'],infra['server'],'record_list',args) ret['domain_id'] = aDict.get('domain_id',0) return ret
def record_list(aDict): """Function docstring for records TBD Args: - type (optional) - domain_id (optional) Output: """ ret = {} select = [] if aDict.get('domain_id'): select.append("domain_id = %s" % aDict.get('domain_id')) if aDict.get('type'): select.append("type = '%s'" % aDict.get('type').upper()) tune = " WHERE %s" % (" AND ".join(select)) if len(select) > 0 else "" with DB(SC['powerdns']['database'], 'localhost', SC['powerdns']['username'], SC['powerdns']['password']) as db: ret['count'] = db.do( "SELECT id, domain_id, name, type, content,ttl,change_date FROM records %s ORDER BY type DESC" % tune) ret['records'] = db.get_rows() return ret
def record_device_create(aDict): """Function docstring for record_device_create. The function actually only creates records for an existing device, and update the device.. It does not expect 'overlapping' reverse or forwarding zones - hence bypassing IPAM's PTR registration and does lookup for first available reverse record Args: - device_id (required) - ip (required) - type (required) - domain_id (required) - fqdn (required) Output: """ ret = {} args = {'op':'update','id':'new','type':aDict['type'].upper()} if args['type'] == 'A': args['name'] = aDict['fqdn'] args['content'] = aDict['ip'] elif args['type'] == 'PTR': def GL_ip2ptr(addr): octets = addr.split('.') octets.reverse() octets.append("in-addr.arpa") return ".".join(octets) args['name'] = GL_ip2ptr(aDict['ip']) args['content'] = aDict['fqdn'] with DB() as db: db.do("SELECT foreign_id, server, node FROM servers LEFT JOIN domains ON domains.server_id = servers.id WHERE domains.id = %s"%aDict['domain_id']) infra = db.get_row() args['domain_id'] = infra['foreign_id'] ret['record'] = node_call(infra['node'],infra['server'],'record_info',args) opres = str(ret['record'].get('update')) == "1" or str(ret['record'].get('insert')) == "1" if opres and (args['type'] in ['A','PTR']): ret['device'] = {'id':aDict['device_id']} ret['device']['update'] = db.do("UPDATE devices SET %s_id = '%s' WHERE id = %s"%(aDict['type'].lower(),ret['record']['data']['id'],aDict['device_id'])) return ret
def contrail_vm_associate_fip(aDict): """Function docstring for contrail_vm_interfaces TBD Args: - token (required) - vm_interface (required) - vm_ip_address (required) - floating_ip (required) Output: """ ret = {} with DB() as db: db.do("SELECT node, service_port, service_url FROM openstack_tokens LEFT JOIN openstack_services ON openstack_tokens.id = openstack_services.id WHERE openstack_tokens.token = '%s' AND service = 'contrail'"%(aDict['token'])) data = db.get_row() controller = Device(data['node'],aDict['token']) try: vmi = controller.call(data['service_port'],data['service_url'] + "virtual-machine-interface/%s"%aDict['vm_interface'])['data']['virtual-machine-interface'] fip = { 'floating-ip':{ 'floating_ip_fixed_ip_address':aDict['vm_ip_address'], 'virtual_machine_interface_refs':[ {'href':vmi['href'],'attr':None,'uuid':vmi['uuid'],'to':vmi['fq_name'] } ] } } res = controller.call(data['service_port'],data['service_url'] +"floating-ip/%s"%aDict['floating_ip'],args=fip,method='PUT') ret['result'] = "OK" if res['code'] == 200 else "NOT_OK" except Exception as e: ret['result'] ='ERROR' ret['info'] = str(e) return ret
def resources_list(aDict): """Function docstring for resources_list TBD Args: - node (required) - user_id (required) - dict (required) - type (optional) - view_public (optional) - dict (optional) Output: """ ret = { 'user_id': aDict.get('user_id', "1"), 'type': aDict.get('type', 'all') } with DB() as db: if aDict.get('view_public') is None: db.do("SELECT view_public FROM users WHERE id = %s" % ret['user_id']) ret['view_public'] = (db.get_val('view_public') == 1) else: ret['view_public'] = aDict.get('view_public') node = "node = '%s'" % aDict['node'] if aDict.get('node') else "true" type = "type = '%s'" % aDict['type'] if aDict.get('type') else "true" user = "******" % (ret['user_id'], 'false' if not ret['view_public'] else 'private = 0') select = "%s AND %s AND %s" % (node, type, user) ret['count'] = db.do( "SELECT id, node, icon, title, href, type, view, user_id FROM resources WHERE %s ORDER BY type,title" % select) ret['data'] = db.get_dict( aDict.get('dict')) if aDict.get('dict') else db.get_rows() return ret
def domain_list(aDict): """Function docstring for domain_list TBD Args: - filter (optional) - dict (optional) - exclude (optional) Output: """ ret = {} with DB(SC['powerdns']['database'], 'localhost', SC['powerdns']['username'], SC['powerdns']['password']) as db: if aDict.get('filter'): ret['count'] = db.do( "SELECT domains.* FROM domains WHERE name %s LIKE '%%arpa' ORDER BY name" % ('' if aDict.get('filter') == 'reverse' else "NOT")) else: ret['count'] = db.do("SELECT domains.* FROM domains") ret['domains'] = db.get_rows( ) if not aDict.get('dict') else db.get_dict(aDict.get('dict')) if aDict.get('dict') and aDict.get('exclude'): ret['domains'].pop(aDict.get('exclude'), None) return ret
def node_register(aDict): """Function docstring for register TBD Args: - node (required) - url (required) - system (optional) - www (optional) Output: """ ret = {} args = { 'node': aDict['node'], 'url': aDict['url'], 'system': aDict.get('system', '0'), 'www': aDict.get('www', '0') } with DB() as db: ret['update'] = db.insert_dict( 'nodes', args, "ON DUPLICATE KEY UPDATE system = %(system)s, www = %(www)s, url = '%(url)s'" % args) return ret
def settings_fetch(aDict): """Function docstring for settings_fetch TBD Args: - node (required) Output: """ ret = {} with DB() as db: db.do( "SELECT section,parameter,value FROM settings WHERE node = '%s'" % aDict['node']) data = db.get_rows() db.do( "SELECT 'nodes' AS section, node AS parameter, url AS value FROM nodes" ) data.extend(db.get_rows()) for setting in data: section = setting.pop('section') if not ret.get(section): ret[section] = {} ret[section][setting['parameter']] = setting['value'] return ret
def new(aDict): """Function docstring for new TBD Args: - a_dom_id (required) - hostname (required) - ipam_network_id (optional) - ip (optional) - vm (optional) - mac (optional) - rack (optional) - consecutive (optional) Output: """ alloc = None # Test if hostname ok or if IP supplied and then if ok and available if aDict['hostname'] == 'unknown': return {'info': 'Hostname unknown not allowed'} elif aDict.get('ipam_network_id') and aDict.get('ip'): from zdcp.rest.ipam import address_allocate alloc = address_allocate({ 'ip': aDict['ip'], 'network_id': aDict['ipam_network_id'] }) if not alloc['valid']: return {'info': 'IP not in network range'} elif not alloc['success']: return {'info': 'IP not available'} ret = {'info': None} with DB() as db: ret['fqdn'] = (db.do( "SELECT id AS existing_device_id, hostname, a_dom_id FROM devices WHERE hostname = '%(hostname)s' AND a_dom_id = %(a_dom_id)s" % aDict) == 0) if ret['fqdn']: try: mac = int(aDict.get('mac', '0').replace(":", ""), 16) except: mac = 0 if alloc: import zdcp.rest.dns as DNS DNS.__add_globals__({'import_module': import_module}) dns = DNS.record_device_update({ 'id': 'new', 'a_id': 'new', 'ptr_id': 'new', 'a_domain_id': aDict['a_dom_id'], 'hostname': aDict['hostname'], 'ip': aDict['ip'] }) ret['insert'] = db.do( "INSERT INTO devices(vm,mac,a_dom_id,a_id,ptr_id,ipam_id,hostname,snmp,model) VALUES(%s,%s,%s,%s,%s,%s,'%s','unknown','unknown')" % (aDict.get('vm', '0'), mac, aDict['a_dom_id'], dns['A']['record_id'], dns['PTR']['record_id'], alloc['id'], aDict['hostname'])) else: ret['insert'] = db.do( "INSERT INTO devices(vm,mac,hostname,snmp,model) VALUES(%s,%s,'%s','unknown','unknown')" % (aDict.get('vm', '0'), mac, aDict['hostname'])) ret['id'] = db.get_last_id() if aDict.get('rack'): ret['racked'] = (db.do( "INSERT INTO rack_info SET device_id = %s, rack_id = %s ON DUPLICATE KEY UPDATE rack_unit = 0, rack_size = 1" % (ret['id'], aDict['rack'])) == 1) else: ret.update(db.get_row()) # also remove allocation if fqdn busy.. if alloc['success'] and not ret['fqdn']: from zdcp.rest.ipam import address_delete ret['info'] = "deallocating ip (%s)" % address_delete( {'id': alloc['id']})['result'] return ret
def list(aDict): """Function docstring for list TBD Args: - field (optional) 'id/ip/mac/hostname/type/base/vm' as search fields - search (optional) content to match on field, special case for mac where non-correct MAC will match all that are not '00:00:00:00:00:00' - extra (optional) list of extra info to add, None/'type'/'webpage' - rack (optional), id of rack to filter devices from - sort (optional) (sort on id or hostname or...) - dict (optional) (output as dictionary instead of list) Output: """ ret = {} sort = 'ORDER BY ia.ip' if aDict.get( 'sort', 'ip') == 'ip' else 'ORDER BY devices.hostname' fields = [ 'devices.id', 'devices.hostname', 'INET_NTOA(ia.ip) AS ip', 'domains.name AS domain', 'model' ] tune = [ 'ipam_addresses AS ia ON ia.id = devices.ipam_id', 'domains ON domains.id = devices.a_dom_id' ] filter = ['TRUE'] if aDict.get('rack'): tune.append("rack_info AS ri ON ri.device_id = devices.id") filter.append("ri.rack_id = %(rack)s" % aDict) if aDict.get('search'): if aDict['field'] == 'hostname': filter.append("devices.hostname LIKE '%%%(search)s%%'" % aDict) elif aDict['field'] == 'ip': filter.append("ia.ip = INET_ATON('%(search)s')" % aDict) elif aDict['field'] == 'type': tune.append("device_types AS dt ON dt.id = devices.type_id") filter.append("dt.name = '%(search)s'" % aDict) elif aDict['field'] == 'base': tune.append("device_types AS dt ON dt.id = devices.type_id") filter.append("dt.base = '%(search)s'" % aDict) elif aDict['field'] == 'mac': try: filter.append("mac = %i" % int(aDict['search'].replace(":", ""), 16)) except: filter.append("mac <> 0") else: filter.append("devices.%(field)s IN (%(search)s)" % aDict) extras = aDict.get('extra') if extras: if 'type' in extras: fields.append('dt.name AS type_name, dt.base AS type_base') if not (aDict.get('field') == 'type' or aDict.get('field') == 'base'): tune.append("device_types AS dt ON dt.id = devices.type_id") if 'webpage' in extras: fields.append('devices.webpage') if 'mac' in extras: fields.append('devices.mac') with DB() as db: sql = "SELECT %s FROM devices LEFT JOIN %s WHERE %s %s" % (", ".join( fields), " LEFT JOIN ".join(tune), " AND ".join(filter), sort) ret['count'] = db.do(sql) data = db.get_rows() if extras and 'mac' in extras: def GL_int2mac(aInt): return ':'.join( s.encode('hex') for s in str(hex(aInt))[2:].zfill( 12).decode('hex')).lower() for row in data: row['mac'] = GL_int2mac(row['mac']) ret['data'] = data if not aDict.get('dict') else { row[aDict['dict']]: row for row in data } return ret