Disable types that are not compatible with a given source
This commit is contained in:
parent
0945bf2ecb
commit
e627e6b5ea
|
@ -53,6 +53,8 @@ func init() {
|
|||
router.DELETE("/api/sources/:sid", apiAuthHandler(sourceMetaHandler(deleteSource)))
|
||||
|
||||
router.GET("/api/sources/:sid/domains", apiAuthHandler(sourceHandler(getDomainsHostedBySource)))
|
||||
|
||||
router.GET("/api/sources/:sid/available_resource_types", apiAuthHandler(sourceHandler(getAvailableResourceTypes)))
|
||||
}
|
||||
|
||||
func getSources(_ *config.Options, req *RequestResources, body io.Reader) Response {
|
||||
|
@ -224,3 +226,17 @@ func getDomainsHostedBySource(_ *config.Options, req *RequestResources, body io.
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func getAvailableResourceTypes(_ *config.Options, req *RequestResources, body io.Reader) Response {
|
||||
lrt, ok := req.Source.Source.(sources.LimitedResourceTypesSource)
|
||||
if !ok {
|
||||
// Return all types known to be supported by happyDNS
|
||||
return APIResponse{
|
||||
response: sources.DefaultAvailableTypes,
|
||||
}
|
||||
} else {
|
||||
return APIResponse{
|
||||
response: lrt.ListAvailableTypes(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -137,6 +137,7 @@
|
|||
<script>
|
||||
import DomainCompare from '@/mixins/domainCompare'
|
||||
import ServiceSpecsApi from '@/services/ServiceSpecsApi'
|
||||
import SourcesApi from '@/services/SourcesApi'
|
||||
import ZoneApi from '@/services/ZoneApi'
|
||||
|
||||
export default {
|
||||
|
@ -166,6 +167,7 @@ export default {
|
|||
|
||||
data: function () {
|
||||
return {
|
||||
availableResourceTypes: [],
|
||||
deleteServiceInProgress: false,
|
||||
hideDomain: {},
|
||||
modal: null,
|
||||
|
@ -224,6 +226,16 @@ export default {
|
|||
const svc = this.services[type]
|
||||
|
||||
if (svc.restrictions) {
|
||||
// Handle NeedTypes restriction: hosting provider need to support given types.
|
||||
if (svc.restrictions.needTypes) {
|
||||
for (const k in svc.restrictions.needTypes) {
|
||||
if (this.availableResourceTypes.indexOf(svc.restrictions.needTypes[k]) < 0) {
|
||||
ret[type] = 'is not available on this domain name hosting provider.'
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Handle Alone restriction: only nearAlone are allowed.
|
||||
if (svc.restrictions.alone && this.myServices.services[this.modal.dn]) {
|
||||
var found = false
|
||||
|
@ -307,7 +319,7 @@ export default {
|
|||
},
|
||||
|
||||
isLoading () {
|
||||
return this.myServices == null && this.zoneId === undefined && this.services === {}
|
||||
return this.myServices == null && this.availableResourceTypes.length > 0 && this.zoneId === undefined && this.services === {}
|
||||
},
|
||||
|
||||
sortedDomains () {
|
||||
|
@ -338,6 +350,13 @@ export default {
|
|||
.then(
|
||||
(response) => (this.services = response.data)
|
||||
)
|
||||
|
||||
SourcesApi.getAvailableResourceTypes(this.domain.id_source)
|
||||
.then(
|
||||
(response) => {
|
||||
this.availableResourceTypes = response.data
|
||||
}
|
||||
)
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
|
|
@ -213,6 +213,7 @@
|
|||
"update": "Update service"
|
||||
},
|
||||
"source": {
|
||||
"available-types": "Resources Types available",
|
||||
"delete": "@:common.delete this @:source.kind",
|
||||
"find": "Can't find your @:source.kind here?",
|
||||
"name-your": "Name your @:source.kind",
|
||||
|
|
|
@ -36,6 +36,10 @@ export default {
|
|||
return Api().get('/api/sources/' + encodeURIComponent(srcId))
|
||||
},
|
||||
|
||||
getAvailableResourceTypes (srcId) {
|
||||
return Api().get('/api/sources/' + encodeURIComponent(srcId) + '/available_resource_types')
|
||||
},
|
||||
|
||||
getSources () {
|
||||
return Api().get('/api/sources')
|
||||
},
|
||||
|
|
|
@ -56,12 +56,21 @@
|
|||
<span class="text-primary">{{ spec.label }}</span><br>
|
||||
<strong>{{ source.Source[spec.id] }}</strong>
|
||||
</p>
|
||||
<p v-if="availableTypes.length">
|
||||
<span class="text-primary">{{ $t('source.available-types') }}</span>
|
||||
<ul style="column-count: 4;">
|
||||
<li v-for="(t, i) in availableTypes" :key="i">
|
||||
{{ t | nsrrtype }}
|
||||
</li>
|
||||
</ul>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import axios from 'axios'
|
||||
import SourcesApi from '@/services/SourcesApi'
|
||||
import SourceSpecsApi from '@/services/SourceSpecsApi'
|
||||
|
||||
export default {
|
||||
|
||||
|
@ -74,6 +83,7 @@ export default {
|
|||
|
||||
data: function () {
|
||||
return {
|
||||
availableTypes: [],
|
||||
source: null,
|
||||
source_specs: null,
|
||||
specs: null
|
||||
|
@ -93,8 +103,7 @@ export default {
|
|||
},
|
||||
|
||||
mounted () {
|
||||
axios
|
||||
.get('/api/source_specs')
|
||||
SourceSpecsApi.getSourceSpecs()
|
||||
.then(response => {
|
||||
this.specs = response.data
|
||||
})
|
||||
|
@ -108,17 +117,20 @@ export default {
|
|||
if (this.domain === undefined || this.domain.id_source === undefined) {
|
||||
return
|
||||
}
|
||||
axios
|
||||
.get('/api/sources/' + encodeURIComponent(this.domain.id_source))
|
||||
SourcesApi.getSource(this.domain.id_source)
|
||||
.then(
|
||||
(response) => {
|
||||
this.source = response.data
|
||||
|
||||
axios
|
||||
.get('/api/source_specs/' + encodeURIComponent(this.source._srctype))
|
||||
SourceSpecsApi.getSourceSpecs(this.source._srctype)
|
||||
.then(response => (
|
||||
this.source_specs = response.data
|
||||
))
|
||||
|
||||
SourcesApi.getAvailableResourceTypes(this.domain.id_source)
|
||||
.then(response => (
|
||||
this.availableTypes = response.data
|
||||
))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -133,6 +133,9 @@ func init() {
|
|||
},
|
||||
Restrictions: ServiceRestrictions{
|
||||
NearAlone: true,
|
||||
NeedTypes: []uint16{
|
||||
dns.TypeCNAME,
|
||||
},
|
||||
},
|
||||
},
|
||||
99999997,
|
||||
|
@ -151,6 +154,9 @@ func init() {
|
|||
Restrictions: ServiceRestrictions{
|
||||
Alone: true,
|
||||
Single: true,
|
||||
NeedTypes: []uint16{
|
||||
dns.TypeCNAME,
|
||||
},
|
||||
},
|
||||
},
|
||||
99999998,
|
||||
|
|
|
@ -152,6 +152,9 @@ func init() {
|
|||
Leaf: true,
|
||||
ExclusiveRR: []string{"svcs.Origin"},
|
||||
Single: true,
|
||||
NeedTypes: []uint16{
|
||||
dns.TypeNS,
|
||||
},
|
||||
},
|
||||
},
|
||||
1,
|
||||
|
|
|
@ -396,6 +396,9 @@ func init() {
|
|||
Tabs: true,
|
||||
Restrictions: ServiceRestrictions{
|
||||
Single: true,
|
||||
NeedTypes: []uint16{
|
||||
dns.TypeMX,
|
||||
},
|
||||
},
|
||||
},
|
||||
1,
|
||||
|
|
|
@ -53,6 +53,9 @@ type ServiceRestrictions struct {
|
|||
// NearAlone allows a service to be present along with Alone restricted services (eg. services that will create sub-subdomain from their given subdomain).
|
||||
NearAlone bool `json:"nearAlone,omitempty"`
|
||||
|
||||
// NeedTypes restricts the service to sources that are compatibles with ALL the given types.
|
||||
NeedTypes []uint16 `json:"needTypes,omitempty"`
|
||||
|
||||
// RootOnly restricts the service to be present at the root of the domain only.
|
||||
RootOnly bool `json:"rootOnly,omitempty"`
|
||||
|
||||
|
|
|
@ -134,6 +134,9 @@ func init() {
|
|||
Restrictions: ServiceRestrictions{
|
||||
NearAlone: true,
|
||||
Single: true,
|
||||
NeedTypes: []uint16{
|
||||
dns.TypeSRV,
|
||||
},
|
||||
},
|
||||
},
|
||||
1,
|
||||
|
|
|
@ -194,6 +194,9 @@ func init() {
|
|||
},
|
||||
Restrictions: ServiceRestrictions{
|
||||
NearAlone: true,
|
||||
NeedTypes: []uint16{
|
||||
dns.TypeOPENPGPKEY,
|
||||
},
|
||||
},
|
||||
},
|
||||
1,
|
||||
|
@ -211,6 +214,9 @@ func init() {
|
|||
},
|
||||
Restrictions: ServiceRestrictions{
|
||||
NearAlone: true,
|
||||
NeedTypes: []uint16{
|
||||
dns.TypeSMIMEA,
|
||||
},
|
||||
},
|
||||
},
|
||||
1,
|
||||
|
|
|
@ -145,6 +145,9 @@ func init() {
|
|||
Restrictions: ServiceRestrictions{
|
||||
RootOnly: true,
|
||||
Single: true,
|
||||
NeedTypes: []uint16{
|
||||
dns.TypeSOA,
|
||||
},
|
||||
},
|
||||
},
|
||||
0,
|
||||
|
|
|
@ -157,6 +157,9 @@ func init() {
|
|||
},
|
||||
Restrictions: ServiceRestrictions{
|
||||
NearAlone: true,
|
||||
NeedTypes: []uint16{
|
||||
dns.TypeSRV,
|
||||
},
|
||||
},
|
||||
},
|
||||
99999,
|
||||
|
|
|
@ -181,6 +181,9 @@ func init() {
|
|||
Restrictions: ServiceRestrictions{
|
||||
NearAlone: true,
|
||||
Single: true,
|
||||
NeedTypes: []uint16{
|
||||
dns.TypeTLSA,
|
||||
},
|
||||
},
|
||||
},
|
||||
100,
|
||||
|
|
|
@ -160,6 +160,9 @@ func init() {
|
|||
Restrictions: ServiceRestrictions{
|
||||
NearAlone: true,
|
||||
Single: true,
|
||||
NeedTypes: []uint16{
|
||||
dns.TypeSRV,
|
||||
},
|
||||
},
|
||||
},
|
||||
1,
|
||||
|
|
|
@ -102,6 +102,21 @@ func doTxt(req *http.Request) (txt []byte, err error) {
|
|||
return
|
||||
}
|
||||
|
||||
func (s *AlwaysdataAPI) ListAvailableTypes() (types []uint16) {
|
||||
return []uint16{
|
||||
dns.TypeA,
|
||||
dns.TypeAAAA,
|
||||
dns.TypeCAA,
|
||||
dns.TypeCNAME,
|
||||
dns.TypeMX,
|
||||
dns.TypeNS,
|
||||
dns.TypePTR,
|
||||
dns.TypeSOA,
|
||||
dns.TypeSRV,
|
||||
dns.TypeTXT,
|
||||
}
|
||||
}
|
||||
|
||||
type alwaysdataInfo struct {
|
||||
Id int64 `json:"id"`
|
||||
Name string `json:"name"`
|
||||
|
|
|
@ -95,6 +95,30 @@ func doJSON(req *http.Request, v interface{}) (err error) {
|
|||
}
|
||||
|
||||
func (s *GandiAPI) ListAvailableTypes() (types []uint16) {
|
||||
types = []uint16{
|
||||
dns.TypeA,
|
||||
dns.TypeAAAA,
|
||||
//dns.TypeALIAS,
|
||||
dns.TypeCAA,
|
||||
dns.TypeCDS,
|
||||
dns.TypeCNAME,
|
||||
dns.TypeDNAME,
|
||||
dns.TypeDS,
|
||||
dns.TypeKEY,
|
||||
dns.TypeLOC,
|
||||
dns.TypeMX,
|
||||
dns.TypeNS,
|
||||
dns.TypeOPENPGPKEY,
|
||||
dns.TypePTR,
|
||||
dns.TypeSPF,
|
||||
dns.TypeSOA,
|
||||
dns.TypeSRV,
|
||||
dns.TypeSSHFP,
|
||||
dns.TypeTLSA,
|
||||
dns.TypeTXT,
|
||||
//dns.TypeWKS,
|
||||
}
|
||||
|
||||
req, err := s.newRequest("GET", "https://api.gandi.net/v5/livedns/dns/rrtypes", nil)
|
||||
if err != nil {
|
||||
return
|
||||
|
@ -107,6 +131,7 @@ func (s *GandiAPI) ListAvailableTypes() (types []uint16) {
|
|||
return
|
||||
}
|
||||
|
||||
types = []uint16{}
|
||||
for _, r := range rrtypes {
|
||||
if t, ok := dns.StringToType[r]; ok {
|
||||
types = append(types, t)
|
||||
|
|
|
@ -36,6 +36,9 @@ import (
|
|||
|
||||
"git.happydns.org/happydns/config"
|
||||
"git.happydns.org/happydns/model"
|
||||
"git.happydns.org/happydns/utils"
|
||||
|
||||
"github.com/miekg/dns"
|
||||
)
|
||||
|
||||
// SourceInfos describes the purpose of a user usable source.
|
||||
|
@ -53,6 +56,12 @@ type ListDomainsSource interface {
|
|||
ListDomains() ([]string, error)
|
||||
}
|
||||
|
||||
type LimitedResourceTypesSource interface {
|
||||
ListAvailableTypes() []uint16
|
||||
}
|
||||
|
||||
var DefaultAvailableTypes []uint16
|
||||
|
||||
// CustomForm is used to create a form with several steps when creating or updating source's settings.
|
||||
type CustomForm struct {
|
||||
// BeforeText is the text presented before the fields.
|
||||
|
@ -116,6 +125,10 @@ func GetSourceCapabilities(src happydns.Source) (caps []string) {
|
|||
caps = append(caps, "CustomSettingsForm")
|
||||
}
|
||||
|
||||
if _, ok := src.(LimitedResourceTypesSource); ok {
|
||||
caps = append(caps, "LimitedResourceTypes")
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -131,3 +144,11 @@ func GenDefaultSettingsForm(src happydns.Source) *CustomForm {
|
|||
PreviousButtonState: -1,
|
||||
}
|
||||
}
|
||||
|
||||
func init() {
|
||||
for t := range dns.TypeToRR {
|
||||
if !utils.IsDNSSECType(t) {
|
||||
DefaultAvailableTypes = append(DefaultAvailableTypes, t)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue