Add Swagger
continuous-integration/drone/push Build is running
Details
continuous-integration/drone/push Build is running
Details
This commit is contained in:
parent
9b6b78d837
commit
216cdee5d5
34
.drone.yml
34
.drone.yml
|
@ -58,8 +58,9 @@ steps:
|
||||||
commands:
|
commands:
|
||||||
- apk add --no-cache git
|
- apk add --no-cache git
|
||||||
- sed -i '/npm run build/d' ui/assets.go
|
- sed -i '/npm run build/d' ui/assets.go
|
||||||
|
- go install github.com/swaggo/swag/cmd/swag@latest
|
||||||
- go generate -v ./...
|
- go generate -v ./...
|
||||||
- go build -v -tags netgo -ldflags '-w -X main.version="${DRONE_BRANCH}-${DRONE_COMMIT}" -X main.build=${DRONE_BUILD_NUMBER}' -o happydomain-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH}
|
- go build -v -tags netgo -ldflags '-w -X main.Version="${DRONE_BRANCH}-${DRONE_COMMIT}" -X main.build=${DRONE_BUILD_NUMBER}' -o happydomain-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH}
|
||||||
- ln happydomain-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH} happydomain
|
- ln happydomain-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH} happydomain
|
||||||
environment:
|
environment:
|
||||||
CGO_ENABLED: 0
|
CGO_ENABLED: 0
|
||||||
|
@ -73,8 +74,9 @@ steps:
|
||||||
commands:
|
commands:
|
||||||
- apk add --no-cache git
|
- apk add --no-cache git
|
||||||
- sed -i '/npm run build/d' ui/assets.go
|
- sed -i '/npm run build/d' ui/assets.go
|
||||||
|
- go install github.com/swaggo/swag/cmd/swag@latest
|
||||||
- go generate -v ./...
|
- go generate -v ./...
|
||||||
- go build -v -tags netgo -ldflags '-w -X main.version=${DRONE_TAG##v} -X main.build=${DRONE_BUILD_NUMBER}' -o happydomain-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH}
|
- go build -v -tags netgo -ldflags '-w -X main.Version=${DRONE_TAG##v} -X main.build=${DRONE_BUILD_NUMBER}' -o happydomain-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH}
|
||||||
- ln happydomain-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH} happydomain
|
- ln happydomain-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH} happydomain
|
||||||
environment:
|
environment:
|
||||||
CGO_ENABLED: 0
|
CGO_ENABLED: 0
|
||||||
|
@ -129,7 +131,7 @@ steps:
|
||||||
image: golang:1-alpine
|
image: golang:1-alpine
|
||||||
commands:
|
commands:
|
||||||
- apk add --no-cache git
|
- apk add --no-cache git
|
||||||
- go build -v -tags netgo -ldflags '-w -X main.version="${DRONE_BRANCH}-${DRONE_COMMIT}" -X main.build=${DRONE_BUILD_NUMBER}' -o happydomain-darwin-${DRONE_STAGE_ARCH}
|
- go build -v -tags netgo -ldflags '-w -X main.Version="${DRONE_BRANCH}-${DRONE_COMMIT}" -X main.build=${DRONE_BUILD_NUMBER}' -o happydomain-darwin-${DRONE_STAGE_ARCH}
|
||||||
environment:
|
environment:
|
||||||
CGO_ENABLED: 0
|
CGO_ENABLED: 0
|
||||||
GOOS: darwin
|
GOOS: darwin
|
||||||
|
@ -143,7 +145,7 @@ steps:
|
||||||
image: golang:1-alpine
|
image: golang:1-alpine
|
||||||
commands:
|
commands:
|
||||||
- apk add --no-cache git
|
- apk add --no-cache git
|
||||||
- go build -v -tags netgo -ldflags '-w -X main.version="${DRONE_TAG##v}" -X main.build=${DRONE_BUILD_NUMBER}' -o happydomain-darwin-${DRONE_STAGE_ARCH}
|
- go build -v -tags netgo -ldflags '-w -X main.Version="${DRONE_TAG##v}" -X main.build=${DRONE_BUILD_NUMBER}' -o happydomain-darwin-${DRONE_STAGE_ARCH}
|
||||||
environment:
|
environment:
|
||||||
CGO_ENABLED: 0
|
CGO_ENABLED: 0
|
||||||
GOOS: darwin
|
GOOS: darwin
|
||||||
|
@ -227,8 +229,9 @@ steps:
|
||||||
commands:
|
commands:
|
||||||
- apk add --no-cache git
|
- apk add --no-cache git
|
||||||
- sed -i '/npm run build/d' ui/assets.go
|
- sed -i '/npm run build/d' ui/assets.go
|
||||||
|
- go install github.com/swaggo/swag/cmd/swag@latest
|
||||||
- go generate -v ./...
|
- go generate -v ./...
|
||||||
- go build -v -tags netgo -ldflags '-w -X main.version="${DRONE_BRANCH}-${DRONE_COMMIT}" -X main.build=${DRONE_BUILD_NUMBER}' -o happydomain-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH}
|
- go build -v -tags netgo -ldflags '-w -X main.Version="${DRONE_BRANCH}-${DRONE_COMMIT}" -X main.build=${DRONE_BUILD_NUMBER}' -o happydomain-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH}
|
||||||
- ln happydomain-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH} happydomain
|
- ln happydomain-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH} happydomain
|
||||||
environment:
|
environment:
|
||||||
CGO_ENABLED: 0
|
CGO_ENABLED: 0
|
||||||
|
@ -242,8 +245,9 @@ steps:
|
||||||
commands:
|
commands:
|
||||||
- apk add --no-cache git
|
- apk add --no-cache git
|
||||||
- sed -i '/npm run build/d' ui/assets.go
|
- sed -i '/npm run build/d' ui/assets.go
|
||||||
|
- go install github.com/swaggo/swag/cmd/swag@latest
|
||||||
- go generate -v ./...
|
- go generate -v ./...
|
||||||
- go build -v -tags netgo -ldflags '-w -X main.version=${DRONE_TAG##v} -X main.build=${DRONE_BUILD_NUMBER}' -o happydomain-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH}
|
- go build -v -tags netgo -ldflags '-w -X main.Version=${DRONE_TAG##v} -X main.build=${DRONE_BUILD_NUMBER}' -o happydomain-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH}
|
||||||
- ln happydomain-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH} happydomain
|
- ln happydomain-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH} happydomain
|
||||||
environment:
|
environment:
|
||||||
CGO_ENABLED: 0
|
CGO_ENABLED: 0
|
||||||
|
@ -290,7 +294,7 @@ steps:
|
||||||
image: golang:1-alpine
|
image: golang:1-alpine
|
||||||
commands:
|
commands:
|
||||||
- apk add --no-cache git
|
- apk add --no-cache git
|
||||||
- go build -v -tags netgo -ldflags '-w -X main.version="${DRONE_BRANCH}-${DRONE_COMMIT}" -X main.build=${DRONE_BUILD_NUMBER}' -o happydomain-darwin-${DRONE_STAGE_ARCH}
|
- go build -v -tags netgo -ldflags '-w -X main.Version="${DRONE_BRANCH}-${DRONE_COMMIT}" -X main.build=${DRONE_BUILD_NUMBER}' -o happydomain-darwin-${DRONE_STAGE_ARCH}
|
||||||
environment:
|
environment:
|
||||||
CGO_ENABLED: 0
|
CGO_ENABLED: 0
|
||||||
GOOS: darwin
|
GOOS: darwin
|
||||||
|
@ -304,7 +308,7 @@ steps:
|
||||||
image: golang:1-alpine
|
image: golang:1-alpine
|
||||||
commands:
|
commands:
|
||||||
- apk add --no-cache git
|
- apk add --no-cache git
|
||||||
- go build -v -tags netgo -ldflags '-w -X main.version="${DRONE_TAG##v}" -X main.build=${DRONE_BUILD_NUMBER}' -o happydomain-darwin-${DRONE_STAGE_ARCH}
|
- go build -v -tags netgo -ldflags '-w -X main.Version="${DRONE_TAG##v}" -X main.build=${DRONE_BUILD_NUMBER}' -o happydomain-darwin-${DRONE_STAGE_ARCH}
|
||||||
environment:
|
environment:
|
||||||
CGO_ENABLED: 0
|
CGO_ENABLED: 0
|
||||||
GOOS: darwin
|
GOOS: darwin
|
||||||
|
@ -388,8 +392,9 @@ steps:
|
||||||
commands:
|
commands:
|
||||||
- apk --no-cache add build-base git
|
- apk --no-cache add build-base git
|
||||||
- sed -i '/npm run build/d' ui/assets.go
|
- sed -i '/npm run build/d' ui/assets.go
|
||||||
|
- go install github.com/swaggo/swag/cmd/swag@latest
|
||||||
- go generate -v ./...
|
- go generate -v ./...
|
||||||
- go build -v -tags netgo -ldflags '-w -X main.version="${DRONE_BRANCH}-${DRONE_COMMIT}" -X main.build=${DRONE_BUILD_NUMBER}' -o happydomain-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH}el
|
- go build -v -tags netgo -ldflags '-w -X main.Version="${DRONE_BRANCH}-${DRONE_COMMIT}" -X main.build=${DRONE_BUILD_NUMBER}' -o happydomain-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH}el
|
||||||
environment:
|
environment:
|
||||||
CGO_ENABLED: 0
|
CGO_ENABLED: 0
|
||||||
GOARM: 5
|
GOARM: 5
|
||||||
|
@ -406,8 +411,9 @@ steps:
|
||||||
commands:
|
commands:
|
||||||
- apk --no-cache add build-base git
|
- apk --no-cache add build-base git
|
||||||
- sed -i '/npm run build/d' ui/assets.go
|
- sed -i '/npm run build/d' ui/assets.go
|
||||||
|
- go install github.com/swaggo/swag/cmd/swag@latest
|
||||||
- go generate -v ./...
|
- go generate -v ./...
|
||||||
- go build -v -tags netgo -ldflags '-w -X main.version="${DRONE_TAG##v}" -X main.build=${DRONE_BUILD_NUMBER}' -o happydomain-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH}el
|
- go build -v -tags netgo -ldflags '-w -X main.Version="${DRONE_TAG##v}" -X main.build=${DRONE_BUILD_NUMBER}' -o happydomain-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH}el
|
||||||
environment:
|
environment:
|
||||||
CGO_ENABLED: 0
|
CGO_ENABLED: 0
|
||||||
GOARM: 5
|
GOARM: 5
|
||||||
|
@ -454,7 +460,7 @@ steps:
|
||||||
image: golang:1-alpine
|
image: golang:1-alpine
|
||||||
commands:
|
commands:
|
||||||
- apk --no-cache add build-base git
|
- apk --no-cache add build-base git
|
||||||
- go build -v -tags netgo -ldflags '-w -X main.version="${DRONE_BRANCH}-${DRONE_COMMIT}" -X main.build=${DRONE_BUILD_NUMBER}' -o happydomain-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH}hf
|
- go build -v -tags netgo -ldflags '-w -X main.Version="${DRONE_BRANCH}-${DRONE_COMMIT}" -X main.build=${DRONE_BUILD_NUMBER}' -o happydomain-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH}hf
|
||||||
environment:
|
environment:
|
||||||
CGO_ENABLED: 0
|
CGO_ENABLED: 0
|
||||||
GOARM: 6
|
GOARM: 6
|
||||||
|
@ -470,7 +476,7 @@ steps:
|
||||||
image: golang:1-alpine
|
image: golang:1-alpine
|
||||||
commands:
|
commands:
|
||||||
- apk --no-cache add build-base git
|
- apk --no-cache add build-base git
|
||||||
- go build -v -tags netgo -ldflags '-w -X main.version="${DRONE_TAG##v}" -X main.build=${DRONE_BUILD_NUMBER}' -o happydomain-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH}hf
|
- go build -v -tags netgo -ldflags '-w -X main.Version="${DRONE_TAG##v}" -X main.build=${DRONE_BUILD_NUMBER}' -o happydomain-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH}hf
|
||||||
environment:
|
environment:
|
||||||
CGO_ENABLED: 0
|
CGO_ENABLED: 0
|
||||||
GOARM: 6
|
GOARM: 6
|
||||||
|
@ -517,7 +523,7 @@ steps:
|
||||||
image: golang:1-alpine
|
image: golang:1-alpine
|
||||||
commands:
|
commands:
|
||||||
- apk --no-cache add build-base git
|
- apk --no-cache add build-base git
|
||||||
- go build -v -tags netgo -ldflags '-w -X main.version="${DRONE_BRANCH}-${DRONE_COMMIT}" -X main.build=${DRONE_BUILD_NUMBER}' -o happydomain-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH}v7
|
- go build -v -tags netgo -ldflags '-w -X main.Version="${DRONE_BRANCH}-${DRONE_COMMIT}" -X main.build=${DRONE_BUILD_NUMBER}' -o happydomain-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH}v7
|
||||||
- ln happydomain-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH}v7 happydomain
|
- ln happydomain-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH}v7 happydomain
|
||||||
environment:
|
environment:
|
||||||
CGO_ENABLED: 0
|
CGO_ENABLED: 0
|
||||||
|
@ -531,7 +537,7 @@ steps:
|
||||||
image: golang:1-alpine
|
image: golang:1-alpine
|
||||||
commands:
|
commands:
|
||||||
- apk --no-cache add build-base git
|
- apk --no-cache add build-base git
|
||||||
- go build -v -tags netgo -ldflags '-w -X main.version="${DRONE_TAG##v}" -X main.build=${DRONE_BUILD_NUMBER}' -o happydomain-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH}v7
|
- go build -v -tags netgo -ldflags '-w -X main.Version="${DRONE_TAG##v}" -X main.build=${DRONE_BUILD_NUMBER}' -o happydomain-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH}v7
|
||||||
- ln happydomain-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH}v7 happydomain
|
- ln happydomain-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH}v7 happydomain
|
||||||
environment:
|
environment:
|
||||||
CGO_ENABLED: 0
|
CGO_ENABLED: 0
|
||||||
|
|
|
@ -30,9 +30,9 @@ COPY storage ./storage
|
||||||
COPY utils ./utils
|
COPY utils ./utils
|
||||||
COPY generate.go go.mod go.sum main.go ./
|
COPY generate.go go.mod go.sum main.go ./
|
||||||
|
|
||||||
RUN sed -i '/yarn --offline build/d' ui/assets.go && \
|
RUN sed -i '/npm run build/d' ui/assets.go && \
|
||||||
go get -d -v && \
|
go install github.com/swaggo/swag/cmd/swag@latest && \
|
||||||
go generate -v && \
|
go generate -v ./... && \
|
||||||
go build -v -ldflags '-w'
|
go build -v -ldflags '-w'
|
||||||
|
|
||||||
|
|
||||||
|
|
116
api/domains.go
116
api/domains.go
|
@ -58,6 +58,19 @@ func declareDomainsRoutes(cfg *config.Options, router *gin.RouterGroup) {
|
||||||
declareZonesRoutes(cfg, apiDomainsRoutes)
|
declareZonesRoutes(cfg, apiDomainsRoutes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetDomains retrieves all domains belonging to the user.
|
||||||
|
//
|
||||||
|
// @Summary Retrieve user's domains
|
||||||
|
// @Schemes
|
||||||
|
// @Description Retrieve all domains belonging to the user.
|
||||||
|
// @Tags domains
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Security securitydefinitions.basic
|
||||||
|
// @Success 200 {array} happydns.Domain
|
||||||
|
// @Failure 401 {object} happydns.Error "Authentication failure"
|
||||||
|
// @Failure 404 {object} happydns.Error "Unable to retrieve user's domains"
|
||||||
|
// @Router /domains [get]
|
||||||
func GetDomains(c *gin.Context) {
|
func GetDomains(c *gin.Context) {
|
||||||
user := myUser(c)
|
user := myUser(c)
|
||||||
if user == nil {
|
if user == nil {
|
||||||
|
@ -75,6 +88,21 @@ func GetDomains(c *gin.Context) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// addDomain appends a new domain to those managed.
|
||||||
|
//
|
||||||
|
// @Summary Manage a new domain
|
||||||
|
// @Schemes
|
||||||
|
// @Description Append a new domain to those managed.
|
||||||
|
// @Tags domains
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param body body happydns.DomainMinimal true "Domain object that you want to manage through happyDomain."
|
||||||
|
// @Security securitydefinitions.basic
|
||||||
|
// @Success 200 {object} happydns.Domain
|
||||||
|
// @Failure 400 {object} happydns.Error "Error in received data"
|
||||||
|
// @Failure 401 {object} happydns.Error "Authentication failure"
|
||||||
|
// @Failure 500 {object} happydns.Error "Unable to retrieve current user's domains"
|
||||||
|
// @Router /domains [post]
|
||||||
func addDomain(c *gin.Context) {
|
func addDomain(c *gin.Context) {
|
||||||
var uz happydns.Domain
|
var uz happydns.Domain
|
||||||
err := c.ShouldBindJSON(&uz)
|
err := c.ShouldBindJSON(&uz)
|
||||||
|
@ -140,15 +168,15 @@ func DomainHandler(c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// If source is provided, check that the domain is a parent of the source
|
// If provider is provided, check that the domain is a parent of the provider
|
||||||
var source *happydns.SourceMeta
|
var provider *happydns.ProviderMeta
|
||||||
if src, exists := c.Get("source"); exists {
|
if src, exists := c.Get("provider"); exists {
|
||||||
source = &src.(*happydns.SourceCombined).SourceMeta
|
provider = &src.(*happydns.ProviderCombined).ProviderMeta
|
||||||
} else if src, exists := c.Get("sourcemeta"); exists {
|
} else if src, exists := c.Get("providermeta"); exists {
|
||||||
source = src.(*happydns.SourceMeta)
|
provider = src.(*happydns.ProviderMeta)
|
||||||
}
|
}
|
||||||
if source != nil && !source.Id.Equals(domain.IdProvider) {
|
if provider != nil && !provider.Id.Equals(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 provider)"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,14 +186,40 @@ func DomainHandler(c *gin.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
type apiDomain struct {
|
type apiDomain struct {
|
||||||
Id happydns.Identifier `json:"id"`
|
// Id is the Domain's identifier in the database.
|
||||||
IdUser happydns.Identifier `json:"id_owner"`
|
Id happydns.Identifier `json:"id" swaggertype:"string"`
|
||||||
IdProvider happydns.Identifier `json:"id_provider"`
|
|
||||||
DomainName string `json:"domain"`
|
// IdUser is the identifier of the Domain's Owner.
|
||||||
|
IdUser happydns.Identifier `json:"id_owner" swaggertype:"string"`
|
||||||
|
|
||||||
|
// IsProvider is the identifier of the Provider used to access and edit the
|
||||||
|
// Domain.
|
||||||
|
IdProvider happydns.Identifier `json:"id_provider" swaggertype:"string"`
|
||||||
|
|
||||||
|
// DomainName is the FQDN of the managed Domain.
|
||||||
|
DomainName string `json:"domain"`
|
||||||
|
// Group is a hint string aims to group domains.
|
||||||
|
Group string `json:"group,omitempty"`
|
||||||
|
|
||||||
|
// ZoneHistory are the metadata associated to each Zone saved with the
|
||||||
|
// current Domain.
|
||||||
ZoneHistory []happydns.ZoneMeta `json:"zone_history"`
|
ZoneHistory []happydns.ZoneMeta `json:"zone_history"`
|
||||||
Group string `json:"group,omitempty"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetDomain retrieves information about a given Domain owned by the user.
|
||||||
|
//
|
||||||
|
// @Summary Retrieve Domain local information.
|
||||||
|
// @Schemes
|
||||||
|
// @Description Retrieve information in the database about a given Domain owned by the user.
|
||||||
|
// @Tags domains
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param domainId path string true "Domain identifier"
|
||||||
|
// @Security securitydefinitions.basic
|
||||||
|
// @Success 200 {object} apiDomain
|
||||||
|
// @Failure 401 {object} happydns.Error "Authentication failure"
|
||||||
|
// @Failure 404 {object} happydns.Error "Domain not found"
|
||||||
|
// @Router /domains/{domainId} [get]
|
||||||
func GetDomain(c *gin.Context) {
|
func GetDomain(c *gin.Context) {
|
||||||
domain := c.MustGet("domain").(*happydns.Domain)
|
domain := c.MustGet("domain").(*happydns.Domain)
|
||||||
ret := &apiDomain{
|
ret := &apiDomain{
|
||||||
|
@ -190,6 +244,24 @@ func GetDomain(c *gin.Context) {
|
||||||
c.JSON(http.StatusOK, ret)
|
c.JSON(http.StatusOK, ret)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UpdateDomain updates the information about a given Domain owned by the user.
|
||||||
|
//
|
||||||
|
// @Summary Update Domain local information.
|
||||||
|
// @Schemes
|
||||||
|
// @Description Updates the information about a given Domain owned by the user.
|
||||||
|
// @Tags domains
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param domainId path string true "Domain identifier"
|
||||||
|
// @Param body body happydns.Domain true "The new object overriding the current domain"
|
||||||
|
// @Security securitydefinitions.basic
|
||||||
|
// @Success 200 {object} happydns.Domain
|
||||||
|
// @Failure 400 {object} happydns.Error "Invalid input"
|
||||||
|
// @Failure 400 {object} happydns.Error "Identifier changed"
|
||||||
|
// @Failure 401 {object} happydns.Error "Authentication failure"
|
||||||
|
// @Failure 404 {object} happydns.Error "Domain not found"
|
||||||
|
// @Failure 500 {object} happydns.Error "Database writing error"
|
||||||
|
// @Router /domains/{domainId} [put]
|
||||||
func UpdateDomain(c *gin.Context) {
|
func UpdateDomain(c *gin.Context) {
|
||||||
old := c.MustGet("domain").(*happydns.Domain)
|
old := c.MustGet("domain").(*happydns.Domain)
|
||||||
|
|
||||||
|
@ -217,6 +289,22 @@ func UpdateDomain(c *gin.Context) {
|
||||||
c.JSON(http.StatusOK, old)
|
c.JSON(http.StatusOK, old)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// delDomain removes a domain from the database.
|
||||||
|
//
|
||||||
|
// @Summary Stop managing a Domain.
|
||||||
|
// @Schemes
|
||||||
|
// @Description Delete all the information in the database about the given Domain. This only stops happyDomain from managing the Domain, it doesn't do anything on the Provider.
|
||||||
|
// @Tags domains
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param domainId path string true "Domain identifier"
|
||||||
|
// @Security securitydefinitions.basic
|
||||||
|
// @Success 204 "Domain deleted"
|
||||||
|
// @Failure 400 {object} happydns.Error "Invalid input"
|
||||||
|
// @Failure 401 {object} happydns.Error "Authentication failure"
|
||||||
|
// @Failure 404 {object} happydns.Error "Domain not found"
|
||||||
|
// @Failure 500 {object} happydns.Error "Database writing error"
|
||||||
|
// @Router /domains/{domainId} [delete]
|
||||||
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: %s", c.ClientIP(), err.Error())
|
log.Printf("%s was unable to DeleteDomain: %s", c.ClientIP(), err.Error())
|
||||||
|
@ -224,5 +312,5 @@ func delDomain(c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.JSON(http.StatusNoContent, true)
|
c.Status(http.StatusNoContent)
|
||||||
}
|
}
|
||||||
|
|
15
api/form.go
15
api/form.go
|
@ -40,10 +40,17 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type FormState struct {
|
type FormState struct {
|
||||||
Id *happydns.Identifier `json:"_id,omitempty"`
|
// Id for an already existing element.
|
||||||
Name string `json:"_comment"`
|
Id *happydns.Identifier `json:"_id,omitempty" swaggertype:"string"`
|
||||||
State int32 `json:"state"`
|
|
||||||
Recall string `json:"recall,omitempty"`
|
// User defined name of the element.
|
||||||
|
Name string `json:"_comment"`
|
||||||
|
|
||||||
|
// State is the desired form to shows next (starting at 0).
|
||||||
|
State int32 `json:"state"`
|
||||||
|
|
||||||
|
// Recall is the identifier for a saved FormState you want to retrieve.
|
||||||
|
Recall string `json:"recall,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func formDoState(cfg *config.Options, c *gin.Context, fs *FormState, data interface{}, defaultForm func(interface{}) *forms.CustomForm) (form *forms.CustomForm, d map[string]interface{}, err error) {
|
func formDoState(cfg *config.Options, c *gin.Context, fs *FormState, data interface{}, defaultForm func(interface{}) *forms.CustomForm) (form *forms.CustomForm, d map[string]interface{}, err error) {
|
||||||
|
|
|
@ -54,15 +54,31 @@ func declareProviderSettingsRoutes(cfg *config.Options, router *gin.RouterGroup)
|
||||||
|
|
||||||
type ProviderSettingsState struct {
|
type ProviderSettingsState struct {
|
||||||
FormState
|
FormState
|
||||||
happydns.Provider
|
happydns.Provider `json:"Provider" swaggertype:"object"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ProviderSettingsResponse struct {
|
type ProviderSettingsResponse struct {
|
||||||
Provider *happydns.Provider `json:"Provider,omitempty"`
|
Provider *happydns.Provider `json:"Provider,omitempty" swaggertype:"object"`
|
||||||
Values map[string]interface{} `json:"values,omitempty"`
|
Values map[string]interface{} `json:"values,omitempty"`
|
||||||
Form *forms.CustomForm `json:"form,omitempty"`
|
Form *forms.CustomForm `json:"form,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getProviderSettingsState creates or updates a Provider with human fillable forms.
|
||||||
|
// @Summary Assistant to Provider creation.
|
||||||
|
// @Schemes
|
||||||
|
// @Description This creates or updates a Provider with human fillable forms.
|
||||||
|
// @Tags provider_specs
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param providerType path string true "The provider's type"
|
||||||
|
// @Param body body ProviderSettingsState true "The current state of the Provider's settings, possibly empty (but not null)"
|
||||||
|
// @Security securitydefinitions.basic
|
||||||
|
// @Success 200 {object} ProviderSettingsResponse "The settings need more rafinement"
|
||||||
|
// @Success 200 {object} happydns.ProviderCombined "The Provider has been created with the given settings"
|
||||||
|
// @Failure 400 {object} happydns.Error "Invalid input"
|
||||||
|
// @Failure 401 {object} happydns.Error "Authentication failure"
|
||||||
|
// @Failure 404 {object} happydns.Error "Provider not found"
|
||||||
|
// @Router /providers/_specs/{providerType}/settings [post]
|
||||||
func getProviderSettingsState(cfg *config.Options, c *gin.Context) {
|
func getProviderSettingsState(cfg *config.Options, c *gin.Context) {
|
||||||
user := myUser(c)
|
user := myUser(c)
|
||||||
if user == nil {
|
if user == nil {
|
||||||
|
|
|
@ -54,6 +54,15 @@ func declareProviderSpecsRoutes(router *gin.RouterGroup) {
|
||||||
apiProviderSpecsRoutes.GET("", getProviderSpec)
|
apiProviderSpecsRoutes.GET("", getProviderSpec)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// listProviders returns the static list of usable providers in this happyDomain release.
|
||||||
|
// @Summary List all providers with which you can connect.
|
||||||
|
// @Schemes
|
||||||
|
// @Description This returns the static list of usable providers in this happyDomain release.
|
||||||
|
// @Tags provider_specs
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Success 200 {object} map[string]providers.ProviderInfos{} "The list"
|
||||||
|
// @Router /providers/_specs [get]
|
||||||
func listProviders(c *gin.Context) {
|
func listProviders(c *gin.Context) {
|
||||||
srcs := providers.GetProviders()
|
srcs := providers.GetProviders()
|
||||||
|
|
||||||
|
@ -65,6 +74,17 @@ func listProviders(c *gin.Context) {
|
||||||
c.JSON(http.StatusOK, ret)
|
c.JSON(http.StatusOK, ret)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getProviderSpecIcon returns the icon as image/png.
|
||||||
|
// @Summary Get the PNG icon.
|
||||||
|
// @Schemes
|
||||||
|
// @Description Return the icon as a image/png file for the given provider type.
|
||||||
|
// @Tags provider_specs
|
||||||
|
// @Accept json
|
||||||
|
// @Produce png
|
||||||
|
// @Param providerType path string true "The provider's type"
|
||||||
|
// @Success 200 {file} png
|
||||||
|
// @Failure 404 {object} happydns.Error "Provider type does not exist"
|
||||||
|
// @Router /providers/_specs/{providerType}/icon.png [get]
|
||||||
func getProviderSpecIcon(c *gin.Context) {
|
func getProviderSpecIcon(c *gin.Context) {
|
||||||
psid := string(c.Param("psid"))
|
psid := string(c.Param("psid"))
|
||||||
|
|
||||||
|
@ -91,10 +111,24 @@ func ProviderSpecsHandler(c *gin.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
type viewProviderSpec struct {
|
type viewProviderSpec struct {
|
||||||
Fields []*forms.Field `json:"fields,omitempty"`
|
// Fields describes the settings needed to configure the provider.
|
||||||
Capabilities []string `json:"capabilities,omitempty"`
|
Fields []*forms.Field `json:"fields,omitempty"`
|
||||||
|
|
||||||
|
// Capabilities exposes what the provider can do.
|
||||||
|
Capabilities []string `json:"capabilities,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getProviderSpec returns a description of the expected settings and the provider capabilities.
|
||||||
|
// @Summary Get the provider capabilities and expected settings.
|
||||||
|
// @Schemes
|
||||||
|
// @Description Return a description of the expected settings and the provider capabilities.
|
||||||
|
// @Tags provider_specs
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param providerType path string true "The provider's type"
|
||||||
|
// @Success 200 {object} viewProviderSpec
|
||||||
|
// @Failure 404 {object} happydns.Error "Provider type does not exist"
|
||||||
|
// @Router /providers/_specs/{providerType} [get]
|
||||||
func getProviderSpec(c *gin.Context) {
|
func getProviderSpec(c *gin.Context) {
|
||||||
src := c.MustGet("providertype").(happydns.Provider)
|
src := c.MustGet("providertype").(happydns.Provider)
|
||||||
|
|
||||||
|
|
|
@ -65,6 +65,18 @@ func declareProvidersRoutes(cfg *config.Options, router *gin.RouterGroup) {
|
||||||
apiProviderRoutes.GET("/domains", getDomainsHostedByProvider)
|
apiProviderRoutes.GET("/domains", getDomainsHostedByProvider)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getDomains retrieves all providers belonging to the user.
|
||||||
|
// @Summary Retrieve user's providers
|
||||||
|
// @Schemes
|
||||||
|
// @Description Retrieve all DNS providers belonging to the user.
|
||||||
|
// @Tags providers
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Security securitydefinitions.basic
|
||||||
|
// @Success 200 {array} happydns.Provider
|
||||||
|
// @Failure 401 {object} happydns.Error "Authentication failure"
|
||||||
|
// @Failure 404 {object} happydns.Error "Unable to retrieve user's domains"
|
||||||
|
// @Router /providers [get]
|
||||||
func getProviders(c *gin.Context) {
|
func getProviders(c *gin.Context) {
|
||||||
user := c.MustGet("LoggedUser").(*happydns.User)
|
user := c.MustGet("LoggedUser").(*happydns.User)
|
||||||
|
|
||||||
|
@ -171,12 +183,39 @@ func ProviderHandler(c *gin.Context) {
|
||||||
c.Next()
|
c.Next()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetProvider retrieves information about a given Provider owned by the user.
|
||||||
|
// @Summary Retrieve Provider information.
|
||||||
|
// @Schemes
|
||||||
|
// @Description Retrieve information in the database about a given Provider owned by the user.
|
||||||
|
// @Tags providers
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param providerId path string true "Provider identifier"
|
||||||
|
// @Security securitydefinitions.basic
|
||||||
|
// @Success 200 {object} happydns.ProviderCombined
|
||||||
|
// @Failure 401 {object} happydns.Error "Authentication failure"
|
||||||
|
// @Failure 404 {object} happydns.Error "Provider not found"
|
||||||
|
// @Router /providers/{providerId} [get]
|
||||||
func GetProvider(c *gin.Context) {
|
func GetProvider(c *gin.Context) {
|
||||||
provider := c.MustGet("provider").(*happydns.ProviderCombined)
|
provider := c.MustGet("provider").(*happydns.ProviderCombined)
|
||||||
|
|
||||||
c.JSON(http.StatusOK, provider)
|
c.JSON(http.StatusOK, provider)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// addProvider appends a new provider.
|
||||||
|
// @Summary Add a new provider
|
||||||
|
// @Schemes
|
||||||
|
// @Description Append a new provider for the user.
|
||||||
|
// @Tags providers
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param body body happydns.ProviderMinimal true "Provider to add"
|
||||||
|
// @Security securitydefinitions.basic
|
||||||
|
// @Success 200 {object} happydns.Provider
|
||||||
|
// @Failure 400 {object} happydns.Error "Error in received data"
|
||||||
|
// @Failure 401 {object} happydns.Error "Authentication failure"
|
||||||
|
// @Failure 500 {object} happydns.Error "Unable to retrieve current user's providers"
|
||||||
|
// @Router /providers [post]
|
||||||
func addProvider(c *gin.Context) {
|
func addProvider(c *gin.Context) {
|
||||||
user := c.MustGet("LoggedUser").(*happydns.User)
|
user := c.MustGet("LoggedUser").(*happydns.User)
|
||||||
|
|
||||||
|
@ -196,6 +235,23 @@ func addProvider(c *gin.Context) {
|
||||||
c.JSON(http.StatusOK, s)
|
c.JSON(http.StatusOK, s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UpdateProvider updates the information about a given Provider owned by the user.
|
||||||
|
// @Summary Update Provider information.
|
||||||
|
// @Schemes
|
||||||
|
// @Description Updates the information about a given Provider owned by the user.
|
||||||
|
// @Tags providers
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param providerId path string true "Provider identifier"
|
||||||
|
// @Param body body happydns.Provider true "The new object overriding the current provider"
|
||||||
|
// @Security securitydefinitions.basic
|
||||||
|
// @Success 200 {object} happydns.Provider
|
||||||
|
// @Failure 400 {object} happydns.Error "Invalid input"
|
||||||
|
// @Failure 400 {object} happydns.Error "Identifier changed"
|
||||||
|
// @Failure 401 {object} happydns.Error "Authentication failure"
|
||||||
|
// @Failure 404 {object} happydns.Error "Provider not found"
|
||||||
|
// @Failure 500 {object} happydns.Error "Database writing error"
|
||||||
|
// @Router /providers/{providerId} [put]
|
||||||
func UpdateProvider(c *gin.Context) {
|
func UpdateProvider(c *gin.Context) {
|
||||||
provider := c.MustGet("provider").(*happydns.ProviderCombined)
|
provider := c.MustGet("provider").(*happydns.ProviderCombined)
|
||||||
|
|
||||||
|
@ -217,6 +273,21 @@ func UpdateProvider(c *gin.Context) {
|
||||||
c.JSON(http.StatusOK, src)
|
c.JSON(http.StatusOK, src)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// deleteProvider removes a provider from the database.
|
||||||
|
// @Summary Delete a Provider.
|
||||||
|
// @Schemes
|
||||||
|
// @Description Delete a Provider from the database. It is required that no Domain are still managed by this Provider before calling this route.
|
||||||
|
// @Tags providers
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param providerId path string true "Provider identifier"
|
||||||
|
// @Security securitydefinitions.basic
|
||||||
|
// @Success 204 "Provider deleted"
|
||||||
|
// @Failure 400 {object} happydns.Error "Invalid input"
|
||||||
|
// @Failure 401 {object} happydns.Error "Authentication failure"
|
||||||
|
// @Failure 404 {object} happydns.Error "Provider not found"
|
||||||
|
// @Failure 500 {object} happydns.Error "Database writing error"
|
||||||
|
// @Router /providers/{providerId} [delete]
|
||||||
func deleteProvider(c *gin.Context) {
|
func deleteProvider(c *gin.Context) {
|
||||||
user := c.MustGet("LoggedUser").(*happydns.User)
|
user := c.MustGet("LoggedUser").(*happydns.User)
|
||||||
providermeta := c.MustGet("providermeta").(*happydns.ProviderMeta)
|
providermeta := c.MustGet("providermeta").(*happydns.ProviderMeta)
|
||||||
|
@ -245,6 +316,22 @@ func deleteProvider(c *gin.Context) {
|
||||||
c.JSON(http.StatusNoContent, nil)
|
c.JSON(http.StatusNoContent, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getDomainsHostedByProvider lists domains available to management from the given Provider.
|
||||||
|
// @Summary Lists manageable domains from the Provider.
|
||||||
|
// @Schemes
|
||||||
|
// @Description List domains available from the given Provider.
|
||||||
|
// @Tags providers
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param providerId path string true "Provider identifier"
|
||||||
|
// @Security securitydefinitions.basic
|
||||||
|
// @Success 200 {object} happydns.ProviderCombined
|
||||||
|
// @Failure 400 {object} happydns.Error "Unable to instantiate the provider"
|
||||||
|
// @Failure 400 {object} happydns.Error "The provider doesn't support domain listing"
|
||||||
|
// @Failure 400 {object} happydns.Error "Provider error"
|
||||||
|
// @Failure 401 {object} happydns.Error "Authentication failure"
|
||||||
|
// @Failure 404 {object} happydns.Error "Provider not found"
|
||||||
|
// @Router /providers/{providerId}/domains [get]
|
||||||
func getDomainsHostedByProvider(c *gin.Context) {
|
func getDomainsHostedByProvider(c *gin.Context) {
|
||||||
provider := c.MustGet("provider").(*happydns.ProviderCombined)
|
provider := c.MustGet("provider").(*happydns.ProviderCombined)
|
||||||
|
|
||||||
|
|
|
@ -51,11 +51,19 @@ func declareResolverRoutes(router *gin.RouterGroup) {
|
||||||
router.POST("/resolver", runResolver)
|
router.POST("/resolver", runResolver)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// resolverRequest holds the resolution parameters
|
||||||
type resolverRequest struct {
|
type resolverRequest struct {
|
||||||
Resolver string `json:"resolver"`
|
// Resolver is the name of the resolver to use (or local or custom).
|
||||||
Custom string `json:"custom,omitempty"`
|
Resolver string `json:"resolver"`
|
||||||
|
|
||||||
|
// Custom is the address to the recursive server to use.
|
||||||
|
Custom string `json:"custom,omitempty"`
|
||||||
|
|
||||||
|
// DomainName is the FQDN to resolve.
|
||||||
DomainName string `json:"domain"`
|
DomainName string `json:"domain"`
|
||||||
Type string `json:"type"`
|
|
||||||
|
// Type is the type of record to retrieve.
|
||||||
|
Type string `json:"type"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func resolverANYQuestion(client dns.Client, resolver string, dn string) (r *dns.Msg, err error) {
|
func resolverANYQuestion(client dns.Client, resolver string, dn string) (r *dns.Msg, err error) {
|
||||||
|
@ -105,6 +113,49 @@ func resolverQuestion(client dns.Client, resolver string, dn string, rrType uint
|
||||||
return r, err
|
return r, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DNSMsg is the documentation structur corresponding to dns.Msg
|
||||||
|
type DNSMsg struct {
|
||||||
|
// Question is the Question section of the DNS response.
|
||||||
|
Question []DNSQuestion
|
||||||
|
|
||||||
|
// Answer is the list of Answer records in the DNS response.
|
||||||
|
Answer []interface{} `swaggertype:"object"`
|
||||||
|
|
||||||
|
// Ns is the list of Authoritative records in the DNS response.
|
||||||
|
Ns []interface{} `swaggertype:"object"`
|
||||||
|
|
||||||
|
// Extra is the list of extra records in the DNS response.
|
||||||
|
Extra []interface{} `swaggertype:"object"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type DNSQuestion struct {
|
||||||
|
// Name is the domain name researched.
|
||||||
|
Name string
|
||||||
|
|
||||||
|
// Qtype is the type of record researched.
|
||||||
|
Qtype uint16
|
||||||
|
|
||||||
|
// Qclass is the class of record researched.
|
||||||
|
Qclass uint16
|
||||||
|
}
|
||||||
|
|
||||||
|
// runResolver performs a NS resolution for a given domain, with options.
|
||||||
|
// @Summary Perform a DNS resolution.
|
||||||
|
// @Schemes
|
||||||
|
// @Description Perform a NS resolution for a given domain, with options.
|
||||||
|
// @Tags resolver
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param body body resolverRequest true "Options to the resolution"
|
||||||
|
// @Success 200 {object} DNSMsg
|
||||||
|
// @Success 204 {object} happydns.Error "No content"
|
||||||
|
// @Failure 400 {object} happydns.Error "Invalid input"
|
||||||
|
// @Failure 401 {object} happydns.Error "Authentication failure"
|
||||||
|
// @Failure 403 {object} happydns.Error "The resolver refused to treat our request"
|
||||||
|
// @Failure 404 {object} happydns.Error "The domain doesn't exist"
|
||||||
|
// @Failure 406 {object} happydns.Error "The resolver returned an error"
|
||||||
|
// @Failure 500 {object} happydns.Error
|
||||||
|
// @Router /resolver [post]
|
||||||
func runResolver(c *gin.Context) {
|
func runResolver(c *gin.Context) {
|
||||||
var urr resolverRequest
|
var urr resolverRequest
|
||||||
if err := c.ShouldBindJSON(&urr); err != nil {
|
if err := c.ShouldBindJSON(&urr); err != nil {
|
||||||
|
|
|
@ -32,11 +32,38 @@
|
||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
swaggerfiles "github.com/swaggo/files"
|
||||||
|
ginSwagger "github.com/swaggo/gin-swagger"
|
||||||
|
|
||||||
"git.happydns.org/happydomain/config"
|
"git.happydns.org/happydomain/config"
|
||||||
|
docs "git.happydns.org/happydomain/docs"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// @title happyDomain API
|
||||||
|
// @version 0.1
|
||||||
|
// @description Finally a simple interface for domain names.
|
||||||
|
|
||||||
|
// @contact.name happyDomain team
|
||||||
|
// @contact.email contact+api@happydomain.org
|
||||||
|
|
||||||
|
// @license.name CeCILL Free Software License Agreement
|
||||||
|
// @license.url https://spdx.org/licenses/CECILL-2.1.html
|
||||||
|
|
||||||
|
// @host localhost:8081
|
||||||
|
// @BasePath /api
|
||||||
|
|
||||||
|
// @securityDefinitions.basic BasicAuth
|
||||||
|
|
||||||
|
// @securityDefinitions.apikey ApiKeyAuth
|
||||||
|
// @in header
|
||||||
|
// @name Authorization
|
||||||
|
// @description Description for what is this security definition being used
|
||||||
|
|
||||||
func DeclareRoutes(cfg *config.Options, router *gin.Engine) {
|
func DeclareRoutes(cfg *config.Options, router *gin.Engine) {
|
||||||
apiRoutes := router.Group("/api")
|
apiRoutes := router.Group("/api")
|
||||||
|
|
||||||
|
@ -54,4 +81,17 @@ func DeclareRoutes(cfg *config.Options, router *gin.Engine) {
|
||||||
declareProvidersRoutes(cfg, apiAuthRoutes)
|
declareProvidersRoutes(cfg, apiAuthRoutes)
|
||||||
declareProviderSettingsRoutes(cfg, apiAuthRoutes)
|
declareProviderSettingsRoutes(cfg, apiAuthRoutes)
|
||||||
declareUsersAuthRoutes(cfg, apiAuthRoutes)
|
declareUsersAuthRoutes(cfg, apiAuthRoutes)
|
||||||
|
|
||||||
|
// Expose Swagger
|
||||||
|
if cfg.ExternalURL != "" {
|
||||||
|
docs.SwaggerInfo.Host = cfg.ExternalURL[strings.Index(cfg.ExternalURL, "://")+3:]
|
||||||
|
} else {
|
||||||
|
docs.SwaggerInfo.Host = fmt.Sprintf("localhost%s", cfg.Bind[strings.Index(cfg.Bind, ":"):])
|
||||||
|
}
|
||||||
|
docs.SwaggerInfo.BasePath = "/api"
|
||||||
|
if cfg.BaseURL != "" {
|
||||||
|
docs.SwaggerInfo.BasePath = cfg.BaseURL + docs.SwaggerInfo.BasePath
|
||||||
|
}
|
||||||
|
router.GET("/swagger", func(c *gin.Context) { c.Redirect(http.StatusFound, "./swagger/index.html") })
|
||||||
|
router.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerfiles.Handler))
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,13 +53,31 @@ func declareServiceSettingsRoutes(cfg *config.Options, router *gin.RouterGroup)
|
||||||
|
|
||||||
type ServiceSettingsState struct {
|
type ServiceSettingsState struct {
|
||||||
FormState
|
FormState
|
||||||
happydns.Service
|
happydns.Service `json:"Service" swaggertype:"object"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ServiceSettingsResponse struct {
|
type ServiceSettingsResponse struct {
|
||||||
Services map[string][]*happydns.ServiceCombined `json:"services,omitempty"`
|
Services map[string][]*happydns.ServiceCombined `json:"services,omitempty"`
|
||||||
|
Values map[string]interface{} `json:"values,omitempty"`
|
||||||
|
Form *forms.CustomForm `json:"form,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getServiceSettingsState creates or updates a Service with human fillable forms.
|
||||||
|
// @Summary Assistant to Service creation.
|
||||||
|
// @Schemes
|
||||||
|
// @Description This creates or updates a Service with human fillable forms.
|
||||||
|
// @Tags service_specs
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param serviceType path string true "The service's type"
|
||||||
|
// @Param body body ServiceSettingsState true "The current state of the Service's parameters, possibly empty (but not null)"
|
||||||
|
// @Security securitydefinitions.basic
|
||||||
|
// @Success 200 {object} ServiceSettingsResponse "The settings need more rafinement"
|
||||||
|
// @Success 200 {object} happydns.ServiceCombined "The Service has been created with the given settings"
|
||||||
|
// @Failure 400 {object} happydns.Error "Invalid input"
|
||||||
|
// @Failure 401 {object} happydns.Error "Authentication failure"
|
||||||
|
// @Failure 404 {object} happydns.Error "Service not found"
|
||||||
|
// @Router /service/{serviceType} [post]
|
||||||
func getServiceSettingsState(cfg *config.Options, c *gin.Context) {
|
func getServiceSettingsState(cfg *config.Options, 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)
|
||||||
|
@ -118,7 +136,7 @@ func getServiceSettingsState(cfg *config.Options, c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.JSON(http.StatusOK, ProviderSettingsResponse{
|
c.JSON(http.StatusOK, ServiceSettingsResponse{
|
||||||
Form: form,
|
Form: form,
|
||||||
Values: p,
|
Values: p,
|
||||||
})
|
})
|
||||||
|
|
|
@ -54,6 +54,15 @@ func declareServiceSpecsRoutes(router *gin.RouterGroup) {
|
||||||
apiServiceSpecsRoutes.GET("", getServiceSpec)
|
apiServiceSpecsRoutes.GET("", getServiceSpec)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getServiceSpecs returns the static list of usable services in this happyDomain release.
|
||||||
|
// @Summary List all services with which you can connect.
|
||||||
|
// @Schemes
|
||||||
|
// @Description This returns the static list of usable services in this happyDomain release.
|
||||||
|
// @Tags service_specs
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Success 200 {object} map[string]svcs.ServiceInfos{} "The list"
|
||||||
|
// @Router /service_specs [get]
|
||||||
func getServiceSpecs(c *gin.Context) {
|
func getServiceSpecs(c *gin.Context) {
|
||||||
services := svcs.GetServices()
|
services := svcs.GetServices()
|
||||||
|
|
||||||
|
@ -65,6 +74,17 @@ func getServiceSpecs(c *gin.Context) {
|
||||||
c.JSON(http.StatusOK, ret)
|
c.JSON(http.StatusOK, ret)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getServiceSpecIcon returns the icon as image/png.
|
||||||
|
// @Summary Get the PNG icon.
|
||||||
|
// @Schemes
|
||||||
|
// @Description Return the icon as a image/png file for the given service type.
|
||||||
|
// @Tags service_specs
|
||||||
|
// @Accept json
|
||||||
|
// @Produce png
|
||||||
|
// @Param serviceType path string true "The service's type"
|
||||||
|
// @Success 200 {file} png
|
||||||
|
// @Failure 404 {object} happydns.Error "Service type does not exist"
|
||||||
|
// @Router /service_specs/{serviceType}/icon.png [get]
|
||||||
func getServiceSpecIcon(c *gin.Context) {
|
func getServiceSpecIcon(c *gin.Context) {
|
||||||
ssid := string(c.Param("ssid"))
|
ssid := string(c.Param("ssid"))
|
||||||
|
|
||||||
|
@ -144,6 +164,17 @@ func getSpecs(svcType reflect.Type) viewServiceSpec {
|
||||||
return viewServiceSpec{fields}
|
return viewServiceSpec{fields}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getServiceSpec returns a description of the expected fields.
|
||||||
|
// @Summary Get the service expected fields.
|
||||||
|
// @Schemes
|
||||||
|
// @Description Return a description of the expected fields.
|
||||||
|
// @Tags service_specs
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param serviceType path string true "The service's type"
|
||||||
|
// @Success 200 {object} viewServiceSpec
|
||||||
|
// @Failure 404 {object} happydns.Error "Service type does not exist"
|
||||||
|
// @Router /services/_specs/{serviceType} [get]
|
||||||
func getServiceSpec(c *gin.Context) {
|
func getServiceSpec(c *gin.Context) {
|
||||||
svctype := c.MustGet("servicetype").(reflect.Type)
|
svctype := c.MustGet("servicetype").(reflect.Type)
|
||||||
|
|
||||||
|
|
|
@ -1,92 +0,0 @@
|
||||||
// Copyright or © or Copr. happyDNS (2020)
|
|
||||||
//
|
|
||||||
// contact@happydomain.org
|
|
||||||
//
|
|
||||||
// This software is a computer program whose purpose is to provide a modern
|
|
||||||
// interface to interact with DNS systems.
|
|
||||||
//
|
|
||||||
// This software is governed by the CeCILL license under French law and abiding
|
|
||||||
// by the rules of distribution of free software. You can use, modify and/or
|
|
||||||
// redistribute the software under the terms of the CeCILL license as
|
|
||||||
// circulated by CEA, CNRS and INRIA at the following URL
|
|
||||||
// "http://www.cecill.info".
|
|
||||||
//
|
|
||||||
// As a counterpart to the access to the source code and rights to copy, modify
|
|
||||||
// and redistribute granted by the license, users are provided only with a
|
|
||||||
// limited warranty and the software's author, the holder of the economic
|
|
||||||
// rights, and the successive licensors have only limited liability.
|
|
||||||
//
|
|
||||||
// In this respect, the user's attention is drawn to the risks associated with
|
|
||||||
// loading, using, modifying and/or developing or reproducing the software by
|
|
||||||
// the user in light of its specific status of free software, that may mean
|
|
||||||
// that it is complicated to manipulate, and that also therefore means that it
|
|
||||||
// is reserved for developers and experienced professionals having in-depth
|
|
||||||
// computer knowledge. Users are therefore encouraged to load and test the
|
|
||||||
// software's suitability as regards their requirements in conditions enabling
|
|
||||||
// the security of their systems and/or data to be ensured and, more generally,
|
|
||||||
// to use and operate it in the same conditions as regards security.
|
|
||||||
//
|
|
||||||
// The fact that you are presently reading this means that you have had
|
|
||||||
// knowledge of the CeCILL license and that you accept its terms.
|
|
||||||
|
|
||||||
package api
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
|
|
||||||
"git.happydns.org/happydomain/model"
|
|
||||||
"git.happydns.org/happydomain/services"
|
|
||||||
"git.happydns.org/happydomain/storage"
|
|
||||||
)
|
|
||||||
|
|
||||||
func declareServiceRoutes(router *gin.RouterGroup) {
|
|
||||||
router.GET("/services", listServices)
|
|
||||||
//router.POST("/services", newService)
|
|
||||||
|
|
||||||
//router.POST("/domains/:domain/analyze", analyzeDomain)
|
|
||||||
}
|
|
||||||
|
|
||||||
func listServices(c *gin.Context) {
|
|
||||||
ret := map[string]svcs.ServiceInfos{}
|
|
||||||
|
|
||||||
for k, svc := range *svcs.GetServices() {
|
|
||||||
ret[k] = svc.Infos
|
|
||||||
}
|
|
||||||
|
|
||||||
c.JSON(http.StatusOK, ret)
|
|
||||||
}
|
|
||||||
|
|
||||||
func analyzeDomain(c *gin.Context) {
|
|
||||||
domain := c.MustGet("domain").(*happydns.Domain)
|
|
||||||
user := myUser(c)
|
|
||||||
if user == nil {
|
|
||||||
c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"errmsg": "User not defined"})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
provider, err := storage.MainStore.GetProvider(user, domain.IdProvider)
|
|
||||||
if err != nil {
|
|
||||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": fmt.Sprintf("Unable to get the related provider: %s", err.Error())})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
zone, err := provider.ImportZone(domain)
|
|
||||||
if err != nil {
|
|
||||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": fmt.Sprintf("Unable to import zone: %s", err.Error())})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
services, defaultTTL, err := svcs.AnalyzeZone(domain.DomainName, zone)
|
|
||||||
if err != nil {
|
|
||||||
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": fmt.Sprintf("An error occurs during analysis: %s", err.Error())})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
c.JSON(http.StatusOK, gin.H{
|
|
||||||
"services": services,
|
|
||||||
"defaultTTL": defaultTTL,
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -71,10 +71,17 @@ func declareAuthenticationRoutes(opts *config.Options, router *gin.RouterGroup)
|
||||||
}
|
}
|
||||||
|
|
||||||
type DisplayUser struct {
|
type DisplayUser struct {
|
||||||
Id happydns.Identifier `json:"id"`
|
// Id is the user identifier
|
||||||
Email string `json:"email"`
|
Id happydns.Identifier `json:"id" swaggertype:"string"`
|
||||||
CreatedAt time.Time `json:"created_at,omitempty"`
|
|
||||||
Settings happydns.UserSettings `json:"settings,omitempty"`
|
// Email is the user email.
|
||||||
|
Email string `json:"email"`
|
||||||
|
|
||||||
|
// CreatedAt stores the date of the account creation.
|
||||||
|
CreatedAt time.Time `json:"created_at,omitempty"`
|
||||||
|
|
||||||
|
// Settings holds the user configuration.
|
||||||
|
Settings happydns.UserSettings `json:"settings,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func currentUser(u *happydns.User) *DisplayUser {
|
func currentUser(u *happydns.User) *DisplayUser {
|
||||||
|
@ -86,6 +93,18 @@ func currentUser(u *happydns.User) *DisplayUser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// displayAuthToken returns the user information.
|
||||||
|
//
|
||||||
|
// @Summary User info.
|
||||||
|
// @Schemes
|
||||||
|
// @Description Retrieve information about the currently logged user.
|
||||||
|
// @Tags user_auth
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Security securitydefinitions.basic
|
||||||
|
// @Success 200 {object} DisplayUser
|
||||||
|
// @Failure 401 {object} happydns.Error "Authentication failure"
|
||||||
|
// @Router /auth [get]
|
||||||
func displayAuthToken(c *gin.Context) {
|
func displayAuthToken(c *gin.Context) {
|
||||||
user := c.MustGet("LoggedUser").(*happydns.User)
|
user := c.MustGet("LoggedUser").(*happydns.User)
|
||||||
|
|
||||||
|
@ -117,6 +136,17 @@ func displayNotAuthToken(opts *config.Options, c *gin.Context) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// logout closes the user session.
|
||||||
|
//
|
||||||
|
// @Summary Close session.
|
||||||
|
// @Schemes
|
||||||
|
// @Description Erase the HTTP-only cookie. This leads to user logout in its browser.
|
||||||
|
// @Tags user_auth
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Success 204 {null} null "Loged out"
|
||||||
|
// @Failure 401 {object} happydns.Error "Authentication failure"
|
||||||
|
// @Router /auth/logout [post]
|
||||||
func logout(opts *config.Options, c *gin.Context) {
|
func logout(opts *config.Options, c *gin.Context) {
|
||||||
c.SetCookie(
|
c.SetCookie(
|
||||||
COOKIE_NAME,
|
COOKIE_NAME,
|
||||||
|
@ -127,14 +157,30 @@ func logout(opts *config.Options, c *gin.Context) {
|
||||||
opts.DevProxy == "" && !strings.HasPrefix(opts.ExternalURL, "http://"),
|
opts.DevProxy == "" && !strings.HasPrefix(opts.ExternalURL, "http://"),
|
||||||
true,
|
true,
|
||||||
)
|
)
|
||||||
c.JSON(http.StatusNoContent, true)
|
c.Status(http.StatusNoContent)
|
||||||
}
|
}
|
||||||
|
|
||||||
type loginForm struct {
|
type loginForm struct {
|
||||||
Email string
|
// Email of the user.
|
||||||
|
Email string
|
||||||
|
|
||||||
|
// Password of the user.
|
||||||
Password string
|
Password string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// checkAuth validate user authentication and delivers a session token.
|
||||||
|
//
|
||||||
|
// @Summary Authenticate user.
|
||||||
|
// @Schemes
|
||||||
|
// @Description Validate user authentication and delivers a session token.
|
||||||
|
// @Tags user_auth
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param body body loginForm true "Login information"
|
||||||
|
// @Success 200 {object} DisplayUser "Login success"
|
||||||
|
// @Failure 401 {object} happydns.Error "Authentication failure"
|
||||||
|
// @Failure 500 {object} happydns.Error
|
||||||
|
// @Router /auth [post]
|
||||||
func checkAuth(opts *config.Options, c *gin.Context) {
|
func checkAuth(opts *config.Options, c *gin.Context) {
|
||||||
var lf loginForm
|
var lf loginForm
|
||||||
if err := c.ShouldBindJSON(&lf); err != nil {
|
if err := c.ShouldBindJSON(&lf); err != nil {
|
||||||
|
|
159
api/users.go
159
api/users.go
|
@ -93,16 +93,27 @@ func myUser(c *gin.Context) (user *happydns.User) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
type UploadedUser struct {
|
type UserRegistration struct {
|
||||||
Kind string
|
|
||||||
Email string
|
Email string
|
||||||
Password string
|
Password string
|
||||||
Language string `json:"lang,omitempty"`
|
Language string `json:"lang,omitempty"`
|
||||||
Newsletter bool `json:"wantReceiveUpdate,omitempty"`
|
Newsletter bool `json:"wantReceiveUpdate,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// registerUser checks and appends a user in the database.
|
||||||
|
// @Summary Register account.
|
||||||
|
// @Schemes
|
||||||
|
// @Description Register a new happyDomain account (when using internal authentication system).
|
||||||
|
// @Tags users
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param body body UserRegistration true "Account information"
|
||||||
|
// @Success 200 {object} happydns.User "The created user"
|
||||||
|
// @Failure 400 {object} happydns.Error "Invalid input"
|
||||||
|
// @Failure 500 {object} happydns.Error
|
||||||
|
// @Router /users [post]
|
||||||
func registerUser(opts *config.Options, c *gin.Context) {
|
func registerUser(opts *config.Options, c *gin.Context) {
|
||||||
var uu UploadedUser
|
var uu UserRegistration
|
||||||
err := c.ShouldBindJSON(&uu)
|
err := c.ShouldBindJSON(&uu)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("%s sends invalid User JSON: %s", c.ClientIP(), err.Error())
|
log.Printf("%s sends invalid User JSON: %s", c.ClientIP(), err.Error())
|
||||||
|
@ -150,8 +161,27 @@ func registerUser(opts *config.Options, c *gin.Context) {
|
||||||
c.JSON(http.StatusOK, user)
|
c.JSON(http.StatusOK, user)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type UserSpecialAction struct {
|
||||||
|
// Kind of special action to perform: "recovery" or "validation".
|
||||||
|
Kind string
|
||||||
|
|
||||||
|
// Email on which to perform actions.
|
||||||
|
Email string
|
||||||
|
}
|
||||||
|
|
||||||
|
// specialUserOperations performs account recovery.
|
||||||
|
// @Summary Account recovery.
|
||||||
|
// @Schemes
|
||||||
|
// @Description This will send an email to the user either to recover its account or with a new email validation link.
|
||||||
|
// @Tags users
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param body body UserSpecialAction true "Description of the action to perform and email of the user"
|
||||||
|
// @Success 200 {object} happydns.Error "Perhaps something happen"
|
||||||
|
// @Failure 500 {object} happydns.Error
|
||||||
|
// @Router /users [patch]
|
||||||
func specialUserOperations(opts *config.Options, c *gin.Context) {
|
func specialUserOperations(opts *config.Options, c *gin.Context) {
|
||||||
var uu UploadedUser
|
var uu UserSpecialAction
|
||||||
err := c.ShouldBindJSON(&uu)
|
err := c.ShouldBindJSON(&uu)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("%s sends invalid User JSON: %s", c.ClientIP(), err.Error())
|
log.Printf("%s sends invalid User JSON: %s", c.ClientIP(), err.Error())
|
||||||
|
@ -229,12 +259,41 @@ func getUser(c *gin.Context) {
|
||||||
c.JSON(http.StatusOK, user)
|
c.JSON(http.StatusOK, user)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getUserSettings gets the settings of the given user.
|
||||||
|
// @Summary Retrieve user's settings.
|
||||||
|
// @Schemes
|
||||||
|
// @Description Retrieve the user's settings.
|
||||||
|
// @Tags users
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param userId path string true "User identifier"
|
||||||
|
// @Security securitydefinitions.basic
|
||||||
|
// @Success 200 {object} happydns.UserSettings "User settings"
|
||||||
|
// @Failure 401 {object} happydns.Error "Authentication failure"
|
||||||
|
// @Failure 403 {object} happydns.Error "Not your account"
|
||||||
|
// @Router /users/{userId}/settings [get]
|
||||||
func getUserSettings(c *gin.Context) {
|
func getUserSettings(c *gin.Context) {
|
||||||
user := c.MustGet("user").(*happydns.User)
|
user := c.MustGet("user").(*happydns.User)
|
||||||
|
|
||||||
c.JSON(http.StatusOK, user.Settings)
|
c.JSON(http.StatusOK, user.Settings)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// changeUserSettings updates the settings of the given user.
|
||||||
|
// @Summary Update user's settings.
|
||||||
|
// @Schemes
|
||||||
|
// @Description Update the user's settings.
|
||||||
|
// @Tags users
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param userId path string true "User identifier"
|
||||||
|
// @Param body body happydns.UserSettings true "User settings"
|
||||||
|
// @Security securitydefinitions.basic
|
||||||
|
// @Success 200 {object} happydns.UserSettings "User settings"
|
||||||
|
// @Failure 400 {object} happydns.Error "Invalid input"
|
||||||
|
// @Failure 401 {object} happydns.Error "Authentication failure"
|
||||||
|
// @Failure 403 {object} happydns.Error "Not your account"
|
||||||
|
// @Failure 500 {object} happydns.Error
|
||||||
|
// @Router /users/{userId}/settings [post]
|
||||||
func changeUserSettings(c *gin.Context) {
|
func changeUserSettings(c *gin.Context) {
|
||||||
user := c.MustGet("user").(*happydns.User)
|
user := c.MustGet("user").(*happydns.User)
|
||||||
|
|
||||||
|
@ -262,6 +321,22 @@ type passwordForm struct {
|
||||||
PasswordConfirm string
|
PasswordConfirm string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// changePassword changes the password of the given account.
|
||||||
|
// @Summary Change password
|
||||||
|
// @Schemes
|
||||||
|
// @Description Change the password of the given account.
|
||||||
|
// @Tags users
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Security securitydefinitions.basic
|
||||||
|
// @Param userId path string true "User identifier"
|
||||||
|
// @Param body body passwordForm true "Password confirmation"
|
||||||
|
// @Success 204 {null} null
|
||||||
|
// @Failure 400 {object} happydns.Error "Invalid input"
|
||||||
|
// @Failure 401 {object} happydns.Error "Authentication failure"
|
||||||
|
// @Failure 403 {object} happydns.Error "Bad current password"
|
||||||
|
// @Failure 500 {object} happydns.Error
|
||||||
|
// @Router /users/{userId}/new_password [post]
|
||||||
func changePassword(opts *config.Options, c *gin.Context) {
|
func changePassword(opts *config.Options, c *gin.Context) {
|
||||||
user := c.MustGet("authuser").(*happydns.UserAuth)
|
user := c.MustGet("authuser").(*happydns.UserAuth)
|
||||||
|
|
||||||
|
@ -314,6 +389,22 @@ func changePassword(opts *config.Options, c *gin.Context) {
|
||||||
logout(opts, c)
|
logout(opts, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// deleteUser delete the account related to the given user.
|
||||||
|
// @Summary Drop account
|
||||||
|
// @Schemes
|
||||||
|
// @Description Delete the account related to the given user.
|
||||||
|
// @Tags users
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Security securitydefinitions.basic
|
||||||
|
// @Param userId path string true "User identifier"
|
||||||
|
// @Param body body passwordForm true "Password confirmation"
|
||||||
|
// @Success 204 {null} null
|
||||||
|
// @Failure 400 {object} happydns.Error "Invalid input"
|
||||||
|
// @Failure 401 {object} happydns.Error "Authentication failure"
|
||||||
|
// @Failure 403 {object} happydns.Error "Bad current password"
|
||||||
|
// @Failure 500 {object} happydns.Error
|
||||||
|
// @Router /users/{userId}/delete [post]
|
||||||
func deleteUser(opts *config.Options, c *gin.Context) {
|
func deleteUser(opts *config.Options, c *gin.Context) {
|
||||||
user := c.MustGet("authuser").(*happydns.UserAuth)
|
user := c.MustGet("authuser").(*happydns.UserAuth)
|
||||||
|
|
||||||
|
@ -408,9 +499,23 @@ func userAuthHandler(c *gin.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
type UploadedAddressValidation struct {
|
type UploadedAddressValidation struct {
|
||||||
|
// Key able to validate the email address.
|
||||||
Key string
|
Key string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// validateUserAddress validates a user address after registration.
|
||||||
|
// @Summary Validate e-mail address.
|
||||||
|
// @Schemes
|
||||||
|
// @Description This is the route called by the web interface in order to validate the e-mail address of the user.
|
||||||
|
// @Tags users
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param userId path string true "User identifier"
|
||||||
|
// @Param body body UploadedAddressValidation true "Validation form"
|
||||||
|
// @Success 204 {null} null "Email validated, you can now login"
|
||||||
|
// @Failure 400 {object} happydns.Error "Invalid input"
|
||||||
|
// @Failure 500 {object} happydns.Error
|
||||||
|
// @Router /users/{userId}/email [post]
|
||||||
func validateUserAddress(c *gin.Context) {
|
func validateUserAddress(c *gin.Context) {
|
||||||
user := c.MustGet("authuser").(*happydns.UserAuth)
|
user := c.MustGet("authuser").(*happydns.UserAuth)
|
||||||
|
|
||||||
|
@ -434,14 +539,30 @@ func validateUserAddress(c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.JSON(http.StatusNoContent, true)
|
c.Status(http.StatusNoContent)
|
||||||
}
|
}
|
||||||
|
|
||||||
type UploadedAccountRecovery struct {
|
type UploadedAccountRecovery struct {
|
||||||
Key string
|
// Key is the secret sent by email to the user.
|
||||||
|
Key string
|
||||||
|
|
||||||
|
// Password is the new password to use with this account.
|
||||||
Password string
|
Password string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// recoverUserAccount performs account recovery by reseting the password of the account.
|
||||||
|
// @Summary Reset password with link in email.
|
||||||
|
// @Schemes
|
||||||
|
// @Description This performs account recovery by reseting the password of the account.
|
||||||
|
// @Tags users
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param userId path string true "User identifier"
|
||||||
|
// @Param body body UploadedAccountRecovery true "Recovery form"
|
||||||
|
// @Success 204 {null} null "Recovery completed, you can now login with your new credentials"
|
||||||
|
// @Failure 400 {object} happydns.Error "Invalid input"
|
||||||
|
// @Failure 500 {object} happydns.Error
|
||||||
|
// @Router /users/{userId}/recovery [post]
|
||||||
func recoverUserAccount(c *gin.Context) {
|
func recoverUserAccount(c *gin.Context) {
|
||||||
user := c.MustGet("authuser").(*happydns.UserAuth)
|
user := c.MustGet("authuser").(*happydns.UserAuth)
|
||||||
|
|
||||||
|
@ -475,19 +596,41 @@ func recoverUserAccount(c *gin.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("%s: User recovered: %s", c.ClientIP(), user.Email)
|
log.Printf("%s: User recovered: %s", c.ClientIP(), user.Email)
|
||||||
c.JSON(http.StatusNoContent, true)
|
c.Status(http.StatusNoContent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getSession gets the content of the current user's session.
|
||||||
|
// @Summary Retrieve user's session content
|
||||||
|
// @Schemes
|
||||||
|
// @Description Get the content of the current user's session.
|
||||||
|
// @Tags users
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Security securitydefinitions.basic
|
||||||
|
// @Success 200 {object} happydns.Session
|
||||||
|
// @Failure 401 {object} happydns.Error "Authentication failure"
|
||||||
|
// @Router /sessions [get]
|
||||||
func getSession(c *gin.Context) {
|
func getSession(c *gin.Context) {
|
||||||
session := c.MustGet("MySession").(*happydns.Session)
|
session := c.MustGet("MySession").(*happydns.Session)
|
||||||
|
|
||||||
c.JSON(http.StatusOK, session)
|
c.JSON(http.StatusOK, session)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// clearSession removes the content of the current user's session.
|
||||||
|
// @Summary Remove user's session content
|
||||||
|
// @Schemes
|
||||||
|
// @Description Remove the content of the current user's session.
|
||||||
|
// @Tags users
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Security securitydefinitions.basic
|
||||||
|
// @Success 204 {null} null
|
||||||
|
// @Failure 401 {object} happydns.Error "Authentication failure"
|
||||||
|
// @Router /sessions [delete]
|
||||||
func clearSession(c *gin.Context) {
|
func clearSession(c *gin.Context) {
|
||||||
session := c.MustGet("MySession").(*happydns.Session)
|
session := c.MustGet("MySession").(*happydns.Session)
|
||||||
|
|
||||||
session.ClearSession()
|
session.ClearSession()
|
||||||
|
|
||||||
c.JSON(http.StatusOK, true)
|
c.Status(http.StatusNoContent)
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,10 +37,27 @@ import (
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
HDVersion Version
|
||||||
|
)
|
||||||
|
|
||||||
func DeclareVersionRoutes(router *gin.RouterGroup) {
|
func DeclareVersionRoutes(router *gin.RouterGroup) {
|
||||||
router.GET("/version", showVersion)
|
router.GET("/version", showVersion)
|
||||||
}
|
}
|
||||||
|
|
||||||
func showVersion(c *gin.Context) {
|
type Version struct {
|
||||||
c.JSON(http.StatusOK, gin.H{"version": 0.1})
|
Version string `json:"version"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// showVersion returns the current happyDomain version.
|
||||||
|
// @Summary Get happyDomain version
|
||||||
|
// @Schemes
|
||||||
|
// @Description Retrieve the current happyDomain version.
|
||||||
|
// @Tags version
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Success 200 {object} Version
|
||||||
|
// @Router /version [get]
|
||||||
|
func showVersion(c *gin.Context) {
|
||||||
|
c.JSON(http.StatusOK, HDVersion)
|
||||||
}
|
}
|
||||||
|
|
165
api/zones.go
165
api/zones.go
|
@ -125,13 +125,50 @@ func subdomainHandler(c *gin.Context) {
|
||||||
c.Next()
|
c.Next()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type zoneServices struct {
|
||||||
|
Services []*happydns.ServiceCombined `json:"services"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// getZoneSubdomain returns the services associated with a given subdomain.
|
||||||
|
// @Summary List services
|
||||||
|
// @Schemes
|
||||||
|
// @Description Returns the services associated with the given subdomain.
|
||||||
|
// @Tags zones
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Security securitydefinitions.basic
|
||||||
|
// @Param domainId path string true "Domain identifier"
|
||||||
|
// @Param zoneId path string true "Zone identifier"
|
||||||
|
// @Param subdomain path string true "Part of the subdomain considered for the service (@ for the root of the zone ; subdomain is relative to the root, do not include it)"
|
||||||
|
// @Success 200 {object} zoneServices
|
||||||
|
// @Failure 401 {object} happydns.Error "Authentication failure"
|
||||||
|
// @Failure 404 {object} happydns.Error "Domain or Zone not found"
|
||||||
|
// @Router /domains/{domainId}/zone/{zoneId}/{subdomain} [get]
|
||||||
func getZoneSubdomain(c *gin.Context) {
|
func getZoneSubdomain(c *gin.Context) {
|
||||||
zone := c.MustGet("zone").(*happydns.Zone)
|
zone := c.MustGet("zone").(*happydns.Zone)
|
||||||
subdomain := c.MustGet("subdomain").(string)
|
subdomain := c.MustGet("subdomain").(string)
|
||||||
|
|
||||||
c.JSON(http.StatusOK, gin.H{"services": zone.Services[subdomain]})
|
c.JSON(http.StatusOK, zoneServices{
|
||||||
|
Services: zone.Services[subdomain],
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// addZoneService adds a Service to the given subdomain of the Zone.
|
||||||
|
// @Summary Add a Service.
|
||||||
|
// @Schemes
|
||||||
|
// @Description Add a Service to the given subdomain of the Zone.
|
||||||
|
// @Tags zones
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Security securitydefinitions.basic
|
||||||
|
// @Param domainId path string true "Domain identifier"
|
||||||
|
// @Param zoneId path string true "Zone identifier"
|
||||||
|
// @Param subdomain path string true "Part of the subdomain considered for the service (@ for the root of the zone ; subdomain is relative to the root, do not include it)"
|
||||||
|
// @Success 200 {object} happydns.Zone
|
||||||
|
// @Failure 400 {object} happydns.Error "Invalid input"
|
||||||
|
// @Failure 401 {object} happydns.Error "Authentication failure"
|
||||||
|
// @Failure 404 {object} happydns.Error "Domain or Zone not found"
|
||||||
|
// @Router /domains/{domainId}/zone/{zoneId}/{subdomain}/services [post]
|
||||||
func addZoneService(c *gin.Context) {
|
func addZoneService(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)
|
||||||
|
@ -178,6 +215,22 @@ func serviceIdHandler(c *gin.Context) {
|
||||||
c.Next()
|
c.Next()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getServiceService retrieves the designated Service.
|
||||||
|
// @Summary Get the Service.
|
||||||
|
// @Schemes
|
||||||
|
// @Description Retrieve the designated Service.
|
||||||
|
// @Tags zones
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Security securitydefinitions.basic
|
||||||
|
// @Param domainId path string true "Domain identifier"
|
||||||
|
// @Param zoneId path string true "Zone identifier"
|
||||||
|
// @Param subdomain path string true "Part of the subdomain considered for the service (@ for the root of the zone ; subdomain is relative to the root, do not include it)"
|
||||||
|
// @Param serviceId path string true "Service identifier"
|
||||||
|
// @Success 200 {object} happydns.ServiceCombined
|
||||||
|
// @Failure 401 {object} happydns.Error "Authentication failure"
|
||||||
|
// @Failure 404 {object} happydns.Error "Domain or Zone not found"
|
||||||
|
// @Router /domains/{domainId}/zone/{zoneId}/{subdomain}/services/{serviceId} [get]
|
||||||
func getZoneService(c *gin.Context) {
|
func getZoneService(c *gin.Context) {
|
||||||
zone := c.MustGet("zone").(*happydns.Zone)
|
zone := c.MustGet("zone").(*happydns.Zone)
|
||||||
serviceid := c.MustGet("serviceid").([]byte)
|
serviceid := c.MustGet("serviceid").([]byte)
|
||||||
|
@ -186,6 +239,19 @@ func getZoneService(c *gin.Context) {
|
||||||
c.JSON(http.StatusOK, zone.FindSubdomainService(subdomain, serviceid))
|
c.JSON(http.StatusOK, zone.FindSubdomainService(subdomain, serviceid))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// retrieveZone retrieves the current zone deployed on the NS Provider.
|
||||||
|
// @Summary Retrieve the zone on the Provider.
|
||||||
|
// @Schemes
|
||||||
|
// @Description Retrieve the current zone deployed on the NS Provider.
|
||||||
|
// @Tags zones
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Security securitydefinitions.basic
|
||||||
|
// @Param domainId path string true "Domain identifier"
|
||||||
|
// @Success 200 {object} happydns.ZoneMeta "The new zone metadata"
|
||||||
|
// @Failure 401 {object} happydns.Error "Authentication failure"
|
||||||
|
// @Failure 404 {object} happydns.Error "Domain not found"
|
||||||
|
// @Router /domains/{domainId}/retrieve_zone [post]
|
||||||
func retrieveZone(c *gin.Context) {
|
func retrieveZone(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)
|
||||||
|
@ -285,6 +351,24 @@ func importZone(c *gin.Context) {
|
||||||
c.JSON(http.StatusOK, zone)
|
c.JSON(http.StatusOK, zone)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// diffZones computes the difference between the two zone identifiers given.
|
||||||
|
// @Summary Compute differences between zones.
|
||||||
|
// @Schemes
|
||||||
|
// @Description Compute the difference between the two zone identifiers given.
|
||||||
|
// @Tags zones
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Security securitydefinitions.basic
|
||||||
|
// @Param domainId path string true "Domain identifier"
|
||||||
|
// @Param zoneId1 path string true "Zone identifier to use as the old one. Currently only @ are expected, to use the currently deployed zone."
|
||||||
|
// @Param zoneId2 path string true "Zone identifier to use as the new one"
|
||||||
|
// @Success 200 {object} []string "Differences, reported as text, one diff per item"
|
||||||
|
// @Failure 400 {object} happydns.Error "Invalid input"
|
||||||
|
// @Failure 401 {object} happydns.Error "Authentication failure"
|
||||||
|
// @Failure 404 {object} happydns.Error "Domain not found"
|
||||||
|
// @Failure 500 {object} happydns.Error
|
||||||
|
// @Failure 501 {object} happydns.Error "Diff between to zone identifier, currently not supported"
|
||||||
|
// @Router /domains/{domainId}/diff_zones/{zoneId1}/{zoneId2} [post]
|
||||||
func diffZones(c *gin.Context) {
|
func diffZones(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)
|
||||||
|
@ -331,6 +415,23 @@ func diffZones(c *gin.Context) {
|
||||||
c.JSON(http.StatusOK, rrCorected)
|
c.JSON(http.StatusOK, rrCorected)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// applyZone performs the requested changes with the provider.
|
||||||
|
// @Summary Performs requested changes to the real zone.
|
||||||
|
// @Schemes
|
||||||
|
// @Description Perform the requested changes with the provider.
|
||||||
|
// @Tags zones
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Security securitydefinitions.basic
|
||||||
|
// @Param domainId path string true "Domain identifier"
|
||||||
|
// @Param zoneId path string true "Zone identifier"
|
||||||
|
// @Param body body []string true "Differences (from /diff_zones) to apply"
|
||||||
|
// @Success 200 {object} happydns.ZoneMeta "The new Zone metadata containing the current zone"
|
||||||
|
// @Failure 400 {object} happydns.Error "Invalid input"
|
||||||
|
// @Failure 401 {object} happydns.Error "Authentication failure"
|
||||||
|
// @Failure 404 {object} happydns.Error "Domain or Zone not found"
|
||||||
|
// @Failure 500 {object} happydns.Error
|
||||||
|
// @Router /domains/{domainId}/zone/{zoneId}/apply_changes [post]
|
||||||
func applyZone(c *gin.Context) {
|
func applyZone(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)
|
||||||
|
@ -422,6 +523,20 @@ func applyZone(c *gin.Context) {
|
||||||
c.JSON(http.StatusOK, newZone.ZoneMeta)
|
c.JSON(http.StatusOK, newZone.ZoneMeta)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// viewZone creates a flatten export of the zone.
|
||||||
|
// @Summary Get flatten zone file.
|
||||||
|
// @Schemes
|
||||||
|
// @Description Create a flatten export of the zone that can be read as a BIND-like file.
|
||||||
|
// @Tags zones
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Security securitydefinitions.basic
|
||||||
|
// @Param domainId path string true "Domain identifier"
|
||||||
|
// @Param zoneId path string true "Zone identifier"
|
||||||
|
// @Success 200 {object} string "The exported zone file (with initial and leading JSON quote)"
|
||||||
|
// @Failure 401 {object} happydns.Error "Authentication failure"
|
||||||
|
// @Failure 404 {object} happydns.Error "Domain or Zone not found"
|
||||||
|
// @Router /domains/{domainId}/zone/{zoneId}/view [post]
|
||||||
func viewZone(c *gin.Context) {
|
func viewZone(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)
|
||||||
|
@ -435,6 +550,21 @@ func viewZone(c *gin.Context) {
|
||||||
c.JSON(http.StatusOK, ret)
|
c.JSON(http.StatusOK, ret)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UpdateZoneService adds or updates a service inside the given Zone.
|
||||||
|
// @Summary Add or update a Service.
|
||||||
|
// @Schemes
|
||||||
|
// @Description Add or update a Service inside the given Zone.
|
||||||
|
// @Tags zones
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Security securitydefinitions.basic
|
||||||
|
// @Param domainId path string true "Domain identifier"
|
||||||
|
// @Param zoneId path string true "Zone identifier"
|
||||||
|
// @Param body body happydns.ServiceCombined true "Service to update"
|
||||||
|
// @Success 200 {object} happydns.Zone
|
||||||
|
// @Failure 401 {object} happydns.Error "Authentication failure"
|
||||||
|
// @Failure 404 {object} happydns.Error "Domain or Zone not found"
|
||||||
|
// @Router /domains/{domainId}/zone/{zoneId} [patch]
|
||||||
func UpdateZoneService(c *gin.Context) {
|
func UpdateZoneService(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)
|
||||||
|
@ -465,6 +595,23 @@ func UpdateZoneService(c *gin.Context) {
|
||||||
c.JSON(http.StatusOK, zone)
|
c.JSON(http.StatusOK, zone)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// deleteZoneService drops the given Service.
|
||||||
|
// @Summary Drop the given Service.
|
||||||
|
// @Schemes
|
||||||
|
// @Description Drop the given Service.
|
||||||
|
// @Tags zones
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Security securitydefinitions.basic
|
||||||
|
// @Param domainId path string true "Domain identifier"
|
||||||
|
// @Param zoneId path string true "Zone identifier"
|
||||||
|
// @Param subdomain path string true "Part of the subdomain considered for the service (@ for the root of the zone ; subdomain is relative to the root, do not include it)"
|
||||||
|
// @Param serviceId path string true "Service identifier"
|
||||||
|
// @Success 200 {object} happydns.Zone
|
||||||
|
// @Failure 400 {object} happydns.Error "Invalid input"
|
||||||
|
// @Failure 401 {object} happydns.Error "Authentication failure"
|
||||||
|
// @Failure 404 {object} happydns.Error "Domain or Zone not found"
|
||||||
|
// @Router /domains/{domainId}/zone/{zoneId}/{subdomain}/services/{serviceId} [delete]
|
||||||
func deleteZoneService(c *gin.Context) {
|
func deleteZoneService(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)
|
||||||
|
@ -494,6 +641,22 @@ type serviceRecord struct {
|
||||||
Fields *dns.RR `json:"fields,omitempty"`
|
Fields *dns.RR `json:"fields,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getServiceRecords retrieves the records that will be generated by a Service.
|
||||||
|
// @Summary Get the records for a Service.
|
||||||
|
// @Schemes
|
||||||
|
// @Description Retrieve the records that will be generated by a Service.
|
||||||
|
// @Tags zones
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Security securitydefinitions.basic
|
||||||
|
// @Param domainId path string true "Domain identifier"
|
||||||
|
// @Param zoneId path string true "Zone identifier"
|
||||||
|
// @Param subdomain path string true "Part of the subdomain considered for the service (@ for the root of the zone ; subdomain is relative to the root, do not include it)"
|
||||||
|
// @Param serviceId path string true "Service identifier"
|
||||||
|
// @Success 200 {object} happydns.Zone
|
||||||
|
// @Failure 401 {object} happydns.Error "Authentication failure"
|
||||||
|
// @Failure 404 {object} happydns.Error "Domain or Zone not found"
|
||||||
|
// @Router /domains/{domainId}/zone/{zoneId}/{subdomain}/services/{serviceId}/records [get]
|
||||||
func getServiceRecords(c *gin.Context) {
|
func getServiceRecords(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)
|
||||||
|
|
|
@ -33,3 +33,4 @@ package main
|
||||||
|
|
||||||
//go:generate go run generators/gen_icon.go providers providers
|
//go:generate go run generators/gen_icon.go providers providers
|
||||||
//go:generate go run generators/gen_icon.go services svcs
|
//go:generate go run generators/gen_icon.go services svcs
|
||||||
|
//go:generate swag init --generalInfo api/routes.go
|
||||||
|
|
13
go.mod
13
go.mod
|
@ -27,7 +27,10 @@ require (
|
||||||
github.com/Azure/go-autorest/autorest/to v0.4.0 // indirect
|
github.com/Azure/go-autorest/autorest/to v0.4.0 // indirect
|
||||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0 // indirect
|
github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0 // indirect
|
||||||
github.com/G-Core/gcore-dns-sdk-go v0.2.6 // indirect
|
github.com/G-Core/gcore-dns-sdk-go v0.2.6 // indirect
|
||||||
|
github.com/KyleBanks/depth v1.2.1 // indirect
|
||||||
github.com/PuerkitoBio/goquery v1.8.1 // indirect
|
github.com/PuerkitoBio/goquery v1.8.1 // indirect
|
||||||
|
github.com/PuerkitoBio/purell v1.1.1 // indirect
|
||||||
|
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
|
||||||
github.com/akamai/AkamaiOPEN-edgegrid-golang v1.2.2 // indirect
|
github.com/akamai/AkamaiOPEN-edgegrid-golang v1.2.2 // indirect
|
||||||
github.com/andybalholm/cascadia v1.3.1 // indirect
|
github.com/andybalholm/cascadia v1.3.1 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2 v1.18.1 // indirect
|
github.com/aws/aws-sdk-go-v2 v1.18.1 // indirect
|
||||||
|
@ -57,6 +60,10 @@ require (
|
||||||
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
|
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
|
||||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||||
github.com/go-gandi/go-gandi v0.6.0 // indirect
|
github.com/go-gandi/go-gandi v0.6.0 // indirect
|
||||||
|
github.com/go-openapi/jsonpointer v0.19.5 // indirect
|
||||||
|
github.com/go-openapi/jsonreference v0.19.6 // indirect
|
||||||
|
github.com/go-openapi/spec v0.20.4 // indirect
|
||||||
|
github.com/go-openapi/swag v0.19.15 // indirect
|
||||||
github.com/go-playground/locales v0.14.1 // indirect
|
github.com/go-playground/locales v0.14.1 // indirect
|
||||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||||
github.com/go-playground/validator/v10 v10.14.0 // indirect
|
github.com/go-playground/validator/v10 v10.14.0 // indirect
|
||||||
|
@ -76,11 +83,13 @@ require (
|
||||||
github.com/hexonet/go-sdk/v3 v3.5.4 // indirect
|
github.com/hexonet/go-sdk/v3 v3.5.4 // indirect
|
||||||
github.com/jinzhu/copier v0.3.5 // indirect
|
github.com/jinzhu/copier v0.3.5 // indirect
|
||||||
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
||||||
|
github.com/josharian/intern v1.0.0 // indirect
|
||||||
github.com/json-iterator/go v1.1.12 // indirect
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
github.com/klauspost/cpuid/v2 v2.2.4 // indirect
|
github.com/klauspost/cpuid/v2 v2.2.4 // indirect
|
||||||
github.com/kolo/xmlrpc v0.0.0-20220921171641-a4b6fa1dd06b // indirect
|
github.com/kolo/xmlrpc v0.0.0-20220921171641-a4b6fa1dd06b // indirect
|
||||||
github.com/kylelemons/godebug v1.1.0 // indirect
|
github.com/kylelemons/godebug v1.1.0 // indirect
|
||||||
github.com/leodido/go-urn v1.2.4 // indirect
|
github.com/leodido/go-urn v1.2.4 // indirect
|
||||||
|
github.com/mailru/easyjson v0.7.6 // indirect
|
||||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.19 // indirect
|
github.com/mattn/go-isatty v0.0.19 // indirect
|
||||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||||
|
@ -103,6 +112,9 @@ require (
|
||||||
github.com/sirupsen/logrus v1.9.0 // indirect
|
github.com/sirupsen/logrus v1.9.0 // indirect
|
||||||
github.com/softlayer/softlayer-go v1.1.2 // indirect
|
github.com/softlayer/softlayer-go v1.1.2 // indirect
|
||||||
github.com/softlayer/xmlrpc v0.0.0-20200409220501-5f089df7cb7e // indirect
|
github.com/softlayer/xmlrpc v0.0.0-20200409220501-5f089df7cb7e // indirect
|
||||||
|
github.com/swaggo/files v1.0.1 // indirect
|
||||||
|
github.com/swaggo/gin-swagger v1.6.0 // indirect
|
||||||
|
github.com/swaggo/swag v1.16.1 // indirect
|
||||||
github.com/transip/gotransip/v6 v6.20.0 // indirect
|
github.com/transip/gotransip/v6 v6.20.0 // indirect
|
||||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||||
github.com/ugorji/go/codec v1.2.11 // indirect
|
github.com/ugorji/go/codec v1.2.11 // indirect
|
||||||
|
@ -128,6 +140,7 @@ require (
|
||||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||||
gopkg.in/mail.v2 v2.3.1 // indirect
|
gopkg.in/mail.v2 v2.3.1 // indirect
|
||||||
gopkg.in/ns1/ns1-go.v2 v2.7.4 // indirect
|
gopkg.in/ns1/ns1-go.v2 v2.7.4 // indirect
|
||||||
|
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
moul.io/http2curl v1.0.0 // indirect
|
moul.io/http2curl v1.0.0 // indirect
|
||||||
)
|
)
|
||||||
|
|
34
go.sum
34
go.sum
|
@ -27,8 +27,14 @@ github.com/G-Core/gcore-dns-sdk-go v0.2.3 h1:WODi+qWlZyF7E7SH8rq/DCACa/Zhsuhu1h0
|
||||||
github.com/G-Core/gcore-dns-sdk-go v0.2.3/go.mod h1:TM+VaDvBPObF+x085lS3i0kc2OPAkuW2c4Leg7Pe6jI=
|
github.com/G-Core/gcore-dns-sdk-go v0.2.3/go.mod h1:TM+VaDvBPObF+x085lS3i0kc2OPAkuW2c4Leg7Pe6jI=
|
||||||
github.com/G-Core/gcore-dns-sdk-go v0.2.6 h1:R82ANd7BnhIe2mV/12Ebdx9QYVl2++E4kfDIu97JEOk=
|
github.com/G-Core/gcore-dns-sdk-go v0.2.6 h1:R82ANd7BnhIe2mV/12Ebdx9QYVl2++E4kfDIu97JEOk=
|
||||||
github.com/G-Core/gcore-dns-sdk-go v0.2.6/go.mod h1:KliUjfPonDvXyAGNiuO+MYVG/7lmWHZ+4Hi0sPxgOjg=
|
github.com/G-Core/gcore-dns-sdk-go v0.2.6/go.mod h1:KliUjfPonDvXyAGNiuO+MYVG/7lmWHZ+4Hi0sPxgOjg=
|
||||||
|
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
|
||||||
|
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
|
||||||
github.com/PuerkitoBio/goquery v1.8.1 h1:uQxhNlArOIdbrH1tr0UXwdVFgDcZDrZVdcpygAcwmWM=
|
github.com/PuerkitoBio/goquery v1.8.1 h1:uQxhNlArOIdbrH1tr0UXwdVFgDcZDrZVdcpygAcwmWM=
|
||||||
github.com/PuerkitoBio/goquery v1.8.1/go.mod h1:Q8ICL1kNUJ2sXGoAhPGUdYDJvgQgHzJsnnd3H7Ho5jQ=
|
github.com/PuerkitoBio/goquery v1.8.1/go.mod h1:Q8ICL1kNUJ2sXGoAhPGUdYDJvgQgHzJsnnd3H7Ho5jQ=
|
||||||
|
github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
|
||||||
|
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||||
|
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
|
||||||
|
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||||
github.com/akamai/AkamaiOPEN-edgegrid-golang v1.2.2 h1:F1j7z+/DKEsYqZNoxC6wvfmaiDneLsQOFQmuq9NADSY=
|
github.com/akamai/AkamaiOPEN-edgegrid-golang v1.2.2 h1:F1j7z+/DKEsYqZNoxC6wvfmaiDneLsQOFQmuq9NADSY=
|
||||||
github.com/akamai/AkamaiOPEN-edgegrid-golang v1.2.2/go.mod h1:QlXr/TrICfQ/ANa76sLeQyhAJyNR9sEcfNuZBkY9jgY=
|
github.com/akamai/AkamaiOPEN-edgegrid-golang v1.2.2/go.mod h1:QlXr/TrICfQ/ANa76sLeQyhAJyNR9sEcfNuZBkY9jgY=
|
||||||
github.com/andybalholm/cascadia v1.3.1 h1:nhxRkql1kdYCc8Snf7D5/D3spOX+dBgjA6u8x004T2c=
|
github.com/andybalholm/cascadia v1.3.1 h1:nhxRkql1kdYCc8Snf7D5/D3spOX+dBgjA6u8x004T2c=
|
||||||
|
@ -152,6 +158,16 @@ github.com/go-gandi/go-gandi v0.6.0 h1:RgFoevggRRp7hF9XsOmWmtwbUg2axhe2ygEdd6Mts
|
||||||
github.com/go-gandi/go-gandi v0.6.0/go.mod h1:9NoYyfWCjFosClPiWjkbbRK5UViaZ4ctpT8/pKSSFlw=
|
github.com/go-gandi/go-gandi v0.6.0/go.mod h1:9NoYyfWCjFosClPiWjkbbRK5UViaZ4ctpT8/pKSSFlw=
|
||||||
github.com/go-mail/mail v2.3.1+incompatible h1:UzNOn0k5lpfVtO31cK3hn6I4VEVGhe3lX8AJBAxXExM=
|
github.com/go-mail/mail v2.3.1+incompatible h1:UzNOn0k5lpfVtO31cK3hn6I4VEVGhe3lX8AJBAxXExM=
|
||||||
github.com/go-mail/mail v2.3.1+incompatible/go.mod h1:VPWjmmNyRsWXQZHVHT3g0YbIINUkSmuKOiLIDkWbL6M=
|
github.com/go-mail/mail v2.3.1+incompatible/go.mod h1:VPWjmmNyRsWXQZHVHT3g0YbIINUkSmuKOiLIDkWbL6M=
|
||||||
|
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||||
|
github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY=
|
||||||
|
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||||
|
github.com/go-openapi/jsonreference v0.19.6 h1:UBIxjkht+AWIgYzCDSv2GN+E/togfwXUJFRTWhl2Jjs=
|
||||||
|
github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns=
|
||||||
|
github.com/go-openapi/spec v0.20.4 h1:O8hJrt0UMnhHcluhIdUgCLRWyM2x7QkBXRvOs7m+O1M=
|
||||||
|
github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I=
|
||||||
|
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||||
|
github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyrCM=
|
||||||
|
github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
|
||||||
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
||||||
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
||||||
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
||||||
|
@ -253,6 +269,8 @@ github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9Y
|
||||||
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
|
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
|
||||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
|
github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
|
||||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
|
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
|
||||||
|
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||||
|
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||||
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
|
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
|
||||||
|
@ -264,6 +282,7 @@ github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8t
|
||||||
github.com/kolo/xmlrpc v0.0.0-20220921171641-a4b6fa1dd06b h1:udzkj9S/zlT5X367kqJis0QP7YMxobob6zhzq6Yre00=
|
github.com/kolo/xmlrpc v0.0.0-20220921171641-a4b6fa1dd06b h1:udzkj9S/zlT5X367kqJis0QP7YMxobob6zhzq6Yre00=
|
||||||
github.com/kolo/xmlrpc v0.0.0-20220921171641-a4b6fa1dd06b/go.mod h1:pcaDhQK0/NJZEvtCO0qQPPropqV0sJOJ6YW7X+9kRwM=
|
github.com/kolo/xmlrpc v0.0.0-20220921171641-a4b6fa1dd06b/go.mod h1:pcaDhQK0/NJZEvtCO0qQPPropqV0sJOJ6YW7X+9kRwM=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
|
@ -275,6 +294,10 @@ github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w=
|
||||||
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
|
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
|
||||||
github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
|
github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
|
||||||
github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
|
github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
|
||||||
|
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||||
|
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||||
|
github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA=
|
||||||
|
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||||
|
@ -371,6 +394,12 @@ github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o
|
||||||
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
|
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
|
||||||
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||||
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||||
|
github.com/swaggo/files v1.0.1 h1:J1bVJ4XHZNq0I46UU90611i9/YzdrF7x92oX1ig5IdE=
|
||||||
|
github.com/swaggo/files v1.0.1/go.mod h1:0qXmMNH6sXNf+73t65aKeB+ApmgxdnkQzVTAj2uaMUg=
|
||||||
|
github.com/swaggo/gin-swagger v1.6.0 h1:y8sxvQ3E20/RCyrXeFfg60r6H0Z+SwpTjMYsMm+zy8M=
|
||||||
|
github.com/swaggo/gin-swagger v1.6.0/go.mod h1:BG00cCEy294xtVpyIAHG6+e2Qzj/xKlRdOqDkvq0uzo=
|
||||||
|
github.com/swaggo/swag v1.16.1 h1:fTNRhKstPKxcnoKsytm4sahr8FaYzUcT7i1/3nd/fBg=
|
||||||
|
github.com/swaggo/swag v1.16.1/go.mod h1:9/LMvHycG3NFHfR6LwvikHv5iFvmPADQ359cKikGxto=
|
||||||
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
|
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
|
||||||
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
|
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
|
||||||
github.com/transip/gotransip/v6 v6.20.0 h1:AuvwyOZ51f2brzMbTqlRy/wmaM3kF7Vx5Wds8xcDflY=
|
github.com/transip/gotransip/v6 v6.20.0 h1:AuvwyOZ51f2brzMbTqlRy/wmaM3kF7Vx5Wds8xcDflY=
|
||||||
|
@ -437,6 +466,7 @@ golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81R
|
||||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
|
golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM=
|
||||||
golang.org/x/net v0.0.0-20210916014120-12bc252f5db8/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20210916014120-12bc252f5db8/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||||
|
@ -473,6 +503,7 @@ golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
@ -569,6 +600,7 @@ google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqw
|
||||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk=
|
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk=
|
||||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk=
|
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||||
|
@ -591,7 +623,9 @@ gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||||
|
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
|
5
main.go
5
main.go
|
@ -42,6 +42,7 @@ import (
|
||||||
|
|
||||||
"github.com/fatih/color"
|
"github.com/fatih/color"
|
||||||
|
|
||||||
|
"git.happydns.org/happydomain/api"
|
||||||
"git.happydns.org/happydomain/config"
|
"git.happydns.org/happydomain/config"
|
||||||
"git.happydns.org/happydomain/internal/app"
|
"git.happydns.org/happydomain/internal/app"
|
||||||
"git.happydns.org/happydomain/storage"
|
"git.happydns.org/happydomain/storage"
|
||||||
|
@ -58,6 +59,10 @@ var (
|
||||||
func main() {
|
func main() {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
|
api.HDVersion = api.Version{
|
||||||
|
Version: Version,
|
||||||
|
}
|
||||||
|
|
||||||
log.Println("This is happyDomain", Version)
|
log.Println("This is happyDomain", Version)
|
||||||
rand.Seed(time.Now().UTC().UnixNano())
|
rand.Seed(time.Now().UTC().UnixNano())
|
||||||
|
|
||||||
|
|
|
@ -35,17 +35,27 @@ import (
|
||||||
"github.com/miekg/dns"
|
"github.com/miekg/dns"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// DomainMinimal is used for swagger documentation as Domain add.
|
||||||
|
type DomainMinimal struct {
|
||||||
|
// IsProvider is the identifier of the Provider used to access and edit the
|
||||||
|
// Domain.
|
||||||
|
IdProvider Identifier `json:"id_provider" swaggertype:"string"`
|
||||||
|
|
||||||
|
// DomainName is the FQDN of the managed Domain.
|
||||||
|
DomainName string `json:"domain"`
|
||||||
|
}
|
||||||
|
|
||||||
// Domain holds information about a domain name own by a User.
|
// Domain holds information about a domain name own by a User.
|
||||||
type Domain struct {
|
type Domain struct {
|
||||||
// Id is the Domain's identifier in the database.
|
// Id is the Domain's identifier in the database.
|
||||||
Id Identifier `json:"id"`
|
Id Identifier `json:"id" swaggertype:"string"`
|
||||||
|
|
||||||
// IdUser is the identifier of the Domain's Owner.
|
// IdUser is the identifier of the Domain's Owner.
|
||||||
IdUser Identifier `json:"id_owner"`
|
IdUser Identifier `json:"id_owner" swaggertype:"string"`
|
||||||
|
|
||||||
// IsProvider is the identifier of the Provider used to access and edit the
|
// IsProvider is the identifier of the Provider used to access and edit the
|
||||||
// Domain.
|
// Domain.
|
||||||
IdProvider Identifier `json:"id_provider"`
|
IdProvider Identifier `json:"id_provider" swaggertype:"string"`
|
||||||
|
|
||||||
// DomainName is the FQDN of the managed Domain.
|
// DomainName is the FQDN of the managed Domain.
|
||||||
DomainName string `json:"domain"`
|
DomainName string `json:"domain"`
|
||||||
|
@ -55,7 +65,7 @@ type Domain struct {
|
||||||
|
|
||||||
// ZoneHistory are the identifiers to the Zone attached to the current
|
// ZoneHistory are the identifiers to the Zone attached to the current
|
||||||
// Domain.
|
// Domain.
|
||||||
ZoneHistory []Identifier `json:"zone_history"`
|
ZoneHistory []Identifier `json:"zone_history" swaggertype:"array,string"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Domains is an array of Domain.
|
// Domains is an array of Domain.
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
package happydns
|
||||||
|
|
||||||
|
type Error struct {
|
||||||
|
// Err describe the error to display to the user.
|
||||||
|
Err string `json:"errmsg"`
|
||||||
|
}
|
|
@ -46,16 +46,27 @@ type Provider interface {
|
||||||
DNSControlName() string
|
DNSControlName() string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ProviderMinimal is used for swagger documentation as Provider add.
|
||||||
|
type ProviderMinimal struct {
|
||||||
|
// Type is the string representation of the Provider's type.
|
||||||
|
Type string `json:"_srctype"`
|
||||||
|
|
||||||
|
Provider
|
||||||
|
|
||||||
|
// Comment is a string that helps user to distinguish the Provider.
|
||||||
|
Comment string `json:"_comment,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
// ProviderMeta holds the metadata associated to a Provider.
|
// ProviderMeta holds the metadata associated to a Provider.
|
||||||
type ProviderMeta struct {
|
type ProviderMeta struct {
|
||||||
// Type is the string representation of the Provider's type.
|
// Type is the string representation of the Provider's type.
|
||||||
Type string `json:"_srctype"`
|
Type string `json:"_srctype"`
|
||||||
|
|
||||||
// Id is the Provider's identifier.
|
// Id is the Provider's identifier.
|
||||||
Id Identifier `json:"_id"`
|
Id Identifier `json:"_id" swaggertype:"string"`
|
||||||
|
|
||||||
// OwnerId is the User's identifier for the current Provider.
|
// OwnerId is the User's identifier for the current Provider.
|
||||||
OwnerId Identifier `json:"_ownerid"`
|
OwnerId Identifier `json:"_ownerid" swaggertype:"string"`
|
||||||
|
|
||||||
// Comment is a string that helps user to distinguish the Provider.
|
// Comment is a string that helps user to distinguish the Provider.
|
||||||
Comment string `json:"_comment,omitempty"`
|
Comment string `json:"_comment,omitempty"`
|
||||||
|
|
|
@ -57,10 +57,10 @@ type ServiceMeta struct {
|
||||||
Type string `json:"_svctype"`
|
Type string `json:"_svctype"`
|
||||||
|
|
||||||
// Id is the Service's identifier.
|
// Id is the Service's identifier.
|
||||||
Id Identifier `json:"_id,omitempty"`
|
Id Identifier `json:"_id,omitempty" swaggertype:"string"`
|
||||||
|
|
||||||
// OwnerId is the User's identifier for the current Service.
|
// OwnerId is the User's identifier for the current Service.
|
||||||
OwnerId Identifier `json:"_ownerid,omitempty"`
|
OwnerId Identifier `json:"_ownerid,omitempty" swaggertype:"string"`
|
||||||
|
|
||||||
// Domain contains the abstract domain where this Service relates.
|
// Domain contains the abstract domain where this Service relates.
|
||||||
Domain string `json:"_domain"`
|
Domain string `json:"_domain"`
|
||||||
|
|
|
@ -42,10 +42,10 @@ import (
|
||||||
// Session holds informatin about a User's currently connected.
|
// Session holds informatin about a User's currently connected.
|
||||||
type Session struct {
|
type Session struct {
|
||||||
// Id is the Session's identifier.
|
// Id is the Session's identifier.
|
||||||
Id Identifier `json:"id"`
|
Id Identifier `json:"id" swaggertype:"string"`
|
||||||
|
|
||||||
// IdUser is the User's identifier of the Session.
|
// IdUser is the User's identifier of the Session.
|
||||||
IdUser Identifier `json:"login"`
|
IdUser Identifier `json:"login" swaggertype:"string"`
|
||||||
|
|
||||||
// IssuedAt holds the creation date of the Session.
|
// IssuedAt holds the creation date of the Session.
|
||||||
IssuedAt time.Time `json:"time"`
|
IssuedAt time.Time `json:"time"`
|
||||||
|
|
|
@ -1,79 +0,0 @@
|
||||||
// Copyright or © or Copr. happyDNS (2020)
|
|
||||||
//
|
|
||||||
// contact@happydomain.org
|
|
||||||
//
|
|
||||||
// This software is a computer program whose purpose is to provide a modern
|
|
||||||
// interface to interact with DNS systems.
|
|
||||||
//
|
|
||||||
// This software is governed by the CeCILL license under French law and abiding
|
|
||||||
// by the rules of distribution of free software. You can use, modify and/or
|
|
||||||
// redistribute the software under the terms of the CeCILL license as
|
|
||||||
// circulated by CEA, CNRS and INRIA at the following URL
|
|
||||||
// "http://www.cecill.info".
|
|
||||||
//
|
|
||||||
// As a counterpart to the access to the source code and rights to copy, modify
|
|
||||||
// and redistribute granted by the license, users are provided only with a
|
|
||||||
// limited warranty and the software's author, the holder of the economic
|
|
||||||
// rights, and the successive licensors have only limited liability.
|
|
||||||
//
|
|
||||||
// In this respect, the user's attention is drawn to the risks associated with
|
|
||||||
// loading, using, modifying and/or developing or reproducing the software by
|
|
||||||
// the user in light of its specific status of free software, that may mean
|
|
||||||
// that it is complicated to manipulate, and that also therefore means that it
|
|
||||||
// is reserved for developers and experienced professionals having in-depth
|
|
||||||
// computer knowledge. Users are therefore encouraged to load and test the
|
|
||||||
// software's suitability as regards their requirements in conditions enabling
|
|
||||||
// the security of their systems and/or data to be ensured and, more generally,
|
|
||||||
// to use and operate it in the same conditions as regards security.
|
|
||||||
//
|
|
||||||
// The fact that you are presently reading this means that you have had
|
|
||||||
// knowledge of the CeCILL license and that you accept its terms.
|
|
||||||
|
|
||||||
package happydns
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/miekg/dns"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Source is where Domains and Zones can be managed.
|
|
||||||
type Source interface {
|
|
||||||
// Validate tells if the Source's settings are good.
|
|
||||||
Validate() error
|
|
||||||
|
|
||||||
// DomainExists tells if the given domain exists for the Source.
|
|
||||||
DomainExists(string) error
|
|
||||||
|
|
||||||
// ImportZone retrieves all RRs for the given Domain.
|
|
||||||
ImportZone(*Domain) ([]dns.RR, error)
|
|
||||||
|
|
||||||
// AddRR adds an RR in the zone of the given Domain.
|
|
||||||
AddRR(*Domain, dns.RR) error
|
|
||||||
|
|
||||||
// DeleteRR removes the given RR in the zone of the given Domain.
|
|
||||||
DeleteRR(*Domain, dns.RR) error
|
|
||||||
|
|
||||||
// UpdateSOA tries to update the Zone's SOA record, according to the
|
|
||||||
// given parameters.
|
|
||||||
UpdateSOA(*Domain, *dns.SOA, bool) error
|
|
||||||
}
|
|
||||||
|
|
||||||
// SourceMeta holds the metadata associated to a Source.
|
|
||||||
type SourceMeta struct {
|
|
||||||
// Type is the string representation of the Source's type.
|
|
||||||
Type string `json:"_srctype"`
|
|
||||||
|
|
||||||
// Id is the Source's identifier.
|
|
||||||
Id Identifier `json:"_id"`
|
|
||||||
|
|
||||||
// OwnerId is the User's identifier for the current Source.
|
|
||||||
OwnerId Identifier `json:"_ownerid"`
|
|
||||||
|
|
||||||
// Comment is a string that helps user to distinguish the Source.
|
|
||||||
Comment string `json:"_comment,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// SourceCombined combined SourceMeta + Source
|
|
||||||
type SourceCombined struct {
|
|
||||||
Source
|
|
||||||
SourceMeta
|
|
||||||
}
|
|
|
@ -42,10 +42,10 @@ import (
|
||||||
// ZoneMeta holds the metadata associated to a Zone.
|
// ZoneMeta holds the metadata associated to a Zone.
|
||||||
type ZoneMeta struct {
|
type ZoneMeta struct {
|
||||||
// Id is the Zone's identifier.
|
// Id is the Zone's identifier.
|
||||||
Id Identifier `json:"id"`
|
Id Identifier `json:"id" swaggertype:"string"`
|
||||||
|
|
||||||
// IdAuthor is the User's identifier for the current Zone.
|
// IdAuthor is the User's identifier for the current Zone.
|
||||||
IdAuthor Identifier `json:"id_author"`
|
IdAuthor Identifier `json:"id_author" swaggertype:"string"`
|
||||||
|
|
||||||
// DefaultTTL is the TTL to use when no TTL has been defined for a record in this Zone.
|
// DefaultTTL is the TTL to use when no TTL has been defined for a record in this Zone.
|
||||||
DefaultTTL uint32 `json:"default_ttl"`
|
DefaultTTL uint32 `json:"default_ttl"`
|
||||||
|
|
Loading…
Reference in New Issue