def check_ip(self): network_segment = IP(self.start_ip + '/' + self.netmask, make_net=True) ret = dict() # 起止IP必须在同一个网段中 if IP(self.end_ip) not in network_segment: ret['state'] = ji.Common.exchange_state(41251) raise ji.PreviewingError(json.dumps(ret, ensure_ascii=False)) # 网关必须与将分配给Guest的IP,处于同一个网段中 if IP(self.gateway) not in network_segment: ret['state'] = ji.Common.exchange_state(41252) raise ji.PreviewingError(json.dumps(ret, ensure_ascii=False)) # 网关不能是网络地址或广播地址 if IP(self.gateway) in [network_segment[i] for i in (0, -1)]: ret['state'] = ji.Common.exchange_state(41253) raise ji.PreviewingError(json.dumps(ret, ensure_ascii=False)) # 当用户输入的起始IP为网络地址时,自动重置其为该网段中第一个可用IP if self.start_ip == network_segment[0].__str__(): self.start_ip = intToIp( (int(IP(self.start_ip).strDec()) + 1).__str__(), 4) # 当用户输入的结束IP为广播地址时,自动重置其为该网段中最后一个可用IP if self.end_ip == network_segment[-1].__str__(): self.end_ip = intToIp( (int(IP(self.end_ip).strDec()) - 1).__str__(), 4) # 起始的可用IP地址必须小于结束的可用IP地址 if IP(self.start_ip) >= IP(self.end_ip): ret['state'] = ji.Common.exchange_state(41254) raise ji.PreviewingError(json.dumps(ret, ensure_ascii=False)) return True
def update(self): if not self.exist(): ret = dict() ret['state'] = ji.Common.exchange_state(40401) ret['state']['sub']['zh-cn'] = ''.join([ ret['state']['sub']['zh-cn'], ': ', self._primary_key.__str__() ]) raise ji.PreviewingError(json.dumps(ret, ensure_ascii=False)) sql_stmt = ("UPDATE " + self._table_name + " SET " + ', '.join([ '{0} = %({0})s'.format(key) for key in filter( lambda _key: _key != self._primary_key, self.__dict__.keys()) ]) + " WHERE " + '{0} = %({0})s'.format(self._primary_key)) cnx = db.cnxpool.get_connection() cursor = cnx.cursor(dictionary=True, buffered=True) try: cursor.execute(sql_stmt, self.__dict__) cnx.commit() except errors.IntegrityError, e: ret = dict() if e.errno == errorcode.ER_DUP_ENTRY: ret['state'] = ji.Common.exchange_state(40901) elif e.errno == errorcode.ER_BAD_NULL_ERROR: ret['state'] = ji.Common.exchange_state(41202) else: ret['state'] = ji.Common.exchange_state(50002) ret['state']['sub']['zh-cn'] = ''.join( [ret['state']['sub']['zh-cn'], ': ', e.msg]) raise ji.PreviewingError(json.dumps(ret, ensure_ascii=False))
def r_change_password(): args_rules = [ Rules.ID.value ] user = User() user.id = g.token.get('uid', 0).__str__() try: ji.Check.previewing(args_rules, user.__dict__) user.get() old_password = request.json.get('old_password', '') if not ji.Security.ji_pbkdf2_check(password=old_password, password_hash=user.password): ret = dict() ret['state'] = ji.Common.exchange_state(40101) ret['state']['sub']['zh-cn'] = ''.join([ret['state']['sub']['zh-cn'], u': 鉴权失败']) raise ji.PreviewingError(json.dumps(ret, ensure_ascii=False)) args_rules = [ Rules.PASSWORD.value ] user.password = request.json.get('password') ji.Check.previewing(args_rules, user.__dict__) user.password = ji.Security.ji_pbkdf2(user.password) user.update() except ji.PreviewingError, e: return json.loads(e.message)
def r_sign_in(): args_rules = [ Rules.LOGIN_NAME.value, Rules.PASSWORD.value ] user = User() user.login_name = request.json.get('login_name') user.password = request.json.get('password') try: ji.Check.previewing(args_rules, user.__dict__) plain_password = user.password user.get_by('login_name') if not ji.Security.ji_pbkdf2_check(password=plain_password, password_hash=user.password): ret = dict() ret['state'] = ji.Common.exchange_state(40101) ret['state']['sub']['zh-cn'] = ''.join([ret['state']['sub']['zh-cn'], u': 鉴权失败']) raise ji.PreviewingError(json.dumps(ret, ensure_ascii=False)) token = Utils.generate_token(user.id) session['token'] = token rep = make_response() rep.data = json.dumps({'state': ji.Common.exchange_state(20000)}, ensure_ascii=False) return rep except ji.PreviewingError, e: return json.loads(e.message)
def create(self): sql_stmt = ( "INSERT INTO " + self._table_name + " (" + ', '.join( filter(lambda _key: _key != self._primary_key, self.__dict__.keys())) + ") VALUES (" + ', '.join([ '%({0})s'.format(key) for key in filter(lambda _key: _key != self._primary_key, self.__dict__.keys()) ]) + ")") cnx = db.cnxpool.get_connection() cursor = cnx.cursor(dictionary=True, buffered=True) try: cursor.execute(sql_stmt, self.__dict__) self.__setattr__(self._primary_key, cursor.lastrowid) cnx.commit() except errors.IntegrityError, e: ret = dict() if e.errno == errorcode.ER_DUP_ENTRY: ret['state'] = ji.Common.exchange_state(40901) elif e.errno == errorcode.ER_BAD_NULL_ERROR: ret['state'] = ji.Common.exchange_state(41202) else: ret['state'] = ji.Common.exchange_state(50002) ret['state']['sub']['zh-cn'] = ''.join( [ret['state']['sub']['zh-cn'], ': ', e.msg]) raise ji.PreviewingError(json.dumps(ret, ensure_ascii=False))
def get_by(self, field): sql_stmt = ("SELECT " + ', '.join(self.__dict__.keys()) + " FROM " + self._table_name + " WHERE " + '{0} = %({0})s'.format(field) + " LIMIT 1") cnx = db.cnxpool.get_connection() cursor = cnx.cursor(dictionary=True, buffered=True) try: cursor.execute(sql_stmt, self.__dict__) row = cursor.fetchone() finally: cursor.close() cnx.close() if isinstance(row, dict): self.__dict__ = row else: ret = dict() ret['state'] = ji.Common.exchange_state(40401) ret['state']['sub']['zh-cn'] = ': '.join([ ret['state']['sub']['zh-cn'], field.__str__(), self.__getattribute__(field).__str__() ]) raise ji.PreviewingError(json.dumps(ret, ensure_ascii=False))
def delete(self): if not self.exist(): ret = dict() ret['state'] = ji.Common.exchange_state(40401) ret['state']['sub']['zh-cn'] = ''.join([ret['state']['sub']['zh-cn'], ': ', self._primary_key.__str__()]) raise ji.PreviewingError(json.dumps(ret, ensure_ascii=False)) sql_stmt = ("DELETE FROM " + self._table_name + " WHERE " + '{0} = %({0})s'.format(self._primary_key)) cnx = db.cnxpool.get_connection() cursor = cnx.cursor(dictionary=True, buffered=True) try: cursor.execute(sql_stmt, self.__dict__) cnx.commit() finally: cursor.close() cnx.close()
def r_create(): args_rules = [ Rules.CPU.value, Rules.MEMORY.value, Rules.BANDWIDTH.value, Rules.BANDWIDTH_UNIT.value, Rules.OS_TEMPLATE_IMAGE_ID.value, Rules.QUANTITY.value, Rules.REMARK.value, Rules.PASSWORD.value, Rules.LEASE_TERM.value ] if 'node_id' in request.json: args_rules.append( Rules.NODE_ID.value ) if 'ssh_keys_id' in request.json: args_rules.append( Rules.SSH_KEYS_ID.value ) try: ret = dict() ret['state'] = ji.Common.exchange_state(20000) ji.Check.previewing(args_rules, request.json) config = Config() config.id = 1 config.get() os_template_image = OSTemplateImage() os_template_profile = OSTemplateProfile() os_template_image.id = request.json.get('os_template_image_id') if not os_template_image.exist(): ret['state'] = ji.Common.exchange_state(40450) ret['state']['sub']['zh-cn'] = ''.join([ret['state']['sub']['zh-cn'], ': ', os_template_image.id.__str__()]) return ret os_template_image.get() os_template_profile.id = os_template_image.os_template_profile_id os_template_profile.get() os_template_initialize_operates, os_template_initialize_operates_count = \ OSTemplateInitializeOperate.get_by_filter( filter_str='os_template_initialize_operate_set_id:eq:' + os_template_profile.os_template_initialize_operate_set_id.__str__()) if db.r.scard(app.config['ip_available_set']) < 1: ret['state'] = ji.Common.exchange_state(50350) return ret node_id = request.json.get('node_id', None) # 默认只取可随机分配虚拟机的 hosts available_hosts = Host.get_available_hosts(nonrandom=False) # 当指定了 host 时,取全部活着的 hosts if node_id is not None: available_hosts = Host.get_available_hosts(nonrandom=None) if available_hosts.__len__() == 0: ret['state'] = ji.Common.exchange_state(50351) return ret available_hosts_mapping_by_node_id = dict() for host in available_hosts: if host['node_id'] not in available_hosts_mapping_by_node_id: available_hosts_mapping_by_node_id[host['node_id']] = host if node_id is not None and node_id not in available_hosts_mapping_by_node_id: ret['state'] = ji.Common.exchange_state(50351) return ret ssh_keys_id = request.json.get('ssh_keys_id', list()) ssh_keys = list() ssh_key_guest_mapping = SSHKeyGuestMapping() if ssh_keys_id.__len__() > 0: rows, _ = SSHKey.get_by_filter( filter_str=':'.join(['id', 'in', ','.join(_id.__str__() for _id in ssh_keys_id)])) for row in rows: ssh_keys.append(row['public_key']) bandwidth = request.json.get('bandwidth') bandwidth_unit = request.json.get('bandwidth_unit') if bandwidth_unit == 'k': bandwidth = bandwidth * 1000 elif bandwidth_unit == 'm': bandwidth = bandwidth * 1000 ** 2 elif bandwidth_unit == 'g': bandwidth = bandwidth * 1000 ** 3 else: ret = dict() ret['state'] = ji.Common.exchange_state(41203) raise ji.PreviewingError(json.dumps(ret, ensure_ascii=False)) # http://man7.org/linux/man-pages/man8/tc.8.html # 如果带宽大于 tc 所控最大速率,则置其为无限带宽 # 34359738360 等于 tc 最大可控字节速率,换算出的比特位 if bandwidth > 34359738360: bandwidth = 0 quantity = request.json.get('quantity') while quantity: quantity -= 1 guest = Guest() guest.uuid = uuid4().__str__() guest.cpu = request.json.get('cpu') # 虚拟机内存单位,模板生成方法中已置其为GiB guest.memory = request.json.get('memory') guest.bandwidth = bandwidth guest.os_template_image_id = request.json.get('os_template_image_id') guest.label = ji.Common.generate_random_code(length=8) guest.remark = request.json.get('remark', '') guest.password = request.json.get('password') if guest.password is None or guest.password.__len__() < 1: guest.password = ji.Common.generate_random_code(length=16) guest.ip = db.r.spop(app.config['ip_available_set']) db.r.sadd(app.config['ip_used_set'], guest.ip) guest.network = config.vm_network guest.manage_network = config.vm_manage_network guest.vnc_port = db.r.spop(app.config['vnc_port_available_set']) db.r.sadd(app.config['vnc_port_used_set'], guest.vnc_port) guest.vnc_password = ji.Common.generate_random_code(length=16) disk = Disk() disk.uuid = guest.uuid disk.remark = guest.label.__str__() + '_SystemImage' disk.format = 'qcow2' disk.sequence = 0 disk.size = 0 disk.path = config.storage_path + '/' + disk.uuid + '.' + disk.format disk.guest_uuid = '' # disk.node_id 由 guest 事件处理机更新。涉及迁移时,其所属 node_id 会变更。参见 @models/event_processory.py:111 附近。 disk.node_id = 0 disk.quota(config=config) disk.create() if node_id is None: # 在可用计算节点中平均分配任务 chosen_host = available_hosts[quantity % available_hosts.__len__()] else: chosen_host = available_hosts_mapping_by_node_id[node_id] guest.node_id = chosen_host['node_id'] guest_xml = GuestXML(host=chosen_host, guest=guest, disk=disk, config=config, os_type=os_template_profile.os_type) guest.xml = guest_xml.get_domain() guest.node_id = int(guest.node_id) guest.create() ssh_key_guest_mapping.guest_uuid = guest.uuid if ssh_keys_id.__len__() > 0: for ssh_key_id in ssh_keys_id: ssh_key_guest_mapping.ssh_key_id = ssh_key_id ssh_key_guest_mapping.create() # 替换占位符为有效内容 _os_template_initialize_operates = copy.deepcopy(os_template_initialize_operates) for k, v in enumerate(_os_template_initialize_operates): _os_template_initialize_operates[k]['content'] = v['content'].replace('{IP}', guest.ip).\ replace('{HOSTNAME}', guest.label). \ replace('{PASSWORD}', guest.password). \ replace('{NETMASK}', config.netmask).\ replace('{GATEWAY}', config.gateway).\ replace('{DNS1}', config.dns1).\ replace('{DNS2}', config.dns2). \ replace('{SSH-KEY}', '\n'.join(ssh_keys)) _os_template_initialize_operates[k]['command'] = v['command'].replace('{IP}', guest.ip). \ replace('{HOSTNAME}', guest.label). \ replace('{PASSWORD}', guest.password). \ replace('{NETMASK}', config.netmask). \ replace('{GATEWAY}', config.gateway). \ replace('{DNS1}', config.dns1). \ replace('{DNS2}', config.dns2). \ replace('{SSH-KEY}', '\n'.join(ssh_keys)) message = { '_object': 'guest', 'action': 'create', 'uuid': guest.uuid, 'storage_mode': config.storage_mode, 'dfs_volume': config.dfs_volume, 'node_id': guest.node_id, 'name': guest.label, 'template_path': os_template_image.path, 'os_type': os_template_profile.os_type, 'disks': [disk.__dict__], 'xml': guest_xml.get_domain(), 'os_template_initialize_operates': _os_template_initialize_operates, 'passback_parameters': {} } Utils.emit_instruction(message=json.dumps(message, ensure_ascii=False)) return ret except ji.PreviewingError, e: return json.loads(e.message)