新增百度云BLB部署

This commit is contained in:
net909
2025-08-27 19:13:55 +08:00
parent 7cb745acdf
commit 4bee80e06e
9 changed files with 184 additions and 46 deletions

View File

@@ -1340,8 +1340,8 @@ class DeployHelper
'name' => '百度云',
'class' => 2,
'icon' => 'baidu.ico',
'desc' => '支持部署到百度云CDN',
'note' => '支持部署到百度云CDN',
'desc' => '支持部署到百度云CDN、BLB',
'note' => '支持部署到百度云CDN、BLB',
'inputs' => [
'AccessKeyId' => [
'name' => 'AccessKeyId',
@@ -1366,10 +1366,54 @@ class DeployHelper
],
],
'taskinputs' => [
'product' => [
'name' => '要部署的产品',
'type' => 'select',
'options' => [
['value'=>'cdn', 'label'=>'CDN'],
['value'=>'blb', 'label'=>'普通型BLB'],
['value'=>'appblb', 'label'=>'应用型BLB'],
],
'value' => 'cdn',
'required' => true,
],
'domain' => [
'name' => '绑定的域名',
'type' => 'input',
'placeholder' => '多个域名可使用,分隔',
'show' => 'product==\'cdn\'',
'required' => true,
],
'region' => [
'name' => '所属地域',
'type' => 'select',
'options' => [
['value'=>'bj', 'label'=>'北京'],
['value'=>'gz', 'label'=>'广州'],
['value'=>'su', 'label'=>'苏州'],
['value'=>'hkg', 'label'=>'香港'],
['value'=>'fwh', 'label'=>'武汉'],
['value'=>'bd', 'label'=>'保定'],
['value'=>'fsh', 'label'=>'上海'],
['value'=>'sin', 'label'=>'新加坡'],
],
'value' => 'bj',
'show' => 'product==\'blb\'||product==\'appblb\'',
'required' => true,
],
'blb_id' => [
'name' => '负载均衡实例ID',
'type' => 'input',
'placeholder' => '',
'show' => 'product==\'blb\'||product==\'appblb\'',
'required' => true,
],
'blb_port' => [
'name' => 'HTTPS监听端口',
'type' => 'input',
'placeholder' => '',
'value' => '443',
'show' => 'product==\'blb\'||product==\'appblb\'',
'required' => true,
],
],
@@ -1378,8 +1422,8 @@ class DeployHelper
'name' => '火山引擎',
'class' => 2,
'icon' => 'huoshan.ico',
'desc' => '支持部署到火山引擎CDN',
'note' => '支持部署到火山引擎CDN',
'desc' => '支持部署到火山引擎CDN、CLB、TOS、直播、veImageX',
'note' => '支持部署到火山引擎CDN、CLB、TOS、直播、veImageX',
'inputs' => [
'AccessKeyId' => [
'name' => 'AccessKeyId',

View File

@@ -29,6 +29,23 @@ class baidu implements DeployInterface
}
public function deploy($fullchain, $privatekey, $config, &$info)
{
if (!isset($config['product']) || $config['product'] == 'cdn') {
$this->deploy_cdn($fullchain, $privatekey, $config, $info);
} else {
$cert_id = $this->get_cert_id($fullchain, $privatekey);
$info['cert_id'] = $cert_id;
if ($config['product'] == 'blb') {
$this->deploy_blb($cert_id, $config);
} elseif ($config['product'] == 'appblb') {
$this->deploy_appblb($cert_id, $config);
} else {
throw new Exception('不支持的产品类型');
}
}
}
public function deploy_cdn($fullchain, $privatekey, $config, &$info)
{
if (empty($config['domain'])) throw new Exception('绑定的域名不能为空');
$certInfo = openssl_x509_parse($fullchain, true);
@@ -36,16 +53,6 @@ class baidu implements DeployInterface
$config['cert_name'] = str_replace('*.', '', $certInfo['subject']['CN']) . '-' . $certInfo['validFrom_time_t'];
$client = new BaiduCloud($this->AccessKeyId, $this->SecretAccessKey, 'cdn.baidubce.com', $this->proxy);
try {
$data = $client->request('GET', '/v2/' . $config['domain'] . '/certificates');
if (isset($data['certName']) && $data['certName'] == $config['cert_name']) {
$this->log('CDN域名 ' . $config['domain'] . ' 证书已存在,无需重复部署');
return;
}
} catch (Exception $e) {
$this->log($e->getMessage());
}
$param = [
'httpsEnable' => 'ON',
'certificate' => [
@@ -54,9 +61,89 @@ class baidu implements DeployInterface
'certPrivateData' => $privatekey,
],
];
$data = $client->request('PUT', '/v2/' . $config['domain'] . '/certificates', null, $param);
$info['cert_id'] = $data['certId'];
$this->log('CDN域名 ' . $config['domain'] . ' 证书部署成功!');
foreach (explode(',', $config['domain']) as $domain) {
if (empty($domain)) continue;
try {
$data = $client->request('GET', '/v2/' . $domain . '/certificates');
if (isset($data['certName']) && $data['certName'] == $config['cert_name']) {
$this->log('CDN域名 ' . $domain . ' 证书已存在,无需重复部署');
return;
}
} catch (Exception $e) {
$this->log($e->getMessage());
}
$data = $client->request('PUT', '/v2/' . $domain . '/certificates', null, $param);
$info['cert_id'] = $data['certId'];
$this->log('CDN域名 ' . $domain . ' 证书部署成功!');
}
}
public function deploy_blb($cert_id, $config)
{
if (empty($config['blb_id'])) throw new Exception('负载均衡实例ID不能为空');
if (empty($config['blb_port'])) throw new Exception('HTTPS监听端口不能为空');
$client = new BaiduCloud($this->AccessKeyId, $this->SecretAccessKey, 'blb.' . $config['region'] . '.baidubce.com', $this->proxy);
$query = [
'listenerPort' => $config['blb_port'],
];
$param = [
'certIds' => [$cert_id],
];
$client->request('PUT', '/v1/blb/' . $config['blb_id'] . '/HTTPSlistener', $query, $param);
$this->log('普通型BLB ' . $config['blb_id'] . ' 部署证书成功!');
}
public function deploy_appblb($cert_id, $config)
{
if (empty($config['blb_id'])) throw new Exception('负载均衡实例ID不能为空');
if (empty($config['blb_port'])) throw new Exception('HTTPS监听端口不能为空');
$client = new BaiduCloud($this->AccessKeyId, $this->SecretAccessKey, 'blb.' . $config['region'] . '.baidubce.com', $this->proxy);
$query = [
'listenerPort' => $config['blb_port'],
];
$param = [
'certIds' => [$cert_id],
];
$client->request('PUT', '/v1/appblb/' . $config['blb_id'] . '/HTTPSlistener', $query, $param);
$this->log('应用型BLB ' . $config['blb_id'] . ' 部署证书成功!');
}
private function get_cert_id($fullchain, $privatekey)
{
$certInfo = openssl_x509_parse($fullchain, true);
if (!$certInfo) throw new Exception('证书解析失败');
$cert_name = str_replace('*.', '', $certInfo['subject']['CN']) . '-' . $certInfo['validFrom_time_t'];
$client = new BaiduCloud($this->AccessKeyId, $this->SecretAccessKey, 'certificate.baidubce.com', $this->proxy);
$query = [
'certName' => $cert_name,
];
try {
$data = $client->request('GET', '/v1/certificate', $query);
} catch (Exception $e) {
throw new Exception('查找证书失败:' . $e->getMessage());
}
foreach ($data['certs'] as $row) {
if ($row['certName'] == $cert_name) {
$this->log('证书已存在 CertId=' . $row['certId']);
return $row['certId'];
}
}
$param = [
'certName' => $cert_name,
'certServerData' => $fullchain,
'certPrivateData' => $privatekey,
];
try {
$data = $client->request('POST', '/v1/certificate', null, $param);
} catch (Exception $e) {
throw new Exception('上传证书失败:' . $e->getMessage());
}
$cert_id = $data['certId'];
$this->log('上传证书成功 CertId=' . $cert_id);
return $cert_id;
}
public function setLogger($func)

View File

@@ -38,6 +38,7 @@ class doge implements DeployInterface
$cert_id = $this->get_cert_id($fullchain, $privatekey, $cert_name);
foreach (explode(',', $domains) as $domain) {
if (empty($domain)) continue;
$param = [
'id' => $cert_id,
'domain' => $domain,

View File

@@ -59,6 +59,7 @@ class huawei implements DeployInterface
],
];
foreach (explode(',', $config['domain']) as $domain) {
if (empty($domain)) continue;
$client->request('PUT', '/v1.1/cdn/configuration/domains/' . $domain . '/configs', null, $param);
$this->log('CDN域名 ' . $domain . ' 部署证书成功!');
}

View File

@@ -89,6 +89,7 @@ class huoshan implements DeployInterface
if (empty($config['domain'])) throw new Exception('绑定的域名不能为空');
$client = new Volcengine($this->AccessKeyId, $this->SecretAccessKey, $config['bucket_domain'], 'tos', '2021-04-01', 'cn-beijing', $this->proxy);
foreach (explode(',', $config['domain']) as $domain) {
if (empty($domain)) continue;
$param = [
'CustomDomainRule' => [
'Domain' => $domain,
@@ -122,6 +123,7 @@ class huoshan implements DeployInterface
$this->log('上传证书成功 ChainID=' . $result['ChainID']);
foreach (explode(',', $config['domain']) as $domain) {
if (empty($domain)) continue;
$param = [
'ChainID' => $result['ChainID'],
'Domain' => $domain,
@@ -138,6 +140,7 @@ class huoshan implements DeployInterface
if (empty($config['domain'])) throw new Exception('绑定的域名不能为空');
$client = new Volcengine($this->AccessKeyId, $this->SecretAccessKey, 'imagex.volcengineapi.com', 'imagex', '2018-08-01', 'cn-north-1', $this->proxy);
foreach (explode(',', $config['domain']) as $domain) {
if (empty($domain)) continue;
$param = [
[
'domain' => $domain,

View File

@@ -39,6 +39,7 @@ class qiniu implements DeployInterface
$cert_id = $this->get_cert_id($fullchain, $privatekey, $certInfo['subject']['CN'], $cert_name);
foreach (explode(',', $domains) as $domain) {
if (empty($domain)) continue;
if ($config['product'] == 'cdn') {
$this->deploy_cdn($domain, $cert_id);
} elseif ($config['product'] == 'oss') {

View File

@@ -35,6 +35,7 @@ class unicloud implements DeployInterface
$url = 'https://unicloud-api.dcloud.net.cn/unicloud/api/host/create-domain-with-cert';
foreach (explode(',', $config['domains']) as $domain) {
if (empty($domain)) continue;
$params = [
'appid' => '',
'provider' => $config['provider'],

View File

@@ -29,7 +29,7 @@ class CertDeployService
$this->client = DeployHelper::getModel($this->aid);
if (!$this->client) throw new Exception('该自动部署任务类型不存在', 102);
$this->info = $task['info'] ? json_decode($task['info'], true) : null;
$this->info = $task['info'] ? json_decode($task['info'], true) : [];
}
public function process($isManual = false)

56
composer.lock generated
View File

@@ -120,22 +120,22 @@
},
{
"name": "guzzlehttp/guzzle",
"version": "7.9.3",
"version": "7.10.0",
"source": {
"type": "git",
"url": "https://github.com/guzzle/guzzle.git",
"reference": "7b2f29fe81dc4da0ca0ea7d42107a0845946ea77"
"reference": "b51ac707cfa420b7bfd4e4d5e510ba8008e822b4"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/7b2f29fe81dc4da0ca0ea7d42107a0845946ea77",
"reference": "7b2f29fe81dc4da0ca0ea7d42107a0845946ea77",
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/b51ac707cfa420b7bfd4e4d5e510ba8008e822b4",
"reference": "b51ac707cfa420b7bfd4e4d5e510ba8008e822b4",
"shasum": ""
},
"require": {
"ext-json": "*",
"guzzlehttp/promises": "^1.5.3 || ^2.0.3",
"guzzlehttp/psr7": "^2.7.0",
"guzzlehttp/promises": "^2.3",
"guzzlehttp/psr7": "^2.8",
"php": "^7.2.5 || ^8.0",
"psr/http-client": "^1.0",
"symfony/deprecation-contracts": "^2.2 || ^3.0"
@@ -226,7 +226,7 @@
],
"support": {
"issues": "https://github.com/guzzle/guzzle/issues",
"source": "https://github.com/guzzle/guzzle/tree/7.9.3"
"source": "https://github.com/guzzle/guzzle/tree/7.10.0"
},
"funding": [
{
@@ -242,20 +242,20 @@
"type": "tidelift"
}
],
"time": "2025-03-27T13:37:11+00:00"
"time": "2025-08-23T22:36:01+00:00"
},
{
"name": "guzzlehttp/promises",
"version": "2.2.0",
"version": "2.3.0",
"source": {
"type": "git",
"url": "https://github.com/guzzle/promises.git",
"reference": "7c69f28996b0a6920945dd20b3857e499d9ca96c"
"reference": "481557b130ef3790cf82b713667b43030dc9c957"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/promises/zipball/7c69f28996b0a6920945dd20b3857e499d9ca96c",
"reference": "7c69f28996b0a6920945dd20b3857e499d9ca96c",
"url": "https://api.github.com/repos/guzzle/promises/zipball/481557b130ef3790cf82b713667b43030dc9c957",
"reference": "481557b130ef3790cf82b713667b43030dc9c957",
"shasum": ""
},
"require": {
@@ -263,7 +263,7 @@
},
"require-dev": {
"bamarni/composer-bin-plugin": "^1.8.2",
"phpunit/phpunit": "^8.5.39 || ^9.6.20"
"phpunit/phpunit": "^8.5.44 || ^9.6.25"
},
"type": "library",
"extra": {
@@ -309,7 +309,7 @@
],
"support": {
"issues": "https://github.com/guzzle/promises/issues",
"source": "https://github.com/guzzle/promises/tree/2.2.0"
"source": "https://github.com/guzzle/promises/tree/2.3.0"
},
"funding": [
{
@@ -325,20 +325,20 @@
"type": "tidelift"
}
],
"time": "2025-03-27T13:27:01+00:00"
"time": "2025-08-22T14:34:08+00:00"
},
{
"name": "guzzlehttp/psr7",
"version": "2.7.1",
"version": "2.8.0",
"source": {
"type": "git",
"url": "https://github.com/guzzle/psr7.git",
"reference": "c2270caaabe631b3b44c85f99e5a04bbb8060d16"
"reference": "21dc724a0583619cd1652f673303492272778051"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/psr7/zipball/c2270caaabe631b3b44c85f99e5a04bbb8060d16",
"reference": "c2270caaabe631b3b44c85f99e5a04bbb8060d16",
"url": "https://api.github.com/repos/guzzle/psr7/zipball/21dc724a0583619cd1652f673303492272778051",
"reference": "21dc724a0583619cd1652f673303492272778051",
"shasum": ""
},
"require": {
@@ -354,7 +354,7 @@
"require-dev": {
"bamarni/composer-bin-plugin": "^1.8.2",
"http-interop/http-factory-tests": "0.9.0",
"phpunit/phpunit": "^8.5.39 || ^9.6.20"
"phpunit/phpunit": "^8.5.44 || ^9.6.25"
},
"suggest": {
"laminas/laminas-httphandlerrunner": "Emit PSR-7 responses"
@@ -425,7 +425,7 @@
],
"support": {
"issues": "https://github.com/guzzle/psr7/issues",
"source": "https://github.com/guzzle/psr7/tree/2.7.1"
"source": "https://github.com/guzzle/psr7/tree/2.8.0"
},
"funding": [
{
@@ -441,7 +441,7 @@
"type": "tidelift"
}
],
"time": "2025-03-27T12:30:47+00:00"
"time": "2025-08-23T21:21:41+00:00"
},
{
"name": "phpmailer/phpmailer",
@@ -1527,16 +1527,16 @@
},
{
"name": "topthink/think-orm",
"version": "v4.0.49",
"version": "v4.0.50",
"source": {
"type": "git",
"url": "https://github.com/top-think/think-orm.git",
"reference": "b04d227fefc7dbfd611f4b5e66975eee4791bba4"
"reference": "ddae72d5ff4d953d3d8cc526fd9c50e8862ce2cc"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/top-think/think-orm/zipball/b04d227fefc7dbfd611f4b5e66975eee4791bba4",
"reference": "b04d227fefc7dbfd611f4b5e66975eee4791bba4",
"url": "https://api.github.com/repos/top-think/think-orm/zipball/ddae72d5ff4d953d3d8cc526fd9c50e8862ce2cc",
"reference": "ddae72d5ff4d953d3d8cc526fd9c50e8862ce2cc",
"shasum": ""
},
"require": {
@@ -1581,9 +1581,9 @@
],
"support": {
"issues": "https://github.com/top-think/think-orm/issues",
"source": "https://github.com/top-think/think-orm/tree/v4.0.49"
"source": "https://github.com/top-think/think-orm/tree/v4.0.50"
},
"time": "2025-08-10T14:08:31+00:00"
"time": "2025-08-26T05:32:22+00:00"
},
{
"name": "topthink/think-template",