mirror of
https://github.com/netcccyun/dnsmgr.git
synced 2026-07-13 19:16:55 +08:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d1eb6267a2 | |||
| 2c81b36249 |
@@ -166,6 +166,11 @@ function getSubstr($str, $leftStr, $rightStr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function arrays_are_equal($array1, $array2)
|
||||||
|
{
|
||||||
|
return empty(array_diff($array1, $array2)) && empty(array_diff($array2, $array1));
|
||||||
|
}
|
||||||
|
|
||||||
function checkRefererHost()
|
function checkRefererHost()
|
||||||
{
|
{
|
||||||
if (!Request::header('referer')) {
|
if (!Request::header('referer')) {
|
||||||
|
|||||||
+85
-1
@@ -317,6 +317,72 @@ class Cert extends BaseController
|
|||||||
Db::name('cert_domain')->insertAll($domainList);
|
Db::name('cert_domain')->insertAll($domainList);
|
||||||
Db::commit();
|
Db::commit();
|
||||||
return json(['code' => 0, 'msg' => '修改证书订单成功!']);
|
return json(['code' => 0, 'msg' => '修改证书订单成功!']);
|
||||||
|
} elseif ($action == 'import') {
|
||||||
|
$fullchain = input('post.fullchain', null, 'trim');
|
||||||
|
$privatekey = input('post.privatekey', null, 'trim');
|
||||||
|
if (!openssl_x509_read($fullchain)) return json(['code' => -1, 'msg' => '证书内容填写错误']);
|
||||||
|
if (!openssl_get_privatekey($privatekey)) return json(['code' => -1, 'msg' => '私钥内容填写错误']);
|
||||||
|
if (!openssl_x509_check_private_key($fullchain, $privatekey)) return json(['code' => -1, 'msg' => 'SSL证书与私钥不匹配']);
|
||||||
|
$certInfo = openssl_x509_parse($fullchain, true);
|
||||||
|
if (!$certInfo || !isset($certInfo['extensions']['subjectAltName'])) return json(['code' => -1, 'msg' => '证书内容解析失败']);
|
||||||
|
|
||||||
|
$domains = [];
|
||||||
|
$subjectAltName = explode(',', $certInfo['extensions']['subjectAltName']);
|
||||||
|
foreach ($subjectAltName as $domain) {
|
||||||
|
$domain = trim($domain);
|
||||||
|
if (strpos($domain, 'DNS:') === 0) $domain = substr($domain, 4);
|
||||||
|
if (!empty($domain)) {
|
||||||
|
$domains[] = $domain;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$domains = array_unique($domains);
|
||||||
|
if (empty($domains)) return json(['code' => -1, 'msg' => '证书绑定域名不能为空']);
|
||||||
|
$issuetime = date('Y-m-d H:i:s', $certInfo['validFrom_time_t']);
|
||||||
|
$expiretime = date('Y-m-d H:i:s', $certInfo['validTo_time_t']);
|
||||||
|
$issuer = $certInfo['issuer']['CN'];
|
||||||
|
|
||||||
|
$order_ids = Db::name('cert_order')->where('issuetime', $issuetime)->column('id');
|
||||||
|
if (!empty($order_ids)) {
|
||||||
|
foreach ($order_ids as $order_id) {
|
||||||
|
$domains2 = Db::name('cert_domain')->where('oid', $order_id)->column('domain');
|
||||||
|
if (arrays_are_equal($domains2, $domains)) {
|
||||||
|
return json(['code' => -1, 'msg' => '该证书已存在,无需重复添加']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$order = [
|
||||||
|
'aid' => input('post.aid/d'),
|
||||||
|
'keytype' => input('post.keytype'),
|
||||||
|
'keysize' => input('post.keysize'),
|
||||||
|
'addtime' => date('Y-m-d H:i:s'),
|
||||||
|
'updatetime' => date('Y-m-d H:i:s'),
|
||||||
|
'issuetime' => $issuetime,
|
||||||
|
'expiretime' => $expiretime,
|
||||||
|
'issuer' => $issuer,
|
||||||
|
'status' => 3,
|
||||||
|
'fullchain' => $fullchain,
|
||||||
|
'privatekey' => $privatekey,
|
||||||
|
];
|
||||||
|
if (empty($order['aid']) || empty($order['keytype']) || empty($order['keysize'])) return json(['code' => -1, 'msg' => '必填参数不能为空']);
|
||||||
|
|
||||||
|
$res = $this->check_order($order, $domains);
|
||||||
|
if (is_array($res)) return json($res);
|
||||||
|
|
||||||
|
Db::startTrans();
|
||||||
|
$id = Db::name('cert_order')->insertGetId($order);
|
||||||
|
$domainList = [];
|
||||||
|
$i = 1;
|
||||||
|
foreach ($domains as $domain) {
|
||||||
|
$domainList[] = [
|
||||||
|
'oid' => $id,
|
||||||
|
'domain' => $domain,
|
||||||
|
'sort' => $i++,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
Db::name('cert_domain')->insertAll($domainList);
|
||||||
|
Db::commit();
|
||||||
|
return json(['code' => 0, 'msg' => '导入证书成功!']);
|
||||||
} elseif ($action == 'del') {
|
} elseif ($action == 'del') {
|
||||||
$id = input('post.id/d');
|
$id = input('post.id/d');
|
||||||
$dcount = DB::name('cert_deploy')->where('oid', $id)->count();
|
$dcount = DB::name('cert_deploy')->where('oid', $id)->count();
|
||||||
@@ -368,7 +434,11 @@ class Cert extends BaseController
|
|||||||
$max_domains = CertHelper::$cert_config[$account['type']]['max_domains'];
|
$max_domains = CertHelper::$cert_config[$account['type']]['max_domains'];
|
||||||
$wildcard = CertHelper::$cert_config[$account['type']]['wildcard'];
|
$wildcard = CertHelper::$cert_config[$account['type']]['wildcard'];
|
||||||
$cname = CertHelper::$cert_config[$account['type']]['cname'];
|
$cname = CertHelper::$cert_config[$account['type']]['cname'];
|
||||||
if (count($domains) > $max_domains) return ['code' => -1, 'msg' => '域名数量不能超过'.$max_domains.'个'];
|
if (count($domains) > $max_domains) {
|
||||||
|
if (!(count($domains) == 2 && $max_domains == 1 && ltrim($domains[0], 'www.') == ltrim($domains[1], 'www.'))) {
|
||||||
|
return ['code' => -1, 'msg' => '域名数量不能超过'.$max_domains.'个'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
foreach($domains as $domain){
|
foreach($domains as $domain){
|
||||||
if(!$wildcard && strpos($domain, '*') !== false) return ['code' => -1, 'msg' => '该证书账户类型不支持泛域名'];
|
if(!$wildcard && strpos($domain, '*') !== false) return ['code' => -1, 'msg' => '该证书账户类型不支持泛域名'];
|
||||||
@@ -438,6 +508,20 @@ class Cert extends BaseController
|
|||||||
return View::fetch();
|
return View::fetch();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function order_import()
|
||||||
|
{
|
||||||
|
if (!checkPermission(2)) return $this->alert('error', '无权限');
|
||||||
|
$accounts = [];
|
||||||
|
foreach (Db::name('cert_account')->where('deploy', 0)->select() as $row) {
|
||||||
|
$accounts[$row['id']] = ['name'=>$row['id'].'_'.CertHelper::$cert_config[$row['type']]['name'], 'type'=>$row['type']];
|
||||||
|
if (!empty($row['remark'])) {
|
||||||
|
$accounts[$row['id']]['name'] .= '(' . $row['remark'] . ')';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
View::assign('accounts', $accounts);
|
||||||
|
return View::fetch();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public function deploytask()
|
public function deploytask()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -667,7 +667,7 @@ class DeployHelper
|
|||||||
'name' => '实例ID',
|
'name' => '实例ID',
|
||||||
'type' => 'input',
|
'type' => 'input',
|
||||||
'placeholder' => '',
|
'placeholder' => '',
|
||||||
'show' => 'product==\'lighthouse\'',
|
'show' => 'product==\'lighthouse\'||product==\'ddos\'',
|
||||||
'required' => true,
|
'required' => true,
|
||||||
],
|
],
|
||||||
'domain' => [
|
'domain' => [
|
||||||
@@ -816,10 +816,18 @@ class DeployHelper
|
|||||||
'options' => [
|
'options' => [
|
||||||
['value'=>'cdn', 'label'=>'CDN'],
|
['value'=>'cdn', 'label'=>'CDN'],
|
||||||
['value'=>'oss', 'label'=>'OSS'],
|
['value'=>'oss', 'label'=>'OSS'],
|
||||||
|
['value'=>'pili', 'label'=>'视频直播'],
|
||||||
],
|
],
|
||||||
'value' => 'cdn',
|
'value' => 'cdn',
|
||||||
'required' => true,
|
'required' => true,
|
||||||
],
|
],
|
||||||
|
'pili_hub' => [
|
||||||
|
'name' => '直播空间名称',
|
||||||
|
'type' => 'input',
|
||||||
|
'placeholder' => '',
|
||||||
|
'show' => 'product==\'pili\'',
|
||||||
|
'required' => true,
|
||||||
|
],
|
||||||
'domain' => [
|
'domain' => [
|
||||||
'name' => '绑定的域名',
|
'name' => '绑定的域名',
|
||||||
'type' => 'input',
|
'type' => 'input',
|
||||||
@@ -931,10 +939,39 @@ class DeployHelper
|
|||||||
],
|
],
|
||||||
],
|
],
|
||||||
'taskinputs' => [
|
'taskinputs' => [
|
||||||
|
'product' => [
|
||||||
|
'name' => '要部署的产品',
|
||||||
|
'type' => 'select',
|
||||||
|
'options' => [
|
||||||
|
['value'=>'cdn', 'label'=>'内容分发网络CDN'],
|
||||||
|
['value'=>'dcdn', 'label'=>'全站加速DCDN'],
|
||||||
|
['value'=>'clb', 'label'=>'负载均衡CLB'],
|
||||||
|
['value'=>'tos', 'label'=>'对象存储TOS'],
|
||||||
|
['value'=>'live', 'label'=>'视频直播'],
|
||||||
|
['value'=>'imagex', 'label'=>'veImageX'],
|
||||||
|
],
|
||||||
|
'value' => 'cdn',
|
||||||
|
'required' => true,
|
||||||
|
],
|
||||||
|
'bucket_domain' => [
|
||||||
|
'name' => 'Bucket域名',
|
||||||
|
'type' => 'input',
|
||||||
|
'placeholder' => '',
|
||||||
|
'show' => 'product==\'tos\'',
|
||||||
|
'required' => true,
|
||||||
|
],
|
||||||
'domain' => [
|
'domain' => [
|
||||||
'name' => '绑定的域名',
|
'name' => '绑定的域名',
|
||||||
'type' => 'input',
|
'type' => 'input',
|
||||||
'placeholder' => '多个域名可使用,分隔',
|
'placeholder' => '多个域名可使用,分隔',
|
||||||
|
'show' => 'product!=\'clb\'',
|
||||||
|
'required' => true,
|
||||||
|
],
|
||||||
|
'listener_id' => [
|
||||||
|
'name' => '监听器ID',
|
||||||
|
'type' => 'input',
|
||||||
|
'placeholder' => '',
|
||||||
|
'show' => 'product==\'clb\'',
|
||||||
'required' => true,
|
'required' => true,
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
@@ -1015,6 +1052,48 @@ class DeployHelper
|
|||||||
],
|
],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
'ctyun' => [
|
||||||
|
'name' => '天翼云',
|
||||||
|
'class' => 2,
|
||||||
|
'icon' => 'ctyun.ico',
|
||||||
|
'note' => '支持部署到天翼云CDN',
|
||||||
|
'inputs' => [
|
||||||
|
'AccessKeyId' => [
|
||||||
|
'name' => 'AccessKeyId',
|
||||||
|
'type' => 'input',
|
||||||
|
'placeholder' => '',
|
||||||
|
'required' => true,
|
||||||
|
],
|
||||||
|
'SecretAccessKey' => [
|
||||||
|
'name' => 'SecretAccessKey',
|
||||||
|
'type' => 'input',
|
||||||
|
'placeholder' => '',
|
||||||
|
'required' => true,
|
||||||
|
],
|
||||||
|
'proxy' => [
|
||||||
|
'name' => '使用代理服务器',
|
||||||
|
'type' => 'radio',
|
||||||
|
'options' => [
|
||||||
|
'0' => '否',
|
||||||
|
'1' => '是',
|
||||||
|
],
|
||||||
|
'value' => '0'
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'taskinputs' => [
|
||||||
|
'product' => [
|
||||||
|
'name' => '产品',
|
||||||
|
'type' => 'hidden',
|
||||||
|
'value' => 'cdn',
|
||||||
|
],
|
||||||
|
'domain' => [
|
||||||
|
'name' => 'CDN域名',
|
||||||
|
'type' => 'input',
|
||||||
|
'placeholder' => '',
|
||||||
|
'required' => true,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
'allwaf' => [
|
'allwaf' => [
|
||||||
'name' => 'AllWAF',
|
'name' => 'AllWAF',
|
||||||
'class' => 2,
|
'class' => 2,
|
||||||
|
|||||||
@@ -227,7 +227,7 @@ class ACMECert extends ACMEv2
|
|||||||
|
|
||||||
public function authOrder($order)
|
public function authOrder($order)
|
||||||
{
|
{
|
||||||
if ($order['status'] != 'ready' && empty($order['challenges'])) {
|
if ($order['status'] != 'pending' && $order['status'] != 'ready' && empty($order['challenges'])) {
|
||||||
throw new Exception('No challenges available');
|
throw new Exception('No challenges available');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,163 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\lib\client;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 天翼云
|
||||||
|
*/
|
||||||
|
class Ctyun
|
||||||
|
{
|
||||||
|
private $AccessKeyId;
|
||||||
|
private $SecretAccessKey;
|
||||||
|
private $endpoint;
|
||||||
|
private $proxy = false;
|
||||||
|
|
||||||
|
public function __construct($AccessKeyId, $SecretAccessKey, $endpoint, $proxy = false)
|
||||||
|
{
|
||||||
|
$this->AccessKeyId = $AccessKeyId;
|
||||||
|
$this->SecretAccessKey = $SecretAccessKey;
|
||||||
|
$this->endpoint = $endpoint;
|
||||||
|
$this->proxy = $proxy;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $method 请求方法
|
||||||
|
* @param string $path 请求路径
|
||||||
|
* @param array|null $query 请求参数
|
||||||
|
* @param array|null $params 请求体
|
||||||
|
* @return array
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function request($method, $path, $query = null, $params = null)
|
||||||
|
{
|
||||||
|
if (!empty($query)) {
|
||||||
|
$query = array_filter($query, function ($a) { return $a !== null;});
|
||||||
|
}
|
||||||
|
if (!empty($params)) {
|
||||||
|
$params = array_filter($params, function ($a) { return $a !== null;});
|
||||||
|
}
|
||||||
|
|
||||||
|
$time = time();
|
||||||
|
$date = date("Ymd\THis\Z", $time);
|
||||||
|
$body = !empty($params) ? json_encode($params) : '';
|
||||||
|
$headers = [
|
||||||
|
'Host' => $this->endpoint,
|
||||||
|
'Eop-date' => $date,
|
||||||
|
'ctyun-eop-request-id' => getSid(),
|
||||||
|
];
|
||||||
|
if ($body) {
|
||||||
|
$headers['Content-Type'] = 'application/json';
|
||||||
|
}
|
||||||
|
|
||||||
|
$authorization = $this->generateSign($query, $headers, $body, $date);
|
||||||
|
$headers['Eop-Authorization'] = $authorization;
|
||||||
|
|
||||||
|
$url = 'https://' . $this->endpoint . $path;
|
||||||
|
if (!empty($query)) {
|
||||||
|
$url .= '?' . http_build_query($query);
|
||||||
|
}
|
||||||
|
$header = [];
|
||||||
|
foreach ($headers as $key => $value) {
|
||||||
|
$header[] = $key . ': ' . $value;
|
||||||
|
}
|
||||||
|
return $this->curl($method, $url, $body, $header);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function generateSign($query, $headers, $body, $date)
|
||||||
|
{
|
||||||
|
// step 1: build canonical request string
|
||||||
|
$canonicalQueryString = $this->getCanonicalQueryString($query);
|
||||||
|
[$canonicalHeaders, $signedHeaders] = $this->getCanonicalHeaders($headers);
|
||||||
|
$hashedRequestPayload = hash("sha256", $body);
|
||||||
|
|
||||||
|
// step 2: build string to sign
|
||||||
|
$stringToSign = $canonicalHeaders . "\n"
|
||||||
|
. $canonicalQueryString . "\n"
|
||||||
|
. $hashedRequestPayload;
|
||||||
|
|
||||||
|
// step 3: sign string
|
||||||
|
$ktime = hash_hmac("sha256", $date, $this->SecretAccessKey, true);
|
||||||
|
$kAk = hash_hmac("sha256", $this->AccessKeyId, $ktime, true);
|
||||||
|
$kdate = hash_hmac("sha256", substr($date, 0, 8), $kAk, true);
|
||||||
|
$signature = hash_hmac("sha256", $stringToSign, $kdate, true);
|
||||||
|
$signature = base64_encode($signature);
|
||||||
|
|
||||||
|
// step 4: build authorization
|
||||||
|
$authorization = $this->AccessKeyId . " Headers=" . $signedHeaders . " Signature=" . $signature;
|
||||||
|
|
||||||
|
return $authorization;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function escape($str)
|
||||||
|
{
|
||||||
|
$search = ['+', '*', '%7E'];
|
||||||
|
$replace = ['%20', '%2A', '~'];
|
||||||
|
return str_replace($search, $replace, urlencode($str));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getCanonicalQueryString($parameters)
|
||||||
|
{
|
||||||
|
if (empty($parameters)) return '';
|
||||||
|
ksort($parameters);
|
||||||
|
$canonicalQueryString = '';
|
||||||
|
foreach ($parameters as $key => $value) {
|
||||||
|
$canonicalQueryString .= '&' . $this->escape($key) . '=' . $this->escape($value);
|
||||||
|
}
|
||||||
|
return substr($canonicalQueryString, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getCanonicalHeaders($oldheaders)
|
||||||
|
{
|
||||||
|
$headers = array();
|
||||||
|
foreach ($oldheaders as $key => $value) {
|
||||||
|
$headers[strtolower($key)] = trim($value);
|
||||||
|
}
|
||||||
|
ksort($headers);
|
||||||
|
|
||||||
|
$canonicalHeaders = '';
|
||||||
|
$signedHeaders = '';
|
||||||
|
foreach ($headers as $key => $value) {
|
||||||
|
$canonicalHeaders .= $key . ':' . $value . "\n";
|
||||||
|
$signedHeaders .= $key . ';';
|
||||||
|
}
|
||||||
|
$signedHeaders = substr($signedHeaders, 0, -1);
|
||||||
|
return [$canonicalHeaders, $signedHeaders];
|
||||||
|
}
|
||||||
|
|
||||||
|
private function curl($method, $url, $body, $header)
|
||||||
|
{
|
||||||
|
$ch = curl_init($url);
|
||||||
|
if ($this->proxy) {
|
||||||
|
curl_set_proxy($ch);
|
||||||
|
}
|
||||||
|
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||||
|
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
||||||
|
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
|
||||||
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||||
|
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
|
||||||
|
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
|
||||||
|
if (!empty($body)) {
|
||||||
|
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
|
||||||
|
}
|
||||||
|
$response = curl_exec($ch);
|
||||||
|
$errno = curl_errno($ch);
|
||||||
|
if ($errno) {
|
||||||
|
curl_close($ch);
|
||||||
|
throw new Exception('Curl error: ' . curl_error($ch));
|
||||||
|
}
|
||||||
|
curl_close($ch);
|
||||||
|
|
||||||
|
$arr = json_decode($response, true);
|
||||||
|
if (isset($arr['statusCode']) && $arr['statusCode'] == 100000) {
|
||||||
|
return isset($arr['returnObj']) ? $arr['returnObj'] : true;
|
||||||
|
} elseif (isset($arr['errorMessage'])) {
|
||||||
|
throw new Exception($arr['errorMessage']);
|
||||||
|
} elseif (isset($arr['message'])) {
|
||||||
|
throw new Exception($arr['message']);
|
||||||
|
} else {
|
||||||
|
throw new Exception('返回数据解析失败');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -61,6 +61,39 @@ class Qiniu
|
|||||||
return $this->curl($method, $url, $body, $header);
|
return $this->curl($method, $url, $body, $header);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function pili_request($method, $path, $query = null, $params = null)
|
||||||
|
{
|
||||||
|
$this->ApiUrl = 'https://pili.qiniuapi.com';
|
||||||
|
$url = $this->ApiUrl . $path;
|
||||||
|
$query_str = null;
|
||||||
|
$body = null;
|
||||||
|
if (!empty($query)) {
|
||||||
|
$query = array_filter($query, function ($a) {
|
||||||
|
return $a !== null;
|
||||||
|
});
|
||||||
|
$query_str = http_build_query($query);
|
||||||
|
$url .= '?' . $query_str;
|
||||||
|
}
|
||||||
|
if (!empty($params)) {
|
||||||
|
$params = array_filter($params, function ($a) {
|
||||||
|
return $a !== null;
|
||||||
|
});
|
||||||
|
$body = json_encode($params);
|
||||||
|
}
|
||||||
|
|
||||||
|
$sign_str = $method . ' ' . $path . ($query_str ? '?' . $query_str : '') . "\nHost: pili.qiniuapi.com" . ($body ? "\nContent-Type: application/json" : '') . "\n\n" . $body;
|
||||||
|
$hmac = hash_hmac('sha1', $sign_str, $this->SecretKey, true);
|
||||||
|
$sign = $this->AccessKey . ':' . $this->base64_urlSafeEncode($hmac);
|
||||||
|
|
||||||
|
$header = [
|
||||||
|
'Authorization: Qiniu ' . $sign,
|
||||||
|
];
|
||||||
|
if ($body) {
|
||||||
|
$header[] = 'Content-Type: application/json';
|
||||||
|
}
|
||||||
|
return $this->curl($method, $url, $body, $header);
|
||||||
|
}
|
||||||
|
|
||||||
private function base64_urlSafeEncode($data)
|
private function base64_urlSafeEncode($data)
|
||||||
{
|
{
|
||||||
$find = array('+', '/');
|
$find = array('+', '/');
|
||||||
@@ -95,7 +128,7 @@ class Qiniu
|
|||||||
|
|
||||||
if ($httpCode == 200) {
|
if ($httpCode == 200) {
|
||||||
$arr = json_decode($response, true);
|
$arr = json_decode($response, true);
|
||||||
if($arr) return $arr;
|
if ($arr) return $arr;
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
$arr = json_decode($response, true);
|
$arr = json_decode($response, true);
|
||||||
|
|||||||
@@ -38,7 +38,9 @@ class Volcengine
|
|||||||
public function request($method, $action, $params = [], $querys = [])
|
public function request($method, $action, $params = [], $querys = [])
|
||||||
{
|
{
|
||||||
if (!empty($params)) {
|
if (!empty($params)) {
|
||||||
$params = array_filter($params, function ($a) { return $a !== null;});
|
$params = array_filter($params, function ($a) {
|
||||||
|
return $a !== null;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
$query = [
|
$query = [
|
||||||
@@ -78,9 +80,51 @@ class Volcengine
|
|||||||
return $this->curl($method, $url, $body, $header);
|
return $this->curl($method, $url, $body, $header);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $method 请求方法
|
||||||
|
* @param string $action 方法名称
|
||||||
|
* @param array $params 请求参数
|
||||||
|
* @return array
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function tos_request($method, $params = [], $query = [])
|
||||||
|
{
|
||||||
|
if (!empty($params)) {
|
||||||
|
$params = array_filter($params, function ($a) {
|
||||||
|
return $a !== null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$body = '';
|
||||||
|
if ($method != 'GET') {
|
||||||
|
$body = !empty($params) ? json_encode($params) : '';
|
||||||
|
}
|
||||||
|
|
||||||
|
$time = time();
|
||||||
|
$headers = [
|
||||||
|
'Host' => $this->endpoint,
|
||||||
|
'X-Tos-Date' => gmdate("Ymd\THis\Z", $time),
|
||||||
|
'X-Tos-Content-Sha256' => hash("sha256", $body),
|
||||||
|
];
|
||||||
|
if ($body) {
|
||||||
|
$headers['Content-Type'] = 'application/json';
|
||||||
|
}
|
||||||
|
$path = '/';
|
||||||
|
|
||||||
|
$authorization = $this->generateSign($method, $path, $query, $headers, $body, $time);
|
||||||
|
$headers['Authorization'] = $authorization;
|
||||||
|
|
||||||
|
$url = 'https://' . $this->endpoint . $path . '?' . http_build_query($query);
|
||||||
|
$header = [];
|
||||||
|
foreach ($headers as $key => $value) {
|
||||||
|
$header[] = $key . ': ' . $value;
|
||||||
|
}
|
||||||
|
return $this->curl($method, $url, $body, $header);
|
||||||
|
}
|
||||||
|
|
||||||
private function generateSign($method, $path, $query, $headers, $body, $time)
|
private function generateSign($method, $path, $query, $headers, $body, $time)
|
||||||
{
|
{
|
||||||
$algorithm = "HMAC-SHA256";
|
$algorithm = $this->service == 'tos' ? "TOS4-HMAC-SHA256" : "HMAC-SHA256";
|
||||||
|
|
||||||
// step 1: build canonical request string
|
// step 1: build canonical request string
|
||||||
$httpRequestMethod = $method;
|
$httpRequestMethod = $method;
|
||||||
@@ -177,21 +221,27 @@ class Volcengine
|
|||||||
curl_close($ch);
|
curl_close($ch);
|
||||||
throw new Exception('Curl error: ' . curl_error($ch));
|
throw new Exception('Curl error: ' . curl_error($ch));
|
||||||
}
|
}
|
||||||
|
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||||
curl_close($ch);
|
curl_close($ch);
|
||||||
|
|
||||||
$arr = json_decode($response, true);
|
$arr = json_decode($response, true);
|
||||||
if ($arr) {
|
if ($httpCode == 200) {
|
||||||
|
if (isset($arr['Result'])) {
|
||||||
|
return $arr['Result'];
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
if (isset($arr['ResponseMetadata']['Error']['MessageCN'])) {
|
if (isset($arr['ResponseMetadata']['Error']['MessageCN'])) {
|
||||||
throw new Exception($arr['ResponseMetadata']['Error']['MessageCN']);
|
throw new Exception($arr['ResponseMetadata']['Error']['MessageCN']);
|
||||||
} elseif (isset($arr['ResponseMetadata']['Error']['Message'])) {
|
} elseif (isset($arr['ResponseMetadata']['Error']['Message'])) {
|
||||||
throw new Exception($arr['ResponseMetadata']['Error']['Message']);
|
throw new Exception($arr['ResponseMetadata']['Error']['Message']);
|
||||||
} elseif (isset($arr['Result'])) {
|
} elseif (isset($arr['Message'])) {
|
||||||
return $arr['Result'];
|
throw new Exception($arr['Message']);
|
||||||
|
} elseif (isset($arr['message'])) {
|
||||||
|
throw new Exception($arr['message']);
|
||||||
} else {
|
} else {
|
||||||
return true;
|
throw new Exception('返回数据解析失败(http_code=' . $httpCode . ')');
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
throw new Exception('返回数据解析失败');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,14 +52,33 @@ class allwaf implements DeployInterface
|
|||||||
$this->log('获取证书列表成功(total=' . count($list) . ')');
|
$this->log('获取证书列表成功(total=' . count($list) . ')');
|
||||||
|
|
||||||
$certInfo = openssl_x509_parse($fullchain, true);
|
$certInfo = openssl_x509_parse($fullchain, true);
|
||||||
|
$cert_name = str_replace('*.', '', $certInfo['subject']['CN']) . '-' . $certInfo['validFrom_time_t'];
|
||||||
|
|
||||||
foreach ($list as $row) {
|
if (!empty($list)) {
|
||||||
|
foreach ($list as $row) {
|
||||||
|
$params = [
|
||||||
|
'sslCertId' => $row['id'],
|
||||||
|
'isOn' => true,
|
||||||
|
'name' => $row['name'],
|
||||||
|
'description' => $row['description'],
|
||||||
|
'serverName' => $row['serverName'],
|
||||||
|
'isCA' => false,
|
||||||
|
'certData' => base64_encode($fullchain),
|
||||||
|
'keyData' => base64_encode($privatekey),
|
||||||
|
'timeBeginAt' => $certInfo['validFrom_time_t'],
|
||||||
|
'timeEndAt' => $certInfo['validTo_time_t'],
|
||||||
|
'dnsNames' => $domains,
|
||||||
|
'commonNames' => [$certInfo['issuer']['CN']],
|
||||||
|
];
|
||||||
|
$this->request('/SSLCertService/updateSSLCert', $params);
|
||||||
|
$this->log('证书ID:' . $row['id'] . '更新成功!');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
$params = [
|
$params = [
|
||||||
'sslCertId' => $row['id'],
|
|
||||||
'isOn' => true,
|
'isOn' => true,
|
||||||
'name' => $row['name'],
|
'name' => $cert_name,
|
||||||
'description' => $row['description'],
|
'description' => $cert_name,
|
||||||
'serverName' => $row['serverName'],
|
'serverName' => $certInfo['subject']['CN'],
|
||||||
'isCA' => false,
|
'isCA' => false,
|
||||||
'certData' => base64_encode($fullchain),
|
'certData' => base64_encode($fullchain),
|
||||||
'keyData' => base64_encode($privatekey),
|
'keyData' => base64_encode($privatekey),
|
||||||
@@ -68,8 +87,8 @@ class allwaf implements DeployInterface
|
|||||||
'dnsNames' => $domains,
|
'dnsNames' => $domains,
|
||||||
'commonNames' => [$certInfo['issuer']['CN']],
|
'commonNames' => [$certInfo['issuer']['CN']],
|
||||||
];
|
];
|
||||||
$this->request('/SSLCertService/updateSSLCert', $params);
|
$result = $this->request('/SSLCertService/createSSLCert', $params);
|
||||||
$this->log('证书ID:' . $row['id'] . '更新成功!');
|
$this->log('证书ID:' . $result['sslCertId'] . '添加成功!');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,81 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\lib\deploy;
|
||||||
|
|
||||||
|
use app\lib\DeployInterface;
|
||||||
|
use app\lib\client\Ctyun as CtyunClient;
|
||||||
|
use Exception;
|
||||||
|
|
||||||
|
class ctyun implements DeployInterface
|
||||||
|
{
|
||||||
|
private $logger;
|
||||||
|
private $AccessKeyId;
|
||||||
|
private $SecretAccessKey;
|
||||||
|
private $proxy;
|
||||||
|
private $client;
|
||||||
|
|
||||||
|
public function __construct($config)
|
||||||
|
{
|
||||||
|
$this->AccessKeyId = $config['AccessKeyId'];
|
||||||
|
$this->SecretAccessKey = $config['SecretAccessKey'];
|
||||||
|
$this->proxy = isset($config['proxy']) ? $config['proxy'] == 1 : false;
|
||||||
|
$this->client = new CtyunClient($this->AccessKeyId, $this->SecretAccessKey, 'ctcdn-global.ctapi.ctyun.cn', $this->proxy);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function check()
|
||||||
|
{
|
||||||
|
if (empty($this->AccessKeyId) || empty($this->SecretAccessKey)) throw new Exception('必填参数不能为空');
|
||||||
|
$this->client->request('GET', '/v1/cert/query-cert-list');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function deploy($fullchain, $privatekey, $config, &$info)
|
||||||
|
{
|
||||||
|
$certInfo = openssl_x509_parse($fullchain, true);
|
||||||
|
if (!$certInfo) throw new Exception('证书解析失败');
|
||||||
|
$cert_name = str_replace('*.', '', $certInfo['subject']['CN']) . '-' . $certInfo['validFrom_time_t'];
|
||||||
|
|
||||||
|
$param = [
|
||||||
|
'name' => $cert_name,
|
||||||
|
'key' => $privatekey,
|
||||||
|
'certs' => $fullchain,
|
||||||
|
];
|
||||||
|
try {
|
||||||
|
$this->client->request('POST', '/v1/cert/creat-cert', null, $param);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
if (strpos($e->getMessage(), '已存在重名的证书') !== false) {
|
||||||
|
$this->log('已存在重名的证书 cert_name=' . $cert_name);
|
||||||
|
} else {
|
||||||
|
throw new Exception('上传证书失败:' . $e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$this->log('上传证书成功 cert_name=' . $cert_name);
|
||||||
|
|
||||||
|
$param = [
|
||||||
|
'domain' => $config['domain'],
|
||||||
|
'https_status' => 'on',
|
||||||
|
'cert_name' => $cert_name,
|
||||||
|
];
|
||||||
|
try {
|
||||||
|
$this->client->request('POST', '/v1/domain/update-domain', null, $param);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
if (strpos($e->getMessage(), '请求已提交,请勿重复操作!') === false) {
|
||||||
|
throw new Exception($e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->log('CDN域名 ' . $config['domain'] . ' 部署证书成功!');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setLogger($func)
|
||||||
|
{
|
||||||
|
$this->logger = $func;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function log($txt)
|
||||||
|
{
|
||||||
|
if ($this->logger) {
|
||||||
|
call_user_func($this->logger, $txt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -50,20 +50,39 @@ class goedge implements DeployInterface
|
|||||||
throw new Exception('获取证书列表失败:' . $e->getMessage());
|
throw new Exception('获取证书列表失败:' . $e->getMessage());
|
||||||
}
|
}
|
||||||
$list = json_decode(base64_decode($data['sslCertsJSON']), true);
|
$list = json_decode(base64_decode($data['sslCertsJSON']), true);
|
||||||
if (!$list || empty($list)) {
|
if ($list === false) {
|
||||||
throw new Exception('证书列表为空');
|
throw new Exception('证书列表为空');
|
||||||
}
|
}
|
||||||
$this->log('获取证书列表成功(total=' . count($list) . ')');
|
$this->log('获取证书列表成功(total=' . count($list) . ')');
|
||||||
|
|
||||||
$certInfo = openssl_x509_parse($fullchain, true);
|
$certInfo = openssl_x509_parse($fullchain, true);
|
||||||
|
$cert_name = str_replace('*.', '', $certInfo['subject']['CN']) . '-' . $certInfo['validFrom_time_t'];
|
||||||
|
|
||||||
foreach ($list as $row) {
|
if (!empty($list)) {
|
||||||
|
foreach ($list as $row) {
|
||||||
|
$params = [
|
||||||
|
'sslCertId' => $row['id'],
|
||||||
|
'isOn' => true,
|
||||||
|
'name' => $row['name'],
|
||||||
|
'description' => $row['description'],
|
||||||
|
'serverName' => $row['serverName'],
|
||||||
|
'isCA' => false,
|
||||||
|
'certData' => base64_encode($fullchain),
|
||||||
|
'keyData' => base64_encode($privatekey),
|
||||||
|
'timeBeginAt' => $certInfo['validFrom_time_t'],
|
||||||
|
'timeEndAt' => $certInfo['validTo_time_t'],
|
||||||
|
'dnsNames' => $domains,
|
||||||
|
'commonNames' => [$certInfo['issuer']['CN']],
|
||||||
|
];
|
||||||
|
$this->request('/SSLCertService/updateSSLCert', $params);
|
||||||
|
$this->log('证书ID:' . $row['id'] . '更新成功!');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
$params = [
|
$params = [
|
||||||
'sslCertId' => $row['id'],
|
|
||||||
'isOn' => true,
|
'isOn' => true,
|
||||||
'name' => $row['name'],
|
'name' => $cert_name,
|
||||||
'description' => $row['description'],
|
'description' => $cert_name,
|
||||||
'serverName' => $row['serverName'],
|
'serverName' => $certInfo['subject']['CN'],
|
||||||
'isCA' => false,
|
'isCA' => false,
|
||||||
'certData' => base64_encode($fullchain),
|
'certData' => base64_encode($fullchain),
|
||||||
'keyData' => base64_encode($privatekey),
|
'keyData' => base64_encode($privatekey),
|
||||||
@@ -72,8 +91,8 @@ class goedge implements DeployInterface
|
|||||||
'dnsNames' => $domains,
|
'dnsNames' => $domains,
|
||||||
'commonNames' => [$certInfo['issuer']['CN']],
|
'commonNames' => [$certInfo['issuer']['CN']],
|
||||||
];
|
];
|
||||||
$this->request('/SSLCertService/updateSSLCert', $params);
|
$result = $this->request('/SSLCertService/createSSLCert', $params);
|
||||||
$this->log('证书ID:' . $row['id'] . '更新成功!');
|
$this->log('证书ID:' . $result['sslCertId'] . '添加成功!');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+133
-20
@@ -23,18 +23,31 @@ class huoshan implements DeployInterface
|
|||||||
public function check()
|
public function check()
|
||||||
{
|
{
|
||||||
if (empty($this->AccessKeyId) || empty($this->SecretAccessKey)) throw new Exception('必填参数不能为空');
|
if (empty($this->AccessKeyId) || empty($this->SecretAccessKey)) throw new Exception('必填参数不能为空');
|
||||||
$client = new Volcengine($this->AccessKeyId, $this->SecretAccessKey, 'cdn.volcengineapi.com', 'cdn', '2021-03-01', 'cn-north-1', $this->proxy);
|
$client = new Volcengine($this->AccessKeyId, $this->SecretAccessKey, 'open.volcengineapi.com', 'cdn', '2021-03-01', 'cn-north-1', $this->proxy);
|
||||||
$client->request('POST', 'ListCertInfo', ['Source' => 'volc_cert_center']);
|
$client->request('POST', 'ListCertInfo', ['Source' => 'volc_cert_center']);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function deploy($fullchain, $privatekey, $config, &$info)
|
public function deploy($fullchain, $privatekey, $config, &$info)
|
||||||
{
|
{
|
||||||
if (empty($config['domain'])) throw new Exception('绑定的域名不能为空');
|
if ($config['product'] == 'live') {
|
||||||
$cert_id = $this->get_cert_id($fullchain, $privatekey);
|
$this->deploy_live($fullchain, $privatekey, $config);
|
||||||
if (!$cert_id) throw new Exception('获取证书ID失败');
|
} else {
|
||||||
$info['cert_id'] = $cert_id;
|
$cert_id = $this->get_cert_id($fullchain, $privatekey);
|
||||||
$this->deploy_cdn($cert_id, $config);
|
if (!$cert_id) throw new Exception('获取证书ID失败');
|
||||||
|
$info['cert_id'] = $cert_id;
|
||||||
|
if (!isset($config['product']) || $config['product'] == 'cdn') {
|
||||||
|
$this->deploy_cdn($cert_id, $config);
|
||||||
|
} elseif ($config['product'] == 'dcdn') {
|
||||||
|
$this->deploy_dcdn($cert_id, $config);
|
||||||
|
} elseif ($config['product'] == 'tos') {
|
||||||
|
$this->deploy_tos($cert_id, $config);
|
||||||
|
} elseif ($config['product'] == 'imagex') {
|
||||||
|
$this->deploy_imagex($cert_id, $config);
|
||||||
|
} elseif ($config['product'] == 'clb') {
|
||||||
|
$this->deploy_clb($cert_id, $config);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function deploy_cdn($cert_id, $config)
|
private function deploy_cdn($cert_id, $config)
|
||||||
@@ -51,37 +64,137 @@ class huoshan implements DeployInterface
|
|||||||
if ($row['Status'] == 'success') {
|
if ($row['Status'] == 'success') {
|
||||||
$this->log('CDN域名 ' . $row['Domain'] . ' 部署证书成功!');
|
$this->log('CDN域名 ' . $row['Domain'] . ' 部署证书成功!');
|
||||||
} else {
|
} else {
|
||||||
$this->log('CDN域名 ' . $row['Domain'] . ' 部署证书失败:' . isset($row['ErrorMsg']) ? $row['ErrorMsg'] : '');
|
$this->log('CDN域名 ' . $row['Domain'] . ' 部署证书失败:' . (isset($row['ErrorMsg']) ? $row['ErrorMsg'] : ''));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function deploy_dcdn($cert_id, $config)
|
||||||
|
{
|
||||||
|
if (empty($config['domain'])) throw new Exception('绑定的域名不能为空');
|
||||||
|
$client = new Volcengine($this->AccessKeyId, $this->SecretAccessKey, 'open.volcengineapi.com', 'dcdn', '2021-04-01', 'cn-north-1', $this->proxy);
|
||||||
|
$param = [
|
||||||
|
'CertId' => $cert_id,
|
||||||
|
'DomainNames' => explode(',', $config['domain']),
|
||||||
|
];
|
||||||
|
$client->request('POST', 'CreateCertBind', $param);
|
||||||
|
$this->log('DCDN域名 ' . $config['domain'] . ' 部署证书成功!');
|
||||||
|
}
|
||||||
|
|
||||||
|
private function deploy_tos($cert_id, $config)
|
||||||
|
{
|
||||||
|
if (empty($config['bucket_domain'])) throw new Exception('Bucket域名不能为空');
|
||||||
|
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) {
|
||||||
|
$param = [
|
||||||
|
'CustomDomainRule' => [
|
||||||
|
'Domain' => $domain,
|
||||||
|
'CertId' => $cert_id,
|
||||||
|
]
|
||||||
|
];
|
||||||
|
$query = ['customdomain' => ''];
|
||||||
|
$client->tos_request('PUT', $param, $query);
|
||||||
|
$this->log('对象存储域名 ' . $config['domain'] . ' 部署证书成功!');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function deploy_live($fullchain, $privatekey, $config)
|
||||||
|
{
|
||||||
|
if (empty($config['domain'])) throw new Exception('绑定的域名不能为空');
|
||||||
|
|
||||||
|
$certInfo = openssl_x509_parse($fullchain, true);
|
||||||
|
if (!$certInfo) throw new Exception('证书解析失败');
|
||||||
|
$cert_name = str_replace('*.', '', $certInfo['subject']['CN']) . '-' . $certInfo['validFrom_time_t'];
|
||||||
|
|
||||||
|
$client = new Volcengine($this->AccessKeyId, $this->SecretAccessKey, 'live.volcengineapi.com', 'live', '2023-01-01', 'cn-north-1', $this->proxy);
|
||||||
|
$param = [
|
||||||
|
'CertName' => $cert_name,
|
||||||
|
'Rsa' => [
|
||||||
|
'Pubkey' => $fullchain,
|
||||||
|
'Prikey' => $privatekey,
|
||||||
|
],
|
||||||
|
'UseWay' => 'https',
|
||||||
|
];
|
||||||
|
$result = $client->request('POST', 'CreateCert', $param);
|
||||||
|
$this->log('上传证书成功 ChainID=' . $result['ChainID']);
|
||||||
|
|
||||||
|
foreach (explode(',', $config['domain']) as $domain) {
|
||||||
|
$param = [
|
||||||
|
'ChainID' => $result['ChainID'],
|
||||||
|
'Domain' => $domain,
|
||||||
|
'HTTPS' => true,
|
||||||
|
'HTTP2' => true,
|
||||||
|
];
|
||||||
|
$client->request('POST', 'BindCert', $param);
|
||||||
|
$this->log('视频直播域名 ' . $domain . ' 部署证书成功!');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function deploy_imagex($cert_id, $config)
|
||||||
|
{
|
||||||
|
if (empty($config['bucket_domain'])) throw new Exception('Bucket域名不能为空');
|
||||||
|
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) {
|
||||||
|
$param = [
|
||||||
|
[
|
||||||
|
'domain' => $domain,
|
||||||
|
'cert_id' => $cert_id,
|
||||||
|
]
|
||||||
|
];
|
||||||
|
$result = $client->request('POST', 'UpdateImageBatchDomainCert', $param);
|
||||||
|
if (isset($result['SuccessDomains']) && count($result['SuccessDomains']) > 0) {
|
||||||
|
$this->log('veImageX域名 ' . $domain . ' 部署证书成功!');
|
||||||
|
} elseif (isset($result['FailedDomains']) && count($result['FailedDomains']) > 0) {
|
||||||
|
$errmsg = $result['FailedDomains'][0]['ErrMsg'];
|
||||||
|
$this->log('veImageX域名 ' . $domain . ' 部署证书失败:' . $errmsg);
|
||||||
|
} else {
|
||||||
|
$this->log('veImageX域名 ' . $domain . ' 部署证书失败');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function deploy_clb($cert_id, $config)
|
||||||
|
{
|
||||||
|
if (empty($config['listener_id'])) throw new Exception('监听器ID不能为空');
|
||||||
|
$client = new Volcengine($this->AccessKeyId, $this->SecretAccessKey, 'open.volcengineapi.com', 'clb', '2020-04-01', 'cn-beijing', $this->proxy);
|
||||||
|
$param = [
|
||||||
|
'ListenerId' => $config['listener_id'],
|
||||||
|
'CertificateSource' => 'cert_center',
|
||||||
|
'CertCenterCertificateId' => $cert_id,
|
||||||
|
];
|
||||||
|
$client->request('GET', 'ModifyListenerAttributes', $param);
|
||||||
|
$this->log('CLB监听器 ' . $config['listener_id'] . ' 部署证书成功!');
|
||||||
|
}
|
||||||
|
|
||||||
private function get_cert_id($fullchain, $privatekey)
|
private function get_cert_id($fullchain, $privatekey)
|
||||||
{
|
{
|
||||||
$certInfo = openssl_x509_parse($fullchain, true);
|
$certInfo = openssl_x509_parse($fullchain, true);
|
||||||
if (!$certInfo) throw new Exception('证书解析失败');
|
if (!$certInfo) throw new Exception('证书解析失败');
|
||||||
$cert_name = str_replace('*.', '', $certInfo['subject']['CN']) . '-' . $certInfo['validFrom_time_t'];
|
$cert_name = str_replace('*.', '', $certInfo['subject']['CN']) . '-' . $certInfo['validFrom_time_t'];
|
||||||
|
|
||||||
$client = new Volcengine($this->AccessKeyId, $this->SecretAccessKey, 'cdn.volcengineapi.com', 'cdn', '2021-03-01', 'cn-north-1', $this->proxy);
|
$client = new Volcengine($this->AccessKeyId, $this->SecretAccessKey, 'open.volcengineapi.com', 'certificate_service', '2024-10-01', 'cn-beijing', $this->proxy);
|
||||||
$param = [
|
$param = [
|
||||||
'Source' => 'volc_cert_center',
|
'Tag' => $cert_name,
|
||||||
'Certificate' => $fullchain,
|
|
||||||
'PrivateKey' => $privatekey,
|
|
||||||
'Desc' => $cert_name,
|
|
||||||
'Repeatable' => false,
|
'Repeatable' => false,
|
||||||
|
'CertificateInfo' => [
|
||||||
|
'CertificateChain' => $fullchain,
|
||||||
|
'PrivateKey' => $privatekey,
|
||||||
|
],
|
||||||
];
|
];
|
||||||
try {
|
try {
|
||||||
$data = $client->request('POST', 'AddCertificate', $param);
|
$data = $client->request('POST', 'ImportCertificate', $param);
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
if (strpos($e->getMessage(), '证书已存在,ID为') !== false) {
|
|
||||||
$cert_id = trim(getSubstr($e->getMessage(), '证书已存在,ID为', '。'));
|
|
||||||
$this->log('证书已存在 CertId=' . $cert_id);
|
|
||||||
return $cert_id;
|
|
||||||
}
|
|
||||||
throw new Exception('上传证书失败:' . $e->getMessage());
|
throw new Exception('上传证书失败:' . $e->getMessage());
|
||||||
}
|
}
|
||||||
$this->log('上传证书成功 CertId=' . $data['CertId']);
|
if (!empty($data['InstanceId'])) {
|
||||||
return $data['CertId'];
|
$cert_id = $data['InstanceId'];
|
||||||
|
} else {
|
||||||
|
$cert_id = $data['RepeatId'];
|
||||||
|
}
|
||||||
|
$this->log('上传证书成功 CertId=' . $cert_id);
|
||||||
|
return $cert_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setLogger($func)
|
public function setLogger($func)
|
||||||
|
|||||||
+28
-26
@@ -40,33 +40,35 @@ class opanel implements DeployInterface
|
|||||||
|
|
||||||
$success = 0;
|
$success = 0;
|
||||||
$errmsg = null;
|
$errmsg = null;
|
||||||
foreach ($data['items'] as $row) {
|
if (!empty($data['items'])) {
|
||||||
if (empty($row['primaryDomain'])) continue;
|
foreach ($data['items'] as $row) {
|
||||||
$cert_domains = [];
|
if (empty($row['primaryDomain'])) continue;
|
||||||
$cert_domains[] = $row['primaryDomain'];
|
$cert_domains = [];
|
||||||
if(!empty($row['domains'])) $cert_domains += explode(',', $row['domains']);
|
$cert_domains[] = $row['primaryDomain'];
|
||||||
$flag = false;
|
if(!empty($row['domains'])) $cert_domains += explode(',', $row['domains']);
|
||||||
foreach ($cert_domains as $domain) {
|
$flag = false;
|
||||||
if (in_array($domain, $domains)) {
|
foreach ($cert_domains as $domain) {
|
||||||
$flag = true;
|
if (in_array($domain, $domains)) {
|
||||||
break;
|
$flag = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
if ($flag) {
|
||||||
if ($flag) {
|
$params = [
|
||||||
$params = [
|
'sslID' => $row['id'],
|
||||||
'sslID' => $row['id'],
|
'type' => 'paste',
|
||||||
'type' => 'paste',
|
'certificate' => $fullchain,
|
||||||
'certificate' => $fullchain,
|
'privateKey' => $privatekey,
|
||||||
'privateKey' => $privatekey,
|
'description' => '',
|
||||||
'description' => '',
|
];
|
||||||
];
|
try {
|
||||||
try {
|
$this->request('/api/v1/websites/ssl/upload', $params);
|
||||||
$this->request('/api/v1/websites/ssl/upload', $params);
|
$this->log("证书ID:{$row['id']}更新成功!");
|
||||||
$this->log("证书ID:{$row['id']}更新成功!");
|
$success++;
|
||||||
$success++;
|
} catch (Exception $e) {
|
||||||
} catch (Exception $e) {
|
$errmsg = $e->getMessage();
|
||||||
$errmsg = $e->getMessage();
|
$this->log("证书ID:{$row['id']}更新失败:" . $errmsg);
|
||||||
$this->log("证书ID:{$row['id']}更新失败:" . $errmsg);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,6 +42,8 @@ class qiniu implements DeployInterface
|
|||||||
$this->deploy_cdn($domain, $cert_id);
|
$this->deploy_cdn($domain, $cert_id);
|
||||||
} elseif ($config['product'] == 'oss') {
|
} elseif ($config['product'] == 'oss') {
|
||||||
$this->deploy_oss($domain, $cert_id);
|
$this->deploy_oss($domain, $cert_id);
|
||||||
|
} elseif ($config['product'] == 'pili') {
|
||||||
|
$this->deploy_pili($config['pili_hub'], $domain, $cert_name);
|
||||||
} else {
|
} else {
|
||||||
throw new Exception('未知的产品类型');
|
throw new Exception('未知的产品类型');
|
||||||
}
|
}
|
||||||
@@ -87,6 +89,15 @@ class qiniu implements DeployInterface
|
|||||||
$this->log('OSS域名 ' . $domain . ' 证书部署成功!');
|
$this->log('OSS域名 ' . $domain . ' 证书部署成功!');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function deploy_pili($hub, $domain, $cert_name)
|
||||||
|
{
|
||||||
|
$param = [
|
||||||
|
'CertName' => $cert_name,
|
||||||
|
];
|
||||||
|
$this->client->pili_request('POST', '/v2/hubs/'.$hub.'/domains/'.$domain.'/cert', null, $param);
|
||||||
|
$this->log('视频直播域名 ' . $domain . ' 证书部署成功!');
|
||||||
|
}
|
||||||
|
|
||||||
private function get_cert_id($fullchain, $privatekey, $common_name, $cert_name)
|
private function get_cert_id($fullchain, $privatekey, $common_name, $cert_name)
|
||||||
{
|
{
|
||||||
$cert_id = null;
|
$cert_id = null;
|
||||||
|
|||||||
@@ -68,7 +68,15 @@ class safeline implements DeployInterface
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($success == 0) {
|
if ($success == 0) {
|
||||||
throw new Exception($errmsg ? $errmsg : '没有要更新的证书');
|
$params = [
|
||||||
|
'manual' => [
|
||||||
|
'crt' => $fullchain,
|
||||||
|
'key' => $privatekey,
|
||||||
|
],
|
||||||
|
'type' => 2,
|
||||||
|
];
|
||||||
|
$this->request('/api/open/cert', $params);
|
||||||
|
$this->log("证书上传成功!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ class tencent implements DeployInterface
|
|||||||
if (empty($config['regionid'])) throw new Exception('所属地域ID不能为空');
|
if (empty($config['regionid'])) throw new Exception('所属地域ID不能为空');
|
||||||
if (empty($config['cos_bucket'])) throw new Exception('存储桶名称不能为空');
|
if (empty($config['cos_bucket'])) throw new Exception('存储桶名称不能为空');
|
||||||
if (empty($config['domain'])) throw new Exception('绑定的域名不能为空');
|
if (empty($config['domain'])) throw new Exception('绑定的域名不能为空');
|
||||||
$instance_id = $config['regionid'] . '#' . $config['cos_bucket'] . '#' . $config['domain'];
|
$instance_id = $config['regionid'] . '|' . $config['cos_bucket'] . '|' . $config['domain'];
|
||||||
$this->client = new TencentCloud($this->SecretId, $this->SecretKey, 'ssl.tencentcloudapi.com', 'ssl', '2019-12-05', $config['regionid'], $this->proxy);
|
$this->client = new TencentCloud($this->SecretId, $this->SecretKey, 'ssl.tencentcloudapi.com', 'ssl', '2019-12-05', $config['regionid'], $this->proxy);
|
||||||
} elseif ($config['product'] == 'tke') {
|
} elseif ($config['product'] == 'tke') {
|
||||||
if (empty($config['regionid'])) throw new Exception('所属地域ID不能为空');
|
if (empty($config['regionid'])) throw new Exception('所属地域ID不能为空');
|
||||||
@@ -52,6 +52,10 @@ class tencent implements DeployInterface
|
|||||||
if (empty($config['domain'])) throw new Exception('绑定的域名不能为空');
|
if (empty($config['domain'])) throw new Exception('绑定的域名不能为空');
|
||||||
$instance_id = $config['regionid'] . '|' . $config['lighthouse_id'] . '|' . $config['domain'];
|
$instance_id = $config['regionid'] . '|' . $config['lighthouse_id'] . '|' . $config['domain'];
|
||||||
$this->client = new TencentCloud($this->SecretId, $this->SecretKey, 'ssl.tencentcloudapi.com', 'ssl', '2019-12-05', $config['regionid'], $this->proxy);
|
$this->client = new TencentCloud($this->SecretId, $this->SecretKey, 'ssl.tencentcloudapi.com', 'ssl', '2019-12-05', $config['regionid'], $this->proxy);
|
||||||
|
} elseif ($config['product'] == 'ddos') {
|
||||||
|
if (empty($config['lighthouse_id'])) throw new Exception('实例ID不能为空');
|
||||||
|
if (empty($config['domain'])) throw new Exception('绑定的域名不能为空');
|
||||||
|
$instance_id = $config['lighthouse_id'] . '|' . $config['domain'] . '|443';
|
||||||
} elseif ($config['product'] == 'clb') {
|
} elseif ($config['product'] == 'clb') {
|
||||||
return $this->deploy_clb($cert_id, $config);
|
return $this->deploy_clb($cert_id, $config);
|
||||||
} elseif ($config['product'] == 'scf') {
|
} elseif ($config['product'] == 'scf') {
|
||||||
|
|||||||
@@ -79,6 +79,9 @@ class CheckUtils
|
|||||||
$target = gethostbyname($target);
|
$target = gethostbyname($target);
|
||||||
if (!$target) return ['status' => false, 'errmsg' => 'DNS resolve failed', 'usetime' => 0];
|
if (!$target) return ['status' => false, 'errmsg' => 'DNS resolve failed', 'usetime' => 0];
|
||||||
}
|
}
|
||||||
|
if (filter_var($target, FILTER_VALIDATE_IP) && strpos($target, ':') !== false) {
|
||||||
|
$target = '['.$target.']';
|
||||||
|
}
|
||||||
$starttime = getMillisecond();
|
$starttime = getMillisecond();
|
||||||
$fp = @fsockopen($target, $port, $errCode, $errStr, $timeout);
|
$fp = @fsockopen($target, $port, $errCode, $errStr, $timeout);
|
||||||
if ($fp) {
|
if ($fp) {
|
||||||
|
|||||||
@@ -229,7 +229,7 @@ class MsgNotice
|
|||||||
'content' => $content,
|
'content' => $content,
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
} elseif (strpos($url, 'open.feishu.cn')) {
|
} elseif (strpos($url, 'open.feishu.cn') || strpos($url, 'open.larksuite.com')) {
|
||||||
$content = str_replace(['\*', '**'], ['*', ''], strip_tags($content));
|
$content = str_replace(['\*', '**'], ['*', ''], strip_tags($content));
|
||||||
$post = [
|
$post = [
|
||||||
'msg_type' => 'text',
|
'msg_type' => 'text',
|
||||||
|
|||||||
@@ -29,7 +29,16 @@ pre.pre-log{height: 330px;overflow-y: auto;width: 100%;background-color: rgba(51
|
|||||||
</div>
|
</div>
|
||||||
<button type="submit" class="btn btn-primary"><i class="fa fa-search"></i> 搜索</button>
|
<button type="submit" class="btn btn-primary"><i class="fa fa-search"></i> 搜索</button>
|
||||||
<a href="javascript:searchClear()" class="btn btn-default" title="刷新订单列表"><i class="fa fa-refresh"></i> 刷新</a>
|
<a href="javascript:searchClear()" class="btn btn-default" title="刷新订单列表"><i class="fa fa-refresh"></i> 刷新</a>
|
||||||
<a href="/cert/order/add" class="btn btn-success"><i class="fa fa-plus"></i> 添加</a>
|
<div class="btn-group">
|
||||||
|
<a href="/cert/order/add" class="btn btn-success"><i class="fa fa-plus"></i> 添加</a>
|
||||||
|
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||||
|
<span class="caret"></span>
|
||||||
|
</button>
|
||||||
|
<ul class="dropdown-menu">
|
||||||
|
<li><a href="/cert/order/import">导入已有证书</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<table id="listTable">
|
<table id="listTable">
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
<style>
|
<style>
|
||||||
.copy-btn{color:#52c41a;cursor:pointer;margin-right: 5px;}
|
.copy-btn{color:#52c41a;cursor:pointer;margin-right: 5px;}
|
||||||
.copy-btn:hover{color:#85ef79;}
|
.copy-btn:hover{color:#85ef79;}
|
||||||
|
.btn-refresh{margin-left:5px;font-size:10px;background-color:#6896cf}
|
||||||
tbody tr>td:nth-child(3){word-break:break-all;max-width:180px;}
|
tbody tr>td:nth-child(3){word-break:break-all;max-width:180px;}
|
||||||
tbody tr>td:nth-child(4){word-break:break-all;max-width:260px;}
|
tbody tr>td:nth-child(4){word-break:break-all;max-width:260px;}
|
||||||
</style>
|
</style>
|
||||||
@@ -120,7 +121,7 @@ $(document).ready(function(){
|
|||||||
} else {
|
} else {
|
||||||
html += '<span class="label label-warning">未验证</span>';
|
html += '<span class="label label-warning">未验证</span>';
|
||||||
}
|
}
|
||||||
html += ' <a href="javascript:checkItem('+row.id+')" title="立即验证" class="btn btn-primary btn-xs"><i class="fa fa-refresh"></i></a>';
|
html += '<a href="javascript:checkItem('+row.id+')" title="立即验证" class="btn btn-primary btn-xs btn-refresh"><i class="fa fa-refresh"></i></a>';
|
||||||
return html;
|
return html;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -0,0 +1,167 @@
|
|||||||
|
{extend name="common/layout" /}
|
||||||
|
{block name="title"}导入已有证书{/block}
|
||||||
|
{block name="main"}
|
||||||
|
<style>
|
||||||
|
.tips{color: #f6a838; padding-left: 5px;}
|
||||||
|
.control-label[is-required]:before {
|
||||||
|
content: "*";
|
||||||
|
color: #f56c6c;
|
||||||
|
margin-right: 4px;
|
||||||
|
}
|
||||||
|
.input-group-addon{padding: 6px 6px;}
|
||||||
|
</style>
|
||||||
|
<div class="row" id="app">
|
||||||
|
<div class="col-xs-12 center-block" style="float: none;">
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading"><h3 class="panel-title"><a href="/cert/certorder" class="btn btn-sm btn-default pull-right" style="margin-top:-6px"><i class="fa fa-reply fa-fw"></i> 返回</a>导入已有证书</h3></div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<form onsubmit="return false" method="post" class="form-horizontal" role="form" id="taskform">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="col-sm-3 control-label no-padding-right" is-required>证书内容</label>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<div class="input-group">
|
||||||
|
<textarea name="fullchain" v-model="set.fullchain" class="form-control" rows="5" placeholder="输入PEM格式证书链" required></textarea>
|
||||||
|
<a class="btn btn-default input-group-addon" @click="upload('fullchain')" title="上传证书文件"><i class="fa fa-upload"></i></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="col-sm-3 control-label no-padding-right" is-required>私钥内容</label>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<div class="input-group">
|
||||||
|
<textarea name="privatekey" v-model="set.privatekey" class="form-control" rows="5" placeholder="输入PEM格式私钥" required></textarea>
|
||||||
|
<a class="btn btn-default input-group-addon" @click="upload('privatekey')" title="上传私钥文件"><i class="fa fa-upload"></i></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="col-sm-3 col-xs-12 control-label no-padding-right" is-required>证书续期账户</label>
|
||||||
|
<div class="col-sm-6"><select name="aid" v-model="set.aid" class="form-control" required>
|
||||||
|
<option value="">--选择证书账户--</option>
|
||||||
|
{foreach $accounts as $k=>$v}
|
||||||
|
<option value="{$k}" data-type="{$v.type}">{$v.name}</option>
|
||||||
|
{/foreach}
|
||||||
|
</select></div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="col-sm-3 control-label no-padding-right" is-required>签名算法</label>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<label class="radio-inline" v-for="item in keytypeList">
|
||||||
|
<input type="radio" name="keytype" :value="item" v-model="set.keytype"> {{item}}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="col-sm-3 control-label no-padding-right" is-required>密钥长度</label>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<label class="radio-inline" v-for="item in keysizeList">
|
||||||
|
<input type="radio" name="keysize" :value="item.value" v-model="set.keysize"> {{item.label}}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-sm-offset-3 col-sm-6"><button type="button" class="btn btn-primary" @click="submit">提交</button></div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/block}
|
||||||
|
{block name="script"}
|
||||||
|
<script src="{$cdnpublic}vue/2.6.14/vue.min.js"></script>
|
||||||
|
<script src="{$cdnpublic}layer/3.1.1/layer.js"></script>
|
||||||
|
<script src="/static/js/bootstrapValidator.min.js"></script>
|
||||||
|
<script>
|
||||||
|
new Vue({
|
||||||
|
el: '#app',
|
||||||
|
data: {
|
||||||
|
type: '',
|
||||||
|
set: {
|
||||||
|
fullchain: '',
|
||||||
|
privatekey: '',
|
||||||
|
aid: '',
|
||||||
|
keytype: '',
|
||||||
|
keysize: '',
|
||||||
|
},
|
||||||
|
keytypeList: [
|
||||||
|
'RSA',
|
||||||
|
'ECC'
|
||||||
|
],
|
||||||
|
keysizeMap: [
|
||||||
|
{label:'2048 bit',value:'2048',type:'RSA'},
|
||||||
|
{label:'3072 bit',value:'3072',type:'RSA'},
|
||||||
|
{label:'P-256',value:'256',type:'ECC'},
|
||||||
|
{label:'P-384',value:'384',type:'ECC'},
|
||||||
|
],
|
||||||
|
keysizeList: [],
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
'set.aid': function(val){
|
||||||
|
this.type = $('option:selected', 'select[name=aid]').data('type');
|
||||||
|
},
|
||||||
|
'set.keytype': function(val){
|
||||||
|
this.keysizeList = this.keysizeMap.filter((item) => {
|
||||||
|
return item.type == val;
|
||||||
|
})
|
||||||
|
if(!this.keysizeList.filter((item) => {return item.value == this.set.keysize}).length)
|
||||||
|
this.set.keysize = this.keysizeList[0].value;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.set.keytype = 'RSA';
|
||||||
|
$("#taskform").bootstrapValidator({
|
||||||
|
live: 'submitted',
|
||||||
|
});
|
||||||
|
$('[data-toggle="tooltip"]').tooltip();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
submit(){
|
||||||
|
var that=this;
|
||||||
|
$("#taskform").data("bootstrapValidator").validate();
|
||||||
|
if(!$("#taskform").data("bootstrapValidator").isValid()){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
var ii = layer.load(2, {shade:[0.1,'#fff']});
|
||||||
|
$.ajax({
|
||||||
|
type: "POST",
|
||||||
|
url: "",
|
||||||
|
data: this.set,
|
||||||
|
dataType: 'json',
|
||||||
|
success: function(data) {
|
||||||
|
layer.close(ii);
|
||||||
|
if(data.code == 0){
|
||||||
|
layer.alert(data.msg, {icon: 1}, function(){
|
||||||
|
if(document.referrer.indexOf('/cert/certorder?') > 0)
|
||||||
|
window.location.href = document.referrer;
|
||||||
|
else
|
||||||
|
window.location.href = '/cert/certorder';
|
||||||
|
});
|
||||||
|
}else{
|
||||||
|
layer.alert(data.msg, {icon: 2});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: function(data){
|
||||||
|
layer.close(ii);
|
||||||
|
layer.msg('服务器错误');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
upload(name){
|
||||||
|
//读取上传文件并填充到表单
|
||||||
|
var file = document.createElement('input');
|
||||||
|
file.type = 'file';
|
||||||
|
file.accept = '.pem,.crt,.key';
|
||||||
|
file.style.display = 'none';
|
||||||
|
file.onchange = function(){
|
||||||
|
var reader = new FileReader();
|
||||||
|
reader.onload = function(e){
|
||||||
|
this.set[name] = e.target.result;
|
||||||
|
}.bind(this);
|
||||||
|
reader.readAsText(file.files[0]);
|
||||||
|
}.bind(this);
|
||||||
|
document.body.appendChild(file);
|
||||||
|
file.click();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
{/block}
|
||||||
@@ -136,7 +136,7 @@
|
|||||||
<li><a href="/optimizeip/opiplist"><i class="fa fa-circle-o"></i> 任务管理</a></li>
|
<li><a href="/optimizeip/opiplist"><i class="fa fa-circle-o"></i> 任务管理</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li class="treeview {:checkIfActive('certaccount,account_form,certorder,order_form,deployaccount,deploytask,deploy_form,certset,cname')}">
|
<li class="treeview {:checkIfActive('certaccount,account_form,certorder,order_form,order_import,deployaccount,deploytask,deploy_form,certset,cname')}">
|
||||||
<a href="javascript:;">
|
<a href="javascript:;">
|
||||||
<i class="fa fa-expeditedssl fa-fw"></i>
|
<i class="fa fa-expeditedssl fa-fw"></i>
|
||||||
<span>SSL证书</span>
|
<span>SSL证书</span>
|
||||||
|
|||||||
+1
-1
@@ -31,7 +31,7 @@ return [
|
|||||||
'show_error_msg' => true,
|
'show_error_msg' => true,
|
||||||
'exception_tmpl' => \think\facade\App::getAppPath() . 'view/exception.tpl',
|
'exception_tmpl' => \think\facade\App::getAppPath() . 'view/exception.tpl',
|
||||||
|
|
||||||
'version' => '1025',
|
'version' => '1027',
|
||||||
|
|
||||||
'dbversion' => '1023'
|
'dbversion' => '1023'
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -93,6 +93,7 @@ Route::group(function () {
|
|||||||
Route::post('/cert/order/data', 'cert/order_data');
|
Route::post('/cert/order/data', 'cert/order_data');
|
||||||
Route::post('/cert/order/process', 'cert/order_process');
|
Route::post('/cert/order/process', 'cert/order_process');
|
||||||
Route::post('/cert/order/:action', 'cert/order_op');
|
Route::post('/cert/order/:action', 'cert/order_op');
|
||||||
|
Route::get('/cert/order/import', 'cert/order_import');
|
||||||
Route::get('/cert/order/:action', 'cert/order_form');
|
Route::get('/cert/order/:action', 'cert/order_form');
|
||||||
|
|
||||||
Route::get('/cert/deploytask', 'cert/deploytask');
|
Route::get('/cert/deploytask', 'cert/deploytask');
|
||||||
|
|||||||
Reference in New Issue
Block a user