Ejemplo n.º 1
0
def _dump_locations(info, macaddr, nodename=None):
    yield msg.KeyValueData({'possiblenode': nodename, 'mac': macaddr})
    retdata = {}
    portinfo = []
    for location in info:
        portinfo.append({'switch': location[0],
                              'port': location[1], 'macsonport': location[2]})
    retdata['ports'] = sorted(portinfo, key=lambda x: x['macsonport'],
                              reverse=True)
    yield msg.KeyValueData(retdata)
Ejemplo n.º 2
0
def send_discovery_datum(info):
    addresses = info.get('addresses', [])
    if info['handler'] == pxeh:
        enrich_pxe_info(info)
    yield msg.KeyValueData({'nodename': info.get('nodename', '')})
    yield msg.KeyValueData({'ipaddrs': [x[0] for x in addresses]})
    sn = info.get('serialnumber', '')
    mn = info.get('modelnumber', '')
    uuid = info.get('uuid', '')
    if uuid:
        relatedmacs = []
        for mac in known_uuids.get(uuid, {}):
            if mac and mac != info.get('hwaddr', ''):
                relatedmacs.append(mac)
        if relatedmacs:
            yield msg.KeyValueData({'relatedmacs': relatedmacs})
    yield msg.KeyValueData({'serialnumber': sn})
    yield msg.KeyValueData({'modelnumber': mn})
    yield msg.KeyValueData({'uuid': uuid})
    if 'enclosure.bay' in info:
        yield msg.KeyValueData({'bay': int(info['enclosure.bay'])})
    yield msg.KeyValueData({'macs': [info.get('hwaddr', '')]})
    types = []
    for infotype in info.get('services', []):
        if infotype in servicenames:
            types.append(servicenames[infotype])
    yield msg.KeyValueData({'types': types})
Ejemplo n.º 3
0
def handle_deployment(configmanager, inputdata, pathcomponents, operation):
    if len(pathcomponents) == 1:
        yield msg.ChildCollection('distributions/')
        yield msg.ChildCollection('profiles/')
        yield msg.ChildCollection('importing/')
        return
    if pathcomponents[1] == 'distributions':
        if len(pathcomponents) == 2 and operation == 'retrieve':
            for dist in osimage.list_distros():
                yield msg.ChildCollection(dist + '/')
            return
        if len(pathcomponents) == 3:
            distname = pathcomponents[-1]
            if 'operation' == 'update':
                if inputdata.get('rescan', False):
                    osimage.rescan_dist(distname)
    if pathcomponents[1] == 'profiles':
        if len(pathcomponents) == 2 and operation == 'retrieve':
            for prof in osimage.list_profiles():
                yield msg.ChildCollection(prof + '/')
            return
        if len(pathcomponents) == 3:
            profname = pathcomponents[-1]
            if operation == 'update' and 'updateboot' in inputdata:
                osimage.update_boot(profname)
                yield msg.KeyValueData({'updated': profname})
                return
    if pathcomponents[1] == 'importing':
        if len(pathcomponents) == 2 or not pathcomponents[-1]:
            if operation == 'retrieve':
                for imp in osimage.list_importing():
                    yield imp
                return
            elif operation == 'create':
                importer = osimage.MediaImporter(inputdata['filename'],
                                                 configmanager)
                yield msg.KeyValueData({
                    'target': importer.targpath,
                    'name': importer.importkey
                })
                return
        elif len(pathcomponents) == 3:
            if operation == 'retrieve':
                for res in osimage.get_importing_status(pathcomponents[-1]):
                    yield res
                return
            elif operation == 'delete':
                for res in osimage.remove_importing(pathcomponents[-1]):
                    yield res
                return
    raise exc.NotFoundException('Unrecognized request')
Ejemplo n.º 4
0
 def read_inventory(self, component):
     invitems = []
     if component == 'all':
         for invdata in self.ipmicmd.get_inventory():
             if invdata[1] is None:
                 newinf = {'present': False, 'information': None}
             else:
                 sanitize_invdata(invdata[1])
                 newinf = {'present': True, 'information': invdata[1]}
             newinf['name'] = invdata[0]
             invitems.append(newinf)
     else:
         self.make_inventory_map()
         compname = self.invmap.get(component, None)
         if compname is None:
             self.output.put(msg.ConfluentTargetNotFound())
             return
         invdata = self.ipmicmd.get_inventory_of_component(compname)
         if invdata is None:
             newinf = {'present': False, 'information': None}
         else:
             sanitize_invdata(invdata)
             newinf = {'present': True, 'information': invdata}
         newinf['name'] = compname
         invitems.append(newinf)
     newinvdata = {'inventory': invitems}
     self.output.put(msg.KeyValueData(newinvdata, self.node))
Ejemplo n.º 5
0
def handle_api_request(configmanager, inputdata, operation, pathcomponents):
    if operation == 'retrieve':
        return handle_read_api_request(pathcomponents)
    elif (operation in ('update', 'create')
          and pathcomponents == ['discovery', 'rescan']):
        if inputdata != {'rescan': 'start'}:
            raise exc.InvalidArgumentException()
        rescan()
        return (msg.KeyValueData({'rescan': 'started'}), )
    elif operation in ('update', 'create'):
        if 'node' not in inputdata:
            raise exc.InvalidArgumentException('Missing node name in input')
        mac = _get_mac_from_query(pathcomponents)
        info = known_info[mac]
        if info['handler'] is None:
            raise exc.NotImplementedException('Unable to {0} to {1}'.format(
                operation, '/'.join(pathcomponents)))
        handler = info['handler'].NodeHandler(info, configmanager)
        eval_node(configmanager, handler, info, inputdata['node'], manual=True)
        return [msg.AssignedResource(inputdata['node'])]
    elif operation == 'delete':
        mac = _get_mac_from_query(pathcomponents)
        del known_info[mac]
        return [msg.DeletedResource(mac)]
    raise exc.NotImplementedException('Unable to {0} to {1}'.format(
        operation, '/'.join(pathcomponents)))
Ejemplo n.º 6
0
def list_updates(nodes, tenant, element, type='firmware'):
    showmode = False
    if type == 'mediaupload':
        myparty = uploadsbytarget
        verb = 'upload'
    else:
        myparty = updatesbytarget
        verb = 'update'
    if type == 'firmware':
        specificlen = 4
    else:
        specificlen = 2
    if len(element) > specificlen:
        showmode = True
        upid = element[-1]
    for node in nodes:
        if showmode:
            try:
                updater = myparty[(node, tenant)][upid]
            except KeyError:
                raise exc.NotFoundException(
                    'No matching {0} process found'.format(verb))
            yield msg.KeyValueData(updater.progress, name=node)
        else:
            for updateid in myparty.get((node, tenant), {}):
                yield msg.ChildCollection(updateid)
Ejemplo n.º 7
0
def _expand_expression(nodes, configmanager, inputdata):
    expression = inputdata.get_attributes(list(nodes)[0])
    if type(expression) is dict:
        expression = expression['expression']
    if type(expression) is dict:
        expression = expression['expression']
    for expanded in configmanager.expand_attrib_expression(nodes, expression):
        yield msg.KeyValueData({'value': expanded[1]}, expanded[0])
Ejemplo n.º 8
0
def retrieve_inventory(configmanager, creds, node, results, element):
    if len(element) == 3:
        results.put(msg.ChildCollection('all'))
        results.put(msg.ChildCollection('system'))
        return
    wc = WebClient(node, configmanager, creds)
    invinfo = wc.fetch('/affluent/inventory/hardware/all', results)
    if invinfo:
        results.put(msg.KeyValueData(invinfo, node))
Ejemplo n.º 9
0
def handle_api_request(configmanager, inputdata, operation, pathcomponents):
    if operation == 'retrieve':
        return handle_read_api_request(pathcomponents)
    if (operation in ('update', 'create')
            and pathcomponents == ['networking', 'macs', 'rescan']):
        if inputdata != {'rescan': 'start'}:
            raise exc.InvalidArgumentException()
        eventlet.spawn_n(rescan, configmanager)
        return [msg.KeyValueData({'rescan': 'started'})]
    raise exc.NotImplementedException(
        'Operation {0} on {1} not implemented'.format(
            operation, '/'.join(pathcomponents)))
Ejemplo n.º 10
0
def abbreviate_noderange(configmanager, inputdata, operation):
    if operation != 'create':
        raise exc.InvalidArgumentException(
            'Must be a create with nodes in list')
    if 'nodes' not in inputdata:
        raise exc.InvalidArgumentException(
            'Must be given list of nodes under key named nodes')
    if isinstance(inputdata['nodes'], str) or isinstance(
            inputdata['nodes'], unicode):
        inputdata['nodes'] = inputdata['nodes'].split(',')
    return (msg.KeyValueData({
        'noderange':
        noderange.ReverseNodeRange(inputdata['nodes'], configmanager).noderange
    }), )
Ejemplo n.º 11
0
def list_updates(nodes, tenant, element):
    showmode = False
    if len(element) > 4:
        showmode = True
        upid = element[-1]
    for node in nodes:
        if showmode:
            try:
                updater = updatesbytarget[(node, tenant)][upid]
            except KeyError:
                raise exc.NotFoundException('No matching update process found')
            yield msg.KeyValueData(updater.progress, name=node)
        else:
            for updateid in updatesbytarget.get((node, tenant), {}):
                yield msg.ChildCollection(updateid)
Ejemplo n.º 12
0
def _expand_expression(nodes, configmanager, inputdata):
    expression = inputdata.get_attributes(list(nodes)[0])
    if type(expression) is dict:
        expression = expression['expression']
    if type(expression) is dict:
        expression = expression['expression']
    pernodeexpressions = {}
    try:
        for expanded in configmanager.expand_attrib_expression(
                nodes, expression):
            pernodeexpressions[expanded[0]] = expanded[1]
        for node in util.natural_sort(pernodeexpressions):
            yield msg.KeyValueData({'value': pernodeexpressions[node]}, node)
    except ValueError as e:
        raise exc.InvalidArgumentException(str(e))
Ejemplo n.º 13
0
def _expand_expression(nodes, configmanager, inputdata):
    expression = inputdata.get_attributes(list(nodes)[0])
    if type(expression) is dict:
        expression = expression['expression']
    if type(expression) is dict:
        expression = expression['expression']
    pernodeexpressions = {}
    try:
        for expanded in configmanager.expand_attrib_expression(
                nodes, expression):
            pernodeexpressions[expanded[0]] = expanded[1]
        for node in util.natural_sort(pernodeexpressions):
            yield msg.KeyValueData({'value': pernodeexpressions[node]}, node)
    except (SyntaxError, ValueError) as e:
        raise exc.InvalidArgumentException(
            'Bad confluent expression syntax (must use "{{" and "}}" if not '
            'desiring confluent expansion): ' + str(e))
Ejemplo n.º 14
0
def handle_autosense_config(operation, inputdata):
    autosense = cfm.get_global('discovery.autosense')
    autosense = autosense or autosense is None
    if operation == 'retrieve':
        yield msg.KeyValueData({'enabled': autosense})
    elif operation == 'update':
        enabled = inputdata['enabled']
        if type(enabled) in (unicode, str):
            enabled = enabled.lower() in ('true', '1', 'y', 'yes', 'enable',
                                          'enabled')
        if autosense == enabled:
            return
        cfm.set_global('discovery.autosense', enabled)
        if enabled:
            start_autosense()
        else:
            stop_autosense()
Ejemplo n.º 15
0
def handle_read_api_request(pathcomponents):
    # TODO(jjohnson2): This should be more generalized...
    #  odd indexes into components are 'by-'*, even indexes
    # starting at 2 are parameters to previous index
    if pathcomponents == ['discovery', 'rescan']:
        return (msg.KeyValueData({'scanning': bool(scanner)}),)
    subcats, queryparms, indexof, coll = _parameterize_path(pathcomponents[1:])
    if len(pathcomponents) == 1:
        dirlist = [msg.ChildCollection(x + '/') for x in sorted(list(subcats))]
        dirlist.append(msg.ChildCollection('rescan'))
        dirlist.append(msg.ChildCollection('autosense'))
        return dirlist
    if not coll:
        return show_info(queryparms['by-mac'])
    if not indexof:
        return [msg.ChildCollection(x + '/') for x in sorted(list(subcats))]
    if indexof not in list_info:
        raise exc.NotFoundException('{0} is not found'.format(indexof))
    return list_info[indexof](queryparms)
Ejemplo n.º 16
0
 def read_inventory(self, component):
     errorneeded = False
     try:
         invitems = []
         if component == 'all':
             for invdata in self.ipmicmd.get_inventory():
                 if invdata[1] is None:
                     newinf = {'present': False, 'information': None}
                 else:
                     sanitize_invdata(invdata[1])
                     newinf = {'present': True, 'information': invdata[1]}
                 newinf['name'] = invdata[0]
                 invitems.append(newinf)
         else:
             self.make_inventory_map()
             compname = self.invmap.get(component, None)
             if compname is None:
                 self.output.put(msg.ConfluentTargetNotFound())
                 return
             invdata = self.ipmicmd.get_inventory_of_component(compname)
             if invdata is None:
                 newinf = {'present': False, 'information': None}
             else:
                 sanitize_invdata(invdata)
                 newinf = {'present': True, 'information': invdata}
             newinf['name'] = compname
             invitems.append(newinf)
     except ssl.SSLEOFError:
         errorneeded = msg.ConfluentNodeError(
             self.node, 'Unable to communicate with the https server on '
                        'the target BMC while trying to read extended '
                        'information')
     except exc.PubkeyInvalid:
         errorneeded = msg.ConfluentNodeError(
             self.node,
             'Extended information unavailable, mismatch detected between '
             'target certificate fingerprint and '
             'pubkeys.tls_hardwaremanager attribute')
     newinvdata = {'inventory': invitems}
     self.output.put(msg.KeyValueData(newinvdata, self.node))
     if errorneeded:
         self.output.put(errorneeded)
Ejemplo n.º 17
0
def retrieve_inventory(configmanager, creds, node, results, element):
    if len(element) == 3:
        results.put(msg.ChildCollection('all'))
        results.put(msg.ChildCollection('system'))
        return
    wc = cnos_login(node, configmanager, creds)
    sysinfo = wc.grab_json_response('/nos/api/sysinfo/inventory')
    invinfo = {
        'inventory': [{
            'name': 'System',
            'present': True,
            'information': {
                'Product name': sysinfo['Model'],
                'Serial Number': sysinfo['Electronic Serial Number'],
                'Board Serial Number': sysinfo['Serial Number'],
                'Manufacturer': 'Lenovo',
                'Model': sysinfo['Machine Type Model'],
                'FRU Number': sysinfo['FRU'].strip(),
            }
        }]
    }
    results.put(msg.KeyValueData(invinfo, node))
Ejemplo n.º 18
0
def handle_api_request(configmanager, inputdata, operation, pathcomponents):
    if operation == 'retrieve':
        return handle_read_api_request(pathcomponents)
    elif (operation in ('update', 'create')
          and pathcomponents == ['discovery', 'rescan']):
        if inputdata != {'rescan': 'start'}:
            raise exc.InvalidArgumentException()
        rescan()
        return (msg.KeyValueData({'rescan': 'started'}), )
    elif (operation in ('update', 'create')):
        if 'node' not in inputdata:
            raise exc.InvalidArgumentException('Missing node name in input')
        _, queryparms, _, _ = _parameterize_path(pathcomponents[1:])
        if 'by-mac' not in queryparms:
            raise exc.InvalidArgumentException('Must target using "by-mac"')
        mac = queryparms['by-mac'].replace('-', ':')
        if mac not in known_info:
            raise exc.NotFoundException('{0} not found'.format(mac))
        info = known_info[mac]
        handler = info['handler'].NodeHandler(info, configmanager)
        eval_node(configmanager, handler, info, inputdata['node'], manual=True)
        return [msg.AssignedResource(inputdata['node'])]
    raise exc.NotImplementedException('Unable to {0} to {1}'.format(
        operation, '/'.join(pathcomponents)))
Ejemplo n.º 19
0
def handle_read_api_request(pathcomponents, configmanager):
    # TODO(jjohnson2): discovery core.py api handler design, apply it here
    # to make this a less tangled mess as it gets extended
    if len(pathcomponents) == 1:
        return [
            msg.ChildCollection('macs/'),
            msg.ChildCollection('neighbors/')
        ]
    elif pathcomponents[1] == 'neighbors':
        if len(pathcomponents) == 3 and pathcomponents[-1] == 'by-switch':
            return [
                msg.ChildCollection(x + '/')
                for x in list_switches(configmanager)
            ]
        else:
            return _handle_neighbor_query(pathcomponents[2:], configmanager)
    elif len(pathcomponents) == 2:
        if pathcomponents[-1] == 'macs':
            return [
                msg.ChildCollection(x) for x in (  # 'by-node/',
                    'by-mac/', 'by-switch/', 'rescan')
            ]
        elif pathcomponents[-1] == 'neighbors':
            return [msg.ChildCollection('by-switch/')]
        else:
            raise exc.NotFoundException(
                'Unknown networking resource {0}'.format(pathcomponents[-1]))
    if False and pathcomponents[2] == 'by-node':
        # TODO: should be list of node names, and then under that 'by-mac'
        if len(pathcomponents) == 3:
            return [
                msg.ChildCollection(x.replace(':', '-'))
                for x in util.natural_sort(list(_nodesbymac))
            ]
        elif len(pathcomponents) == 4:
            macaddr = pathcomponents[-1].replace('-', ':')
            return dump_macinfo(macaddr)
    elif pathcomponents[2] == 'by-mac':
        if len(pathcomponents) == 3:
            return [
                msg.ChildCollection(x.replace(':', '-'))
                for x in sorted(list(_apimacmap))
            ]
        elif len(pathcomponents) == 4:
            return dump_macinfo(pathcomponents[-1])
    elif pathcomponents[2] == 'by-switch':
        if len(pathcomponents) == 3:
            return [
                msg.ChildCollection(x + '/')
                for x in list_switches(configmanager)
            ]
        if len(pathcomponents) == 4:
            return [msg.ChildCollection('by-port/')]
        if len(pathcomponents) == 5:
            switchname = pathcomponents[-2]
            if switchname not in _macsbyswitch:
                raise exc.NotFoundException(
                    'No known macs for switch {0}'.format(switchname))
            return [
                msg.ChildCollection(x.replace('/', '-') + '/')
                for x in util.natural_sort(list(_macsbyswitch[switchname]))
            ]
        if len(pathcomponents) == 6:
            return [msg.ChildCollection('by-mac/')]
        if len(pathcomponents) == 7:
            switchname = pathcomponents[-4]
            portname = pathcomponents[-2]
            try:
                if portname not in _macsbyswitch[switchname]:
                    portname = portname.replace('-', '/')
                maclist = _macsbyswitch[switchname][portname]
            except KeyError:
                foundsomemacs = False
                if switchname in _macsbyswitch:
                    try:
                        matcher = re.compile(portname)
                    except Exception:
                        raise exc.InvalidArgumentException(
                            'Invalid regular expression specified')
                    maclist = []
                    for actualport in _macsbyswitch[switchname]:
                        if bool(matcher.match(actualport)):
                            foundsomemacs = True
                            maclist = maclist + _macsbyswitch[switchname][
                                actualport]
                if not foundsomemacs:
                    raise exc.NotFoundException('No known macs for switch {0} '
                                                'port {1}'.format(
                                                    switchname, portname))
            return [
                msg.ChildCollection(x.replace(':', '-'))
                for x in sorted(maclist)
            ]
        if len(pathcomponents) == 8:
            return dump_macinfo(pathcomponents[-1])
    elif pathcomponents[2] == 'rescan':
        return [msg.KeyValueData({'scanning': mapupdating.locked()})]
    raise exc.NotFoundException('Unrecognized path {0}'.format(
        '/'.join(pathcomponents)))
Ejemplo n.º 20
0
def get_importing_status(importkey):
    yield msg.KeyValueData(importing[importkey].progress)
Ejemplo n.º 21
0
def _dump_neighbordatum(info):
    return [msg.KeyValueData(info)]