def post(capsule_id, user): sshkey_data = request.get_json() capsule = _get_capsule(capsule_id, user) for public_key in sshkey_data: if not valid_sshkey(public_key): raise BadRequest(description=f"'{public_key}' is not " "a valid ssh public key") for key in capsule.authorized_keys: if public_key == key.public_key: raise Conflict(description="'public_key' already exist " "for this capsule") sshkey = SSHKey(public_key=public_key) capsule.authorized_keys.append(sshkey) db.session.commit() now = datetime.datetime.now() if now > (capsule.no_update + datetime.timedelta(hours=24)): nats.publish_webapp_present(capsule) result = Capsule.query.filter_by(id=capsule_id).first() return capsule_output_schema.dump(result), 201, { 'Location': f'{request.base_url}/capsules/{capsule.id}', }
def r_create(): args_rules = [Rules.LABEL.value, Rules.PUBLIC_KEY.value] try: ret = dict() ret['state'] = ji.Common.exchange_state(20000) ji.Check.previewing(args_rules, request.json) ssh_key = SSHKey() ssh_key.label = request.json.get('label') ssh_key.public_key = request.json.get('public_key') if ssh_key.exist_by('public_key'): ret['state'] = ji.Common.exchange_state(40901) ret['state']['sub']['zh-cn'] = ''.join( [ret['state']['sub']['zh-cn'], ': ', ssh_key.public_key]) return ret ssh_key.create() return ret except ji.PreviewingError, e: return json.loads(e.message)
def update_ssh_key(uuid): guest = Guest() guest.uuid = uuid guest.get_by('uuid') # 不支持更新离线虚拟机的 SSH-KEY if guest.status != GuestState.running.value: return os_template_image = OSTemplateImage() os_template_profile = OSTemplateProfile() os_template_image.id = guest.os_template_image_id os_template_image.get() os_template_profile.id = os_template_image.os_template_profile_id os_template_profile.get() # 不支持更新 Windows 虚拟机的 SSH-KEY if os_template_profile.os_type == 'windows': return rows, _ = SSHKeyGuestMapping.get_by_filter( filter_str=':'.join(['guest_uuid', 'eq', uuid])) ssh_keys_id = list() for row in rows: ssh_keys_id.append(row['ssh_key_id'].__str__()) ssh_keys = list() if ssh_keys_id.__len__() > 0: rows, _ = SSHKey.get_by_filter( filter_str=':'.join(['id', 'in', ','.join(ssh_keys_id)])) for row in rows: ssh_keys.append(row['public_key']) else: ssh_keys.append('') message = { '_object': 'guest', 'uuid': uuid, 'node_id': guest.node_id, 'action': 'update_ssh_key', 'ssh_keys': ssh_keys, 'os_type': os_template_profile.os_type, 'passback_parameters': { 'uuid': uuid, 'ssh_keys': ssh_keys, 'os_type': os_template_profile.os_type } } Utils.emit_instruction(message=json.dumps(message, ensure_ascii=False))
def create_ssh_key(request): if request.method == 'POST': form = SSHKeyForm(request.POST,request.FILES) if form.is_valid(): key = SSHKey(name=form.cleaned_data['name'],key=form.cleaned_data['rsa_key'],user=request.user) # key = form.save(commit=False) # key.user=request.user key.save() from settings.settings import AUTHORIZED_KEYS_FILE import subprocess # subprocess.check_call(['/bin/chmod','600',AUTHORIZED_KEYS_FILE]) auth_keys = open(AUTHORIZED_KEYS_FILE, "a") auth_keys.write(key.create_authorized_key()+'\n') auth_keys.close() # subprocess.check_call(['/bin/chmod','400',AUTHORIZED_KEYS_FILE]) return HttpResponseRedirect(reverse('list_ssh_keys')) else: form = SSHKeyForm() return render(request, 'ssh/new_key.html', {'form': form})
def r_get(uuids): ret = guest_base.get(ids=uuids, ids_rule=Rules.UUIDS.value, by_field='uuid') if '200' != ret['state']['code']: return ret rows, _ = SSHKeyGuestMapping.get_by_filter(filter_str=':'.join(['guest_uuid', 'in', uuids])) guest_uuid_ssh_key_id_mapping = dict() ssh_keys_id = list() for row in rows: if row['ssh_key_id'] not in ssh_keys_id: ssh_keys_id.append(row['ssh_key_id'].__str__()) if row['guest_uuid'] not in guest_uuid_ssh_key_id_mapping: guest_uuid_ssh_key_id_mapping[row['guest_uuid']] = list() guest_uuid_ssh_key_id_mapping[row['guest_uuid']].append(row['ssh_key_id']) rows, _ = SSHKey.get_by_filter(filter_str=':'.join(['id', 'in', ','.join(ssh_keys_id)])) ssh_key_id_mapping = dict() for row in rows: row['url'] = url_for('v_ssh_keys.show') ssh_key_id_mapping[row['id']] = row if -1 == uuids.find(','): if 'ssh_keys' not in ret['data']: ret['data']['ssh_keys'] = list() if ret['data']['uuid'] in guest_uuid_ssh_key_id_mapping: for ssh_key_id in guest_uuid_ssh_key_id_mapping[ret['data']['uuid']]: if ssh_key_id not in ssh_key_id_mapping: continue ret['data']['ssh_keys'].append(ssh_key_id_mapping[ssh_key_id]) else: for i, guest in enumerate(ret['data']): if 'ssh_keys' not in ret['data'][i]: ret['data'][i]['ssh_keys'] = list() if ret['data'][i]['uuid'] in guest_uuid_ssh_key_id_mapping: for ssh_key_id in guest_uuid_ssh_key_id_mapping[ret['data'][i]['uuid']]: if ssh_key_id not in ssh_key_id_mapping: continue ret['data'][i]['ssh_keys'].append(ssh_key_id_mapping[ssh_key_id]) return ret
def get_user_ssh_keys(username): username = pipes.quote(username) keyFile = open("/home/" + username + "/.ssh/authorized_keys", "r") keys = [] for line in keyFile.read().split("\n"): if line: k = sshpubkeys.SSHKey(line) keys.append(SSHKey(k.comment, k.hash_md5())) keyFile.close() return keys
def post(user): sshkey_data = request.get_json() # data = sshkey_schema.load(sshkey_data) if 'public_key' not in sshkey_data: raise BadRequest("The key 'public_key' is required.") public_key = sshkey_data["public_key"] if not valid_sshkey(public_key): raise BadRequest(description=f"'{public_key}' is not " "a valid ssh public key") sshkey = SSHKey(public_key=public_key, user_id=user.id) db.session.add(sshkey) db.session.commit() nats_publish_webapp_present(user) result = SSHKey.query.get(sshkey.id) return sshkey_schema.dump(result), 201, { 'Location': f'{request.base_url}/sshkeys/{sshkey.id}', }
def __init__(self, db): self.validation_rule1 = AvailableOptionValidationRule( type=ValidationRuleEnum.min, arg="1", ) self.validation_rule2 = AvailableOptionValidationRule( type=ValidationRuleEnum.max, arg="42", ) self.validation_rule1bis = AvailableOptionValidationRule( type=ValidationRuleEnum.min, arg="1", ) self.validation_rule2bis = AvailableOptionValidationRule( type=ValidationRuleEnum.max, arg="42", ) self.validation_rule3 = AvailableOptionValidationRule( type=ValidationRuleEnum.regex, arg="^[a-z0-9][-a-z0-9]*[a-z0-9]$", ) self.validation_rule4 = AvailableOptionValidationRule( type=ValidationRuleEnum.eq, arg="foobar", ) self.validation_rule5 = AvailableOptionValidationRule( type=ValidationRuleEnum.neq, arg="barfoo", ) self.validation_rule6 = AvailableOptionValidationRule( type=ValidationRuleEnum.format, arg="json", ) self.validation_rule7 = AvailableOptionValidationRule( type=ValidationRuleEnum.into, arg="[a, b, c]", ) self.available_opt1 = AvailableOption( access_level=RoleEnum.user, tag="Apache", field_name="vhost.conf", value_type=OptionValueTypeEnum.base64, field_description="Apache2 vhost configuration file.", default_value="", ) self.available_opt2 = AvailableOption( access_level=RoleEnum.user, tag="PHP", field_name="worker", value_type=OptionValueTypeEnum.integer, field_description="PHP worker count.", default_value="6", validation_rules=[ self.validation_rule1, self.validation_rule2, ], ) self.available_opt2bis = AvailableOption( access_level=RoleEnum.user, tag="PHP", field_name="test_min_max", value_type=OptionValueTypeEnum.integer, field_description="Test min and max option rules", default_value="6", validation_rules=[ self.validation_rule1bis, self.validation_rule2bis, ], ) self.available_opt3 = AvailableOption( access_level=RoleEnum.user, tag="SQL", field_name="my.cnf", value_type=OptionValueTypeEnum.base64, field_description="MySQL configuration file.", ) self.available_opt4 = AvailableOption( access_level=RoleEnum.admin, tag="PHP", field_name="test_regex", value_type=OptionValueTypeEnum.string, field_description="Test regex option rule", validation_rules=[ self.validation_rule3, ] ) self.available_opt5 = AvailableOption( access_level=RoleEnum.admin, tag="PHP", field_name="test_eq", value_type=OptionValueTypeEnum.string, field_description="Test eq option rule", validation_rules=[ self.validation_rule4, ] ) self.available_opt6 = AvailableOption( access_level=RoleEnum.admin, tag="PHP", field_name="test_neq", value_type=OptionValueTypeEnum.string, field_description="Test neq option rule", validation_rules=[ self.validation_rule5, ] ) self.available_opt7 = AvailableOption( access_level=RoleEnum.admin, tag="PHP", field_name="test_format", value_type=OptionValueTypeEnum.string, field_description="Test format option rule", validation_rules=[ self.validation_rule6, ] ) self.available_opt8 = AvailableOption( access_level=RoleEnum.admin, tag="PHP", field_name="test_into", value_type=OptionValueTypeEnum.string, field_description="Test into option rule", validation_rules=[ self.validation_rule7, ] ) self.runtime1 = Runtime( name="apache-2.4 php-7.2.x", description="Stack web classique Apache 2.4 + PHP 7.2.x", fam="Apache PHP", runtime_type=RuntimeTypeEnum.webapp, available_opts=[ self.available_opt1, self.available_opt2, ], ) self.runtime2 = Runtime( name="MariaDB 10.1", description="SQL server", fam="SQL", runtime_type=RuntimeTypeEnum.addon, available_opts=[ self.available_opt3, ], uri_template='{"pattern": "mysql://{udbname}:{password}@' 'host:port/{udbname}",' '"variables": [{"length": 16, "name": "udbname", ' '"src": "capsule", "unique": true, "set_name": true},' '{"length": 32, "name": "password", ' '"set_name": false, "src": "random", ' '"unique": false}]}', ) self.runtime3 = Runtime( name="MariaDB 12.1", description="SQL server", fam="SQL", runtime_type=RuntimeTypeEnum.addon, ) self.runtime4 = Runtime( name="apache-3.1 php-9.3.x", description="Stack web futuriste Apache 3.1 + PHP 9.3.x", fam="Apache PHP", runtime_type=RuntimeTypeEnum.webapp, available_opts=[ self.available_opt2bis, self.available_opt4, self.available_opt5, self.available_opt6, self.available_opt7, self.available_opt8, ], ) self.fqdn1 = FQDN( name="main.fqdn.ac-versailles.fr", alias=False, ) self.fqdn2 = FQDN( name="secondary.fqdn.ac-versailles.fr", alias=True, ) self.option1 = Option( field_name="worker", tag="PHP", value="42", value_type='integer', ) self.cron1 = Cron( command="rm -rf *", hour="*/6", minute="15", month="*", ) self.webapp1 = WebApp( env='{"HTTP_PROXY": "http://*****:*****@doe", ) self.sshkey2 = SSHKey( public_key="ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC/YCx71smBufMXF" "thQQsjSW18adRCpI5L+I8z4qtx+8SQeTSFWZF/E9QSgG6UoajwzCb" "5oQM/+M9Hmel1rSUUfjGx8HQV4smVbCRTgRGDJTpFhbvoeO0AC6YJ" "6n/eBzu0zKVlW0UqMqJU1cQLWgnFfSDURmzLHlnPn467uXPx5Pw==" " jane@doe", ) self.sshkey3 = SSHKey( public_key="ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDCVu8lOZxm+7fjM" "QpdNuU2HinAhWmmEtYcX9wxCcBs14GmDrDSOhZB61bq9vdzkSlV0W" "st711mUlEZlXh/999NL7iAy6COKYxsEmRgbCU+9k8rBsSTDcXS6MW" "+aJI4vnqMgVSGwBDgxZs4X2mthYhCitgbk9D3WbstAinUkhEtzQ==" " phpseclib-generated-key" ) token = "KDCte1raIV-ItPQf-sf_tapY4q-kLmvlcJ9yUKPlqbo" hashed_token = sha512(token.encode('ascii')).hexdigest() self.apptoken1 = AppToken( app="My super app", token=hashed_token) # Users. self.admin_user = User( name="admin_user", role=RoleEnum.admin) self.superadmin_user = User( name="superadmin_user", role=RoleEnum.superadmin) self.fake_user = User( name="fake_user", role=RoleEnum.user) self.user1 = User( name="user1", role=RoleEnum.user) self.user2 = User( name="user2", role=RoleEnum.user) self.user3 = User( name="user3", role=RoleEnum.user) self.user1.public_keys.append(self.sshkey1) self.user2.public_keys.append(self.sshkey2) self.user3.apptokens.append(self.apptoken1) self.capsule1 = Capsule( name="test-default-capsule", owners=[ self.user1, self.user2, ], webapp=self.webapp1, addons=[ self.addon1, ], authorized_keys=[ self.sshkey2, self.sshkey3, ], fqdns=[ self.fqdn1, self.fqdn2, ], force_redirect_https=True, enable_https=True, ) array_obj = [] for name, value in vars(self).items(): array_obj.append(value) db.session.add_all(array_obj) db.session.commit() # Just handy in test functions. self.users = [ self.admin_user, self.superadmin_user, self.fake_user, self.user1, self.user2, self.user3, ] self.runtimes = [ self.runtime1, self.runtime2, self.runtime3, self.runtime4, ]
def r_content_search(): ret = guest_base.content_search() uuids = list() for guest in ret['data']: uuids.append(guest['uuid']) rows, _ = SSHKeyGuestMapping.get_by_filter(filter_str=':'.join(['guest_uuid', 'in', ','.join(uuids)])) guest_uuid_ssh_key_id_mapping = dict() ssh_keys_id = list() for row in rows: if row['ssh_key_id'] not in ssh_keys_id: ssh_keys_id.append(row['ssh_key_id'].__str__()) if row['guest_uuid'] not in guest_uuid_ssh_key_id_mapping: guest_uuid_ssh_key_id_mapping[row['guest_uuid']] = list() guest_uuid_ssh_key_id_mapping[row['guest_uuid']].append(row['ssh_key_id']) rows, _ = SSHKey.get_by_filter(filter_str=':'.join(['id', 'in', ','.join(ssh_keys_id)])) ssh_key_id_mapping = dict() for row in rows: row['url'] = url_for('v_ssh_keys.show') ssh_key_id_mapping[row['id']] = row rows, _ = Snapshot.get_by_filter(filter_str=':'.join(['guest_uuid', 'in', ','.join(uuids)])) snapshots_guest_uuid_mapping = dict() for row in rows: guest_uuid = row['guest_uuid'] if guest_uuid not in snapshots_guest_uuid_mapping: snapshots_guest_uuid_mapping[guest_uuid] = list() snapshots_guest_uuid_mapping[guest_uuid].append(row) for i, guest in enumerate(ret['data']): guest_uuid = ret['data'][i]['uuid'] if 'ssh_keys' not in ret['data'][i]: ret['data'][i]['ssh_keys'] = list() if guest_uuid in guest_uuid_ssh_key_id_mapping: for ssh_key_id in guest_uuid_ssh_key_id_mapping[guest_uuid]: if ssh_key_id not in ssh_key_id_mapping: continue ret['data'][i]['ssh_keys'].append(ssh_key_id_mapping[ssh_key_id]) if 'snapshot' not in ret['data'][i]: ret['data'][i]['snapshot'] = { 'creatable': True, 'mapping': list() } if guest_uuid in snapshots_guest_uuid_mapping: ret['data'][i]['snapshot']['mapping'] = snapshots_guest_uuid_mapping[guest_uuid] for snapshot in snapshots_guest_uuid_mapping[guest_uuid]: if snapshot['progress'] == 100: continue else: ret['data'][i]['snapshot']['creatable'] = False return ret
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)
def post(): capsule_data = request.get_json() data = capsule_input_schema.load(capsule_data) cluster_parts = getClusterPartsUsage("") if 'size' in data: proposed_parts = SizeEnum.getparts(data['size']) else: proposed_parts = SizeEnum.getparts(SizeEnum.tiny) target_parts = cluster_parts + proposed_parts if target_parts > current_app.config['CLUSTER_PARTS']: msg = 'Please set a lower size for this capsule or prepare '\ 'some Bitcoins... :-)' raise PaymentRequired(description=msg) try: # Check if owners exist on Keycloak check_owners_on_keycloak(data['owners']) except KeycloakUserNotFound as e: raise BadRequest( description=f'{e.missing_username} is an invalid user.') # Get existent users, create the others for i, owner in enumerate(data['owners']): user = User.query.filter_by(name=owner).one_or_none() if user is None: # User does not exist in DB data['owners'][i] = User(name=owner, role=RoleEnum.user) else: data['owners'][i] = user # Get existent ssh keys, create the others if 'authorized_keys' in data: for i, public_key in enumerate(data['authorized_keys']): sshkey = SSHKey.query\ .filter_by(public_key=public_key).one_or_none() if sshkey is None: data['authorized_keys'][i] = SSHKey(public_key=public_key) else: data['authorized_keys'][i] = sshkey capsule_name = data['name'] # https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#dns-label-names if not is_valid_name(capsule_name): msg = f'The capsule name "{capsule_name}" is invalid: only lowercase '\ 'alphanumeric characters or "-" are allowed, the first and the '\ 'last characters must be alphanumeric, the name must have at '\ 'least 2 characters and less than 64 characters.' raise BadRequest(description=msg) newArgs = dict() if "fqdns" in data: fqdns_list = [e['name'] for e in data["fqdns"]] if len(fqdns_list) != len(set(fqdns_list)): raise BadRequest(description='Repetitions are not ' 'allowed for FQDNs') try: fqdns = FQDN.create(data["fqdns"]) except FQDNAlreadyExists as e: raise BadRequest(description=f'{e.existing_fqdn} already exists.') data.pop("fqdns") newArgs["fqdns"] = fqdns caps = Capsule.query.filter_by(name=capsule_name).limit(1).one_or_none() if caps is not None: raise BadRequest(description=f'{capsule_name} already exists.') capsule = Capsule(**data, **newArgs) db.session.add(capsule) db.session.commit() caps = Capsule.query.filter_by(id=capsule.id).first() result = capsule_output_schema.dump(caps) return result, 201, { 'Location': f'{request.base_url}/capsules/{capsule.id}', }
def r_update(_id): ssh_key = SSHKey() args_rules = [Rules.ID.value] if 'label' in request.json: args_rules.append(Rules.LABEL.value, ) if 'public_key' in request.json: args_rules.append(Rules.PUBLIC_KEY.value, ) if args_rules.__len__() < 2: ret = dict() ret['state'] = ji.Common.exchange_state(20000) return ret request.json['id'] = _id try: ji.Check.previewing(args_rules, request.json) ssh_key.id = request.json.get('id') ssh_key.get() ssh_key.label = request.json.get('label', ssh_key.label) ssh_key.public_key = request.json.get('public_key', ssh_key.public_key) ssh_key.update() ssh_key.get() ret = dict() ret['state'] = ji.Common.exchange_state(20000) ret['data'] = ssh_key.__dict__ return ret except ji.PreviewingError, e: return json.loads(e.message)
def r_bind(ssh_key_id, uuids): args_rules = [Rules.SSH_KEY_ID_EXT.value, Rules.UUIDS.value] try: ji.Check.previewing(args_rules, { 'ssh_key_id': ssh_key_id, 'uuids': uuids }) ret = dict() ret['state'] = ji.Common.exchange_state(20000) ssh_key = SSHKey() ssh_key.id = ssh_key_id # 判断 ssh_key id 为 ssh_key_id 的对象是否存在 if not ssh_key.exist(): ret['state'] = ji.Common.exchange_state(40401) ret['state']['sub']['zh-cn'] = ''.join( [ret['state']['sub']['zh-cn'], ': ssh_key_id: ', ssh_key_id]) return ret # 获取已经和该 ssh_key 绑定过的 guest uuid 集合,用于判断是否已经绑定过该 ssh_key,避免重复绑定 rows, _ = SSHKeyGuestMapping.get_by_filter( filter_str=':'.join(['ssh_key_id', 'eq', ssh_key_id])) guests_uuid = list() for row in rows: guests_uuid.append(row['guest_uuid']) ssh_key_guest_mapping = SSHKeyGuestMapping() for uuid in uuids.split(','): # 如果已经绑定过,则忽略 if uuid in guests_uuid: continue ssh_key_guest_mapping.ssh_key_id = ssh_key_id ssh_key_guest_mapping.guest_uuid = uuid ssh_key_guest_mapping.create() update_ssh_key(uuid=uuid) # 返回执行结果 rows, _ = SSHKeyGuestMapping.get_by_filter( filter_str=':'.join(['ssh_key_id', 'eq', ssh_key_id])) guests_uuid = list() for row in rows: guests_uuid.append(row['guest_uuid']) if guests_uuid.__len__() == 0: guests_uuid.append('_') request.__setattr__( 'args', ImmutableMultiDict([ ('filter', ':'.join(['uuid', 'in', ','.join(guests_uuid)])), ('page_size', 10000) ])) return guest_base.get_by_filter() except ji.PreviewingError, e: return json.loads(e.message)