def test_intospect_failed(self, introspect_mock): introspect_mock.side_effect = utils.Error("boom") res = self.app.post('/v1/introspection/uuid1') self.assertEqual(400, res.status_code) self.assertEqual(b"boom", res.data) introspect_mock.assert_called_once_with("uuid1", setup_ipmi_credentials=False)
def find_node(**attributes): """Find node in cache. :param attributes: attributes known about this node (like macs, BMC etc) :returns: structure NodeInfo with attributes ``uuid`` and ``created_at`` :raises: Error if node is not found """ # NOTE(dtantsur): sorting is not required, but gives us predictability found = set() db = _db() for (name, value) in sorted(attributes.items()): if not value: LOG.debug('Empty value for attribute %s', name) continue if not isinstance(value, list): value = [value] LOG.debug('Trying to use %s of value %s for node look up' % (name, value)) rows = db.execute('select distinct uuid from attributes where ' + ' OR '.join('name=? AND value=?' for _ in value), sum(([name, v] for v in value), [])).fetchall() if rows: found.update(item[0] for item in rows) if not found: raise utils.Error( 'Could not find a node for attributes %s' % attributes, code=404) elif len(found) > 1: raise utils.Error( 'Multiple matching nodes found for attributes %s: %s' % (attributes, list(found)), code=404) uuid = found.pop() row = db.execute('select started_at, finished_at from nodes where uuid=?', (uuid,)).fetchone() if not row: raise utils.Error( 'Could not find node %s in introspection cache, ' 'probably it\'s not on introspection now' % uuid, code=404) if row['finished_at']: raise utils.Error( 'Introspection for node %s already finished on %s' % (uuid, row['finished_at'])) return NodeInfo(uuid=uuid, started_at=row['started_at'])
def test_introspect_failed_authentication(self, introspect_mock, auth_mock): conf.CONF.set('discoverd', 'authenticate', 'true') auth_mock.side_effect = utils.Error('Boom', code=403) res = self.app.post('/v1/introspection/uuid', headers={'X-Auth-Token': 'token'}) self.assertEqual(403, res.status_code) self.assertFalse(introspect_mock.called)
def get_node(uuid): """Get node from cache by it's UUID. :param uuid: node UUID. :returns: structure NodeInfo. """ row = _db().execute('select * from nodes where uuid=?', (uuid,)).fetchone() if row is None: raise utils.Error('Could not find node %s in cache' % uuid, code=404) return NodeInfo.from_row(row)
def before_processing(self, node_info): """Validate that required properties are provided by the ramdisk.""" missing = [key for key in self.KEYS if not node_info.get(key)] if missing: raise utils.Error( 'The following required parameters are missing: %s' % missing) LOG.info( 'Discovered data: CPUs: %(cpus)s %(cpu_arch)s, ' 'memory %(memory_mb)s MiB, disk %(local_gb)s GiB', {key: node_info.get(key) for key in self.KEYS})
def add_node(uuid, **attributes): """Store information about a node under introspection. All existing information about this node is dropped. Empty values are skipped. :param uuid: Ironic node UUID :param attributes: attributes known about this node (like macs, BMC etc) :returns: NodeInfo """ started_at = time.time() with _db() as db: db.execute("delete from nodes where uuid=?", (uuid,)) db.execute("delete from attributes where uuid=?", (uuid,)) db.execute("delete from options where uuid=?", (uuid,)) db.execute("insert into nodes(uuid, started_at) " "values(?, ?)", (uuid, started_at)) for (name, value) in attributes.items(): if not value: continue if not isinstance(value, list): value = [value] try: db.executemany("insert into attributes(name, value, uuid) " "values(?, ?, ?)", [(name, v, uuid) for v in value]) except sqlite3.IntegrityError as exc: LOG.error('Database integrity error %s during ' 'adding attributes', exc) raise utils.Error( 'Some or all of %(name)s\'s %(value)s are already ' 'on introspection' % {'name': name, 'value': value}) return NodeInfo(uuid=uuid, started_at=started_at)
def before_processing(self, node_info): if not node_info.get('error'): return raise utils.Error('Ramdisk reported error: %s' % node_info['error'])
def test_continue_failed(self, process_mock): process_mock.side_effect = utils.Error("boom") res = self.app.post('/v1/continue', data='"JSON"') self.assertEqual(400, res.status_code) process_mock.assert_called_once_with("JSON") self.assertEqual(b'boom', res.data)