From af2117faf0de56409e16165e9d3f9f58c94db91d Mon Sep 17 00:00:00 2001 From: net909 Date: Wed, 25 Jun 2025 13:37:37 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E6=8C=81=E9=9B=A8=E4=BA=91SSL?= =?UTF-8?q?=E8=87=AA=E5=8A=A8=E9=83=A8=E7=BD=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/lib/DeployHelper.php | 42 +++++++++++++++++- app/lib/deploy/rainyun.php | 78 ++++++++++++++++++++++++++++++++++ public/static/images/doge.png | Bin 0 -> 13776 bytes 3 files changed, 119 insertions(+), 1 deletion(-) create mode 100644 app/lib/deploy/rainyun.php create mode 100644 public/static/images/doge.png diff --git a/app/lib/DeployHelper.php b/app/lib/DeployHelper.php index facd557..418632e 100644 --- a/app/lib/DeployHelper.php +++ b/app/lib/DeployHelper.php @@ -1170,7 +1170,7 @@ class DeployHelper 'doge' => [ 'name' => '多吉云', 'class' => 2, - 'icon' => 'cloud.png', + 'icon' => 'doge.png', 'desc' => '支持部署到多吉云融合CDN', 'note' => '支持部署到多吉云融合CDN', 'inputs' => [ @@ -1578,6 +1578,46 @@ class DeployHelper ], ], ], + 'rainyun' => [ + 'name' => '雨云', + 'class' => 2, + 'icon' => 'waf.png', + 'desc' => '替换雨云证书管理内的证书', + 'note' => null, + 'inputs' => [ + 'account' => [ + 'name' => '账号', + 'type' => 'input', + 'placeholder' => '仅用作标记', + 'required' => true, + ], + 'apikey' => [ + 'name' => 'ApiKey', + 'type' => 'input', + 'placeholder' => '', + 'note' => '在 账户设置->API密钥 页面查看', + 'required' => true, + ], + 'proxy' => [ + 'name' => '使用代理服务器', + 'type' => 'radio', + 'options' => [ + '0' => '否', + '1' => '是', + ], + 'value' => '0' + ], + ], + 'taskinputs' => [ + 'id' => [ + 'name' => '证书ID', + 'type' => 'input', + 'placeholder' => '', + 'note' => '在SSL证书->我的证书页面查看,注意域名是否与证书匹配', + 'required' => true, + ], + ], + ], 'aws' => [ 'name' => 'AWS', 'class' => 2, diff --git a/app/lib/deploy/rainyun.php b/app/lib/deploy/rainyun.php new file mode 100644 index 0000000..c5e3f40 --- /dev/null +++ b/app/lib/deploy/rainyun.php @@ -0,0 +1,78 @@ +apikey = $config['apikey']; + $this->proxy = $config['proxy'] == 1; + } + + public function check() + { + if (empty($this->apikey)) throw new Exception('ApiKey不能为空'); + $this->request('/product/'); + } + + public function deploy($fullchain, $privatekey, $config, &$info) + { + if (empty($config['id'])) throw new Exception('证书ID不能为空'); + + $params = [ + 'cert' => $fullchain, + 'key' => $privatekey, + ]; + try { + $this->request('/product/sslcenter/' . $config['id'], $params, 'PUT'); + } catch (Exception $e) { + throw new Exception($e->getMessage()); + } + + $this->log('证书ID:' . $config['id'] . '更新成功!'); + } + + private function request($path, $params = null, $method = null) + { + $url = $this->url . $path; + $headers = [ + 'x-api-key' => $this->apikey, + ]; + $body = null; + if ($params) { + $headers['Content-Type'] = 'application/json'; + $body = json_encode($params); + } + $response = http_request($url, $body, null, null, $headers, $this->proxy, $method); + $result = json_decode($response['body'], true); + if (isset($result['code']) && $result['code'] == 200) { + return $result; + } elseif (isset($result['message'])) { + throw new Exception($result['message']); + } else { + if (!empty($response['body'])) $this->log('Response:' . $response['body']); + throw new Exception('请求失败(httpCode=' . $response['code'] . ')'); + } + } + + public function setLogger($func) + { + $this->logger = $func; + } + + private function log($txt) + { + if ($this->logger) { + call_user_func($this->logger, $txt); + } + } +} diff --git a/public/static/images/doge.png b/public/static/images/doge.png new file mode 100644 index 0000000000000000000000000000000000000000..f6a3c41b9b88f80961d6077ba07a7c6f054ddefd GIT binary patch literal 13776 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