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
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
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
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
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)
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()
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
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
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
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
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()
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
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