Example #1
0
    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)
Example #2
0
 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
Example #3
0
 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))
Example #4
0
 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]
Example #5
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']
Example #6
0
 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))
Example #7
0
 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))
Example #8
0
    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()
Example #9
0
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)
Example #10
0
 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))
Example #11
0
    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