From d0eb096873ebdc0fa5e9fce191aadd6233fb081d Mon Sep 17 00:00:00 2001 From: net909 Date: Thu, 25 Dec 2025 11:49:07 +0800 Subject: [PATCH] =?UTF-8?q?=E8=85=BE=E8=AE=AF=E4=BA=91=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E8=AF=81=E4=B9=A6=E5=86=85=E5=AE=B9=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/lib/DeployHelper.php | 9 ++++ app/lib/deploy/tencent.php | 92 ++++++++++++++++++++++++++++++++++++++ config/app.php | 2 +- 3 files changed, 102 insertions(+), 1 deletion(-) diff --git a/app/lib/DeployHelper.php b/app/lib/DeployHelper.php index 2427ece..e08d3ca 100644 --- a/app/lib/DeployHelper.php +++ b/app/lib/DeployHelper.php @@ -1224,6 +1224,7 @@ ctrl+x 保存退出', ['value'=>'tse', 'label'=>'云原生API网关TSE'], ['value'=>'tcb', 'label'=>'云开发TCB'], ['value'=>'lighthouse', 'label'=>'轻量应用服务器'], + ['value'=>'update', 'label'=>'更新证书内容(证书ID不变)'], ], 'value' => 'cdn', 'required' => true, @@ -1327,6 +1328,14 @@ ctrl+x 保存退出', 'note' => 'CDN、EO、WAF多个域名可用,隔开,其他只能填写1个域名', 'required' => true, ], + 'cert_id' => [ + 'name' => '证书ID', + 'type' => 'input', + 'placeholder' => '要更新的证书ID,在我的证书列表查看', + 'show' => 'product==\'update\'', + 'required' => true, + 'note' => '当前接口需联系加白使用', + ], ], ], 'huawei' => [ diff --git a/app/lib/deploy/tencent.php b/app/lib/deploy/tencent.php index f290288..91f2d7c 100644 --- a/app/lib/deploy/tencent.php +++ b/app/lib/deploy/tencent.php @@ -31,6 +31,9 @@ class tencent implements DeployInterface public function deploy($fullchain, $privatekey, $config, &$info) { + if ($config['product'] == 'update') { + return $this->update_cert($fullchain, $privatekey, $config); + } $cert_id = $this->get_cert_id($fullchain, $privatekey); if (!$cert_id) throw new Exception('证书ID获取失败'); if ($config['product'] == 'cos') { @@ -281,6 +284,95 @@ class tencent implements DeployInterface $this->log('边缘安全加速域名 ' . $config['domain'] . ' 部署证书成功!'); } + private function update_cert($fullchain, $privatekey, $config) + { + if (empty($config['cert_id'])) throw new Exception('证书ID不能为空'); + + $param = [ + 'CertificateIds' => [$config['cert_id']], + 'IsCache' => 1, + ]; + try { + $data = $this->client->request('CreateCertificateBindResourceSyncTask', $param); + if (empty($data['CertTaskIds'])) throw new Exception('返回任务ID为空'); + } catch (Exception $e) { + throw new Exception('创建关联云资源查询任务失败:' . $e->getMessage()); + } + $task_id = $data['CertTaskIds'][0]['TaskId']; + $this->log('创建关联云资源查询任务成功 TaskId=' . $task_id); + + $retry = 0; + $resource_result = null; + while ($retry++ < 30) { + sleep(2); + $param = [ + 'TaskIds' => [$task_id], + ]; + try { + $data = $this->client->request('DescribeCertificateBindResourceTaskResult', $param); + if (empty($data['SyncTaskBindResourceResult'])) throw new Exception('返回结果为空'); + } catch (Exception $e) { + throw new Exception('查询关联云资源任务结果失败:' . $e->getMessage()); + } + $taskResult = $data['SyncTaskBindResourceResult'][0]; + if ($taskResult['Status'] == 1) { + $resource_result = $taskResult['BindResourceResult']; + break; + } elseif ($taskResult['Status'] == 2) { + throw new Exception('关联云资源查询任务执行失败:' . isset($taskResult['Error']) ? $taskResult['Error']['Message'] : '未知错误'); + } + }; + if (!$resource_result) { + throw new Exception('关联云资源查询任务超时未完成,请稍后重试'); + } + + $resourceTypes = []; + $resourceTypesRegions = []; + foreach ($resource_result as $res) { + if ($res['ResourceType'] != 'clb') continue; + $totalCount = 0; + $regions = []; + foreach ($res['BindResourceRegionResult'] as $regionRes) { + if ($regionRes['TotalCount'] > 0) { + $totalCount += $regionRes['TotalCount']; + if (!empty($regionRes['Region'])) { + $regions[] = $regionRes['Region']; + } + } + } + if ($totalCount > 0) { + $resourceTypes[] = $res['ResourceType']; + if (!empty($regions)) { + $resourceTypesRegions[] = [ + 'ResourceType' => $res['ResourceType'], + 'Regions' => $regions, + ]; + } + } + } + + $param = [ + 'OldCertificateId' => $config['cert_id'], + 'CertificatePublicKey' => $fullchain, + 'CertificatePrivateKey' => $privatekey, + 'ResourceTypes' => $resourceTypes, + 'ResourceTypesRegions' => $resourceTypesRegions, + ]; + $retry = 0; + while ($retry++ < 10) { + try { + $data = $this->client->request('UploadUpdateCertificateInstance', $param); + } catch (Exception $e) { + throw new Exception('更新证书内容失败:' . $e->getMessage()); + } + if ($data['DeployStatus'] == 1) { + break; + } + sleep(1); + } + $this->log('更新证书内容成功,可能需要一些时间完成各资源的证书更新部署'); + } + public function setLogger($func) { $this->logger = $func; diff --git a/config/app.php b/config/app.php index c81ffc9..9b89298 100644 --- a/config/app.php +++ b/config/app.php @@ -31,7 +31,7 @@ return [ 'show_error_msg' => true, 'exception_tmpl' => \think\facade\App::getAppPath() . 'view/exception.tpl', - 'version' => '1043', + 'version' => '1044', 'dbversion' => '1040' ];