From 27b713250303629a96579d514f479892a05a7cd6 Mon Sep 17 00:00:00 2001 From: jingrow Date: Mon, 28 Jul 2025 15:39:13 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0update=5Fserver=5Frecord?= =?UTF-8?q?=E7=AB=AF=E7=82=B9=E7=94=A8=E4=BA=8E=E6=9B=B4=E6=96=B0=E4=BA=91?= =?UTF-8?q?=E6=9C=8D=E5=8A=A1=E5=99=A8=E7=9B=B8=E5=85=B3=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jcloud/api/aliyun_server_light.py | 127 +++++++++++++++++- .../pagetype/jsite_server/jsite_server.json | 36 +++-- .../pagetype/jsite_server/jsite_server.py | 8 +- 3 files changed, 141 insertions(+), 30 deletions(-) diff --git a/jcloud/api/aliyun_server_light.py b/jcloud/api/aliyun_server_light.py index 50951d0..3bb839f 100644 --- a/jcloud/api/aliyun_server_light.py +++ b/jcloud/api/aliyun_server_light.py @@ -1,6 +1,9 @@ import jingrow import os import sys +import json +import random +from datetime import datetime from typing import Dict, Any from alibabacloud_swas_open20200601.client import Client as SWAS_OPEN20200601Client @@ -10,6 +13,8 @@ from alibabacloud_swas_open20200601 import models as swas__open20200601_models from alibabacloud_tea_util import models as util_models from alibabacloud_tea_util.client import Client as UtilClient +from jcloud.utils import get_current_team + class AliyunLightServerManager: """阿里云轻量应用服务器管理器""" @@ -337,6 +342,27 @@ class AliyunLightServerManager: jingrow.log_error("删除密钥对失败", f"删除实例 {instance_id} 密钥对 {key_pair_name} 时发生错误: {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) + try: + # 如果instance_ids是列表,转换为JSON字符串 + if isinstance(instance_ids, list): + instance_ids_str = json.dumps(instance_ids) + else: + instance_ids_str = instance_ids + + request = swas__open20200601_models.ListInstancesRequest( + region_id=region_id, + instance_ids=instance_ids_str + ) + runtime = util_models.RuntimeOptions() + response = client.list_instances_with_options(request, runtime) + return {'success': True, 'data': self._convert_response_to_dict(response.body), 'message': '获取实例详细信息成功'} + except Exception as e: + jingrow.log_error("获取实例详细信息失败", f"获取实例详细信息时发生错误: {str(e)}") + return {'success': False, 'error': str(e), 'message': '获取实例详细信息失败'} + # 全局管理器实例 _aliyun_manager = None @@ -440,6 +466,11 @@ def delete_aliyun_instance_key_pair(instance_id, key_pair_name, region_id='cn-sh manager = _get_manager() return manager.delete_instance_key_pair(instance_id, key_pair_name, region_id) +@jingrow.whitelist() +def get_aliyun_instance_details(instance_ids, region_id='cn-shanghai'): + """获取实例详细信息(支持批量查询)""" + manager = _get_manager() + return manager.get_instance_details(instance_ids, region_id) # 服务器订单和创建相关 @@ -456,7 +487,6 @@ def create_server_order(**kwargs): if not plan_id or not image_id: jingrow.throw("缺少必要参数") - from jcloud.utils import get_current_team team = get_current_team(True) # 获取套餐价格 @@ -474,8 +504,6 @@ def create_server_order(**kwargs): total_amount = monthly_price * period # 生成订单号 - from datetime import datetime - import random order_id = datetime.now().strftime('%Y%m%d%H%M%S%f')[:-3] + ''.join(random.choices('0123456789', k=6)) # 创建订单记录 @@ -498,7 +526,7 @@ def create_server_order(**kwargs): "order_id": order_id, "status": "Pending", "region": region_id, - "system_image": image_id, + "image_id": image_id, "end_date": jingrow.utils.add_months(jingrow.utils.nowdate(), period), "title": f"{region_id} - {selected_plan.get('core')}核/{selected_plan.get('memory')}GB", "planid": plan_id, @@ -532,7 +560,7 @@ def create_aliyun_server(order_name): # 从服务器记录中获取配置信息 region_id = server.region or 'cn-shanghai' - image_id = server.system_image or 'e9363571cf2444aba422b17470285465' + image_id = server.image_id or 'e9363571cf2444aba422b17470285465' plan_id = server.planid or 'swas.s.c2m1s30b1.linux' period = server.period or 1 @@ -549,8 +577,7 @@ def create_aliyun_server(order_name): instance_id = result['data']['instance_ids'][0] # 更新服务器记录状态 - server.status = "Active" - server.running_status = "运行中" + server.status = "Running" server.instance_id = instance_id server.save(ignore_permissions=True) @@ -605,4 +632,90 @@ def create_server_key_pair(instance_id): except Exception as e: jingrow.log_error("创建密钥对失败", f"实例 {instance_id}: {str(e)}") + return {"success": False, "message": str(e)} + +@jingrow.whitelist() +def update_server_record(instance_ids): + """根据阿里云实例信息更新Jsite Server记录""" + try: + # 解析instance_ids(JSON字符串格式) + if isinstance(instance_ids, str): + instance_ids = json.loads(instance_ids) + + # 获取第一个实例ID + instance_id = instance_ids[0] + + # 查找对应的Jsite Server记录获取region_id + server = jingrow.get_pg("Jsite Server", {"instance_id": instance_id}) + if not server: + jingrow.log_error("更新服务器信息失败", f"找不到实例ID为 {instance_id} 的Jsite Server记录") + return {"success": False, "message": f"找不到实例ID为 {instance_id} 的Jsite Server记录"} + + region_id = server.region or 'cn-shanghai' + + # 获取阿里云实例详细信息 + instance_details = get_aliyun_instance_details(instance_ids, region_id) + + if not instance_details or not instance_details.get('success'): + error_msg = f"获取阿里云实例信息失败: {instance_details.get('message', '未知错误')}" + jingrow.log_error("更新服务器信息失败", error_msg) + return {"success": False, "message": error_msg} + + # 解析实例信息 + instances = instance_details.get('data', {}).get('instances', []) + if not instances: + jingrow.log_error("更新服务器信息失败", "未找到实例信息") + return {"success": False, "message": "未找到实例信息"} + + instance_info = instances[0] # 取第一个实例 + + # 更新public_ip + public_ip = instance_info.get('public_ip_address') + if public_ip: + server.public_ip = public_ip + + # 更新end_date(从expired_time转换) + expired_time = instance_info.get('expired_time') + if expired_time: + try: + expired_datetime = datetime.fromisoformat(expired_time.replace('Z', '+00:00')) + server.end_date = expired_datetime.strftime('%Y-%m-%d %H:%M:%S') + except Exception as e: + jingrow.log_error("时间格式转换失败", f"转换expired_time {expired_time} 时发生错误: {str(e)}") + + # 更新其他相关信息 + server.status = instance_info.get('status', '') + + # 更新系统信息 + image_info = instance_info.get('image', {}) + if image_info: + image_name = image_info.get('image_name', '') + image_version = image_info.get('image_version', '') + server.system = f"{image_name} {image_version}".strip() + + # 更新资源规格信息 + resource_spec = instance_info.get('resource_spec', {}) + if resource_spec: + server.cpu = resource_spec.get('cpu') + server.memory = resource_spec.get('memory') + server.disk_size = resource_spec.get('disk_size') + server.bandwidth = resource_spec.get('bandwidth') + + # 保存更新 + server.save(ignore_permissions=True) + jingrow.db.commit() + + return { + "success": True, + "message": "服务器信息更新成功", + "updated_fields": { + "public_ip": public_ip, + "end_date": server.end_date, + "status": server.status, + "system": server.system + } + } + + except Exception as e: + jingrow.log_error("更新服务器信息失败", f"更新服务器信息时发生错误: {str(e)}") return {"success": False, "message": str(e)} \ No newline at end of file diff --git a/jcloud/jcloud/pagetype/jsite_server/jsite_server.json b/jcloud/jcloud/pagetype/jsite_server/jsite_server.json index 63d6aef..fd99951 100644 --- a/jcloud/jcloud/pagetype/jsite_server/jsite_server.json +++ b/jcloud/jcloud/pagetype/jsite_server/jsite_server.json @@ -15,14 +15,14 @@ "cpu", "disk_size", "region", - "system_image", + "image_id", "planid", "column_break_aliyun", "end_date", "memory", "bandwidth", "public_ip", - "running_status", + "system", "period", "ssh_section", "ssh_user", @@ -38,7 +38,7 @@ "in_list_view": 1, "in_standard_filter": 1, "label": "状态", - "options": "Pending\nInstalling\nActive\nBroken\nArchived", + "options": "Pending\nStarting\nRunning\nStopping\nStopped\nResetting\nUpgrading\nDisabled", "read_only": 1 }, { @@ -92,7 +92,7 @@ }, { "fieldname": "end_date", - "fieldtype": "Date", + "fieldtype": "Datetime", "in_list_view": 1, "label": "到期时间", "read_only": 1 @@ -137,20 +137,6 @@ "label": "硬盘容量(GB)", "read_only": 1 }, - { - "fieldname": "system_image", - "fieldtype": "Data", - "label": "系统镜像" - }, - { - "fetch_from": "virtual_machine.public_ip_address", - "fieldname": "running_status", - "fieldtype": "Select", - "in_list_view": 1, - "label": "运行状态", - "options": "\n运行中\n已停机", - "read_only": 1 - }, { "fieldname": "order_id", "fieldtype": "Data", @@ -182,11 +168,23 @@ "in_list_view": 1, "label": "公网IP", "read_only": 1 + }, + { + "fieldname": "image_id", + "fieldtype": "Data", + "label": "镜像ID", + "read_only": 1 + }, + { + "fieldname": "system", + "fieldtype": "Data", + "label": "系统", + "read_only": 1 } ], "index_web_pages_for_search": 1, "links": [], - "modified": "2025-07-28 13:48:36.022662", + "modified": "2025-07-28 15:36:38.598173", "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 aa4a995..f2d3bf2 100644 --- a/jcloud/jcloud/pagetype/jsite_server/jsite_server.py +++ b/jcloud/jcloud/pagetype/jsite_server/jsite_server.py @@ -17,7 +17,8 @@ class JsiteServer(Document): bandwidth: DF.Data | None cpu: DF.Data | None disk_size: DF.Data | None - end_date: DF.Date | None + end_date: DF.Datetime | None + image_id: DF.Data | None instance_id: DF.Data | None memory: DF.Data | None order_id: DF.Data | None @@ -26,11 +27,10 @@ class JsiteServer(Document): private_key: DF.Text | None public_ip: DF.Data | None region: DF.Data | None - running_status: DF.Literal["", "\u8fd0\u884c\u4e2d", "\u5df2\u505c\u673a"] ssh_port: DF.Int ssh_user: DF.Data | None - status: DF.Literal["Pending", "Installing", "Active", "Broken", "Archived"] - system_image: DF.Data | None + status: DF.Literal["Pending", "Starting", "Running", "Stopping", "Stopped", "Resetting", "Upgrading", "Disabled"] + system: DF.Data | None team: DF.Link | None title: DF.Data | None # end: auto-generated types