diff --git a/jcloud/api/aliyun_server_light.py b/jcloud/api/aliyun_server_light.py index 07a6b0b..fdee79c 100644 --- a/jcloud/api/aliyun_server_light.py +++ b/jcloud/api/aliyun_server_light.py @@ -4,6 +4,7 @@ import sys import json import random import time +import uuid from datetime import datetime from typing import Dict, Any @@ -330,37 +331,53 @@ class AliyunLightServerManager: jingrow.log_error("创建密钥对失败", f"为实例 {instance_id} 创建密钥对 {key_pair_name} 时发生错误: {str(e)}") return {'success': False, 'error': str(e), 'message': '密钥对创建失败'} - def list_instance_key_pairs(self, instance_id, region_id='cn-shanghai'): - """获取实例的密钥对列表""" - client = self._get_client(region_id) - try: - request = swas__open20200601_models.ListInstanceKeyPairsRequest( - region_id=region_id, - instance_id=instance_id - ) - runtime = util_models.RuntimeOptions() - response = client.list_instance_key_pairs_with_options(request, runtime) - return {'success': True, 'data': self._convert_response_to_dict(response.body), 'message': '获取密钥对列表成功'} - except Exception as e: - jingrow.log_error("获取密钥对列表失败", f"获取实例 {instance_id} 密钥对列表时发生错误: {str(e)}") - return {'success': False, 'error': str(e), 'message': '获取密钥对列表失败'} - def delete_instance_key_pair(self, instance_id, key_pair_name, region_id='cn-shanghai'): - """删除实例的密钥对""" + + def delete_instance_key_pair(self, instance_id, region_id='cn-shanghai'): + """解绑实例的密钥对""" client = self._get_client(region_id) try: request = swas__open20200601_models.DeleteInstanceKeyPairRequest( region_id=region_id, - instance_id=instance_id, - key_pair_name=key_pair_name + instance_id=instance_id ) runtime = util_models.RuntimeOptions() response = client.delete_instance_key_pair_with_options(request, runtime) + return {'success': True, 'data': self._convert_response_to_dict(response.body), 'message': '密钥对解绑成功'} + except Exception as e: + jingrow.log_error("解绑密钥对失败", f"解绑实例 {instance_id} 密钥对时发生错误: {str(e)}") + return {'success': False, 'error': str(e), 'message': '密钥对解绑失败'} + + def delete_key_pairs(self, key_pair_names, region_id='cn-shanghai'): + """删除密钥对""" + client = self._get_client(region_id) + try: + request = swas__open20200601_models.DeleteKeyPairsRequest( + region_id=region_id, + key_pair_names=key_pair_names + ) + runtime = util_models.RuntimeOptions() + response = client.delete_key_pairs_with_options(request, runtime) return {'success': True, 'data': self._convert_response_to_dict(response.body), 'message': '密钥对删除成功'} except Exception as e: - jingrow.log_error("删除密钥对失败", f"删除实例 {instance_id} 密钥对 {key_pair_name} 时发生错误: {str(e)}") + jingrow.log_error("删除密钥对失败", f"删除密钥对 {key_pair_names} 时发生错误: {str(e)}") return {'success': False, 'error': str(e), 'message': '密钥对删除失败'} + def get_instance_key_pair(self, instance_id, region_id='cn-shanghai'): + """获取实例的密钥对详细信息""" + client = self._get_client(region_id) + try: + request = swas__open20200601_models.DescribeInstanceKeyPairRequest( + region_id=region_id, + instance_id=instance_id + ) + runtime = util_models.RuntimeOptions() + response = client.describe_instance_key_pair_with_options(request, runtime) + return {'success': True, 'data': self._convert_response_to_dict(response.body), 'message': '获取密钥对详细信息成功'} + except Exception as e: + jingrow.log_error("获取密钥对详细信息失败", f"获取实例 {instance_id} 密钥对详细信息时发生错误: {str(e)}") + return {'success': False, 'error': str(e), 'message': '获取密钥对详细信息失败'} + def get_instance_details(self, instance_ids, region_id='cn-shanghai'): """获取实例详细信息(支持批量查询)""" client = self._get_client(region_id) @@ -604,17 +621,53 @@ def create_aliyun_instance_key_pair(instance_id, key_pair_name, region_id='cn-sh manager = _get_manager() return manager.create_instance_key_pair(instance_id, key_pair_name, region_id) -@jingrow.whitelist() -def list_aliyun_instance_key_pairs(instance_id, region_id='cn-shanghai'): - """获取实例的密钥对列表""" - manager = _get_manager() - return manager.list_instance_key_pairs(instance_id, region_id) + @jingrow.whitelist() -def delete_aliyun_instance_key_pair(instance_id, key_pair_name, region_id='cn-shanghai'): - """删除实例的密钥对""" +def delete_aliyun_instance_key_pair(instance_id): + """解绑并删除实例的密钥对""" + try: + # 1. 查找对应的Jsite Server记录获取key_pair_name和region_id + server = jingrow.get_pg("Jsite Server", {"instance_id": instance_id}) + if not server: + return {"success": False, "message": "找不到对应的服务器记录"} + + key_pair_name = server.key_pair_name + region_id = server.region + + if not key_pair_name: + return {"success": True, "message": "实例没有关联的密钥对"} + + manager = _get_manager() + + # 2. 解绑实例的密钥对 + unbind_result = manager.delete_instance_key_pair(instance_id, region_id) + if not unbind_result or not unbind_result.get('success'): + return {"success": False, "message": f"解绑密钥对失败: {unbind_result.get('message', '未知错误')}"} + + # 3. 删除密钥对 + delete_result = manager.delete_key_pairs([key_pair_name], region_id) + if not delete_result or not delete_result.get('success'): + return {"success": False, "message": f"删除密钥对失败: {delete_result.get('message', '未知错误')}"} + + # 4. 清除服务器记录中的密钥对信息 + server.key_pair_name = None + server.private_key = None + server.save(ignore_permissions=True) + jingrow.db.commit() + + return {"success": True, "message": "密钥对解绑并删除成功"} + + except Exception as e: + jingrow.log_error("删除实例密钥对失败", f"删除实例 {instance_id} 密钥对时发生错误: {str(e)}") + return {"success": False, "message": str(e)} + + +@jingrow.whitelist() +def get_aliyun_instance_key_pair(instance_id, region_id='cn-shanghai'): + """获取实例的密钥对详细信息""" manager = _get_manager() - return manager.delete_instance_key_pair(instance_id, key_pair_name, region_id) + return manager.get_instance_key_pair(instance_id, region_id) @jingrow.whitelist() def get_aliyun_instance_details(instance_ids, region_id='cn-shanghai'): @@ -753,15 +806,22 @@ def create_server_key_pair(instance_id): jingrow.log_error("找不到对应的服务器记录") region_id = server.region - key_pair_name = f"{region_id}-{instance_id[:8]}" + uuid_suffix = str(uuid.uuid4())[:4] + key_pair_name = f"{region_id}-{instance_id[:8]}-{uuid_suffix}" - # 调用阿里云API创建密钥对 - key_pair_result = create_aliyun_instance_key_pair(instance_id, key_pair_name, region_id) + # 直接调用管理器方法创建密钥对 + manager = _get_manager() + key_pair_result = manager.create_instance_key_pair(instance_id, key_pair_name, region_id) + + # 添加调试日志 + jingrow.log_error("密钥对创建调试", f"完整的key_pair_result: {key_pair_result}") if not key_pair_result or not key_pair_result.get('success'): - jingrow.log_error(f"密钥对创建失败: {key_pair_result.get('message', '未知错误')}") + error_msg = key_pair_result.get('message', '未知错误') if key_pair_result else '返回结果为空' + jingrow.log_error(f"密钥对创建失败: {error_msg}") + return {"success": False, "message": f"密钥对创建失败: {error_msg}"} - # 获取私钥 + # 获取私钥 - 直接访问data字段 key_pair_data = key_pair_result.get('data', {}) private_key = key_pair_data.get('private_key') @@ -770,6 +830,7 @@ def create_server_key_pair(instance_id): server.key_pair_name = key_pair_name server.private_key = private_key server.save(ignore_permissions=True) + jingrow.db.commit() return { "success": True, @@ -778,7 +839,8 @@ def create_server_key_pair(instance_id): "private_key": private_key } else: - jingrow.log_error("密钥对创建成功但未获取到私钥") + jingrow.log_error("密钥对创建成功但未获取到私钥", f"完整的key_pair_result: {key_pair_result}") + return {"success": False, "message": "密钥对创建成功但未获取到私钥"} except Exception as e: jingrow.log_error("创建密钥对失败", f"实例 {instance_id}: {str(e)}") diff --git a/jcloud/jcloud/pagetype/jsite_server/jsite_server.json b/jcloud/jcloud/pagetype/jsite_server/jsite_server.json index 618a6db..d2aba15 100644 --- a/jcloud/jcloud/pagetype/jsite_server/jsite_server.json +++ b/jcloud/jcloud/pagetype/jsite_server/jsite_server.json @@ -29,6 +29,7 @@ "ssh_port", "password", "column_break_20", + "key_pair_name", "private_key" ], "fields": [ @@ -187,11 +188,16 @@ "fieldname": "password", "fieldtype": "Password", "label": "服务器密码" + }, + { + "fieldname": "key_pair_name", + "fieldtype": "Data", + "label": "密钥对名称" } ], "index_web_pages_for_search": 1, "links": [], - "modified": "2025-07-28 17:53:25.476573", + "modified": "2025-07-28 20:45:29.493153", "modified_by": "Administrator", "module": "Jcloud", "name": "Jsite Server", diff --git a/jcloud/jcloud/pagetype/jsite_server/jsite_server.py b/jcloud/jcloud/pagetype/jsite_server/jsite_server.py index bcae718..5aa4d4c 100644 --- a/jcloud/jcloud/pagetype/jsite_server/jsite_server.py +++ b/jcloud/jcloud/pagetype/jsite_server/jsite_server.py @@ -20,6 +20,7 @@ class JsiteServer(Document): end_date: DF.Datetime | None image_id: DF.Data | None instance_id: DF.Data | None + key_pair_name: DF.Data | None memory: DF.Data | None order_id: DF.Data | None password: DF.Password | None