WIP Can import domain through dnscontrol
This commit is contained in:
parent
af5c500215
commit
4a431565df
|
@ -101,7 +101,7 @@ func addDomain(c *gin.Context) {
|
||||||
|
|
||||||
user := c.MustGet("LoggedUser").(*happydns.User)
|
user := c.MustGet("LoggedUser").(*happydns.User)
|
||||||
|
|
||||||
source, err := storage.MainStore.GetSource(user, uz.IdSource)
|
provider, err := storage.MainStore.GetProvider(user, uz.IdProvider)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": fmt.Sprintf("Unable to find the provider.")})
|
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": fmt.Sprintf("Unable to find the provider.")})
|
||||||
return
|
return
|
||||||
|
@ -111,7 +111,7 @@ func addDomain(c *gin.Context) {
|
||||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": "This domain has already been imported."})
|
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": "This domain has already been imported."})
|
||||||
return
|
return
|
||||||
|
|
||||||
} else if err := source.DomainExists(uz.DomainName); err != nil {
|
} else if err := provider.DomainExists(uz.DomainName); err != nil {
|
||||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": err.Error()})
|
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": err.Error()})
|
||||||
return
|
return
|
||||||
} else if err := storage.MainStore.CreateDomain(user, &uz); err != nil {
|
} else if err := storage.MainStore.CreateDomain(user, &uz); err != nil {
|
||||||
|
@ -144,7 +144,7 @@ func DomainHandler(c *gin.Context) {
|
||||||
} else if src, exists := c.Get("sourcemeta"); exists {
|
} else if src, exists := c.Get("sourcemeta"); exists {
|
||||||
source = src.(*happydns.SourceMeta)
|
source = src.(*happydns.SourceMeta)
|
||||||
}
|
}
|
||||||
if source != nil && source.Id != domain.IdSource {
|
if source != nil && source.Id != domain.IdProvider {
|
||||||
c.AbortWithStatusJSON(http.StatusNotFound, gin.H{"errmsg": "Domain not found (not child of source)"})
|
c.AbortWithStatusJSON(http.StatusNotFound, gin.H{"errmsg": "Domain not found (not child of source)"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -167,7 +167,7 @@ func GetDomain(c *gin.Context) {
|
||||||
ret := &apiDomain{
|
ret := &apiDomain{
|
||||||
Id: domain.Id,
|
Id: domain.Id,
|
||||||
IdUser: domain.IdUser,
|
IdUser: domain.IdUser,
|
||||||
IdSource: domain.IdSource,
|
IdSource: domain.IdProvider,
|
||||||
DomainName: domain.DomainName,
|
DomainName: domain.DomainName,
|
||||||
ZoneHistory: []happydns.ZoneMeta{},
|
ZoneHistory: []happydns.ZoneMeta{},
|
||||||
}
|
}
|
||||||
|
@ -188,7 +188,7 @@ func GetDomain(c *gin.Context) {
|
||||||
func delDomain(c *gin.Context) {
|
func delDomain(c *gin.Context) {
|
||||||
if err := storage.MainStore.DeleteDomain(c.MustGet("domain").(*happydns.Domain)); err != nil {
|
if err := storage.MainStore.DeleteDomain(c.MustGet("domain").(*happydns.Domain)); err != nil {
|
||||||
log.Printf("%s was unable to DeleteDomain: %w", c.ClientIP(), err)
|
log.Printf("%s was unable to DeleteDomain: %w", c.ClientIP(), err)
|
||||||
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": fmt.Sprintf("Unable to delete your domain: %w", err)})
|
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": fmt.Sprintf("Unable to delete your domain: %s", err.Error())})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,9 +199,9 @@ func axfrDomain(c *gin.Context) {
|
||||||
user := c.MustGet("LoggedUser").(*happydns.User)
|
user := c.MustGet("LoggedUser").(*happydns.User)
|
||||||
domain := c.MustGet("domain").(*happydns.Domain)
|
domain := c.MustGet("domain").(*happydns.Domain)
|
||||||
|
|
||||||
source, err := storage.MainStore.GetSource(user, domain.IdSource)
|
source, err := storage.MainStore.GetSource(user, domain.IdProvider)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.AbortWithStatusJSON(http.StatusNotFound, gin.H{"errmsg": fmt.Sprintf("Unable to find your provider: %w", err)})
|
c.AbortWithStatusJSON(http.StatusNotFound, gin.H{"errmsg": fmt.Sprintf("Unable to find your provider: %s", err.Error())})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,7 +246,7 @@ func prepareRR(next func(c *gin.Context, source *happydns.SourceCombined, domain
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
source, err := storage.MainStore.GetSource(user, domain.IdSource)
|
source, err := storage.MainStore.GetSource(user, domain.IdProvider)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.AbortWithStatusJSON(http.StatusNotFound, gin.H{"errmsg": fmt.Sprintf("Unable to find the required source: %w", err)})
|
c.AbortWithStatusJSON(http.StatusNotFound, gin.H{"errmsg": fmt.Sprintf("Unable to find the required source: %w", err)})
|
||||||
return
|
return
|
||||||
|
|
|
@ -100,7 +100,7 @@ func DecodeProvider(c *gin.Context) (*happydns.ProviderCombined, int, error) {
|
||||||
return nil, http.StatusBadRequest, err
|
return nil, http.StatusBadRequest, err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = src.NewDNSServiceProvider()
|
err = src.Validate()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, http.StatusBadRequest, err
|
return nil, http.StatusBadRequest, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,7 +67,7 @@ func analyzeDomain(c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
source, err := storage.MainStore.GetSource(user, domain.IdSource)
|
source, err := storage.MainStore.GetSource(user, domain.IdProvider)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": fmt.Sprintf("Unable to get the related source: %w", err)})
|
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": fmt.Sprintf("Unable to get the related source: %w", err)})
|
||||||
return
|
return
|
||||||
|
|
|
@ -233,7 +233,7 @@ func deleteSource(c *gin.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, domain := range domains {
|
for _, domain := range domains {
|
||||||
if domain.IdSource == sourcemeta.Id {
|
if domain.IdProvider == sourcemeta.Id {
|
||||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": "You cannot delete this source because there is still some domains associated with it."})
|
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": "You cannot delete this source because there is still some domains associated with it."})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
10
api/zones.go
10
api/zones.go
|
@ -192,13 +192,13 @@ func importZone(c *gin.Context) {
|
||||||
user := c.MustGet("LoggedUser").(*happydns.User)
|
user := c.MustGet("LoggedUser").(*happydns.User)
|
||||||
domain := c.MustGet("domain").(*happydns.Domain)
|
domain := c.MustGet("domain").(*happydns.Domain)
|
||||||
|
|
||||||
source, err := storage.MainStore.GetSource(user, domain.IdSource)
|
provider, err := storage.MainStore.GetProvider(user, domain.IdProvider)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.AbortWithStatusJSON(http.StatusNotFound, gin.H{"errmsg": fmt.Sprintf("Unable to find your provider: %w", err)})
|
c.AbortWithStatusJSON(http.StatusNotFound, gin.H{"errmsg": fmt.Sprintf("Unable to find your provider: %w", err)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
zone, err := source.ImportZone(domain)
|
zone, err := provider.ImportZone(domain)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": err.Error()})
|
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": err.Error()})
|
||||||
return
|
return
|
||||||
|
@ -251,9 +251,9 @@ func importZone(c *gin.Context) {
|
||||||
|
|
||||||
func loadRecordsFromZoneId(user *happydns.User, domain *happydns.Domain, id string) ([]dns.RR, int, error) {
|
func loadRecordsFromZoneId(user *happydns.User, domain *happydns.Domain, id string) ([]dns.RR, int, error) {
|
||||||
if id == "@" {
|
if id == "@" {
|
||||||
source, err := storage.MainStore.GetSource(user, domain.IdSource)
|
source, err := storage.MainStore.GetSource(user, domain.IdProvider)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, http.StatusNotFound, fmt.Errorf("Unable to find the given source: %q for %q", domain.IdSource, domain.DomainName)
|
return nil, http.StatusNotFound, fmt.Errorf("Unable to find the given source: %q for %q", domain.IdProvider, domain.DomainName)
|
||||||
}
|
}
|
||||||
|
|
||||||
rrs, err := source.ImportZone(domain)
|
rrs, err := source.ImportZone(domain)
|
||||||
|
@ -309,7 +309,7 @@ func applyZone(c *gin.Context) {
|
||||||
domain := c.MustGet("domain").(*happydns.Domain)
|
domain := c.MustGet("domain").(*happydns.Domain)
|
||||||
zone := c.MustGet("zone").(*happydns.Zone)
|
zone := c.MustGet("zone").(*happydns.Zone)
|
||||||
|
|
||||||
source, err := storage.MainStore.GetSource(user, domain.IdSource)
|
source, err := storage.MainStore.GetSource(user, domain.IdProvider)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.AbortWithStatusJSON(http.StatusNotFound, gin.H{"errmsg": fmt.Sprintf("Unable to find your provider: %w", err)})
|
c.AbortWithStatusJSON(http.StatusNotFound, gin.H{"errmsg": fmt.Sprintf("Unable to find your provider: %w", err)})
|
||||||
return
|
return
|
||||||
|
|
|
@ -43,9 +43,9 @@ type Domain struct {
|
||||||
// IdUser is the identifier of the Domain's Owner.
|
// IdUser is the identifier of the Domain's Owner.
|
||||||
IdUser int64 `json:"id_owner"`
|
IdUser int64 `json:"id_owner"`
|
||||||
|
|
||||||
// IsSource is the identifier of the Source used to access and edit the
|
// IsProvider is the identifier of the Provider used to access and edit the
|
||||||
// Domain.
|
// Domain.
|
||||||
IdSource int64 `json:"id_source"`
|
IdProvider int64 `json:"id_provider"`
|
||||||
|
|
||||||
// DomainName is the FQDN of the managed Domain.
|
// DomainName is the FQDN of the managed Domain.
|
||||||
DomainName string `json:"domain"`
|
DomainName string `json:"domain"`
|
||||||
|
@ -70,10 +70,10 @@ func (d *Domain) HasZone(zoneId int64) (found bool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDomain fills a new Domain structure.
|
// NewDomain fills a new Domain structure.
|
||||||
func NewDomain(u *User, st *SourceMeta, dn string) (d *Domain) {
|
func NewDomain(u *User, st *ProviderMeta, dn string) (d *Domain) {
|
||||||
d = &Domain{
|
d = &Domain{
|
||||||
IdUser: u.Id,
|
IdUser: u.Id,
|
||||||
IdSource: st.Id,
|
IdProvider: st.Id,
|
||||||
DomainName: dns.Fqdn(dn),
|
DomainName: dns.Fqdn(dn),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,11 @@
|
||||||
package happydns
|
package happydns
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/StackExchange/dnscontrol/v3/providers"
|
"github.com/StackExchange/dnscontrol/v3/providers"
|
||||||
|
"github.com/miekg/dns"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Provider is where Domains and Zones can be managed.
|
// Provider is where Domains and Zones can be managed.
|
||||||
|
@ -60,3 +64,54 @@ type ProviderCombined struct {
|
||||||
Provider
|
Provider
|
||||||
ProviderMeta
|
ProviderMeta
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *ProviderCombined) Validate() (err error) {
|
||||||
|
_, err = p.NewDNSServiceProvider()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *ProviderCombined) DomainExists(fqdn string) (err error) {
|
||||||
|
var s providers.DNSServiceProvider
|
||||||
|
s, err = p.NewDNSServiceProvider()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
if a := recover(); a != nil {
|
||||||
|
err = fmt.Errorf("%s", a)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
_, err = s.GetZoneRecords(strings.TrimSuffix(fqdn, "."))
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *ProviderCombined) ImportZone(dn *Domain) (rrs []dns.RR, err error) {
|
||||||
|
var s providers.DNSServiceProvider
|
||||||
|
s, err = p.NewDNSServiceProvider()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
if a := recover(); a != nil {
|
||||||
|
err = fmt.Errorf("%s", a)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
rcs, err := s.GetZoneRecords(strings.TrimSuffix(dn.DomainName, "."))
|
||||||
|
if err != nil {
|
||||||
|
return rrs, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, rc := range rcs {
|
||||||
|
rrs = append(rrs, rc.ToRR())
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
|
@ -193,11 +193,11 @@ func (s *LevelDBStorage) TidyDomains() error {
|
||||||
log.Printf("Deleting orphan domain (user %d not found): %v\n", domain.IdUser, domain)
|
log.Printf("Deleting orphan domain (user %d not found): %v\n", domain.IdUser, domain)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = s.GetSource(u, domain.IdSource)
|
_, err = s.GetSource(u, domain.IdProvider)
|
||||||
if err == leveldb.ErrNotFound {
|
if err == leveldb.ErrNotFound {
|
||||||
// Drop domain of unexistant source
|
// Drop domain of unexistant source
|
||||||
err = tx.Delete(iter.Key(), nil)
|
err = tx.Delete(iter.Key(), nil)
|
||||||
log.Printf("Deleting orphan domain (source %d not found): %v\n", domain.IdSource, domain)
|
log.Printf("Deleting orphan domain (source %d not found): %v\n", domain.IdProvider, domain)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Drop unreadable domains
|
// Drop unreadable domains
|
||||||
|
|
|
@ -64,7 +64,7 @@
|
||||||
<template v-else-if="listImportableDomains.length === 0" #no-domain>
|
<template v-else-if="listImportableDomains.length === 0" #no-domain>
|
||||||
<b-list-group-item class="text-center">
|
<b-list-group-item class="text-center">
|
||||||
<i18n path="errors.domain-all-imported">
|
<i18n path="errors.domain-all-imported">
|
||||||
{{ sourceSpecs_getAll[provider._srctype].name }}
|
{{ providerSpecs_getAll[provider._srctype].name }}
|
||||||
</i18n>
|
</i18n>
|
||||||
</b-list-group-item>
|
</b-list-group-item>
|
||||||
</template>
|
</template>
|
||||||
|
@ -136,10 +136,10 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
noDomainsList () {
|
noDomainsList () {
|
||||||
return !this.sourceSpecs_getAll[this.provider._srctype] || !this.sourceSpecs_getAll[this.provider._srctype].capabilities || this.sourceSpecs_getAll[this.provider._srctype].capabilities.indexOf('ListDomains') === -1
|
return !this.providerSpecs_getAll[this.provider._srctype] || !this.providerSpecs_getAll[this.provider._srctype].capabilities || this.providerSpecs_getAll[this.provider._srctype].capabilities.indexOf('ListDomains') === -1
|
||||||
},
|
},
|
||||||
|
|
||||||
...mapGetters('sourceSpecs', ['sourceSpecs_getAll']),
|
...mapGetters('providerSpecs', ['providerSpecs_getAll']),
|
||||||
...mapGetters('domains', ['domains_getAll'])
|
...mapGetters('domains', ['domains_getAll'])
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -152,7 +152,7 @@ export default {
|
||||||
this.getImportableDomains()
|
this.getImportableDomains()
|
||||||
},
|
},
|
||||||
|
|
||||||
sourceSpecs_getAll: function (ss) {
|
providerSpecs_getAll: function (ss) {
|
||||||
if (ss) {
|
if (ss) {
|
||||||
this.getImportableDomains()
|
this.getImportableDomains()
|
||||||
}
|
}
|
||||||
|
@ -241,7 +241,7 @@ export default {
|
||||||
this.$router.replace('/providers/' + encodeURIComponent(this.myProvider._id))
|
this.$router.replace('/providers/' + encodeURIComponent(this.myProvider._id))
|
||||||
})
|
})
|
||||||
|
|
||||||
if (!this.showDomainsWithActions || this.sourceSpecs_getAll[this.provider._srctype].capabilities.indexOf('ListDomainsWithActions') === -1) {
|
if (!this.showDomainsWithActions || this.providerSpecs_getAll[this.provider._srctype].capabilities.indexOf('ListDomainsWithActions') === -1) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -230,6 +230,18 @@ export default {
|
||||||
this.importInProgress = false
|
this.importInProgress = false
|
||||||
this.updateDomainInfo()
|
this.updateDomainInfo()
|
||||||
this.selectedHistory = response.data.id
|
this.selectedHistory = response.data.id
|
||||||
|
},
|
||||||
|
(error) => {
|
||||||
|
this.importInProgress = false
|
||||||
|
this.$root.$bvToast.toast(
|
||||||
|
error.response.data.errmsg, {
|
||||||
|
title: this.$t('errors.occurs', { when: 'importing the zone' }),
|
||||||
|
autoHideDelay: 5000,
|
||||||
|
variant: 'danger',
|
||||||
|
toaster: 'b-toaster-content-right'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
this.$router.push('/domains/')
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue
Block a user