Add docs for internal cluster API at /v1/swagger/index.html

This commit is contained in:
Ingo Oppermann
2023-06-06 13:00:16 +02:00
parent cefc03bcb2
commit 3adf5fd7d4
8 changed files with 3025 additions and 316 deletions

View File

@@ -23,7 +23,8 @@ build_linux:
## swagger: Update swagger API documentation (requires github.com/swaggo/swag)
swagger:
swag init -g http/server.go
swag init -g http/server.go -o ./docs --exclude ./cluster
swag init -g cluster/api.go -o ./cluster/docs --exclude ./http --instanceName ClusterAPI
## gqlgen: Regenerate GraphQL server from schema
gqlgen:

View File

@@ -1,12 +1,25 @@
// @title datarhei Core Cluster API
// @version 1.0
// @description Internal REST API for the datarhei Core cluster
// @contact.name datarhei Core Support
// @contact.url https://www.datarhei.com
// @contact.email hello@datarhei.com
// @license.name Apache 2.0
// @license.url https://github.com/datarhei/core/v16/blob/main/LICENSE
// @BasePath /
package cluster
import (
"context"
"fmt"
"net/http"
"strings"
"github.com/datarhei/core/v16/cluster/client"
httpapi "github.com/datarhei/core/v16/http/api"
"github.com/datarhei/core/v16/http/errorhandler"
"github.com/datarhei/core/v16/http/handler/util"
httplog "github.com/datarhei/core/v16/http/log"
@@ -17,6 +30,9 @@ import (
"github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware"
echoSwagger "github.com/swaggo/echo-swagger" // echo-swagger middleware
_ "github.com/datarhei/core/v16/cluster/docs"
)
type api struct {
@@ -75,284 +91,28 @@ func NewAPI(config APIConfig) (API, error) {
}))
a.router.Logger.SetOutput(httplog.NewWrapper(a.logger))
a.router.POST("/v1/server", func(c echo.Context) error {
r := client.JoinRequest{}
swagHandler := echoSwagger.EchoWrapHandler(echoSwagger.InstanceName("ClusterAPI"))
if err := util.ShouldBindJSON(c, &r); err != nil {
return httpapi.Err(http.StatusBadRequest, "Invalid JSON", "%s", err)
}
// Swagger API documentation router group
doc := a.router.Group("/v1/swagger/*")
doc.GET("", swagHandler)
a.logger.Debug().WithFields(log.Fields{
"id": r.ID,
"request": r,
}).Log("Join request: %+v", r)
a.router.POST("/v1/server", a.AddServer)
a.router.DELETE("/v1/server/:id", a.RemoveServer)
origin := c.Request().Header.Get("X-Cluster-Origin")
a.router.GET("/v1/snaphot", a.Snapshot)
if origin == a.id {
return httpapi.Err(http.StatusLoopDetected, "", "breaking circuit")
}
a.router.POST("/v1/process", a.AddProcess)
a.router.DELETE("/v1/process/:id", a.RemoveProcess)
a.router.PUT("/v1/process/:id", a.UpdateProcess)
a.router.PUT("/v1/process/:id/metadata/:key", a.SetProcessMetadata)
err := a.cluster.Join(origin, r.ID, r.RaftAddress, "")
if err != nil {
a.logger.Debug().WithError(err).WithField("id", r.ID).Log("Unable to join cluster")
return httpapi.Err(http.StatusInternalServerError, "unable to join cluster", "%s", err)
}
a.router.POST("/v1/iam/user", a.AddIdentity)
a.router.PUT("/v1/iam/user/:name", a.UpdateIdentity)
a.router.PUT("/v1/iam/user/:name/policies", a.SetIdentityPolicies)
a.router.DELETE("/v1/iam/user/:name", a.RemoveIdentity)
return c.JSON(http.StatusOK, "OK")
})
a.router.DELETE("/v1/server/:id", func(c echo.Context) error {
id := util.PathParam(c, "id")
a.logger.Debug().WithFields(log.Fields{
"id": id,
}).Log("Leave request")
origin := c.Request().Header.Get("X-Cluster-Origin")
if origin == a.id {
return httpapi.Err(http.StatusLoopDetected, "", "breaking circuit")
}
err := a.cluster.Leave(origin, id)
if err != nil {
a.logger.Debug().WithError(err).WithField("id", id).Log("Unable to leave cluster")
return httpapi.Err(http.StatusInternalServerError, "unable to leave cluster", "%s", err)
}
return c.JSON(http.StatusOK, "OK")
})
a.router.GET("/v1/snaphot", func(c echo.Context) error {
data, err := a.cluster.Snapshot()
if err != nil {
a.logger.Debug().WithError(err).Log("Unable to create snaphot")
return httpapi.Err(http.StatusInternalServerError, "unable to create snapshot", "%s", err)
}
defer data.Close()
return c.Stream(http.StatusOK, "application/octet-stream", data)
})
a.router.POST("/v1/process", func(c echo.Context) error {
r := client.AddProcessRequest{}
if err := util.ShouldBindJSON(c, &r); err != nil {
return httpapi.Err(http.StatusBadRequest, "Invalid JSON", "%s", err)
}
origin := c.Request().Header.Get("X-Cluster-Origin")
if origin == a.id {
return httpapi.Err(http.StatusLoopDetected, "", "breaking circuit")
}
a.logger.Debug().WithField("id", r.Config.ID).Log("Add process request")
err := a.cluster.AddProcess(origin, &r.Config)
if err != nil {
a.logger.Debug().WithError(err).WithField("id", r.Config.ID).Log("Unable to add process")
return httpapi.Err(http.StatusInternalServerError, "unable to add process", "%s", err)
}
return c.JSON(http.StatusOK, "OK")
})
a.router.DELETE("/v1/process/:id", func(c echo.Context) error {
id := util.PathParam(c, "id")
domain := util.DefaultQuery(c, "domain", "")
origin := c.Request().Header.Get("X-Cluster-Origin")
if origin == a.id {
return httpapi.Err(http.StatusLoopDetected, "", "breaking circuit")
}
pid := app.ProcessID{ID: id, Domain: domain}
a.logger.Debug().WithField("id", pid).Log("Remove process request")
err := a.cluster.RemoveProcess(origin, pid)
if err != nil {
a.logger.Debug().WithError(err).WithField("id", pid).Log("Unable to remove process")
return httpapi.Err(http.StatusInternalServerError, "unable to remove process", "%s", err)
}
return c.JSON(http.StatusOK, "OK")
})
a.router.PUT("/v1/process/:id", func(c echo.Context) error {
id := util.PathParam(c, "id")
domain := util.DefaultQuery(c, "domain", "")
r := client.UpdateProcessRequest{}
if err := util.ShouldBindJSON(c, &r); err != nil {
return httpapi.Err(http.StatusBadRequest, "Invalid JSON", "%s", err)
}
origin := c.Request().Header.Get("X-Cluster-Origin")
if origin == a.id {
return httpapi.Err(http.StatusLoopDetected, "", "breaking circuit")
}
pid := app.ProcessID{ID: id, Domain: domain}
if !pid.Equals(r.ID) {
return httpapi.Err(http.StatusBadRequest, "Invalid data", "the ID in the path and the request do not match")
}
a.logger.Debug().WithFields(log.Fields{
"old_id": r.ID,
"new_id": r.Config.ProcessID(),
}).Log("Update process request")
err := a.cluster.UpdateProcess(origin, r.ID, &r.Config)
if err != nil {
a.logger.Debug().WithError(err).WithField("id", r.ID).Log("Unable to update process")
return httpapi.Err(http.StatusInternalServerError, "unable to update process", "%s", err)
}
return c.JSON(http.StatusOK, "OK")
})
a.router.PUT("/v1/process/:id/metadata/:key", func(c echo.Context) error {
id := util.PathParam(c, "id")
key := util.PathParam(c, "key")
domain := util.DefaultQuery(c, "domain", "")
r := client.SetProcessMetadataRequest{}
if err := util.ShouldBindJSON(c, &r); err != nil {
return httpapi.Err(http.StatusBadRequest, "Invalid JSON", "%s", err)
}
origin := c.Request().Header.Get("X-Cluster-Origin")
if origin == a.id {
return httpapi.Err(http.StatusLoopDetected, "", "breaking circuit")
}
pid := app.ProcessID{ID: id, Domain: domain}
err := a.cluster.SetProcessMetadata(origin, pid, key, r.Metadata)
if err != nil {
a.logger.Debug().WithError(err).WithField("id", r.ID).Log("Unable to update metadata")
return httpapi.Err(http.StatusInternalServerError, "unable to update metadata", "%s", err)
}
return c.JSON(http.StatusOK, "OK")
})
a.router.POST("/v1/iam/user", func(c echo.Context) error {
r := client.AddIdentityRequest{}
if err := util.ShouldBindJSON(c, &r); err != nil {
return httpapi.Err(http.StatusBadRequest, "Invalid JSON", "%s", err)
}
origin := c.Request().Header.Get("X-Cluster-Origin")
if origin == a.id {
return httpapi.Err(http.StatusLoopDetected, "", "breaking circuit")
}
a.logger.Debug().WithField("identity", r.Identity).Log("Add identity request")
err := a.cluster.AddIdentity(origin, r.Identity)
if err != nil {
a.logger.Debug().WithError(err).WithField("identity", r.Identity).Log("Unable to add identity")
return httpapi.Err(http.StatusInternalServerError, "unable to add identity", "%s", err)
}
return c.JSON(http.StatusOK, "OK")
})
a.router.PUT("/v1/iam/user/:name", func(c echo.Context) error {
name := util.PathParam(c, "name")
r := client.UpdateIdentityRequest{}
if err := util.ShouldBindJSON(c, &r); err != nil {
return httpapi.Err(http.StatusBadRequest, "Invalid JSON", "%s", err)
}
origin := c.Request().Header.Get("X-Cluster-Origin")
if origin == a.id {
return httpapi.Err(http.StatusLoopDetected, "", "breaking circuit")
}
a.logger.Debug().WithFields(log.Fields{
"name": name,
"identity": r.Identity,
}).Log("Update identity request")
err := a.cluster.UpdateIdentity(origin, name, r.Identity)
if err != nil {
a.logger.Debug().WithError(err).WithFields(log.Fields{
"name": name,
"identity": r.Identity,
}).Log("Unable to add identity")
return httpapi.Err(http.StatusInternalServerError, "unable to update identity", "%s", err)
}
return c.JSON(http.StatusOK, "OK")
})
a.router.PUT("/v1/iam/user/:name/policies", func(c echo.Context) error {
name := util.PathParam(c, "name")
r := client.SetPoliciesRequest{}
if err := util.ShouldBindJSON(c, &r); err != nil {
return httpapi.Err(http.StatusBadRequest, "Invalid JSON", "%s", err)
}
origin := c.Request().Header.Get("X-Cluster-Origin")
if origin == a.id {
return httpapi.Err(http.StatusLoopDetected, "", "breaking circuit")
}
a.logger.Debug().WithField("policies", r.Policies).Log("Set policiesrequest")
err = a.cluster.SetPolicies(origin, name, r.Policies)
if err != nil {
a.logger.Debug().WithError(err).WithField("policies", r.Policies).Log("Unable to set policies")
return httpapi.Err(http.StatusInternalServerError, "unable to add identity", "%s", err)
}
return c.JSON(http.StatusOK, "OK")
})
a.router.DELETE("/v1/iam/user/:name", func(c echo.Context) error {
name := util.PathParam(c, "name")
origin := c.Request().Header.Get("X-Cluster-Origin")
if origin == a.id {
return httpapi.Err(http.StatusLoopDetected, "", "breaking circuit")
}
a.logger.Debug().WithField("identity", name).Log("Remove identity request")
err := a.cluster.RemoveIdentity(origin, name)
if err != nil {
a.logger.Debug().WithError(err).WithField("identity", name).Log("Unable to remove identity")
return httpapi.Err(http.StatusInternalServerError, "unable to remove identity", "%s", err)
}
return c.JSON(http.StatusOK, "OK")
})
a.router.GET("/v1/core", func(c echo.Context) error {
address, _ := a.cluster.CoreAPIAddress("")
return c.JSON(http.StatusOK, address)
})
a.router.GET("/v1/core", a.CoreAPIAddress)
return a, nil
}
@@ -366,3 +126,464 @@ func (a *api) Shutdown(ctx context.Context) error {
a.logger.Debug().WithField("address", a.address).Log("Shutting down api")
return a.router.Shutdown(ctx)
}
// AddServer adds a new server to the cluster
// @Summary Add a new server
// @Description Add a new server to the cluster
// @Tags v1.0.0
// @ID cluster-1-add-server
// @Accept json
// @Produce json
// @Param config body client.JoinRequest true "Server ID and address"
// @Param X-Cluster-Origin header string false "Origin ID of request"
// @Success 200 {string} string
// @Failure 400 {object} Error
// @Failure 500 {object} Error
// @Failure 508 {object} Error
// @Router /v1/server [post]
func (a *api) AddServer(c echo.Context) error {
r := client.JoinRequest{}
if err := util.ShouldBindJSON(c, &r); err != nil {
return Err(http.StatusBadRequest, "Invalid JSON", "%s", err)
}
a.logger.Debug().WithFields(log.Fields{
"id": r.ID,
"request": r,
}).Log("Join request: %+v", r)
origin := c.Request().Header.Get("X-Cluster-Origin")
if origin == a.id {
return Err(http.StatusLoopDetected, "", "breaking circuit")
}
err := a.cluster.Join(origin, r.ID, r.RaftAddress, "")
if err != nil {
a.logger.Debug().WithError(err).WithField("id", r.ID).Log("Unable to join cluster")
return Err(http.StatusInternalServerError, "unable to join cluster", "%s", err)
}
return c.JSON(http.StatusOK, "OK")
}
// RemoveServer removes a server from the cluster
// @Summary Remove a server
// @Description Remove a server from the cluster
// @Tags v1.0.0
// @ID cluster-1-remove-server
// @Produce json
// @Param id path string true "Server ID"
// @Param X-Cluster-Origin header string false "Origin ID of request"
// @Success 200 {string} string
// @Failure 500 {object} Error
// @Failure 508 {object} Error
// @Router /v1/server/{id} [delete]
func (a *api) RemoveServer(c echo.Context) error {
id := util.PathParam(c, "id")
a.logger.Debug().WithFields(log.Fields{
"id": id,
}).Log("Leave request")
origin := c.Request().Header.Get("X-Cluster-Origin")
if origin == a.id {
return Err(http.StatusLoopDetected, "", "breaking circuit")
}
err := a.cluster.Leave(origin, id)
if err != nil {
a.logger.Debug().WithError(err).WithField("id", id).Log("Unable to leave cluster")
return Err(http.StatusInternalServerError, "unable to leave cluster", "%s", err)
}
return c.JSON(http.StatusOK, "OK")
}
// Snapshot returns a current snapshot of the cluster DB
// @Summary Cluster DB snapshot
// @Description Current snapshot of the clusterDB
// @Tags v1.0.0
// @ID cluster-1-snapshot
// @Produce application/octet-stream
// @Success 200 {file} byte
// @Success 500 {array} Error
// @Router /v1/snapshot [get]
func (a *api) Snapshot(c echo.Context) error {
data, err := a.cluster.Snapshot()
if err != nil {
a.logger.Debug().WithError(err).Log("Unable to create snaphot")
return Err(http.StatusInternalServerError, "unable to create snapshot", "%s", err)
}
defer data.Close()
return c.Stream(http.StatusOK, "application/octet-stream", data)
}
// AddProcess adds a process to the cluster DB
// @Summary Add a process
// @Description Add a process to the cluster DB
// @Tags v1.0.0
// @ID cluster-1-add-process
// @Accept json
// @Produce json
// @Param config body client.AddProcessRequest true "Process config"
// @Param X-Cluster-Origin header string false "Origin ID of request"
// @Success 200 {string} string
// @Failure 400 {object} Error
// @Failure 500 {object} Error
// @Failure 508 {object} Error
// @Router /v1/process [post]
func (a *api) AddProcess(c echo.Context) error {
r := client.AddProcessRequest{}
if err := util.ShouldBindJSON(c, &r); err != nil {
return Err(http.StatusBadRequest, "Invalid JSON", "%s", err)
}
origin := c.Request().Header.Get("X-Cluster-Origin")
if origin == a.id {
return Err(http.StatusLoopDetected, "", "breaking circuit")
}
a.logger.Debug().WithField("id", r.Config.ID).Log("Add process request")
err := a.cluster.AddProcess(origin, &r.Config)
if err != nil {
a.logger.Debug().WithError(err).WithField("id", r.Config.ID).Log("Unable to add process")
return Err(http.StatusInternalServerError, "unable to add process", "%s", err)
}
return c.JSON(http.StatusOK, "OK")
}
// RemoveProcess removes a process from the cluster DB
// @Summary Remove a process
// @Description Remove a process from the cluster DB
// @Tags v1.0.0
// @ID cluster-1-remove-process
// @Produce json
// @Param id path string true "Process ID"
// @Param domain query string false "Domain to act on"
// @Param X-Cluster-Origin header string false "Origin ID of request"
// @Success 200 {string} string
// @Failure 500 {object} Error
// @Failure 508 {object} Error
// @Router /v1/process/{id} [delete]
func (a *api) RemoveProcess(c echo.Context) error {
id := util.PathParam(c, "id")
domain := util.DefaultQuery(c, "domain", "")
origin := c.Request().Header.Get("X-Cluster-Origin")
if origin == a.id {
return Err(http.StatusLoopDetected, "", "breaking circuit")
}
pid := app.ProcessID{ID: id, Domain: domain}
a.logger.Debug().WithField("id", pid).Log("Remove process request")
err := a.cluster.RemoveProcess(origin, pid)
if err != nil {
a.logger.Debug().WithError(err).WithField("id", pid).Log("Unable to remove process")
return Err(http.StatusInternalServerError, "unable to remove process", "%s", err)
}
return c.JSON(http.StatusOK, "OK")
}
// UpdateProcess replaces an existing process in the cluster DB
// @Summary Replace an existing process
// @Description Replace an existing process in the cluster DB
// @Tags v1.0.0
// @ID cluster-1-update-process
// @Accept json
// @Produce json
// @Param id path string true "Process ID"
// @Param domain query string false "Domain to act on"
// @Param config body client.UpdateProcessRequest true "Process config"
// @Success 200 {string} string
// @Failure 500 {object} Error
// @Failure 508 {object} Error
// @Router /v1/process/{id} [put]
func (a *api) UpdateProcess(c echo.Context) error {
id := util.PathParam(c, "id")
domain := util.DefaultQuery(c, "domain", "")
r := client.UpdateProcessRequest{}
if err := util.ShouldBindJSON(c, &r); err != nil {
return Err(http.StatusBadRequest, "Invalid JSON", "%s", err)
}
origin := c.Request().Header.Get("X-Cluster-Origin")
if origin == a.id {
return Err(http.StatusLoopDetected, "", "breaking circuit")
}
pid := app.ProcessID{ID: id, Domain: domain}
a.logger.Debug().WithFields(log.Fields{
"old_id": pid,
"new_id": r.Config.ProcessID(),
}).Log("Update process request")
err := a.cluster.UpdateProcess(origin, pid, &r.Config)
if err != nil {
a.logger.Debug().WithError(err).WithField("id", pid).Log("Unable to update process")
return Err(http.StatusInternalServerError, "unable to update process", "%s", err)
}
return c.JSON(http.StatusOK, "OK")
}
// SetProcessMetadata stores metadata with a process
// @Summary Add JSON metadata with a process under the given key
// @Description Add arbitrary JSON metadata under the given key. If the key exists, all already stored metadata with this key will be overwritten. If the key doesn't exist, it will be created.
// @Tags v1.0.0
// @ID cluster-3-set-process-metadata
// @Produce json
// @Param id path string true "Process ID"
// @Param key path string true "Key for data store"
// @Param domain query string false "Domain to act on"
// @Param data body client.SetProcessMetadataRequest true "Arbitrary JSON data. The null value will remove the key and its contents"
// @Success 200 {string} string
// @Failure 500 {object} Error
// @Failure 508 {object} Error
// @Router /v1/process/{id}/metadata/{key} [put]
func (a *api) SetProcessMetadata(c echo.Context) error {
id := util.PathParam(c, "id")
key := util.PathParam(c, "key")
domain := util.DefaultQuery(c, "domain", "")
r := client.SetProcessMetadataRequest{}
if err := util.ShouldBindJSON(c, &r); err != nil {
return Err(http.StatusBadRequest, "Invalid JSON", "%s", err)
}
origin := c.Request().Header.Get("X-Cluster-Origin")
if origin == a.id {
return Err(http.StatusLoopDetected, "", "breaking circuit")
}
pid := app.ProcessID{ID: id, Domain: domain}
err := a.cluster.SetProcessMetadata(origin, pid, key, r.Metadata)
if err != nil {
a.logger.Debug().WithError(err).WithField("id", pid).Log("Unable to update metadata")
return Err(http.StatusInternalServerError, "unable to update metadata", "%s", err)
}
return c.JSON(http.StatusOK, "OK")
}
// AddIdentity adds an identity to the cluster DB
// @Summary Add an identity
// @Description Add an identity to the cluster DB
// @Tags v1.0.0
// @ID cluster-1-add-identity
// @Accept json
// @Produce json
// @Param config body client.AddIdentityRequest true "Identity config"
// @Param X-Cluster-Origin header string false "Origin ID of request"
// @Success 200 {string} string
// @Failure 400 {object} Error
// @Failure 500 {object} Error
// @Failure 508 {object} Error
// @Router /v1/iam/user [post]
func (a *api) AddIdentity(c echo.Context) error {
r := client.AddIdentityRequest{}
if err := util.ShouldBindJSON(c, &r); err != nil {
return Err(http.StatusBadRequest, "Invalid JSON", "%s", err)
}
origin := c.Request().Header.Get("X-Cluster-Origin")
if origin == a.id {
return Err(http.StatusLoopDetected, "", "breaking circuit")
}
a.logger.Debug().WithField("identity", r.Identity).Log("Add identity request")
err := a.cluster.AddIdentity(origin, r.Identity)
if err != nil {
a.logger.Debug().WithError(err).WithField("identity", r.Identity).Log("Unable to add identity")
return Err(http.StatusInternalServerError, "unable to add identity", "%s", err)
}
return c.JSON(http.StatusOK, "OK")
}
// UpdateIdentity replaces an existing identity in the cluster DB
// @Summary Replace an existing identity
// @Description Replace an existing identity in the cluster DB
// @Tags v1.0.0
// @ID cluster-1-update-identity
// @Accept json
// @Produce json
// @Param name path string true "Process ID"
// @Param config body client.UpdateIdentityRequest true "Identity config"
// @Success 200 {string} string
// @Failure 500 {object} Error
// @Failure 508 {object} Error
// @Router /v1/iam/user/{name} [put]
func (a *api) UpdateIdentity(c echo.Context) error {
name := util.PathParam(c, "name")
r := client.UpdateIdentityRequest{}
if err := util.ShouldBindJSON(c, &r); err != nil {
return Err(http.StatusBadRequest, "Invalid JSON", "%s", err)
}
origin := c.Request().Header.Get("X-Cluster-Origin")
if origin == a.id {
return Err(http.StatusLoopDetected, "", "breaking circuit")
}
a.logger.Debug().WithFields(log.Fields{
"name": name,
"identity": r.Identity,
}).Log("Update identity request")
err := a.cluster.UpdateIdentity(origin, name, r.Identity)
if err != nil {
a.logger.Debug().WithError(err).WithFields(log.Fields{
"name": name,
"identity": r.Identity,
}).Log("Unable to add identity")
return Err(http.StatusInternalServerError, "unable to update identity", "%s", err)
}
return c.JSON(http.StatusOK, "OK")
}
// SetIdentityPolicies set policies for an identity in the cluster DB
// @Summary Set identity policies
// @Description Set policies for an identity in the cluster DB. Any existing policies will be replaced.
// @Tags v1.0.0
// @ID cluster-3-set-identity-policies
// @Produce json
// @Param id path string true "Process ID"SetPoliciesRequest
// @Param data body client.SetPoliciesRequest true "Policies for that user"
// @Success 200 {string} string
// @Failure 400 {object} Error
// @Failure 500 {object} Error
// @Failure 508 {object} Error
// @Router /v1/iam/user/{name}/policies [put]
func (a *api) SetIdentityPolicies(c echo.Context) error {
name := util.PathParam(c, "name")
r := client.SetPoliciesRequest{}
if err := util.ShouldBindJSON(c, &r); err != nil {
return Err(http.StatusBadRequest, "Invalid JSON", "%s", err)
}
origin := c.Request().Header.Get("X-Cluster-Origin")
if origin == a.id {
return Err(http.StatusLoopDetected, "", "breaking circuit")
}
a.logger.Debug().WithField("policies", r.Policies).Log("Set policiesrequest")
err := a.cluster.SetPolicies(origin, name, r.Policies)
if err != nil {
a.logger.Debug().WithError(err).WithField("policies", r.Policies).Log("Unable to set policies")
return Err(http.StatusInternalServerError, "unable to add identity", "%s", err)
}
return c.JSON(http.StatusOK, "OK")
}
// RemoveIdentity removes an identity from the cluster DB
// @Summary Remove an identity
// @Description Remove an identity from the cluster DB
// @Tags v1.0.0
// @ID cluster-1-remove-identity
// @Produce json
// @Param name path string true "Identity name"
// @Param X-Cluster-Origin header string false "Origin ID of request"
// @Success 200 {string} string
// @Failure 500 {object} Error
// @Failure 508 {object} Error
// @Router /v1/iam/user/{name} [delete]
func (a *api) RemoveIdentity(c echo.Context) error {
name := util.PathParam(c, "name")
origin := c.Request().Header.Get("X-Cluster-Origin")
if origin == a.id {
return Err(http.StatusLoopDetected, "", "breaking circuit")
}
a.logger.Debug().WithField("identity", name).Log("Remove identity request")
err := a.cluster.RemoveIdentity(origin, name)
if err != nil {
a.logger.Debug().WithError(err).WithField("identity", name).Log("Unable to remove identity")
return Err(http.StatusInternalServerError, "unable to remove identity", "%s", err)
}
return c.JSON(http.StatusOK, "OK")
}
// CoreAPIAddress returns the Core API address and login of this node
// @Summary Core API address and login
// @Description Core API address and login of this node
// @Tags v1.0.0
// @ID cluster-1-core-api-address
// @Produce json
// @Success 200 {string} string
// @Success 500 {array} Error
// @Router /v1/core [get]
func (a *api) CoreAPIAddress(c echo.Context) error {
address, _ := a.cluster.CoreAPIAddress("")
return c.JSON(http.StatusOK, address)
}
// Error represents an error response of the API
type Error struct {
Code int `json:"code" jsonschema:"required" format:"int"`
Message string `json:"message" jsonschema:""`
Details []string `json:"details" jsonschema:""`
}
// Error returns the string representation of the error
func (e Error) Error() string {
return fmt.Sprintf("code=%d, message=%s, details=%s", e.Code, e.Message, strings.Join(e.Details, " "))
}
// Err creates a new API error with the given HTTP status code. If message is empty, the default message
// for the given code is used. If the first entry in args is a string, it is interpreted as a format string
// for the remaining entries in args, that is used for fmt.Sprintf. Otherwise the args are ignored.
func Err(code int, message string, args ...interface{}) Error {
if len(message) == 0 {
message = http.StatusText(code)
}
e := Error{
Code: code,
Message: message,
Details: []string{},
}
if len(args) >= 1 {
if format, ok := args[0].(string); ok {
e.Details = strings.Split(fmt.Sprintf(format, args[1:]...), "\n")
}
}
return e
}

View File

@@ -19,22 +19,15 @@ type JoinRequest struct {
RaftAddress string `json:"raft_address"`
}
type LeaveRequest struct {
ID string `json:"id"`
}
type AddProcessRequest struct {
Config app.Config `json:"config"`
}
type UpdateProcessRequest struct {
ID app.ProcessID `json:"id"`
Config app.Config `json:"config"`
}
type SetProcessMetadataRequest struct {
ID app.ProcessID `json:"id"`
Key string `json:"key"`
Metadata interface{} `json:"metadata"`
}
@@ -43,12 +36,10 @@ type AddIdentityRequest struct {
}
type UpdateIdentityRequest struct {
Name string `json:"name"`
Identity iamidentity.User `json:"identity"`
}
type SetPoliciesRequest struct {
Name string `json:"name"`
Policies []iamaccess.Policy `json:"policies"`
}
@@ -106,24 +97,24 @@ func (c *APIClient) RemoveProcess(origin string, id app.ProcessID) error {
return err
}
func (c *APIClient) UpdateProcess(origin string, r UpdateProcessRequest) error {
func (c *APIClient) UpdateProcess(origin string, id app.ProcessID, r UpdateProcessRequest) error {
data, err := json.Marshal(r)
if err != nil {
return err
}
_, err = c.call(http.MethodPut, "/process/"+r.ID.ID+"?domain="+r.ID.Domain, "application/json", bytes.NewReader(data), origin)
_, err = c.call(http.MethodPut, "/process/"+id.ID+"?domain="+id.Domain, "application/json", bytes.NewReader(data), origin)
return err
}
func (c *APIClient) SetProcessMetadata(origin string, r SetProcessMetadataRequest) error {
func (c *APIClient) SetProcessMetadata(origin string, id app.ProcessID, key string, r SetProcessMetadataRequest) error {
data, err := json.Marshal(r)
if err != nil {
return err
}
_, err = c.call(http.MethodPut, "/process/"+r.ID.ID+"/metadata/"+r.Key+"?domain="+r.ID.Domain, "application/json", bytes.NewReader(data), origin)
_, err = c.call(http.MethodPut, "/process/"+id.ID+"/metadata/"+key+"?domain="+id.Domain, "application/json", bytes.NewReader(data), origin)
return err
}

View File

@@ -25,26 +25,6 @@ import (
"github.com/datarhei/core/v16/restream/app"
)
/*
/api/v3:
GET /cluster/store/node - list all nodes that are stored in the FSM - Cluster.Store.ListNodes()
POST /cluster/store/node - add a node to the FSM - Cluster.Store.AddNode()
DELETE /cluster/store/node/:id - remove a node from the FSM - Cluster.Store.RemoveNode()
GET /cluster/store/process - list all process configs that are stored in the FSM - Cluster.Store.ListProcesses()
POST /cluster/store/process - add a process config to the FSM - Cluster.Store.AddProcess()
PUT /cluster/store/process/:id - update a process config in the FSM - Cluster.Store.UpdateProcess()
DELETE /cluster/store/process/:id - remove a process config from the FSM - Cluster.Store.RemoveProcess()
** for the processes, the leader will decide where to actually run them. the process configs will
also be added to the regular process DB of each core.
POST /cluster/join - join the cluster - Cluster.Join()
DELETE /cluster/:id - leave the cluster - Cluster.Leave()
** all these endpoints will forward the request to the leader.
*/
type Cluster interface {
// Address returns the raft address of this node
Address() string

View File

@@ -0,0 +1,961 @@
// Code generated by swaggo/swag. DO NOT EDIT.
package docs
import "github.com/swaggo/swag"
const docTemplateClusterAPI = `{
"schemes": {{ marshal .Schemes }},
"swagger": "2.0",
"info": {
"description": "{{escape .Description}}",
"title": "{{.Title}}",
"contact": {
"name": "datarhei Core Support",
"url": "https://www.datarhei.com",
"email": "hello@datarhei.com"
},
"license": {
"name": "Apache 2.0",
"url": "https://github.com/datarhei/core/v16/blob/main/LICENSE"
},
"version": "{{.Version}}"
},
"host": "{{.Host}}",
"basePath": "{{.BasePath}}",
"paths": {
"/v1/core": {
"get": {
"description": "Core API address and login of this node",
"produces": [
"application/json"
],
"tags": [
"v1.0.0"
],
"summary": "Core API address and login",
"operationId": "cluster-1-core-api-address",
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "string"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/cluster.Error"
}
}
}
}
}
},
"/v1/iam/user": {
"post": {
"description": "Add an identity to the cluster DB",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"v1.0.0"
],
"summary": "Add an identity",
"operationId": "cluster-1-add-identity",
"parameters": [
{
"description": "Identity config",
"name": "config",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/client.AddIdentityRequest"
}
},
{
"type": "string",
"description": "Origin ID of request",
"name": "X-Cluster-Origin",
"in": "header"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "string"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/cluster.Error"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/cluster.Error"
}
},
"508": {
"description": "Loop Detected",
"schema": {
"$ref": "#/definitions/cluster.Error"
}
}
}
}
},
"/v1/iam/user/{name}": {
"put": {
"description": "Replace an existing identity in the cluster DB",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"v1.0.0"
],
"summary": "Replace an existing identity",
"operationId": "cluster-1-update-identity",
"parameters": [
{
"type": "string",
"description": "Process ID",
"name": "name",
"in": "path",
"required": true
},
{
"description": "Identity config",
"name": "config",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/client.UpdateIdentityRequest"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "string"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/cluster.Error"
}
},
"508": {
"description": "Loop Detected",
"schema": {
"$ref": "#/definitions/cluster.Error"
}
}
}
},
"delete": {
"description": "Remove an identity from the cluster DB",
"produces": [
"application/json"
],
"tags": [
"v1.0.0"
],
"summary": "Remove an identity",
"operationId": "cluster-1-remove-identity",
"parameters": [
{
"type": "string",
"description": "Identity name",
"name": "name",
"in": "path",
"required": true
},
{
"type": "string",
"description": "Origin ID of request",
"name": "X-Cluster-Origin",
"in": "header"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "string"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/cluster.Error"
}
},
"508": {
"description": "Loop Detected",
"schema": {
"$ref": "#/definitions/cluster.Error"
}
}
}
}
},
"/v1/iam/user/{name}/policies": {
"put": {
"description": "Set policies for an identity in the cluster DB. Any existing policies will be replaced.",
"produces": [
"application/json"
],
"tags": [
"v1.0.0"
],
"summary": "Set identity policies",
"operationId": "cluster-3-set-identity-policies",
"parameters": [
{
"type": "string",
"description": "Process ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Policies for that user",
"name": "data",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/client.SetPoliciesRequest"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "string"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/cluster.Error"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/cluster.Error"
}
},
"508": {
"description": "Loop Detected",
"schema": {
"$ref": "#/definitions/cluster.Error"
}
}
}
}
},
"/v1/process": {
"post": {
"description": "Add a process to the cluster DB",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"v1.0.0"
],
"summary": "Add a process",
"operationId": "cluster-1-add-process",
"parameters": [
{
"description": "Process config",
"name": "config",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/client.AddProcessRequest"
}
},
{
"type": "string",
"description": "Origin ID of request",
"name": "X-Cluster-Origin",
"in": "header"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "string"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/cluster.Error"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/cluster.Error"
}
},
"508": {
"description": "Loop Detected",
"schema": {
"$ref": "#/definitions/cluster.Error"
}
}
}
}
},
"/v1/process/{id}": {
"put": {
"description": "Replace an existing process in the cluster DB",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"v1.0.0"
],
"summary": "Replace an existing process",
"operationId": "cluster-1-update-process",
"parameters": [
{
"type": "string",
"description": "Process ID",
"name": "id",
"in": "path",
"required": true
},
{
"type": "string",
"description": "Domain to act on",
"name": "domain",
"in": "query"
},
{
"description": "Process config",
"name": "config",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/client.UpdateProcessRequest"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "string"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/cluster.Error"
}
},
"508": {
"description": "Loop Detected",
"schema": {
"$ref": "#/definitions/cluster.Error"
}
}
}
},
"delete": {
"description": "Remove a process from the cluster DB",
"produces": [
"application/json"
],
"tags": [
"v1.0.0"
],
"summary": "Remove a process",
"operationId": "cluster-1-remove-process",
"parameters": [
{
"type": "string",
"description": "Process ID",
"name": "id",
"in": "path",
"required": true
},
{
"type": "string",
"description": "Domain to act on",
"name": "domain",
"in": "query"
},
{
"type": "string",
"description": "Origin ID of request",
"name": "X-Cluster-Origin",
"in": "header"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "string"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/cluster.Error"
}
},
"508": {
"description": "Loop Detected",
"schema": {
"$ref": "#/definitions/cluster.Error"
}
}
}
}
},
"/v1/process/{id}/metadata/{key}": {
"put": {
"description": "Add arbitrary JSON metadata under the given key. If the key exists, all already stored metadata with this key will be overwritten. If the key doesn't exist, it will be created.",
"produces": [
"application/json"
],
"tags": [
"v1.0.0"
],
"summary": "Add JSON metadata with a process under the given key",
"operationId": "cluster-3-set-process-metadata",
"parameters": [
{
"type": "string",
"description": "Process ID",
"name": "id",
"in": "path",
"required": true
},
{
"type": "string",
"description": "Key for data store",
"name": "key",
"in": "path",
"required": true
},
{
"type": "string",
"description": "Domain to act on",
"name": "domain",
"in": "query"
},
{
"description": "Arbitrary JSON data. The null value will remove the key and its contents",
"name": "data",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/client.SetProcessMetadataRequest"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "string"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/cluster.Error"
}
},
"508": {
"description": "Loop Detected",
"schema": {
"$ref": "#/definitions/cluster.Error"
}
}
}
}
},
"/v1/server": {
"post": {
"description": "Add a new server to the cluster",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"v1.0.0"
],
"summary": "Add a new server",
"operationId": "cluster-1-add-server",
"parameters": [
{
"description": "Server ID and address",
"name": "config",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/client.JoinRequest"
}
},
{
"type": "string",
"description": "Origin ID of request",
"name": "X-Cluster-Origin",
"in": "header"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "string"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/cluster.Error"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/cluster.Error"
}
},
"508": {
"description": "Loop Detected",
"schema": {
"$ref": "#/definitions/cluster.Error"
}
}
}
}
},
"/v1/server/{id}": {
"delete": {
"description": "Remove a server from the cluster",
"produces": [
"application/json"
],
"tags": [
"v1.0.0"
],
"summary": "Remove a server",
"operationId": "cluster-1-remove-server",
"parameters": [
{
"type": "string",
"description": "Server ID",
"name": "id",
"in": "path",
"required": true
},
{
"type": "string",
"description": "Origin ID of request",
"name": "X-Cluster-Origin",
"in": "header"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "string"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/cluster.Error"
}
},
"508": {
"description": "Loop Detected",
"schema": {
"$ref": "#/definitions/cluster.Error"
}
}
}
}
},
"/v1/snapshot": {
"get": {
"description": "Current snapshot of the clusterDB",
"produces": [
"application/octet-stream"
],
"tags": [
"v1.0.0"
],
"summary": "Cluster DB snapshot",
"operationId": "cluster-1-snapshot",
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "file"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/cluster.Error"
}
}
}
}
}
}
},
"definitions": {
"access.Policy": {
"type": "object",
"properties": {
"actions": {
"type": "array",
"items": {
"type": "string"
}
},
"domain": {
"type": "string"
},
"name": {
"type": "string"
},
"resource": {
"type": "string"
}
}
},
"app.Config": {
"type": "object",
"properties": {
"autostart": {
"type": "boolean"
},
"domain": {
"type": "string"
},
"ffversion": {
"type": "string"
},
"id": {
"type": "string"
},
"input": {
"type": "array",
"items": {
"$ref": "#/definitions/app.ConfigIO"
}
},
"limitCPU": {
"description": "percent",
"type": "number"
},
"limitMemory": {
"description": "bytes",
"type": "integer"
},
"limitWaitFor": {
"description": "seconds",
"type": "integer"
},
"logPatterns": {
"description": "will we interpreted as regualr expressions",
"type": "array",
"items": {
"type": "string"
}
},
"options": {
"type": "array",
"items": {
"type": "string"
}
},
"output": {
"type": "array",
"items": {
"$ref": "#/definitions/app.ConfigIO"
}
},
"owner": {
"type": "string"
},
"reconnect": {
"type": "boolean"
},
"reconnectDelay": {
"description": "seconds",
"type": "integer"
},
"reference": {
"type": "string"
},
"scheduler": {
"description": "crontab pattern or RFC3339 timestamp",
"type": "string"
},
"staleTimeout": {
"description": "seconds",
"type": "integer"
},
"timeout": {
"description": "seconds",
"type": "integer"
}
}
},
"app.ConfigIO": {
"type": "object",
"properties": {
"address": {
"type": "string"
},
"cleanup": {
"type": "array",
"items": {
"$ref": "#/definitions/app.ConfigIOCleanup"
}
},
"id": {
"type": "string"
},
"options": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"app.ConfigIOCleanup": {
"type": "object",
"properties": {
"maxFileAge": {
"type": "integer"
},
"maxFiles": {
"type": "integer"
},
"pattern": {
"type": "string"
},
"purgeOnDelete": {
"type": "boolean"
}
}
},
"client.AddIdentityRequest": {
"type": "object",
"properties": {
"identity": {
"$ref": "#/definitions/identity.User"
}
}
},
"client.AddProcessRequest": {
"type": "object",
"properties": {
"config": {
"$ref": "#/definitions/app.Config"
}
}
},
"client.JoinRequest": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"raft_address": {
"type": "string"
}
}
},
"client.SetPoliciesRequest": {
"type": "object",
"properties": {
"policies": {
"type": "array",
"items": {
"$ref": "#/definitions/access.Policy"
}
}
}
},
"client.SetProcessMetadataRequest": {
"type": "object",
"properties": {
"metadata": {}
}
},
"client.UpdateIdentityRequest": {
"type": "object",
"properties": {
"identity": {
"$ref": "#/definitions/identity.User"
}
}
},
"client.UpdateProcessRequest": {
"type": "object",
"properties": {
"config": {
"$ref": "#/definitions/app.Config"
}
}
},
"cluster.Error": {
"type": "object",
"properties": {
"code": {
"type": "integer",
"format": "int"
},
"details": {
"type": "array",
"items": {
"type": "string"
}
},
"message": {
"type": "string"
}
}
},
"identity.Auth0Tenant": {
"type": "object",
"properties": {
"audience": {
"type": "string"
},
"client_id": {
"type": "string"
},
"domain": {
"type": "string"
}
}
},
"identity.User": {
"type": "object",
"properties": {
"auth": {
"$ref": "#/definitions/identity.UserAuth"
},
"name": {
"type": "string"
},
"superuser": {
"type": "boolean"
}
}
},
"identity.UserAuth": {
"type": "object",
"properties": {
"api": {
"$ref": "#/definitions/identity.UserAuthAPI"
},
"services": {
"$ref": "#/definitions/identity.UserAuthServices"
}
}
},
"identity.UserAuthAPI": {
"type": "object",
"properties": {
"auth0": {
"$ref": "#/definitions/identity.UserAuthAPIAuth0"
},
"password": {
"type": "string"
}
}
},
"identity.UserAuthAPIAuth0": {
"type": "object",
"properties": {
"tenant": {
"$ref": "#/definitions/identity.Auth0Tenant"
},
"user": {
"type": "string"
}
}
},
"identity.UserAuthServices": {
"type": "object",
"properties": {
"basic": {
"type": "array",
"items": {
"type": "string"
}
},
"token": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
}`
// SwaggerInfoClusterAPI holds exported Swagger Info so clients can modify it
var SwaggerInfoClusterAPI = &swag.Spec{
Version: "1.0",
Host: "",
BasePath: "/",
Schemes: []string{},
Title: "datarhei Core Cluster API",
Description: "Internal REST API for the datarhei Core cluster",
InfoInstanceName: "ClusterAPI",
SwaggerTemplate: docTemplateClusterAPI,
LeftDelim: "{{",
RightDelim: "}}",
}
func init() {
swag.Register(SwaggerInfoClusterAPI.InstanceName(), SwaggerInfoClusterAPI)
}

View File

@@ -0,0 +1,935 @@
{
"swagger": "2.0",
"info": {
"description": "Internal REST API for the datarhei Core cluster",
"title": "datarhei Core Cluster API",
"contact": {
"name": "datarhei Core Support",
"url": "https://www.datarhei.com",
"email": "hello@datarhei.com"
},
"license": {
"name": "Apache 2.0",
"url": "https://github.com/datarhei/core/v16/blob/main/LICENSE"
},
"version": "1.0"
},
"basePath": "/",
"paths": {
"/v1/core": {
"get": {
"description": "Core API address and login of this node",
"produces": [
"application/json"
],
"tags": [
"v1.0.0"
],
"summary": "Core API address and login",
"operationId": "cluster-1-core-api-address",
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "string"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/cluster.Error"
}
}
}
}
}
},
"/v1/iam/user": {
"post": {
"description": "Add an identity to the cluster DB",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"v1.0.0"
],
"summary": "Add an identity",
"operationId": "cluster-1-add-identity",
"parameters": [
{
"description": "Identity config",
"name": "config",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/client.AddIdentityRequest"
}
},
{
"type": "string",
"description": "Origin ID of request",
"name": "X-Cluster-Origin",
"in": "header"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "string"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/cluster.Error"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/cluster.Error"
}
},
"508": {
"description": "Loop Detected",
"schema": {
"$ref": "#/definitions/cluster.Error"
}
}
}
}
},
"/v1/iam/user/{name}": {
"put": {
"description": "Replace an existing identity in the cluster DB",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"v1.0.0"
],
"summary": "Replace an existing identity",
"operationId": "cluster-1-update-identity",
"parameters": [
{
"type": "string",
"description": "Process ID",
"name": "name",
"in": "path",
"required": true
},
{
"description": "Identity config",
"name": "config",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/client.UpdateIdentityRequest"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "string"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/cluster.Error"
}
},
"508": {
"description": "Loop Detected",
"schema": {
"$ref": "#/definitions/cluster.Error"
}
}
}
},
"delete": {
"description": "Remove an identity from the cluster DB",
"produces": [
"application/json"
],
"tags": [
"v1.0.0"
],
"summary": "Remove an identity",
"operationId": "cluster-1-remove-identity",
"parameters": [
{
"type": "string",
"description": "Identity name",
"name": "name",
"in": "path",
"required": true
},
{
"type": "string",
"description": "Origin ID of request",
"name": "X-Cluster-Origin",
"in": "header"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "string"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/cluster.Error"
}
},
"508": {
"description": "Loop Detected",
"schema": {
"$ref": "#/definitions/cluster.Error"
}
}
}
}
},
"/v1/iam/user/{name}/policies": {
"put": {
"description": "Set policies for an identity in the cluster DB. Any existing policies will be replaced.",
"produces": [
"application/json"
],
"tags": [
"v1.0.0"
],
"summary": "Set identity policies",
"operationId": "cluster-3-set-identity-policies",
"parameters": [
{
"type": "string",
"description": "Process ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Policies for that user",
"name": "data",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/client.SetPoliciesRequest"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "string"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/cluster.Error"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/cluster.Error"
}
},
"508": {
"description": "Loop Detected",
"schema": {
"$ref": "#/definitions/cluster.Error"
}
}
}
}
},
"/v1/process": {
"post": {
"description": "Add a process to the cluster DB",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"v1.0.0"
],
"summary": "Add a process",
"operationId": "cluster-1-add-process",
"parameters": [
{
"description": "Process config",
"name": "config",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/client.AddProcessRequest"
}
},
{
"type": "string",
"description": "Origin ID of request",
"name": "X-Cluster-Origin",
"in": "header"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "string"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/cluster.Error"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/cluster.Error"
}
},
"508": {
"description": "Loop Detected",
"schema": {
"$ref": "#/definitions/cluster.Error"
}
}
}
}
},
"/v1/process/{id}": {
"put": {
"description": "Replace an existing process in the cluster DB",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"v1.0.0"
],
"summary": "Replace an existing process",
"operationId": "cluster-1-update-process",
"parameters": [
{
"type": "string",
"description": "Process ID",
"name": "id",
"in": "path",
"required": true
},
{
"type": "string",
"description": "Domain to act on",
"name": "domain",
"in": "query"
},
{
"description": "Process config",
"name": "config",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/client.UpdateProcessRequest"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "string"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/cluster.Error"
}
},
"508": {
"description": "Loop Detected",
"schema": {
"$ref": "#/definitions/cluster.Error"
}
}
}
},
"delete": {
"description": "Remove a process from the cluster DB",
"produces": [
"application/json"
],
"tags": [
"v1.0.0"
],
"summary": "Remove a process",
"operationId": "cluster-1-remove-process",
"parameters": [
{
"type": "string",
"description": "Process ID",
"name": "id",
"in": "path",
"required": true
},
{
"type": "string",
"description": "Domain to act on",
"name": "domain",
"in": "query"
},
{
"type": "string",
"description": "Origin ID of request",
"name": "X-Cluster-Origin",
"in": "header"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "string"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/cluster.Error"
}
},
"508": {
"description": "Loop Detected",
"schema": {
"$ref": "#/definitions/cluster.Error"
}
}
}
}
},
"/v1/process/{id}/metadata/{key}": {
"put": {
"description": "Add arbitrary JSON metadata under the given key. If the key exists, all already stored metadata with this key will be overwritten. If the key doesn't exist, it will be created.",
"produces": [
"application/json"
],
"tags": [
"v1.0.0"
],
"summary": "Add JSON metadata with a process under the given key",
"operationId": "cluster-3-set-process-metadata",
"parameters": [
{
"type": "string",
"description": "Process ID",
"name": "id",
"in": "path",
"required": true
},
{
"type": "string",
"description": "Key for data store",
"name": "key",
"in": "path",
"required": true
},
{
"type": "string",
"description": "Domain to act on",
"name": "domain",
"in": "query"
},
{
"description": "Arbitrary JSON data. The null value will remove the key and its contents",
"name": "data",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/client.SetProcessMetadataRequest"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "string"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/cluster.Error"
}
},
"508": {
"description": "Loop Detected",
"schema": {
"$ref": "#/definitions/cluster.Error"
}
}
}
}
},
"/v1/server": {
"post": {
"description": "Add a new server to the cluster",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"v1.0.0"
],
"summary": "Add a new server",
"operationId": "cluster-1-add-server",
"parameters": [
{
"description": "Server ID and address",
"name": "config",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/client.JoinRequest"
}
},
{
"type": "string",
"description": "Origin ID of request",
"name": "X-Cluster-Origin",
"in": "header"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "string"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/cluster.Error"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/cluster.Error"
}
},
"508": {
"description": "Loop Detected",
"schema": {
"$ref": "#/definitions/cluster.Error"
}
}
}
}
},
"/v1/server/{id}": {
"delete": {
"description": "Remove a server from the cluster",
"produces": [
"application/json"
],
"tags": [
"v1.0.0"
],
"summary": "Remove a server",
"operationId": "cluster-1-remove-server",
"parameters": [
{
"type": "string",
"description": "Server ID",
"name": "id",
"in": "path",
"required": true
},
{
"type": "string",
"description": "Origin ID of request",
"name": "X-Cluster-Origin",
"in": "header"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "string"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/cluster.Error"
}
},
"508": {
"description": "Loop Detected",
"schema": {
"$ref": "#/definitions/cluster.Error"
}
}
}
}
},
"/v1/snapshot": {
"get": {
"description": "Current snapshot of the clusterDB",
"produces": [
"application/octet-stream"
],
"tags": [
"v1.0.0"
],
"summary": "Cluster DB snapshot",
"operationId": "cluster-1-snapshot",
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "file"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/cluster.Error"
}
}
}
}
}
}
},
"definitions": {
"access.Policy": {
"type": "object",
"properties": {
"actions": {
"type": "array",
"items": {
"type": "string"
}
},
"domain": {
"type": "string"
},
"name": {
"type": "string"
},
"resource": {
"type": "string"
}
}
},
"app.Config": {
"type": "object",
"properties": {
"autostart": {
"type": "boolean"
},
"domain": {
"type": "string"
},
"ffversion": {
"type": "string"
},
"id": {
"type": "string"
},
"input": {
"type": "array",
"items": {
"$ref": "#/definitions/app.ConfigIO"
}
},
"limitCPU": {
"description": "percent",
"type": "number"
},
"limitMemory": {
"description": "bytes",
"type": "integer"
},
"limitWaitFor": {
"description": "seconds",
"type": "integer"
},
"logPatterns": {
"description": "will we interpreted as regualr expressions",
"type": "array",
"items": {
"type": "string"
}
},
"options": {
"type": "array",
"items": {
"type": "string"
}
},
"output": {
"type": "array",
"items": {
"$ref": "#/definitions/app.ConfigIO"
}
},
"owner": {
"type": "string"
},
"reconnect": {
"type": "boolean"
},
"reconnectDelay": {
"description": "seconds",
"type": "integer"
},
"reference": {
"type": "string"
},
"scheduler": {
"description": "crontab pattern or RFC3339 timestamp",
"type": "string"
},
"staleTimeout": {
"description": "seconds",
"type": "integer"
},
"timeout": {
"description": "seconds",
"type": "integer"
}
}
},
"app.ConfigIO": {
"type": "object",
"properties": {
"address": {
"type": "string"
},
"cleanup": {
"type": "array",
"items": {
"$ref": "#/definitions/app.ConfigIOCleanup"
}
},
"id": {
"type": "string"
},
"options": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"app.ConfigIOCleanup": {
"type": "object",
"properties": {
"maxFileAge": {
"type": "integer"
},
"maxFiles": {
"type": "integer"
},
"pattern": {
"type": "string"
},
"purgeOnDelete": {
"type": "boolean"
}
}
},
"client.AddIdentityRequest": {
"type": "object",
"properties": {
"identity": {
"$ref": "#/definitions/identity.User"
}
}
},
"client.AddProcessRequest": {
"type": "object",
"properties": {
"config": {
"$ref": "#/definitions/app.Config"
}
}
},
"client.JoinRequest": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"raft_address": {
"type": "string"
}
}
},
"client.SetPoliciesRequest": {
"type": "object",
"properties": {
"policies": {
"type": "array",
"items": {
"$ref": "#/definitions/access.Policy"
}
}
}
},
"client.SetProcessMetadataRequest": {
"type": "object",
"properties": {
"metadata": {}
}
},
"client.UpdateIdentityRequest": {
"type": "object",
"properties": {
"identity": {
"$ref": "#/definitions/identity.User"
}
}
},
"client.UpdateProcessRequest": {
"type": "object",
"properties": {
"config": {
"$ref": "#/definitions/app.Config"
}
}
},
"cluster.Error": {
"type": "object",
"properties": {
"code": {
"type": "integer",
"format": "int"
},
"details": {
"type": "array",
"items": {
"type": "string"
}
},
"message": {
"type": "string"
}
}
},
"identity.Auth0Tenant": {
"type": "object",
"properties": {
"audience": {
"type": "string"
},
"client_id": {
"type": "string"
},
"domain": {
"type": "string"
}
}
},
"identity.User": {
"type": "object",
"properties": {
"auth": {
"$ref": "#/definitions/identity.UserAuth"
},
"name": {
"type": "string"
},
"superuser": {
"type": "boolean"
}
}
},
"identity.UserAuth": {
"type": "object",
"properties": {
"api": {
"$ref": "#/definitions/identity.UserAuthAPI"
},
"services": {
"$ref": "#/definitions/identity.UserAuthServices"
}
}
},
"identity.UserAuthAPI": {
"type": "object",
"properties": {
"auth0": {
"$ref": "#/definitions/identity.UserAuthAPIAuth0"
},
"password": {
"type": "string"
}
}
},
"identity.UserAuthAPIAuth0": {
"type": "object",
"properties": {
"tenant": {
"$ref": "#/definitions/identity.Auth0Tenant"
},
"user": {
"type": "string"
}
}
},
"identity.UserAuthServices": {
"type": "object",
"properties": {
"basic": {
"type": "array",
"items": {
"type": "string"
}
},
"token": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
}

View File

@@ -0,0 +1,625 @@
basePath: /
definitions:
access.Policy:
properties:
actions:
items:
type: string
type: array
domain:
type: string
name:
type: string
resource:
type: string
type: object
app.Config:
properties:
autostart:
type: boolean
domain:
type: string
ffversion:
type: string
id:
type: string
input:
items:
$ref: '#/definitions/app.ConfigIO'
type: array
limitCPU:
description: percent
type: number
limitMemory:
description: bytes
type: integer
limitWaitFor:
description: seconds
type: integer
logPatterns:
description: will we interpreted as regualr expressions
items:
type: string
type: array
options:
items:
type: string
type: array
output:
items:
$ref: '#/definitions/app.ConfigIO'
type: array
owner:
type: string
reconnect:
type: boolean
reconnectDelay:
description: seconds
type: integer
reference:
type: string
scheduler:
description: crontab pattern or RFC3339 timestamp
type: string
staleTimeout:
description: seconds
type: integer
timeout:
description: seconds
type: integer
type: object
app.ConfigIO:
properties:
address:
type: string
cleanup:
items:
$ref: '#/definitions/app.ConfigIOCleanup'
type: array
id:
type: string
options:
items:
type: string
type: array
type: object
app.ConfigIOCleanup:
properties:
maxFileAge:
type: integer
maxFiles:
type: integer
pattern:
type: string
purgeOnDelete:
type: boolean
type: object
client.AddIdentityRequest:
properties:
identity:
$ref: '#/definitions/identity.User'
type: object
client.AddProcessRequest:
properties:
config:
$ref: '#/definitions/app.Config'
type: object
client.JoinRequest:
properties:
id:
type: string
raft_address:
type: string
type: object
client.SetPoliciesRequest:
properties:
policies:
items:
$ref: '#/definitions/access.Policy'
type: array
type: object
client.SetProcessMetadataRequest:
properties:
metadata: {}
type: object
client.UpdateIdentityRequest:
properties:
identity:
$ref: '#/definitions/identity.User'
type: object
client.UpdateProcessRequest:
properties:
config:
$ref: '#/definitions/app.Config'
type: object
cluster.Error:
properties:
code:
format: int
type: integer
details:
items:
type: string
type: array
message:
type: string
type: object
identity.Auth0Tenant:
properties:
audience:
type: string
client_id:
type: string
domain:
type: string
type: object
identity.User:
properties:
auth:
$ref: '#/definitions/identity.UserAuth'
name:
type: string
superuser:
type: boolean
type: object
identity.UserAuth:
properties:
api:
$ref: '#/definitions/identity.UserAuthAPI'
services:
$ref: '#/definitions/identity.UserAuthServices'
type: object
identity.UserAuthAPI:
properties:
auth0:
$ref: '#/definitions/identity.UserAuthAPIAuth0'
password:
type: string
type: object
identity.UserAuthAPIAuth0:
properties:
tenant:
$ref: '#/definitions/identity.Auth0Tenant'
user:
type: string
type: object
identity.UserAuthServices:
properties:
basic:
items:
type: string
type: array
token:
items:
type: string
type: array
type: object
info:
contact:
email: hello@datarhei.com
name: datarhei Core Support
url: https://www.datarhei.com
description: Internal REST API for the datarhei Core cluster
license:
name: Apache 2.0
url: https://github.com/datarhei/core/v16/blob/main/LICENSE
title: datarhei Core Cluster API
version: "1.0"
paths:
/v1/core:
get:
description: Core API address and login of this node
operationId: cluster-1-core-api-address
produces:
- application/json
responses:
"200":
description: OK
schema:
type: string
"500":
description: Internal Server Error
schema:
items:
$ref: '#/definitions/cluster.Error'
type: array
summary: Core API address and login
tags:
- v1.0.0
/v1/iam/user:
post:
consumes:
- application/json
description: Add an identity to the cluster DB
operationId: cluster-1-add-identity
parameters:
- description: Identity config
in: body
name: config
required: true
schema:
$ref: '#/definitions/client.AddIdentityRequest'
- description: Origin ID of request
in: header
name: X-Cluster-Origin
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
type: string
"400":
description: Bad Request
schema:
$ref: '#/definitions/cluster.Error'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/cluster.Error'
"508":
description: Loop Detected
schema:
$ref: '#/definitions/cluster.Error'
summary: Add an identity
tags:
- v1.0.0
/v1/iam/user/{name}:
delete:
description: Remove an identity from the cluster DB
operationId: cluster-1-remove-identity
parameters:
- description: Identity name
in: path
name: name
required: true
type: string
- description: Origin ID of request
in: header
name: X-Cluster-Origin
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
type: string
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/cluster.Error'
"508":
description: Loop Detected
schema:
$ref: '#/definitions/cluster.Error'
summary: Remove an identity
tags:
- v1.0.0
put:
consumes:
- application/json
description: Replace an existing identity in the cluster DB
operationId: cluster-1-update-identity
parameters:
- description: Process ID
in: path
name: name
required: true
type: string
- description: Identity config
in: body
name: config
required: true
schema:
$ref: '#/definitions/client.UpdateIdentityRequest'
produces:
- application/json
responses:
"200":
description: OK
schema:
type: string
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/cluster.Error'
"508":
description: Loop Detected
schema:
$ref: '#/definitions/cluster.Error'
summary: Replace an existing identity
tags:
- v1.0.0
/v1/iam/user/{name}/policies:
put:
description: Set policies for an identity in the cluster DB. Any existing policies
will be replaced.
operationId: cluster-3-set-identity-policies
parameters:
- description: Process ID
in: path
name: id
required: true
type: string
- description: Policies for that user
in: body
name: data
required: true
schema:
$ref: '#/definitions/client.SetPoliciesRequest'
produces:
- application/json
responses:
"200":
description: OK
schema:
type: string
"400":
description: Bad Request
schema:
$ref: '#/definitions/cluster.Error'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/cluster.Error'
"508":
description: Loop Detected
schema:
$ref: '#/definitions/cluster.Error'
summary: Set identity policies
tags:
- v1.0.0
/v1/process:
post:
consumes:
- application/json
description: Add a process to the cluster DB
operationId: cluster-1-add-process
parameters:
- description: Process config
in: body
name: config
required: true
schema:
$ref: '#/definitions/client.AddProcessRequest'
- description: Origin ID of request
in: header
name: X-Cluster-Origin
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
type: string
"400":
description: Bad Request
schema:
$ref: '#/definitions/cluster.Error'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/cluster.Error'
"508":
description: Loop Detected
schema:
$ref: '#/definitions/cluster.Error'
summary: Add a process
tags:
- v1.0.0
/v1/process/{id}:
delete:
description: Remove a process from the cluster DB
operationId: cluster-1-remove-process
parameters:
- description: Process ID
in: path
name: id
required: true
type: string
- description: Domain to act on
in: query
name: domain
type: string
- description: Origin ID of request
in: header
name: X-Cluster-Origin
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
type: string
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/cluster.Error'
"508":
description: Loop Detected
schema:
$ref: '#/definitions/cluster.Error'
summary: Remove a process
tags:
- v1.0.0
put:
consumes:
- application/json
description: Replace an existing process in the cluster DB
operationId: cluster-1-update-process
parameters:
- description: Process ID
in: path
name: id
required: true
type: string
- description: Domain to act on
in: query
name: domain
type: string
- description: Process config
in: body
name: config
required: true
schema:
$ref: '#/definitions/client.UpdateProcessRequest'
produces:
- application/json
responses:
"200":
description: OK
schema:
type: string
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/cluster.Error'
"508":
description: Loop Detected
schema:
$ref: '#/definitions/cluster.Error'
summary: Replace an existing process
tags:
- v1.0.0
/v1/process/{id}/metadata/{key}:
put:
description: Add arbitrary JSON metadata under the given key. If the key exists,
all already stored metadata with this key will be overwritten. If the key
doesn't exist, it will be created.
operationId: cluster-3-set-process-metadata
parameters:
- description: Process ID
in: path
name: id
required: true
type: string
- description: Key for data store
in: path
name: key
required: true
type: string
- description: Domain to act on
in: query
name: domain
type: string
- description: Arbitrary JSON data. The null value will remove the key and its
contents
in: body
name: data
required: true
schema:
$ref: '#/definitions/client.SetProcessMetadataRequest'
produces:
- application/json
responses:
"200":
description: OK
schema:
type: string
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/cluster.Error'
"508":
description: Loop Detected
schema:
$ref: '#/definitions/cluster.Error'
summary: Add JSON metadata with a process under the given key
tags:
- v1.0.0
/v1/server:
post:
consumes:
- application/json
description: Add a new server to the cluster
operationId: cluster-1-add-server
parameters:
- description: Server ID and address
in: body
name: config
required: true
schema:
$ref: '#/definitions/client.JoinRequest'
- description: Origin ID of request
in: header
name: X-Cluster-Origin
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
type: string
"400":
description: Bad Request
schema:
$ref: '#/definitions/cluster.Error'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/cluster.Error'
"508":
description: Loop Detected
schema:
$ref: '#/definitions/cluster.Error'
summary: Add a new server
tags:
- v1.0.0
/v1/server/{id}:
delete:
description: Remove a server from the cluster
operationId: cluster-1-remove-server
parameters:
- description: Server ID
in: path
name: id
required: true
type: string
- description: Origin ID of request
in: header
name: X-Cluster-Origin
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
type: string
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/cluster.Error'
"508":
description: Loop Detected
schema:
$ref: '#/definitions/cluster.Error'
summary: Remove a server
tags:
- v1.0.0
/v1/snapshot:
get:
description: Current snapshot of the clusterDB
operationId: cluster-1-snapshot
produces:
- application/octet-stream
responses:
"200":
description: OK
schema:
type: file
"500":
description: Internal Server Error
schema:
items:
$ref: '#/definitions/cluster.Error'
type: array
summary: Cluster DB snapshot
tags:
- v1.0.0
swagger: "2.0"

View File

@@ -161,7 +161,6 @@ func (f *forwarder) UpdateProcess(origin string, id app.ProcessID, config *app.C
}
r := apiclient.UpdateProcessRequest{
ID: id,
Config: *config,
}
@@ -169,7 +168,7 @@ func (f *forwarder) UpdateProcess(origin string, id app.ProcessID, config *app.C
client := f.client
f.lock.RUnlock()
return client.UpdateProcess(origin, r)
return client.UpdateProcess(origin, id, r)
}
func (f *forwarder) SetProcessMetadata(origin string, id app.ProcessID, key string, data interface{}) error {
@@ -178,8 +177,6 @@ func (f *forwarder) SetProcessMetadata(origin string, id app.ProcessID, key stri
}
r := apiclient.SetProcessMetadataRequest{
ID: id,
Key: key,
Metadata: data,
}
@@ -187,7 +184,7 @@ func (f *forwarder) SetProcessMetadata(origin string, id app.ProcessID, key stri
client := f.client
f.lock.RUnlock()
return client.SetProcessMetadata(origin, r)
return client.SetProcessMetadata(origin, id, key, r)
}
func (f *forwarder) RemoveProcess(origin string, id app.ProcessID) error {
@@ -224,7 +221,6 @@ func (f *forwarder) UpdateIdentity(origin, name string, identity iamidentity.Use
}
r := apiclient.UpdateIdentityRequest{
Name: name,
Identity: identity,
}
@@ -241,7 +237,6 @@ func (f *forwarder) SetPolicies(origin, name string, policies []iamaccess.Policy
}
r := apiclient.SetPoliciesRequest{
Name: name,
Policies: policies,
}