From c551c487ca664efe2facaf9e67b5be88ae735d98 Mon Sep 17 00:00:00 2001 From: Sayan Mallick Date: Thu, 15 Aug 2024 11:55:01 +0530 Subject: [PATCH] New Docs (#3034) * New Docs CSS update and Dockerfile to include docs folder flash of unrendered text fix markdown docs ignore docs/docs.go improving the docs generation github actions for docs generation go runner version fix updated docs.yml update repo action updated updated actions and dns docs dns complete More docs update Complete docs and updated workflow Update documentation Tue Aug 6 11:17:42 UTC 2024 Update documentation Thu Aug 8 12:26:57 UTC 2024 clean up clean up Dockerfile clean up Updated workflow Updated workflow Update docs.yml Update docs.yml * requested changes * changed ingress gateway to remote access gateway --- .github/workflows/docs.yml | 50 + controllers/controller.go | 20 +- controllers/dns.go | 167 +- controllers/docs.go | 475 ----- controllers/enrollmentkeys.go | 103 +- controllers/ext_client.go | 331 ++-- controllers/files.go | 18 +- controllers/hosts.go | 430 +++-- controllers/ipservice.go | 17 +- controllers/legacy.go | 20 +- controllers/network.go | 229 +-- controllers/node.go | 276 +-- controllers/server.go | 51 +- controllers/user.go | 479 +++-- docs/APIUsage.md | 1 + docs/Authentication.md | 10 + docs/Pricing.md | 1 + main.go | 38 +- models/node.go | 185 +- pro/controllers/failover.go | 166 +- pro/controllers/inet_gws.go | 112 +- pro/controllers/relay.go | 100 +- pro/controllers/users.go | 214 ++- swagger.yaml | 3105 +++++++++++++++++++++++++++++++++ swagger.yml | 3006 ------------------------------- 25 files changed, 4916 insertions(+), 4688 deletions(-) create mode 100644 .github/workflows/docs.yml delete mode 100644 controllers/docs.go create mode 100644 docs/APIUsage.md create mode 100644 docs/Authentication.md create mode 100644 docs/Pricing.md create mode 100644 swagger.yaml delete mode 100644 swagger.yml diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 00000000..2d034544 --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,50 @@ +name: Generate Documentation + +on: + workflow_dispatch: + inputs: + branch: + description: 'Branch to run the workflow against' + required: true + default: 'master' + +jobs: + generate-docs: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + repository: gravitl/netmaker + ref: ${{ github.event.inputs.branch || 'master' }} + + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version-file: go.mod + + - name: Install Swag + run: go install github.com/swaggo/swag/cmd/swag@latest + + - name: Generating Docs + run: | + export PATH=$PATH:$(go env GOPATH)/bin + swag i --md docs/ --parseDependency --parseInternal --outputTypes yaml --parseDepth 1 --output . + + - name: Get current timestamp + id: timestamp + run: echo "timestamp=$(date +'%Y-%m-%d %H:%M:%S')" >> $GITHUB_OUTPUT + + - name: Create Pull Request + uses: peter-evans/create-pull-request@v5 + with: + token: ${{ secrets.GITHUB_TOKEN }} + commit-message: "Update documentation ${{ steps.timestamp.outputs.timestamp }}" + title: "Update Swagger documentation ${{ steps.timestamp.outputs.timestamp }}" + body: | + This PR updates the swagger.yml file with the latest documentation changes. + + Updated on: ${{ steps.timestamp.outputs.timestamp }} + branch: update-swagger-docs-${{ github.event.inputs.branch }} + base: ${{ github.event.inputs.branch }} + delete-branch: true diff --git a/controllers/controller.go b/controllers/controller.go index 4ce41e47..749baa06 100644 --- a/controllers/controller.go +++ b/controllers/controller.go @@ -35,7 +35,6 @@ var HttpHandlers = []interface{}{ legacyHandlers, } -// HandleRESTRequests - handles the rest requests func HandleRESTRequests(wg *sync.WaitGroup, ctx context.Context) { defer wg.Done() @@ -43,9 +42,19 @@ func HandleRESTRequests(wg *sync.WaitGroup, ctx context.Context) { // Currently allowed dev origin is all. Should change in prod // should consider analyzing the allowed methods further - headersOk := handlers.AllowedHeaders([]string{"Access-Control-Allow-Origin", "X-Requested-With", "Content-Type", "authorization", "From-Ui"}) + headersOk := handlers.AllowedHeaders( + []string{ + "Access-Control-Allow-Origin", + "X-Requested-With", + "Content-Type", + "authorization", + "From-Ui", + }, + ) originsOk := handlers.AllowedOrigins(strings.Split(servercfg.GetAllowedOrigin(), ",")) - methodsOk := handlers.AllowedMethods([]string{http.MethodGet, http.MethodPut, http.MethodPost, http.MethodDelete}) + methodsOk := handlers.AllowedMethods( + []string{http.MethodGet, http.MethodPut, http.MethodPost, http.MethodDelete}, + ) for _, middleware := range HttpMiddlewares { r.Use(middleware) @@ -57,7 +66,10 @@ func HandleRESTRequests(wg *sync.WaitGroup, ctx context.Context) { port := servercfg.GetAPIPort() - srv := &http.Server{Addr: ":" + port, Handler: handlers.CORS(originsOk, headersOk, methodsOk)(r)} + srv := &http.Server{ + Addr: ":" + port, + Handler: handlers.CORS(originsOk, headersOk, methodsOk)(r), + } go func() { err := srv.ListenAndServe() if err != nil { diff --git a/controllers/dns.go b/controllers/dns.go index 1c0157c0..b1fc71fc 100644 --- a/controllers/dns.go +++ b/controllers/dns.go @@ -16,25 +16,29 @@ import ( func dnsHandlers(r *mux.Router) { - r.HandleFunc("/api/dns", logic.SecurityCheck(true, http.HandlerFunc(getAllDNS))).Methods(http.MethodGet) - r.HandleFunc("/api/dns/adm/{network}/nodes", logic.SecurityCheck(true, http.HandlerFunc(getNodeDNS))).Methods(http.MethodGet) - r.HandleFunc("/api/dns/adm/{network}/custom", logic.SecurityCheck(true, http.HandlerFunc(getCustomDNS))).Methods(http.MethodGet) - r.HandleFunc("/api/dns/adm/{network}", logic.SecurityCheck(true, http.HandlerFunc(getDNS))).Methods(http.MethodGet) - r.HandleFunc("/api/dns/{network}", logic.SecurityCheck(true, http.HandlerFunc(createDNS))).Methods(http.MethodPost) - r.HandleFunc("/api/dns/adm/pushdns", logic.SecurityCheck(true, http.HandlerFunc(pushDNS))).Methods(http.MethodPost) - r.HandleFunc("/api/dns/{network}/{domain}", logic.SecurityCheck(true, http.HandlerFunc(deleteDNS))).Methods(http.MethodDelete) + r.HandleFunc("/api/dns", logic.SecurityCheck(true, http.HandlerFunc(getAllDNS))). + Methods(http.MethodGet) + r.HandleFunc("/api/dns/adm/{network}/nodes", logic.SecurityCheck(true, http.HandlerFunc(getNodeDNS))). + Methods(http.MethodGet) + r.HandleFunc("/api/dns/adm/{network}/custom", logic.SecurityCheck(true, http.HandlerFunc(getCustomDNS))). + Methods(http.MethodGet) + r.HandleFunc("/api/dns/adm/{network}", logic.SecurityCheck(true, http.HandlerFunc(getDNS))). + Methods(http.MethodGet) + r.HandleFunc("/api/dns/{network}", logic.SecurityCheck(true, http.HandlerFunc(createDNS))). + Methods(http.MethodPost) + r.HandleFunc("/api/dns/adm/pushdns", logic.SecurityCheck(true, http.HandlerFunc(pushDNS))). + Methods(http.MethodPost) + r.HandleFunc("/api/dns/{network}/{domain}", logic.SecurityCheck(true, http.HandlerFunc(deleteDNS))). + Methods(http.MethodDelete) } -// swagger:route GET /api/dns/adm/{network}/nodes dns getNodeDNS -// -// Gets node DNS entries associated with a network. -// -// Schemes: https -// -// Security: -// oauth -// Responses: -// 200: dnsResponse +// @Summary Gets node DNS entries associated with a network +// @Router /api/dns/{network} [get] +// @Tags DNS +// @Accept json +// @Param network path string true "Network identifier" +// @Success 200 {array} models.DNSEntry +// @Failure 500 {object} models.ErrorResponse func getNodeDNS(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") @@ -53,17 +57,12 @@ func getNodeDNS(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(dns) } -// swagger:route GET /api/dns dns getAllDNS -// -// Gets all DNS entries. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: dnsResponse +// @Summary Get all DNS entries +// @Router /api/dns [get] +// @Tags DNS +// @Accept json +// @Success 200 {array} models.DNSEntry +// @Failure 500 {object} models.ErrorResponse func getAllDNS(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") dns, err := logic.GetAllDNS() @@ -77,17 +76,13 @@ func getAllDNS(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(dns) } -// swagger:route GET /api/dns/adm/{network}/custom dns getCustomDNS -// -// Gets custom DNS entries associated with a network. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: dnsResponse +// @Summary Gets custom DNS entries associated with a network +// @Router /api/dns/adm/{network}/custom [get] +// @Tags DNS +// @Accept json +// @Param network path string true "Network identifier" +// @Success 200 {array} models.DNSEntry +// @Failure 500 {object} models.ErrorResponse func getCustomDNS(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") @@ -97,8 +92,15 @@ func getCustomDNS(w http.ResponseWriter, r *http.Request) { network := params["network"] dns, err := logic.GetCustomDNS(network) if err != nil { - logger.Log(0, r.Header.Get("user"), - fmt.Sprintf("failed to get custom DNS entries for network [%s]: %v", network, err.Error())) + logger.Log( + 0, + r.Header.Get("user"), + fmt.Sprintf( + "failed to get custom DNS entries for network [%s]: %v", + network, + err.Error(), + ), + ) logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal")) return } @@ -106,17 +108,13 @@ func getCustomDNS(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(dns) } -// swagger:route GET /api/dns/adm/{network} dns getDNS -// -// Gets all DNS entries associated with the network. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: dnsResponse +// @Summary Get all DNS entries associated with the network +// @Router /api/dns/adm/{network} [get] +// @Tags DNS +// @Accept json +// @Param network path string true "Network identifier" +// @Success 200 {array} models.DNSEntry +// @Failure 500 {object} models.ErrorResponse func getDNS(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") @@ -135,17 +133,15 @@ func getDNS(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(dns) } -// swagger:route POST /api/dns/{network} dns createDNS -// -// Create a DNS entry. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: dnsResponse +// @Summary Create a new DNS entry +// @Router /api/dns/adm/{network} [post] +// @Tags DNS +// @Accept json +// @Param network path string true "Network identifier" +// @Param body body models.DNSEntry true "DNS entry details" +// @Success 200 {object} models.DNSEntry +// @Failure 400 {object} models.ErrorResponse +// @Failure 500 {object} models.ErrorResponse func createDNS(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") @@ -187,18 +183,14 @@ func createDNS(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(entry) } -// swagger:route DELETE /api/dns/{network}/{domain} dns deleteDNS -// -// Delete a DNS entry. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: stringJSONResponse -// *: stringJSONResponse +// @Summary Delete a DNS entry +// @Router /api/dns/{network}/{domain} [delete] +// @Tags DNS +// @Accept json +// @Param network path string true "Network identifier" +// @Param domain path string true "Domain Name" +// @Success 200 {array} models.DNSEntry +// @Failure 500 {object} models.ErrorResponse func deleteDNS(w http.ResponseWriter, r *http.Request) { // Set header w.Header().Set("Content-Type", "application/json") @@ -243,23 +235,22 @@ func GetDNSEntry(domain string, network string) (models.DNSEntry, error) { return entry, err } -// swagger:route POST /api/dns/adm/pushdns dns pushDNS -// -// Push DNS entries to nameserver. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: dnsResponse -// *: dnsResponse +// @Summary Push DNS entries to nameserver +// @Router /api/dns/adm/pushdns [post] +// @Tags DNS +// @Accept json +// @Success 200 {string} string "DNS Pushed to CoreDNS" +// @Failure 400 {object} models.ErrorResponse +// @Failure 500 {object} models.ErrorResponse func pushDNS(w http.ResponseWriter, r *http.Request) { // Set header w.Header().Set("Content-Type", "application/json") if !servercfg.IsDNSMode() { - logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("DNS Mode is set to off"), "badrequest")) + logic.ReturnErrorResponse( + w, + r, + logic.FormatError(errors.New("DNS Mode is set to off"), "badrequest"), + ) return } err := logic.SetDNS() diff --git a/controllers/docs.go b/controllers/docs.go deleted file mode 100644 index a3c2f94d..00000000 --- a/controllers/docs.go +++ /dev/null @@ -1,475 +0,0 @@ -// Package classification Netmaker -// -// # API Usage -// -// Most actions that can be performed via API can be performed via UI. We recommend managing your networks using the official netmaker-ui project. However, Netmaker can also be run without the UI, and all functions can be achieved via API calls. If your use case requires using Netmaker without the UI or you need to do some troubleshooting/advanced configuration, using the API directly may help. -// -// # Authentication -// -// API calls must be authenticated via a header of the format -H “Authorization: Bearer ” There are two methods to obtain YOUR_SECRET_KEY: 1. Using the masterkey. By default, this value is “secret key,” but you should change this on your instance and keep it secure. This value can be set via env var at startup or in a config file (config/environments/< env >.yaml). See the [Netmaker](https://docs.netmaker.org/index.html) documentation for more details. 2. Using a JWT received for a node. This can be retrieved by calling the /api/nodes//authenticate endpoint, as documented below. -// -// Schemes: https -// BasePath: / -// Version: 0.25.0 -// Host: api.demo.netmaker.io -// -// Consumes: -// - application/json -// -// Produces: -// - application/json -// -// Security: -// - oauth -// -// swagger:meta -package controller - -import ( - "os" - - "github.com/gravitl/netmaker/config" - "github.com/gravitl/netmaker/logic/acls" - "github.com/gravitl/netmaker/models" -) - -var _ = useUnused() // "use" the function to prevent "unused function" errors - -// swagger:parameters getFile -type filenameToGet struct { - // Filename - // in: path - // required: true - Filename string `json:"filename"` -} - -// swagger:response hasAdmin -type hasAdmin struct { - // in: body - Admin bool -} - -// swagger:response apiHostSliceResponse -type apiHostSliceResponse struct { - // in: body - Host []models.ApiHost -} - -// swagger:response apiHostResponse -type apiHostResponse struct { - // in: body - Host models.ApiHost -} - -// swagger:parameters getNodeDNS getCustomDNS getDNS -type dnsNetworkPathParam struct { - // Network - // in: path - Network string `json:"network"` -} - -// swagger:parameters createDNS -type dnsParams struct { - // Network - // in: path - Network string `json:"network"` - // DNS Entry - // in: body - Body []models.DNSEntry `json:"body"` -} - -// Success -// swagger:response dnsResponse -type dnsResponse struct { - // in: body - Body []models.DNSEntry `json:"body"` -} - -// swagger:parameters deleteDNS -type dnsDeletePathParams struct { - // Network - // in: path - Network string `json:"network"` - - // Domain - // in: path - Domain string `json:"domain"` -} - -// swagger:response stringJSONResponse -type stringJSONResponse struct { - // Response - // in: body - Response string `json:"response"` -} - -//swagger:response EnrollmentKey -type EnrollmentKey struct { - // in: body - EnrollmentKey models.EnrollmentKey -} - -//swagger:response EnrollmentKeys -type EnrollmentKeys struct { - // in: body - EnrollmentKeys []models.EnrollmentKey -} - -// swagger:parameters getAllExtClients -type getAllClientsRequest struct { - // Networks - // in:body - Networks []string `json:"networks"` -} - -// swagger:response extClientSliceResponse -type extClientSliceResponse struct { - // ExtClients - // in: body - ExtClients []models.ExtClient `json:"ext_clients"` -} - -// swagger:response extClientResponse -type extClientResponse struct { - // ExtClient - // in: body - ExtClient models.ExtClient `json:"ext_client"` -} - -// swagger:response fileResponse -type fileResponse struct { - // in: body - File os.File -} - -// swagger:response successResponse -type successResponse struct { - // Success Response - // in: body - SuccessResponse models.SuccessResponse `json:"success_response"` -} - -// swagger:parameters getExtClientConf -type extClientConfParams struct { - // Client ID - // in: path - ClientID string `json:"clientid"` - // Network - // in: path - Network string `json:"network"` - // Type - // in: path - Type string `json:"type"` -} - -// swagger:parameters getExtClient getExtClientConf updateExtClient deleteExtClient -type extClientPathParams struct { - // Client ID - // in: path - ClientID string `json:"clientid"` - // Network - // in: path - Network string `json:"network"` -} - -// swagger:parameters updateExtClient -type extClientBodyParam struct { - // ExtClient - // in: body - ExtClient models.ExtClient `json:"ext_client"` -} - -// swagger:parameters getNetworkExtClients -type extClientNetworkPathParam struct { - // Network - // in: path - Network string `json:"network"` -} - -// swagger:parameters createExtClient -type createExtClientPathParams struct { - // Network - // in: path - Network string `json:"network"` - - // Node ID - // in: path - NodeID string `json:"nodeid"` - - // Custom ExtClient - // in: body - CustomExtClient models.CustomExtClient `json:"custom_ext_client"` -} - -// swagger:parameters getNode updateNode deleteNode createRelay deleteRelay createEgressGateway deleteEgressGateway createIngressGateway deleteIngressGateway ingressGatewayUsers -type networkNodePathParams struct { - // in: path - Network string `json:"network"` - // in: path - NodeID string `json:"nodeid"` -} - -// swagger:response byteArrayResponse -type byteArrayResponse struct { - // in: body - ByteArray []byte `json:"byte_array"` -} - -// swagger:parameters getNetwork deleteNetwork updateNetwork getNetworkACL updateNetworkACL -type NetworkParam struct { - // name: network name - // in: path - Networkname string `json:"networkname"` -} - -// swagger:response getNetworksSliceResponse -type getNetworksSliceResponse struct { - // Networks - // in: body - Networks []models.Network `json:"networks"` -} - -// swagger:response hostPull -type hostPull struct { - // hostPull - // in: body - HostPull models.HostPull -} - -// swagger:parameters createNetwork updateNetwork -type networkBodyParam struct { - // Network - // in: body - Network models.Network `json:"network"` -} - -// swagger:parameters updateNetworkNodeLimit keyUpdate createAccessKey getAccessKeys getNetworkNodes -type networkPathParam struct { - // Network - // in: path - Network string `json:"network"` -} - -// swagger:response networkBodyResponse -type networkBodyResponse struct { - // Network - // in: body - Network models.Network `json:"network"` -} - -// swagger:parameters updateNetworkACL -type aclContainerBodyParam struct { - // ACL Container - // in: body - ACLContainer acls.ACLContainer `json:"acl_container"` -} - -// swagger:response aclContainerResponse -type aclContainerResponse struct { - // ACL Container - // in: body - ACLContainer acls.ACLContainer `json:"acl_container"` -} - -// swagger:response nodeSliceResponse -type nodeSliceResponse struct { - // Nodes - // in: body - Nodes []models.ApiNode `json:"nodes"` -} - -// swagger:response nodeResponse -type nodeResponse struct { - // Node - // in: body - Node models.LegacyNode `json:"node"` -} - -// swagger:parameters updateNode deleteNode -type nodeBodyParam struct { - // Node - // in: body - Node models.LegacyNode `json:"node"` -} - -//swagger:response okResponse -type okRespone struct{} - -// swagger:response RegisterResponse -type RegisterResponse struct { - // in: body - RegisterResponse models.RegisterResponse -} - -// swagger:parameters createRelay -type relayRequestBodyParam struct { - // Relay Request - // in: body - RelayRequest models.RelayRequest `json:"relay_request"` -} - -// swagger:parameters createEgressGateway -type egressGatewayBodyParam struct { - // Egress Gateway Request - // in: body - EgressGatewayRequest models.EgressGatewayRequest `json:"egress_gateway_request"` -} - -// swagger:parameters attachUserToRemoteAccessGateway removeUserFromRemoteAccessGW getUserRemoteAccessGws -type RemoteAccessGatewayUser struct { - // in: path - Username string `json:"username"` -} - -// swagger:parameters authenticate -type authParamBodyParam struct { - // network - // in: path - Network string `json:"network"` - // AuthParams - // in: body - AuthParams models.AuthParams `json:"auth_params"` -} - -// swagger:response signal -type signal struct { - // in: body - Signal models.Signal -} - -// swagger:parameters synchost deleteHost updateHost signalPeer updateKeys -type HostID struct { - // HostID - // in: path - HostID string `json:"hostid"` -} - -// swagger:parameters addHostToNetwork deleteHostFromNetwork -type HostFromNetworkParams struct { - // hostid to add or delete from network - // in: path - HostID string `json:"hostid"` - // network - // in: path - Network string `json:"network"` -} - -// swagger:parameters createEnrollmentKey -type createEnrollmentKeyParams struct { - // APIEnrollmentKey - // in: body - Body models.APIEnrollmentKey `json:"body"` -} - -// swagger:parameters updateEnrollmentKey -type updateEnrollmentKeyParams struct { - // KeyID - // in: path - KeyID string `json:"keyid"` - - // APIEnrollmentKey - // in: body - Body models.APIEnrollmentKey `json:"body"` -} - -// swagger:parameters deleteEnrollmentKey -type deleteEnrollmentKeyParam struct { - // in: path - KeyID string `json:"keyid"` -} - -// swagger:parameters handleHostRegister -type RegisterParams struct { - // in: path - Token string `json:"token"` - // in: body - Host models.Host `json:"host"` -} - -// swagger:response serverConfigResponse -type serverConfigResponse struct { - // Server Config - // in: body - // example - //{ - //"mqusername": "xxxxxxx" - //} - ServerConfig config.ServerConfig `json:"server_config"` -} - -// swagger:parameters createAdmin updateUser updateUserNetworks createUser -type userBodyParam struct { - // User - // in: body - User models.User `json:"user"` -} - -// swagger:response userBodyResponse -type userBodyResponse struct { - // User - // in: body - User models.User `json:"user"` -} - -// swagger:parameters authenticateUser -type userAuthBodyParam struct { - // User Auth Params - // in: body - UserAuthParams models.UserAuthParams `json:"user_auth_params"` -} - -// swagger:parameters updateUser updateUserNetworks updateUserAdm createUser deleteUser getUser -type usernamePathParam struct { - // Username - // in: path - Username string `json:"username"` -} - -// prevent issues with integration tests for types just used by Swagger docs. -func useUnused() bool { - _ = dnsParams{} - _ = dnsResponse{} - _ = dnsDeletePathParams{} - _ = stringJSONResponse{} - _ = getAllClientsRequest{} - _ = extClientSliceResponse{} - _ = extClientResponse{} - _ = successResponse{} - _ = extClientPathParams{} - _ = extClientBodyParam{} - _ = extClientNetworkPathParam{} - _ = createExtClientPathParams{} - _ = networkNodePathParams{} - _ = byteArrayResponse{} - _ = getNetworksSliceResponse{} - _ = networkBodyParam{} - _ = networkPathParam{} - _ = networkBodyResponse{} - _ = aclContainerBodyParam{} - _ = aclContainerResponse{} - _ = nodeSliceResponse{} - _ = nodeResponse{} - _ = nodeBodyParam{} - _ = relayRequestBodyParam{} - _ = egressGatewayBodyParam{} - _ = authParamBodyParam{} - _ = serverConfigResponse{} - _ = userBodyParam{} - _ = userBodyResponse{} - _ = userAuthBodyParam{} - _ = usernamePathParam{} - _ = hasAdmin{} - _ = apiHostSliceResponse{} - _ = apiHostResponse{} - _ = fileResponse{} - _ = extClientConfParams{} - _ = hostPull{} - _ = okRespone{} - _ = signal{} - _ = filenameToGet{} - _ = dnsNetworkPathParam{} - _ = createEnrollmentKeyParams{} - _ = updateEnrollmentKeyParams{} - _ = deleteEnrollmentKeyParam{} - return false -} diff --git a/controllers/enrollmentkeys.go b/controllers/enrollmentkeys.go index 87a189a4..71e9313d 100644 --- a/controllers/enrollmentkeys.go +++ b/controllers/enrollmentkeys.go @@ -32,17 +32,12 @@ func enrollmentKeyHandlers(r *mux.Router) { Methods(http.MethodPut) } -// swagger:route GET /api/v1/enrollment-keys enrollmentKeys getEnrollmentKeys -// -// Lists all EnrollmentKeys for admins. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: EnrollmentKeys +// @Summary Lists all EnrollmentKeys for admins +// @Router /api/v1/enrollment-keys [get] +// @Tags EnrollmentKeys +// @Security oauth +// @Success 200 {array} models.EnrollmentKey +// @Failure 500 {object} models.ErrorResponse func getEnrollmentKeys(w http.ResponseWriter, r *http.Request) { keys, err := logic.GetAllEnrollmentKeys() if err != nil { @@ -67,17 +62,13 @@ func getEnrollmentKeys(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(ret) } -// swagger:route DELETE /api/v1/enrollment-keys/{keyid} enrollmentKeys deleteEnrollmentKey -// -// Deletes an EnrollmentKey from Netmaker server. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: okResponse +// @Summary Deletes an EnrollmentKey from Netmaker server +// @Router /api/v1/enrollment-keys/{keyid} [delete] +// @Tags EnrollmentKeys +// @Security oauth +// @Param keyid path string true "Enrollment Key ID" +// @Success 200 +// @Failure 500 {object} models.ErrorResponse func deleteEnrollmentKey(w http.ResponseWriter, r *http.Request) { params := mux.Vars(r) keyID := params["keyID"] @@ -91,17 +82,14 @@ func deleteEnrollmentKey(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) } -// swagger:route POST /api/v1/enrollment-keys enrollmentKeys createEnrollmentKey -// -// Creates an EnrollmentKey for hosts to use on Netmaker server. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: EnrollmentKey +// @Summary Creates an EnrollmentKey for hosts to register with server and join networks +// @Router /api/v1/enrollment-keys [post] +// @Tags EnrollmentKeys +// @Security oauth +// @Param body body models.APIEnrollmentKey true "Enrollment Key parameters" +// @Success 200 {object} models.EnrollmentKey +// @Failure 400 {object} models.ErrorResponse +// @Failure 500 {object} models.ErrorResponse func createEnrollmentKey(w http.ResponseWriter, r *http.Request) { var enrollmentKeyBody models.APIEnrollmentKey @@ -121,7 +109,14 @@ func createEnrollmentKey(w http.ResponseWriter, r *http.Request) { if err != nil { logger.Log(0, r.Header.Get("user"), "error validating request body: ", err.Error()) - logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("validation error: name length must be between 3 and 32: %w", err), "badrequest")) + logic.ReturnErrorResponse( + w, + r, + logic.FormatError( + fmt.Errorf("validation error: name length must be between 3 and 32: %w", err), + "badrequest", + ), + ) return } @@ -180,17 +175,15 @@ func createEnrollmentKey(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(newEnrollmentKey) } -// swagger:route PUT /api/v1/enrollment-keys/{keyid} enrollmentKeys updateEnrollmentKey -// -// Updates an EnrollmentKey for hosts to use on Netmaker server. Updates only the relay to use. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: EnrollmentKey +// @Summary Updates an EnrollmentKey. Updates are only limited to the relay to use +// @Router /api/v1/enrollment-keys/{keyid} [put] +// @Tags EnrollmentKeys +// @Security oauth +// @Param keyid path string true "Enrollment Key ID" +// @Param body body models.APIEnrollmentKey true "Enrollment Key parameters" +// @Success 200 {object} models.EnrollmentKey +// @Failure 400 {object} models.ErrorResponse +// @Failure 500 {object} models.ErrorResponse func updateEnrollmentKey(w http.ResponseWriter, r *http.Request) { var enrollmentKeyBody models.APIEnrollmentKey params := mux.Vars(r) @@ -231,17 +224,15 @@ func updateEnrollmentKey(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(newEnrollmentKey) } -// swagger:route POST /api/v1/enrollment-keys/{token} enrollmentKeys handleHostRegister -// -// Handles a Netclient registration with server and add nodes accordingly. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: RegisterResponse +// @Summary Handles a Netclient registration with server and add nodes accordingly +// @Router /api/v1/host/register/{token} [post] +// @Tags EnrollmentKeys +// @Security oauth +// @Param token path string true "Enrollment Key Token" +// @Param body body models.Host true "Host registration parameters" +// @Success 200 {object} models.RegisterResponse +// @Failure 400 {object} models.ErrorResponse +// @Failure 500 {object} models.ErrorResponse func handleHostRegister(w http.ResponseWriter, r *http.Request) { params := mux.Vars(r) token := params["token"] diff --git a/controllers/ext_client.go b/controllers/ext_client.go index 1b1ec3dc..2452d49c 100644 --- a/controllers/ext_client.go +++ b/controllers/ext_client.go @@ -28,13 +28,20 @@ import ( func extClientHandlers(r *mux.Router) { - r.HandleFunc("/api/extclients", logic.SecurityCheck(true, http.HandlerFunc(getAllExtClients))).Methods(http.MethodGet) - r.HandleFunc("/api/extclients/{network}", logic.SecurityCheck(true, http.HandlerFunc(getNetworkExtClients))).Methods(http.MethodGet) - r.HandleFunc("/api/extclients/{network}/{clientid}", logic.SecurityCheck(false, http.HandlerFunc(getExtClient))).Methods(http.MethodGet) - r.HandleFunc("/api/extclients/{network}/{clientid}/{type}", logic.SecurityCheck(false, http.HandlerFunc(getExtClientConf))).Methods(http.MethodGet) - r.HandleFunc("/api/extclients/{network}/{clientid}", logic.SecurityCheck(false, http.HandlerFunc(updateExtClient))).Methods(http.MethodPut) - r.HandleFunc("/api/extclients/{network}/{clientid}", logic.SecurityCheck(false, http.HandlerFunc(deleteExtClient))).Methods(http.MethodDelete) - r.HandleFunc("/api/extclients/{network}/{nodeid}", logic.SecurityCheck(false, checkFreeTierLimits(limitChoiceMachines, http.HandlerFunc(createExtClient)))).Methods(http.MethodPost) + r.HandleFunc("/api/extclients", logic.SecurityCheck(true, http.HandlerFunc(getAllExtClients))). + Methods(http.MethodGet) + r.HandleFunc("/api/extclients/{network}", logic.SecurityCheck(true, http.HandlerFunc(getNetworkExtClients))). + Methods(http.MethodGet) + r.HandleFunc("/api/extclients/{network}/{clientid}", logic.SecurityCheck(false, http.HandlerFunc(getExtClient))). + Methods(http.MethodGet) + r.HandleFunc("/api/extclients/{network}/{clientid}/{type}", logic.SecurityCheck(false, http.HandlerFunc(getExtClientConf))). + Methods(http.MethodGet) + r.HandleFunc("/api/extclients/{network}/{clientid}", logic.SecurityCheck(false, http.HandlerFunc(updateExtClient))). + Methods(http.MethodPut) + r.HandleFunc("/api/extclients/{network}/{clientid}", logic.SecurityCheck(false, http.HandlerFunc(deleteExtClient))). + Methods(http.MethodDelete) + r.HandleFunc("/api/extclients/{network}/{nodeid}", logic.SecurityCheck(false, checkFreeTierLimits(limitChoiceMachines, http.HandlerFunc(createExtClient)))). + Methods(http.MethodPost) } func checkIngressExists(nodeID string) bool { @@ -45,18 +52,12 @@ func checkIngressExists(nodeID string) bool { return node.IsIngressGateway } -// swagger:route GET /api/extclients/{network} ext_client getNetworkExtClients -// -// Get all extclients associated with network. -// Gets all extclients associated with network, including pending extclients. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: extClientSliceResponse +// @Summary Get all remote access client associated with network +// @Router /api/extclients/{network} [get] +// @Tags Remote Access Client +// @Security oauth2 +// @Success 200 {object} models.ExtClient +// @Failure 500 {object} models.ErrorResponse func getNetworkExtClients(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") @@ -77,18 +78,12 @@ func getNetworkExtClients(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(extclients) } -// swagger:route GET /api/extclients ext_client getAllExtClients -// -// A separate function to get all extclients, not just extclients for a particular network. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: extClientSliceResponse -// +// @Summary Fetches All Remote Access Clients across all networks +// @Router /api/extclients [get] +// @Tags Remote Access Client +// @Security oauth2 +// @Success 200 {object} models.ExtClient +// @Failure 500 {object} models.ErrorResponse // Not quite sure if this is necessary. Probably necessary based on front end but may // want to review after iteration 1 if it's being used or not func getAllExtClients(w http.ResponseWriter, r *http.Request) { @@ -107,17 +102,13 @@ func getAllExtClients(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(clients) } -// swagger:route GET /api/extclients/{network}/{clientid} ext_client getExtClient -// -// Get an individual extclient. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: extClientResponse +// @Summary Get an individual remote access client +// @Router /api/extclients/{network}/{clientid} [get] +// @Tags Remote Access Client +// @Security oauth2 +// @Success 200 {object} models.ExtClient +// @Failure 500 {object} models.ErrorResponse +// @Failure 403 {object} models.ErrorResponse func getExtClient(w http.ResponseWriter, r *http.Request) { // set header. w.Header().Set("Content-Type", "application/json") @@ -128,8 +119,12 @@ func getExtClient(w http.ResponseWriter, r *http.Request) { network := params["network"] client, err := logic.GetExtClient(clientid, network) if err != nil { - logger.Log(0, r.Header.Get("user"), fmt.Sprintf("failed to get extclient for [%s] on network [%s]: %v", - clientid, network, err)) + logger.Log( + 0, + r.Header.Get("user"), + fmt.Sprintf("failed to get extclient for [%s] on network [%s]: %v", + clientid, network, err), + ) logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal")) return } @@ -137,7 +132,11 @@ func getExtClient(w http.ResponseWriter, r *http.Request) { // check if user has access to extclient slog.Error("failed to get extclient", "network", network, "clientID", clientid, "error", errors.New("access is denied")) - logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("access is denied"), "forbidden")) + logic.ReturnErrorResponse( + w, + r, + logic.FormatError(errors.New("access is denied"), "forbidden"), + ) return } @@ -146,17 +145,13 @@ func getExtClient(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(client) } -// swagger:route GET /api/extclients/{network}/{clientid}/{type} ext_client getExtClientConf -// -// Get an individual extclient. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: extClientResponse +// @Summary Get an individual remote access client +// @Router /api/extclients/{network}/{clientid}/{type} [get] +// @Tags Remote Access Client +// @Security oauth2 +// @Success 200 {object} models.ExtClient +// @Failure 500 {object} models.ErrorResponse +// @Failure 403 {object} models.ErrorResponse func getExtClientConf(w http.ResponseWriter, r *http.Request) { // set header. w.Header().Set("Content-Type", "application/json") @@ -166,36 +161,63 @@ func getExtClientConf(w http.ResponseWriter, r *http.Request) { networkid := params["network"] client, err := logic.GetExtClient(clientid, networkid) if err != nil { - logger.Log(0, r.Header.Get("user"), fmt.Sprintf("failed to get extclient for [%s] on network [%s]: %v", - clientid, networkid, err)) + logger.Log( + 0, + r.Header.Get("user"), + fmt.Sprintf("failed to get extclient for [%s] on network [%s]: %v", + clientid, networkid, err), + ) logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal")) return } if !logic.IsUserAllowedAccessToExtClient(r.Header.Get("user"), client) { slog.Error("failed to get extclient", "network", networkid, "clientID", clientid, "error", errors.New("access is denied")) - logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("access is denied"), "forbidden")) + logic.ReturnErrorResponse( + w, + r, + logic.FormatError(errors.New("access is denied"), "forbidden"), + ) return } gwnode, err := logic.GetNodeByID(client.IngressGatewayID) if err != nil { - logger.Log(0, r.Header.Get("user"), - fmt.Sprintf("failed to get ingress gateway node [%s] info: %v", client.IngressGatewayID, err)) + logger.Log( + 0, + r.Header.Get("user"), + fmt.Sprintf( + "failed to get ingress gateway node [%s] info: %v", + client.IngressGatewayID, + err, + ), + ) logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal")) return } host, err := logic.GetHost(gwnode.HostID.String()) if err != nil { - logger.Log(0, r.Header.Get("user"), - fmt.Sprintf("failed to get host for ingress gateway node [%s] info: %v", client.IngressGatewayID, err)) + logger.Log( + 0, + r.Header.Get("user"), + fmt.Sprintf( + "failed to get host for ingress gateway node [%s] info: %v", + client.IngressGatewayID, + err, + ), + ) logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal")) return } network, err := logic.GetParentNetwork(client.Network) if err != nil { - logger.Log(1, r.Header.Get("user"), "Could not retrieve Ingress Gateway Network", client.Network) + logger.Log( + 1, + r.Header.Get("user"), + "Could not retrieve Ingress Gateway Network", + client.Network, + ) logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal")) return } @@ -209,8 +231,19 @@ func getExtClientConf(w http.ResponseWriter, r *http.Request) { allowedPreferredIps = append(allowedPreferredIps, host.EndpointIP.String()) allowedPreferredIps = append(allowedPreferredIps, host.EndpointIPv6.String()) if !slices.Contains(allowedPreferredIps, preferredIp) { - slog.Warn("preferred endpoint ip is not associated with the RAG. proceeding with preferred ip", "preferred ip", preferredIp) - logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("preferred endpoint ip is not associated with the RAG"), "badrequest")) + slog.Warn( + "preferred endpoint ip is not associated with the RAG. proceeding with preferred ip", + "preferred ip", + preferredIp, + ) + logic.ReturnErrorResponse( + w, + r, + logic.FormatError( + errors.New("preferred endpoint ip is not associated with the RAG"), + "badrequest", + ), + ) return } if net.ParseIP(preferredIp).To4() == nil { @@ -354,16 +387,14 @@ Endpoint = %s json.NewEncoder(w).Encode(client) } -// swagger:route POST /api/extclients/{network}/{nodeid} ext_client createExtClient -// -// Create an individual extclient. Must have valid key and be unique. -// -// Schemes: https -// -// Security: -// oauth -// Responses: -// 200: okResponse +// @Summary Create an individual remote access client +// @Router /api/extclients/{network}/{nodeid} [post] +// @Tags Remote Access Client +// @Security oauth2 +// @Success 200 {string} string "OK" +// @Failure 500 {object} models.ErrorResponse +// @Failure 400 {object} models.ErrorResponse +// @Failure 403 {object} models.ErrorResponse func createExtClient(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") @@ -466,16 +497,40 @@ func createExtClient(w http.ResponseWriter, r *http.Request) { } if err = logic.CreateExtClient(&extclient); err != nil { - slog.Error("failed to create extclient", "user", r.Header.Get("user"), "network", node.Network, "error", err) + slog.Error( + "failed to create extclient", + "user", + r.Header.Get("user"), + "network", + node.Network, + "error", + err, + ) logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal")) return } - slog.Info("created extclient", "user", r.Header.Get("user"), "network", node.Network, "clientid", extclient.ClientID) + slog.Info( + "created extclient", + "user", + r.Header.Get("user"), + "network", + node.Network, + "clientid", + extclient.ClientID, + ) w.WriteHeader(http.StatusOK) go func() { if err := logic.SetClientDefaultACLs(&extclient); err != nil { - slog.Error("failed to set default acls for extclient", "user", r.Header.Get("user"), "network", node.Network, "error", err) + slog.Error( + "failed to set default acls for extclient", + "user", + r.Header.Get("user"), + "network", + node.Network, + "error", + err, + ) logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal")) return } @@ -488,17 +543,14 @@ func createExtClient(w http.ResponseWriter, r *http.Request) { }() } -// swagger:route PUT /api/extclients/{network}/{clientid} ext_client updateExtClient -// -// Update an individual extclient. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: extClientResponse +// @Summary Update an individual remote access client +// @Router /api/extclients/{network}/{clientid} [put] +// @Tags Remote Access Client +// @Security oauth2 +// @Success 200 {object} models.ExtClient +// @Failure 500 {object} models.ErrorResponse +// @Failure 400 {object} models.ErrorResponse +// @Failure 403 {object} models.ErrorResponse func updateExtClient(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") @@ -518,7 +570,15 @@ func updateExtClient(w http.ResponseWriter, r *http.Request) { network := params["network"] oldExtClient, err := logic.GetExtClientByName(clientid) if err != nil { - slog.Error("failed to retrieve extclient", "user", r.Header.Get("user"), "id", clientid, "error", err) + slog.Error( + "failed to retrieve extclient", + "user", + r.Header.Get("user"), + "id", + clientid, + "error", + err, + ) logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal")) return } @@ -526,7 +586,11 @@ func updateExtClient(w http.ResponseWriter, r *http.Request) { // check if user has access to extclient slog.Error("failed to get extclient", "network", network, "clientID", clientid, "error", errors.New("access is denied")) - logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("access is denied"), "forbidden")) + logic.ReturnErrorResponse( + w, + r, + logic.FormatError(errors.New("access is denied"), "forbidden"), + ) return } @@ -567,12 +631,32 @@ func updateExtClient(w http.ResponseWriter, r *http.Request) { } newclient := logic.UpdateExtClient(&oldExtClient, &update) if err := logic.DeleteExtClient(oldExtClient.Network, oldExtClient.ClientID); err != nil { - slog.Error("failed to delete ext client", "user", r.Header.Get("user"), "id", oldExtClient.ClientID, "network", oldExtClient.Network, "error", err) + slog.Error( + "failed to delete ext client", + "user", + r.Header.Get("user"), + "id", + oldExtClient.ClientID, + "network", + oldExtClient.Network, + "error", + err, + ) logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal")) return } if err := logic.SaveExtClient(&newclient); err != nil { - slog.Error("failed to save ext client", "user", r.Header.Get("user"), "id", newclient.ClientID, "network", newclient.Network, "error", err) + slog.Error( + "failed to save ext client", + "user", + r.Header.Get("user"), + "id", + newclient.ClientID, + "network", + newclient.Network, + "error", + err, + ) logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal")) return } @@ -588,13 +672,25 @@ func updateExtClient(w http.ResponseWriter, r *http.Request) { ingressNode, err := logic.GetNodeByID(newclient.IngressGatewayID) if err == nil { if err = mq.PublishPeerUpdate(false); err != nil { - logger.Log(1, "error setting ext peers on", ingressNode.ID.String(), ":", err.Error()) + logger.Log( + 1, + "error setting ext peers on", + ingressNode.ID.String(), + ":", + err.Error(), + ) } } if !update.Enabled { ingressHost, err := logic.GetHost(ingressNode.HostID.String()) if err != nil { - slog.Error("Failed to get ingress host", "node", ingressNode.ID.String(), "error", err) + slog.Error( + "Failed to get ingress host", + "node", + ingressNode.ID.String(), + "error", + err, + ) return } nodes, err := logic.GetAllNodes() @@ -602,7 +698,13 @@ func updateExtClient(w http.ResponseWriter, r *http.Request) { slog.Error("Failed to get nodes", "error", err) return } - go mq.PublishSingleHostPeerUpdate(ingressHost, nodes, nil, []models.ExtClient{oldExtClient}, false) + go mq.PublishSingleHostPeerUpdate( + ingressHost, + nodes, + nil, + []models.ExtClient{oldExtClient}, + false, + ) } } @@ -610,17 +712,13 @@ func updateExtClient(w http.ResponseWriter, r *http.Request) { } -// swagger:route DELETE /api/extclients/{network}/{clientid} ext_client deleteExtClient -// -// Delete an individual extclient. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: successResponse +// @Summary Delete an individual remote access client +// @Router /api/extclients/{network}/{clientid} [delete] +// @Tags Remote Access Client +// @Security oauth2 +// @Success 200 +// @Failure 500 {object} models.ErrorResponse +// @Failure 403 {object} models.ErrorResponse func deleteExtClient(w http.ResponseWriter, r *http.Request) { // Set header w.Header().Set("Content-Type", "application/json") @@ -640,13 +738,24 @@ func deleteExtClient(w http.ResponseWriter, r *http.Request) { if !logic.IsUserAllowedAccessToExtClient(r.Header.Get("user"), extclient) { slog.Error("user not allowed to delete", "network", network, "clientID", clientid, "error", errors.New("access is denied")) - logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("access is denied"), "forbidden")) + logic.ReturnErrorResponse( + w, + r, + logic.FormatError(errors.New("access is denied"), "forbidden"), + ) return } ingressnode, err := logic.GetNodeByID(extclient.IngressGatewayID) if err != nil { - logger.Log(0, r.Header.Get("user"), - fmt.Sprintf("failed to get ingress gateway node [%s] info: %v", extclient.IngressGatewayID, err)) + logger.Log( + 0, + r.Header.Get("user"), + fmt.Sprintf( + "failed to get ingress gateway node [%s] info: %v", + extclient.IngressGatewayID, + err, + ), + ) logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal")) return } diff --git a/controllers/files.go b/controllers/files.go index e4e6bf0f..69dcec48 100644 --- a/controllers/files.go +++ b/controllers/files.go @@ -6,16 +6,12 @@ import ( "github.com/gorilla/mux" ) +// @Summary Retrieve a file from the file server +// @Router /meshclient/files/{filename} [get] +// @Tags Meshclient +// @Success 200 {body} file "file" +// @Failure 404 {string} string "404 not found" func fileHandlers(r *mux.Router) { - // swagger:route GET /meshclient/files/{filename} meshclient getFile - // - // Retrieve a file from the file server. - // - // Schemes: https - // - // Security: - // oauth - // Responses: - // 200: fileResponse - r.PathPrefix("/meshclient/files").Handler(http.StripPrefix("/meshclient/files", http.FileServer(http.Dir("./meshclient/files")))) + r.PathPrefix("/meshclient/files"). + Handler(http.StripPrefix("/meshclient/files", http.FileServer(http.Dir("./meshclient/files")))) } diff --git a/controllers/hosts.go b/controllers/hosts.go index 440fd74e..ebcd8059 100644 --- a/controllers/hosts.go +++ b/controllers/hosts.go @@ -19,23 +19,43 @@ import ( ) func hostHandlers(r *mux.Router) { - r.HandleFunc("/api/hosts", logic.SecurityCheck(true, http.HandlerFunc(getHosts))).Methods(http.MethodGet) - r.HandleFunc("/api/hosts/keys", logic.SecurityCheck(true, http.HandlerFunc(updateAllKeys))).Methods(http.MethodPut) - r.HandleFunc("/api/hosts/{hostid}/keys", logic.SecurityCheck(true, http.HandlerFunc(updateKeys))).Methods(http.MethodPut) - r.HandleFunc("/api/hosts/{hostid}/sync", logic.SecurityCheck(true, http.HandlerFunc(syncHost))).Methods(http.MethodPost) - r.HandleFunc("/api/hosts/{hostid}", logic.SecurityCheck(true, http.HandlerFunc(updateHost))).Methods(http.MethodPut) - r.HandleFunc("/api/hosts/{hostid}", Authorize(true, false, "all", http.HandlerFunc(deleteHost))).Methods(http.MethodDelete) - r.HandleFunc("/api/hosts/{hostid}/upgrade", logic.SecurityCheck(true, http.HandlerFunc(upgradeHost))).Methods(http.MethodPut) - r.HandleFunc("/api/hosts/{hostid}/networks/{network}", logic.SecurityCheck(true, http.HandlerFunc(addHostToNetwork))).Methods(http.MethodPost) - r.HandleFunc("/api/hosts/{hostid}/networks/{network}", logic.SecurityCheck(true, http.HandlerFunc(deleteHostFromNetwork))).Methods(http.MethodDelete) + r.HandleFunc("/api/hosts", logic.SecurityCheck(true, http.HandlerFunc(getHosts))). + Methods(http.MethodGet) + r.HandleFunc("/api/hosts/keys", logic.SecurityCheck(true, http.HandlerFunc(updateAllKeys))). + Methods(http.MethodPut) + r.HandleFunc("/api/hosts/{hostid}/keys", logic.SecurityCheck(true, http.HandlerFunc(updateKeys))). + Methods(http.MethodPut) + r.HandleFunc("/api/hosts/{hostid}/sync", logic.SecurityCheck(true, http.HandlerFunc(syncHost))). + Methods(http.MethodPost) + r.HandleFunc("/api/hosts/{hostid}", logic.SecurityCheck(true, http.HandlerFunc(updateHost))). + Methods(http.MethodPut) + r.HandleFunc("/api/hosts/{hostid}", Authorize(true, false, "all", http.HandlerFunc(deleteHost))). + Methods(http.MethodDelete) + r.HandleFunc("/api/hosts/{hostid}/upgrade", logic.SecurityCheck(true, http.HandlerFunc(upgradeHost))). + Methods(http.MethodPut) + r.HandleFunc("/api/hosts/{hostid}/networks/{network}", logic.SecurityCheck(true, http.HandlerFunc(addHostToNetwork))). + Methods(http.MethodPost) + r.HandleFunc("/api/hosts/{hostid}/networks/{network}", logic.SecurityCheck(true, http.HandlerFunc(deleteHostFromNetwork))). + Methods(http.MethodDelete) r.HandleFunc("/api/hosts/adm/authenticate", authenticateHost).Methods(http.MethodPost) - r.HandleFunc("/api/v1/host", Authorize(true, false, "host", http.HandlerFunc(pull))).Methods(http.MethodGet) - r.HandleFunc("/api/v1/host/{hostid}/signalpeer", Authorize(true, false, "host", http.HandlerFunc(signalPeer))).Methods(http.MethodPost) - r.HandleFunc("/api/v1/fallback/host/{hostid}", Authorize(true, false, "host", http.HandlerFunc(hostUpdateFallback))).Methods(http.MethodPut) - r.HandleFunc("/api/emqx/hosts", logic.SecurityCheck(true, http.HandlerFunc(delEmqxHosts))).Methods(http.MethodDelete) + r.HandleFunc("/api/v1/host", Authorize(true, false, "host", http.HandlerFunc(pull))). + Methods(http.MethodGet) + r.HandleFunc("/api/v1/host/{hostid}/signalpeer", Authorize(true, false, "host", http.HandlerFunc(signalPeer))). + Methods(http.MethodPost) + r.HandleFunc("/api/v1/fallback/host/{hostid}", Authorize(true, false, "host", http.HandlerFunc(hostUpdateFallback))). + Methods(http.MethodPut) + r.HandleFunc("/api/emqx/hosts", logic.SecurityCheck(true, http.HandlerFunc(delEmqxHosts))). + Methods(http.MethodDelete) r.HandleFunc("/api/v1/auth-register/host", socketHandler) } +// @Summary Upgrade a host +// @Router /api/hosts/{hostid}/upgrade [put] +// @Tags Hosts +// @Security oauth +// @Param hostid path string true "Host ID" +// @Success 200 {string} string "passed message to upgrade host" +// @Failure 500 {object} models.ErrorResponse // upgrade host is a handler to send upgrade message to a host func upgradeHost(w http.ResponseWriter, r *http.Request) { host, err := logic.GetHost(mux.Vars(r)["hostid"]) @@ -52,17 +72,12 @@ func upgradeHost(w http.ResponseWriter, r *http.Request) { logic.ReturnSuccessResponse(w, r, "passed message to upgrade host") } -// swagger:route GET /api/hosts hosts getHosts -// -// Lists all hosts. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: apiHostSliceResponse +// @Summary List all hosts +// @Router /api/hosts [get] +// @Tags Hosts +// @Security oauth +// @Success 200 {array} models.ApiHost +// @Failure 500 {object} models.ErrorResponse func getHosts(w http.ResponseWriter, r *http.Request) { currentHosts, err := logic.GetAllHosts() if err != nil { @@ -77,23 +92,22 @@ func getHosts(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(apiHosts) } -// swagger:route GET /api/v1/host hosts pullHost -// -// Used by clients for "pull" command -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: hostPull +// @Summary Used by clients for "pull" command +// @Router /api/v1/host [get] +// @Tags Hosts +// @Security oauth +// @Success 200 {object} models.HostPull +// @Failure 500 {object} models.ErrorResponse func pull(w http.ResponseWriter, r *http.Request) { hostID := r.Header.Get(hostIDHeader) // return JSON/API formatted keys if len(hostID) == 0 { logger.Log(0, "no host authorized to pull") - logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("no host authorized to pull"), "internal")) + logic.ReturnErrorResponse( + w, + r, + logic.FormatError(fmt.Errorf("no host authorized to pull"), "internal"), + ) return } host, err := logic.GetHost(hostID) @@ -153,17 +167,14 @@ func pull(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(&response) } -// swagger:route PUT /api/hosts/{hostid} hosts updateHost -// -// Updates a Netclient host on Netmaker server. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: apiHostResponse +// @Summary Updates a Netclient host on Netmaker server +// @Router /api/hosts/{hostid} [put] +// @Tags Hosts +// @Security oauth +// @Param hostid path string true "Host ID" +// @Param body body models.ApiHost true "New host data" +// @Success 200 {object} models.ApiHost +// @Failure 500 {object} models.ErrorResponse func updateHost(w http.ResponseWriter, r *http.Request) { var newHostData models.ApiHost err := json.NewDecoder(r.Body).Decode(&newHostData) @@ -194,7 +205,13 @@ func updateHost(w http.ResponseWriter, r *http.Request) { Action: models.UpdateHost, Host: *newHost, }); err != nil { - logger.Log(0, r.Header.Get("user"), "failed to send host update: ", currHost.ID.String(), err.Error()) + logger.Log( + 0, + r.Header.Get("user"), + "failed to send host update: ", + currHost.ID.String(), + err.Error(), + ) } go func() { if err := mq.PublishPeerUpdate(false); err != nil { @@ -213,17 +230,14 @@ func updateHost(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(apiHostData) } -// swagger:route PUT /api/v1/fallback/host/{hostid} hosts hostUpdateFallback -// -// Updates a Netclient host on Netmaker server. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: apiHostResponse +// @Summary Updates a Netclient host on Netmaker server +// @Router /api/v1/fallback/host/{hostid} [put] +// @Tags Hosts +// @Security oauth +// @Param hostid path string true "Host ID" +// @Param body body models.HostUpdate true "Host update data" +// @Success 200 {string} string "updated host data" +// @Failure 500 {object} models.ErrorResponse func hostUpdateFallback(w http.ResponseWriter, r *http.Request) { var params = mux.Vars(r) hostid := params["hostid"] @@ -273,17 +287,14 @@ func hostUpdateFallback(w http.ResponseWriter, r *http.Request) { logic.ReturnSuccessResponse(w, r, "updated host data") } -// swagger:route DELETE /api/hosts/{hostid} hosts deleteHost -// -// Deletes a Netclient host from Netmaker server. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: apiHostResponse +// @Summary Deletes a Netclient host from Netmaker server +// @Router /api/hosts/{hostid} [delete] +// @Tags Hosts +// @Security oauth +// @Param hostid path string true "Host ID" +// @Param force query bool false "Force delete" +// @Success 200 {object} models.ApiHost +// @Failure 500 {object} models.ErrorResponse func deleteHost(w http.ResponseWriter, r *http.Request) { var params = mux.Vars(r) hostid := params["hostid"] @@ -312,14 +323,26 @@ func deleteHost(w http.ResponseWriter, r *http.Request) { if servercfg.GetBrokerType() == servercfg.EmqxBrokerType { // delete EMQX credentials for host if err := mq.GetEmqxHandler().DeleteEmqxUser(currHost.ID.String()); err != nil { - slog.Error("failed to remove host credentials from EMQX", "id", currHost.ID, "error", err) + slog.Error( + "failed to remove host credentials from EMQX", + "id", + currHost.ID, + "error", + err, + ) } } if err = mq.HostUpdate(&models.HostUpdate{ Action: models.DeleteHost, Host: *currHost, }); err != nil { - logger.Log(0, r.Header.Get("user"), "failed to send delete host update: ", currHost.ID.String(), err.Error()) + logger.Log( + 0, + r.Header.Get("user"), + "failed to send delete host update: ", + currHost.ID.String(), + err.Error(), + ) } if err = logic.RemoveHost(currHost, forceDelete); err != nil { logger.Log(0, r.Header.Get("user"), "failed to delete a host:", err.Error()) @@ -333,23 +356,25 @@ func deleteHost(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(apiHostData) } -// swagger:route POST /api/hosts/{hostid}/networks/{network} hosts addHostToNetwork -// -// Given a network, a host is added to the network. -// -// Schemes: https -// -// Security: -// oauth -// Responses: -// 200: okResponse +// @Summary To Add Host To Network +// @Router /api/hosts/{hostid}/networks/{network} [post] +// @Tags Hosts +// @Security oauth +// @Param hostid path string true "Host ID" +// @Param network path string true "Network name" +// @Success 200 {string} string "OK" +// @Failure 500 {object} models.ErrorResponse func addHostToNetwork(w http.ResponseWriter, r *http.Request) { var params = mux.Vars(r) hostid := params["hostid"] network := params["network"] if hostid == "" || network == "" { - logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("hostid or network cannot be empty"), "badrequest")) + logic.ReturnErrorResponse( + w, + r, + logic.FormatError(errors.New("hostid or network cannot be empty"), "badrequest"), + ) return } // confirm host exists @@ -362,7 +387,14 @@ func addHostToNetwork(w http.ResponseWriter, r *http.Request) { newNode, err := logic.UpdateHostNetwork(currHost, network, true) if err != nil { - logger.Log(0, r.Header.Get("user"), "failed to add host to network:", hostid, network, err.Error()) + logger.Log( + 0, + r.Header.Get("user"), + "failed to add host to network:", + hostid, + network, + err.Error(), + ) logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal")) return } @@ -384,21 +416,23 @@ func addHostToNetwork(w http.ResponseWriter, r *http.Request) { logic.SetDNS() } }() - logger.Log(2, r.Header.Get("user"), fmt.Sprintf("added host %s to network %s", currHost.Name, network)) + logger.Log( + 2, + r.Header.Get("user"), + fmt.Sprintf("added host %s to network %s", currHost.Name, network), + ) w.WriteHeader(http.StatusOK) } -// swagger:route DELETE /api/hosts/{hostid}/networks/{network} hosts deleteHostFromNetwork -// -// Given a network, a host is removed from the network. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: okResponse +// @Summary To Remove Host from Network +// @Router /api/hosts/{hostid}/networks/{network} [delete] +// @Tags Hosts +// @Security oauth +// @Param hostid path string true "Host ID" +// @Param network path string true "Network name" +// @Param force query bool false "Force delete" +// @Success 200 {string} string "OK" +// @Failure 500 {object} models.ErrorResponse func deleteHostFromNetwork(w http.ResponseWriter, r *http.Request) { var params = mux.Vars(r) @@ -406,7 +440,11 @@ func deleteHostFromNetwork(w http.ResponseWriter, r *http.Request) { network := params["network"] forceDelete := r.URL.Query().Get("force") == "true" if hostid == "" || network == "" { - logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("hostid or network cannot be empty"), "badrequest")) + logic.ReturnErrorResponse( + w, + r, + logic.FormatError(errors.New("hostid or network cannot be empty"), "badrequest"), + ) return } // confirm host exists @@ -416,14 +454,29 @@ func deleteHostFromNetwork(w http.ResponseWriter, r *http.Request) { // check if there is any daemon nodes that needs to be deleted node, err := logic.GetNodeByHostRef(hostid, network) if err != nil { - slog.Error("couldn't get node for host", "hostid", hostid, "network", network, "error", err) + slog.Error( + "couldn't get node for host", + "hostid", + hostid, + "network", + network, + "error", + err, + ) logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest")) return } if err = logic.DeleteNodeByID(&node); err != nil { slog.Error("failed to force delete daemon node", "nodeid", node.ID.String(), "hostid", hostid, "network", network, "error", err) - logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("failed to force delete daemon node: "+err.Error()), "internal")) + logic.ReturnErrorResponse( + w, + r, + logic.FormatError( + fmt.Errorf("failed to force delete daemon node: "+err.Error()), + "internal", + ), + ) return } logic.ReturnSuccessResponse(w, r, "force deleted daemon node successfully") @@ -441,20 +494,42 @@ func deleteHostFromNetwork(w http.ResponseWriter, r *http.Request) { // force cleanup the node node, err := logic.GetNodeByHostRef(hostid, network) if err != nil { - slog.Error("couldn't get node for host", "hostid", hostid, "network", network, "error", err) + slog.Error( + "couldn't get node for host", + "hostid", + hostid, + "network", + network, + "error", + err, + ) logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest")) return } if err = logic.DeleteNodeByID(&node); err != nil { slog.Error("failed to force delete daemon node", "nodeid", node.ID.String(), "hostid", hostid, "network", network, "error", err) - logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("failed to force delete daemon node: "+err.Error()), "internal")) + logic.ReturnErrorResponse( + w, + r, + logic.FormatError( + fmt.Errorf("failed to force delete daemon node: "+err.Error()), + "internal", + ), + ) return } logic.ReturnSuccessResponse(w, r, "force deleted daemon node successfully") return } - logger.Log(0, r.Header.Get("user"), "failed to remove host from network:", hostid, network, err.Error()) + logger.Log( + 0, + r.Header.Get("user"), + "failed to remove host from network:", + hostid, + network, + err.Error(), + ) logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal")) return } @@ -464,7 +539,11 @@ func deleteHostFromNetwork(w http.ResponseWriter, r *http.Request) { } logger.Log(1, "deleting node", node.ID.String(), "from host", currHost.Name) if err := logic.DeleteNode(node, forceDelete); err != nil { - logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("failed to delete node"), "internal")) + logic.ReturnErrorResponse( + w, + r, + logic.FormatError(fmt.Errorf("failed to delete node"), "internal"), + ) return } go func() { @@ -473,21 +552,23 @@ func deleteHostFromNetwork(w http.ResponseWriter, r *http.Request) { logic.SetDNS() } }() - logger.Log(2, r.Header.Get("user"), fmt.Sprintf("removed host %s from network %s", currHost.Name, network)) + logger.Log( + 2, + r.Header.Get("user"), + fmt.Sprintf("removed host %s from network %s", currHost.Name, network), + ) w.WriteHeader(http.StatusOK) } -// swagger:route POST /api/hosts/adm/authenticate authenticate authenticateHost -// -// Host based authentication for making further API calls. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: successResponse +// @Summary To Fetch Auth Token for a Host +// @Router /api/hosts/adm/authenticate [post] +// @Tags Auth +// @Accept json +// @Param body body models.AuthParams true "Authentication parameters" +// @Success 200 {object} models.SuccessResponse +// @Failure 400 {object} models.ErrorResponse +// @Failure 401 {object} models.ErrorResponse +// @Failure 500 {object} models.ErrorResponse func authenticateHost(response http.ResponseWriter, request *http.Request) { var authRequest models.AuthParams var errorResponse = models.ErrorResponse{ @@ -579,17 +660,14 @@ func authenticateHost(response http.ResponseWriter, request *http.Request) { response.Write(successJSONResponse) } -// swagger:route POST /api/hosts/{hostid}/signalpeer hosts signalPeer -// -// send signal to peer. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: signal +// @Summary Send signal to peer +// @Router /api/v1/host/{hostid}/signalpeer [post] +// @Tags Hosts +// @Security oauth +// @Param hostid path string true "Host ID" +// @Param body body models.Signal true "Signal data" +// @Success 200 {object} models.Signal +// @Failure 400 {object} models.ErrorResponse func signalPeer(w http.ResponseWriter, r *http.Request) { var params = mux.Vars(r) hostid := params["hostid"] @@ -617,7 +695,11 @@ func signalPeer(w http.ResponseWriter, r *http.Request) { signal.IsPro = servercfg.IsPro peerHost, err := logic.GetHost(signal.ToHostID) if err != nil { - logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("failed to signal, peer not found"), "badrequest")) + logic.ReturnErrorResponse( + w, + r, + logic.FormatError(errors.New("failed to signal, peer not found"), "badrequest"), + ) return } err = mq.HostUpdate(&models.HostUpdate{ @@ -626,7 +708,14 @@ func signalPeer(w http.ResponseWriter, r *http.Request) { Signal: signal, }) if err != nil { - logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("failed to publish signal to peer: "+err.Error()), "badrequest")) + logic.ReturnErrorResponse( + w, + r, + logic.FormatError( + errors.New("failed to publish signal to peer: "+err.Error()), + "badrequest", + ), + ) return } @@ -634,17 +723,12 @@ func signalPeer(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(signal) } -// swagger:route POST /api/hosts/keys hosts updateAllKeys -// -// Update keys for a network. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: networkBodyResponse +// @Summary Update keys for all hosts +// @Router /api/hosts/keys [put] +// @Tags Hosts +// @Security oauth +// @Success 200 {string} string "OK" +// @Failure 400 {object} models.ErrorResponse func updateAllKeys(w http.ResponseWriter, r *http.Request) { var errorResponse = models.ErrorResponse{} w.Header().Set("Content-Type", "application/json") @@ -664,7 +748,12 @@ func updateAllKeys(w http.ResponseWriter, r *http.Request) { hostUpdate.Host = host logger.Log(2, "updating host", host.ID.String(), " for a key update") if err = mq.HostUpdate(&hostUpdate); err != nil { - logger.Log(0, "failed to send update to node during a network wide key update", host.ID.String(), err.Error()) + logger.Log( + 0, + "failed to send update to node during a network wide key update", + host.ID.String(), + err.Error(), + ) } } }() @@ -672,17 +761,13 @@ func updateAllKeys(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) } -// swagger:route POST /api/hosts/{hostid}keys hosts updateKeys -// -// Update keys for a network. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: networkBodyResponse +// @Summary Update keys for a host +// @Router /api/hosts/{hostid}/keys [put] +// @Tags Hosts +// @Security oauth +// @Param hostid path string true "Host ID" +// @Success 200 {string} string "OK" +// @Failure 400 {object} models.ErrorResponse func updateKeys(w http.ResponseWriter, r *http.Request) { var errorResponse = models.ErrorResponse{} w.Header().Set("Content-Type", "application/json") @@ -711,17 +796,13 @@ func updateKeys(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) } -// swagger:route POST /api/hosts/{hostid}/sync hosts synchost -// -// Requests a host to pull. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: networkBodyResponse +// @Summary Requests a host to pull +// @Router /api/hosts/{hostid}/sync [post] +// @Tags Hosts +// @Security oauth +// @Param hostid path string true "Host ID" +// @Success 200 {string} string "OK" +// @Failure 400 {object} models.ErrorResponse func syncHost(w http.ResponseWriter, r *http.Request) { hostId := mux.Vars(r)["hostid"] @@ -751,17 +832,12 @@ func syncHost(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) } -// swagger:route DELETE /api/emqx/hosts hosts delEmqxHosts -// -// Lists all hosts. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: apiHostResponse +// @Summary Deletes all EMQX hosts +// @Router /api/emqx/hosts [delete] +// @Tags Hosts +// @Security oauth +// @Success 200 {string} string "deleted hosts data on emqx" +// @Failure 500 {object} models.ErrorResponse func delEmqxHosts(w http.ResponseWriter, r *http.Request) { currentHosts, err := logic.GetAllHosts() if err != nil { @@ -777,7 +853,13 @@ func delEmqxHosts(w http.ResponseWriter, r *http.Request) { } err = mq.GetEmqxHandler().DeleteEmqxUser(servercfg.GetMqUserName()) if err != nil { - slog.Error("failed to remove server credentials from EMQX", "user", servercfg.GetMqUserName(), "error", err) + slog.Error( + "failed to remove server credentials from EMQX", + "user", + servercfg.GetMqUserName(), + "error", + err, + ) } logic.ReturnSuccessResponse(w, r, "deleted hosts data on emqx") } diff --git a/controllers/ipservice.go b/controllers/ipservice.go index 59e09d04..1c931c8e 100644 --- a/controllers/ipservice.go +++ b/controllers/ipservice.go @@ -15,17 +15,12 @@ func ipHandlers(r *mux.Router) { r.HandleFunc("/api/getip", http.HandlerFunc(getPublicIP)).Methods(http.MethodGet) } -// swagger:route GET /api/getip ipservice getPublicIP -// -// Get the current public IP address. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: byteArrayResponse +// @Summary Get the current public IP address. +// @Router /api/getip [get] +// @Tags IP Service +// @Security oauth2 +// @Success 200 {string} string "The public IP address." +// @Failure 400 {string} string "Invalid IP address or no IP found." func getPublicIP(w http.ResponseWriter, r *http.Request) { r.Header.Set("Connection", "close") ip, err := parseIP(r) diff --git a/controllers/legacy.go b/controllers/legacy.go index a6115be9..c118fb7d 100644 --- a/controllers/legacy.go +++ b/controllers/legacy.go @@ -9,20 +9,16 @@ import ( ) func legacyHandlers(r *mux.Router) { - r.HandleFunc("/api/v1/legacy/nodes", logic.SecurityCheck(true, http.HandlerFunc(wipeLegacyNodes))).Methods(http.MethodDelete) + r.HandleFunc("/api/v1/legacy/nodes", logic.SecurityCheck(true, http.HandlerFunc(wipeLegacyNodes))). + Methods(http.MethodDelete) } -// swagger:route DELETE /api/v1/legacy/nodes nodes wipeLegacyNodes -// -// Delete all legacy nodes from DB. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: successResponse +// @Summary Delete all legacy nodes from DB. +// @Router /api/v1/legacy/nodes [delete] +// @Tags Nodes +// @Security oauth2 +// @Success 200 {string} string "Wiped all legacy nodes." +// @Failure 400 {object} models.ErrorResponse func wipeLegacyNodes(w http.ResponseWriter, r *http.Request) { // Set header w.Header().Set("Content-Type", "application/json") diff --git a/controllers/network.go b/controllers/network.go index 4bd6606d..a7050771 100644 --- a/controllers/network.go +++ b/controllers/network.go @@ -22,28 +22,32 @@ import ( ) func networkHandlers(r *mux.Router) { - r.HandleFunc("/api/networks", logic.SecurityCheck(true, http.HandlerFunc(getNetworks))).Methods(http.MethodGet) - r.HandleFunc("/api/networks", logic.SecurityCheck(true, checkFreeTierLimits(limitChoiceNetworks, http.HandlerFunc(createNetwork)))).Methods(http.MethodPost) - r.HandleFunc("/api/networks/{networkname}", logic.SecurityCheck(true, http.HandlerFunc(getNetwork))).Methods(http.MethodGet) - r.HandleFunc("/api/networks/{networkname}", logic.SecurityCheck(true, http.HandlerFunc(deleteNetwork))).Methods(http.MethodDelete) - r.HandleFunc("/api/networks/{networkname}", logic.SecurityCheck(true, http.HandlerFunc(updateNetwork))).Methods(http.MethodPut) + r.HandleFunc("/api/networks", logic.SecurityCheck(true, http.HandlerFunc(getNetworks))). + Methods(http.MethodGet) + r.HandleFunc("/api/networks", logic.SecurityCheck(true, checkFreeTierLimits(limitChoiceNetworks, http.HandlerFunc(createNetwork)))). + Methods(http.MethodPost) + r.HandleFunc("/api/networks/{networkname}", logic.SecurityCheck(true, http.HandlerFunc(getNetwork))). + Methods(http.MethodGet) + r.HandleFunc("/api/networks/{networkname}", logic.SecurityCheck(true, http.HandlerFunc(deleteNetwork))). + Methods(http.MethodDelete) + r.HandleFunc("/api/networks/{networkname}", logic.SecurityCheck(true, http.HandlerFunc(updateNetwork))). + Methods(http.MethodPut) // ACLs - r.HandleFunc("/api/networks/{networkname}/acls", logic.SecurityCheck(true, http.HandlerFunc(updateNetworkACL))).Methods(http.MethodPut) - r.HandleFunc("/api/networks/{networkname}/acls/v2", logic.SecurityCheck(true, http.HandlerFunc(updateNetworkACLv2))).Methods(http.MethodPut) - r.HandleFunc("/api/networks/{networkname}/acls", logic.SecurityCheck(true, http.HandlerFunc(getNetworkACL))).Methods(http.MethodGet) + r.HandleFunc("/api/networks/{networkname}/acls", logic.SecurityCheck(true, http.HandlerFunc(updateNetworkACL))). + Methods(http.MethodPut) + r.HandleFunc("/api/networks/{networkname}/acls/v2", logic.SecurityCheck(true, http.HandlerFunc(updateNetworkACLv2))). + Methods(http.MethodPut) + r.HandleFunc("/api/networks/{networkname}/acls", logic.SecurityCheck(true, http.HandlerFunc(getNetworkACL))). + Methods(http.MethodGet) } -// swagger:route GET /api/networks networks getNetworks -// -// Lists all networks. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: getNetworksSliceResponse +// @Summary Lists all networks +// @Router /api/networks [get] +// @Tags Networks +// @Security oauth +// @Produce json +// @Success 200 {object} models.Network +// @Failure 500 {object} models.ErrorResponse func getNetworks(w http.ResponseWriter, r *http.Request) { var err error @@ -61,17 +65,14 @@ func getNetworks(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(allnetworks) } -// swagger:route GET /api/networks/{networkname} networks getNetwork -// -// Get a network. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: networkBodyResponse +// @Summary Get a network +// @Router /api/networks/{networkname} [get] +// @Tags Networks +// @Security oauth +// @Param networkname path string true "Network name" +// @Produce json +// @Success 200 {object} models.Network +// @Failure 500 {object} models.ErrorResponse func getNetwork(w http.ResponseWriter, r *http.Request) { // set header. w.Header().Set("Content-Type", "application/json") @@ -90,17 +91,16 @@ func getNetwork(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(network) } -// swagger:route PUT /api/networks/{networkname}/acls networks updateNetworkACL -// -// Update a network ACL (Access Control List). -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: aclContainerResponse +// @Summary Update a network ACL (Access Control List) +// @Router /api/networks/{networkname}/acls [put] +// @Tags Networks +// @Security oauth +// @Param networkname path string true "Network name" +// @Param body body acls.ACLContainer true "ACL container" +// @Produce json +// @Success 200 {object} acls.ACLContainer +// @Failure 400 {object} models.ErrorResponse +// @Failure 500 {object} models.ErrorResponse func updateNetworkACL(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") var params = mux.Vars(r) @@ -140,17 +140,16 @@ func updateNetworkACL(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(newNetACL) } -// swagger:route PUT /api/networks/{networkname}/acls/v2 networks updateNetworkACL -// -// Update a network ACL (Access Control List). -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: aclContainerResponse +// @Summary Update a network ACL (Access Control List) +// @Router /api/networks/{networkname}/acls/v2 [put] +// @Tags Networks +// @Security oauth +// @Param networkname path string true "Network name" +// @Param body body acls.ACLContainer true "ACL container" +// @Produce json +// @Success 200 {object} acls.ACLContainer +// @Failure 400 {object} models.ErrorResponse +// @Failure 500 {object} models.ErrorResponse func updateNetworkACLv2(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") var params = mux.Vars(r) @@ -279,13 +278,25 @@ func updateNetworkACLv2(w http.ResponseWriter, r *http.Request) { client := client err := logic.DeleteExtClient(client.Network, client.ClientID) if err != nil { - slog.Error("failed to delete client during update", "client", client.ClientID, "error", err.Error()) + slog.Error( + "failed to delete client during update", + "client", + client.ClientID, + "error", + err.Error(), + ) logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal")) return } err = logic.SaveExtClient(&client) if err != nil { - slog.Error("failed to save client during update", "client", client.ClientID, "error", err.Error()) + slog.Error( + "failed to save client during update", + "client", + client.ClientID, + "error", + err.Error(), + ) logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal")) return } @@ -310,7 +321,11 @@ func updateNetworkACLv2(w http.ResponseWriter, r *http.Request) { // update ingress gateways of associated clients hosts, err := logic.GetAllHosts() if err != nil { - slog.Error("failed to fetch hosts after network ACL update. skipping publish extclients ACL", "network", netname) + slog.Error( + "failed to fetch hosts after network ACL update. skipping publish extclients ACL", + "network", + netname, + ) return } hostsMap := make(map[uuid.UUID]models.Host) @@ -320,7 +335,13 @@ func updateNetworkACLv2(w http.ResponseWriter, r *http.Request) { for hostId, clients := range assocClientsToDisconnectPerHost { if host, ok := hostsMap[hostId]; ok { if err = mq.PublishSingleHostPeerUpdate(&host, allNodes, nil, clients, false); err != nil { - slog.Error("failed to publish peer update to ingress after ACL update on network", "network", netname, "host", hostId) + slog.Error( + "failed to publish peer update to ingress after ACL update on network", + "network", + netname, + "host", + hostId, + ) } } } @@ -330,17 +351,14 @@ func updateNetworkACLv2(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(networkACLChange) } -// swagger:route GET /api/networks/{networkname}/acls networks getNetworkACL -// -// Get a network ACL (Access Control List). -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: aclContainerResponse +// @Summary Get a network ACL (Access Control List) +// @Router /api/networks/{networkname}/acls [get] +// @Tags Networks +// @Security oauth +// @Param networkname path string true "Network name" +// @Produce json +// @Success 200 {object} acls.ACLContainer +// @Failure 500 {object} models.ErrorResponse func getNetworkACL(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") var params = mux.Vars(r) @@ -364,17 +382,15 @@ func getNetworkACL(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(networkACL) } -// swagger:route DELETE /api/networks/{networkname} networks deleteNetwork -// -// Delete a network. Will not delete if there are any nodes that belong to the network. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: successResponse +// @Summary Delete a network +// @Router /api/networks/{networkname} [delete] +// @Tags Networks +// @Security oauth +// @Param networkname path string true "Network name" +// @Produce json +// @Success 200 {object} models.SuccessResponse +// @Failure 400 {object} models.ErrorResponse +// @Failure 403 {object} models.ErrorResponse func deleteNetwork(w http.ResponseWriter, r *http.Request) { // Set header w.Header().Set("Content-Type", "application/json") @@ -398,17 +414,14 @@ func deleteNetwork(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode("success") } -// swagger:route POST /api/networks networks createNetwork -// -// Create a network. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: networkBodyResponse +// @Summary Create a network +// @Router /api/networks [post] +// @Tags Networks +// @Security oauth +// @Param body body models.Network true "Network details" +// @Produce json +// @Success 200 {object} models.Network +// @Failure 400 {object} models.ErrorResponse func createNetwork(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") @@ -473,7 +486,14 @@ func createNetwork(w http.ResponseWriter, r *http.Request) { currHost := &defaultHosts[i] newNode, err := logic.UpdateHostNetwork(currHost, network.NetID, true) if err != nil { - logger.Log(0, r.Header.Get("user"), "failed to add host to network:", currHost.ID.String(), network.NetID, err.Error()) + logger.Log( + 0, + r.Header.Get("user"), + "failed to add host to network:", + currHost.ID.String(), + network.NetID, + err.Error(), + ) logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal")) return } @@ -483,7 +503,14 @@ func createNetwork(w http.ResponseWriter, r *http.Request) { Host: *currHost, Node: *newNode, }); err != nil { - logger.Log(0, r.Header.Get("user"), "failed to add host to network:", currHost.ID.String(), network.NetID, err.Error()) + logger.Log( + 0, + r.Header.Get("user"), + "failed to add host to network:", + currHost.ID.String(), + network.NetID, + err.Error(), + ) } // make host failover logic.CreateFailOver(*newNode) @@ -501,17 +528,15 @@ func createNetwork(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(network) } -// swagger:route PUT /api/networks/{networkname} networks updateNetwork -// -// Update pro settings for a network. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: networkBodyResponse +// @Summary Update network settings +// @Router /api/networks/{networkname} [put] +// @Tags Networks +// @Security oauth +// @Param networkname path string true "Network name" +// @Param body body models.Network true "Network details" +// @Produce json +// @Success 200 {object} models.Network +// @Failure 400 {object} models.ErrorResponse func updateNetwork(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") diff --git a/controllers/node.go b/controllers/node.go index b7027f2c..739dee46 100644 --- a/controllers/node.go +++ b/controllers/node.go @@ -21,30 +21,28 @@ var hostIDHeader = "host-id" func nodeHandlers(r *mux.Router) { - r.HandleFunc("/api/nodes", Authorize(false, false, "user", http.HandlerFunc(getAllNodes))).Methods(http.MethodGet) - r.HandleFunc("/api/nodes/{network}", Authorize(false, true, "network", http.HandlerFunc(getNetworkNodes))).Methods(http.MethodGet) - r.HandleFunc("/api/nodes/{network}/{nodeid}", Authorize(true, true, "node", http.HandlerFunc(getNode))).Methods(http.MethodGet) - r.HandleFunc("/api/nodes/{network}/{nodeid}", logic.SecurityCheck(true, http.HandlerFunc(updateNode))).Methods(http.MethodPut) - r.HandleFunc("/api/nodes/{network}/{nodeid}", Authorize(true, true, "node", http.HandlerFunc(deleteNode))).Methods(http.MethodDelete) - r.HandleFunc("/api/nodes/{network}/{nodeid}/creategateway", logic.SecurityCheck(true, checkFreeTierLimits(limitChoiceEgress, http.HandlerFunc(createEgressGateway)))).Methods(http.MethodPost) - r.HandleFunc("/api/nodes/{network}/{nodeid}/deletegateway", logic.SecurityCheck(true, http.HandlerFunc(deleteEgressGateway))).Methods(http.MethodDelete) - r.HandleFunc("/api/nodes/{network}/{nodeid}/createingress", logic.SecurityCheck(true, checkFreeTierLimits(limitChoiceIngress, http.HandlerFunc(createIngressGateway)))).Methods(http.MethodPost) - r.HandleFunc("/api/nodes/{network}/{nodeid}/deleteingress", logic.SecurityCheck(true, http.HandlerFunc(deleteIngressGateway))).Methods(http.MethodDelete) + r.HandleFunc("/api/nodes", Authorize(false, false, "user", http.HandlerFunc(getAllNodes))). + Methods(http.MethodGet) + r.HandleFunc("/api/nodes/{network}", Authorize(false, true, "network", http.HandlerFunc(getNetworkNodes))). + Methods(http.MethodGet) + r.HandleFunc("/api/nodes/{network}/{nodeid}", Authorize(true, true, "node", http.HandlerFunc(getNode))). + Methods(http.MethodGet) + r.HandleFunc("/api/nodes/{network}/{nodeid}", logic.SecurityCheck(true, http.HandlerFunc(updateNode))). + Methods(http.MethodPut) + r.HandleFunc("/api/nodes/{network}/{nodeid}", Authorize(true, true, "node", http.HandlerFunc(deleteNode))). + Methods(http.MethodDelete) + r.HandleFunc("/api/nodes/{network}/{nodeid}/creategateway", logic.SecurityCheck(true, checkFreeTierLimits(limitChoiceEgress, http.HandlerFunc(createEgressGateway)))). + Methods(http.MethodPost) + r.HandleFunc("/api/nodes/{network}/{nodeid}/deletegateway", logic.SecurityCheck(true, http.HandlerFunc(deleteEgressGateway))). + Methods(http.MethodDelete) + r.HandleFunc("/api/nodes/{network}/{nodeid}/createingress", logic.SecurityCheck(true, checkFreeTierLimits(limitChoiceIngress, http.HandlerFunc(createIngressGateway)))). + Methods(http.MethodPost) + r.HandleFunc("/api/nodes/{network}/{nodeid}/deleteingress", logic.SecurityCheck(true, http.HandlerFunc(deleteIngressGateway))). + Methods(http.MethodDelete) r.HandleFunc("/api/nodes/adm/{network}/authenticate", authenticate).Methods(http.MethodPost) r.HandleFunc("/api/v1/nodes/migrate", migrate).Methods(http.MethodPost) } -// swagger:route POST /api/nodes/adm/{network}/authenticate authenticate authenticate -// -// Authenticate to make further API calls related to a network. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: successResponse func authenticate(response http.ResponseWriter, request *http.Request) { var authRequest models.AuthParams @@ -149,7 +147,11 @@ func authenticate(response http.ResponseWriter, request *http.Request) { // even if it's technically ok // This is kind of a poor man's RBAC. There's probably a better/smarter way. // TODO: Consider better RBAC implementations -func Authorize(hostAllowed, networkCheck bool, authNetwork string, next http.Handler) http.HandlerFunc { +func Authorize( + hostAllowed, networkCheck bool, + authNetwork string, + next http.Handler, +) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { var errorResponse = models.ErrorResponse{ Code: http.StatusForbidden, Message: logic.Forbidden_Msg, @@ -258,17 +260,12 @@ func Authorize(hostAllowed, networkCheck bool, authNetwork string, next http.Han } } -// swagger:route GET /api/nodes/{network} nodes getNetworkNodes -// -// Gets all nodes associated with network including pending nodes. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: nodeSliceResponse +// @Summary Gets all nodes associated with network including pending nodes +// @Router /api/nodes/adm/{network} [get] +// @Securitydefinitions.oauth2.application OAuth2Application +// @Tags Nodes +// @Success 200 {array} models.Node +// @Failure 500 {object} models.ErrorResponse func getNetworkNodes(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") var params = mux.Vars(r) @@ -288,18 +285,12 @@ func getNetworkNodes(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(apiNodes) } -// swagger:route GET /api/nodes nodes getAllNodes -// -// Get all nodes across all networks. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: nodeSliceResponse -// +// @Summary Get all nodes across all networks +// @Router /api/nodes [get] +// @Tags Nodes +// @Securitydefinitions.oauth2.application OAuth2Application +// @Success 200 {array} models.ApiNode +// @Failure 500 {object} models.ErrorResponse // Not quite sure if this is necessary. Probably necessary based on front end but may want to review after iteration 1 if it's being used or not func getAllNodes(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") @@ -327,17 +318,12 @@ func getAllNodes(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(apiNodes) } -// swagger:route GET /api/nodes/{network}/{nodeid} nodes getNode -// -// Get an individual node. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: nodeResponse +// @Summary Get an individual node +// @Router /api/nodes/{network}/{nodeid} [get] +// @Tags Nodes +// @Security oauth2 +// @Success 200 {object} models.NodeGet +// @Failure 500 {object} models.ErrorResponse func getNode(w http.ResponseWriter, r *http.Request) { // set header. w.Header().Set("Content-Type", "application/json") @@ -359,15 +345,29 @@ func getNode(w http.ResponseWriter, r *http.Request) { } allNodes, err := logic.GetAllNodes() if err != nil { - logger.Log(0, r.Header.Get("user"), - fmt.Sprintf("error fetching wg peers config for host [ %s ]: %v", host.ID.String(), err)) + logger.Log( + 0, + r.Header.Get("user"), + fmt.Sprintf( + "error fetching wg peers config for host [ %s ]: %v", + host.ID.String(), + err, + ), + ) logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal")) return } hostPeerUpdate, err := logic.GetPeerUpdateForHost(node.Network, host, allNodes, nil, nil) if err != nil && !database.IsEmptyRecord(err) { - logger.Log(0, r.Header.Get("user"), - fmt.Sprintf("error fetching wg peers config for host [ %s ]: %v", host.ID.String(), err)) + logger.Log( + 0, + r.Header.Get("user"), + fmt.Sprintf( + "error fetching wg peers config for host [ %s ]: %v", + host.ID.String(), + err, + ), + ) logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal")) return } @@ -388,17 +388,12 @@ func getNode(w http.ResponseWriter, r *http.Request) { // == EGRESS == -// swagger:route POST /api/nodes/{network}/{nodeid}/creategateway nodes createEgressGateway -// -// Create an egress gateway. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: nodeResponse +// @Summary Create an egress gateway +// @Router /api/nodes/{network}/{nodeid}/creategateway [post] +// @Tags Nodes +// @Security oauth2 +// @Success 200 {object} models.ApiNode +// @Failure 500 {object} models.ErrorResponse func createEgressGateway(w http.ResponseWriter, r *http.Request) { var gateway models.EgressGatewayRequest var params = mux.Vars(r) @@ -431,7 +426,14 @@ func createEgressGateway(w http.ResponseWriter, r *http.Request) { } apiNode := node.ConvertToAPINode() - logger.Log(1, r.Header.Get("user"), "created egress gateway on node", gateway.NodeID, "on network", gateway.NetID) + logger.Log( + 1, + r.Header.Get("user"), + "created egress gateway on node", + gateway.NodeID, + "on network", + gateway.NetID, + ) w.WriteHeader(http.StatusOK) json.NewEncoder(w).Encode(apiNode) go func() { @@ -442,17 +444,12 @@ func createEgressGateway(w http.ResponseWriter, r *http.Request) { }() } -// swagger:route DELETE /api/nodes/{network}/{nodeid}/deletegateway nodes deleteEgressGateway -// -// Delete an egress gateway. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: nodeResponse +// @Summary Delete an egress gateway +// @Router /api/nodes/{network}/{nodeid}/deletegateway [delete] +// @Tags Nodes +// @Security oauth2 +// @Success 200 {object} models.ApiNode +// @Failure 500 {object} models.ErrorResponse func deleteEgressGateway(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") @@ -474,7 +471,14 @@ func deleteEgressGateway(w http.ResponseWriter, r *http.Request) { } apiNode := node.ConvertToAPINode() - logger.Log(1, r.Header.Get("user"), "deleted egress gateway on node", nodeid, "on network", netid) + logger.Log( + 1, + r.Header.Get("user"), + "deleted egress gateway on node", + nodeid, + "on network", + netid, + ) w.WriteHeader(http.StatusOK) json.NewEncoder(w).Encode(apiNode) go func() { @@ -487,17 +491,12 @@ func deleteEgressGateway(w http.ResponseWriter, r *http.Request) { // == INGRESS == -// swagger:route POST /api/nodes/{network}/{nodeid}/createingress nodes createIngressGateway -// -// Create an ingress gateway. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: nodeResponse +// @Summary Create an remote access gateway +// @Router /api/nodes/{network}/{nodeid}/createingress [post] +// @Tags Nodes +// @Security oauth2 +// @Success 200 {object} models.ApiNode +// @Failure 500 {object} models.ErrorResponse func createIngressGateway(w http.ResponseWriter, r *http.Request) { var params = mux.Vars(r) w.Header().Set("Content-Type", "application/json") @@ -520,7 +519,14 @@ func createIngressGateway(w http.ResponseWriter, r *http.Request) { } apiNode := node.ConvertToAPINode() - logger.Log(1, r.Header.Get("user"), "created ingress gateway on node", nodeid, "on network", netid) + logger.Log( + 1, + r.Header.Get("user"), + "created ingress gateway on node", + nodeid, + "on network", + netid, + ) w.WriteHeader(http.StatusOK) json.NewEncoder(w).Encode(apiNode) go func() { @@ -530,17 +536,12 @@ func createIngressGateway(w http.ResponseWriter, r *http.Request) { }() } -// swagger:route DELETE /api/nodes/{network}/{nodeid}/deleteingress nodes deleteIngressGateway -// -// Delete an ingress gateway. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: nodeResponse +// @Summary Delete an remote access gateway +// @Router /api/nodes/{network}/{nodeid}/deleteingress [delete] +// @Tags Nodes +// @Security oauth2 +// @Success 200 {object} models.ApiNode +// @Failure 500 {object} models.ErrorResponse func deleteIngressGateway(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") var params = mux.Vars(r) @@ -596,7 +597,13 @@ func deleteIngressGateway(w http.ResponseWriter, r *http.Request) { slog.Error("publishSingleHostUpdate", "host", host.Name, "error", err) } if err := mq.NodeUpdate(&node); err != nil { - slog.Error("error publishing node update to node", "node", node.ID, "error", err) + slog.Error( + "error publishing node update to node", + "node", + node.ID, + "error", + err, + ) } if servercfg.IsDNSMode() { logic.SetDNS() @@ -606,17 +613,12 @@ func deleteIngressGateway(w http.ResponseWriter, r *http.Request) { } } -// swagger:route PUT /api/nodes/{network}/{nodeid} nodes updateNode -// -// Update an individual node. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: nodeResponse +// @Summary Update an individual node +// @Router /api/nodes/{network}/{nodeid} [put] +// @Tags Nodes +// @Security oauth2 +// @Success 200 {object} models.ApiNode +// @Failure 500 {object} models.ErrorResponse func updateNode(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") @@ -642,7 +644,11 @@ func updateNode(w http.ResponseWriter, r *http.Request) { } newNode := newData.ConvertToServerNode(¤tNode) if newNode == nil { - logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("error converting node"), "badrequest")) + logic.ReturnErrorResponse( + w, + r, + logic.FormatError(fmt.Errorf("error converting node"), "badrequest"), + ) return } if newNode.IsInternetGateway != currentNode.IsInternetGateway { @@ -686,7 +692,14 @@ func updateNode(w http.ResponseWriter, r *http.Request) { } apiNode := newNode.ConvertToAPINode() - logger.Log(1, r.Header.Get("user"), "updated node", currentNode.ID.String(), "on network", currentNode.Network) + logger.Log( + 1, + r.Header.Get("user"), + "updated node", + currentNode.ID.String(), + "on network", + currentNode.Network, + ) w.WriteHeader(http.StatusOK) json.NewEncoder(w).Encode(apiNode) go func(aclUpdate, relayupdate bool, newNode *models.Node) { @@ -704,17 +717,12 @@ func updateNode(w http.ResponseWriter, r *http.Request) { }(aclUpdate, relayUpdate, newNode) } -// swagger:route DELETE /api/nodes/{network}/{nodeid} nodes deleteNode -// -// Delete an individual node. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: nodeResponse +// @Summary Delete an individual node +// @Router /api/nodes/{network}/{nodeid} [delete] +// @Tags Nodes +// @Security oauth2 +// @Success 200 {string} string "Node deleted." +// @Failure 500 {object} models.ErrorResponse func deleteNode(w http.ResponseWriter, r *http.Request) { // Set header w.Header().Set("Content-Type", "application/json") @@ -735,7 +743,11 @@ func deleteNode(w http.ResponseWriter, r *http.Request) { } purge := forceDelete || fromNode if err := logic.DeleteNode(&node, purge); err != nil { - logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("failed to delete node"), "internal")) + logic.ReturnErrorResponse( + w, + r, + logic.FormatError(fmt.Errorf("failed to delete node"), "internal"), + ) return } diff --git a/controllers/server.go b/controllers/server.go index 6c8c121e..f2a059ad 100644 --- a/controllers/server.go +++ b/controllers/server.go @@ -102,18 +102,12 @@ func getUsage(w http.ResponseWriter, _ *http.Request) { }) } -// swagger:route GET /api/server/status server getStatus -// -// Get the server configuration. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: serverConfigResponse +// @Summary Get the server status +// @Router /api/server/status [get] +// @Tags Server +// @Security oauth2 func getStatus(w http.ResponseWriter, r *http.Request) { + // @Success 200 {object} status type status struct { DB bool `json:"db_connected"` Broker bool `json:"broker_connected"` @@ -131,7 +125,8 @@ func getStatus(w http.ResponseWriter, r *http.Request) { var trialEndDate time.Time var err error isOnTrial := false - if servercfg.IsPro && (servercfg.GetLicenseKey() == "" || servercfg.GetNetmakerTenantID() == "") { + if servercfg.IsPro && + (servercfg.GetLicenseKey() == "" || servercfg.GetNetmakerTenantID() == "") { trialEndDate, err = logic.GetTrialEndDate() if err != nil { slog.Error("failed to get trial end date", "error", err) @@ -177,17 +172,11 @@ func allowUsers(next http.Handler) http.HandlerFunc { } } -// swagger:route GET /api/server/getserverinfo server getServerInfo -// -// Get the server configuration. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: serverConfigResponse +// @Summary Get the server information +// @Router /api/server/getserverinfo [get] +// @Tags Server +// @Security oauth2 +// @Success 200 {object} models.ServerConfig func getServerInfo(w http.ResponseWriter, r *http.Request) { // Set header w.Header().Set("Content-Type", "application/json") @@ -198,17 +187,11 @@ func getServerInfo(w http.ResponseWriter, r *http.Request) { // w.WriteHeader(http.StatusOK) } -// swagger:route GET /api/server/getconfig server getConfig -// -// Get the server configuration. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: serverConfigResponse +// @Summary Get the server configuration +// @Router /api/server/getconfig [get] +// @Tags Server +// @Security oauth2 +// @Success 200 {object} config.ServerConfig func getConfig(w http.ResponseWriter, r *http.Request) { // Set header w.Header().Set("Content-Type", "application/json") diff --git a/controllers/user.go b/controllers/user.go index ea2d4a82..3b5c67b9 100644 --- a/controllers/user.go +++ b/controllers/user.go @@ -25,31 +25,39 @@ var ( func userHandlers(r *mux.Router) { r.HandleFunc("/api/users/adm/hassuperadmin", hasSuperAdmin).Methods(http.MethodGet) r.HandleFunc("/api/users/adm/createsuperadmin", createSuperAdmin).Methods(http.MethodPost) - r.HandleFunc("/api/users/adm/transfersuperadmin/{username}", logic.SecurityCheck(true, http.HandlerFunc(transferSuperAdmin))).Methods(http.MethodPost) + r.HandleFunc("/api/users/adm/transfersuperadmin/{username}", logic.SecurityCheck(true, http.HandlerFunc(transferSuperAdmin))). + Methods(http.MethodPost) r.HandleFunc("/api/users/adm/authenticate", authenticateUser).Methods(http.MethodPost) - r.HandleFunc("/api/users/{username}", logic.SecurityCheck(true, http.HandlerFunc(updateUser))).Methods(http.MethodPut) - r.HandleFunc("/api/users/{username}", logic.SecurityCheck(true, checkFreeTierLimits(limitChoiceUsers, http.HandlerFunc(createUser)))).Methods(http.MethodPost) - r.HandleFunc("/api/users/{username}", logic.SecurityCheck(true, http.HandlerFunc(deleteUser))).Methods(http.MethodDelete) - r.HandleFunc("/api/users/{username}", logic.SecurityCheck(false, logic.ContinueIfUserMatch(http.HandlerFunc(getUser)))).Methods(http.MethodGet) - r.HandleFunc("/api/users", logic.SecurityCheck(true, http.HandlerFunc(getUsers))).Methods(http.MethodGet) - r.HandleFunc("/api/users_pending", logic.SecurityCheck(true, http.HandlerFunc(getPendingUsers))).Methods(http.MethodGet) - r.HandleFunc("/api/users_pending", logic.SecurityCheck(true, http.HandlerFunc(deleteAllPendingUsers))).Methods(http.MethodDelete) - r.HandleFunc("/api/users_pending/user/{username}", logic.SecurityCheck(true, http.HandlerFunc(deletePendingUser))).Methods(http.MethodDelete) - r.HandleFunc("/api/users_pending/user/{username}", logic.SecurityCheck(true, http.HandlerFunc(approvePendingUser))).Methods(http.MethodPost) + r.HandleFunc("/api/users/{username}", logic.SecurityCheck(true, http.HandlerFunc(updateUser))). + Methods(http.MethodPut) + r.HandleFunc("/api/users/{username}", logic.SecurityCheck(true, checkFreeTierLimits(limitChoiceUsers, http.HandlerFunc(createUser)))). + Methods(http.MethodPost) + r.HandleFunc("/api/users/{username}", logic.SecurityCheck(true, http.HandlerFunc(deleteUser))). + Methods(http.MethodDelete) + r.HandleFunc("/api/users/{username}", logic.SecurityCheck(false, logic.ContinueIfUserMatch(http.HandlerFunc(getUser)))). + Methods(http.MethodGet) + r.HandleFunc("/api/users", logic.SecurityCheck(true, http.HandlerFunc(getUsers))). + Methods(http.MethodGet) + r.HandleFunc("/api/users_pending", logic.SecurityCheck(true, http.HandlerFunc(getPendingUsers))). + Methods(http.MethodGet) + r.HandleFunc("/api/users_pending", logic.SecurityCheck(true, http.HandlerFunc(deleteAllPendingUsers))). + Methods(http.MethodDelete) + r.HandleFunc("/api/users_pending/user/{username}", logic.SecurityCheck(true, http.HandlerFunc(deletePendingUser))). + Methods(http.MethodDelete) + r.HandleFunc("/api/users_pending/user/{username}", logic.SecurityCheck(true, http.HandlerFunc(approvePendingUser))). + Methods(http.MethodPost) } -// swagger:route POST /api/users/adm/authenticate authenticate authenticateUser -// -// User authenticates using its password and retrieves a JWT for authorization. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: successResponse +// @Summary Authenticate a user to retrieve an authorization token +// @Router /api/users/adm/authenticate [post] +// @Tags Auth +// @Accept json +// @Param body body models.UserAuthParams true "Authentication parameters" +// @Success 200 {object} models.SuccessResponse +// @Failure 400 {object} models.ErrorResponse +// @Failure 401 {object} models.ErrorResponse +// @Failure 500 {object} models.ErrorResponse func authenticateUser(response http.ResponseWriter, request *http.Request) { // Auth request consists of Mac Address and Password (from node that is authorizing @@ -60,7 +68,11 @@ func authenticateUser(response http.ResponseWriter, request *http.Request) { } if !servercfg.IsBasicAuthEnabled() { - logic.ReturnErrorResponse(response, request, logic.FormatError(fmt.Errorf("basic auth is disabled"), "badrequest")) + logic.ReturnErrorResponse( + response, + request, + logic.FormatError(fmt.Errorf("basic auth is disabled"), "badrequest"), + ) return } @@ -83,7 +95,11 @@ func authenticateUser(response http.ResponseWriter, request *http.Request) { return } if !(user.IsAdmin || user.IsSuperAdmin) { - logic.ReturnErrorResponse(response, request, logic.FormatError(errors.New("only admins can access dashboard"), "unauthorized")) + logic.ReturnErrorResponse( + response, + request, + logic.FormatError(errors.New("only admins can access dashboard"), "unauthorized"), + ) return } } @@ -99,7 +115,11 @@ func authenticateUser(response http.ResponseWriter, request *http.Request) { if jwt == "" { // very unlikely that err is !nil and no jwt returned, but handle it anyways. logger.Log(0, username, "jwt token is empty") - logic.ReturnErrorResponse(response, request, logic.FormatError(errors.New("no token returned"), "internal")) + logic.ReturnErrorResponse( + response, + request, + logic.FormatError(errors.New("no token returned"), "internal"), + ) return } @@ -133,9 +153,19 @@ func authenticateUser(response http.ResponseWriter, request *http.Request) { } for _, client := range clients { if client.OwnerID == username && !client.Enabled { - slog.Info(fmt.Sprintf("enabling ext client %s for user %s due to RAC autodisabling feature", client.ClientID, client.OwnerID)) + slog.Info( + fmt.Sprintf( + "enabling ext client %s for user %s due to RAC autodisabling feature", + client.ClientID, + client.OwnerID, + ), + ) if newClient, err := logic.ToggleExtClientConnectivity(&client, true); err != nil { - slog.Error("error enabling ext client in RAC autodisable hook", "error", err) + slog.Error( + "error enabling ext client in RAC autodisable hook", + "error", + err, + ) continue // dont return but try for other clients } else { // publish peer update to ingress gateway @@ -151,17 +181,11 @@ func authenticateUser(response http.ResponseWriter, request *http.Request) { }() } -// swagger:route GET /api/users/adm/hassuperadmin user hasSuperAdmin -// -// Checks whether the server has an admin. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: hasAdmin +// @Summary Check if the server has a super admin +// @Router /api/users/adm/hassuperadmin [get] +// @Tags Users +// @Success 200 {object} bool +// @Failure 500 {object} models.ErrorResponse func hasSuperAdmin(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") @@ -177,17 +201,12 @@ func hasSuperAdmin(w http.ResponseWriter, r *http.Request) { } -// swagger:route GET /api/users/{username} user getUser -// -// Get an individual user. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: userBodyResponse +// @Summary Get an individual user +// @Router /api/users/{username} [get] +// @Tags Users +// @Param username path string true "Username of the user to fetch" +// @Success 200 {object} models.User +// @Failure 500 {object} models.ErrorResponse func getUser(w http.ResponseWriter, r *http.Request) { // set header. w.Header().Set("Content-Type", "application/json") @@ -205,17 +224,11 @@ func getUser(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(user) } -// swagger:route GET /api/users user getUsers -// -// Get all users. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: userBodyResponse +// @Summary Get all users +// @Router /api/users [get] +// @Tags Users +// @Success 200 {array} models.User +// @Failure 500 {object} models.ErrorResponse func getUsers(w http.ResponseWriter, r *http.Request) { // set header. w.Header().Set("Content-Type", "application/json") @@ -233,17 +246,13 @@ func getUsers(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(users) } -// swagger:route POST /api/users/adm/createsuperadmin user createAdmin -// -// Make a user an admin. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: userBodyResponse +// @Summary Create a super admin +// @Router /api/users/adm/createsuperadmin [post] +// @Tags Users +// @Param body body models.User true "User details" +// @Success 200 {object} models.User +// @Failure 400 {object} models.ErrorResponse +// @Failure 500 {object} models.ErrorResponse func createSuperAdmin(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") @@ -257,7 +266,11 @@ func createSuperAdmin(w http.ResponseWriter, r *http.Request) { } if !servercfg.IsBasicAuthEnabled() { - logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("basic auth is disabled"), "badrequest")) + logic.ReturnErrorResponse( + w, + r, + logic.FormatError(fmt.Errorf("basic auth is disabled"), "badrequest"), + ) return } @@ -271,17 +284,13 @@ func createSuperAdmin(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(logic.ToReturnUser(u)) } -// swagger:route POST /api/users/adm/transfersuperadmin user transferSuperAdmin -// -// Transfers superadmin role to an admin user. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: userBodyResponse +// @Summary Transfer super admin role to another admin user +// @Router /api/users/adm/transfersuperadmin/{username} [post] +// @Tags Users +// @Param username path string true "Username of the user to transfer super admin role" +// @Success 200 {object} models.User +// @Failure 403 {object} models.ErrorResponse +// @Failure 500 {object} models.ErrorResponse func transferSuperAdmin(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") caller, err := logic.GetUser(r.Header.Get("user")) @@ -289,7 +298,14 @@ func transferSuperAdmin(w http.ResponseWriter, r *http.Request) { logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal")) } if !caller.IsSuperAdmin { - logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("only superadmin can assign the superadmin role to another user"), "forbidden")) + logic.ReturnErrorResponse( + w, + r, + logic.FormatError( + errors.New("only superadmin can assign the superadmin role to another user"), + "forbidden", + ), + ) return } var params = mux.Vars(r) @@ -301,11 +317,22 @@ func transferSuperAdmin(w http.ResponseWriter, r *http.Request) { return } if !u.IsAdmin { - logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("only admins can be promoted to superadmin role"), "forbidden")) + logic.ReturnErrorResponse( + w, + r, + logic.FormatError( + errors.New("only admins can be promoted to superadmin role"), + "forbidden", + ), + ) return } if !servercfg.IsBasicAuthEnabled() { - logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("basic auth is disabled"), "badrequest")) + logic.ReturnErrorResponse( + w, + r, + logic.FormatError(fmt.Errorf("basic auth is disabled"), "badrequest"), + ) return } @@ -329,17 +356,15 @@ func transferSuperAdmin(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(logic.ToReturnUser(*u)) } -// swagger:route POST /api/users/{username} user createUser -// -// Create a user. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: userBodyResponse +// @Summary Create a user +// @Router /api/users/{username} [post] +// @Tags Users +// @Param username path string true "Username of the user to create" +// @Param body body models.User true "User details" +// @Success 200 {object} models.User +// @Failure 400 {object} models.ErrorResponse +// @Failure 403 {object} models.ErrorResponse +// @Failure 500 {object} models.ErrorResponse func createUser(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") caller, err := logic.GetUser(r.Header.Get("user")) @@ -368,7 +393,14 @@ func createUser(w http.ResponseWriter, r *http.Request) { return } if !servercfg.IsPro && !user.IsAdmin { - logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("non-admins users can only be created on Pro version"), "forbidden")) + logic.ReturnErrorResponse( + w, + r, + logic.FormatError( + errors.New("non-admins users can only be created on Pro version"), + "forbidden", + ), + ) return } @@ -382,17 +414,15 @@ func createUser(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(logic.ToReturnUser(user)) } -// swagger:route PUT /api/users/{username} user updateUser -// -// Update a user. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: userBodyResponse +// @Summary Update a user +// @Router /api/users/{username} [put] +// @Tags Users +// @Param username path string true "Username of the user to update" +// @Param body body models.User true "User details" +// @Success 200 {object} models.User +// @Failure 400 {object} models.ErrorResponse +// @Failure 403 {object} models.ErrorResponse +// @Failure 500 {object} models.ErrorResponse func updateUser(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") var params = mux.Vars(r) @@ -426,7 +456,14 @@ func updateUser(w http.ResponseWriter, r *http.Request) { return } if user.UserName != userchange.UserName { - logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("user in param and request body not matching"), "badrequest")) + logic.ReturnErrorResponse( + w, + r, + logic.FormatError( + errors.New("user in param and request body not matching"), + "badrequest", + ), + ) return } selfUpdate := false @@ -436,23 +473,64 @@ func updateUser(w http.ResponseWriter, r *http.Request) { if !ismaster && !selfUpdate { if caller.IsAdmin && user.IsSuperAdmin { - slog.Error("non-superadmin user", "caller", caller.UserName, "attempted to update superadmin user", username) - logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("cannot update superadmin user"), "forbidden")) + slog.Error( + "non-superadmin user", + "caller", + caller.UserName, + "attempted to update superadmin user", + username, + ) + logic.ReturnErrorResponse( + w, + r, + logic.FormatError(errors.New("cannot update superadmin user"), "forbidden"), + ) return } if !caller.IsAdmin && !caller.IsSuperAdmin { - slog.Error("operation not allowed", "caller", caller.UserName, "attempted to update user", username) - logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("cannot update superadmin user"), "forbidden")) + slog.Error( + "operation not allowed", + "caller", + caller.UserName, + "attempted to update user", + username, + ) + logic.ReturnErrorResponse( + w, + r, + logic.FormatError(errors.New("cannot update superadmin user"), "forbidden"), + ) return } if caller.IsAdmin && user.IsAdmin { - slog.Error("admin user cannot update another admin", "caller", caller.UserName, "attempted to update admin user", username) - logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("admin user cannot update another admin"), "forbidden")) + slog.Error( + "admin user cannot update another admin", + "caller", + caller.UserName, + "attempted to update admin user", + username, + ) + logic.ReturnErrorResponse( + w, + r, + logic.FormatError( + errors.New("admin user cannot update another admin"), + "forbidden", + ), + ) return } if caller.IsAdmin && userchange.IsAdmin { err = errors.New("admin user cannot update role of an another user to admin") - slog.Error("failed to update user", "caller", caller.UserName, "attempted to update user", username, "error", err) + slog.Error( + "failed to update user", + "caller", + caller.UserName, + "attempted to update user", + username, + "error", + err, + ) logic.ReturnErrorResponse(w, r, logic.FormatError(err, "forbidden")) return } @@ -460,16 +538,39 @@ func updateUser(w http.ResponseWriter, r *http.Request) { } if !ismaster && selfUpdate { if user.IsAdmin != userchange.IsAdmin || user.IsSuperAdmin != userchange.IsSuperAdmin { - slog.Error("user cannot change his own role", "caller", caller.UserName, "attempted to update user role", username) - logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("user not allowed to self assign role"), "forbidden")) + slog.Error( + "user cannot change his own role", + "caller", + caller.UserName, + "attempted to update user role", + username, + ) + logic.ReturnErrorResponse( + w, + r, + logic.FormatError(errors.New("user not allowed to self assign role"), "forbidden"), + ) return } } if ismaster { if !user.IsSuperAdmin && userchange.IsSuperAdmin { - slog.Error("operation not allowed", "caller", logic.MasterUser, "attempted to update user role to superadmin", username) - logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("attempted to update user role to superadmin"), "forbidden")) + slog.Error( + "operation not allowed", + "caller", + logic.MasterUser, + "attempted to update user role to superadmin", + username, + ) + logic.ReturnErrorResponse( + w, + r, + logic.FormatError( + errors.New("attempted to update user role to superadmin"), + "forbidden", + ), + ) return } } @@ -491,17 +592,12 @@ func updateUser(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(logic.ToReturnUser(*user)) } -// swagger:route DELETE /api/users/{username} user deleteUser -// -// Delete a user. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: userBodyResponse +// @Summary Delete a user +// @Router /api/users/{username} [delete] +// @Tags Users +// @Param username path string true "Username of the user to delete" +// @Success 200 {string} string +// @Failure 500 {object} models.ErrorResponse func deleteUser(w http.ResponseWriter, r *http.Request) { // Set header w.Header().Set("Content-Type", "application/json") @@ -523,14 +619,30 @@ func deleteUser(w http.ResponseWriter, r *http.Request) { if user.IsSuperAdmin { slog.Error( "failed to delete user: ", "user", username, "error", "superadmin cannot be deleted") - logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("superadmin cannot be deleted"), "internal")) + logic.ReturnErrorResponse( + w, + r, + logic.FormatError(fmt.Errorf("superadmin cannot be deleted"), "internal"), + ) return } if !caller.IsSuperAdmin { if caller.IsAdmin && user.IsAdmin { slog.Error( - "failed to delete user: ", "user", username, "error", "admin cannot delete another admin user, including oneself") - logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("admin cannot delete another admin user, including oneself"), "internal")) + "failed to delete user: ", + "user", + username, + "error", + "admin cannot delete another admin user, including oneself", + ) + logic.ReturnErrorResponse( + w, + r, + logic.FormatError( + fmt.Errorf("admin cannot delete another admin user, including oneself"), + "internal", + ), + ) return } } @@ -586,17 +698,11 @@ func socketHandler(w http.ResponseWriter, r *http.Request) { go auth.SessionHandler(conn) } -// swagger:route GET /api/users_pending user getPendingUsers -// -// Get all pending users. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: userBodyResponse +// @Summary Get all pending users +// @Router /api/users_pending [get] +// @Tags Users +// @Success 200 {array} models.User +// @Failure 500 {object} models.ErrorResponse func getPendingUsers(w http.ResponseWriter, r *http.Request) { // set header. w.Header().Set("Content-Type", "application/json") @@ -613,17 +719,12 @@ func getPendingUsers(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(users) } -// swagger:route POST /api/users_pending/user/{username} user approvePendingUser -// -// approve pending user. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: userBodyResponse +// @Summary Approve a pending user +// @Router /api/users_pending/user/{username} [post] +// @Tags Users +// @Param username path string true "Username of the pending user to approve" +// @Success 200 {string} string +// @Failure 500 {object} models.ErrorResponse func approvePendingUser(w http.ResponseWriter, r *http.Request) { // set header. w.Header().Set("Content-Type", "application/json") @@ -647,12 +748,23 @@ func approvePendingUser(w http.ResponseWriter, r *http.Request) { UserName: user.UserName, Password: newPass, }); err != nil { - logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("failed to create user: %s", err), "internal")) + logic.ReturnErrorResponse( + w, + r, + logic.FormatError(fmt.Errorf("failed to create user: %s", err), "internal"), + ) return } err = logic.DeletePendingUser(username) if err != nil { - logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("failed to delete pending user: %s", err), "internal")) + logic.ReturnErrorResponse( + w, + r, + logic.FormatError( + fmt.Errorf("failed to delete pending user: %s", err), + "internal", + ), + ) return } break @@ -661,17 +773,12 @@ func approvePendingUser(w http.ResponseWriter, r *http.Request) { logic.ReturnSuccessResponse(w, r, "approved "+username) } -// swagger:route DELETE /api/users_pending/user/{username} user deletePendingUser -// -// delete pending user. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: userBodyResponse +// @Summary Delete a pending user +// @Router /api/users_pending/user/{username} [delete] +// @Tags Users +// @Param username path string true "Username of the pending user to delete" +// @Success 200 {string} string +// @Failure 500 {object} models.ErrorResponse func deletePendingUser(w http.ResponseWriter, r *http.Request) { // set header. w.Header().Set("Content-Type", "application/json") @@ -688,7 +795,14 @@ func deletePendingUser(w http.ResponseWriter, r *http.Request) { if user.UserName == username { err = logic.DeletePendingUser(username) if err != nil { - logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("failed to delete pending user: %s", err), "internal")) + logic.ReturnErrorResponse( + w, + r, + logic.FormatError( + fmt.Errorf("failed to delete pending user: %s", err), + "internal", + ), + ) return } break @@ -697,23 +811,24 @@ func deletePendingUser(w http.ResponseWriter, r *http.Request) { logic.ReturnSuccessResponse(w, r, "deleted pending "+username) } -// swagger:route DELETE /api/users_pending/{username}/pending user deleteAllPendingUsers -// -// delete all pending users. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: userBodyResponse +// @Summary Delete all pending users +// @Router /api/users_pending [delete] +// @Tags Users +// @Success 200 {string} string +// @Failure 500 {object} models.ErrorResponse func deleteAllPendingUsers(w http.ResponseWriter, r *http.Request) { // set header. w.Header().Set("Content-Type", "application/json") err := database.DeleteAllRecords(database.PENDING_USERS_TABLE_NAME) if err != nil { - logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("failed to delete all pending users "+err.Error()), "internal")) + logic.ReturnErrorResponse( + w, + r, + logic.FormatError( + errors.New("failed to delete all pending users "+err.Error()), + "internal", + ), + ) return } logic.ReturnSuccessResponse(w, r, "cleared all pending users") diff --git a/docs/APIUsage.md b/docs/APIUsage.md new file mode 100644 index 00000000..a4d9db5e --- /dev/null +++ b/docs/APIUsage.md @@ -0,0 +1 @@ +Most actions that can be performed via API can be performed via UI. We recommend managing your networks using the official netmaker-ui project. However, Netmaker can also be run without the UI, and all functions can be achieved via API calls. If your use case requires using Netmaker without the UI or you need to do some troubleshooting/advanced configuration, using the API directly may help. diff --git a/docs/Authentication.md b/docs/Authentication.md new file mode 100644 index 00000000..b1a7a444 --- /dev/null +++ b/docs/Authentication.md @@ -0,0 +1,10 @@ +API calls are primarily authenticated using a user authentication token. This token should be included in the header as follows: + +-H "Authorization: Bearer " + +To obtain YOUR_AUTH_TOKEN: +Call the api/users/adm/authenticate endpoint (see documentation below for details). + +Note: While a MasterKey exists (configurable via env var or config file), it should be considered a backup option, used only when server access is lost. By default, this key is "secret key," but it's crucial to change this and keep it secure in your instance. + +For more information on configuration and security best practices, refer to the [Netmaker documentation](https://docs.netmaker.org/index.html). diff --git a/docs/Pricing.md b/docs/Pricing.md new file mode 100644 index 00000000..87514383 --- /dev/null +++ b/docs/Pricing.md @@ -0,0 +1 @@ +Check out our [Pricing](https://www.netmaker.io/pricing). And Feel Free to [Contact Us](https://www.netmaker.io/contact) if you have any questions or need some clarifications. diff --git a/main.go b/main.go index 489c934a..14d32661 100644 --- a/main.go +++ b/main.go @@ -29,6 +29,17 @@ import ( var version = "v0.25.0" +// @title NetMaker +// @version 0.24.3 +// @description NetMaker API Docs +// @tag.name APIUsage +// @tag.description.markdown +// @tag.name Authentication +// @tag.description.markdown +// @tag.name Pricing +// @tag.description.markdown +// @host api.demo.netmaker.io + // Start DB Connection and start API Request Handler func main() { absoluteConfigPath := flag.String("c", "", "absolute path to configuration file") @@ -135,7 +146,10 @@ func startControllers(wg *sync.WaitGroup, ctx context.Context) { } if !servercfg.IsRestBackend() && !servercfg.IsMessageQueueBackend() { - logger.Log(0, "No Server Mode selected, so nothing is being served! Set Rest mode (REST_BACKEND) or MessageQueue (MESSAGEQUEUE_BACKEND) to 'true'.") + logger.Log( + 0, + "No Server Mode selected, so nothing is being served! Set Rest mode (REST_BACKEND) or MessageQueue (MESSAGEQUEUE_BACKEND) to 'true'.", + ) } wg.Add(1) @@ -167,10 +181,21 @@ func runMessageQueue(wg *sync.WaitGroup, ctx context.Context) { node.Action = models.NODE_DELETE node.PendingDelete = true if err := mq.NodeUpdate(node); err != nil { - logger.Log(0, "failed to send peer update for deleted node: ", node.ID.String(), err.Error()) + logger.Log( + 0, + "failed to send peer update for deleted node: ", + node.ID.String(), + err.Error(), + ) } if err := logic.DeleteNode(node, true); err != nil { - slog.Error("error deleting expired node", "nodeid", node.ID.String(), "error", err.Error()) + slog.Error( + "error deleting expired node", + "nodeid", + node.ID.String(), + "error", + err.Error(), + ) } go mq.PublishDeletedNodePeerUpdate(node) } @@ -189,7 +214,12 @@ func setVerbosity() { } return a } - logger := slog.New(slog.NewJSONHandler(os.Stderr, &slog.HandlerOptions{AddSource: true, ReplaceAttr: replace, Level: logLevel})) + logger := slog.New( + slog.NewJSONHandler( + os.Stderr, + &slog.HandlerOptions{AddSource: true, ReplaceAttr: replace, Level: logLevel}, + ), + ) slog.SetDefault(logger) switch verbose { case 4: diff --git a/models/node.go b/models/node.go index c55eef03..a15bc6c9 100644 --- a/models/node.go +++ b/models/node.go @@ -52,111 +52,111 @@ type Iface struct { // CommonNode - represents a commonn node data elements shared by netmaker and netclient type CommonNode struct { - ID uuid.UUID `json:"id" yaml:"id"` - HostID uuid.UUID `json:"hostid" yaml:"hostid"` - Network string `json:"network" yaml:"network"` - NetworkRange net.IPNet `json:"networkrange" yaml:"networkrange"` - NetworkRange6 net.IPNet `json:"networkrange6" yaml:"networkrange6"` - Server string `json:"server" yaml:"server"` - Connected bool `json:"connected" yaml:"connected"` - Address net.IPNet `json:"address" yaml:"address"` - Address6 net.IPNet `json:"address6" yaml:"address6"` - Action string `json:"action" yaml:"action"` - LocalAddress net.IPNet `json:"localaddress" yaml:"localaddress"` - IsEgressGateway bool `json:"isegressgateway" yaml:"isegressgateway"` - EgressGatewayRanges []string `json:"egressgatewayranges" bson:"egressgatewayranges" yaml:"egressgatewayranges"` - IsIngressGateway bool `json:"isingressgateway" yaml:"isingressgateway"` - IsRelayed bool `json:"isrelayed" bson:"isrelayed" yaml:"isrelayed"` - RelayedBy string `json:"relayedby" bson:"relayedby" yaml:"relayedby"` - IsRelay bool `json:"isrelay" bson:"isrelay" yaml:"isrelay"` - RelayedNodes []string `json:"relaynodes" yaml:"relayedNodes"` - IngressDNS string `json:"ingressdns" yaml:"ingressdns"` - DNSOn bool `json:"dnson" yaml:"dnson"` + ID uuid.UUID `json:"id" yaml:"id"` + HostID uuid.UUID `json:"hostid" yaml:"hostid"` + Network string `json:"network" yaml:"network"` + NetworkRange net.IPNet `json:"networkrange" yaml:"networkrange" swaggertype:"primitive,integer"` + NetworkRange6 net.IPNet `json:"networkrange6" yaml:"networkrange6" swaggertype:"primitive,number"` + Server string `json:"server" yaml:"server"` + Connected bool `json:"connected" yaml:"connected"` + Address net.IPNet `json:"address" yaml:"address"` + Address6 net.IPNet `json:"address6" yaml:"address6"` + Action string `json:"action" yaml:"action"` + LocalAddress net.IPNet `json:"localaddress" yaml:"localaddress"` + IsEgressGateway bool `json:"isegressgateway" yaml:"isegressgateway"` + EgressGatewayRanges []string `json:"egressgatewayranges" yaml:"egressgatewayranges" bson:"egressgatewayranges"` + IsIngressGateway bool `json:"isingressgateway" yaml:"isingressgateway"` + IsRelayed bool `json:"isrelayed" yaml:"isrelayed" bson:"isrelayed"` + RelayedBy string `json:"relayedby" yaml:"relayedby" bson:"relayedby"` + IsRelay bool `json:"isrelay" yaml:"isrelay" bson:"isrelay"` + RelayedNodes []string `json:"relaynodes" yaml:"relayedNodes"` + IngressDNS string `json:"ingressdns" yaml:"ingressdns"` + DNSOn bool `json:"dnson" yaml:"dnson"` } // Node - a model of a network node type Node struct { CommonNode - PendingDelete bool `json:"pendingdelete" bson:"pendingdelete" yaml:"pendingdelete"` - LastModified time.Time `json:"lastmodified" bson:"lastmodified" yaml:"lastmodified"` - LastCheckIn time.Time `json:"lastcheckin" bson:"lastcheckin" yaml:"lastcheckin"` - LastPeerUpdate time.Time `json:"lastpeerupdate" bson:"lastpeerupdate" yaml:"lastpeerupdate"` - ExpirationDateTime time.Time `json:"expdatetime" bson:"expdatetime" yaml:"expdatetime"` + PendingDelete bool `json:"pendingdelete" bson:"pendingdelete" yaml:"pendingdelete"` + LastModified time.Time `json:"lastmodified" bson:"lastmodified" yaml:"lastmodified"` + LastCheckIn time.Time `json:"lastcheckin" bson:"lastcheckin" yaml:"lastcheckin"` + LastPeerUpdate time.Time `json:"lastpeerupdate" bson:"lastpeerupdate" yaml:"lastpeerupdate"` + ExpirationDateTime time.Time `json:"expdatetime" bson:"expdatetime" yaml:"expdatetime"` EgressGatewayNatEnabled bool `json:"egressgatewaynatenabled" bson:"egressgatewaynatenabled" yaml:"egressgatewaynatenabled"` - EgressGatewayRequest EgressGatewayRequest `json:"egressgatewayrequest" bson:"egressgatewayrequest" yaml:"egressgatewayrequest"` - IngressGatewayRange string `json:"ingressgatewayrange" bson:"ingressgatewayrange" yaml:"ingressgatewayrange"` - IngressGatewayRange6 string `json:"ingressgatewayrange6" bson:"ingressgatewayrange6" yaml:"ingressgatewayrange6"` + EgressGatewayRequest EgressGatewayRequest `json:"egressgatewayrequest" bson:"egressgatewayrequest" yaml:"egressgatewayrequest"` + IngressGatewayRange string `json:"ingressgatewayrange" bson:"ingressgatewayrange" yaml:"ingressgatewayrange"` + IngressGatewayRange6 string `json:"ingressgatewayrange6" bson:"ingressgatewayrange6" yaml:"ingressgatewayrange6"` Metadata string `json:"metadata"` // == PRO == - DefaultACL string `json:"defaultacl,omitempty" bson:"defaultacl,omitempty" yaml:"defaultacl,omitempty" validate:"checkyesornoorunset"` - OwnerID string `json:"ownerid,omitempty" bson:"ownerid,omitempty" yaml:"ownerid,omitempty"` - IsFailOver bool `json:"is_fail_over" yaml:"is_fail_over"` - FailOverPeers map[string]struct{} `json:"fail_over_peers" yaml:"fail_over_peers"` - FailedOverBy uuid.UUID `json:"failed_over_by" yaml:"failed_over_by"` - IsInternetGateway bool `json:"isinternetgateway" yaml:"isinternetgateway"` - InetNodeReq InetNodeReq `json:"inet_node_req" yaml:"inet_node_req"` - InternetGwID string `json:"internetgw_node_id" yaml:"internetgw_node_id"` - AdditionalRagIps []net.IP `json:"additional_rag_ips" yaml:"additional_rag_ips"` + DefaultACL string `json:"defaultacl,omitempty" bson:"defaultacl,omitempty" yaml:"defaultacl,omitempty" validate:"checkyesornoorunset"` + OwnerID string `json:"ownerid,omitempty" bson:"ownerid,omitempty" yaml:"ownerid,omitempty"` + IsFailOver bool `json:"is_fail_over" yaml:"is_fail_over"` + FailOverPeers map[string]struct{} `json:"fail_over_peers" yaml:"fail_over_peers"` + FailedOverBy uuid.UUID `json:"failed_over_by" yaml:"failed_over_by"` + IsInternetGateway bool `json:"isinternetgateway" yaml:"isinternetgateway"` + InetNodeReq InetNodeReq `json:"inet_node_req" yaml:"inet_node_req"` + InternetGwID string `json:"internetgw_node_id" yaml:"internetgw_node_id"` + AdditionalRagIps []net.IP `json:"additional_rag_ips" yaml:"additional_rag_ips" swaggertype:"array,number"` } // LegacyNode - legacy struct for node model type LegacyNode struct { - ID string `json:"id,omitempty" bson:"id,omitempty" yaml:"id,omitempty" validate:"required,min=5,id_unique"` - Address string `json:"address" bson:"address" yaml:"address" validate:"omitempty,ipv4"` - Address6 string `json:"address6" bson:"address6" yaml:"address6" validate:"omitempty,ipv6"` - LocalAddress string `json:"localaddress" bson:"localaddress" yaml:"localaddress" validate:"omitempty"` - Interfaces []Iface `json:"interfaces" yaml:"interfaces"` - Name string `json:"name" bson:"name" yaml:"name" validate:"omitempty,max=62,in_charset"` - NetworkSettings Network `json:"networksettings" bson:"networksettings" yaml:"networksettings" validate:"-"` - ListenPort int32 `json:"listenport" bson:"listenport" yaml:"listenport" validate:"omitempty,numeric,min=1024,max=65535"` - LocalListenPort int32 `json:"locallistenport" bson:"locallistenport" yaml:"locallistenport" validate:"numeric,min=0,max=65535"` - PublicKey string `json:"publickey" bson:"publickey" yaml:"publickey" validate:"required,base64"` - Endpoint string `json:"endpoint" bson:"endpoint" yaml:"endpoint" validate:"required,ip"` - AllowedIPs []string `json:"allowedips" bson:"allowedips" yaml:"allowedips"` - PersistentKeepalive int32 `json:"persistentkeepalive" bson:"persistentkeepalive" yaml:"persistentkeepalive" validate:"omitempty,numeric,max=1000"` - IsHub string `json:"ishub" bson:"ishub" yaml:"ishub" validate:"checkyesorno"` - AccessKey string `json:"accesskey" bson:"accesskey" yaml:"accesskey"` - Interface string `json:"interface" bson:"interface" yaml:"interface"` - LastModified int64 `json:"lastmodified" bson:"lastmodified" yaml:"lastmodified"` - ExpirationDateTime int64 `json:"expdatetime" bson:"expdatetime" yaml:"expdatetime"` - LastPeerUpdate int64 `json:"lastpeerupdate" bson:"lastpeerupdate" yaml:"lastpeerupdate"` - LastCheckIn int64 `json:"lastcheckin" bson:"lastcheckin" yaml:"lastcheckin"` - MacAddress string `json:"macaddress" bson:"macaddress" yaml:"macaddress"` - Password string `json:"password" bson:"password" yaml:"password" validate:"required,min=6"` - Network string `json:"network" bson:"network" yaml:"network" validate:"network_exists"` - IsRelayed string `json:"isrelayed" bson:"isrelayed" yaml:"isrelayed"` - IsPending string `json:"ispending" bson:"ispending" yaml:"ispending"` - IsRelay string `json:"isrelay" bson:"isrelay" yaml:"isrelay" validate:"checkyesorno"` - IsDocker string `json:"isdocker" bson:"isdocker" yaml:"isdocker" validate:"checkyesorno"` - IsK8S string `json:"isk8s" bson:"isk8s" yaml:"isk8s" validate:"checkyesorno"` - IsEgressGateway string `json:"isegressgateway" bson:"isegressgateway" yaml:"isegressgateway" validate:"checkyesorno"` - IsIngressGateway string `json:"isingressgateway" bson:"isingressgateway" yaml:"isingressgateway" validate:"checkyesorno"` - EgressGatewayRanges []string `json:"egressgatewayranges" bson:"egressgatewayranges" yaml:"egressgatewayranges"` + ID string `json:"id,omitempty" bson:"id,omitempty" yaml:"id,omitempty" validate:"required,min=5,id_unique"` + Address string `json:"address" bson:"address" yaml:"address" validate:"omitempty,ipv4"` + Address6 string `json:"address6" bson:"address6" yaml:"address6" validate:"omitempty,ipv6"` + LocalAddress string `json:"localaddress" bson:"localaddress" yaml:"localaddress" validate:"omitempty"` + Interfaces []Iface `json:"interfaces" yaml:"interfaces"` + Name string `json:"name" bson:"name" yaml:"name" validate:"omitempty,max=62,in_charset"` + NetworkSettings Network `json:"networksettings" bson:"networksettings" yaml:"networksettings" validate:"-"` + ListenPort int32 `json:"listenport" bson:"listenport" yaml:"listenport" validate:"omitempty,numeric,min=1024,max=65535"` + LocalListenPort int32 `json:"locallistenport" bson:"locallistenport" yaml:"locallistenport" validate:"numeric,min=0,max=65535"` + PublicKey string `json:"publickey" bson:"publickey" yaml:"publickey" validate:"required,base64"` + Endpoint string `json:"endpoint" bson:"endpoint" yaml:"endpoint" validate:"required,ip"` + AllowedIPs []string `json:"allowedips" bson:"allowedips" yaml:"allowedips"` + PersistentKeepalive int32 `json:"persistentkeepalive" bson:"persistentkeepalive" yaml:"persistentkeepalive" validate:"omitempty,numeric,max=1000"` + IsHub string `json:"ishub" bson:"ishub" yaml:"ishub" validate:"checkyesorno"` + AccessKey string `json:"accesskey" bson:"accesskey" yaml:"accesskey"` + Interface string `json:"interface" bson:"interface" yaml:"interface"` + LastModified int64 `json:"lastmodified" bson:"lastmodified" yaml:"lastmodified"` + ExpirationDateTime int64 `json:"expdatetime" bson:"expdatetime" yaml:"expdatetime"` + LastPeerUpdate int64 `json:"lastpeerupdate" bson:"lastpeerupdate" yaml:"lastpeerupdate"` + LastCheckIn int64 `json:"lastcheckin" bson:"lastcheckin" yaml:"lastcheckin"` + MacAddress string `json:"macaddress" bson:"macaddress" yaml:"macaddress"` + Password string `json:"password" bson:"password" yaml:"password" validate:"required,min=6"` + Network string `json:"network" bson:"network" yaml:"network" validate:"network_exists"` + IsRelayed string `json:"isrelayed" bson:"isrelayed" yaml:"isrelayed"` + IsPending string `json:"ispending" bson:"ispending" yaml:"ispending"` + IsRelay string `json:"isrelay" bson:"isrelay" yaml:"isrelay" validate:"checkyesorno"` + IsDocker string `json:"isdocker" bson:"isdocker" yaml:"isdocker" validate:"checkyesorno"` + IsK8S string `json:"isk8s" bson:"isk8s" yaml:"isk8s" validate:"checkyesorno"` + IsEgressGateway string `json:"isegressgateway" bson:"isegressgateway" yaml:"isegressgateway" validate:"checkyesorno"` + IsIngressGateway string `json:"isingressgateway" bson:"isingressgateway" yaml:"isingressgateway" validate:"checkyesorno"` + EgressGatewayRanges []string `json:"egressgatewayranges" bson:"egressgatewayranges" yaml:"egressgatewayranges"` EgressGatewayNatEnabled string `json:"egressgatewaynatenabled" bson:"egressgatewaynatenabled" yaml:"egressgatewaynatenabled"` - EgressGatewayRequest EgressGatewayRequest `json:"egressgatewayrequest" bson:"egressgatewayrequest" yaml:"egressgatewayrequest"` - RelayAddrs []string `json:"relayaddrs" bson:"relayaddrs" yaml:"relayaddrs"` - FailoverNode string `json:"failovernode" bson:"failovernode" yaml:"failovernode"` - IngressGatewayRange string `json:"ingressgatewayrange" bson:"ingressgatewayrange" yaml:"ingressgatewayrange"` - IngressGatewayRange6 string `json:"ingressgatewayrange6" bson:"ingressgatewayrange6" yaml:"ingressgatewayrange6"` + EgressGatewayRequest EgressGatewayRequest `json:"egressgatewayrequest" bson:"egressgatewayrequest" yaml:"egressgatewayrequest"` + RelayAddrs []string `json:"relayaddrs" bson:"relayaddrs" yaml:"relayaddrs"` + FailoverNode string `json:"failovernode" bson:"failovernode" yaml:"failovernode"` + IngressGatewayRange string `json:"ingressgatewayrange" bson:"ingressgatewayrange" yaml:"ingressgatewayrange"` + IngressGatewayRange6 string `json:"ingressgatewayrange6" bson:"ingressgatewayrange6" yaml:"ingressgatewayrange6"` // IsStatic - refers to if the Endpoint is set manually or dynamically - IsStatic string `json:"isstatic" bson:"isstatic" yaml:"isstatic" validate:"checkyesorno"` - UDPHolePunch string `json:"udpholepunch" bson:"udpholepunch" yaml:"udpholepunch" validate:"checkyesorno"` - DNSOn string `json:"dnson" bson:"dnson" yaml:"dnson" validate:"checkyesorno"` - IsServer string `json:"isserver" bson:"isserver" yaml:"isserver" validate:"checkyesorno"` - Action string `json:"action" bson:"action" yaml:"action"` - IPForwarding string `json:"ipforwarding" bson:"ipforwarding" yaml:"ipforwarding" validate:"checkyesorno"` - OS string `json:"os" bson:"os" yaml:"os"` - MTU int32 `json:"mtu" bson:"mtu" yaml:"mtu"` - Version string `json:"version" bson:"version" yaml:"version"` - Server string `json:"server" bson:"server" yaml:"server"` - TrafficKeys TrafficKeys `json:"traffickeys" bson:"traffickeys" yaml:"traffickeys"` - FirewallInUse string `json:"firewallinuse" bson:"firewallinuse" yaml:"firewallinuse"` - InternetGateway string `json:"internetgateway" bson:"internetgateway" yaml:"internetgateway"` - Connected string `json:"connected" bson:"connected" yaml:"connected" validate:"checkyesorno"` + IsStatic string `json:"isstatic" bson:"isstatic" yaml:"isstatic" validate:"checkyesorno"` + UDPHolePunch string `json:"udpholepunch" bson:"udpholepunch" yaml:"udpholepunch" validate:"checkyesorno"` + DNSOn string `json:"dnson" bson:"dnson" yaml:"dnson" validate:"checkyesorno"` + IsServer string `json:"isserver" bson:"isserver" yaml:"isserver" validate:"checkyesorno"` + Action string `json:"action" bson:"action" yaml:"action"` + IPForwarding string `json:"ipforwarding" bson:"ipforwarding" yaml:"ipforwarding" validate:"checkyesorno"` + OS string `json:"os" bson:"os" yaml:"os"` + MTU int32 `json:"mtu" bson:"mtu" yaml:"mtu"` + Version string `json:"version" bson:"version" yaml:"version"` + Server string `json:"server" bson:"server" yaml:"server"` + TrafficKeys TrafficKeys `json:"traffickeys" bson:"traffickeys" yaml:"traffickeys"` + FirewallInUse string `json:"firewallinuse" bson:"firewallinuse" yaml:"firewallinuse"` + InternetGateway string `json:"internetgateway" bson:"internetgateway" yaml:"internetgateway"` + Connected string `json:"connected" bson:"connected" yaml:"connected" validate:"checkyesorno"` // == PRO == - DefaultACL string `json:"defaultacl,omitempty" bson:"defaultacl,omitempty" yaml:"defaultacl,omitempty" validate:"checkyesornoorunset"` - OwnerID string `json:"ownerid,omitempty" bson:"ownerid,omitempty" yaml:"ownerid,omitempty"` - Failover string `json:"failover" bson:"failover" yaml:"failover" validate:"checkyesorno"` + DefaultACL string `json:"defaultacl,omitempty" bson:"defaultacl,omitempty" yaml:"defaultacl,omitempty" validate:"checkyesornoorunset"` + OwnerID string `json:"ownerid,omitempty" bson:"ownerid,omitempty" yaml:"ownerid,omitempty"` + Failover string `json:"failover" bson:"failover" yaml:"failover" validate:"checkyesorno"` } // NodesArray - used for node sorting @@ -375,7 +375,10 @@ func (node *LegacyNode) SetDefaultFailover() { } // Node.Fill - fills other node data into calling node data if not set on calling node (skips DNSOn) -func (newNode *Node) Fill(currentNode *Node, isPro bool) { // TODO add new field for nftables present +func (newNode *Node) Fill( + currentNode *Node, + isPro bool, +) { // TODO add new field for nftables present newNode.ID = currentNode.ID newNode.HostID = currentNode.HostID // Revisit the logic for boolean values diff --git a/pro/controllers/failover.go b/pro/controllers/failover.go index 42c02734..10ae6a02 100644 --- a/pro/controllers/failover.go +++ b/pro/controllers/failover.go @@ -19,24 +19,25 @@ import ( // FailOverHandlers - handlers for FailOver func FailOverHandlers(r *mux.Router) { - r.HandleFunc("/api/v1/node/{nodeid}/failover", http.HandlerFunc(getfailOver)).Methods(http.MethodGet) - r.HandleFunc("/api/v1/node/{nodeid}/failover", logic.SecurityCheck(true, http.HandlerFunc(createfailOver))).Methods(http.MethodPost) - r.HandleFunc("/api/v1/node/{nodeid}/failover", logic.SecurityCheck(true, http.HandlerFunc(deletefailOver))).Methods(http.MethodDelete) - r.HandleFunc("/api/v1/node/{network}/failover/reset", logic.SecurityCheck(true, http.HandlerFunc(resetFailOver))).Methods(http.MethodPost) - r.HandleFunc("/api/v1/node/{nodeid}/failover_me", controller.Authorize(true, false, "host", http.HandlerFunc(failOverME))).Methods(http.MethodPost) + r.HandleFunc("/api/v1/node/{nodeid}/failover", http.HandlerFunc(getfailOver)). + Methods(http.MethodGet) + r.HandleFunc("/api/v1/node/{nodeid}/failover", logic.SecurityCheck(true, http.HandlerFunc(createfailOver))). + Methods(http.MethodPost) + r.HandleFunc("/api/v1/node/{nodeid}/failover", logic.SecurityCheck(true, http.HandlerFunc(deletefailOver))). + Methods(http.MethodDelete) + r.HandleFunc("/api/v1/node/{network}/failover/reset", logic.SecurityCheck(true, http.HandlerFunc(resetFailOver))). + Methods(http.MethodPost) + r.HandleFunc("/api/v1/node/{nodeid}/failover_me", controller.Authorize(true, false, "host", http.HandlerFunc(failOverME))). + Methods(http.MethodPost) } -// swagger:route GET /api/v1/node/failover node getfailOver -// -// get failover node. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: nodeResponse +// @Summary Get failover node +// @Router /api/v1/node/{nodeid}/failover [get] +// @Tags PRO +// @Param nodeid path string true "Node ID" +// @Success 200 {object} models.Node +// @Failure 400 {object} models.ErrorResponse +// @Failure 404 {object} models.ErrorResponse func getfailOver(w http.ResponseWriter, r *http.Request) { var params = mux.Vars(r) nodeid := params["nodeid"] @@ -50,24 +51,24 @@ func getfailOver(w http.ResponseWriter, r *http.Request) { failOverNode, exists := proLogic.FailOverExists(node.Network) if !exists { - logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("failover node not found"), "notfound")) + logic.ReturnErrorResponse( + w, + r, + logic.FormatError(errors.New("failover node not found"), "notfound"), + ) return } w.Header().Set("Content-Type", "application/json") logic.ReturnSuccessResponseWithJson(w, r, failOverNode, "get failover node successfully") } -// swagger:route POST /api/v1/node/failover node createfailOver -// -// Create a relay. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: nodeResponse +// @Summary Create failover node +// @Router /api/v1/node/{nodeid}/failover [post] +// @Tags PRO +// @Param nodeid path string true "Node ID" +// @Success 200 {object} models.Node +// @Failure 400 {object} models.ErrorResponse +// @Failure 500 {object} models.ErrorResponse func createfailOver(w http.ResponseWriter, r *http.Request) { var params = mux.Vars(r) nodeid := params["nodeid"] @@ -88,6 +89,12 @@ func createfailOver(w http.ResponseWriter, r *http.Request) { logic.ReturnSuccessResponseWithJson(w, r, node, "created failover successfully") } +// @Summary Reset failover for a network +// @Router /api/v1/node/{network}/failover/reset [post] +// @Tags PRO +// @Param network path string true "Network ID" +// @Success 200 {object} models.SuccessResponse +// @Failure 500 {object} models.ErrorResponse func resetFailOver(w http.ResponseWriter, r *http.Request) { var params = mux.Vars(r) net := params["network"] @@ -108,17 +115,13 @@ func resetFailOver(w http.ResponseWriter, r *http.Request) { logic.ReturnSuccessResponse(w, r, "failover has been reset successfully") } -// swagger:route DELETE /api/v1/node/failover node deletefailOver -// -// Create a relay. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: nodeResponse +// @Summary Delete failover node +// @Router /api/v1/node/{nodeid}/failover [delete] +// @Tags PRO +// @Param nodeid path string true "Node ID" +// @Success 200 {object} models.Node +// @Failure 400 {object} models.ErrorResponse +// @Failure 500 {object} models.ErrorResponse func deletefailOver(w http.ResponseWriter, r *http.Request) { var params = mux.Vars(r) nodeid := params["nodeid"] @@ -145,17 +148,15 @@ func deletefailOver(w http.ResponseWriter, r *http.Request) { logic.ReturnSuccessResponseWithJson(w, r, node, "deleted failover successfully") } -// swagger:route POST /api/node/{nodeid}/failOverME node failOver_me -// -// Create a relay. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: nodeResponse +// @Summary Failover me +// @Router /api/v1/node/{nodeid}/failover_me [post] +// @Tags PRO +// @Param nodeid path string true "Node ID" +// @Accept json +// @Param body body models.FailOverMeReq true "Failover request" +// @Success 200 {object} models.SuccessResponse +// @Failure 400 {object} models.ErrorResponse +// @Failure 500 {object} models.ErrorResponse func failOverME(w http.ResponseWriter, r *http.Request) { var params = mux.Vars(r) nodeid := params["nodeid"] @@ -174,7 +175,14 @@ func failOverME(w http.ResponseWriter, r *http.Request) { failOverNode, exists := proLogic.FailOverExists(node.Network) if !exists { - logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("req-from: %s, failover node doesn't exist in the network", host.Name), "badrequest")) + logic.ReturnErrorResponse( + w, + r, + logic.FormatError( + fmt.Errorf("req-from: %s, failover node doesn't exist in the network", host.Name), + "badrequest", + ), + ) return } var failOverReq models.FailOverMeReq @@ -188,27 +196,57 @@ func failOverME(w http.ResponseWriter, r *http.Request) { peerNode, err := logic.GetNodeByID(failOverReq.NodeID) if err != nil { slog.Error("peer not found: ", "nodeid", failOverReq.NodeID, "error", err) - logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("peer not found"), "badrequest")) + logic.ReturnErrorResponse( + w, + r, + logic.FormatError(errors.New("peer not found"), "badrequest"), + ) return } if node.IsFailOver { - logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("node is acting as failover"), "badrequest")) + logic.ReturnErrorResponse( + w, + r, + logic.FormatError(errors.New("node is acting as failover"), "badrequest"), + ) return } if node.IsRelayed && node.RelayedBy == peerNode.ID.String() { - logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("node is relayed by peer node"), "badrequest")) + logic.ReturnErrorResponse( + w, + r, + logic.FormatError(errors.New("node is relayed by peer node"), "badrequest"), + ) return } if node.IsRelay && peerNode.RelayedBy == node.ID.String() { - logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("node acting as relay for the peer node"), "badrequest")) + logic.ReturnErrorResponse( + w, + r, + logic.FormatError(errors.New("node acting as relay for the peer node"), "badrequest"), + ) return } if node.IsInternetGateway && peerNode.InternetGwID == node.ID.String() { - logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("node acting as internet gw for the peer node"), "badrequest")) + logic.ReturnErrorResponse( + w, + r, + logic.FormatError( + errors.New("node acting as internet gw for the peer node"), + "badrequest", + ), + ) return } if node.InternetGwID != "" && node.InternetGwID == peerNode.ID.String() { - logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("node using a internet gw by the peer node"), "badrequest")) + logic.ReturnErrorResponse( + w, + r, + logic.FormatError( + errors.New("node using a internet gw by the peer node"), + "badrequest", + ), + ) return } @@ -216,10 +254,20 @@ func failOverME(w http.ResponseWriter, r *http.Request) { if err != nil { slog.Error("failed to create failover", "id", node.ID.String(), "network", node.Network, "error", err) - logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("failed to create failover: %v", err), "internal")) + logic.ReturnErrorResponse( + w, + r, + logic.FormatError(fmt.Errorf("failed to create failover: %v", err), "internal"), + ) return } - slog.Info("[auto-relay] created relay on node", "node", node.ID.String(), "network", node.Network) + slog.Info( + "[auto-relay] created relay on node", + "node", + node.ID.String(), + "network", + node.Network, + ) sendPeerUpdate = true if sendPeerUpdate { diff --git a/pro/controllers/inet_gws.go b/pro/controllers/inet_gws.go index 651ea58a..22716514 100644 --- a/pro/controllers/inet_gws.go +++ b/pro/controllers/inet_gws.go @@ -16,22 +16,24 @@ import ( // InetHandlers - handlers for internet gw func InetHandlers(r *mux.Router) { - r.HandleFunc("/api/nodes/{network}/{nodeid}/inet_gw", logic.SecurityCheck(true, http.HandlerFunc(createInternetGw))).Methods(http.MethodPost) - r.HandleFunc("/api/nodes/{network}/{nodeid}/inet_gw", logic.SecurityCheck(true, http.HandlerFunc(updateInternetGw))).Methods(http.MethodPut) - r.HandleFunc("/api/nodes/{network}/{nodeid}/inet_gw", logic.SecurityCheck(true, http.HandlerFunc(deleteInternetGw))).Methods(http.MethodDelete) + r.HandleFunc("/api/nodes/{network}/{nodeid}/inet_gw", logic.SecurityCheck(true, http.HandlerFunc(createInternetGw))). + Methods(http.MethodPost) + r.HandleFunc("/api/nodes/{network}/{nodeid}/inet_gw", logic.SecurityCheck(true, http.HandlerFunc(updateInternetGw))). + Methods(http.MethodPut) + r.HandleFunc("/api/nodes/{network}/{nodeid}/inet_gw", logic.SecurityCheck(true, http.HandlerFunc(deleteInternetGw))). + Methods(http.MethodDelete) } -// swagger:route POST /api/nodes/{network}/{nodeid}/inet_gw nodes createInternetGw -// -// Create an inet node. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: nodeResponse +// @Summary Create an internet gateway +// @Router /api/nodes/{network}/{nodeid}/inet_gw [post] +// @Tags PRO +// @Accept json +// @Param network path string true "Network ID" +// @Param nodeid path string true "Node ID" +// @Param body body models.InetNodeReq true "Internet gateway request" +// @Success 200 {object} models.Node +// @Failure 400 {object} models.ErrorResponse +// @Failure 500 {object} models.ErrorResponse func createInternetGw(w http.ResponseWriter, r *http.Request) { var params = mux.Vars(r) w.Header().Set("Content-Type", "application/json") @@ -58,7 +60,14 @@ func createInternetGw(w http.ResponseWriter, r *http.Request) { return } if host.OS != models.OS_Types.Linux { - logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("only linux nodes can be made internet gws"), "badrequest")) + logic.ReturnErrorResponse( + w, + r, + logic.FormatError( + errors.New("only linux nodes can be made internet gws"), + "badrequest", + ), + ) return } err = proLogic.ValidateInetGwReq(node, request, false) @@ -81,23 +90,29 @@ func createInternetGw(w http.ResponseWriter, r *http.Request) { return } apiNode := node.ConvertToAPINode() - logger.Log(1, r.Header.Get("user"), "created ingress gateway on node", nodeid, "on network", netid) + logger.Log( + 1, + r.Header.Get("user"), + "created ingress gateway on node", + nodeid, + "on network", + netid, + ) w.WriteHeader(http.StatusOK) json.NewEncoder(w).Encode(apiNode) go mq.PublishPeerUpdate(false) } -// swagger:route PUT /api/nodes/{network}/{nodeid}/inet_gw nodes updateInternetGw -// -// update an inet node. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: nodeResponse +// @Summary Update an internet gateway +// @Router /api/nodes/{network}/{nodeid}/inet_gw [put] +// @Tags PRO +// @Accept json +// @Param network path string true "Network ID" +// @Param nodeid path string true "Node ID" +// @Param body body models.InetNodeReq true "Internet gateway request" +// @Success 200 {object} models.Node +// @Failure 400 {object} models.ErrorResponse +// @Failure 500 {object} models.ErrorResponse func updateInternetGw(w http.ResponseWriter, r *http.Request) { var params = mux.Vars(r) w.Header().Set("Content-Type", "application/json") @@ -115,7 +130,11 @@ func updateInternetGw(w http.ResponseWriter, r *http.Request) { return } if !node.IsInternetGateway { - logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("node is not a internet gw"), "badrequest")) + logic.ReturnErrorResponse( + w, + r, + logic.FormatError(errors.New("node is not a internet gw"), "badrequest"), + ) return } err = proLogic.ValidateInetGwReq(node, request, true) @@ -131,23 +150,27 @@ func updateInternetGw(w http.ResponseWriter, r *http.Request) { return } apiNode := node.ConvertToAPINode() - logger.Log(1, r.Header.Get("user"), "created ingress gateway on node", nodeid, "on network", netid) + logger.Log( + 1, + r.Header.Get("user"), + "created ingress gateway on node", + nodeid, + "on network", + netid, + ) w.WriteHeader(http.StatusOK) json.NewEncoder(w).Encode(apiNode) go mq.PublishPeerUpdate(false) } -// swagger:route DELETE /api/nodes/{network}/{nodeid}/inet_gw nodes deleteInternetGw -// -// Delete an internet gw. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: nodeResponse +// @Summary Delete an internet gateway +// @Router /api/nodes/{network}/{nodeid}/inet_gw [delete] +// @Tags PRO +// @Param network path string true "Network ID" +// @Param nodeid path string true "Node ID" +// @Success 200 {object} models.Node +// @Failure 400 {object} models.ErrorResponse +// @Failure 500 {object} models.ErrorResponse func deleteInternetGw(w http.ResponseWriter, r *http.Request) { var params = mux.Vars(r) w.Header().Set("Content-Type", "application/json") @@ -166,7 +189,14 @@ func deleteInternetGw(w http.ResponseWriter, r *http.Request) { return } apiNode := node.ConvertToAPINode() - logger.Log(1, r.Header.Get("user"), "created ingress gateway on node", nodeid, "on network", netid) + logger.Log( + 1, + r.Header.Get("user"), + "created ingress gateway on node", + nodeid, + "on network", + netid, + ) w.WriteHeader(http.StatusOK) json.NewEncoder(w).Encode(apiNode) go mq.PublishPeerUpdate(false) diff --git a/pro/controllers/relay.go b/pro/controllers/relay.go index a3bacab6..b8061b4f 100644 --- a/pro/controllers/relay.go +++ b/pro/controllers/relay.go @@ -19,22 +19,25 @@ import ( // RelayHandlers - handle Pro Relays func RelayHandlers(r *mux.Router) { - r.HandleFunc("/api/nodes/{network}/{nodeid}/createrelay", controller.Authorize(false, true, "user", http.HandlerFunc(createRelay))).Methods(http.MethodPost) - r.HandleFunc("/api/nodes/{network}/{nodeid}/deleterelay", controller.Authorize(false, true, "user", http.HandlerFunc(deleteRelay))).Methods(http.MethodDelete) - r.HandleFunc("/api/v1/host/{hostid}/failoverme", controller.Authorize(true, false, "host", http.HandlerFunc(failOverME))).Methods(http.MethodPost) + r.HandleFunc("/api/nodes/{network}/{nodeid}/createrelay", controller.Authorize(false, true, "user", http.HandlerFunc(createRelay))). + Methods(http.MethodPost) + r.HandleFunc("/api/nodes/{network}/{nodeid}/deleterelay", controller.Authorize(false, true, "user", http.HandlerFunc(deleteRelay))). + Methods(http.MethodDelete) + r.HandleFunc("/api/v1/host/{hostid}/failoverme", controller.Authorize(true, false, "host", http.HandlerFunc(failOverME))). + Methods(http.MethodPost) } -// swagger:route POST /api/nodes/{network}/{nodeid}/createrelay nodes createRelay -// -// Create a relay. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: nodeResponse +// @Summary Create a relay +// @Router /api/nodes/{network}/{nodeid}/createrelay [post] +// @Tags PRO +// @Accept json +// @Produce json +// @Param network path string true "Network ID" +// @Param nodeid path string true "Node ID" +// @Param body body models.RelayRequest true "Relay request parameters" +// @Success 200 {object} models.ApiNode +// @Failure 400 {object} models.ErrorResponse +// @Failure 500 {object} models.ErrorResponse func createRelay(w http.ResponseWriter, r *http.Request) { var relayRequest models.RelayRequest var params = mux.Vars(r) @@ -49,8 +52,16 @@ func createRelay(w http.ResponseWriter, r *http.Request) { relayRequest.NodeID = params["nodeid"] _, relayNode, err := proLogic.CreateRelay(relayRequest) if err != nil { - logger.Log(0, r.Header.Get("user"), - fmt.Sprintf("failed to create relay on node [%s] on network [%s]: %v", relayRequest.NodeID, relayRequest.NetID, err)) + logger.Log( + 0, + r.Header.Get("user"), + fmt.Sprintf( + "failed to create relay on node [%s] on network [%s]: %v", + relayRequest.NodeID, + relayRequest.NetID, + err, + ), + ) logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal")) return } @@ -64,23 +75,29 @@ func createRelay(w http.ResponseWriter, r *http.Request) { } } go mq.PublishPeerUpdate(false) - logger.Log(1, r.Header.Get("user"), "created relay on node", relayRequest.NodeID, "on network", relayRequest.NetID) + logger.Log( + 1, + r.Header.Get("user"), + "created relay on node", + relayRequest.NodeID, + "on network", + relayRequest.NetID, + ) apiNode := relayNode.ConvertToAPINode() w.WriteHeader(http.StatusOK) json.NewEncoder(w).Encode(apiNode) } -// swagger:route DELETE /api/nodes/{network}/{nodeid}/deleterelay nodes deleteRelay -// -// Remove a relay. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: nodeResponse +// @Summary Remove a relay +// @Router /api/nodes/{network}/{nodeid}/deleterelay [delete] +// @Tags PRO +// @Accept json +// @Produce json +// @Param network path string true "Network ID" +// @Param nodeid path string true "Node ID" +// @Success 200 {object} models.ApiNode +// @Failure 400 {object} models.ErrorResponse +// @Failure 500 {object} models.ErrorResponse func deleteRelay(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") var params = mux.Vars(r) @@ -97,7 +114,15 @@ func deleteRelay(w http.ResponseWriter, r *http.Request) { for _, relayedNode := range updateNodes { err = mq.NodeUpdate(&relayedNode) if err != nil { - logger.Log(1, "relayed node update ", relayedNode.ID.String(), "on network", relayedNode.Network, ": ", err.Error()) + logger.Log( + 1, + "relayed node update ", + relayedNode.ID.String(), + "on network", + relayedNode.Network, + ": ", + err.Error(), + ) } h, err := logic.GetHost(relayedNode.HostID.String()) @@ -109,14 +134,27 @@ func deleteRelay(w http.ResponseWriter, r *http.Request) { } node.IsRelay = true // for iot update to recognise that it has to delete relay peer if err = mq.PublishSingleHostPeerUpdate(h, nodes, &node, nil, false); err != nil { - logger.Log(1, "failed to publish peer update to host", h.ID.String(), ": ", err.Error()) + logger.Log( + 1, + "failed to publish peer update to host", + h.ID.String(), + ": ", + err.Error(), + ) } } } } mq.PublishPeerUpdate(false) }() - logger.Log(1, r.Header.Get("user"), "deleted relay on node", node.ID.String(), "on network", node.Network) + logger.Log( + 1, + r.Header.Get("user"), + "deleted relay on node", + node.ID.String(), + "on network", + node.Network, + ) apiNode := node.ConvertToAPINode() w.WriteHeader(http.StatusOK) json.NewEncoder(w).Encode(apiNode) diff --git a/pro/controllers/users.go b/pro/controllers/users.go index 1d6d2093..987e9274 100644 --- a/pro/controllers/users.go +++ b/pro/controllers/users.go @@ -17,27 +17,30 @@ import ( ) func UserHandlers(r *mux.Router) { - r.HandleFunc("/api/users/{username}/remote_access_gw/{remote_access_gateway_id}", logic.SecurityCheck(true, http.HandlerFunc(attachUserToRemoteAccessGw))).Methods(http.MethodPost) - r.HandleFunc("/api/users/{username}/remote_access_gw/{remote_access_gateway_id}", logic.SecurityCheck(true, http.HandlerFunc(removeUserFromRemoteAccessGW))).Methods(http.MethodDelete) - r.HandleFunc("/api/users/{username}/remote_access_gw", logic.SecurityCheck(false, logic.ContinueIfUserMatch(http.HandlerFunc(getUserRemoteAccessGws)))).Methods(http.MethodGet) - r.HandleFunc("/api/users/ingress/{ingress_id}", logic.SecurityCheck(true, http.HandlerFunc(ingressGatewayUsers))).Methods(http.MethodGet) + r.HandleFunc("/api/users/{username}/remote_access_gw/{remote_access_gateway_id}", logic.SecurityCheck(true, http.HandlerFunc(attachUserToRemoteAccessGw))). + Methods(http.MethodPost) + r.HandleFunc("/api/users/{username}/remote_access_gw/{remote_access_gateway_id}", logic.SecurityCheck(true, http.HandlerFunc(removeUserFromRemoteAccessGW))). + Methods(http.MethodDelete) + r.HandleFunc("/api/users/{username}/remote_access_gw", logic.SecurityCheck(false, logic.ContinueIfUserMatch(http.HandlerFunc(getUserRemoteAccessGws)))). + Methods(http.MethodGet) + r.HandleFunc("/api/users/ingress/{ingress_id}", logic.SecurityCheck(true, http.HandlerFunc(ingressGatewayUsers))). + Methods(http.MethodGet) r.HandleFunc("/api/oauth/login", auth.HandleAuthLogin).Methods(http.MethodGet) r.HandleFunc("/api/oauth/callback", auth.HandleAuthCallback).Methods(http.MethodGet) r.HandleFunc("/api/oauth/headless", auth.HandleHeadlessSSO) r.HandleFunc("/api/oauth/register/{regKey}", auth.RegisterHostSSO).Methods(http.MethodGet) } -// swagger:route POST /api/users/{username}/remote_access_gw user attachUserToRemoteAccessGateway -// -// Attach User to a remote access gateway. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: userBodyResponse +// @Summary Attach user to a remote access gateway +// @Router /api/users/{username}/remote_access_gw/{remote_access_gateway_id} [post] +// @Tags PRO +// @Accept json +// @Produce json +// @Param username path string true "Username" +// @Param remote_access_gateway_id path string true "Remote Access Gateway ID" +// @Success 200 {object} models.ReturnUser +// @Failure 400 {object} models.ErrorResponse +// @Failure 500 {object} models.ErrorResponse func attachUserToRemoteAccessGw(w http.ResponseWriter, r *http.Request) { // set header. w.Header().Set("Content-Type", "application/json") @@ -46,27 +49,59 @@ func attachUserToRemoteAccessGw(w http.ResponseWriter, r *http.Request) { username := params["username"] remoteGwID := params["remote_access_gateway_id"] if username == "" || remoteGwID == "" { - logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("required params `username` and `remote_access_gateway_id`"), "badrequest")) + logic.ReturnErrorResponse( + w, + r, + logic.FormatError( + errors.New("required params `username` and `remote_access_gateway_id`"), + "badrequest", + ), + ) return } user, err := logic.GetUser(username) if err != nil { slog.Error("failed to fetch user: ", "username", username, "error", err.Error()) - logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("failed to fetch user %s, error: %v", username, err), "badrequest")) + logic.ReturnErrorResponse( + w, + r, + logic.FormatError( + fmt.Errorf("failed to fetch user %s, error: %v", username, err), + "badrequest", + ), + ) return } if user.IsAdmin || user.IsSuperAdmin { - logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("superadmins/admins have access to all gateways"), "badrequest")) + logic.ReturnErrorResponse( + w, + r, + logic.FormatError( + errors.New("superadmins/admins have access to all gateways"), + "badrequest", + ), + ) return } node, err := logic.GetNodeByID(remoteGwID) if err != nil { slog.Error("failed to fetch gateway node", "nodeID", remoteGwID, "error", err) - logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("failed to fetch remote access gateway node, error: %v", err), "badrequest")) + logic.ReturnErrorResponse( + w, + r, + logic.FormatError( + fmt.Errorf("failed to fetch remote access gateway node, error: %v", err), + "badrequest", + ), + ) return } if !node.IsIngressGateway { - logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("node is not a remote access gateway"), "badrequest")) + logic.ReturnErrorResponse( + w, + r, + logic.FormatError(fmt.Errorf("node is not a remote access gateway"), "badrequest"), + ) return } if user.RemoteGwIDs == nil { @@ -76,24 +111,30 @@ func attachUserToRemoteAccessGw(w http.ResponseWriter, r *http.Request) { err = logic.UpsertUser(*user) if err != nil { slog.Error("failed to update user's gateways", "user", username, "error", err) - logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("failed to fetch remote access gateway node,error: %v", err), "badrequest")) + logic.ReturnErrorResponse( + w, + r, + logic.FormatError( + fmt.Errorf("failed to fetch remote access gateway node,error: %v", err), + "badrequest", + ), + ) return } json.NewEncoder(w).Encode(logic.ToReturnUser(*user)) } -// swagger:route DELETE /api/users/{username}/remote_access_gw user removeUserFromRemoteAccessGW -// -// Delete User from a remote access gateway. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: userBodyResponse +// @Summary Remove user from a remote access gateway +// @Router /api/users/{username}/remote_access_gw/{remote_access_gateway_id} [delete] +// @Tags PRO +// @Accept json +// @Produce json +// @Param username path string true "Username" +// @Param remote_access_gateway_id path string true "Remote Access Gateway ID" +// @Success 200 {object} models.ReturnUser +// @Failure 400 {object} models.ErrorResponse +// @Failure 500 {object} models.ErrorResponse func removeUserFromRemoteAccessGW(w http.ResponseWriter, r *http.Request) { // set header. w.Header().Set("Content-Type", "application/json") @@ -102,13 +143,27 @@ func removeUserFromRemoteAccessGW(w http.ResponseWriter, r *http.Request) { username := params["username"] remoteGwID := params["remote_access_gateway_id"] if username == "" || remoteGwID == "" { - logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("required params `username` and `remote_access_gateway_id`"), "badrequest")) + logic.ReturnErrorResponse( + w, + r, + logic.FormatError( + errors.New("required params `username` and `remote_access_gateway_id`"), + "badrequest", + ), + ) return } user, err := logic.GetUser(username) if err != nil { logger.Log(0, username, "failed to fetch user: ", err.Error()) - logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("failed to fetch user %s, error: %v", username, err), "badrequest")) + logic.ReturnErrorResponse( + w, + r, + logic.FormatError( + fmt.Errorf("failed to fetch user %s, error: %v", username, err), + "badrequest", + ), + ) return } delete(user.RemoteGwIDs, remoteGwID) @@ -139,23 +194,30 @@ func removeUserFromRemoteAccessGW(w http.ResponseWriter, r *http.Request) { err = logic.UpsertUser(*user) if err != nil { slog.Error("failed to update user gateways", "user", username, "error", err) - logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("failed to fetch remote access gaetway node "+err.Error()), "badrequest")) + logic.ReturnErrorResponse( + w, + r, + logic.FormatError( + errors.New("failed to fetch remote access gaetway node "+err.Error()), + "badrequest", + ), + ) return } json.NewEncoder(w).Encode(logic.ToReturnUser(*user)) } -// swagger:route GET "/api/users/{username}/remote_access_gw" nodes getUserRemoteAccessGws -// -// Get an individual node. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: nodeResponse +// @Summary Get user's remote access gateways +// @Router /api/users/{username}/remote_access_gw [get] +// @Tags PRO +// @Accept json +// @Produce json +// @Param username path string true "Username" +// @Param remote_access_clientid query string false "Remote Access Client ID" +// @Param from_mobile query boolean false "Request from mobile" +// @Success 200 {array} models.UserRemoteGws +// @Failure 400 {object} models.ErrorResponse +// @Failure 500 {object} models.ErrorResponse func getUserRemoteAccessGws(w http.ResponseWriter, r *http.Request) { // set header. w.Header().Set("Content-Type", "application/json") @@ -163,7 +225,11 @@ func getUserRemoteAccessGws(w http.ResponseWriter, r *http.Request) { var params = mux.Vars(r) username := params["username"] if username == "" { - logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("required params username"), "badrequest")) + logic.ReturnErrorResponse( + w, + r, + logic.FormatError(errors.New("required params username"), "badrequest"), + ) return } remoteAccessClientID := r.URL.Query().Get("remote_access_clientid") @@ -178,7 +244,11 @@ func getUserRemoteAccessGws(w http.ResponseWriter, r *http.Request) { } reqFromMobile := r.URL.Query().Get("from_mobile") == "true" if req.RemoteAccessClientID == "" && remoteAccessClientID == "" { - logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("remote access client id cannot be empty"), "badrequest")) + logic.ReturnErrorResponse( + w, + r, + logic.FormatError(errors.New("remote access client id cannot be empty"), "badrequest"), + ) return } if req.RemoteAccessClientID == "" { @@ -188,7 +258,14 @@ func getUserRemoteAccessGws(w http.ResponseWriter, r *http.Request) { user, err := logic.GetUser(username) if err != nil { logger.Log(0, username, "failed to fetch user: ", err.Error()) - logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("failed to fetch user %s, error: %v", username, err), "badrequest")) + logic.ReturnErrorResponse( + w, + r, + logic.FormatError( + fmt.Errorf("failed to fetch user %s, error: %v", username, err), + "badrequest", + ), + ) return } allextClients, err := logic.GetAllExtClients() @@ -199,7 +276,8 @@ func getUserRemoteAccessGws(w http.ResponseWriter, r *http.Request) { processedAdminNodeIds := make(map[string]struct{}) for _, extClient := range allextClients { - if extClient.RemoteAccessClientID == req.RemoteAccessClientID && extClient.OwnerID == username { + if extClient.RemoteAccessClientID == req.RemoteAccessClientID && + extClient.OwnerID == username { node, err := logic.GetNodeByID(extClient.IngressGatewayID) if err != nil { continue @@ -219,7 +297,8 @@ func getUserRemoteAccessGws(w http.ResponseWriter, r *http.Request) { slog.Error("failed to get node network", "error", err) } - if _, ok := user.RemoteGwIDs[node.ID.String()]; (!user.IsAdmin && !user.IsSuperAdmin) && ok { + if _, ok := user.RemoteGwIDs[node.ID.String()]; (!user.IsAdmin && !user.IsSuperAdmin) && + ok { gws := userGws[node.Network] extClient.AllowedIPs = logic.GetExtclientAllowedIPs(extClient) gws = append(gws, models.UserRemoteGws{ @@ -345,17 +424,15 @@ func getUserRemoteAccessGws(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(userGws) } -// swagger:route GET /api/nodes/{network}/{nodeid}/ingress/users users ingressGatewayUsers -// -// Lists all the users attached to an ingress gateway. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: nodeResponse +// @Summary List users attached to an remote access gateway +// @Router /api/nodes/{network}/{nodeid}/ingress/users [get] +// @Tags PRO +// @Accept json +// @Produce json +// @Param ingress_id path string true "Ingress Gateway ID" +// @Success 200 {array} models.IngressGwUsers +// @Failure 400 {object} models.ErrorResponse +// @Failure 500 {object} models.ErrorResponse func ingressGatewayUsers(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") var params = mux.Vars(r) @@ -368,8 +445,17 @@ func ingressGatewayUsers(w http.ResponseWriter, r *http.Request) { } gwUsers, err := logic.GetIngressGwUsers(node) if err != nil { - slog.Error("failed to get users on ingress gateway", "nodeid", ingressID, "network", node.Network, "user", r.Header.Get("user"), - "error", err) + slog.Error( + "failed to get users on ingress gateway", + "nodeid", + ingressID, + "network", + node.Network, + "user", + r.Header.Get("user"), + "error", + err, + ) logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal")) return } diff --git a/swagger.yaml b/swagger.yaml new file mode 100644 index 00000000..e0b27e4b --- /dev/null +++ b/swagger.yaml @@ -0,0 +1,3105 @@ +definitions: + acls.ACL: + additionalProperties: + type: integer + type: object + acls.ACLContainer: + additionalProperties: + $ref: '#/definitions/acls.ACL' + type: object + config.ServerConfig: + properties: + IsEE: + type: string + allowedEmailDomains: + type: string + allowedOrigin: + type: string + apiconnString: + type: string + apihost: + type: string + apiport: + type: string + authProvider: + type: string + azureTenant: + type: string + basicAuth: + type: string + broker: + type: string + brokerType: + type: string + cacheEnabled: + type: string + clientID: + type: string + clientSecret: + type: string + coreDNSAddr: + type: string + database: + type: string + deployedByOperator: + type: boolean + disableRemoteIPCheck: + type: string + displayKeys: + type: string + dnskey: + type: string + dnsmode: + type: string + egressesLimit: + type: integer + emqxRestEndpoint: + type: string + endpoint_detection: + type: boolean + environment: + type: string + frontendURL: + type: string + hostNetwork: + type: string + ingressesLimit: + type: integer + jwtValidityDuration: + $ref: '#/definitions/time.Duration' + licenseValue: + type: string + machinesLimit: + type: integer + masterKey: + type: string + messageQueueBackend: + type: string + metricInterval: + type: string + metricsExporter: + type: string + mqpassword: + type: string + mquserName: + type: string + netclientAutoUpdate: + type: string + netclientEndpointDetection: + type: string + netmakerTenantID: + type: string + networksLimit: + type: integer + nodeID: + type: string + oidcissuer: + type: string + platform: + type: string + publicIPService: + type: string + racAutoDisable: + type: boolean + restBackend: + type: string + server: + type: string + serverBrokerEndpoint: + type: string + sqlconn: + type: string + stunList: + type: string + stunPort: + type: integer + telemetry: + type: string + turnApiServer: + type: string + turnPassword: + type: string + turnPort: + type: integer + turnServer: + type: string + turnUserName: + type: string + useTurn: + type: boolean + usersLimit: + type: integer + verbosity: + type: integer + version: + type: string + type: object + models.APIEnrollmentKey: + properties: + expiration: + type: integer + networks: + items: + type: string + type: array + relay: + type: string + tags: + items: + type: string + type: array + type: + $ref: '#/definitions/models.KeyType' + unlimited: + type: boolean + uses_remaining: + type: integer + required: + - tags + type: object + models.ApiHost: + properties: + autoupdate: + type: boolean + debug: + type: boolean + defaultinterface: + type: string + endpointip: + type: string + endpointipv6: + type: string + firewallinuse: + type: string + id: + type: string + interfaces: + items: + $ref: '#/definitions/models.ApiIface' + type: array + isdefault: + type: boolean + isstatic: + type: boolean + isstaticport: + type: boolean + listenport: + type: integer + macaddress: + type: string + mtu: + type: integer + name: + type: string + nat_type: + type: string + nodes: + items: + type: string + type: array + os: + type: string + persistentkeepalive: + type: integer + publickey: + type: string + verbosity: + type: integer + version: + type: string + wg_public_listen_port: + type: integer + type: object + models.ApiIface: + properties: + addressString: + type: string + name: + type: string + type: object + models.ApiNode: + properties: + additional_rag_ips: + items: + type: string + type: array + address: + type: string + address6: + type: string + allowedips: + items: + type: string + type: array + connected: + type: boolean + defaultacl: + description: == PRO == + type: string + dnson: + type: boolean + egressgatewaynatenabled: + type: boolean + egressgatewayranges: + items: + type: string + type: array + expdatetime: + type: integer + fail_over_peers: + additionalProperties: + type: object + type: object + failed_over_by: + type: string + hostid: + minLength: 5 + type: string + id: + minLength: 5 + type: string + inet_node_req: + $ref: '#/definitions/models.InetNodeReq' + ingressdns: + type: string + internetgw_node_id: + type: string + is_fail_over: + type: boolean + isegressgateway: + type: boolean + isingressgateway: + type: boolean + isinternetgateway: + type: boolean + isrelay: + type: boolean + isrelayed: + type: boolean + lastcheckin: + type: integer + lastmodified: + type: integer + lastpeerupdate: + type: integer + localaddress: + type: string + metadata: + type: string + network: + type: string + networkrange: + type: string + networkrange6: + type: string + pendingdelete: + type: boolean + relayedby: + type: string + relaynodes: + items: + type: string + type: array + server: + type: string + required: + - hostid + - id + type: object + models.AuthParams: + properties: + id: + type: string + macaddress: + type: string + password: + type: string + type: object + models.DNSEntry: + properties: + address: + type: string + address6: + type: string + name: + maxLength: 192 + minLength: 1 + type: string + network: + type: string + required: + - name + type: object + models.EgressGatewayRequest: + properties: + natenabled: + type: string + netid: + type: string + nodeid: + type: string + ranges: + items: + type: string + type: array + type: object + models.EgressInfo: + properties: + egress_gateway_cfg: + $ref: '#/definitions/models.EgressGatewayRequest' + egress_gw_addr: + $ref: '#/definitions/net.IPNet' + egress_gw_addr6: + $ref: '#/definitions/net.IPNet' + egress_id: + type: string + network: + $ref: '#/definitions/net.IPNet' + network6: + $ref: '#/definitions/net.IPNet' + type: object + models.EgressNetworkRoutes: + properties: + egress_gw_addr: + $ref: '#/definitions/net.IPNet' + egress_gw_addr6: + $ref: '#/definitions/net.IPNet' + egress_ranges: + items: + type: string + type: array + node_addr: + $ref: '#/definitions/net.IPNet' + node_addr6: + $ref: '#/definitions/net.IPNet' + type: object + models.EnrollmentKey: + properties: + expiration: + type: string + networks: + items: + type: string + type: array + relay: + type: string + tags: + items: + type: string + type: array + token: + description: B64 value of EnrollmentToken + type: string + type: + $ref: '#/definitions/models.KeyType' + unlimited: + type: boolean + uses_remaining: + type: integer + value: + type: string + type: object + models.ErrorResponse: + properties: + code: + type: integer + message: + type: string + type: object + models.ExtClient: + properties: + address: + type: string + address6: + type: string + allowed_ips: + items: + type: string + type: array + clientid: + type: string + deniednodeacls: + additionalProperties: + type: object + type: object + dns: + type: string + enabled: + type: boolean + extraallowedips: + items: + type: string + type: array + ingressgatewayendpoint: + type: string + ingressgatewayid: + type: string + lastmodified: + type: integer + network: + type: string + ownerid: + type: string + postdown: + type: string + postup: + type: string + privatekey: + type: string + publickey: + type: string + remote_access_client_id: + description: unique ID (MAC address) of RAC machine + type: string + type: object + models.FailOverMeReq: + properties: + node_id: + type: string + type: object + models.FwUpdate: + properties: + egress_info: + additionalProperties: + $ref: '#/definitions/models.EgressInfo' + type: object + is_egress_gw: + type: boolean + type: object + models.Host: + properties: + autoupdate: + type: boolean + daemoninstalled: + type: boolean + debug: + type: boolean + defaultinterface: + type: string + endpointip: + items: + type: integer + type: array + endpointipv6: + items: + type: integer + type: array + firewallinuse: + type: string + hostpass: + type: string + id: + type: string + interface: + type: string + interfaces: + items: + $ref: '#/definitions/models.Iface' + type: array + ipforwarding: + type: boolean + isdefault: + type: boolean + isdocker: + type: boolean + isk8s: + type: boolean + isstatic: + type: boolean + isstaticport: + type: boolean + listenport: + type: integer + macaddress: + items: + type: integer + type: array + mtu: + type: integer + name: + type: string + nat_type: + type: string + nodes: + items: + type: string + type: array + os: + type: string + persistentkeepalive: + $ref: '#/definitions/time.Duration' + publickey: + items: + type: integer + type: array + traffickeypublic: + items: + type: integer + type: array + turn_endpoint: + $ref: '#/definitions/netip.AddrPort' + verbosity: + type: integer + version: + type: string + wg_public_listen_port: + type: integer + type: object + models.HostInfoMap: + additionalProperties: + $ref: '#/definitions/models.HostNetworkInfo' + type: object + models.HostMqAction: + enum: + - UPGRADE + - SIGNAL_HOST + - UPDATE_HOST + - DELETE_HOST + - JOIN_HOST_TO_NETWORK + - ACK + - REQ_ACK + - CHECK_IN + - UPDATE_KEYS + - REQ_PULL + - SIGNAL_PULL + - UPDATE_METRICS + type: string + x-enum-varnames: + - Upgrade + - SignalHost + - UpdateHost + - DeleteHost + - JoinHostToNetwork + - Acknowledgement + - RequestAck + - CheckIn + - UpdateKeys + - RequestPull + - SignalPull + - UpdateMetrics + models.HostNetworkInfo: + properties: + interfaces: + items: + $ref: '#/definitions/models.Iface' + type: array + is_static: + type: boolean + is_static_port: + type: boolean + listen_port: + type: integer + type: object + models.HostPull: + properties: + change_default_gw: + type: boolean + default_gw_ip: + items: + type: integer + type: array + egress_network_routes: + items: + $ref: '#/definitions/models.EgressNetworkRoutes' + type: array + endpoint_detection: + type: boolean + fw_update: + $ref: '#/definitions/models.FwUpdate' + host: + $ref: '#/definitions/models.Host' + host_network_info: + $ref: '#/definitions/models.HostInfoMap' + is_inet_gw: + type: boolean + nodes: + items: + $ref: '#/definitions/models.Node' + type: array + peer_ids: + $ref: '#/definitions/models.PeerMap' + peers: + items: + $ref: '#/definitions/wgtypes.PeerConfig' + type: array + server_config: + $ref: '#/definitions/models.ServerConfig' + type: object + models.HostUpdate: + properties: + action: + $ref: '#/definitions/models.HostMqAction' + host: + $ref: '#/definitions/models.Host' + newMetrics: + $ref: '#/definitions/models.Metrics' + node: + $ref: '#/definitions/models.Node' + signal: + $ref: '#/definitions/models.Signal' + type: object + models.IDandAddr: + properties: + address: + type: string + host_id: + type: string + id: + type: string + is_extclient: + type: boolean + isserver: + type: string + listen_port: + type: integer + name: + type: string + network: + type: string + type: object + models.Iface: + properties: + address: + $ref: '#/definitions/net.IPNet' + addressString: + type: string + name: + type: string + type: object + models.InetNodeReq: + properties: + inet_node_client_ids: + items: + type: string + type: array + type: object + models.IngressGwUsers: + properties: + network: + type: string + node_id: + type: string + users: + items: + $ref: '#/definitions/models.ReturnUser' + type: array + type: object + models.KeyType: + enum: + - 0 + - 1 + - 2 + - 3 + type: integer + x-enum-varnames: + - Undefined + - TimeExpiration + - Uses + - Unlimited + models.Metric: + properties: + actualuptime: + $ref: '#/definitions/time.Duration' + connected: + type: boolean + latency: + type: integer + node_name: + type: string + percentup: + type: number + totalreceived: + type: integer + totalsent: + type: integer + totaltime: + type: integer + uptime: + type: integer + type: object + models.Metrics: + properties: + connectivity: + additionalProperties: + $ref: '#/definitions/models.Metric' + type: object + network: + type: string + node_id: + type: string + node_name: + type: string + type: object + models.Network: + properties: + addressrange: + type: string + addressrange6: + type: string + allowmanualsignup: + type: string + defaultacl: + type: string + defaultinterface: + maxLength: 35 + minLength: 1 + type: string + defaultkeepalive: + maximum: 1000 + type: integer + defaultlistenport: + maximum: 65535 + minimum: 1024 + type: integer + defaultmtu: + type: integer + defaultpostdown: + type: string + defaultudpholepunch: + type: string + isipv4: + type: string + isipv6: + type: string + netid: + maxLength: 32 + minLength: 1 + type: string + networklastmodified: + type: integer + nodelimit: + type: integer + nodeslastmodified: + type: integer + required: + - netid + type: object + models.Node: + properties: + action: + type: string + additional_rag_ips: + items: + type: number + type: array + address: + $ref: '#/definitions/net.IPNet' + address6: + $ref: '#/definitions/net.IPNet' + connected: + type: boolean + defaultacl: + description: == PRO == + type: string + dnson: + type: boolean + egressgatewaynatenabled: + type: boolean + egressgatewayranges: + items: + type: string + type: array + egressgatewayrequest: + $ref: '#/definitions/models.EgressGatewayRequest' + expdatetime: + type: string + fail_over_peers: + additionalProperties: + type: object + type: object + failed_over_by: + type: string + hostid: + type: string + id: + type: string + inet_node_req: + $ref: '#/definitions/models.InetNodeReq' + ingressdns: + type: string + ingressgatewayrange: + type: string + ingressgatewayrange6: + type: string + internetgw_node_id: + type: string + is_fail_over: + type: boolean + isegressgateway: + type: boolean + isingressgateway: + type: boolean + isinternetgateway: + type: boolean + isrelay: + type: boolean + isrelayed: + type: boolean + lastcheckin: + type: string + lastmodified: + type: string + lastpeerupdate: + type: string + localaddress: + $ref: '#/definitions/net.IPNet' + metadata: + type: string + network: + type: string + networkrange: + type: integer + networkrange6: + type: number + ownerid: + type: string + pendingdelete: + type: boolean + relayedby: + type: string + relaynodes: + items: + type: string + type: array + server: + type: string + type: object + models.NodeGet: + properties: + host: + $ref: '#/definitions/models.Host' + host_peers: + items: + $ref: '#/definitions/wgtypes.PeerConfig' + type: array + node: + $ref: '#/definitions/models.Node' + peerids: + $ref: '#/definitions/models.PeerMap' + peers: + items: + $ref: '#/definitions/wgtypes.PeerConfig' + type: array + serverconfig: + $ref: '#/definitions/models.ServerConfig' + type: object + models.PeerMap: + additionalProperties: + $ref: '#/definitions/models.IDandAddr' + type: object + models.RegisterResponse: + properties: + requested_host: + $ref: '#/definitions/models.Host' + server_config: + $ref: '#/definitions/models.ServerConfig' + type: object + models.RelayRequest: + properties: + netid: + type: string + nodeid: + type: string + relayaddrs: + items: + type: string + type: array + type: object + models.ReturnUser: + properties: + isadmin: + type: boolean + issuperadmin: + type: boolean + last_login_time: + type: string + remote_gw_ids: + additionalProperties: + type: object + type: object + username: + type: string + type: object + models.ServerConfig: + properties: + Is_EE: + type: boolean + api: + type: string + apiport: + type: string + broker: + type: string + brokerType: + type: string + coreDNSAddr: + type: string + dnsmode: + type: string + metricInterval: + type: string + mqpassword: + type: string + mqport: + type: string + mquserName: + type: string + server: + type: string + trafficKey: + items: + type: integer + type: array + version: + type: string + type: object + models.Signal: + properties: + action: + $ref: '#/definitions/models.SignalAction' + from_host_id: + type: string + from_host_pubkey: + type: string + from_node_id: + type: string + is_pro: + type: boolean + reply: + type: boolean + server: + type: string + timestamp: + type: integer + to_host_id: + type: string + to_host_pubkey: + type: string + to_node_id: + type: string + type: object + models.SignalAction: + enum: + - CONNECTION_NEGOTIATION + - RELAY_ME + type: string + x-enum-varnames: + - ConnNegotiation + - RelayME + models.SuccessResponse: + properties: + code: + type: integer + message: + type: string + response: {} + type: object + models.User: + properties: + isadmin: + type: boolean + issuperadmin: + type: boolean + last_login_time: + type: string + password: + minLength: 5 + type: string + remote_gw_ids: + additionalProperties: + type: object + type: object + username: + maxLength: 40 + minLength: 3 + type: string + required: + - password + type: object + models.UserAuthParams: + properties: + password: + type: string + username: + type: string + type: object + models.UserRemoteGws: + properties: + allowed_endpoints: + items: + type: string + type: array + connected: + type: boolean + gw_client: + $ref: '#/definitions/models.ExtClient' + gw_listen_port: + type: integer + gw_name: + type: string + gw_peer_public_key: + type: string + is_internet_gateway: + type: boolean + metadata: + type: string + network: + type: string + network_addresses: + items: + type: string + type: array + remote_access_gw_id: + type: string + type: object + net.IPNet: + properties: + ip: + description: network number + items: + type: integer + type: array + mask: + description: network mask + items: + type: integer + type: array + type: object + net.UDPAddr: + properties: + ip: + items: + type: integer + type: array + port: + type: integer + zone: + description: IPv6 scoped addressing zone + type: string + type: object + netip.AddrPort: + type: object + time.Duration: + enum: + - -9223372036854775808 + - 9223372036854775807 + - 1 + - 1000 + - 1000000 + - 1000000000 + - 60000000000 + - 3600000000000 + - -9223372036854775808 + - 9223372036854775807 + - 1 + - 1000 + - 1000000 + - 1000000000 + - 60000000000 + - 3600000000000 + type: integer + x-enum-varnames: + - minDuration + - maxDuration + - Nanosecond + - Microsecond + - Millisecond + - Second + - Minute + - Hour + - minDuration + - maxDuration + - Nanosecond + - Microsecond + - Millisecond + - Second + - Minute + - Hour + wgtypes.PeerConfig: + properties: + allowedIPs: + description: |- + AllowedIPs specifies a list of allowed IP addresses in CIDR notation + for this peer. + items: + $ref: '#/definitions/net.IPNet' + type: array + endpoint: + allOf: + - $ref: '#/definitions/net.UDPAddr' + description: Endpoint specifies the endpoint of this peer entry, if not nil. + persistentKeepaliveInterval: + allOf: + - $ref: '#/definitions/time.Duration' + description: |- + PersistentKeepaliveInterval specifies the persistent keepalive interval + for this peer, if not nil. + + A non-nil value of 0 will clear the persistent keepalive interval. + presharedKey: + description: |- + PresharedKey specifies a peer's preshared key configuration, if not nil. + + A non-nil, zero-value Key will clear the preshared key. + items: + type: integer + type: array + publicKey: + description: |- + PublicKey specifies the public key of this peer. PublicKey is a + mandatory field for all PeerConfigs. + items: + type: integer + type: array + remove: + description: |- + Remove specifies if the peer with this public key should be removed + from a device's peer list. + type: boolean + replaceAllowedIPs: + description: |- + ReplaceAllowedIPs specifies if the allowed IPs specified in this peer + configuration should replace any existing ones, instead of appending them + to the allowed IPs list. + type: boolean + updateOnly: + description: |- + UpdateOnly specifies that an operation will only occur on this peer + if the peer already exists as part of the interface. + type: boolean + type: object +host: api.demo.netmaker.io +info: + contact: {} + description: NetMaker API Docs + title: NetMaker + version: 0.24.3 +paths: + /api/dns: + get: + consumes: + - application/json + responses: + "200": + description: OK + schema: + items: + $ref: '#/definitions/models.DNSEntry' + type: array + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + summary: Get all DNS entries + tags: + - DNS + /api/dns/{network}: + get: + consumes: + - application/json + parameters: + - description: Network identifier + in: path + name: network + required: true + type: string + responses: + "200": + description: OK + schema: + items: + $ref: '#/definitions/models.DNSEntry' + type: array + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + summary: Gets node DNS entries associated with a network + tags: + - DNS + /api/dns/{network}/{domain}: + delete: + consumes: + - application/json + parameters: + - description: Network identifier + in: path + name: network + required: true + type: string + - description: Domain Name + in: path + name: domain + required: true + type: string + responses: + "200": + description: OK + schema: + items: + $ref: '#/definitions/models.DNSEntry' + type: array + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + summary: Delete a DNS entry + tags: + - DNS + /api/dns/adm/{network}: + get: + consumes: + - application/json + parameters: + - description: Network identifier + in: path + name: network + required: true + type: string + responses: + "200": + description: OK + schema: + items: + $ref: '#/definitions/models.DNSEntry' + type: array + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + summary: Get all DNS entries associated with the network + tags: + - DNS + post: + consumes: + - application/json + parameters: + - description: Network identifier + in: path + name: network + required: true + type: string + - description: DNS entry details + in: body + name: body + required: true + schema: + $ref: '#/definitions/models.DNSEntry' + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.DNSEntry' + "400": + description: Bad Request + schema: + $ref: '#/definitions/models.ErrorResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + summary: Create a new DNS entry + tags: + - DNS + /api/dns/adm/{network}/custom: + get: + consumes: + - application/json + parameters: + - description: Network identifier + in: path + name: network + required: true + type: string + responses: + "200": + description: OK + schema: + items: + $ref: '#/definitions/models.DNSEntry' + type: array + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + summary: Gets custom DNS entries associated with a network + tags: + - DNS + /api/dns/adm/pushdns: + post: + consumes: + - application/json + responses: + "200": + description: DNS Pushed to CoreDNS + schema: + type: string + "400": + description: Bad Request + schema: + $ref: '#/definitions/models.ErrorResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + summary: Push DNS entries to nameserver + tags: + - DNS + /api/emqx/hosts: + delete: + responses: + "200": + description: deleted hosts data on emqx + schema: + type: string + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + security: + - oauth: [] + summary: Deletes all EMQX hosts + tags: + - Hosts + /api/extclients: + get: + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.ExtClient' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + security: + - oauth2: [] + summary: Fetches All Remote Access Clients across all networks + tags: + - Remote Access Client + /api/extclients/{network}: + get: + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.ExtClient' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + security: + - oauth2: [] + summary: Get all remote access client associated with network + tags: + - Remote Access Client + /api/extclients/{network}/{clientid}: + delete: + responses: + "200": + description: OK + "403": + description: Forbidden + schema: + $ref: '#/definitions/models.ErrorResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + security: + - oauth2: [] + summary: Delete an individual remote access client + tags: + - Remote Access Client + get: + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.ExtClient' + "403": + description: Forbidden + schema: + $ref: '#/definitions/models.ErrorResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + security: + - oauth2: [] + summary: Get an individual remote access client + tags: + - Remote Access Client + put: + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.ExtClient' + "400": + description: Bad Request + schema: + $ref: '#/definitions/models.ErrorResponse' + "403": + description: Forbidden + schema: + $ref: '#/definitions/models.ErrorResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + security: + - oauth2: [] + summary: Update an individual remote access client + tags: + - Remote Access Client + /api/extclients/{network}/{clientid}/{type}: + get: + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.ExtClient' + "403": + description: Forbidden + schema: + $ref: '#/definitions/models.ErrorResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + security: + - oauth2: [] + summary: Get an individual remote access client + tags: + - Remote Access Client + /api/extclients/{network}/{nodeid}: + post: + responses: + "200": + description: OK + schema: + type: string + "400": + description: Bad Request + schema: + $ref: '#/definitions/models.ErrorResponse' + "403": + description: Forbidden + schema: + $ref: '#/definitions/models.ErrorResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + security: + - oauth2: [] + summary: Create an individual remote access client + tags: + - Remote Access Client + /api/getip: + get: + responses: + "200": + description: The public IP address. + schema: + type: string + "400": + description: Invalid IP address or no IP found. + schema: + type: string + security: + - oauth2: [] + summary: Get the current public IP address. + tags: + - IP Service + /api/hosts: + get: + responses: + "200": + description: OK + schema: + items: + $ref: '#/definitions/models.ApiHost' + type: array + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + security: + - oauth: [] + summary: List all hosts + tags: + - Hosts + /api/hosts/{hostid}: + delete: + parameters: + - description: Host ID + in: path + name: hostid + required: true + type: string + - description: Force delete + in: query + name: force + type: boolean + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.ApiHost' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + security: + - oauth: [] + summary: Deletes a Netclient host from Netmaker server + tags: + - Hosts + put: + parameters: + - description: Host ID + in: path + name: hostid + required: true + type: string + - description: New host data + in: body + name: body + required: true + schema: + $ref: '#/definitions/models.ApiHost' + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.ApiHost' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + security: + - oauth: [] + summary: Updates a Netclient host on Netmaker server + tags: + - Hosts + /api/hosts/{hostid}/keys: + put: + parameters: + - description: Host ID + in: path + name: hostid + required: true + type: string + responses: + "200": + description: OK + schema: + type: string + "400": + description: Bad Request + schema: + $ref: '#/definitions/models.ErrorResponse' + security: + - oauth: [] + summary: Update keys for a host + tags: + - Hosts + /api/hosts/{hostid}/networks/{network}: + delete: + parameters: + - description: Host ID + in: path + name: hostid + required: true + type: string + - description: Network name + in: path + name: network + required: true + type: string + - description: Force delete + in: query + name: force + type: boolean + responses: + "200": + description: OK + schema: + type: string + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + security: + - oauth: [] + summary: To Remove Host from Network + tags: + - Hosts + post: + parameters: + - description: Host ID + in: path + name: hostid + required: true + type: string + - description: Network name + in: path + name: network + required: true + type: string + responses: + "200": + description: OK + schema: + type: string + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + security: + - oauth: [] + summary: To Add Host To Network + tags: + - Hosts + /api/hosts/{hostid}/sync: + post: + parameters: + - description: Host ID + in: path + name: hostid + required: true + type: string + responses: + "200": + description: OK + schema: + type: string + "400": + description: Bad Request + schema: + $ref: '#/definitions/models.ErrorResponse' + security: + - oauth: [] + summary: Requests a host to pull + tags: + - Hosts + /api/hosts/{hostid}/upgrade: + put: + parameters: + - description: Host ID + in: path + name: hostid + required: true + type: string + responses: + "200": + description: passed message to upgrade host + schema: + type: string + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + security: + - oauth: [] + summary: Upgrade a host + tags: + - Hosts + /api/hosts/adm/authenticate: + post: + consumes: + - application/json + parameters: + - description: Authentication parameters + in: body + name: body + required: true + schema: + $ref: '#/definitions/models.AuthParams' + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.SuccessResponse' + "400": + description: Bad Request + schema: + $ref: '#/definitions/models.ErrorResponse' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/models.ErrorResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + summary: To Fetch Auth Token for a Host + tags: + - Auth + /api/hosts/keys: + put: + responses: + "200": + description: OK + schema: + type: string + "400": + description: Bad Request + schema: + $ref: '#/definitions/models.ErrorResponse' + security: + - oauth: [] + summary: Update keys for all hosts + tags: + - Hosts + /api/networks: + get: + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.Network' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + security: + - oauth: [] + summary: Lists all networks + tags: + - Networks + post: + parameters: + - description: Network details + in: body + name: body + required: true + schema: + $ref: '#/definitions/models.Network' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.Network' + "400": + description: Bad Request + schema: + $ref: '#/definitions/models.ErrorResponse' + security: + - oauth: [] + summary: Create a network + tags: + - Networks + /api/networks/{networkname}: + delete: + parameters: + - description: Network name + in: path + name: networkname + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.SuccessResponse' + "400": + description: Bad Request + schema: + $ref: '#/definitions/models.ErrorResponse' + "403": + description: Forbidden + schema: + $ref: '#/definitions/models.ErrorResponse' + security: + - oauth: [] + summary: Delete a network + tags: + - Networks + get: + parameters: + - description: Network name + in: path + name: networkname + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.Network' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + security: + - oauth: [] + summary: Get a network + tags: + - Networks + put: + parameters: + - description: Network name + in: path + name: networkname + required: true + type: string + - description: Network details + in: body + name: body + required: true + schema: + $ref: '#/definitions/models.Network' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.Network' + "400": + description: Bad Request + schema: + $ref: '#/definitions/models.ErrorResponse' + security: + - oauth: [] + summary: Update network settings + tags: + - Networks + /api/networks/{networkname}/acls: + get: + parameters: + - description: Network name + in: path + name: networkname + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/acls.ACLContainer' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + security: + - oauth: [] + summary: Get a network ACL (Access Control List) + tags: + - Networks + put: + parameters: + - description: Network name + in: path + name: networkname + required: true + type: string + - description: ACL container + in: body + name: body + required: true + schema: + $ref: '#/definitions/acls.ACLContainer' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/acls.ACLContainer' + "400": + description: Bad Request + schema: + $ref: '#/definitions/models.ErrorResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + security: + - oauth: [] + summary: Update a network ACL (Access Control List) + tags: + - Networks + /api/networks/{networkname}/acls/v2: + put: + parameters: + - description: Network name + in: path + name: networkname + required: true + type: string + - description: ACL container + in: body + name: body + required: true + schema: + $ref: '#/definitions/acls.ACLContainer' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/acls.ACLContainer' + "400": + description: Bad Request + schema: + $ref: '#/definitions/models.ErrorResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + security: + - oauth: [] + summary: Update a network ACL (Access Control List) + tags: + - Networks + /api/nodes: + get: + responses: + "200": + description: OK + schema: + items: + $ref: '#/definitions/models.ApiNode' + type: array + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + summary: Get all nodes across all networks + tags: + - Nodes + /api/nodes/{network}/{nodeid}: + delete: + responses: + "200": + description: Node deleted. + schema: + type: string + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + security: + - oauth2: [] + summary: Delete an individual node + tags: + - Nodes + get: + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.NodeGet' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + security: + - oauth2: [] + summary: Get an individual node + tags: + - Nodes + put: + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.ApiNode' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + security: + - oauth2: [] + summary: Update an individual node + tags: + - Nodes + /api/nodes/{network}/{nodeid}/creategateway: + post: + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.ApiNode' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + security: + - oauth2: [] + summary: Create an egress gateway + tags: + - Nodes + /api/nodes/{network}/{nodeid}/createingress: + post: + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.ApiNode' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + security: + - oauth2: [] + summary: Create an remote access gateway + tags: + - Nodes + /api/nodes/{network}/{nodeid}/createrelay: + post: + consumes: + - application/json + parameters: + - description: Network ID + in: path + name: network + required: true + type: string + - description: Node ID + in: path + name: nodeid + required: true + type: string + - description: Relay request parameters + in: body + name: body + required: true + schema: + $ref: '#/definitions/models.RelayRequest' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.ApiNode' + "400": + description: Bad Request + schema: + $ref: '#/definitions/models.ErrorResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + summary: Create a relay + tags: + - PRO + /api/nodes/{network}/{nodeid}/deletegateway: + delete: + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.ApiNode' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + security: + - oauth2: [] + summary: Delete an egress gateway + tags: + - Nodes + /api/nodes/{network}/{nodeid}/deleteingress: + delete: + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.ApiNode' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + security: + - oauth2: [] + summary: Delete an remote access gateway + tags: + - Nodes + /api/nodes/{network}/{nodeid}/deleterelay: + delete: + consumes: + - application/json + parameters: + - description: Network ID + in: path + name: network + required: true + type: string + - description: Node ID + in: path + name: nodeid + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.ApiNode' + "400": + description: Bad Request + schema: + $ref: '#/definitions/models.ErrorResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + summary: Remove a relay + tags: + - PRO + /api/nodes/{network}/{nodeid}/inet_gw: + delete: + parameters: + - description: Network ID + in: path + name: network + required: true + type: string + - description: Node ID + in: path + name: nodeid + required: true + type: string + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.Node' + "400": + description: Bad Request + schema: + $ref: '#/definitions/models.ErrorResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + summary: Delete an internet gateway + tags: + - PRO + post: + consumes: + - application/json + parameters: + - description: Network ID + in: path + name: network + required: true + type: string + - description: Node ID + in: path + name: nodeid + required: true + type: string + - description: Internet gateway request + in: body + name: body + required: true + schema: + $ref: '#/definitions/models.InetNodeReq' + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.Node' + "400": + description: Bad Request + schema: + $ref: '#/definitions/models.ErrorResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + summary: Create an internet gateway + tags: + - PRO + put: + consumes: + - application/json + parameters: + - description: Network ID + in: path + name: network + required: true + type: string + - description: Node ID + in: path + name: nodeid + required: true + type: string + - description: Internet gateway request + in: body + name: body + required: true + schema: + $ref: '#/definitions/models.InetNodeReq' + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.Node' + "400": + description: Bad Request + schema: + $ref: '#/definitions/models.ErrorResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + summary: Update an internet gateway + tags: + - PRO + /api/nodes/{network}/{nodeid}/ingress/users: + get: + consumes: + - application/json + parameters: + - description: Ingress Gateway ID + in: path + name: ingress_id + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + items: + $ref: '#/definitions/models.IngressGwUsers' + type: array + "400": + description: Bad Request + schema: + $ref: '#/definitions/models.ErrorResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + summary: List users attached to an ingress gateway + tags: + - PRO + /api/nodes/adm/{network}: + get: + responses: + "200": + description: OK + schema: + items: + $ref: '#/definitions/models.Node' + type: array + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + summary: Gets all nodes associated with network including pending nodes + tags: + - Nodes + /api/server/getconfig: + get: + responses: + "200": + description: OK + schema: + $ref: '#/definitions/config.ServerConfig' + security: + - oauth2: [] + summary: Get the server configuration + tags: + - Server + /api/server/getserverinfo: + get: + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.ServerConfig' + security: + - oauth2: [] + summary: Get the server information + tags: + - Server + /api/server/status: + get: + responses: {} + security: + - oauth2: [] + summary: Get the server status + tags: + - Server + /api/users: + get: + responses: + "200": + description: OK + schema: + items: + $ref: '#/definitions/models.User' + type: array + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + summary: Get all users + tags: + - Users + /api/users/{username}: + delete: + parameters: + - description: Username of the user to delete + in: path + name: username + required: true + type: string + responses: + "200": + description: OK + schema: + type: string + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + summary: Delete a user + tags: + - Users + get: + parameters: + - description: Username of the user to fetch + in: path + name: username + required: true + type: string + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.User' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + summary: Get an individual user + tags: + - Users + post: + parameters: + - description: Username of the user to create + in: path + name: username + required: true + type: string + - description: User details + in: body + name: body + required: true + schema: + $ref: '#/definitions/models.User' + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.User' + "400": + description: Bad Request + schema: + $ref: '#/definitions/models.ErrorResponse' + "403": + description: Forbidden + schema: + $ref: '#/definitions/models.ErrorResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + summary: Create a user + tags: + - Users + put: + parameters: + - description: Username of the user to update + in: path + name: username + required: true + type: string + - description: User details + in: body + name: body + required: true + schema: + $ref: '#/definitions/models.User' + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.User' + "400": + description: Bad Request + schema: + $ref: '#/definitions/models.ErrorResponse' + "403": + description: Forbidden + schema: + $ref: '#/definitions/models.ErrorResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + summary: Update a user + tags: + - Users + /api/users/{username}/remote_access_gw: + get: + consumes: + - application/json + parameters: + - description: Username + in: path + name: username + required: true + type: string + - description: Remote Access Client ID + in: query + name: remote_access_clientid + type: string + - description: Request from mobile + in: query + name: from_mobile + type: boolean + produces: + - application/json + responses: + "200": + description: OK + schema: + items: + $ref: '#/definitions/models.UserRemoteGws' + type: array + "400": + description: Bad Request + schema: + $ref: '#/definitions/models.ErrorResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + summary: Get user's remote access gateways + tags: + - PRO + /api/users/{username}/remote_access_gw/{remote_access_gateway_id}: + delete: + consumes: + - application/json + parameters: + - description: Username + in: path + name: username + required: true + type: string + - description: Remote Access Gateway ID + in: path + name: remote_access_gateway_id + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.ReturnUser' + "400": + description: Bad Request + schema: + $ref: '#/definitions/models.ErrorResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + summary: Remove user from a remote access gateway + tags: + - PRO + post: + consumes: + - application/json + parameters: + - description: Username + in: path + name: username + required: true + type: string + - description: Remote Access Gateway ID + in: path + name: remote_access_gateway_id + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.ReturnUser' + "400": + description: Bad Request + schema: + $ref: '#/definitions/models.ErrorResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + summary: Attach user to a remote access gateway + tags: + - PRO + /api/users/adm/authenticate: + post: + consumes: + - application/json + parameters: + - description: Authentication parameters + in: body + name: body + required: true + schema: + $ref: '#/definitions/models.UserAuthParams' + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.SuccessResponse' + "400": + description: Bad Request + schema: + $ref: '#/definitions/models.ErrorResponse' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/models.ErrorResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + summary: Authenticate a user to retrieve an authorization token + tags: + - Auth + /api/users/adm/createsuperadmin: + post: + parameters: + - description: User details + in: body + name: body + required: true + schema: + $ref: '#/definitions/models.User' + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.User' + "400": + description: Bad Request + schema: + $ref: '#/definitions/models.ErrorResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + summary: Create a super admin + tags: + - Users + /api/users/adm/hassuperadmin: + get: + responses: + "200": + description: OK + schema: + type: boolean + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + summary: Check if the server has a super admin + tags: + - Users + /api/users/adm/transfersuperadmin/{username}: + post: + parameters: + - description: Username of the user to transfer super admin role + in: path + name: username + required: true + type: string + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.User' + "403": + description: Forbidden + schema: + $ref: '#/definitions/models.ErrorResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + summary: Transfer super admin role to another admin user + tags: + - Users + /api/users_pending: + delete: + responses: + "200": + description: OK + schema: + type: string + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + summary: Delete all pending users + tags: + - Users + get: + responses: + "200": + description: OK + schema: + items: + $ref: '#/definitions/models.User' + type: array + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + summary: Get all pending users + tags: + - Users + /api/users_pending/user/{username}: + delete: + parameters: + - description: Username of the pending user to delete + in: path + name: username + required: true + type: string + responses: + "200": + description: OK + schema: + type: string + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + summary: Delete a pending user + tags: + - Users + post: + parameters: + - description: Username of the pending user to approve + in: path + name: username + required: true + type: string + responses: + "200": + description: OK + schema: + type: string + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + summary: Approve a pending user + tags: + - Users + /api/v1/enrollment-keys: + get: + responses: + "200": + description: OK + schema: + items: + $ref: '#/definitions/models.EnrollmentKey' + type: array + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + security: + - oauth: [] + summary: Lists all EnrollmentKeys for admins + tags: + - EnrollmentKeys + post: + parameters: + - description: Enrollment Key parameters + in: body + name: body + required: true + schema: + $ref: '#/definitions/models.APIEnrollmentKey' + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.EnrollmentKey' + "400": + description: Bad Request + schema: + $ref: '#/definitions/models.ErrorResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + security: + - oauth: [] + summary: Creates an EnrollmentKey for hosts to register with server and join + networks + tags: + - EnrollmentKeys + /api/v1/enrollment-keys/{keyid}: + delete: + parameters: + - description: Enrollment Key ID + in: path + name: keyid + required: true + type: string + responses: + "200": + description: OK + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + security: + - oauth: [] + summary: Deletes an EnrollmentKey from Netmaker server + tags: + - EnrollmentKeys + put: + parameters: + - description: Enrollment Key ID + in: path + name: keyid + required: true + type: string + - description: Enrollment Key parameters + in: body + name: body + required: true + schema: + $ref: '#/definitions/models.APIEnrollmentKey' + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.EnrollmentKey' + "400": + description: Bad Request + schema: + $ref: '#/definitions/models.ErrorResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + security: + - oauth: [] + summary: Updates an EnrollmentKey. Updates are only limited to the relay to + use + tags: + - EnrollmentKeys + /api/v1/fallback/host/{hostid}: + put: + parameters: + - description: Host ID + in: path + name: hostid + required: true + type: string + - description: Host update data + in: body + name: body + required: true + schema: + $ref: '#/definitions/models.HostUpdate' + responses: + "200": + description: updated host data + schema: + type: string + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + security: + - oauth: [] + summary: Updates a Netclient host on Netmaker server + tags: + - Hosts + /api/v1/host: + get: + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.HostPull' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + security: + - oauth: [] + summary: Used by clients for "pull" command + tags: + - Hosts + /api/v1/host/{hostid}/signalpeer: + post: + parameters: + - description: Host ID + in: path + name: hostid + required: true + type: string + - description: Signal data + in: body + name: body + required: true + schema: + $ref: '#/definitions/models.Signal' + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.Signal' + "400": + description: Bad Request + schema: + $ref: '#/definitions/models.ErrorResponse' + security: + - oauth: [] + summary: Send signal to peer + tags: + - Hosts + /api/v1/host/register/{token}: + post: + parameters: + - description: Enrollment Key Token + in: path + name: token + required: true + type: string + - description: Host registration parameters + in: body + name: body + required: true + schema: + $ref: '#/definitions/models.Host' + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.RegisterResponse' + "400": + description: Bad Request + schema: + $ref: '#/definitions/models.ErrorResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + security: + - oauth: [] + summary: Handles a Netclient registration with server and add nodes accordingly + tags: + - EnrollmentKeys + /api/v1/legacy/nodes: + delete: + responses: + "200": + description: Wiped all legacy nodes. + schema: + type: string + "400": + description: Bad Request + schema: + $ref: '#/definitions/models.ErrorResponse' + security: + - oauth2: [] + summary: Delete all legacy nodes from DB. + tags: + - Nodes + /api/v1/node/{network}/failover/reset: + post: + parameters: + - description: Network ID + in: path + name: network + required: true + type: string + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.SuccessResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + summary: Reset failover for a network + tags: + - PRO + /api/v1/node/{nodeid}/failover: + delete: + parameters: + - description: Node ID + in: path + name: nodeid + required: true + type: string + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.Node' + "400": + description: Bad Request + schema: + $ref: '#/definitions/models.ErrorResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + summary: Delete failover node + tags: + - PRO + get: + parameters: + - description: Node ID + in: path + name: nodeid + required: true + type: string + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.Node' + "400": + description: Bad Request + schema: + $ref: '#/definitions/models.ErrorResponse' + "404": + description: Not Found + schema: + $ref: '#/definitions/models.ErrorResponse' + summary: Get failover node + tags: + - PRO + post: + parameters: + - description: Node ID + in: path + name: nodeid + required: true + type: string + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.Node' + "400": + description: Bad Request + schema: + $ref: '#/definitions/models.ErrorResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + summary: Create failover node + tags: + - PRO + /api/v1/node/{nodeid}/failover_me: + post: + consumes: + - application/json + parameters: + - description: Node ID + in: path + name: nodeid + required: true + type: string + - description: Failover request + in: body + name: body + required: true + schema: + $ref: '#/definitions/models.FailOverMeReq' + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.SuccessResponse' + "400": + description: Bad Request + schema: + $ref: '#/definitions/models.ErrorResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/models.ErrorResponse' + summary: Failover me + tags: + - PRO + /meshclient/files/{filename}: + get: + responses: + "200": + description: file + schema: + type: body + "404": + description: 404 not found + schema: + type: string + summary: Retrieve a file from the file server + tags: + - Meshclient +swagger: "2.0" +tags: +- description: | + Most actions that can be performed via API can be performed via UI. We recommend managing your networks using the official netmaker-ui project. However, Netmaker can also be run without the UI, and all functions can be achieved via API calls. If your use case requires using Netmaker without the UI or you need to do some troubleshooting/advanced configuration, using the API directly may help. + name: APIUsage +- description: | + API calls are primarily authenticated using a user authentication token. This token should be included in the header as follows: + + -H "Authorization: Bearer " + + To obtain YOUR_AUTH_TOKEN: + Call the api/users/adm/authenticate endpoint (see documentation below for details). + + Note: While a MasterKey exists (configurable via env var or config file), it should be considered a backup option, used only when server access is lost. By default, this key is "secret key," but it's crucial to change this and keep it secure in your instance. + + For more information on configuration and security best practices, refer to the [Netmaker documentation](https://docs.netmaker.org/index.html). + name: Authentication +- description: | + Check out our [Pricing](https://www.netmaker.io/pricing). And Feel Free to [Contact Us](https://www.netmaker.io/contact) if you have any questions or need some clarifications. + name: Pricing diff --git a/swagger.yml b/swagger.yml deleted file mode 100644 index a0418b17..00000000 --- a/swagger.yml +++ /dev/null @@ -1,3006 +0,0 @@ -basePath: / -consumes: - - application/json -definitions: - ACL: - additionalProperties: - format: uint8 - type: integer - description: ACL - the ACL of other nodes in a NetworkACL for a single unique node - type: object - x-go-package: github.com/gravitl/netmaker/logic/acls - ACLContainer: - additionalProperties: - $ref: '#/definitions/ACL' - description: ACLContainer - the total list of all node's ACL in a given network - type: object - x-go-package: github.com/gravitl/netmaker/logic/acls - APIEnrollmentKey: - description: APIEnrollmentKey - used to create enrollment keys via API - properties: - expiration: - format: int64 - type: integer - x-go-name: Expiration - networks: - items: - type: string - type: array - x-go-name: Networks - relay: - type: string - x-go-name: Relay - tags: - items: - type: string - type: array - x-go-name: Tags - type: - $ref: '#/definitions/KeyType' - unlimited: - type: boolean - x-go-name: Unlimited - uses_remaining: - format: int64 - type: integer - x-go-name: UsesRemaining - type: object - x-go-package: github.com/gravitl/netmaker/models - ApiHost: - description: ApiHost - the host struct for API usage - properties: - autoupdate: - type: boolean - x-go-name: AutoUpdate - debug: - type: boolean - x-go-name: Debug - defaultinterface: - type: string - x-go-name: DefaultInterface - endpointip: - type: string - x-go-name: EndpointIP - endpointipv6: - type: string - x-go-name: EndpointIPv6 - firewallinuse: - type: string - x-go-name: FirewallInUse - id: - type: string - x-go-name: ID - interfaces: - items: - $ref: '#/definitions/ApiIface' - type: array - x-go-name: Interfaces - isdefault: - type: boolean - x-go-name: IsDefault - isstatic: - type: boolean - x-go-name: IsStatic - listenport: - format: int64 - type: integer - x-go-name: ListenPort - macaddress: - type: string - x-go-name: MacAddress - mtu: - format: int64 - type: integer - x-go-name: MTU - name: - type: string - x-go-name: Name - nat_type: - type: string - x-go-name: NatType - nodes: - items: - type: string - type: array - x-go-name: Nodes - os: - type: string - x-go-name: OS - persistentkeepalive: - format: int64 - type: integer - x-go-name: PersistentKeepalive - publickey: - type: string - x-go-name: PublicKey - verbosity: - format: int64 - type: integer - x-go-name: Verbosity - version: - type: string - x-go-name: Version - wg_public_listen_port: - format: int64 - type: integer - x-go-name: WgPublicListenPort - type: object - x-go-package: github.com/gravitl/netmaker/models - ApiIface: - description: |- - ApiIface - the interface struct for API usage - The original Iface struct contains a net.Address, which does not get marshalled correctly - properties: - addressString: - type: string - x-go-name: AddressString - name: - type: string - x-go-name: Name - type: object - x-go-package: github.com/gravitl/netmaker/models - ApiNode: - description: ApiNode is a stripped down Node DTO that exposes only required fields to external systems - properties: - address: - type: string - x-go-name: Address - address6: - type: string - x-go-name: Address6 - allowedips: - items: - type: string - type: array - x-go-name: AllowedIPs - connected: - type: boolean - x-go-name: Connected - defaultacl: - description: == PRO == - type: string - x-go-name: DefaultACL - dnson: - type: boolean - x-go-name: DNSOn - egressgatewaynatenabled: - type: boolean - x-go-name: EgressGatewayNatEnabled - egressgatewayranges: - items: - type: string - type: array - x-go-name: EgressGatewayRanges - expdatetime: - format: int64 - type: integer - x-go-name: ExpirationDateTime - fail_over_peers: - additionalProperties: - type: object - type: object - x-go-name: FailOverPeers - failed_over_by: - format: uuid - type: string - x-go-name: FailedOverBy - hostid: - type: string - x-go-name: HostID - id: - type: string - x-go-name: ID - inet_node_req: - $ref: '#/definitions/InetNodeReq' - ingressdns: - type: string - x-go-name: IngressDns - internetgw_node_id: - type: string - x-go-name: InternetGwID - is_fail_over: - type: boolean - x-go-name: IsFailOver - isegressgateway: - type: boolean - x-go-name: IsEgressGateway - isingressgateway: - type: boolean - x-go-name: IsIngressGateway - isinternetgateway: - type: boolean - x-go-name: IsInternetGateway - isrelay: - type: boolean - x-go-name: IsRelay - isrelayed: - type: boolean - x-go-name: IsRelayed - lastcheckin: - format: int64 - type: integer - x-go-name: LastCheckIn - lastmodified: - format: int64 - type: integer - x-go-name: LastModified - lastpeerupdate: - format: int64 - type: integer - x-go-name: LastPeerUpdate - localaddress: - type: string - x-go-name: LocalAddress - metadata: - type: string - x-go-name: Metadata - network: - type: string - x-go-name: Network - networkrange: - type: string - x-go-name: NetworkRange - networkrange6: - type: string - x-go-name: NetworkRange6 - pendingdelete: - type: boolean - x-go-name: PendingDelete - relayedby: - type: string - x-go-name: RelayedBy - relaynodes: - items: - type: string - type: array - x-go-name: RelayedNodes - server: - type: string - x-go-name: Server - type: object - x-go-package: github.com/gravitl/netmaker/models - AuthParams: - description: AuthParams - struct for auth params - properties: - id: - type: string - x-go-name: ID - macaddress: - type: string - x-go-name: MacAddress - password: - type: string - x-go-name: Password - type: object - x-go-package: github.com/gravitl/netmaker/models - CustomExtClient: - description: CustomExtClient - struct for CustomExtClient params - properties: - clientid: - type: string - x-go-name: ClientID - deniednodeacls: - additionalProperties: - type: object - type: object - x-go-name: DeniedACLs - dns: - type: string - x-go-name: DNS - enabled: - type: boolean - x-go-name: Enabled - extraallowedips: - items: - type: string - type: array - x-go-name: ExtraAllowedIPs - postdown: - type: string - x-go-name: PostDown - postup: - type: string - x-go-name: PostUp - publickey: - type: string - x-go-name: PublicKey - remote_access_client_id: - type: string - x-go-name: RemoteAccessClientID - type: object - x-go-package: github.com/gravitl/netmaker/models - DNSEntry: - description: DNSEntry - a DNS entry represented as struct - properties: - address: - type: string - x-go-name: Address - address6: - type: string - x-go-name: Address6 - name: - type: string - x-go-name: Name - network: - type: string - x-go-name: Network - type: object - x-go-package: github.com/gravitl/netmaker/models - Duration: - description: |- - A Duration represents the elapsed time between two instants - as an int64 nanosecond count. The representation limits the - largest representable duration to approximately 290 years. - format: int64 - type: integer - x-go-package: time - EgressGatewayRequest: - description: EgressGatewayRequest - egress gateway request - properties: - natenabled: - type: string - x-go-name: NatEnabled - netid: - type: string - x-go-name: NetID - nodeid: - type: string - x-go-name: NodeID - ranges: - items: - type: string - type: array - x-go-name: Ranges - type: object - x-go-package: github.com/gravitl/netmaker/models - EgressInfo: - description: EgressInfo - struct for egress info - properties: - egress_gateway_cfg: - $ref: '#/definitions/EgressGatewayRequest' - egress_gw_addr: - $ref: '#/definitions/IPNet' - egress_id: - type: string - x-go-name: EgressID - network: - $ref: '#/definitions/IPNet' - type: object - x-go-package: github.com/gravitl/netmaker/models - EgressNetworkRoutes: - description: EgressNetworkRoutes - struct for egress network routes for adding routes to peer's interface - properties: - egress_ranges: - items: - type: string - type: array - x-go-name: EgressRanges - node_addr: - $ref: '#/definitions/IPNet' - node_addr6: - $ref: '#/definitions/IPNet' - type: object - x-go-package: github.com/gravitl/netmaker/models - EnrollmentKey: - description: EnrollmentKey - the key used to register hosts and join them to specific networks - properties: - expiration: - format: date-time - type: string - x-go-name: Expiration - networks: - items: - type: string - type: array - x-go-name: Networks - relay: - format: uuid - type: string - x-go-name: Relay - tags: - items: - type: string - type: array - x-go-name: Tags - token: - type: string - x-go-name: Token - type: - $ref: '#/definitions/KeyType' - unlimited: - type: boolean - x-go-name: Unlimited - uses_remaining: - format: int64 - type: integer - x-go-name: UsesRemaining - value: - type: string - x-go-name: Value - type: object - x-go-package: github.com/gravitl/netmaker/models - ExtClient: - description: ExtClient - struct for external clients - properties: - address: - type: string - x-go-name: Address - address6: - type: string - x-go-name: Address6 - allowed_ips: - items: - type: string - type: array - x-go-name: AllowedIPs - clientid: - type: string - x-go-name: ClientID - deniednodeacls: - additionalProperties: - type: object - type: object - x-go-name: DeniedACLs - dns: - type: string - x-go-name: DNS - enabled: - type: boolean - x-go-name: Enabled - extraallowedips: - items: - type: string - type: array - x-go-name: ExtraAllowedIPs - ingressgatewayendpoint: - type: string - x-go-name: IngressGatewayEndpoint - ingressgatewayid: - type: string - x-go-name: IngressGatewayID - lastmodified: - format: int64 - type: integer - x-go-name: LastModified - network: - type: string - x-go-name: Network - ownerid: - type: string - x-go-name: OwnerID - postdown: - type: string - x-go-name: PostDown - postup: - type: string - x-go-name: PostUp - privatekey: - type: string - x-go-name: PrivateKey - publickey: - type: string - x-go-name: PublicKey - remote_access_client_id: - type: string - x-go-name: RemoteAccessClientID - type: object - x-go-package: github.com/gravitl/netmaker/models - File: - title: File represents an open file descriptor. - type: object - x-go-package: os - FwUpdate: - description: FwUpdate - struct for firewall updates - properties: - egress_info: - additionalProperties: - $ref: '#/definitions/EgressInfo' - type: object - x-go-name: EgressInfo - is_egress_gw: - type: boolean - x-go-name: IsEgressGw - type: object - x-go-package: github.com/gravitl/netmaker/models - HardwareAddr: - items: - format: uint8 - type: integer - title: A HardwareAddr represents a physical hardware address. - type: array - x-go-package: net - Host: - description: Host - represents a host on the network - properties: - autoupdate: - type: boolean - x-go-name: AutoUpdate - daemoninstalled: - type: boolean - x-go-name: DaemonInstalled - debug: - type: boolean - x-go-name: Debug - defaultinterface: - type: string - x-go-name: DefaultInterface - endpointip: - type: string - x-go-name: EndpointIP - endpointipv6: - type: string - x-go-name: EndpointIPv6 - firewallinuse: - type: string - x-go-name: FirewallInUse - hostpass: - type: string - x-go-name: HostPass - id: - format: uuid - type: string - x-go-name: ID - interface: - type: string - x-go-name: Interface - interfaces: - items: - $ref: '#/definitions/Iface' - type: array - x-go-name: Interfaces - ipforwarding: - type: boolean - x-go-name: IPForwarding - isdefault: - type: boolean - x-go-name: IsDefault - isdocker: - type: boolean - x-go-name: IsDocker - isk8s: - type: boolean - x-go-name: IsK8S - isstatic: - type: boolean - x-go-name: IsStatic - listenport: - format: int64 - type: integer - x-go-name: ListenPort - macaddress: - $ref: '#/definitions/HardwareAddr' - mtu: - format: int64 - type: integer - x-go-name: MTU - name: - type: string - x-go-name: Name - nat_type: - type: string - x-go-name: NatType - nodes: - items: - type: string - type: array - x-go-name: Nodes - os: - type: string - x-go-name: OS - persistentkeepalive: - $ref: '#/definitions/Duration' - publickey: - $ref: '#/definitions/Key' - traffickeypublic: - items: - format: uint8 - type: integer - type: array - x-go-name: TrafficKeyPublic - turn_endpoint: - type: string - x-go-name: TurnEndpoint - verbosity: - format: int64 - type: integer - x-go-name: Verbosity - version: - type: string - x-go-name: Version - wg_public_listen_port: - format: int64 - type: integer - x-go-name: WgPublicListenPort - type: object - x-go-package: github.com/gravitl/netmaker/models - HostInfoMap: - additionalProperties: - $ref: '#/definitions/HostNetworkInfo' - description: HostInfoMap - map of host public keys to host networking info - type: object - x-go-package: github.com/gravitl/netmaker/models - HostNetworkInfo: - description: HostNetworkInfo - holds info related to host networking (used for client side peer calculations) - properties: - interfaces: - items: - $ref: '#/definitions/Iface' - type: array - x-go-name: Interfaces - is_static: - type: boolean - x-go-name: IsStatic - listen_port: - format: int64 - type: integer - x-go-name: ListenPort - type: object - x-go-package: github.com/gravitl/netmaker/models - HostPull: - description: HostPull - response of a host's pull - properties: - change_default_gw: - type: boolean - x-go-name: ChangeDefaultGw - default_gw_ip: - type: string - x-go-name: DefaultGwIp - egress_network_routes: - items: - $ref: '#/definitions/EgressNetworkRoutes' - type: array - x-go-name: EgressRoutes - endpoint_detection: - type: boolean - x-go-name: EndpointDetection - fw_update: - $ref: '#/definitions/FwUpdate' - host: - $ref: '#/definitions/Host' - host_network_info: - $ref: '#/definitions/HostInfoMap' - is_inet_gw: - type: boolean - x-go-name: IsInternetGw - nodes: - items: - $ref: '#/definitions/Node' - type: array - x-go-name: Nodes - peer_ids: - $ref: '#/definitions/PeerMap' - peers: - items: - $ref: '#/definitions/PeerConfig' - type: array - x-go-name: Peers - server_config: - $ref: '#/definitions/ServerConfig' - type: object - x-go-package: github.com/gravitl/netmaker/models - IDandAddr: - description: IDandAddr - struct to hold ID and primary Address - properties: - address: - type: string - x-go-name: Address - host_id: - type: string - x-go-name: HostID - id: - type: string - x-go-name: ID - is_extclient: - type: boolean - x-go-name: IsExtClient - isserver: - type: string - x-go-name: IsServer - listen_port: - format: int64 - type: integer - x-go-name: ListenPort - name: - type: string - x-go-name: Name - network: - type: string - x-go-name: Network - type: object - x-go-package: github.com/gravitl/netmaker/models - IPMask: - description: See type IPNet and func ParseCIDR for details. - items: - format: uint8 - type: integer - title: |- - An IPMask is a bitmask that can be used to manipulate - IP addresses for IP addressing and routing. - type: array - x-go-package: net - IPNet: - properties: - IP: - type: string - Mask: - $ref: '#/definitions/IPMask' - title: An IPNet represents an IP network. - type: object - x-go-package: net - Iface: - description: Iface struct for local interfaces of a node - properties: - address: - $ref: '#/definitions/IPNet' - addressString: - type: string - x-go-name: AddressString - name: - type: string - x-go-name: Name - type: object - x-go-package: github.com/gravitl/netmaker/models - InetNodeReq: - description: InetNodeReq - exit node request struct - properties: - inet_node_client_ids: - items: - type: string - type: array - x-go-name: InetNodeClientIDs - type: object - x-go-package: github.com/gravitl/netmaker/models - Key: - description: |- - A Key is a public, private, or pre-shared secret key. The Key constructor - functions in this package can be used to create Keys suitable for each of - these applications. - items: - format: uint8 - type: integer - type: array - x-go-package: golang.zx2c4.com/wireguard/wgctrl/wgtypes - KeyType: - description: KeyType - the type of enrollment key - format: int64 - type: integer - x-go-package: github.com/gravitl/netmaker/models - LegacyNode: - description: LegacyNode - legacy struct for node model - properties: - accesskey: - type: string - x-go-name: AccessKey - action: - type: string - x-go-name: Action - address: - type: string - x-go-name: Address - address6: - type: string - x-go-name: Address6 - allowedips: - items: - type: string - type: array - x-go-name: AllowedIPs - connected: - type: string - x-go-name: Connected - defaultacl: - description: == PRO == - type: string - x-go-name: DefaultACL - dnson: - type: string - x-go-name: DNSOn - egressgatewaynatenabled: - type: string - x-go-name: EgressGatewayNatEnabled - egressgatewayranges: - items: - type: string - type: array - x-go-name: EgressGatewayRanges - egressgatewayrequest: - $ref: '#/definitions/EgressGatewayRequest' - endpoint: - type: string - x-go-name: Endpoint - expdatetime: - format: int64 - type: integer - x-go-name: ExpirationDateTime - failover: - type: string - x-go-name: Failover - failovernode: - type: string - x-go-name: FailoverNode - firewallinuse: - type: string - x-go-name: FirewallInUse - id: - type: string - x-go-name: ID - ingressgatewayrange: - type: string - x-go-name: IngressGatewayRange - ingressgatewayrange6: - type: string - x-go-name: IngressGatewayRange6 - interface: - type: string - x-go-name: Interface - interfaces: - items: - $ref: '#/definitions/Iface' - type: array - x-go-name: Interfaces - internetgateway: - type: string - x-go-name: InternetGateway - ipforwarding: - type: string - x-go-name: IPForwarding - isdocker: - type: string - x-go-name: IsDocker - isegressgateway: - type: string - x-go-name: IsEgressGateway - ishub: - type: string - x-go-name: IsHub - isingressgateway: - type: string - x-go-name: IsIngressGateway - isk8s: - type: string - x-go-name: IsK8S - ispending: - type: string - x-go-name: IsPending - isrelay: - type: string - x-go-name: IsRelay - isrelayed: - type: string - x-go-name: IsRelayed - isserver: - type: string - x-go-name: IsServer - isstatic: - description: IsStatic - refers to if the Endpoint is set manually or dynamically - type: string - x-go-name: IsStatic - lastcheckin: - format: int64 - type: integer - x-go-name: LastCheckIn - lastmodified: - format: int64 - type: integer - x-go-name: LastModified - lastpeerupdate: - format: int64 - type: integer - x-go-name: LastPeerUpdate - listenport: - format: int32 - type: integer - x-go-name: ListenPort - localaddress: - type: string - x-go-name: LocalAddress - locallistenport: - format: int32 - type: integer - x-go-name: LocalListenPort - macaddress: - type: string - x-go-name: MacAddress - mtu: - format: int32 - type: integer - x-go-name: MTU - name: - type: string - x-go-name: Name - network: - type: string - x-go-name: Network - networksettings: - $ref: '#/definitions/Network' - os: - type: string - x-go-name: OS - ownerid: - type: string - x-go-name: OwnerID - password: - type: string - x-go-name: Password - persistentkeepalive: - format: int32 - type: integer - x-go-name: PersistentKeepalive - publickey: - type: string - x-go-name: PublicKey - relayaddrs: - items: - type: string - type: array - x-go-name: RelayAddrs - server: - type: string - x-go-name: Server - traffickeys: - $ref: '#/definitions/TrafficKeys' - udpholepunch: - type: string - x-go-name: UDPHolePunch - version: - type: string - x-go-name: Version - type: object - x-go-package: github.com/gravitl/netmaker/models - Network: - description: |- - Network Struct - contains info for a given unique network - At some point, need to replace all instances of Name with something else like Identifier - properties: - addressrange: - type: string - x-go-name: AddressRange - addressrange6: - type: string - x-go-name: AddressRange6 - allowmanualsignup: - type: string - x-go-name: AllowManualSignUp - defaultacl: - type: string - x-go-name: DefaultACL - defaultinterface: - type: string - x-go-name: DefaultInterface - defaultkeepalive: - format: int32 - type: integer - x-go-name: DefaultKeepalive - defaultlistenport: - format: int32 - type: integer - x-go-name: DefaultListenPort - defaultmtu: - format: int32 - type: integer - x-go-name: DefaultMTU - defaultpostdown: - type: string - x-go-name: DefaultPostDown - defaultudpholepunch: - type: string - x-go-name: DefaultUDPHolePunch - isipv4: - type: string - x-go-name: IsIPv4 - isipv6: - type: string - x-go-name: IsIPv6 - netid: - type: string - x-go-name: NetID - networklastmodified: - format: int64 - type: integer - x-go-name: NetworkLastModified - nodelimit: - format: int32 - type: integer - x-go-name: NodeLimit - nodeslastmodified: - format: int64 - type: integer - x-go-name: NodesLastModified - type: object - x-go-package: github.com/gravitl/netmaker/models - Node: - description: Node - a model of a network node - properties: - action: - type: string - x-go-name: Action - address: - $ref: '#/definitions/IPNet' - address6: - $ref: '#/definitions/IPNet' - connected: - type: boolean - x-go-name: Connected - defaultacl: - description: == PRO == - type: string - x-go-name: DefaultACL - dnson: - type: boolean - x-go-name: DNSOn - egressgatewaynatenabled: - type: boolean - x-go-name: EgressGatewayNatEnabled - egressgatewayranges: - items: - type: string - type: array - x-go-name: EgressGatewayRanges - egressgatewayrequest: - $ref: '#/definitions/EgressGatewayRequest' - expdatetime: - format: date-time - type: string - x-go-name: ExpirationDateTime - fail_over_peers: - additionalProperties: - type: object - type: object - x-go-name: FailOverPeers - failed_over_by: - format: uuid - type: string - x-go-name: FailedOverBy - hostid: - format: uuid - type: string - x-go-name: HostID - id: - format: uuid - type: string - x-go-name: ID - inet_node_req: - $ref: '#/definitions/InetNodeReq' - ingressdns: - type: string - x-go-name: IngressDNS - ingressgatewayrange: - type: string - x-go-name: IngressGatewayRange - ingressgatewayrange6: - type: string - x-go-name: IngressGatewayRange6 - internetgw_node_id: - type: string - x-go-name: InternetGwID - is_fail_over: - type: boolean - x-go-name: IsFailOver - isegressgateway: - type: boolean - x-go-name: IsEgressGateway - isingressgateway: - type: boolean - x-go-name: IsIngressGateway - isinternetgateway: - type: boolean - x-go-name: IsInternetGateway - isrelay: - type: boolean - x-go-name: IsRelay - isrelayed: - type: boolean - x-go-name: IsRelayed - lastcheckin: - format: date-time - type: string - x-go-name: LastCheckIn - lastmodified: - format: date-time - type: string - x-go-name: LastModified - lastpeerupdate: - format: date-time - type: string - x-go-name: LastPeerUpdate - localaddress: - $ref: '#/definitions/IPNet' - metadata: - type: string - x-go-name: Metadata - network: - type: string - x-go-name: Network - networkrange: - $ref: '#/definitions/IPNet' - networkrange6: - $ref: '#/definitions/IPNet' - ownerid: - type: string - x-go-name: OwnerID - pendingdelete: - type: boolean - x-go-name: PendingDelete - relayedby: - type: string - x-go-name: RelayedBy - relaynodes: - items: - type: string - type: array - x-go-name: RelayedNodes - server: - type: string - x-go-name: Server - type: object - x-go-package: github.com/gravitl/netmaker/models - PeerConfig: - description: |- - Because the zero value of some Go types may be significant to WireGuard for - PeerConfig fields, pointer types are used for some of these fields. Only - pointer fields which are not nil will be applied when configuring a peer. - properties: - AllowedIPs: - description: |- - AllowedIPs specifies a list of allowed IP addresses in CIDR notation - for this peer. - items: - $ref: '#/definitions/IPNet' - type: array - Endpoint: - $ref: '#/definitions/UDPAddr' - PersistentKeepaliveInterval: - $ref: '#/definitions/Duration' - PresharedKey: - $ref: '#/definitions/Key' - PublicKey: - $ref: '#/definitions/Key' - Remove: - description: |- - Remove specifies if the peer with this public key should be removed - from a device's peer list. - type: boolean - ReplaceAllowedIPs: - description: |- - ReplaceAllowedIPs specifies if the allowed IPs specified in this peer - configuration should replace any existing ones, instead of appending them - to the allowed IPs list. - type: boolean - UpdateOnly: - description: |- - UpdateOnly specifies that an operation will only occur on this peer - if the peer already exists as part of the interface. - type: boolean - title: A PeerConfig is a WireGuard device peer configuration. - type: object - x-go-package: golang.zx2c4.com/wireguard/wgctrl/wgtypes - PeerMap: - additionalProperties: - $ref: '#/definitions/IDandAddr' - description: PeerMap - peer map for ids and addresses in metrics - type: object - x-go-package: github.com/gravitl/netmaker/models - RegisterResponse: - description: RegisterResponse - the response to a successful enrollment register - properties: - requested_host: - $ref: '#/definitions/Host' - server_config: - $ref: '#/definitions/ServerConfig' - type: object - x-go-package: github.com/gravitl/netmaker/models - RelayRequest: - description: RelayRequest - relay request struct - properties: - netid: - type: string - x-go-name: NetID - nodeid: - type: string - x-go-name: NodeID - relayaddrs: - items: - type: string - type: array - x-go-name: RelayedNodes - type: object - x-go-package: github.com/gravitl/netmaker/models - ServerConfig: - description: ServerConfig - server conf struct - properties: - APIConnString: - type: string - APIHost: - type: string - APIPort: - type: string - AllowedEmailDomains: - type: string - AllowedOrigin: - type: string - AuthProvider: - type: string - AzureTenant: - type: string - BasicAuth: - type: string - Broker: - type: string - BrokerType: - type: string - CacheEnabled: - type: string - ClientID: - type: string - ClientSecret: - type: string - CoreDNSAddr: - type: string - DNSKey: - type: string - DNSMode: - type: string - Database: - type: string - DeployedByOperator: - type: boolean - DisableRemoteIPCheck: - type: string - DisplayKeys: - type: string - EgressesLimit: - format: int64 - type: integer - EmqxRestEndpoint: - type: string - Environment: - type: string - FrontendURL: - type: string - HostNetwork: - type: string - IngressesLimit: - format: int64 - type: integer - IsEE: - type: string - x-go-name: IsPro - JwtValidityDuration: - $ref: '#/definitions/Duration' - LicenseValue: - type: string - MQPassword: - type: string - MQUserName: - type: string - MachinesLimit: - format: int64 - type: integer - MasterKey: - type: string - MessageQueueBackend: - type: string - MetricsExporter: - type: string - NetclientAutoUpdate: - type: string - NetclientEndpointDetection: - type: string - NetmakerTenantID: - type: string - NetworksLimit: - format: int64 - type: integer - NodeID: - type: string - OIDCIssuer: - type: string - Platform: - type: string - PublicIPService: - type: string - RacAutoDisable: - type: boolean - RestBackend: - type: string - SQLConn: - type: string - Server: - type: string - ServerBrokerEndpoint: - type: string - StunList: - type: string - StunPort: - format: int64 - type: integer - Telemetry: - type: string - TurnApiServer: - type: string - TurnPassword: - type: string - TurnPort: - format: int64 - type: integer - TurnServer: - type: string - TurnUserName: - type: string - UseTurn: - type: boolean - UsersLimit: - format: int64 - type: integer - Verbosity: - format: int32 - type: integer - Version: - type: string - endpoint_detection: - type: boolean - x-go-name: EndpointDetection - type: object - x-go-package: github.com/gravitl/netmaker/config - Signal: - description: Signal - struct for signalling peer - properties: - action: - $ref: '#/definitions/SignalAction' - from_host_id: - type: string - x-go-name: FromHostID - from_host_pubkey: - type: string - x-go-name: FromHostPubKey - from_node_id: - type: string - x-go-name: FromNodeID - is_pro: - type: boolean - x-go-name: IsPro - reply: - type: boolean - x-go-name: Reply - server: - type: string - x-go-name: Server - timestamp: - format: int64 - type: integer - x-go-name: TimeStamp - to_host_id: - type: string - x-go-name: ToHostID - to_host_pubkey: - type: string - x-go-name: ToHostPubKey - to_node_id: - type: string - x-go-name: ToNodeID - type: object - x-go-package: github.com/gravitl/netmaker/models - SignalAction: - description: SignalAction - turn peer signal action - type: string - x-go-package: github.com/gravitl/netmaker/models - SuccessResponse: - properties: - Code: - format: int64 - type: integer - Message: - type: string - Response: {} - title: SuccessResponse is struct for sending error message with code. - type: object - x-go-package: github.com/gravitl/netmaker/models - TrafficKeys: - description: TrafficKeys - struct to hold public keys - properties: - mine: - items: - format: uint8 - type: integer - type: array - x-go-name: Mine - server: - items: - format: uint8 - type: integer - type: array - x-go-name: Server - type: object - x-go-package: github.com/gravitl/netmaker/models - UDPAddr: - properties: - IP: - type: string - Port: - format: int64 - type: integer - Zone: - type: string - title: UDPAddr represents the address of a UDP end point. - type: object - x-go-package: net - User: - description: User struct - struct for Users - properties: - isadmin: - type: boolean - x-go-name: IsAdmin - issuperadmin: - type: boolean - x-go-name: IsSuperAdmin - last_login_time: - format: date-time - type: string - x-go-name: LastLoginTime - password: - type: string - x-go-name: Password - remote_gw_ids: - additionalProperties: - type: object - type: object - x-go-name: RemoteGwIDs - username: - type: string - x-go-name: UserName - type: object - x-go-package: github.com/gravitl/netmaker/models - UserAuthParams: - description: UserAuthParams - user auth params struct - properties: - password: - type: string - x-go-name: Password - username: - type: string - x-go-name: UserName - type: object - x-go-package: github.com/gravitl/netmaker/models -host: api.demo.netmaker.io -info: - description: |- - # API Usage - - Most actions that can be performed via API can be performed via UI. We recommend managing your networks using the official netmaker-ui project. However, Netmaker can also be run without the UI, and all functions can be achieved via API calls. If your use case requires using Netmaker without the UI or you need to do some troubleshooting/advanced configuration, using the API directly may help. - - # Authentication - - API calls must be authenticated via a header of the format -H “Authorization: Bearer ” There are two methods to obtain YOUR_SECRET_KEY: 1. Using the masterkey. By default, this value is “secret key,” but you should change this on your instance and keep it secure. This value can be set via env var at startup or in a config file (config/environments/< env >.yaml). See the [Netmaker](https://docs.netmaker.org/index.html) documentation for more details. 2. Using a JWT received for a node. This can be retrieved by calling the /api/nodes//authenticate endpoint, as documented below. - title: Netmaker - version: 0.25.0 -paths: - /api/dns: - get: - operationId: getAllDNS - responses: - "200": - $ref: '#/responses/dnsResponse' - schemes: - - https - summary: Gets all DNS entries. - tags: - - dns - /api/dns/{network}: - post: - operationId: createDNS - parameters: - - description: Network - in: path - name: network - required: true - type: string - x-go-name: Network - - description: DNS Entry - in: body - name: body - schema: - items: - $ref: '#/definitions/DNSEntry' - type: array - x-go-name: Body - responses: - "200": - $ref: '#/responses/dnsResponse' - schemes: - - https - summary: Create a DNS entry. - tags: - - dns - /api/dns/{network}/{domain}: - delete: - operationId: deleteDNS - parameters: - - description: Network - in: path - name: network - required: true - type: string - x-go-name: Network - - description: Domain - in: path - name: domain - required: true - type: string - x-go-name: Domain - responses: - "200": - $ref: '#/responses/stringJSONResponse' - schemes: - - https - summary: Delete a DNS entry. - tags: - - dns - /api/dns/adm/{network}: - get: - operationId: getDNS - parameters: - - description: Network - in: path - name: network - required: true - type: string - x-go-name: Network - responses: - "200": - $ref: '#/responses/dnsResponse' - schemes: - - https - summary: Gets all DNS entries associated with the network. - tags: - - dns - /api/dns/adm/{network}/custom: - get: - operationId: getCustomDNS - parameters: - - description: Network - in: path - name: network - required: true - type: string - x-go-name: Network - responses: - "200": - $ref: '#/responses/dnsResponse' - schemes: - - https - summary: Gets custom DNS entries associated with a network. - tags: - - dns - /api/dns/adm/{network}/nodes: - get: - operationId: getNodeDNS - parameters: - - description: Network - in: path - name: network - required: true - type: string - x-go-name: Network - responses: - "200": - $ref: '#/responses/dnsResponse' - schemes: - - https - summary: Gets node DNS entries associated with a network. - tags: - - dns - /api/dns/adm/pushdns: - post: - operationId: pushDNS - responses: - "200": - $ref: '#/responses/dnsResponse' - schemes: - - https - summary: Push DNS entries to nameserver. - tags: - - dns - /api/emqx/hosts: - delete: - operationId: delEmqxHosts - responses: - "200": - $ref: '#/responses/apiHostResponse' - schemes: - - https - summary: Lists all hosts. - tags: - - hosts - /api/extclients: - get: - operationId: getAllExtClients - parameters: - - description: Networks - in: body - name: networks - schema: - items: - type: string - type: array - x-go-name: Networks - responses: - "200": - $ref: '#/responses/extClientSliceResponse' - schemes: - - https - summary: A separate function to get all extclients, not just extclients for a particular network. - tags: - - ext_client - /api/extclients/{network}: - get: - description: Gets all extclients associated with network, including pending extclients. - operationId: getNetworkExtClients - parameters: - - description: Network - in: path - name: network - required: true - type: string - x-go-name: Network - responses: - "200": - $ref: '#/responses/extClientSliceResponse' - schemes: - - https - summary: Get all extclients associated with network. - tags: - - ext_client - /api/extclients/{network}/{clientid}: - delete: - operationId: deleteExtClient - parameters: - - description: Client ID - in: path - name: clientid - required: true - type: string - x-go-name: ClientID - - description: Network - in: path - name: network - required: true - type: string - x-go-name: Network - responses: - "200": - $ref: '#/responses/successResponse' - schemes: - - https - summary: Delete an individual extclient. - tags: - - ext_client - get: - operationId: getExtClient - parameters: - - description: Client ID - in: path - name: clientid - required: true - type: string - x-go-name: ClientID - - description: Network - in: path - name: network - required: true - type: string - x-go-name: Network - responses: - "200": - $ref: '#/responses/extClientResponse' - schemes: - - https - summary: Get an individual extclient. - tags: - - ext_client - put: - operationId: updateExtClient - parameters: - - description: Client ID - in: path - name: clientid - required: true - type: string - x-go-name: ClientID - - description: Network - in: path - name: network - required: true - type: string - x-go-name: Network - - description: ExtClient - in: body - name: ext_client - schema: - $ref: '#/definitions/ExtClient' - x-go-name: ExtClient - responses: - "200": - $ref: '#/responses/extClientResponse' - schemes: - - https - summary: Update an individual extclient. - tags: - - ext_client - /api/extclients/{network}/{clientid}/{type}: - get: - operationId: getExtClientConf - parameters: - - description: Type - in: path - name: type - required: true - type: string - x-go-name: Type - - description: Client ID - in: path - name: clientid - required: true - type: string - x-go-name: ClientID - - description: Network - in: path - name: network - required: true - type: string - x-go-name: Network - responses: - "200": - $ref: '#/responses/extClientResponse' - schemes: - - https - summary: Get an individual extclient. - tags: - - ext_client - /api/extclients/{network}/{nodeid}: - post: - operationId: createExtClient - parameters: - - description: Network - in: path - name: network - required: true - type: string - x-go-name: Network - - description: Node ID - in: path - name: nodeid - required: true - type: string - x-go-name: NodeID - - description: Custom ExtClient - in: body - name: custom_ext_client - schema: - $ref: '#/definitions/CustomExtClient' - x-go-name: CustomExtClient - responses: - "200": - $ref: '#/responses/okResponse' - schemes: - - https - summary: Create an individual extclient. Must have valid key and be unique. - tags: - - ext_client - /api/getip: - get: - operationId: getPublicIP - responses: - "200": - $ref: '#/responses/byteArrayResponse' - schemes: - - https - summary: Get the current public IP address. - tags: - - ipservice - /api/hosts: - get: - operationId: getHosts - responses: - "200": - $ref: '#/responses/apiHostSliceResponse' - schemes: - - https - summary: Lists all hosts. - tags: - - hosts - /api/hosts/{hostid}: - delete: - operationId: deleteHost - parameters: - - description: HostID - in: path - name: hostid - required: true - type: string - x-go-name: HostID - responses: - "200": - $ref: '#/responses/apiHostResponse' - schemes: - - https - summary: Deletes a Netclient host from Netmaker server. - tags: - - hosts - put: - operationId: updateHost - parameters: - - description: HostID - in: path - name: hostid - required: true - type: string - x-go-name: HostID - responses: - "200": - $ref: '#/responses/apiHostResponse' - schemes: - - https - summary: Updates a Netclient host on Netmaker server. - tags: - - hosts - /api/hosts/{hostid}/networks/{network}: - delete: - operationId: deleteHostFromNetwork - parameters: - - description: hostid to add or delete from network - in: path - name: hostid - required: true - type: string - x-go-name: HostID - - description: network - in: path - name: network - required: true - type: string - x-go-name: Network - responses: - "200": - $ref: '#/responses/okResponse' - schemes: - - https - summary: Given a network, a host is removed from the network. - tags: - - hosts - post: - operationId: addHostToNetwork - parameters: - - description: hostid to add or delete from network - in: path - name: hostid - required: true - type: string - x-go-name: HostID - - description: network - in: path - name: network - required: true - type: string - x-go-name: Network - responses: - "200": - $ref: '#/responses/okResponse' - schemes: - - https - summary: Given a network, a host is added to the network. - tags: - - hosts - /api/hosts/{hostid}/signalpeer: - post: - operationId: signalPeer - parameters: - - description: HostID - in: path - name: hostid - required: true - type: string - x-go-name: HostID - responses: - "200": - $ref: '#/responses/signal' - schemes: - - https - summary: send signal to peer. - tags: - - hosts - /api/hosts/{hostid}/sync: - post: - operationId: synchost - parameters: - - description: HostID - in: path - name: hostid - required: true - type: string - x-go-name: HostID - responses: - "200": - $ref: '#/responses/networkBodyResponse' - schemes: - - https - summary: Requests a host to pull. - tags: - - hosts - /api/hosts/{hostid}keys: - post: - operationId: updateKeys - parameters: - - description: HostID - in: path - name: hostid - required: true - type: string - x-go-name: HostID - responses: - "200": - $ref: '#/responses/networkBodyResponse' - schemes: - - https - summary: Update keys for a network. - tags: - - hosts - /api/hosts/adm/authenticate: - post: - operationId: authenticateHost - responses: - "200": - $ref: '#/responses/successResponse' - schemes: - - https - summary: Host based authentication for making further API calls. - tags: - - authenticate - /api/hosts/keys: - post: - operationId: updateAllKeys - responses: - "200": - $ref: '#/responses/networkBodyResponse' - schemes: - - https - summary: Update keys for a network. - tags: - - hosts - /api/networks: - get: - operationId: getNetworks - responses: - "200": - $ref: '#/responses/getNetworksSliceResponse' - schemes: - - https - summary: Lists all networks. - tags: - - networks - post: - operationId: createNetwork - parameters: - - description: Network - in: body - name: network - schema: - $ref: '#/definitions/Network' - x-go-name: Network - responses: - "200": - $ref: '#/responses/networkBodyResponse' - schemes: - - https - summary: Create a network. - tags: - - networks - /api/networks/{networkname}: - delete: - operationId: deleteNetwork - parameters: - - description: 'name: network name' - in: path - name: networkname - required: true - type: string - x-go-name: Networkname - responses: - "200": - $ref: '#/responses/successResponse' - schemes: - - https - summary: Delete a network. Will not delete if there are any nodes that belong to the network. - tags: - - networks - get: - operationId: getNetwork - parameters: - - description: 'name: network name' - in: path - name: networkname - required: true - type: string - x-go-name: Networkname - responses: - "200": - $ref: '#/responses/networkBodyResponse' - schemes: - - https - summary: Get a network. - tags: - - networks - put: - operationId: updateNetwork - parameters: - - description: 'name: network name' - in: path - name: networkname - required: true - type: string - x-go-name: Networkname - - description: Network - in: body - name: network - schema: - $ref: '#/definitions/Network' - x-go-name: Network - responses: - "200": - $ref: '#/responses/networkBodyResponse' - schemes: - - https - summary: Update pro settings for a network. - tags: - - networks - /api/networks/{networkname}/acls: - get: - operationId: getNetworkACL - parameters: - - description: 'name: network name' - in: path - name: networkname - required: true - type: string - x-go-name: Networkname - responses: - "200": - $ref: '#/responses/aclContainerResponse' - schemes: - - https - summary: Get a network ACL (Access Control List). - tags: - - networks - put: - operationId: updateNetworkACL - parameters: - - description: 'name: network name' - in: path - name: networkname - required: true - type: string - x-go-name: Networkname - - description: ACL Container - in: body - name: acl_container - schema: - $ref: '#/definitions/ACLContainer' - x-go-name: ACLContainer - responses: - "200": - $ref: '#/responses/aclContainerResponse' - schemes: - - https - summary: Update a network ACL (Access Control List). - tags: - - networks - /api/networks/{networkname}/acls/v2: - put: - operationId: updateNetworkACL - parameters: - - description: 'name: network name' - in: path - name: networkname - required: true - type: string - x-go-name: Networkname - - description: ACL Container - in: body - name: acl_container - schema: - $ref: '#/definitions/ACLContainer' - x-go-name: ACLContainer - responses: - "200": - $ref: '#/responses/aclContainerResponse' - schemes: - - https - summary: Update a network ACL (Access Control List). - tags: - - networks - /api/node/{nodeid}/failOverME: - post: - operationId: failOver_me - responses: - "200": - $ref: '#/responses/nodeResponse' - schemes: - - https - summary: Create a relay. - tags: - - node - /api/nodes: - get: - operationId: getAllNodes - responses: - "200": - $ref: '#/responses/nodeSliceResponse' - schemes: - - https - summary: Get all nodes across all networks. - tags: - - nodes - /api/nodes/{network}: - get: - operationId: getNetworkNodes - parameters: - - description: Network - in: path - name: network - required: true - type: string - x-go-name: Network - responses: - "200": - $ref: '#/responses/nodeSliceResponse' - schemes: - - https - summary: Gets all nodes associated with network including pending nodes. - tags: - - nodes - /api/nodes/{network}/{nodeid}: - delete: - operationId: deleteNode - parameters: - - in: path - name: network - required: true - type: string - x-go-name: Network - - in: path - name: nodeid - required: true - type: string - x-go-name: NodeID - - description: Node - in: body - name: node - schema: - $ref: '#/definitions/LegacyNode' - x-go-name: Node - responses: - "200": - $ref: '#/responses/nodeResponse' - schemes: - - https - summary: Delete an individual node. - tags: - - nodes - get: - operationId: getNode - parameters: - - in: path - name: network - required: true - type: string - x-go-name: Network - - in: path - name: nodeid - required: true - type: string - x-go-name: NodeID - responses: - "200": - $ref: '#/responses/nodeResponse' - schemes: - - https - summary: Get an individual node. - tags: - - nodes - put: - operationId: updateNode - parameters: - - in: path - name: network - required: true - type: string - x-go-name: Network - - in: path - name: nodeid - required: true - type: string - x-go-name: NodeID - - description: Node - in: body - name: node - schema: - $ref: '#/definitions/LegacyNode' - x-go-name: Node - responses: - "200": - $ref: '#/responses/nodeResponse' - schemes: - - https - summary: Update an individual node. - tags: - - nodes - /api/nodes/{network}/{nodeid}/creategateway: - post: - operationId: createEgressGateway - parameters: - - in: path - name: network - required: true - type: string - x-go-name: Network - - in: path - name: nodeid - required: true - type: string - x-go-name: NodeID - - description: Egress Gateway Request - in: body - name: egress_gateway_request - schema: - $ref: '#/definitions/EgressGatewayRequest' - x-go-name: EgressGatewayRequest - responses: - "200": - $ref: '#/responses/nodeResponse' - schemes: - - https - summary: Create an egress gateway. - tags: - - nodes - /api/nodes/{network}/{nodeid}/createingress: - post: - operationId: createIngressGateway - parameters: - - in: path - name: network - required: true - type: string - x-go-name: Network - - in: path - name: nodeid - required: true - type: string - x-go-name: NodeID - responses: - "200": - $ref: '#/responses/nodeResponse' - schemes: - - https - summary: Create an ingress gateway. - tags: - - nodes - /api/nodes/{network}/{nodeid}/createrelay: - post: - operationId: createRelay - parameters: - - in: path - name: network - required: true - type: string - x-go-name: Network - - in: path - name: nodeid - required: true - type: string - x-go-name: NodeID - - description: Relay Request - in: body - name: relay_request - schema: - $ref: '#/definitions/RelayRequest' - x-go-name: RelayRequest - responses: - "200": - $ref: '#/responses/nodeResponse' - schemes: - - https - summary: Create a relay. - tags: - - nodes - /api/nodes/{network}/{nodeid}/deletegateway: - delete: - operationId: deleteEgressGateway - parameters: - - in: path - name: network - required: true - type: string - x-go-name: Network - - in: path - name: nodeid - required: true - type: string - x-go-name: NodeID - responses: - "200": - $ref: '#/responses/nodeResponse' - schemes: - - https - summary: Delete an egress gateway. - tags: - - nodes - /api/nodes/{network}/{nodeid}/deleteingress: - delete: - operationId: deleteIngressGateway - parameters: - - in: path - name: network - required: true - type: string - x-go-name: Network - - in: path - name: nodeid - required: true - type: string - x-go-name: NodeID - responses: - "200": - $ref: '#/responses/nodeResponse' - schemes: - - https - summary: Delete an ingress gateway. - tags: - - nodes - /api/nodes/{network}/{nodeid}/deleterelay: - delete: - operationId: deleteRelay - parameters: - - in: path - name: network - required: true - type: string - x-go-name: Network - - in: path - name: nodeid - required: true - type: string - x-go-name: NodeID - responses: - "200": - $ref: '#/responses/nodeResponse' - schemes: - - https - summary: Remove a relay. - tags: - - nodes - /api/nodes/{network}/{nodeid}/inet_gw: - delete: - operationId: deleteInternetGw - responses: - "200": - $ref: '#/responses/nodeResponse' - schemes: - - https - summary: Delete an internet gw. - tags: - - nodes - post: - operationId: createInternetGw - responses: - "200": - $ref: '#/responses/nodeResponse' - schemes: - - https - summary: Create an inet node. - tags: - - nodes - put: - operationId: updateInternetGw - responses: - "200": - $ref: '#/responses/nodeResponse' - schemes: - - https - summary: update an inet node. - tags: - - nodes - /api/nodes/{network}/{nodeid}/ingress/users: - get: - operationId: ingressGatewayUsers - parameters: - - in: path - name: network - required: true - type: string - x-go-name: Network - - in: path - name: nodeid - required: true - type: string - x-go-name: NodeID - responses: - "200": - $ref: '#/responses/nodeResponse' - schemes: - - https - summary: Lists all the users attached to an ingress gateway. - tags: - - users - /api/nodes/adm/{network}/authenticate: - post: - operationId: authenticate - parameters: - - description: network - in: path - name: network - required: true - type: string - x-go-name: Network - - description: AuthParams - in: body - name: auth_params - schema: - $ref: '#/definitions/AuthParams' - x-go-name: AuthParams - responses: - "200": - $ref: '#/responses/successResponse' - schemes: - - https - summary: Authenticate to make further API calls related to a network. - tags: - - authenticate - /api/oauth/login: - get: - operationId: HandleAuthLogin - responses: - "200": - $ref: '#/responses/okResponse' - schemes: - - https - summary: Handles OAuth login. - tags: - - nodes - /api/server/getconfig: - get: - operationId: getConfig - responses: - "200": - $ref: '#/responses/serverConfigResponse' - schemes: - - https - summary: Get the server configuration. - tags: - - server - /api/server/getserverinfo: - get: - operationId: getServerInfo - responses: - "200": - $ref: '#/responses/serverConfigResponse' - schemes: - - https - summary: Get the server configuration. - tags: - - server - /api/server/status: - get: - operationId: getStatus - responses: - "200": - $ref: '#/responses/serverConfigResponse' - schemes: - - https - summary: Get the server configuration. - tags: - - server - /api/users: - get: - operationId: getUsers - responses: - "200": - $ref: '#/responses/userBodyResponse' - schemes: - - https - summary: Get all users. - tags: - - user - /api/users/{username}: - delete: - operationId: deleteUser - parameters: - - description: Username - in: path - name: username - required: true - type: string - x-go-name: Username - responses: - "200": - $ref: '#/responses/userBodyResponse' - schemes: - - https - summary: Delete a user. - tags: - - user - get: - operationId: getUser - parameters: - - description: Username - in: path - name: username - required: true - type: string - x-go-name: Username - responses: - "200": - $ref: '#/responses/userBodyResponse' - schemes: - - https - summary: Get an individual user. - tags: - - user - post: - operationId: createUser - parameters: - - description: User - in: body - name: user - schema: - $ref: '#/definitions/User' - x-go-name: User - - description: Username - in: path - name: username - required: true - type: string - x-go-name: Username - responses: - "200": - $ref: '#/responses/userBodyResponse' - schemes: - - https - summary: Create a user. - tags: - - user - put: - operationId: updateUser - parameters: - - description: User - in: body - name: user - schema: - $ref: '#/definitions/User' - x-go-name: User - - description: Username - in: path - name: username - required: true - type: string - x-go-name: Username - responses: - "200": - $ref: '#/responses/userBodyResponse' - schemes: - - https - summary: Update a user. - tags: - - user - /api/users/{username}/remote_access_gw: - delete: - operationId: removeUserFromRemoteAccessGW - parameters: - - in: path - name: username - required: true - type: string - x-go-name: Username - responses: - "200": - $ref: '#/responses/userBodyResponse' - schemes: - - https - summary: Delete User from a remote access gateway. - tags: - - user - post: - operationId: attachUserToRemoteAccessGateway - parameters: - - in: path - name: username - required: true - type: string - x-go-name: Username - responses: - "200": - $ref: '#/responses/userBodyResponse' - schemes: - - https - summary: Attach User to a remote access gateway. - tags: - - user - /api/users/adm/authenticate: - post: - operationId: authenticateUser - parameters: - - description: User Auth Params - in: body - name: user_auth_params - schema: - $ref: '#/definitions/UserAuthParams' - x-go-name: UserAuthParams - responses: - "200": - $ref: '#/responses/successResponse' - schemes: - - https - summary: User authenticates using its password and retrieves a JWT for authorization. - tags: - - authenticate - /api/users/adm/createsuperadmin: - post: - operationId: createAdmin - parameters: - - description: User - in: body - name: user - schema: - $ref: '#/definitions/User' - x-go-name: User - responses: - "200": - $ref: '#/responses/userBodyResponse' - schemes: - - https - summary: Make a user an admin. - tags: - - user - /api/users/adm/hassuperadmin: - get: - operationId: hasSuperAdmin - responses: - "200": - $ref: '#/responses/hasAdmin' - schemes: - - https - summary: Checks whether the server has an admin. - tags: - - user - /api/users/adm/transfersuperadmin: - post: - operationId: transferSuperAdmin - responses: - "200": - $ref: '#/responses/userBodyResponse' - schemes: - - https - summary: Transfers superadmin role to an admin user. - tags: - - user - /api/users_pending: - get: - operationId: getPendingUsers - responses: - "200": - $ref: '#/responses/userBodyResponse' - schemes: - - https - summary: Get all pending users. - tags: - - user - /api/users_pending/{username}/pending: - delete: - operationId: deleteAllPendingUsers - responses: - "200": - $ref: '#/responses/userBodyResponse' - schemes: - - https - summary: delete all pending users. - tags: - - user - /api/users_pending/user/{username}: - delete: - operationId: deletePendingUser - responses: - "200": - $ref: '#/responses/userBodyResponse' - schemes: - - https - summary: delete pending user. - tags: - - user - post: - operationId: approvePendingUser - responses: - "200": - $ref: '#/responses/userBodyResponse' - schemes: - - https - summary: approve pending user. - tags: - - user - /api/v1/enrollment-keys: - get: - operationId: getEnrollmentKeys - responses: - "200": - $ref: '#/responses/EnrollmentKeys' - schemes: - - https - summary: Lists all EnrollmentKeys for admins. - tags: - - enrollmentKeys - post: - operationId: createEnrollmentKey - parameters: - - description: APIEnrollmentKey - in: body - name: body - schema: - $ref: '#/definitions/APIEnrollmentKey' - x-go-name: Body - responses: - "200": - $ref: '#/responses/EnrollmentKey' - schemes: - - https - summary: Creates an EnrollmentKey for hosts to use on Netmaker server. - tags: - - enrollmentKeys - /api/v1/enrollment-keys/{keyid}: - delete: - operationId: deleteEnrollmentKey - parameters: - - in: path - name: keyid - required: true - type: string - x-go-name: KeyID - responses: - "200": - $ref: '#/responses/okResponse' - schemes: - - https - summary: Deletes an EnrollmentKey from Netmaker server. - tags: - - enrollmentKeys - put: - operationId: updateEnrollmentKey - parameters: - - description: KeyID - in: path - name: keyid - required: true - type: string - x-go-name: KeyID - - description: APIEnrollmentKey - in: body - name: body - schema: - $ref: '#/definitions/APIEnrollmentKey' - x-go-name: Body - responses: - "200": - $ref: '#/responses/EnrollmentKey' - schemes: - - https - summary: Updates an EnrollmentKey for hosts to use on Netmaker server. Updates only the relay to use. - tags: - - enrollmentKeys - /api/v1/enrollment-keys/{token}: - post: - operationId: handleHostRegister - parameters: - - in: path - name: token - required: true - type: string - x-go-name: Token - - in: body - name: host - schema: - $ref: '#/definitions/Host' - x-go-name: Host - responses: - "200": - $ref: '#/responses/RegisterResponse' - schemes: - - https - summary: Handles a Netclient registration with server and add nodes accordingly. - tags: - - enrollmentKeys - /api/v1/fallback/host/{hostid}: - put: - operationId: hostUpdateFallback - responses: - "200": - $ref: '#/responses/apiHostResponse' - schemes: - - https - summary: Updates a Netclient host on Netmaker server. - tags: - - hosts - /api/v1/host: - get: - description: Used by clients for "pull" command - operationId: pullHost - responses: - "200": - $ref: '#/responses/hostPull' - schemes: - - https - tags: - - hosts - /api/v1/legacy/nodes: - delete: - operationId: wipeLegacyNodes - responses: - "200": - $ref: '#/responses/successResponse' - schemes: - - https - summary: Delete all legacy nodes from DB. - tags: - - nodes - /api/v1/node/failover: - delete: - operationId: deletefailOver - responses: - "200": - $ref: '#/responses/nodeResponse' - schemes: - - https - summary: Create a relay. - tags: - - node - post: - operationId: createfailOver - responses: - "200": - $ref: '#/responses/nodeResponse' - schemes: - - https - summary: Create a relay. - tags: - - node - /api/v1/nodes/migrate: - put: - operationId: migrateData - responses: - "200": - $ref: '#/responses/hostPull' - schemes: - - https - summary: Used to migrate a legacy node. - tags: - - nodes - /meshclient/files/{filename}: - get: - operationId: getFile - parameters: - - description: Filename - in: path - name: filename - required: true - type: string - x-go-name: Filename - responses: - "200": - $ref: '#/responses/fileResponse' - schemes: - - https - summary: Retrieve a file from the file server. - tags: - - meshclient -produces: - - application/json -responses: - EnrollmentKey: - description: "" - schema: - $ref: '#/definitions/EnrollmentKey' - EnrollmentKeys: - description: "" - schema: - items: - $ref: '#/definitions/EnrollmentKey' - type: array - RegisterResponse: - description: "" - schema: - $ref: '#/definitions/RegisterResponse' - aclContainerResponse: - description: "" - schema: - $ref: '#/definitions/ACLContainer' - apiHostResponse: - description: "" - schema: - $ref: '#/definitions/ApiHost' - apiHostSliceResponse: - description: "" - schema: - items: - $ref: '#/definitions/ApiHost' - type: array - byteArrayResponse: - description: "" - schema: - items: - format: uint8 - type: integer - type: array - dnsResponse: - description: Success - schema: - items: - $ref: '#/definitions/DNSEntry' - type: array - extClientResponse: - description: "" - schema: - $ref: '#/definitions/ExtClient' - extClientSliceResponse: - description: "" - schema: - items: - $ref: '#/definitions/ExtClient' - type: array - fileResponse: - description: "" - schema: - $ref: '#/definitions/File' - getNetworksSliceResponse: - description: "" - schema: - items: - $ref: '#/definitions/Network' - type: array - hasAdmin: - description: "" - hostPull: - description: "" - schema: - $ref: '#/definitions/HostPull' - networkBodyResponse: - description: "" - schema: - $ref: '#/definitions/Network' - nodeResponse: - description: "" - schema: - $ref: '#/definitions/LegacyNode' - nodeSliceResponse: - description: "" - schema: - items: - $ref: '#/definitions/ApiNode' - type: array - okResponse: - description: "" - serverConfigResponse: - description: "" - schema: - $ref: '#/definitions/ServerConfig' - signal: - description: "" - schema: - $ref: '#/definitions/Signal' - stringJSONResponse: - description: "" - successResponse: - description: "" - schema: - $ref: '#/definitions/SuccessResponse' - userBodyResponse: - description: "" - schema: - $ref: '#/definitions/User' -schemes: - - https -swagger: "2.0"