def servers_list(self, context, rack_name, cluster_name, serials, ips, macs, names, from_status, sku_name, detailed): # get servers skus = self.db.sku_get_all() if detailed or sku_name else None filters = dict() filters['asset.rack.location'] = context.location if serials: filters['asset.serial'] = serials if rack_name: filters['asset.rack.name'] = rack_name if cluster_name: filters['cluster_id'] = self.db.cluster_get(cluster_name).id if from_status: filters['status'] = from_status if ips: filters['interfaces.ip'] = ips if macs: filters['interfaces.mac'] = [str(netaddr.eui.EUI(m)) for m in macs] if sku_name: try: filters['sku_id'] = [ sku.id for sku in skus if sku.name == sku_name ][0] except IndexError: raise exceptions.DAONotFound( 'SKU <{0}> not found'.format(sku_name)) if names: filters['name'] = names servers = self.db.servers_get_by(**filters) # format servers output return self._servers2dict(servers, skus, detailed)
def _request(self, method, url, params=None, data=None): url = requests.utils.requote_uri('%s/%s' % (self.url, url)) if data: data = json.dumps(data) log_func = logger.debug if method == 'get' else logger.info log_func('%s issued, url=%s, params=%s, data=%s', method, url, params, data) method = getattr(requests, method) for i in range(5): r = method(url=url, auth=(self.user, self.password), data=data, params=params, verify=False, headers={ 'Content-Type': 'application/json', 'Accept': 'version=2,application/json' }) if 200 <= r.status_code < 300: break eventlet.sleep(5) else: if r.status_code == 404: raise exceptions.DAONotFound('%s not found' % url) logger.warning(r.text) data = r.json().get('error') msg = data.get('full_messages') or data.get('message') or r.text raise exceptions.DAOException( 'Text: %r, foreman status code is: %s' % (msg, r.status_code)) r = r.json() # logger.debug('Foreman response: %r', r) return r
def _search_one(self, object_type, **kwargs): obj = self._get_objects_by(object_type, **kwargs) if obj: return obj[0] else: raise exceptions.DAONotFound('Can not find foreman %s, %s' % (object_type, kwargs))
def _get_host_no_cache(self, key, value): # create network kwargs = {key: value} host = self._get_objects_by('hosts', **kwargs) if not host: raise exceptions.DAONotFound('No hosts found for %s: %s' % (key, value)) return host[0]
def ensure_os_family(self, os_args): try: hostgroup = self._search_one('hostgroups', name=os_args['os_name']) except exceptions.DAONotFound: raise exceptions.DAONotFound('OS (hostgroup) {0} not found'.format( os_args['os_name'])) os = self._get_one('operatingsystems', hostgroup['operatingsystem_id']) return os['family']
def get_instance(cls, server): # Leasy discovery brand2cls = dict((i.brand, i) for i in globals().values() if (type(i) is type and issubclass(i, PreValidationBase) and i.brand is not None)) try: return brand2cls[server.asset.brand](server) except KeyError: raise exceptions.DAONotFound('Update backend for {0} is not found'. format(server.asset.brand))
def get_backend(cls, ip): """ :rtype: IPMIHelper """ # In order to support different brands, use SNMP first # ipmitool doesn't work for FX2 chassis try: oid = cls._snmp_invoke(ip, 'SNMPv2-MIB', 'sysObjectID', '0') except exceptions.DAOException, exc: LOG.debug('Unable to communicate to idrac: {0}'.format(repr(exc))) raise exceptions.DAONotFound( 'Backend for {0} is not supported'.format(ip))
def rack_update(self, context, rack_name, env, gw, net_map, worker_name, reset_worker, meta): """Update rack with meta information""" rack = self.db.rack_get(name=rack_name) if rack.location != context.location: raise exceptions.DAOConflict('Rack {0} is not from {1}'.format( rack.name, context.location)) if env: rack.environment = env if gw: # Chech if gateway is meaningful subnets = self.db.subnets_get(rack_name) gateway = netaddr.IPAddress(gw) for net in subnets: if gateway in net.subnet: break else: raise exceptions.DAONotFound('There is no subnet for gateway') rack.gw_ip = gw if net_map: rack.network_map = self.db.network_map_get(name=net_map) if worker_name is not None: worker = self.db.worker_get(name=worker_name) rack.worker = worker elif reset_worker: worker = rack.worker rack.worker = None else: worker = None if meta: rack.meta = meta self.db.update(rack, log=True) if worker: api = worker_api.WorkerAPI.get_api(worker=worker) api.call('dhcp_rack_update', rack_name) return self.db.rack_get(name=rack_name).to_dict()
class IPMIHelper(object): user = CONF.worker.ipmi_login password = CONF.worker.ipmi_password brand_name = None re_vendor = re.compile('Product Manufacturer.*: (\w+)') mib_brand_id = None mib_header = 'iso.org.dod.internet.private.enterprises' def __init__(self, ip, serial, asset_type, chassis_serial): self.ip = ip self.serial = serial self.asset_type = asset_type self.chassis_serial = chassis_serial @classmethod def get_backend(cls, ip): """ :rtype: IPMIHelper """ # In order to support different brands, use SNMP first # ipmitool doesn't work for FX2 chassis try: oid = cls._snmp_invoke(ip, 'SNMPv2-MIB', 'sysObjectID', '0') except exceptions.DAOException, exc: LOG.debug('Unable to communicate to idrac: {0}'.format(repr(exc))) raise exceptions.DAONotFound( 'Backend for {0} is not supported'.format(ip)) oid, label, suffix = mib_view.getNodeNameByOid(oid) backends = [Dell] label = '.'.join(label) for b_cls in backends: if label == b_cls.mib_header and suffix[0] == b_cls.mib_brand_id: return b_cls(ip) else: raise exceptions.DAONotFound('Backend for %s is not supported' % ip)
def rack_get_by_subnet_ip(cls, ip): """ :type ip: str :rtype: models.Rack """ with Session() as session: nds = cls._object_get_by( models.NetworkDevice, [models.SwitchInterface], # Join on interfaces ['asset.rack._network_map', '_interfaces'], session=session, **{ '_interfaces.net_ip': ip }).all() racks = set(nd.asset.rack.id for nd in nds) if racks: if len(racks) == 1: return nds[0].asset.rack else: raise exceptions.DAOManyFound( 'More than one rack for {0}'.format(ip)) else: raise exceptions.DAONotFound( 'No rack found for {0}'.format(ip))
def rack_trigger(self, context, rack_name, cluster_name, role, hdd_type, serial, names, from_status, set_status, target_status, os_args): rack = self.db.rack_get(name=rack_name) if rack.meta.get('maintenance', False): raise exceptions.DAOConflict('Rack is under maintenance') request_id = uuid.uuid4().get_hex() response = ['Request_id={0}'.format(request_id)] LOG.info('Request id: {0}'.format(request_id)) filters = {'asset.rack.location': context.location} if rack_name: filters['asset.rack.name'] = rack_name if serial: filters['asset.serial'] = serial if names: filters['name'] = names if from_status: filters['status'] = from_status servers = self.db.servers_get_by(**filters) if cluster_name: cluster = self.db.cluster_get(cluster_name) if not servers: raise exceptions.DAONotFound( 'No servers were found. Please check filter conditions') for server in servers: old_status = server.status if server.lock_id: response.append('Server {0.id}:{0.name} is busy ' 'with request {0.lock_id}'.format(server)) continue if server.asset.protected: response.append( 'Server {0.id}:{0.name} is protected one'.format(server)) continue if server.meta.get('ironicated', False): response.append('Server {0.key}:{0.name} ' 'is under Ironic control'.format(server)) continue action = None if os_args: server.os_args = os_args if set_status is not None: server.status = set_status if role is not None: server.role = role if cluster_name: server.cluster_set(cluster) if target_status is not None: server.target_status = target_status if hdd_type is not None: server.hdd_type = hdd_type # Ensure current and target statuses _index = server_processor.ServerProcessor.statuses.index if _index(server.status) > _index(server.target_status): action = 'target status is less than current status. Ignored.' elif _index(server.target_status) >= _index('Provisioned'): # for some reason if cluster wasn't assigned cluster_id is '0' # because of this validate cluster_name if not cluster_name and not server.cluster_name: action = 'cluster is not specified. Ignored.' elif not server.role: action = 'role is not specified. Ignored.' # if everything is ok with parameters continue if not action: message = 'Pre-provision clean-up' \ if old_status != server.status else None server.lock_id = request_id server.initiator = context.user server = self.db.server_update(server, message, log=True) started = server_processor.ServerProcessor(server).next() if started: action = 'Processing started' if started else 'ignored' else: action = 'Fields update only, status={0}, ' \ 'target_status={1}'.\ format(server.status, server.target_status) response.append('Server {0.id}:{0.name} {1}'.format( server, action)) return response