From 47335ca5e9447b2de08a4a83e55541918914835e Mon Sep 17 00:00:00 2001 From: Sense T Date: Fri, 19 Apr 2024 12:47:00 +0800 Subject: [PATCH] swagger done --- TODO | 5 +- database/basedao.go | 4 +- docs/docs.go | 1043 +++++++++++++++++++++++++++++++++++- docs/swagger.json | 1041 ++++++++++++++++++++++++++++++++++- docs/swagger.yaml | 571 +++++++++++++++++++- go.mod | 1 + go.sum | 2 + main.go | 5 + models/domain.go | 2 +- models/record.go | 10 +- models/settings.go | 1 + server/handlers_domains.go | 52 +- server/handlers_records.go | 72 ++- server/response.go | 12 +- server/route.go | 1 + 15 files changed, 2801 insertions(+), 21 deletions(-) diff --git a/TODO b/TODO index d3947a7..8fe8ab9 100644 --- a/TODO +++ b/TODO @@ -3,7 +3,10 @@ - [x] i18n - [x] modals - [] debug -- [] swagger +- [x] swagger +- [] comments - [] Nix Module + +v2.0 - [] RBAC - [] Audit diff --git a/database/basedao.go b/database/basedao.go index 3f87251..cc634fb 100644 --- a/database/basedao.go +++ b/database/basedao.go @@ -3,7 +3,7 @@ package database import ( "errors" - "github.com/huandu/go-clone" + clone "github.com/huandu/go-clone/generic" "gorm.io/gorm" ) @@ -31,7 +31,7 @@ func (BaseDAO[T]) GetAll(db *gorm.DB, e T, cond ...T) ([]T, error) { return nil, err } - i := clone.Clone(e).(T) + i := clone.Clone(e) r = append(r, i) } diff --git a/docs/docs.go b/docs/docs.go index 6676994..6914a19 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -14,17 +14,1050 @@ const docTemplate = `{ }, "host": "{{.Host}}", "basePath": "{{.BasePath}}", - "paths": {} + "paths": { + "/domains/": { + "get": { + "description": "List all domains", + "consumes": [ + "application/json" + ], + "tags": [ + "domains" + ], + "summary": "List all domains", + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/models.Domain" + } + } + } + } + ] + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + } + } + } + ] + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + } + } + } + ] + } + } + } + }, + "put": { + "description": "Update a domain", + "consumes": [ + "application/json" + ], + "tags": [ + "domains" + ], + "summary": "Update a domain", + "parameters": [ + { + "description": "content", + "name": "object", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/models.Domain" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/models.Domain" + } + } + } + ] + } + }, + "400": { + "description": "Bad Request", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + } + } + } + ] + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + } + } + } + ] + } + }, + "404": { + "description": "Not Found", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + } + } + } + ] + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + } + } + } + ] + } + } + } + }, + "post": { + "description": "Create a domain", + "tags": [ + "domains" + ], + "summary": "Create a domain", + "parameters": [ + { + "description": "content", + "name": "object", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/models.Domain" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/models.Domain" + } + } + } + ] + } + }, + "400": { + "description": "Bad Request", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + } + } + } + ] + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + } + } + } + ] + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + } + } + } + ] + } + } + } + } + }, + "/domains/{id}": { + "delete": { + "description": "Delete a domain", + "tags": [ + "domains" + ], + "summary": "Delete a domain", + "parameters": [ + { + "type": "integer", + "description": "Domain ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + } + } + } + ] + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + } + } + } + ] + } + }, + "404": { + "description": "Not Found", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + } + } + } + ] + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + } + } + } + ] + } + } + } + } + }, + "/records/{domain}": { + "get": { + "description": "List all records of a domain", + "tags": [ + "records" + ], + "summary": "List all records of a domain", + "parameters": [ + { + "type": "string", + "description": "domain", + "name": "domain", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/models.Record-models_RecordContentDefault" + } + } + } + } + ] + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + } + } + } + ] + } + }, + "404": { + "description": "Not Found", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + } + } + } + ] + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + } + } + } + ] + } + } + } + }, + "put": { + "description": "Update a record of a domain", + "consumes": [ + "application/json" + ], + "tags": [ + "records" + ], + "summary": "Update a record of a domain", + "parameters": [ + { + "type": "string", + "description": "domain", + "name": "domain", + "in": "path", + "required": true + }, + { + "description": "content", + "name": "object", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/models.Record-models_RecordContentDefault" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/models.Record-models_RecordContentDefault" + } + } + } + ] + } + }, + "400": { + "description": "Bad Request", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + } + } + } + ] + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + } + } + } + ] + } + }, + "404": { + "description": "Not Found", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + } + } + } + ] + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + } + } + } + ] + } + } + } + }, + "post": { + "description": "Create a record of a domain", + "consumes": [ + "application/json" + ], + "tags": [ + "records" + ], + "summary": "Create a record of a domain", + "parameters": [ + { + "type": "string", + "description": "domain", + "name": "domain", + "in": "path", + "required": true + }, + { + "description": "content", + "name": "object", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/models.Record-models_RecordContentDefault" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/models.Record-models_RecordContentDefault" + } + } + } + ] + } + }, + "400": { + "description": "Bad Request", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + } + } + } + ] + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + } + } + } + ] + } + }, + "404": { + "description": "Not Found", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + } + } + } + ] + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + } + } + } + ] + } + } + } + } + }, + "/records/{domain}/bulk": { + "post": { + "description": "Create some records of a domain", + "consumes": [ + "application/json" + ], + "tags": [ + "records" + ], + "summary": "Create some records of a domain", + "parameters": [ + { + "type": "string", + "description": "domain", + "name": "domain", + "in": "path", + "required": true + }, + { + "description": "content", + "name": "object", + "in": "body", + "required": true, + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/models.Record-models_RecordContentDefault" + } + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/models.Record-models_RecordContentDefault" + } + } + } + ] + } + }, + "400": { + "description": "Bad Request", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + } + } + } + ] + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + } + } + } + ] + } + }, + "404": { + "description": "Not Found", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + } + } + } + ] + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + } + } + } + ] + } + } + } + } + }, + "/records/{domain}/{id}": { + "delete": { + "description": "Delete a record of a domain, except SOA record.", + "tags": [ + "records" + ], + "summary": "Delete a record of a domain", + "parameters": [ + { + "type": "string", + "description": "domain", + "name": "domain", + "in": "path", + "required": true + }, + { + "type": "integer", + "description": "Record ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + } + } + } + ] + } + }, + "400": { + "description": "Bad Request", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + } + } + } + ] + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + } + } + } + ] + } + }, + "404": { + "description": "Not Found", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + } + } + } + ] + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + } + } + } + ] + } + } + } + } + } + }, + "definitions": { + "models.Domain": { + "type": "object", + "properties": { + "admin_email": { + "type": "string" + }, + "domain_name": { + "type": "string" + }, + "expiry_period": { + "type": "integer" + }, + "id": { + "type": "integer" + }, + "main_dns": { + "type": "string" + }, + "negative_ttl": { + "type": "integer" + }, + "refresh_interval": { + "type": "integer" + }, + "retry_interval": { + "type": "integer" + }, + "serial_number": { + "type": "integer" + } + } + }, + "models.Record-models_RecordContentDefault": { + "type": "object", + "properties": { + "content": { + "description": "see https://github.com/cloud66-oss/coredns_mysql/blob/main/types.go for content", + "allOf": [ + { + "$ref": "#/definitions/models.RecordContentDefault" + } + ] + }, + "id": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "record_type": { + "type": "string" + }, + "ttl": { + "type": "integer" + }, + "zone": { + "type": "string" + } + } + }, + "models.RecordContentDefault": { + "type": "object", + "additionalProperties": {} + }, + "server.Response": { + "type": "object", + "properties": { + "data": { + "description": "payload here" + }, + "message": { + "description": "error message", + "type": "string" + }, + "succeed": { + "description": "` + "`" + `true` + "`" + ` for 2xx, else ` + "`" + `false` + "`" + `", + "type": "boolean" + } + } + } + }, + "securityDefinitions": { + "BasicAuth": { + "type": "basic" + } + } }` // SwaggerInfo holds exported Swagger Info so clients can modify it var SwaggerInfo = &swag.Spec{ - Version: "", + Version: "1.0", Host: "", - BasePath: "", + BasePath: "/api/v1", Schemes: []string{}, - Title: "", - Description: "", + Title: "reCoreD-UI API", + Description: "APIs for reCoreD-UI", InfoInstanceName: "swagger", SwaggerTemplate: docTemplate, LeftDelim: "{{", diff --git a/docs/swagger.json b/docs/swagger.json index ec416cd..799b0e4 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -1,7 +1,1044 @@ { "swagger": "2.0", "info": { - "contact": {} + "description": "APIs for reCoreD-UI", + "title": "reCoreD-UI API", + "contact": {}, + "version": "1.0" }, - "paths": {} + "basePath": "/api/v1", + "paths": { + "/domains/": { + "get": { + "description": "List all domains", + "consumes": [ + "application/json" + ], + "tags": [ + "domains" + ], + "summary": "List all domains", + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/models.Domain" + } + } + } + } + ] + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + } + } + } + ] + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + } + } + } + ] + } + } + } + }, + "put": { + "description": "Update a domain", + "consumes": [ + "application/json" + ], + "tags": [ + "domains" + ], + "summary": "Update a domain", + "parameters": [ + { + "description": "content", + "name": "object", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/models.Domain" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/models.Domain" + } + } + } + ] + } + }, + "400": { + "description": "Bad Request", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + } + } + } + ] + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + } + } + } + ] + } + }, + "404": { + "description": "Not Found", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + } + } + } + ] + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + } + } + } + ] + } + } + } + }, + "post": { + "description": "Create a domain", + "tags": [ + "domains" + ], + "summary": "Create a domain", + "parameters": [ + { + "description": "content", + "name": "object", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/models.Domain" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/models.Domain" + } + } + } + ] + } + }, + "400": { + "description": "Bad Request", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + } + } + } + ] + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + } + } + } + ] + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + } + } + } + ] + } + } + } + } + }, + "/domains/{id}": { + "delete": { + "description": "Delete a domain", + "tags": [ + "domains" + ], + "summary": "Delete a domain", + "parameters": [ + { + "type": "integer", + "description": "Domain ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + } + } + } + ] + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + } + } + } + ] + } + }, + "404": { + "description": "Not Found", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + } + } + } + ] + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + } + } + } + ] + } + } + } + } + }, + "/records/{domain}": { + "get": { + "description": "List all records of a domain", + "tags": [ + "records" + ], + "summary": "List all records of a domain", + "parameters": [ + { + "type": "string", + "description": "domain", + "name": "domain", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/models.Record-models_RecordContentDefault" + } + } + } + } + ] + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + } + } + } + ] + } + }, + "404": { + "description": "Not Found", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + } + } + } + ] + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + } + } + } + ] + } + } + } + }, + "put": { + "description": "Update a record of a domain", + "consumes": [ + "application/json" + ], + "tags": [ + "records" + ], + "summary": "Update a record of a domain", + "parameters": [ + { + "type": "string", + "description": "domain", + "name": "domain", + "in": "path", + "required": true + }, + { + "description": "content", + "name": "object", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/models.Record-models_RecordContentDefault" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/models.Record-models_RecordContentDefault" + } + } + } + ] + } + }, + "400": { + "description": "Bad Request", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + } + } + } + ] + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + } + } + } + ] + } + }, + "404": { + "description": "Not Found", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + } + } + } + ] + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + } + } + } + ] + } + } + } + }, + "post": { + "description": "Create a record of a domain", + "consumes": [ + "application/json" + ], + "tags": [ + "records" + ], + "summary": "Create a record of a domain", + "parameters": [ + { + "type": "string", + "description": "domain", + "name": "domain", + "in": "path", + "required": true + }, + { + "description": "content", + "name": "object", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/models.Record-models_RecordContentDefault" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/models.Record-models_RecordContentDefault" + } + } + } + ] + } + }, + "400": { + "description": "Bad Request", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + } + } + } + ] + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + } + } + } + ] + } + }, + "404": { + "description": "Not Found", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + } + } + } + ] + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + } + } + } + ] + } + } + } + } + }, + "/records/{domain}/bulk": { + "post": { + "description": "Create some records of a domain", + "consumes": [ + "application/json" + ], + "tags": [ + "records" + ], + "summary": "Create some records of a domain", + "parameters": [ + { + "type": "string", + "description": "domain", + "name": "domain", + "in": "path", + "required": true + }, + { + "description": "content", + "name": "object", + "in": "body", + "required": true, + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/models.Record-models_RecordContentDefault" + } + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/models.Record-models_RecordContentDefault" + } + } + } + ] + } + }, + "400": { + "description": "Bad Request", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + } + } + } + ] + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + } + } + } + ] + } + }, + "404": { + "description": "Not Found", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + } + } + } + ] + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + } + } + } + ] + } + } + } + } + }, + "/records/{domain}/{id}": { + "delete": { + "description": "Delete a record of a domain, except SOA record.", + "tags": [ + "records" + ], + "summary": "Delete a record of a domain", + "parameters": [ + { + "type": "string", + "description": "domain", + "name": "domain", + "in": "path", + "required": true + }, + { + "type": "integer", + "description": "Record ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + } + } + } + ] + } + }, + "400": { + "description": "Bad Request", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + } + } + } + ] + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + } + } + } + ] + } + }, + "404": { + "description": "Not Found", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + } + } + } + ] + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/server.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + } + } + } + ] + } + } + } + } + } + }, + "definitions": { + "models.Domain": { + "type": "object", + "properties": { + "admin_email": { + "type": "string" + }, + "domain_name": { + "type": "string" + }, + "expiry_period": { + "type": "integer" + }, + "id": { + "type": "integer" + }, + "main_dns": { + "type": "string" + }, + "negative_ttl": { + "type": "integer" + }, + "refresh_interval": { + "type": "integer" + }, + "retry_interval": { + "type": "integer" + }, + "serial_number": { + "type": "integer" + } + } + }, + "models.Record-models_RecordContentDefault": { + "type": "object", + "properties": { + "content": { + "description": "see https://github.com/cloud66-oss/coredns_mysql/blob/main/types.go for content", + "allOf": [ + { + "$ref": "#/definitions/models.RecordContentDefault" + } + ] + }, + "id": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "record_type": { + "type": "string" + }, + "ttl": { + "type": "integer" + }, + "zone": { + "type": "string" + } + } + }, + "models.RecordContentDefault": { + "type": "object", + "additionalProperties": {} + }, + "server.Response": { + "type": "object", + "properties": { + "data": { + "description": "payload here" + }, + "message": { + "description": "error message", + "type": "string" + }, + "succeed": { + "description": "`true` for 2xx, else `false`", + "type": "boolean" + } + } + } + }, + "securityDefinitions": { + "BasicAuth": { + "type": "basic" + } + } } \ No newline at end of file diff --git a/docs/swagger.yaml b/docs/swagger.yaml index b64379c..a0f090d 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -1,4 +1,573 @@ +basePath: /api/v1 +definitions: + models.Domain: + properties: + admin_email: + type: string + domain_name: + type: string + expiry_period: + type: integer + id: + type: integer + main_dns: + type: string + negative_ttl: + type: integer + refresh_interval: + type: integer + retry_interval: + type: integer + serial_number: + type: integer + type: object + models.Record-models_RecordContentDefault: + properties: + content: + allOf: + - $ref: '#/definitions/models.RecordContentDefault' + description: see https://github.com/cloud66-oss/coredns_mysql/blob/main/types.go + for content + id: + type: integer + name: + type: string + record_type: + type: string + ttl: + type: integer + zone: + type: string + type: object + models.RecordContentDefault: + additionalProperties: {} + type: object + server.Response: + properties: + data: + description: payload here + message: + description: error message + type: string + succeed: + description: '`true` for 2xx, else `false`' + type: boolean + type: object info: contact: {} -paths: {} + description: APIs for reCoreD-UI + title: reCoreD-UI API + version: "1.0" +paths: + /domains/: + get: + consumes: + - application/json + description: List all domains + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/server.Response' + - properties: + data: + items: + $ref: '#/definitions/models.Domain' + type: array + type: object + "401": + description: Unauthorized + schema: + allOf: + - $ref: '#/definitions/server.Response' + - properties: + data: + type: object + type: object + "500": + description: Internal Server Error + schema: + allOf: + - $ref: '#/definitions/server.Response' + - properties: + data: + type: object + type: object + summary: List all domains + tags: + - domains + post: + description: Create a domain + parameters: + - description: content + in: body + name: object + required: true + schema: + $ref: '#/definitions/models.Domain' + responses: + "201": + description: Created + schema: + allOf: + - $ref: '#/definitions/server.Response' + - properties: + data: + $ref: '#/definitions/models.Domain' + type: object + "400": + description: Bad Request + schema: + allOf: + - $ref: '#/definitions/server.Response' + - properties: + data: + type: object + type: object + "401": + description: Unauthorized + schema: + allOf: + - $ref: '#/definitions/server.Response' + - properties: + data: + type: object + type: object + "500": + description: Internal Server Error + schema: + allOf: + - $ref: '#/definitions/server.Response' + - properties: + data: + type: object + type: object + summary: Create a domain + tags: + - domains + put: + consumes: + - application/json + description: Update a domain + parameters: + - description: content + in: body + name: object + required: true + schema: + $ref: '#/definitions/models.Domain' + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/server.Response' + - properties: + data: + $ref: '#/definitions/models.Domain' + type: object + "400": + description: Bad Request + schema: + allOf: + - $ref: '#/definitions/server.Response' + - properties: + data: + type: object + type: object + "401": + description: Unauthorized + schema: + allOf: + - $ref: '#/definitions/server.Response' + - properties: + data: + type: object + type: object + "404": + description: Not Found + schema: + allOf: + - $ref: '#/definitions/server.Response' + - properties: + data: + type: object + type: object + "500": + description: Internal Server Error + schema: + allOf: + - $ref: '#/definitions/server.Response' + - properties: + data: + type: object + type: object + summary: Update a domain + tags: + - domains + /domains/{id}: + delete: + description: Delete a domain + parameters: + - description: Domain ID + in: path + name: id + required: true + type: integer + responses: + "204": + description: No Content + schema: + allOf: + - $ref: '#/definitions/server.Response' + - properties: + data: + type: object + type: object + "401": + description: Unauthorized + schema: + allOf: + - $ref: '#/definitions/server.Response' + - properties: + data: + type: object + type: object + "404": + description: Not Found + schema: + allOf: + - $ref: '#/definitions/server.Response' + - properties: + data: + type: object + type: object + "500": + description: Internal Server Error + schema: + allOf: + - $ref: '#/definitions/server.Response' + - properties: + data: + type: object + type: object + summary: Delete a domain + tags: + - domains + /records/{domain}: + get: + description: List all records of a domain + parameters: + - description: domain + in: path + name: domain + required: true + type: string + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/server.Response' + - properties: + data: + items: + $ref: '#/definitions/models.Record-models_RecordContentDefault' + type: array + type: object + "401": + description: Unauthorized + schema: + allOf: + - $ref: '#/definitions/server.Response' + - properties: + data: + type: object + type: object + "404": + description: Not Found + schema: + allOf: + - $ref: '#/definitions/server.Response' + - properties: + data: + type: object + type: object + "500": + description: Internal Server Error + schema: + allOf: + - $ref: '#/definitions/server.Response' + - properties: + data: + type: object + type: object + summary: List all records of a domain + tags: + - records + post: + consumes: + - application/json + description: Create a record of a domain + parameters: + - description: domain + in: path + name: domain + required: true + type: string + - description: content + in: body + name: object + required: true + schema: + $ref: '#/definitions/models.Record-models_RecordContentDefault' + responses: + "201": + description: Created + schema: + allOf: + - $ref: '#/definitions/server.Response' + - properties: + data: + $ref: '#/definitions/models.Record-models_RecordContentDefault' + type: object + "400": + description: Bad Request + schema: + allOf: + - $ref: '#/definitions/server.Response' + - properties: + data: + type: object + type: object + "401": + description: Unauthorized + schema: + allOf: + - $ref: '#/definitions/server.Response' + - properties: + data: + type: object + type: object + "404": + description: Not Found + schema: + allOf: + - $ref: '#/definitions/server.Response' + - properties: + data: + type: object + type: object + "500": + description: Internal Server Error + schema: + allOf: + - $ref: '#/definitions/server.Response' + - properties: + data: + type: object + type: object + summary: Create a record of a domain + tags: + - records + put: + consumes: + - application/json + description: Update a record of a domain + parameters: + - description: domain + in: path + name: domain + required: true + type: string + - description: content + in: body + name: object + required: true + schema: + $ref: '#/definitions/models.Record-models_RecordContentDefault' + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/server.Response' + - properties: + data: + $ref: '#/definitions/models.Record-models_RecordContentDefault' + type: object + "400": + description: Bad Request + schema: + allOf: + - $ref: '#/definitions/server.Response' + - properties: + data: + type: object + type: object + "401": + description: Unauthorized + schema: + allOf: + - $ref: '#/definitions/server.Response' + - properties: + data: + type: object + type: object + "404": + description: Not Found + schema: + allOf: + - $ref: '#/definitions/server.Response' + - properties: + data: + type: object + type: object + "500": + description: Internal Server Error + schema: + allOf: + - $ref: '#/definitions/server.Response' + - properties: + data: + type: object + type: object + summary: Update a record of a domain + tags: + - records + /records/{domain}/{id}: + delete: + description: Delete a record of a domain, except SOA record. + parameters: + - description: domain + in: path + name: domain + required: true + type: string + - description: Record ID + in: path + name: id + required: true + type: integer + responses: + "204": + description: No Content + schema: + allOf: + - $ref: '#/definitions/server.Response' + - properties: + data: + type: object + type: object + "400": + description: Bad Request + schema: + allOf: + - $ref: '#/definitions/server.Response' + - properties: + data: + type: object + type: object + "401": + description: Unauthorized + schema: + allOf: + - $ref: '#/definitions/server.Response' + - properties: + data: + type: object + type: object + "404": + description: Not Found + schema: + allOf: + - $ref: '#/definitions/server.Response' + - properties: + data: + type: object + type: object + "500": + description: Internal Server Error + schema: + allOf: + - $ref: '#/definitions/server.Response' + - properties: + data: + type: object + type: object + summary: Delete a record of a domain + tags: + - records + /records/{domain}/bulk: + post: + consumes: + - application/json + description: Create some records of a domain + parameters: + - description: domain + in: path + name: domain + required: true + type: string + - description: content + in: body + name: object + required: true + schema: + items: + $ref: '#/definitions/models.Record-models_RecordContentDefault' + type: array + responses: + "201": + description: Created + schema: + allOf: + - $ref: '#/definitions/server.Response' + - properties: + data: + $ref: '#/definitions/models.Record-models_RecordContentDefault' + type: object + "400": + description: Bad Request + schema: + allOf: + - $ref: '#/definitions/server.Response' + - properties: + data: + type: object + type: object + "401": + description: Unauthorized + schema: + allOf: + - $ref: '#/definitions/server.Response' + - properties: + data: + type: object + type: object + "404": + description: Not Found + schema: + allOf: + - $ref: '#/definitions/server.Response' + - properties: + data: + type: object + type: object + "500": + description: Internal Server Error + schema: + allOf: + - $ref: '#/definitions/server.Response' + - properties: + data: + type: object + type: object + summary: Create some records of a domain + tags: + - records +securityDefinitions: + BasicAuth: + type: basic swagger: "2.0" diff --git a/go.mod b/go.mod index 96f855e..737a3d1 100644 --- a/go.mod +++ b/go.mod @@ -74,6 +74,7 @@ require ( require ( github.com/cloud66-oss/coredns_mysql v0.0.0-20231116193749-de52e2924a6f github.com/gin-gonic/gin v1.9.1 + github.com/huandu/go-clone/generic v1.7.2 github.com/sirupsen/logrus v1.9.3 github.com/swaggo/files v1.0.1 github.com/urfave/cli/v2 v2.27.1 diff --git a/go.sum b/go.sum index 4a925fa..4cc489a 100644 --- a/go.sum +++ b/go.sum @@ -357,6 +357,8 @@ github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpO github.com/huandu/go-assert v1.1.5/go.mod h1:yOLvuqZwmcHIC5rIzrBhT7D3Q9c3GFnd0JrPVhn/06U= github.com/huandu/go-clone v1.7.2 h1:3+Aq0Ed8XK+zKkLjE2dfHg0XrpIfcohBE1K+c8Usxoo= github.com/huandu/go-clone v1.7.2/go.mod h1:ReGivhG6op3GYr+UY3lS6mxjKp7MIGTknuU5TbTVaXE= +github.com/huandu/go-clone/generic v1.7.2 h1:47pQphxs1Xc9cVADjOHN+Bm5D0hNagwH9UXErbxgVKA= +github.com/huandu/go-clone/generic v1.7.2/go.mod h1:xgd9ZebcMsBWWcBx5mVMCoqMX24gLWr5lQicr+nVXNs= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= diff --git a/main.go b/main.go index f5fcdcd..42ca3d8 100644 --- a/main.go +++ b/main.go @@ -15,6 +15,11 @@ func init() { logrus.SetReportCaller(true) } +// @title reCoreD-UI API +// @version 1.0 +// @description APIs for reCoreD-UI +// @BasePath /api/v1 +// @securityDefinitions.basic BasicAuth func main() { flags := []cli.Flag{ &cli.StringFlag{ diff --git a/models/domain.go b/models/domain.go index a3ad043..4152492 100644 --- a/models/domain.go +++ b/models/domain.go @@ -5,11 +5,11 @@ import ( "strings" ) +// Domain domain data structure type Domain struct { ID uint `gorm:"primaryKey" json:"id"` DomainName string `gorm:"unique,not null,size:255" json:"domain_name"` - //SOA Info MainDNS string `gorm:"not null;size:255" json:"main_dns"` AdminEmail string `gorm:"not null;size:255" json:"admin_email"` SerialNumber int64 `gorm:"not null;default:1" json:"serial_number"` diff --git a/models/record.go b/models/record.go index d34c04a..0378a31 100644 --- a/models/record.go +++ b/models/record.go @@ -24,11 +24,13 @@ type recordContentTypes interface { ARecord | AAAARecord | CNAMERecord | CAARecord | NSRecord | MXRecord | SOARecord | SRVRecord | TXTRecord | RecordContentDefault } +// Record dns records for coredns mysql plugin type Record[T recordContentTypes] struct { - ID uint `gorm:"primaryKey" json:"id"` - Zone string `gorm:"not null;size:255" json:"zone"` - Name string `gorm:"not null;size:255" json:"name"` - Ttl int `json:"ttl"` + ID uint `gorm:"primaryKey" json:"id"` + Zone string `gorm:"not null;size:255" json:"zone"` + Name string `gorm:"not null;size:255" json:"name"` + Ttl int `json:"ttl"` + // see https://github.com/cloud66-oss/coredns_mysql/blob/main/types.go for content Content T `gorm:"serializer:json;type:text" json:"content"` RecordType string `gorm:"not null;size:255" json:"record_type"` } diff --git a/models/settings.go b/models/settings.go index 20b75ec..16f6e86 100644 --- a/models/settings.go +++ b/models/settings.go @@ -10,6 +10,7 @@ const ( SettingsKeyDNSServer = "dns.servers" ) +// Settings settings for this app type Settings struct { ID uint `gorm:"primaryKey"` Key string `gorm:"unique;not null;size:255"` diff --git a/server/handlers_domains.go b/server/handlers_domains.go index 9a2629c..fdbadd2 100644 --- a/server/handlers_domains.go +++ b/server/handlers_domains.go @@ -6,9 +6,21 @@ import ( "reCoreD-UI/models" "github.com/gin-gonic/gin" + + _ "reCoreD-UI/docs" ) -// GetDomains +// GetDomains godoc +// +// @Router /domains/ [get] +// @Summary List all domains +// @Description List all domains +// @Tags domains +// @Accept json +// @Product json +// @Success 200 {object} Response{data=[]models.Domain} +// @Failure 401 {object} Response{data=nil} +// @Failure 500 {object} Response{data=nil} func getDomains(c *gin.Context) { domains, err := controllers.GetDomains("") if err != nil { @@ -22,6 +34,18 @@ func getDomains(c *gin.Context) { }) } +// CreateDomain godoc +// +// @Router /domains/ [post] +// @Summary Create a domain +// @Description Create a domain +// @Tags domains +// @Product json +// @Param object body models.Domain true "content" +// @Success 201 {object} Response{data=models.Domain} +// @Failure 400 {object} Response{data=nil} +// @Failure 401 {object} Response{data=nil} +// @Failure 500 {object} Response{data=nil} func createDomain(c *gin.Context) { domain := &models.Domain{} @@ -45,6 +69,20 @@ func createDomain(c *gin.Context) { }) } +// UpdateDomain godoc +// +// @Router /domains/ [put] +// @Summary Update a domain +// @Description Update a domain +// @Tags domains +// @Accept json +// @Product json +// @Param object body models.Domain true "content" +// @Success 200 {object} Response{data=models.Domain} +// @Failure 400 {object} Response{data=nil} +// @Failure 401 {object} Response{data=nil} +// @Failure 404 {object} Response{data=nil} +// @Failure 500 {object} Response{data=nil} func updateDomain(c *gin.Context) { domain := &models.Domain{} @@ -66,6 +104,18 @@ func updateDomain(c *gin.Context) { }) } +// DeleteDomain godoc +// +// @Router /domains/{id} [delete] +// @Summary Delete a domain +// @Description Delete a domain +// @Tags domains +// @Product json +// @Param id path int true "Domain ID" +// @Success 204 {object} Response{data=nil} +// @Failure 401 {object} Response{data=nil} +// @Failure 404 {object} Response{data=nil} +// @Failure 500 {object} Response{data=nil} func deleteDomain(c *gin.Context) { id := c.Param("id") if err := controllers.DeleteDomain(id); err != nil { diff --git a/server/handlers_records.go b/server/handlers_records.go index 0f42b3d..aca14a6 100644 --- a/server/handlers_records.go +++ b/server/handlers_records.go @@ -10,7 +10,6 @@ import ( ) func validateRecord(r models.IRecord) error { - switch r.GetType() { case models.RecordTypeA: record := &models.Record[models.ARecord]{} @@ -71,6 +70,18 @@ func validateRecord(r models.IRecord) error { } } +// GetRecords godoc +// +// @Router /records/{domain} [get] +// @Summary List all records of a domain +// @Description List all records of a domain +// @Tags records +// @Product json +// @Param domain path string true "domain" +// @Success 200 {object} Response{data=[]models.Record[models.RecordContentDefault]} +// @Failure 401 {object} Response{data=nil} +// @Failure 404 {object} Response{data=nil} +// @Failure 500 {object} Response{data=nil} func getRecords(c *gin.Context) { query := &models.Record[models.RecordContentDefault]{Content: make(models.RecordContentDefault)} if err := c.BindQuery(query); err != nil { @@ -95,6 +106,21 @@ func getRecords(c *gin.Context) { }) } +// CreateRecord godoc +// +// @Router /records/{domain} [post] +// @Summary Create a record of a domain +// @Description Create a record of a domain +// @Tags records +// @Accept json +// @Product json +// @Param domain path string true "domain" +// @Param object body models.Record[models.RecordContentDefault] true "content" +// @Success 201 {object} Response{data=models.Record[models.RecordContentDefault]} +// @Failure 400 {object} Response{data=nil} +// @Failure 401 {object} Response{data=nil} +// @Failure 404 {object} Response{data=nil} +// @Failure 500 {object} Response{data=nil} func createRecord(c *gin.Context) { record := &models.Record[models.RecordContentDefault]{Content: make(models.RecordContentDefault)} if err := c.BindJSON(record); err != nil { @@ -134,6 +160,21 @@ func createRecord(c *gin.Context) { }) } +// CreateRecords godoc +// +// @Router /records/{domain}/bulk [post] +// @Summary Create some records of a domain +// @Description Create some records of a domain +// @Tags records +// @Accept json +// @Product json +// @Param domain path string true "domain" +// @Param object body []models.Record[models.RecordContentDefault] true "content" +// @Success 201 {object} Response{data=models.Record[models.RecordContentDefault]} +// @Failure 400 {object} Response{data=nil} +// @Failure 401 {object} Response{data=nil} +// @Failure 404 {object} Response{data=nil} +// @Failure 500 {object} Response{data=nil} func createRecords(c *gin.Context) { var records []models.Record[models.RecordContentDefault] if err := c.BindJSON(&records); err != nil { @@ -159,6 +200,21 @@ func createRecords(c *gin.Context) { }) } +// UpdateRecord godoc +// +// @Router /records/{domain} [put] +// @Summary Update a record of a domain +// @Description Update a record of a domain +// @Tags records +// @Accept json +// @Product json +// @Param domain path string true "domain" +// @Param object body models.Record[models.RecordContentDefault] true "content" +// @Success 200 {object} Response{data=models.Record[models.RecordContentDefault]} +// @Failure 400 {object} Response{data=nil} +// @Failure 401 {object} Response{data=nil} +// @Failure 404 {object} Response{data=nil} +// @Failure 500 {object} Response{data=nil} func updateRecord(c *gin.Context) { record := &models.Record[models.RecordContentDefault]{Content: make(models.RecordContentDefault)} if err := c.BindJSON(record); err != nil { @@ -196,6 +252,20 @@ func updateRecord(c *gin.Context) { }) } +// DeleteRecord godoc +// +// @Router /records/{domain}/{id} [delete] +// @Summary Delete a record of a domain +// @Description Delete a record of a domain, except SOA record. +// @Tags records +// @Product json +// @Param domain path string true "domain" +// @Param id path int true "Record ID" +// @Success 204 {object} Response{data=nil} +// @Failure 400 {object} Response{data=nil} +// @Failure 401 {object} Response{data=nil} +// @Failure 404 {object} Response{data=nil} +// @Failure 500 {object} Response{data=nil} func deleteRecord(c *gin.Context) { domain := c.Param("domain") id := c.Param("id") diff --git a/server/response.go b/server/response.go index 9b3c01f..9ccc18d 100644 --- a/server/response.go +++ b/server/response.go @@ -10,10 +10,16 @@ import ( "gorm.io/gorm" ) +// Response common http response type Response struct { - Succeed bool `json:"succeed"` - Message string `json:"message"` - Data interface{} `json:"data"` + // `true` for 2xx, else `false` + Succeed bool `json:"succeed"` + + // error message + Message string `json:"message"` + + // payload here + Data interface{} `json:"data"` } func errorHandler(c *gin.Context, err error) { diff --git a/server/route.go b/server/route.go index 3e69e4e..b2d44bb 100644 --- a/server/route.go +++ b/server/route.go @@ -18,6 +18,7 @@ const ( swaggerPrefix = "/swagger" ) + func (s *Server) setupRoute() { username, password, err := controllers.GetAdmin() if err != nil {