1
0
mirror of https://github.com/1Panel-dev/1Panel.git synced 2025-03-13 17:24:44 +08:00

feat: 增加手动域名解析

This commit is contained in:
zhengkunwang223 2022-11-25 00:08:44 +08:00 committed by zhengkunwang223
parent 3ccac92df6
commit bd082d4e08
8 changed files with 168 additions and 74 deletions

View File

@ -38,9 +38,10 @@ type WebsiteDNSReq struct {
}
type WebsiteDNSRes struct {
Key string `json:"resolve"`
Value string `json:"value"`
Type string `json:"type"`
Key string `json:"resolve"`
Value string `json:"value"`
Domain string `json:"domain"`
Err string `json:"err"`
}
type WebsiteSSLRenew struct {

View File

@ -168,24 +168,29 @@ func (w WebSiteSSLService) Renew(sslId uint) error {
return websiteSSLRepo.Save(websiteSSL)
}
func (w WebSiteSSLService) GetDNSResolve(req dto.WebsiteDNSReq) (dto.WebsiteDNSRes, error) {
func (w WebSiteSSLService) GetDNSResolve(req dto.WebsiteDNSReq) ([]dto.WebsiteDNSRes, error) {
acmeAccount, err := websiteAcmeRepo.GetFirst(commonRepo.WithByID(req.AcmeAccountID))
if err != nil {
return dto.WebsiteDNSRes{}, err
return nil, err
}
client, err := ssl.NewPrivateKeyClient(acmeAccount.Email, acmeAccount.PrivateKey)
if err != nil {
return dto.WebsiteDNSRes{}, err
return nil, err
}
re, err := client.UseManualDns(req.Domains)
resolves, err := client.GetDNSResolve(req.Domains)
if err != nil {
return dto.WebsiteDNSRes{}, err
return nil, err
}
var res []dto.WebsiteDNSRes
for k, v := range resolves {
res = append(res, dto.WebsiteDNSRes{
Domain: k,
Key: v.Key,
Value: v.Value,
Err: v.Err,
})
}
var res dto.WebsiteDNSRes
res.Key = re.Key
res.Value = re.Value
res.Type = "TXT"
return res, nil
}

View File

@ -1,27 +1,27 @@
-----BEGIN privateKey-----
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
-----END privateKey-----

View File

@ -3,6 +3,8 @@ package ssl
import (
"crypto"
"encoding/json"
"github.com/go-acme/lego/v4/acme"
"github.com/go-acme/lego/v4/acme/api"
"github.com/go-acme/lego/v4/certificate"
"github.com/go-acme/lego/v4/challenge"
"github.com/go-acme/lego/v4/challenge/dns01"
@ -166,6 +168,7 @@ func (c *AcmeClient) RenewSSL(certUrl string) (certificate.Resource, error) {
type Resolve struct {
Key string
Value string
Err string
}
type manualDnsProvider struct {
@ -173,11 +176,6 @@ type manualDnsProvider struct {
}
func (p *manualDnsProvider) Present(domain, token, keyAuth string) error {
fqdn, value := dns01.GetRecord(domain, keyAuth)
p.Resolve = &Resolve{
Key: fqdn,
Value: value,
}
return nil
}
@ -185,6 +183,60 @@ func (p *manualDnsProvider) CleanUp(domain, token, keyAuth string) error {
return nil
}
func (c *AcmeClient) GetDNSResolve() {
func (c *AcmeClient) GetDNSResolve(domains []string) (map[string]Resolve, error) {
core, err := api.New(c.Config.HTTPClient, c.Config.UserAgent, c.Config.CADirURL, c.User.Registration.URI, c.User.Key)
if err != nil {
panic(err)
}
order, err := core.Orders.New(domains)
if err != nil {
panic(err)
}
resolves := make(map[string]Resolve)
resc, errc := make(chan acme.Authorization), make(chan domainError)
for _, authzURL := range order.Authorizations {
go func(authzURL string) {
authz, err := core.Authorizations.Get(authzURL)
if err != nil {
errc <- domainError{Domain: authz.Identifier.Value, Error: err}
return
}
resc <- authz
}(authzURL)
}
var responses []acme.Authorization
for i := 0; i < len(order.Authorizations); i++ {
select {
case res := <-resc:
responses = append(responses, res)
case err := <-errc:
resolves[err.Domain] = Resolve{Err: err.Error.Error()}
}
}
close(resc)
close(errc)
for _, auth := range responses {
domain := challenge.GetTargetedDomain(auth)
chlng, err := challenge.FindChallenge(challenge.DNS01, auth)
if err != nil {
resolves[domain] = Resolve{Err: err.Error()}
continue
}
keyAuth, err := core.GetKeyAuthorization(chlng.Token)
if err != nil {
resolves[domain] = Resolve{Err: err.Error()}
continue
}
fqdn, value := dns01.GetRecord(domain, keyAuth)
resolves[domain] = Resolve{
Key: fqdn,
Value: value,
}
}
return resolves, nil
}

View File

@ -0,0 +1,29 @@
package ssl
import (
"bytes"
"fmt"
"sort"
)
type obtainError map[string]error
func (e obtainError) Error() string {
buffer := bytes.NewBufferString("error: one or more domains had a problem:\n")
var domains []string
for domain := range e {
domains = append(domains, domain)
}
sort.Strings(domains)
for _, domain := range domains {
buffer.WriteString(fmt.Sprintf("[%s] %s\n", domain, e[domain]))
}
return buffer.String()
}
type domainError struct {
Domain string
Error error
}

View File

@ -160,9 +160,10 @@ export namespace WebSite {
}
export interface DNSResolve {
key: string;
resolve: string;
value: string;
type: string;
domain: string;
err: string;
}
export interface SSLReq {

View File

@ -120,7 +120,7 @@ export const RenewSSL = (req: WebSite.SSLRenew) => {
};
export const GetDnsResolve = (req: WebSite.DNSResolveReq) => {
return http.post<WebSite.DNSResolve>(`/websites/ssl/resolve`, req);
return http.post<WebSite.DNSResolve[]>(`/websites/ssl/resolve`, req);
};
export const GetHTTPSConfig = (id: number) => {

View File

@ -1,10 +1,10 @@
<template>
<el-dialog v-model="open" :title="$t('commons.button.create')" width="30%" :before-close="handleClose">
<el-dialog v-model="open" :title="$t('commons.button.create')" width="60%" :before-close="handleClose">
<el-form
ref="sslForm"
label-position="right"
:model="ssl"
label-width="125px"
label-width="100px"
:rules="rules"
v-loading="loading"
>
@ -41,18 +41,21 @@
></el-option>
</el-select>
</el-form-item>
<!-- <el-form-item :label="$t('website.domain')" prop="domains">
<el-checkbox-group v-model="ssl.domains">
<el-checkbox v-for="domain in domains" :key="domain.domain" :label="domain.domain"></el-checkbox>
</el-checkbox-group>
</el-form-item> -->
<!-- <el-form-item>
<div>
<span>解析域名: {{ dnsResolve.key }}</span>
<span>记录值: {{ dnsResolve.value }}</span>
<span>类型: {{ dnsResolve.type }}</span>
<el-form-item v-if="dnsResolve.length > 0">
<div v-for="(re, index) in dnsResolve" :key="index">
<el-descriptions direction="vertical" :column="4" border>
<el-descriptions-item label="域名">{{ re.domain }}</el-descriptions-item>
<div v-if="re.err != ''">
<el-descriptions-item label="错误">{{ re.err }}</el-descriptions-item>
</div>
<div v-else>
<el-descriptions-item label="解析域名">{{ re.resolve }}</el-descriptions-item>
<el-descriptions-item label="记录值">{{ re.value }}</el-descriptions-item>
<el-descriptions-item label="类型">TXT</el-descriptions-item>
</div>
</el-descriptions>
</div>
</el-form-item> -->
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
@ -67,7 +70,7 @@
<script lang="ts" setup>
import { WebSite } from '@/api/interface/website';
import { CreateSSL, SearchAcmeAccount, SearchDnsAccount } from '@/api/modules/website';
import { CreateSSL, GetDnsResolve, SearchAcmeAccount, SearchDnsAccount } from '@/api/modules/website';
import { Rules } from '@/global/form-rules';
import i18n from '@/lang';
import { ElMessage, FormInstance } from 'element-plus';
@ -112,11 +115,7 @@ let ssl = ref({
acmeAccountId: 0,
dnsAccountId: 0,
});
// let dnsResolve = ref<WebSite.DNSResolve>({
// key: '',
// value: '',
// type: '',
// });
let dnsResolve = ref<WebSite.DNSResolve[]>([]);
let hasResolve = ref(false);
const em = defineEmits(['close']);
@ -166,14 +165,16 @@ const getDnsAccounts = async () => {
// domains.value = (await GetWebsite(id)).data.domains || [];
// };
// const getDnsResolve = async (acmeAccountId: number, domains: string[]) => {
// hasResolve.value = false;
// const res = await GetDnsResolve({ acmeAccountId: acmeAccountId, domains: domains });
// if (res.data) {
// dnsResolve.value = res.data;
// hasResolve.value = true;
// }
// };
const getDnsResolve = async (acmeAccountId: number, domains: string[]) => {
hasResolve.value = false;
loading.value = true;
const res = await GetDnsResolve({ acmeAccountId: acmeAccountId, domains: domains });
if (res.data) {
dnsResolve.value = res.data;
hasResolve.value = true;
}
loading.value = false;
};
const submit = async (formEl: FormInstance | undefined) => {
if (!formEl) return;
@ -192,7 +193,12 @@ const submit = async (formEl: FormInstance | undefined) => {
loading.value = false;
});
} else {
// getDnsResolve(ssl.value.acmeAccountId, ssl.value.domains);
let domains = [ssl.value.primaryDomain];
if (ssl.value.otherDomains != '') {
let otherDomains = ssl.value.otherDomains.split('\n');
domains = domains.concat(otherDomains);
}
getDnsResolve(ssl.value.acmeAccountId, domains);
}
});
};