Esempio n. 1
0
    def server_stop(self, context, request_id, names, rack_name, force):
        filters = dict()
        filters['asset.rack.location'] = context.location
        if request_id:
            filters['lock_id'] = request_id
        else:
            if not force:
                raise exceptions.DAOConflict(
                    'force is False and not request_id specified')
            if not rack_name and not names:
                raise exceptions.DAOConflict(
                    'force is True and names or rack_name used')
        if names:
            filters['name'] = names
        if rack_name:
            filters['asset.rack.name'] = rack_name

        servers = self.db.servers_get_by(**filters)
        response = []
        for server in servers:
            if server.lock_id:
                result = server_processor.ServerProcessor(server).stop()
                if result:
                    action = 'Stop sent'
                else:
                    server_processor.ServerProcessor(server).error('stop')
                    action = 'Force unlock'
                response.append('Server {0.name} {1}'.format(server, action))
        return response
Esempio n. 2
0
 def _create_isc_port(self, net, rack, serial, mac, ip):
     """
     :type rack: str
     :type net: dao.control.db.model.Subnet
     :type serial: str
     :type mac: str
     :type ip: str
     :rtype: dao.control.db.model.Port
     """
     ports = self.db.ports_list(vlan_tag=net.vlan_tag, rack_name=rack)
     allocated = [p for p in ports if p.device_id == serial]
     if allocated:
         port = allocated[0]
         if ip and port.ip != ip:
             raise exceptions.DAOConflict(
                 'Port is already created, IP '
                 'mismatch: {0} instead of {1}'.format(port.ip, ip))
     else:
         if not ip:
             # TODO move this hardcode to config opt
             first = (netaddr.IPAddress(net.first_ip).value -
                      net.subnet.value
                      if net.first_ip else CONF.dhcp.first_ip_offset)
             subnet = net.subnet[first:CONF.dhcp.last_ip_offset]
             ips = set(netaddr.IPAddress(p.ip) for p in ports)
             ip = str(list(set(subnet).difference(ips))[0])
         port = self.db.port_create(rack, serial, net.vlan_tag, mac, ip,
                                    net.id)
     return port
Esempio n. 3
0
 def _create_port(self, net_name, rack_name, serial, mac, ip, pxe=False):
     neutron = self._get_client()
     net_id = neutron.list_networks(name=net_name)['networks'][0]['id']
     ports = neutron.list_ports(network_id=net_id, mac_address=mac)
     if ports['ports']:
         port = ports['ports'][0]
         if port['device_owner'] not in ('', self.device_owner):
             raise exceptions.DAOConflict('Port {0} in use, {1}'.format(
                 ip, port['device_owner']))
         old_ip = port['fixed_ips'][0]['ip_address']
         if ip and old_ip != ip:
             raise exceptions.DAOConflict(
                 'Port is already created, IP '
                 'mismatch: {0} instead of {1}'.format(old_ip, ip))
     else:
         body = {
             'port': {
                 'network_id': net_id,
                 'admin_state_up': True,
                 'mac_address': mac.replace('-', ':').lower(),
                 'device_owner': self.device_owner,
                 'device_id': serial
             }
         }
         if ip:
             body['port']['fixed_ips'] = [{'ip_address': ip}]
         else:
             subnet = neutron.list_subnets(
                 network_id=net_id, name=rack_name.lower())['subnets'][0]
             body['port']['fixed_ips'] = [{'subnet_id': subnet['id']}]
         port = neutron.create_port(body)['port']
     if pxe:
         options = [{
             'opt_name': 'bootfile-name',
             'opt_value': 'pxelinux.0'
         }, {
             'opt_name': 'server-ip-address',
             'opt_value': self.tftp_url
         }, {
             'opt_name': 'tftp-server',
             'opt_value': self.tftp_url
         }]
         port_req_body = {'port': {'extra_dhcp_opts': options}}
         neutron.update_port(port['id'], port_req_body)
     return port
Esempio n. 4
0
 def pre_validate(self):
     ironic = ironic_helper.get_client()
     if self.server.asset.status != 'New':
         try:
             ironic.node.get(self.server.name)
             raise exceptions.DAOConflict('Server is managed by Ironic')
         except ironic_helper.exceptions.NotFound:
             pass
     return self.server
Esempio n. 5
0
 def server_delete(self, context, sid, serial, name):
     server = self.db.server_get_by(**{
         'id': int(sid),
         'asset.serial': serial,
         'name': name
     })
     if server.lock_id:
         raise exceptions.DAOConflict('Server {0} is busy'.format(name))
     worker = self._worker_get(context, rack_name=server.asset.rack.name)
     worker = worker_api.WorkerAPI.get_api(worker=worker)
     return worker.call('server_delete', server.id)
Esempio n. 6
0
 def asset_protect(self, context, serial, rack_name, set_protected):
     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))
     try:
         asset = self.db.asset_get_by(serial=serial)
         if asset.rack.name != rack.name:
             raise exceptions.DAOConflict(
                 'Asset {serial} belongs to rack {asset.rack.name}'.format(
                     **locals()))
         asset.protected = set_protected
         asset = self.db.update(asset, log=True)
     except exceptions.DAONotFound:
         if set_protected:
             asset = self.db.asset_create(rack,
                                          serial=serial,
                                          type='Server',
                                          name=serial)
         else:
             raise
     return asset.to_dict()
Esempio n. 7
0
 def cluster_create(self, location, name, cluster_type):
     """ Create Cluster object.
     :rtype: models.Cluster
     """
     try:
         self.cluster_get(name)
         raise exceptions.DAOConflict(
             'Cluster {0} already exists'.format(name))
     except exceptions.DAONotFound:
         cluster = models.Cluster()
         cluster.name = name
         cluster.type = cluster_type
         cluster.location = location or CONF.common.location
         cluster.save()
         return cluster
Esempio n. 8
0
    def server_create(self, cluster, asset, **kwargs):
        """

        :type server: models.Asset
        :return:
        """
        try:
            server = models.Server()
            server.update(kwargs)
            server.asset_id = asset.id
            server.cluster_id = cluster.id
            self.server_get_by(**{'asset.serial': asset.serial})
            raise exceptions.DAOConflict('Server %r exists' % server)
        except exceptions.DAONotFound:
            with Session() as session:
                server.save(session)
                return server
Esempio n. 9
0
 def network_map_create(self, name, port2number, number2unit, pxe_nic,
                        network):
     """ Create NetworkMap new object
     :rtype: models.NetworkMap
     """
     try:
         self.network_map_get(name)
         raise exceptions.DAOConflict(
             'Networking map {0} already exists'.format(name))
     except exceptions.DAONotFound:
         net_map = models.NetworkMap()
         net_map.name = name
         net_map.mgmt_port_map = port2number
         net_map.number2unit = number2unit
         net_map.pxe_nic = pxe_nic
         net_map.network = network
         net_map.save()
         return net_map
Esempio n. 10
0
 def sku_create(self, location, name, cpu, ram, storage, description=''):
     """ Create new SKU object
     :rtype: models.Sku
     """
     with Session() as session:
         try:
             self.sku_get(name)
             raise exceptions.DAOConflict(
                 'SKU <{0}> already exists'.format(name))
         except exceptions.DAONotFound:
             sku = models.Sku()
             sku.name = name
             sku.location = location or CONF.common.location
             sku.cpu = cpu
             sku.ram = ram
             sku.storage = storage
             sku.description = description
             sku.save(session)
             return sku
Esempio n. 11
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()
Esempio n. 12
0
 def port_create(rack_name, device_id, vlan_tag, mac, ip, subnet_id):
     """ Create new port record
     :type rack_name: str
     :type device_id: str
     :type vlan_tag: int
     :type mac: str
     :type ip: str
     :type subnet_id: int
     :rtype: dao.control.db.model.Port
     """
     with Session() as session:
         ports = model_query(models.Port, session=session).\
             filter_by(ip=ip).all()
         if ports:
             raise exceptions.DAOConflict('Port for ip %r exists' % ip)
         p = models.Port()
         p.device_id = device_id
         p.rack_name = rack_name
         p.vlan_tag = vlan_tag
         p.ip = ip
         p.mac = mac
         p.subnet_id = subnet_id
         p.save(session=session)
         return p
Esempio n. 13
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