mirror of
https://github.com/netcccyun/dnsmgr.git
synced 2026-02-21 07:17:22 +08:00
新增支持宝塔Win极速版,lecdn支持令牌认证
This commit is contained in:
parent
fd21a55d01
commit
79437aba60
@ -67,7 +67,7 @@ class Schedule extends BaseController
|
||||
'switchdate' => input('post.switchdate', null, 'trim'),
|
||||
'switchtime' => input('post.switchtime', null, 'trim'),
|
||||
'value' => input('post.value', null, 'trim'),
|
||||
'line' => input('post.value', null, 'trim'),
|
||||
'line' => input('post.line', null, 'trim'),
|
||||
'remark' => input('post.remark', null, 'trim'),
|
||||
'recordinfo' => input('post.recordinfo', null, 'trim'),
|
||||
'addtime' => time(),
|
||||
@ -96,7 +96,7 @@ class Schedule extends BaseController
|
||||
'switchdate' => input('post.switchdate', null, 'trim'),
|
||||
'switchtime' => input('post.switchtime', null, 'trim'),
|
||||
'value' => input('post.value', null, 'trim'),
|
||||
'line' => input('post.value', null, 'trim'),
|
||||
'line' => input('post.line', null, 'trim'),
|
||||
'remark' => input('post.remark', null, 'trim'),
|
||||
'recordinfo' => input('post.recordinfo', null, 'trim'),
|
||||
];
|
||||
|
||||
@ -11,7 +11,7 @@ class DeployHelper
|
||||
'name' => '宝塔面板',
|
||||
'class' => 1,
|
||||
'icon' => 'bt.png',
|
||||
'desc' => '支持部署到宝塔面板搭建的站点、Docker、邮局与面板本身',
|
||||
'desc' => '支持部署到宝塔面板&aaPanel搭建的站点、Docker、邮局与面板本身',
|
||||
'note' => null,
|
||||
'inputs' => [
|
||||
'url' => [
|
||||
@ -27,6 +27,15 @@ class DeployHelper
|
||||
'placeholder' => '宝塔面板设置->面板设置->API接口',
|
||||
'required' => true,
|
||||
],
|
||||
'version' => [
|
||||
'name' => '面板版本',
|
||||
'type' => 'radio',
|
||||
'options' => [
|
||||
'0' => 'Linux面板+Win经典版',
|
||||
'1' => 'Win极速版',
|
||||
],
|
||||
'value' => '0'
|
||||
],
|
||||
'proxy' => [
|
||||
'name' => '使用代理服务器',
|
||||
'type' => 'radio',
|
||||
@ -54,10 +63,20 @@ class DeployHelper
|
||||
'name' => '网站名称列表',
|
||||
'type' => 'textarea',
|
||||
'placeholder' => '填写要部署证书的网站名称,每行一个',
|
||||
'note' => 'PHP项目和反代项目填写创建时绑定的第一个域名,Java/Node/Go等其他项目填写项目名称,邮局填写域名',
|
||||
'note' => 'PHP项目和反代项目填写创建时绑定的第一个域名,Java/Node/Go等其他项目填写项目名称,邮局和IIS站点填写绑定的域名',
|
||||
'show' => 'type==0||type==2||type==3',
|
||||
'required' => true,
|
||||
],
|
||||
'is_iis' => [
|
||||
'name' => '是否IIS站点',
|
||||
'type' => 'radio',
|
||||
'options' => [
|
||||
'0' => '否',
|
||||
'1' => '是',
|
||||
],
|
||||
'show' => 'type==0',
|
||||
'value' => '0'
|
||||
],
|
||||
],
|
||||
],
|
||||
'kangle' => [
|
||||
@ -360,17 +379,36 @@ class DeployHelper
|
||||
'note' => '填写示例:http://demo.xxxx.cn',
|
||||
'required' => true,
|
||||
],
|
||||
'auth' => [
|
||||
'name' => '认证方式',
|
||||
'type' => 'radio',
|
||||
'options' => [
|
||||
'0' => '账号密码(旧版)',
|
||||
'1' => 'API访问令牌',
|
||||
],
|
||||
'value' => '0',
|
||||
'required' => true,
|
||||
],
|
||||
'api_key' => [
|
||||
'name' => 'API访问令牌',
|
||||
'type' => 'input',
|
||||
'placeholder' => '',
|
||||
'required' => true,
|
||||
'show' => 'auth==1',
|
||||
],
|
||||
'email' => [
|
||||
'name' => '邮箱地址',
|
||||
'type' => 'input',
|
||||
'placeholder' => '',
|
||||
'required' => true,
|
||||
'show' => 'auth==0',
|
||||
],
|
||||
'password' => [
|
||||
'name' => '密码',
|
||||
'type' => 'input',
|
||||
'placeholder' => '',
|
||||
'required' => true,
|
||||
'show' => 'auth==0',
|
||||
],
|
||||
'proxy' => [
|
||||
'name' => '使用代理服务器',
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
namespace app\lib\deploy;
|
||||
|
||||
use app\lib\DeployInterface;
|
||||
use app\lib\CertHelper;
|
||||
use Exception;
|
||||
|
||||
class btpanel implements DeployInterface
|
||||
@ -10,12 +11,14 @@ class btpanel implements DeployInterface
|
||||
private $logger;
|
||||
private $url;
|
||||
private $key;
|
||||
private $version;
|
||||
private $proxy;
|
||||
|
||||
public function __construct($config)
|
||||
{
|
||||
$this->url = rtrim($config['url'], '/');
|
||||
$this->key = $config['key'];
|
||||
$this->version = isset($config['version']) ? intval($config['version']) : 0;
|
||||
$this->proxy = $config['proxy'] == 1;
|
||||
}
|
||||
|
||||
@ -23,13 +26,24 @@ class btpanel implements DeployInterface
|
||||
{
|
||||
if (empty($this->url) || empty($this->key)) throw new Exception('请填写面板地址和接口密钥');
|
||||
|
||||
$path = '/config?action=get_config';
|
||||
$response = $this->request($path, []);
|
||||
$result = json_decode($response, true);
|
||||
if (isset($result['status']) && ($result['status']==1 || isset($result['sites_path']))) {
|
||||
return true;
|
||||
if ($this->version == 1) {
|
||||
$path = '/config/get_config';
|
||||
$response = $this->request($path, []);
|
||||
$result = json_decode($response, true);
|
||||
if (isset($result['panel']['status']) && $result['panel']['status']) {
|
||||
return true;
|
||||
} else {
|
||||
throw new Exception(isset($result['msg']) ? $result['msg'] : '面板地址无法连接');
|
||||
}
|
||||
} else {
|
||||
throw new Exception(isset($result['msg']) ? $result['msg'] : '面板地址无法连接');
|
||||
$path = '/config?action=get_config';
|
||||
$response = $this->request($path, []);
|
||||
$result = json_decode($response, true);
|
||||
if (isset($result['status']) && ($result['status'] == 1 || isset($result['sites_path']))) {
|
||||
return true;
|
||||
} else {
|
||||
throw new Exception(isset($result['msg']) ? $result['msg'] : '面板地址无法连接');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -40,6 +54,40 @@ class btpanel implements DeployInterface
|
||||
$this->log("面板证书部署成功");
|
||||
return;
|
||||
}
|
||||
|
||||
$isIIS = $config['type'] == '0' && $this->version == 1 && isset($config['is_iis']) && $config['is_iis'] == '1';
|
||||
if ($isIIS) {
|
||||
$response = $this->request('/panel/get_config', []);
|
||||
$result = json_decode($response, true);
|
||||
if (isset($result['paths']['soft'])) {
|
||||
if ($result['config']['webserver'] != 'iis') {
|
||||
throw new Exception('当前安装的Web服务器不是IIS');
|
||||
}
|
||||
$panel_path = $result['paths']['soft'];
|
||||
} else {
|
||||
throw new Exception(isset($result['msg']) ? $result['msg'] : '面板地址无法连接');
|
||||
}
|
||||
|
||||
$pfx_dir = $panel_path . '/temp/ssl/' . getMillisecond();
|
||||
$pfx_path = $pfx_dir . '/cert.pfx';
|
||||
$pfx_password = '123456';
|
||||
$pfx = CertHelper::getPfx($fullchain, $privatekey, $pfx_password);
|
||||
$data = [
|
||||
['name' => 'path', 'contents' => $pfx_dir],
|
||||
['name' => 'filename', 'contents' => 'cert.pfx'],
|
||||
['name' => 'size', 'contents' => strlen($pfx)],
|
||||
['name' => 'start', 'contents' => '0'],
|
||||
['name' => 'blob', 'filename' => 'cert.pfx', 'contents' => $pfx],
|
||||
['name' => 'force', 'contents' => 'true'],
|
||||
];
|
||||
$response = $this->request('/files/upload', $data, true);
|
||||
$result = json_decode($response, true);
|
||||
if (isset($result['status']) && $result['status']) {
|
||||
} else {
|
||||
throw new Exception(isset($result['msg']) ? $result['msg'] : '面板地址无法连接');
|
||||
}
|
||||
}
|
||||
|
||||
$sites = explode("\n", $config['sites']);
|
||||
$success = 0;
|
||||
$errmsg = null;
|
||||
@ -64,6 +112,15 @@ class btpanel implements DeployInterface
|
||||
$errmsg = $e->getMessage();
|
||||
$this->log("邮局域名 {$siteName} 证书部署失败:" . $errmsg);
|
||||
}
|
||||
} elseif ($isIIS) {
|
||||
try {
|
||||
$this->deployIISSite($siteName, $pfx_path, $pfx_password);
|
||||
$this->log("域名 {$siteName} 证书部署成功");
|
||||
$success++;
|
||||
} catch (Exception $e) {
|
||||
$errmsg = $e->getMessage();
|
||||
$this->log("域名 {$siteName} 证书部署失败:" . $errmsg);
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
$this->deploySite($siteName, $fullchain, $privatekey);
|
||||
@ -82,30 +139,113 @@ class btpanel implements DeployInterface
|
||||
|
||||
private function deployPanel($fullchain, $privatekey)
|
||||
{
|
||||
$path = '/config?action=SavePanelSSL';
|
||||
$data = [
|
||||
'privateKey' => $privatekey,
|
||||
'certPem' => $fullchain,
|
||||
];
|
||||
$response = $this->request($path, $data);
|
||||
$result = json_decode($response, true);
|
||||
if (isset($result['status']) && $result['status']) {
|
||||
return true;
|
||||
} elseif (isset($result['msg'])) {
|
||||
throw new Exception($result['msg']);
|
||||
if ($this->version == 1) {
|
||||
$path = '/config/set_panel_ssl';
|
||||
$data = [
|
||||
'ssl_key' => $privatekey,
|
||||
'ssl_pem' => $fullchain,
|
||||
];
|
||||
$response = $this->request($path, $data);
|
||||
$result = json_decode($response, true);
|
||||
if (isset($result['status']) && $result['status']) {
|
||||
return true;
|
||||
} elseif (isset($result['msg'])) {
|
||||
throw new Exception($result['msg']);
|
||||
} else {
|
||||
throw new Exception($response ? $response : '返回数据解析失败');
|
||||
}
|
||||
} else {
|
||||
throw new Exception($response ? $response : '返回数据解析失败');
|
||||
$path = '/config?action=SavePanelSSL';
|
||||
$data = [
|
||||
'privateKey' => $privatekey,
|
||||
'certPem' => $fullchain,
|
||||
];
|
||||
$response = $this->request($path, $data);
|
||||
$result = json_decode($response, true);
|
||||
if (isset($result['status']) && $result['status']) {
|
||||
return true;
|
||||
} elseif (isset($result['msg'])) {
|
||||
throw new Exception($result['msg']);
|
||||
} else {
|
||||
throw new Exception($response ? $response : '返回数据解析失败');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function deploySite($siteName, $fullchain, $privatekey)
|
||||
{
|
||||
$path = '/site?action=SetSSL';
|
||||
if ($this->version == 1) {
|
||||
$path = '/datalist/get_data_list';
|
||||
$data = [
|
||||
'table' => 'sites',
|
||||
'search_type' => 'PHP',
|
||||
'search' => $siteName,
|
||||
'p' => 1,
|
||||
'limit' => 10,
|
||||
'type' => -1,
|
||||
];
|
||||
$response = $this->request($path, $data);
|
||||
$result = json_decode($response, true);
|
||||
if (isset($result['data'])) {
|
||||
if (empty($result['data'])) throw new Exception("网站 {$siteName} 不存在");
|
||||
$siteId = null;
|
||||
foreach ($result['data'] as $item) {
|
||||
if ($item['name'] == $siteName) {
|
||||
$siteId = $item['id'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (is_null($siteId)) throw new Exception("网站 {$siteName} 不存在");
|
||||
$path = '/site/set_site_ssl';
|
||||
$data = [
|
||||
'siteid' => $siteId,
|
||||
'status' => 'true',
|
||||
'sslType' => '',
|
||||
'cert' => $fullchain,
|
||||
'key' => $privatekey,
|
||||
];
|
||||
$response = $this->request($path, $data);
|
||||
$result = json_decode($response, true);
|
||||
if (isset($result['status']) && $result['status']) {
|
||||
return true;
|
||||
} elseif (isset($result['msg'])) {
|
||||
throw new Exception($result['msg']);
|
||||
} else {
|
||||
throw new Exception($response ? $response : '返回数据解析失败');
|
||||
}
|
||||
return true;
|
||||
} elseif (isset($result['msg'])) {
|
||||
throw new Exception($result['msg']);
|
||||
} else {
|
||||
throw new Exception($response ? $response : '返回数据解析失败');
|
||||
}
|
||||
} else {
|
||||
$path = '/site?action=SetSSL';
|
||||
$data = [
|
||||
'type' => '0',
|
||||
'siteName' => $siteName,
|
||||
'key' => $privatekey,
|
||||
'csr' => $fullchain,
|
||||
];
|
||||
$response = $this->request($path, $data);
|
||||
$result = json_decode($response, true);
|
||||
if (isset($result['status']) && $result['status']) {
|
||||
return true;
|
||||
} elseif (isset($result['msg'])) {
|
||||
throw new Exception($result['msg']);
|
||||
} else {
|
||||
throw new Exception($response ? $response : '返回数据解析失败');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function deployIISSite($domain, $pfx_path, $password = '123456')
|
||||
{
|
||||
$path = '/site/set_site_domain_ssl';
|
||||
$data = [
|
||||
'type' => '0',
|
||||
'siteName' => $siteName,
|
||||
'key' => $privatekey,
|
||||
'csr' => $fullchain,
|
||||
'domain' => $domain,
|
||||
'path' => $pfx_path,
|
||||
'password' => $password,
|
||||
];
|
||||
$response = $this->request($path, $data);
|
||||
$result = json_decode($response, true);
|
||||
@ -169,17 +309,27 @@ class btpanel implements DeployInterface
|
||||
}
|
||||
}
|
||||
|
||||
private function request($path, $params)
|
||||
private function request($path, $params, $file = false)
|
||||
{
|
||||
$url = $this->url . $path;
|
||||
|
||||
$now_time = time();
|
||||
$post_data = [
|
||||
'request_token' => md5($now_time . md5($this->key)),
|
||||
'request_time' => $now_time
|
||||
];
|
||||
$post_data = array_merge($post_data, $params);
|
||||
$response = http_request($url, $post_data, null, null, null, $this->proxy);
|
||||
$headers = [];
|
||||
if ($file) {
|
||||
$post_data = [
|
||||
['name' => 'request_token', 'contents' => md5($now_time . md5($this->key))],
|
||||
['name' => 'request_time', 'contents' => $now_time],
|
||||
];
|
||||
$post_data = array_merge($post_data, $params);
|
||||
$headers['Content-Type'] = 'multipart/form-data';
|
||||
} else {
|
||||
$post_data = [
|
||||
'request_token' => md5($now_time . md5($this->key)),
|
||||
'request_time' => $now_time
|
||||
];
|
||||
$post_data = array_merge($post_data, $params);
|
||||
}
|
||||
$response = http_request($url, $post_data, null, null, $headers, $this->proxy);
|
||||
return $response['body'];
|
||||
}
|
||||
}
|
||||
|
||||
@ -11,6 +11,8 @@ class lecdn implements DeployInterface
|
||||
private $url;
|
||||
private $email;
|
||||
private $password;
|
||||
private $auth;
|
||||
private $apiKey;
|
||||
private $proxy;
|
||||
private $accessToken;
|
||||
|
||||
@ -19,13 +21,22 @@ class lecdn implements DeployInterface
|
||||
$this->url = rtrim($config['url'], '/');
|
||||
$this->email = $config['email'];
|
||||
$this->password = $config['password'];
|
||||
$this->auth = isset($config['auth']) ? intval($config['auth']) : 0;
|
||||
if ($this->auth == 1) {
|
||||
$this->apiKey = $config['api_key'];
|
||||
}
|
||||
$this->proxy = $config['proxy'] == 1;
|
||||
}
|
||||
|
||||
public function check()
|
||||
{
|
||||
if (empty($this->url) || empty($this->email) || empty($this->password)) throw new Exception('账号和密码不能为空');
|
||||
$this->login();
|
||||
if ($this->auth == 1) {
|
||||
if (empty($this->url) || empty($this->apiKey)) throw new Exception('API访问令牌不能为空');
|
||||
$this->request('/prod-api/system/info');
|
||||
} else {
|
||||
if (empty($this->url) || empty($this->email) || empty($this->password)) throw new Exception('账号和密码不能为空');
|
||||
$this->login();
|
||||
}
|
||||
}
|
||||
|
||||
public function deploy($fullchain, $privatekey, $config, &$info)
|
||||
@ -33,7 +44,9 @@ class lecdn implements DeployInterface
|
||||
$id = $config['id'];
|
||||
if (empty($id)) throw new Exception('证书ID不能为空');
|
||||
|
||||
$this->login();
|
||||
if ($this->auth == 0) {
|
||||
$this->login();
|
||||
}
|
||||
|
||||
try {
|
||||
$data = $this->request('/prod-api/certificate/' . $id);
|
||||
@ -77,6 +90,8 @@ class lecdn implements DeployInterface
|
||||
$body = null;
|
||||
if ($this->accessToken) {
|
||||
$headers['Authorization'] = 'Bearer ' . $this->accessToken;
|
||||
} elseif ($this->auth == 1 && $this->apiKey) {
|
||||
$headers['Authorization'] = $this->apiKey;
|
||||
}
|
||||
if ($params) {
|
||||
$headers['Content-Type'] = 'application/json;charset=UTF-8';
|
||||
|
||||
Loading…
Reference in New Issue
Block a user