mirror of
https://github.com/datarhei/core.git
synced 2025-10-04 23:53:12 +08:00
Enforce policies
This commit is contained in:
@@ -236,7 +236,41 @@ func NewAPI(config APIConfig) (API, error) {
|
|||||||
return c.JSON(http.StatusOK, "OK")
|
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 {
|
a.router.PUT("/v1/iam/user/:name/policies", func(c echo.Context) error {
|
||||||
|
name := util.PathParam(c, "name")
|
||||||
|
|
||||||
r := client.SetPoliciesRequest{}
|
r := client.SetPoliciesRequest{}
|
||||||
|
|
||||||
if err := util.ShouldBindJSON(c, &r); err != nil {
|
if err := util.ShouldBindJSON(c, &r); err != nil {
|
||||||
@@ -251,7 +285,7 @@ func NewAPI(config APIConfig) (API, error) {
|
|||||||
|
|
||||||
a.logger.Debug().WithField("policies", r.Policies).Log("Set policiesrequest")
|
a.logger.Debug().WithField("policies", r.Policies).Log("Set policiesrequest")
|
||||||
|
|
||||||
err = a.cluster.SetPolicies(origin, r.Name, r.Policies)
|
err = a.cluster.SetPolicies(origin, name, r.Policies)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
a.logger.Debug().WithError(err).WithField("policies", r.Policies).Log("Unable to set policies")
|
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 httpapi.Err(http.StatusInternalServerError, "unable to add identity", "%s", err)
|
||||||
|
@@ -36,6 +36,11 @@ type AddIdentityRequest struct {
|
|||||||
Identity iamidentity.User `json:"identity"`
|
Identity iamidentity.User `json:"identity"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type UpdateIdentityRequest struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Identity iamidentity.User `json:"identity"`
|
||||||
|
}
|
||||||
|
|
||||||
type SetPoliciesRequest struct {
|
type SetPoliciesRequest struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Policies []iamaccess.Policy `json:"policies"`
|
Policies []iamaccess.Policy `json:"policies"`
|
||||||
@@ -117,6 +122,17 @@ func (c *APIClient) AddIdentity(origin string, r AddIdentityRequest) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *APIClient) UpdateIdentity(origin, name string, r UpdateIdentityRequest) error {
|
||||||
|
data, err := json.Marshal(r)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = c.call(http.MethodPut, "/iam/user/"+name, "application/json", bytes.NewReader(data), origin)
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
func (c *APIClient) SetPolicies(origin, name string, r SetPoliciesRequest) error {
|
func (c *APIClient) SetPolicies(origin, name string, r SetPoliciesRequest) error {
|
||||||
data, err := json.Marshal(r)
|
data, err := json.Marshal(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@@ -72,9 +72,12 @@ type Cluster interface {
|
|||||||
UpdateProcess(origin, id string, config *app.Config) error
|
UpdateProcess(origin, id string, config *app.Config) error
|
||||||
|
|
||||||
IAM(superuser iamidentity.User, jwtRealm, jwtSecret string) (iam.IAM, error)
|
IAM(superuser iamidentity.User, jwtRealm, jwtSecret string) (iam.IAM, error)
|
||||||
ListIdentities() store.Users
|
ListIdentities() (time.Time, []iamidentity.User)
|
||||||
ListPolicies() store.Policies
|
ListIdentity(name string) (time.Time, iamidentity.User, error)
|
||||||
|
ListPolicies() (time.Time, []iamaccess.Policy)
|
||||||
|
ListUserPolicies(name string) (time.Time, []iamaccess.Policy)
|
||||||
AddIdentity(origin string, identity iamidentity.User) error
|
AddIdentity(origin string, identity iamidentity.User) error
|
||||||
|
UpdateIdentity(origin, name string, identity iamidentity.User) error
|
||||||
SetPolicies(origin, name string, policies []iamaccess.Policy) error
|
SetPolicies(origin, name string, policies []iamaccess.Policy) error
|
||||||
RemoveIdentity(origin string, name string) error
|
RemoveIdentity(origin string, name string) error
|
||||||
|
|
||||||
@@ -779,12 +782,32 @@ func (c *cluster) IAM(superuser iamidentity.User, jwtRealm, jwtSecret string) (i
|
|||||||
return iam, nil
|
return iam, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *cluster) ListIdentities() store.Users {
|
func (c *cluster) ListIdentities() (time.Time, []iamidentity.User) {
|
||||||
return c.store.UserList()
|
users := c.store.UserList()
|
||||||
|
|
||||||
|
return users.UpdatedAt, users.Users
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *cluster) ListPolicies() store.Policies {
|
func (c *cluster) ListIdentity(name string) (time.Time, iamidentity.User, error) {
|
||||||
return c.store.PolicyList()
|
user := c.store.GetUser(name)
|
||||||
|
|
||||||
|
if len(user.Users) == 0 {
|
||||||
|
return time.Time{}, iamidentity.User{}, fmt.Errorf("not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
return user.UpdatedAt, user.Users[0], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *cluster) ListPolicies() (time.Time, []iamaccess.Policy) {
|
||||||
|
policies := c.store.PolicyList()
|
||||||
|
|
||||||
|
return policies.UpdatedAt, policies.Policies
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *cluster) ListUserPolicies(name string) (time.Time, []iamaccess.Policy) {
|
||||||
|
policies := c.store.PolicyUserList(name)
|
||||||
|
|
||||||
|
return policies.UpdatedAt, policies.Policies
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *cluster) AddIdentity(origin string, identity iamidentity.User) error {
|
func (c *cluster) AddIdentity(origin string, identity iamidentity.User) error {
|
||||||
@@ -802,6 +825,22 @@ func (c *cluster) AddIdentity(origin string, identity iamidentity.User) error {
|
|||||||
return c.applyCommand(cmd)
|
return c.applyCommand(cmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *cluster) UpdateIdentity(origin, name string, identity iamidentity.User) error {
|
||||||
|
if !c.IsRaftLeader() {
|
||||||
|
return c.forwarder.UpdateIdentity(origin, name, identity)
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd := &store.Command{
|
||||||
|
Operation: store.OpUpdateIdentity,
|
||||||
|
Data: &store.CommandUpdateIdentity{
|
||||||
|
Name: name,
|
||||||
|
Identity: identity,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.applyCommand(cmd)
|
||||||
|
}
|
||||||
|
|
||||||
func (c *cluster) SetPolicies(origin, name string, policies []iamaccess.Policy) error {
|
func (c *cluster) SetPolicies(origin, name string, policies []iamaccess.Policy) error {
|
||||||
if !c.IsRaftLeader() {
|
if !c.IsRaftLeader() {
|
||||||
return c.forwarder.SetPolicies(origin, name, policies)
|
return c.forwarder.SetPolicies(origin, name, policies)
|
||||||
@@ -841,7 +880,7 @@ func (c *cluster) applyCommand(cmd *store.Command) error {
|
|||||||
|
|
||||||
err = c.raft.Apply(b)
|
err = c.raft.Apply(b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("applying command failed: %w", err)
|
return fmt.Errorf("apply command: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@@ -27,6 +27,7 @@ type Forwarder interface {
|
|||||||
RemoveProcess(origin, id string) error
|
RemoveProcess(origin, id string) error
|
||||||
|
|
||||||
AddIdentity(origin string, identity iamidentity.User) error
|
AddIdentity(origin string, identity iamidentity.User) error
|
||||||
|
UpdateIdentity(origin, name string, identity iamidentity.User) error
|
||||||
SetPolicies(origin, name string, policies []iamaccess.Policy) error
|
SetPolicies(origin, name string, policies []iamaccess.Policy) error
|
||||||
RemoveIdentity(origin string, name string) error
|
RemoveIdentity(origin string, name string) error
|
||||||
}
|
}
|
||||||
@@ -198,6 +199,23 @@ func (f *forwarder) AddIdentity(origin string, identity iamidentity.User) error
|
|||||||
return client.AddIdentity(origin, r)
|
return client.AddIdentity(origin, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (f *forwarder) UpdateIdentity(origin, name string, identity iamidentity.User) error {
|
||||||
|
if origin == "" {
|
||||||
|
origin = f.id
|
||||||
|
}
|
||||||
|
|
||||||
|
r := apiclient.UpdateIdentityRequest{
|
||||||
|
Name: name,
|
||||||
|
Identity: identity,
|
||||||
|
}
|
||||||
|
|
||||||
|
f.lock.RLock()
|
||||||
|
client := f.client
|
||||||
|
f.lock.RUnlock()
|
||||||
|
|
||||||
|
return client.UpdateIdentity(origin, name, r)
|
||||||
|
}
|
||||||
|
|
||||||
func (f *forwarder) SetPolicies(origin, name string, policies []iamaccess.Policy) error {
|
func (f *forwarder) SetPolicies(origin, name string, policies []iamaccess.Policy) error {
|
||||||
if origin == "" {
|
if origin == "" {
|
||||||
origin = f.id
|
origin = f.id
|
||||||
|
@@ -223,6 +223,13 @@ func (r *raft) Apply(data []byte) error {
|
|||||||
return fmt.Errorf("applying command failed: %w", err)
|
return fmt.Errorf("applying command failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
res := future.Response()
|
||||||
|
if res != nil {
|
||||||
|
if err, ok := res.(store.StoreError); ok {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -24,7 +24,19 @@ type Store interface {
|
|||||||
GetProcess(id string) (Process, error)
|
GetProcess(id string) (Process, error)
|
||||||
|
|
||||||
UserList() Users
|
UserList() Users
|
||||||
|
GetUser(name string) Users
|
||||||
PolicyList() Policies
|
PolicyList() Policies
|
||||||
|
PolicyUserList(nam string) Policies
|
||||||
|
}
|
||||||
|
|
||||||
|
type StoreError string
|
||||||
|
|
||||||
|
func NewStoreError(format string, a ...any) StoreError {
|
||||||
|
return StoreError(fmt.Sprintf(format, a...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (se StoreError) Error() string {
|
||||||
|
return string(se)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Process struct {
|
type Process struct {
|
||||||
@@ -50,6 +62,7 @@ const (
|
|||||||
OpRemoveProcess Operation = "removeProcess"
|
OpRemoveProcess Operation = "removeProcess"
|
||||||
OpUpdateProcess Operation = "updateProcess"
|
OpUpdateProcess Operation = "updateProcess"
|
||||||
OpAddIdentity Operation = "addIdentity"
|
OpAddIdentity Operation = "addIdentity"
|
||||||
|
OpUpdateIdentity Operation = "updateIdentity"
|
||||||
OpRemoveIdentity Operation = "removeIdentity"
|
OpRemoveIdentity Operation = "removeIdentity"
|
||||||
OpSetPolicies Operation = "setPolicies"
|
OpSetPolicies Operation = "setPolicies"
|
||||||
)
|
)
|
||||||
@@ -76,6 +89,11 @@ type CommandAddIdentity struct {
|
|||||||
Identity identity.User
|
Identity identity.User
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type CommandUpdateIdentity struct {
|
||||||
|
Name string
|
||||||
|
Identity identity.User
|
||||||
|
}
|
||||||
|
|
||||||
type CommandRemoveIdentity struct {
|
type CommandRemoveIdentity struct {
|
||||||
Name string
|
Name string
|
||||||
}
|
}
|
||||||
@@ -138,7 +156,7 @@ func (s *store) Apply(entry *raft.Log) interface{} {
|
|||||||
err := json.Unmarshal(entry.Data, &c)
|
err := json.Unmarshal(entry.Data, &c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error().WithError(err).Log("Invalid entry")
|
logger.Error().WithError(err).Log("Invalid entry")
|
||||||
return fmt.Errorf("invalid log entry")
|
return NewStoreError("invalid log entry, index: %d, term: %d", entry.Index, entry.Term)
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Debug().WithField("operation", c.Operation).Log("")
|
logger.Debug().WithField("operation", c.Operation).Log("")
|
||||||
@@ -149,87 +167,51 @@ func (s *store) Apply(entry *raft.Log) interface{} {
|
|||||||
cmd := CommandAddProcess{}
|
cmd := CommandAddProcess{}
|
||||||
json.Unmarshal(b, &cmd)
|
json.Unmarshal(b, &cmd)
|
||||||
|
|
||||||
s.lock.Lock()
|
err = s.addProcess(cmd)
|
||||||
_, ok := s.Process[cmd.ID]
|
|
||||||
if !ok {
|
|
||||||
now := time.Now()
|
|
||||||
s.Process[cmd.ID] = Process{
|
|
||||||
CreatedAt: now,
|
|
||||||
UpdatedAt: now,
|
|
||||||
Config: &cmd.Config,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
s.lock.Unlock()
|
|
||||||
case OpRemoveProcess:
|
case OpRemoveProcess:
|
||||||
b, _ := json.Marshal(c.Data)
|
b, _ := json.Marshal(c.Data)
|
||||||
cmd := CommandRemoveProcess{}
|
cmd := CommandRemoveProcess{}
|
||||||
json.Unmarshal(b, &cmd)
|
json.Unmarshal(b, &cmd)
|
||||||
|
|
||||||
s.lock.Lock()
|
err = s.removeProcess(cmd)
|
||||||
delete(s.Process, cmd.ID)
|
|
||||||
s.lock.Unlock()
|
|
||||||
case OpUpdateProcess:
|
case OpUpdateProcess:
|
||||||
b, _ := json.Marshal(c.Data)
|
b, _ := json.Marshal(c.Data)
|
||||||
cmd := CommandUpdateProcess{}
|
cmd := CommandUpdateProcess{}
|
||||||
json.Unmarshal(b, &cmd)
|
json.Unmarshal(b, &cmd)
|
||||||
|
|
||||||
s.lock.Lock()
|
err = s.updateProcess(cmd)
|
||||||
_, ok := s.Process[cmd.ID]
|
|
||||||
if ok {
|
|
||||||
if cmd.ID == cmd.Config.ID {
|
|
||||||
s.Process[cmd.ID] = Process{
|
|
||||||
UpdatedAt: time.Now(),
|
|
||||||
Config: &cmd.Config,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
_, ok := s.Process[cmd.Config.ID]
|
|
||||||
if !ok {
|
|
||||||
delete(s.Process, cmd.ID)
|
|
||||||
s.Process[cmd.Config.ID] = Process{
|
|
||||||
UpdatedAt: time.Now(),
|
|
||||||
Config: &cmd.Config,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return fmt.Errorf("the process with the ID %s already exists", cmd.Config.ID)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
s.lock.Unlock()
|
|
||||||
case OpAddIdentity:
|
case OpAddIdentity:
|
||||||
b, _ := json.Marshal(c.Data)
|
b, _ := json.Marshal(c.Data)
|
||||||
cmd := CommandAddIdentity{}
|
cmd := CommandAddIdentity{}
|
||||||
json.Unmarshal(b, &cmd)
|
json.Unmarshal(b, &cmd)
|
||||||
|
|
||||||
s.lock.Lock()
|
err = s.addIdentity(cmd)
|
||||||
_, ok := s.Users.Users[cmd.Identity.Name]
|
case OpUpdateIdentity:
|
||||||
if !ok {
|
b, _ := json.Marshal(c.Data)
|
||||||
s.Users.UpdatedAt = time.Now()
|
cmd := CommandUpdateIdentity{}
|
||||||
s.Users.Users[cmd.Identity.Name] = cmd.Identity
|
json.Unmarshal(b, &cmd)
|
||||||
}
|
|
||||||
s.lock.Unlock()
|
err = s.updateIdentity(cmd)
|
||||||
case OpRemoveIdentity:
|
case OpRemoveIdentity:
|
||||||
b, _ := json.Marshal(c.Data)
|
b, _ := json.Marshal(c.Data)
|
||||||
cmd := CommandRemoveIdentity{}
|
cmd := CommandRemoveIdentity{}
|
||||||
json.Unmarshal(b, &cmd)
|
json.Unmarshal(b, &cmd)
|
||||||
|
|
||||||
s.lock.Lock()
|
err = s.removeIdentity(cmd)
|
||||||
delete(s.Users.Users, cmd.Name)
|
|
||||||
s.Users.UpdatedAt = time.Now()
|
|
||||||
delete(s.Policies.Policies, cmd.Name)
|
|
||||||
s.Policies.UpdatedAt = time.Now()
|
|
||||||
s.lock.Unlock()
|
|
||||||
case OpSetPolicies:
|
case OpSetPolicies:
|
||||||
b, _ := json.Marshal(c.Data)
|
b, _ := json.Marshal(c.Data)
|
||||||
cmd := CommandSetPolicies{}
|
cmd := CommandSetPolicies{}
|
||||||
json.Unmarshal(b, &cmd)
|
json.Unmarshal(b, &cmd)
|
||||||
|
|
||||||
s.lock.Lock()
|
err = s.setPolicies(cmd)
|
||||||
delete(s.Policies.Policies, cmd.Name)
|
|
||||||
s.Policies.Policies[cmd.Name] = cmd.Policies
|
|
||||||
s.Policies.UpdatedAt = time.Now()
|
|
||||||
s.lock.Unlock()
|
|
||||||
default:
|
default:
|
||||||
s.logger.Warn().WithField("operation", c.Operation).Log("Unknown operation")
|
s.logger.Warn().WithField("operation", c.Operation).Log("Unknown operation")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
logger.Debug().WithError(err).WithField("operation", c.Operation).Log("")
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
s.lock.RLock()
|
s.lock.RLock()
|
||||||
@@ -238,9 +220,123 @@ func (s *store) Apply(entry *raft.Log) interface{} {
|
|||||||
}
|
}
|
||||||
s.lock.RUnlock()
|
s.lock.RUnlock()
|
||||||
|
|
||||||
s.lock.RLock()
|
return nil
|
||||||
s.logger.Debug().WithField("processes", s.Process).Log("")
|
}
|
||||||
s.lock.RUnlock()
|
|
||||||
|
func (s *store) addProcess(cmd CommandAddProcess) error {
|
||||||
|
s.lock.Lock()
|
||||||
|
defer s.lock.Unlock()
|
||||||
|
|
||||||
|
_, ok := s.Process[cmd.ID]
|
||||||
|
if ok {
|
||||||
|
return NewStoreError("the process with the ID '%s' already exists", cmd.ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
now := time.Now()
|
||||||
|
s.Process[cmd.ID] = Process{
|
||||||
|
CreatedAt: now,
|
||||||
|
UpdatedAt: now,
|
||||||
|
Config: &cmd.Config,
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *store) removeProcess(cmd CommandRemoveProcess) error {
|
||||||
|
s.lock.Lock()
|
||||||
|
defer s.lock.Unlock()
|
||||||
|
|
||||||
|
delete(s.Process, cmd.ID)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *store) updateProcess(cmd CommandUpdateProcess) error {
|
||||||
|
s.lock.Lock()
|
||||||
|
defer s.lock.Unlock()
|
||||||
|
|
||||||
|
_, ok := s.Process[cmd.ID]
|
||||||
|
if ok {
|
||||||
|
if cmd.ID == cmd.Config.ID {
|
||||||
|
s.Process[cmd.ID] = Process{
|
||||||
|
UpdatedAt: time.Now(),
|
||||||
|
Config: &cmd.Config,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_, ok := s.Process[cmd.Config.ID]
|
||||||
|
if !ok {
|
||||||
|
delete(s.Process, cmd.ID)
|
||||||
|
s.Process[cmd.Config.ID] = Process{
|
||||||
|
UpdatedAt: time.Now(),
|
||||||
|
Config: &cmd.Config,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return NewStoreError("the process with the ID %s already exists", cmd.Config.ID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *store) addIdentity(cmd CommandAddIdentity) error {
|
||||||
|
s.lock.Lock()
|
||||||
|
defer s.lock.Unlock()
|
||||||
|
|
||||||
|
_, ok := s.Users.Users[cmd.Identity.Name]
|
||||||
|
if ok {
|
||||||
|
return NewStoreError("the identity with the name '%s' already exists", cmd.Identity.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
s.Users.UpdatedAt = time.Now()
|
||||||
|
s.Users.Users[cmd.Identity.Name] = cmd.Identity
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *store) updateIdentity(cmd CommandUpdateIdentity) error {
|
||||||
|
s.lock.Lock()
|
||||||
|
defer s.lock.Unlock()
|
||||||
|
|
||||||
|
_, ok := s.Users.Users[cmd.Name]
|
||||||
|
if ok {
|
||||||
|
if cmd.Name == cmd.Identity.Name {
|
||||||
|
s.Users.UpdatedAt = time.Now()
|
||||||
|
s.Users.Users[cmd.Identity.Name] = cmd.Identity
|
||||||
|
} else {
|
||||||
|
_, ok := s.Users.Users[cmd.Identity.Name]
|
||||||
|
if !ok {
|
||||||
|
s.Users.UpdatedAt = time.Now()
|
||||||
|
s.Users.Users[cmd.Identity.Name] = cmd.Identity
|
||||||
|
} else {
|
||||||
|
return NewStoreError("the identity with the name '%s' already exists", cmd.Identity.Name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *store) removeIdentity(cmd CommandRemoveIdentity) error {
|
||||||
|
s.lock.Lock()
|
||||||
|
defer s.lock.Unlock()
|
||||||
|
|
||||||
|
delete(s.Users.Users, cmd.Name)
|
||||||
|
s.Users.UpdatedAt = time.Now()
|
||||||
|
delete(s.Policies.Policies, cmd.Name)
|
||||||
|
s.Policies.UpdatedAt = time.Now()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *store) setPolicies(cmd CommandSetPolicies) error {
|
||||||
|
s.lock.Lock()
|
||||||
|
defer s.lock.Unlock()
|
||||||
|
|
||||||
|
delete(s.Policies.Policies, cmd.Name)
|
||||||
|
s.Policies.Policies[cmd.Name] = cmd.Policies
|
||||||
|
s.Policies.UpdatedAt = time.Now()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -329,6 +425,21 @@ func (s *store) UserList() Users {
|
|||||||
return u
|
return u
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *store) GetUser(name string) Users {
|
||||||
|
s.lock.RLock()
|
||||||
|
defer s.lock.RUnlock()
|
||||||
|
|
||||||
|
u := Users{
|
||||||
|
UpdatedAt: s.Users.UpdatedAt,
|
||||||
|
}
|
||||||
|
|
||||||
|
if user, ok := s.Users.Users[name]; ok {
|
||||||
|
u.Users = append(u.Users, user)
|
||||||
|
}
|
||||||
|
|
||||||
|
return u
|
||||||
|
}
|
||||||
|
|
||||||
func (s *store) PolicyList() Policies {
|
func (s *store) PolicyList() Policies {
|
||||||
s.lock.RLock()
|
s.lock.RLock()
|
||||||
defer s.lock.RUnlock()
|
defer s.lock.RUnlock()
|
||||||
@@ -344,6 +455,19 @@ func (s *store) PolicyList() Policies {
|
|||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *store) PolicyUserList(name string) Policies {
|
||||||
|
s.lock.RLock()
|
||||||
|
defer s.lock.RUnlock()
|
||||||
|
|
||||||
|
p := Policies{
|
||||||
|
UpdatedAt: s.Policies.UpdatedAt,
|
||||||
|
}
|
||||||
|
|
||||||
|
p.Policies = append(p.Policies, s.Policies.Policies[name]...)
|
||||||
|
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
type fsmSnapshot struct {
|
type fsmSnapshot struct {
|
||||||
data []byte
|
data []byte
|
||||||
}
|
}
|
||||||
|
386
docs/docs.go
386
docs/docs.go
@@ -150,12 +150,6 @@ const docTemplate = `{
|
|||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/api.ClusterAbout"
|
"$ref": "#/definitions/api.ClusterAbout"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"404": {
|
|
||||||
"description": "Not Found",
|
|
||||||
"schema": {
|
|
||||||
"$ref": "#/definitions/api.Error"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -247,6 +241,44 @@ const docTemplate = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/api/v3/cluster/db/user/{name}": {
|
||||||
|
"get": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"ApiKeyAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "List of identities in the cluster",
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"v16.?.?"
|
||||||
|
],
|
||||||
|
"summary": "List of identities in the cluster",
|
||||||
|
"operationId": "cluster-3-db-list-identity",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.IAMUser"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"403": {
|
||||||
|
"description": "Forbidden",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.Error"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"404": {
|
||||||
|
"description": "Not Found",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.Error"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/api/v3/cluster/iam/policies": {
|
"/api/v3/cluster/iam/policies": {
|
||||||
"get": {
|
"get": {
|
||||||
"security": [
|
"security": [
|
||||||
@@ -276,22 +308,22 @@ const docTemplate = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/api/v3/cluster/iam/policies/reload": {
|
"/api/v3/cluster/iam/reload": {
|
||||||
"get": {
|
"get": {
|
||||||
"security": [
|
"security": [
|
||||||
{
|
{
|
||||||
"ApiKeyAuth": []
|
"ApiKeyAuth": []
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "Reload policies",
|
"description": "Reload identities and policies",
|
||||||
"produces": [
|
"produces": [
|
||||||
"application/json"
|
"application/json"
|
||||||
],
|
],
|
||||||
"tags": [
|
"tags": [
|
||||||
"v16.?.?"
|
"v16.?.?"
|
||||||
],
|
],
|
||||||
"summary": "Reload policies",
|
"summary": "Reload identities and policies",
|
||||||
"operationId": "cluster-3-iam-reload-policies",
|
"operationId": "cluster-3-iam-reload",
|
||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
"description": "OK",
|
"description": "OK",
|
||||||
@@ -377,31 +409,118 @@ const docTemplate = `{
|
|||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/api.Error"
|
"$ref": "#/definitions/api.Error"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"403": {
|
||||||
|
"description": "Forbidden",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.Error"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/api/v3/cluster/iam/user/reload": {
|
"/api/v3/cluster/iam/user/{name}": {
|
||||||
"get": {
|
"get": {
|
||||||
"security": [
|
"security": [
|
||||||
{
|
{
|
||||||
"ApiKeyAuth": []
|
"ApiKeyAuth": []
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "Reload identities",
|
"description": "Identity in IAM",
|
||||||
"produces": [
|
"produces": [
|
||||||
"application/json"
|
"application/json"
|
||||||
],
|
],
|
||||||
"tags": [
|
"tags": [
|
||||||
"v16.?.?"
|
"v16.?.?"
|
||||||
],
|
],
|
||||||
"summary": "Reload identities",
|
"summary": "Identity in IAM",
|
||||||
"operationId": "cluster-3-iam-reload-identities",
|
"operationId": "cluster-3-iam-list-identity",
|
||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
"description": "OK",
|
"description": "OK",
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "string"
|
"$ref": "#/definitions/api.IAMUser"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"403": {
|
||||||
|
"description": "Forbidden",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.Error"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"404": {
|
||||||
|
"description": "Not Found",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.Error"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"put": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"ApiKeyAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Replace an existing user.",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"v16.?.?"
|
||||||
|
],
|
||||||
|
"summary": "Replace an existing user",
|
||||||
|
"operationId": "cluster-3-update-identity",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Username",
|
||||||
|
"name": "name",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Domain of the acting user",
|
||||||
|
"name": "domain",
|
||||||
|
"in": "query"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "User definition",
|
||||||
|
"name": "user",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.IAMUser"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.IAMUser"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.Error"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"403": {
|
||||||
|
"description": "Forbidden",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.Error"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"404": {
|
||||||
|
"description": "Not Found",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.Error"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"500": {
|
"500": {
|
||||||
@@ -411,9 +530,7 @@ const docTemplate = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
},
|
|
||||||
"/api/v3/cluster/iam/user/{name}": {
|
|
||||||
"delete": {
|
"delete": {
|
||||||
"security": [
|
"security": [
|
||||||
{
|
{
|
||||||
@@ -445,6 +562,12 @@ const docTemplate = `{
|
|||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"403": {
|
||||||
|
"description": "Forbidden",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.Error"
|
||||||
|
}
|
||||||
|
},
|
||||||
"404": {
|
"404": {
|
||||||
"description": "Not Found",
|
"description": "Not Found",
|
||||||
"schema": {
|
"schema": {
|
||||||
@@ -516,6 +639,12 @@ const docTemplate = `{
|
|||||||
"$ref": "#/definitions/api.Error"
|
"$ref": "#/definitions/api.Error"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"403": {
|
||||||
|
"description": "Forbidden",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.Error"
|
||||||
|
}
|
||||||
|
},
|
||||||
"404": {
|
"404": {
|
||||||
"description": "Not Found",
|
"description": "Not Found",
|
||||||
"schema": {
|
"schema": {
|
||||||
@@ -671,6 +800,12 @@ const docTemplate = `{
|
|||||||
"name": "id",
|
"name": "id",
|
||||||
"in": "path",
|
"in": "path",
|
||||||
"required": true
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Domain to act on",
|
||||||
|
"name": "domain",
|
||||||
|
"in": "query"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
@@ -727,7 +862,7 @@ const docTemplate = `{
|
|||||||
"200": {
|
"200": {
|
||||||
"description": "OK",
|
"description": "OK",
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/api.ClusterNode"
|
"$ref": "#/definitions/api.Version"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"404": {
|
"404": {
|
||||||
@@ -755,6 +890,14 @@ const docTemplate = `{
|
|||||||
],
|
],
|
||||||
"summary": "List of processes in the cluster",
|
"summary": "List of processes in the cluster",
|
||||||
"operationId": "cluster-3-list-all-node-processes",
|
"operationId": "cluster-3-list-all-node-processes",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Domain to act on",
|
||||||
|
"name": "domain",
|
||||||
|
"in": "query"
|
||||||
|
}
|
||||||
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
"description": "OK",
|
"description": "OK",
|
||||||
@@ -808,6 +951,12 @@ const docTemplate = `{
|
|||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/api.Error"
|
"$ref": "#/definitions/api.Error"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"403": {
|
||||||
|
"description": "Forbidden",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.Error"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -862,6 +1011,12 @@ const docTemplate = `{
|
|||||||
"$ref": "#/definitions/api.Error"
|
"$ref": "#/definitions/api.Error"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"403": {
|
||||||
|
"description": "Forbidden",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.Error"
|
||||||
|
}
|
||||||
|
},
|
||||||
"404": {
|
"404": {
|
||||||
"description": "Not Found",
|
"description": "Not Found",
|
||||||
"schema": {
|
"schema": {
|
||||||
@@ -901,8 +1056,14 @@ const docTemplate = `{
|
|||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"404": {
|
"403": {
|
||||||
"description": "Not Found",
|
"description": "Forbidden",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.Error"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/api.Error"
|
"$ref": "#/definitions/api.Error"
|
||||||
}
|
}
|
||||||
@@ -930,7 +1091,7 @@ const docTemplate = `{
|
|||||||
"200": {
|
"200": {
|
||||||
"description": "OK",
|
"description": "OK",
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/github_com_datarhei_core_v16_http_api.Config"
|
"$ref": "#/definitions/api.GetConfig"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1784,6 +1945,12 @@ const docTemplate = `{
|
|||||||
"summary": "List all known processes",
|
"summary": "List all known processes",
|
||||||
"operationId": "process-3-get-all",
|
"operationId": "process-3-get-all",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Domain to act on",
|
||||||
|
"name": "domain",
|
||||||
|
"in": "query"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "Comma separated list of fields (config, state, report, metadata) that will be part of the output. If empty, all fields will be part of the output.",
|
"description": "Comma separated list of fields (config, state, report, metadata) that will be part of the output. If empty, all fields will be part of the output.",
|
||||||
@@ -1880,6 +2047,12 @@ const docTemplate = `{
|
|||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/api.Error"
|
"$ref": "#/definitions/api.Error"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"403": {
|
||||||
|
"description": "Forbidden",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.Error"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1908,6 +2081,12 @@ const docTemplate = `{
|
|||||||
"in": "path",
|
"in": "path",
|
||||||
"required": true
|
"required": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Domain to act on",
|
||||||
|
"name": "domain",
|
||||||
|
"in": "query"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "Comma separated list of fields (config, state, report, metadata) to be part of the output. If empty, all fields will be part of the output",
|
"description": "Comma separated list of fields (config, state, report, metadata) to be part of the output. If empty, all fields will be part of the output",
|
||||||
@@ -1922,6 +2101,12 @@ const docTemplate = `{
|
|||||||
"$ref": "#/definitions/api.Process"
|
"$ref": "#/definitions/api.Process"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"403": {
|
||||||
|
"description": "Forbidden",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.Error"
|
||||||
|
}
|
||||||
|
},
|
||||||
"404": {
|
"404": {
|
||||||
"description": "Not Found",
|
"description": "Not Found",
|
||||||
"schema": {
|
"schema": {
|
||||||
@@ -1956,6 +2141,12 @@ const docTemplate = `{
|
|||||||
"in": "path",
|
"in": "path",
|
||||||
"required": true
|
"required": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Domain to act on",
|
||||||
|
"name": "domain",
|
||||||
|
"in": "query"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"description": "Process config",
|
"description": "Process config",
|
||||||
"name": "config",
|
"name": "config",
|
||||||
@@ -1979,6 +2170,12 @@ const docTemplate = `{
|
|||||||
"$ref": "#/definitions/api.Error"
|
"$ref": "#/definitions/api.Error"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"403": {
|
||||||
|
"description": "Forbidden",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.Error"
|
||||||
|
}
|
||||||
|
},
|
||||||
"404": {
|
"404": {
|
||||||
"description": "Not Found",
|
"description": "Not Found",
|
||||||
"schema": {
|
"schema": {
|
||||||
@@ -2009,6 +2206,12 @@ const docTemplate = `{
|
|||||||
"name": "id",
|
"name": "id",
|
||||||
"in": "path",
|
"in": "path",
|
||||||
"required": true
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Domain to act on",
|
||||||
|
"name": "domain",
|
||||||
|
"in": "query"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
@@ -2018,6 +2221,12 @@ const docTemplate = `{
|
|||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"403": {
|
||||||
|
"description": "Forbidden",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.Error"
|
||||||
|
}
|
||||||
|
},
|
||||||
"404": {
|
"404": {
|
||||||
"description": "Not Found",
|
"description": "Not Found",
|
||||||
"schema": {
|
"schema": {
|
||||||
@@ -2054,6 +2263,12 @@ const docTemplate = `{
|
|||||||
"in": "path",
|
"in": "path",
|
||||||
"required": true
|
"required": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Domain to act on",
|
||||||
|
"name": "domain",
|
||||||
|
"in": "query"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"description": "Process command",
|
"description": "Process command",
|
||||||
"name": "command",
|
"name": "command",
|
||||||
@@ -2077,6 +2292,12 @@ const docTemplate = `{
|
|||||||
"$ref": "#/definitions/api.Error"
|
"$ref": "#/definitions/api.Error"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"403": {
|
||||||
|
"description": "Forbidden",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.Error"
|
||||||
|
}
|
||||||
|
},
|
||||||
"404": {
|
"404": {
|
||||||
"description": "Not Found",
|
"description": "Not Found",
|
||||||
"schema": {
|
"schema": {
|
||||||
@@ -2109,6 +2330,12 @@ const docTemplate = `{
|
|||||||
"name": "id",
|
"name": "id",
|
||||||
"in": "path",
|
"in": "path",
|
||||||
"required": true
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Domain to act on",
|
||||||
|
"name": "domain",
|
||||||
|
"in": "query"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
@@ -2124,6 +2351,12 @@ const docTemplate = `{
|
|||||||
"$ref": "#/definitions/api.Error"
|
"$ref": "#/definitions/api.Error"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"403": {
|
||||||
|
"description": "Forbidden",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.Error"
|
||||||
|
}
|
||||||
|
},
|
||||||
"404": {
|
"404": {
|
||||||
"description": "Not Found",
|
"description": "Not Found",
|
||||||
"schema": {
|
"schema": {
|
||||||
@@ -2163,6 +2396,12 @@ const docTemplate = `{
|
|||||||
"name": "key",
|
"name": "key",
|
||||||
"in": "path",
|
"in": "path",
|
||||||
"required": true
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Domain to act on",
|
||||||
|
"name": "domain",
|
||||||
|
"in": "query"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
@@ -2176,6 +2415,12 @@ const docTemplate = `{
|
|||||||
"$ref": "#/definitions/api.Error"
|
"$ref": "#/definitions/api.Error"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"403": {
|
||||||
|
"description": "Forbidden",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.Error"
|
||||||
|
}
|
||||||
|
},
|
||||||
"404": {
|
"404": {
|
||||||
"description": "Not Found",
|
"description": "Not Found",
|
||||||
"schema": {
|
"schema": {
|
||||||
@@ -2214,6 +2459,12 @@ const docTemplate = `{
|
|||||||
"in": "path",
|
"in": "path",
|
||||||
"required": true
|
"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",
|
"description": "Arbitrary JSON data. The null value will remove the key and its contents",
|
||||||
"name": "data",
|
"name": "data",
|
||||||
@@ -2233,6 +2484,12 @@ const docTemplate = `{
|
|||||||
"$ref": "#/definitions/api.Error"
|
"$ref": "#/definitions/api.Error"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"403": {
|
||||||
|
"description": "Forbidden",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.Error"
|
||||||
|
}
|
||||||
|
},
|
||||||
"404": {
|
"404": {
|
||||||
"description": "Not Found",
|
"description": "Not Found",
|
||||||
"schema": {
|
"schema": {
|
||||||
@@ -2635,6 +2892,12 @@ const docTemplate = `{
|
|||||||
"name": "id",
|
"name": "id",
|
||||||
"in": "path",
|
"in": "path",
|
||||||
"required": true
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Domain to act on",
|
||||||
|
"name": "domain",
|
||||||
|
"in": "query"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
@@ -2643,6 +2906,12 @@ const docTemplate = `{
|
|||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/api.Probe"
|
"$ref": "#/definitions/api.Probe"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"403": {
|
||||||
|
"description": "Forbidden",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.Error"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2670,6 +2939,12 @@ const docTemplate = `{
|
|||||||
"name": "id",
|
"name": "id",
|
||||||
"in": "path",
|
"in": "path",
|
||||||
"required": true
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Domain to act on",
|
||||||
|
"name": "domain",
|
||||||
|
"in": "query"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
@@ -2685,6 +2960,12 @@ const docTemplate = `{
|
|||||||
"$ref": "#/definitions/api.Error"
|
"$ref": "#/definitions/api.Error"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"403": {
|
||||||
|
"description": "Forbidden",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.Error"
|
||||||
|
}
|
||||||
|
},
|
||||||
"404": {
|
"404": {
|
||||||
"description": "Not Found",
|
"description": "Not Found",
|
||||||
"schema": {
|
"schema": {
|
||||||
@@ -2717,6 +2998,12 @@ const docTemplate = `{
|
|||||||
"name": "id",
|
"name": "id",
|
||||||
"in": "path",
|
"in": "path",
|
||||||
"required": true
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Domain to act on",
|
||||||
|
"name": "domain",
|
||||||
|
"in": "query"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
@@ -2732,6 +3019,12 @@ const docTemplate = `{
|
|||||||
"$ref": "#/definitions/api.Error"
|
"$ref": "#/definitions/api.Error"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"403": {
|
||||||
|
"description": "Forbidden",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.Error"
|
||||||
|
}
|
||||||
|
},
|
||||||
"404": {
|
"404": {
|
||||||
"description": "Not Found",
|
"description": "Not Found",
|
||||||
"schema": {
|
"schema": {
|
||||||
@@ -3900,6 +4193,29 @@ const docTemplate = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"api.GetConfig": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"config": {
|
||||||
|
"$ref": "#/definitions/api.ConfigData"
|
||||||
|
},
|
||||||
|
"created_at": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"loaded_at": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"overrides": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"updated_at": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"api.GraphQuery": {
|
"api.GraphQuery": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
@@ -3945,6 +4261,9 @@ const docTemplate = `{
|
|||||||
"domain": {
|
"domain": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"resource": {
|
"resource": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
@@ -6022,29 +6341,6 @@ const docTemplate = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"github_com_datarhei_core_v16_http_api.Config": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"config": {
|
|
||||||
"$ref": "#/definitions/api.ConfigData"
|
|
||||||
},
|
|
||||||
"created_at": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"loaded_at": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"overrides": {
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"updated_at": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"value.Auth0Tenant": {
|
"value.Auth0Tenant": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
@@ -142,12 +142,6 @@
|
|||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/api.ClusterAbout"
|
"$ref": "#/definitions/api.ClusterAbout"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"404": {
|
|
||||||
"description": "Not Found",
|
|
||||||
"schema": {
|
|
||||||
"$ref": "#/definitions/api.Error"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -239,6 +233,44 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/api/v3/cluster/db/user/{name}": {
|
||||||
|
"get": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"ApiKeyAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "List of identities in the cluster",
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"v16.?.?"
|
||||||
|
],
|
||||||
|
"summary": "List of identities in the cluster",
|
||||||
|
"operationId": "cluster-3-db-list-identity",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.IAMUser"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"403": {
|
||||||
|
"description": "Forbidden",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.Error"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"404": {
|
||||||
|
"description": "Not Found",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.Error"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/api/v3/cluster/iam/policies": {
|
"/api/v3/cluster/iam/policies": {
|
||||||
"get": {
|
"get": {
|
||||||
"security": [
|
"security": [
|
||||||
@@ -268,22 +300,22 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/api/v3/cluster/iam/policies/reload": {
|
"/api/v3/cluster/iam/reload": {
|
||||||
"get": {
|
"get": {
|
||||||
"security": [
|
"security": [
|
||||||
{
|
{
|
||||||
"ApiKeyAuth": []
|
"ApiKeyAuth": []
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "Reload policies",
|
"description": "Reload identities and policies",
|
||||||
"produces": [
|
"produces": [
|
||||||
"application/json"
|
"application/json"
|
||||||
],
|
],
|
||||||
"tags": [
|
"tags": [
|
||||||
"v16.?.?"
|
"v16.?.?"
|
||||||
],
|
],
|
||||||
"summary": "Reload policies",
|
"summary": "Reload identities and policies",
|
||||||
"operationId": "cluster-3-iam-reload-policies",
|
"operationId": "cluster-3-iam-reload",
|
||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
"description": "OK",
|
"description": "OK",
|
||||||
@@ -369,31 +401,118 @@
|
|||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/api.Error"
|
"$ref": "#/definitions/api.Error"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"403": {
|
||||||
|
"description": "Forbidden",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.Error"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/api/v3/cluster/iam/user/reload": {
|
"/api/v3/cluster/iam/user/{name}": {
|
||||||
"get": {
|
"get": {
|
||||||
"security": [
|
"security": [
|
||||||
{
|
{
|
||||||
"ApiKeyAuth": []
|
"ApiKeyAuth": []
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "Reload identities",
|
"description": "Identity in IAM",
|
||||||
"produces": [
|
"produces": [
|
||||||
"application/json"
|
"application/json"
|
||||||
],
|
],
|
||||||
"tags": [
|
"tags": [
|
||||||
"v16.?.?"
|
"v16.?.?"
|
||||||
],
|
],
|
||||||
"summary": "Reload identities",
|
"summary": "Identity in IAM",
|
||||||
"operationId": "cluster-3-iam-reload-identities",
|
"operationId": "cluster-3-iam-list-identity",
|
||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
"description": "OK",
|
"description": "OK",
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "string"
|
"$ref": "#/definitions/api.IAMUser"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"403": {
|
||||||
|
"description": "Forbidden",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.Error"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"404": {
|
||||||
|
"description": "Not Found",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.Error"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"put": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"ApiKeyAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Replace an existing user.",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"v16.?.?"
|
||||||
|
],
|
||||||
|
"summary": "Replace an existing user",
|
||||||
|
"operationId": "cluster-3-update-identity",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Username",
|
||||||
|
"name": "name",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Domain of the acting user",
|
||||||
|
"name": "domain",
|
||||||
|
"in": "query"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "User definition",
|
||||||
|
"name": "user",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.IAMUser"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.IAMUser"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.Error"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"403": {
|
||||||
|
"description": "Forbidden",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.Error"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"404": {
|
||||||
|
"description": "Not Found",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.Error"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"500": {
|
"500": {
|
||||||
@@ -403,9 +522,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
},
|
|
||||||
"/api/v3/cluster/iam/user/{name}": {
|
|
||||||
"delete": {
|
"delete": {
|
||||||
"security": [
|
"security": [
|
||||||
{
|
{
|
||||||
@@ -437,6 +554,12 @@
|
|||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"403": {
|
||||||
|
"description": "Forbidden",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.Error"
|
||||||
|
}
|
||||||
|
},
|
||||||
"404": {
|
"404": {
|
||||||
"description": "Not Found",
|
"description": "Not Found",
|
||||||
"schema": {
|
"schema": {
|
||||||
@@ -508,6 +631,12 @@
|
|||||||
"$ref": "#/definitions/api.Error"
|
"$ref": "#/definitions/api.Error"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"403": {
|
||||||
|
"description": "Forbidden",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.Error"
|
||||||
|
}
|
||||||
|
},
|
||||||
"404": {
|
"404": {
|
||||||
"description": "Not Found",
|
"description": "Not Found",
|
||||||
"schema": {
|
"schema": {
|
||||||
@@ -663,6 +792,12 @@
|
|||||||
"name": "id",
|
"name": "id",
|
||||||
"in": "path",
|
"in": "path",
|
||||||
"required": true
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Domain to act on",
|
||||||
|
"name": "domain",
|
||||||
|
"in": "query"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
@@ -719,7 +854,7 @@
|
|||||||
"200": {
|
"200": {
|
||||||
"description": "OK",
|
"description": "OK",
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/api.ClusterNode"
|
"$ref": "#/definitions/api.Version"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"404": {
|
"404": {
|
||||||
@@ -747,6 +882,14 @@
|
|||||||
],
|
],
|
||||||
"summary": "List of processes in the cluster",
|
"summary": "List of processes in the cluster",
|
||||||
"operationId": "cluster-3-list-all-node-processes",
|
"operationId": "cluster-3-list-all-node-processes",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Domain to act on",
|
||||||
|
"name": "domain",
|
||||||
|
"in": "query"
|
||||||
|
}
|
||||||
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
"description": "OK",
|
"description": "OK",
|
||||||
@@ -800,6 +943,12 @@
|
|||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/api.Error"
|
"$ref": "#/definitions/api.Error"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"403": {
|
||||||
|
"description": "Forbidden",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.Error"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -854,6 +1003,12 @@
|
|||||||
"$ref": "#/definitions/api.Error"
|
"$ref": "#/definitions/api.Error"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"403": {
|
||||||
|
"description": "Forbidden",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.Error"
|
||||||
|
}
|
||||||
|
},
|
||||||
"404": {
|
"404": {
|
||||||
"description": "Not Found",
|
"description": "Not Found",
|
||||||
"schema": {
|
"schema": {
|
||||||
@@ -893,8 +1048,14 @@
|
|||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"404": {
|
"403": {
|
||||||
"description": "Not Found",
|
"description": "Forbidden",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.Error"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/api.Error"
|
"$ref": "#/definitions/api.Error"
|
||||||
}
|
}
|
||||||
@@ -922,7 +1083,7 @@
|
|||||||
"200": {
|
"200": {
|
||||||
"description": "OK",
|
"description": "OK",
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/github_com_datarhei_core_v16_http_api.Config"
|
"$ref": "#/definitions/api.GetConfig"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1776,6 +1937,12 @@
|
|||||||
"summary": "List all known processes",
|
"summary": "List all known processes",
|
||||||
"operationId": "process-3-get-all",
|
"operationId": "process-3-get-all",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Domain to act on",
|
||||||
|
"name": "domain",
|
||||||
|
"in": "query"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "Comma separated list of fields (config, state, report, metadata) that will be part of the output. If empty, all fields will be part of the output.",
|
"description": "Comma separated list of fields (config, state, report, metadata) that will be part of the output. If empty, all fields will be part of the output.",
|
||||||
@@ -1872,6 +2039,12 @@
|
|||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/api.Error"
|
"$ref": "#/definitions/api.Error"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"403": {
|
||||||
|
"description": "Forbidden",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.Error"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1900,6 +2073,12 @@
|
|||||||
"in": "path",
|
"in": "path",
|
||||||
"required": true
|
"required": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Domain to act on",
|
||||||
|
"name": "domain",
|
||||||
|
"in": "query"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "Comma separated list of fields (config, state, report, metadata) to be part of the output. If empty, all fields will be part of the output",
|
"description": "Comma separated list of fields (config, state, report, metadata) to be part of the output. If empty, all fields will be part of the output",
|
||||||
@@ -1914,6 +2093,12 @@
|
|||||||
"$ref": "#/definitions/api.Process"
|
"$ref": "#/definitions/api.Process"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"403": {
|
||||||
|
"description": "Forbidden",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.Error"
|
||||||
|
}
|
||||||
|
},
|
||||||
"404": {
|
"404": {
|
||||||
"description": "Not Found",
|
"description": "Not Found",
|
||||||
"schema": {
|
"schema": {
|
||||||
@@ -1948,6 +2133,12 @@
|
|||||||
"in": "path",
|
"in": "path",
|
||||||
"required": true
|
"required": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Domain to act on",
|
||||||
|
"name": "domain",
|
||||||
|
"in": "query"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"description": "Process config",
|
"description": "Process config",
|
||||||
"name": "config",
|
"name": "config",
|
||||||
@@ -1971,6 +2162,12 @@
|
|||||||
"$ref": "#/definitions/api.Error"
|
"$ref": "#/definitions/api.Error"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"403": {
|
||||||
|
"description": "Forbidden",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.Error"
|
||||||
|
}
|
||||||
|
},
|
||||||
"404": {
|
"404": {
|
||||||
"description": "Not Found",
|
"description": "Not Found",
|
||||||
"schema": {
|
"schema": {
|
||||||
@@ -2001,6 +2198,12 @@
|
|||||||
"name": "id",
|
"name": "id",
|
||||||
"in": "path",
|
"in": "path",
|
||||||
"required": true
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Domain to act on",
|
||||||
|
"name": "domain",
|
||||||
|
"in": "query"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
@@ -2010,6 +2213,12 @@
|
|||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"403": {
|
||||||
|
"description": "Forbidden",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.Error"
|
||||||
|
}
|
||||||
|
},
|
||||||
"404": {
|
"404": {
|
||||||
"description": "Not Found",
|
"description": "Not Found",
|
||||||
"schema": {
|
"schema": {
|
||||||
@@ -2046,6 +2255,12 @@
|
|||||||
"in": "path",
|
"in": "path",
|
||||||
"required": true
|
"required": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Domain to act on",
|
||||||
|
"name": "domain",
|
||||||
|
"in": "query"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"description": "Process command",
|
"description": "Process command",
|
||||||
"name": "command",
|
"name": "command",
|
||||||
@@ -2069,6 +2284,12 @@
|
|||||||
"$ref": "#/definitions/api.Error"
|
"$ref": "#/definitions/api.Error"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"403": {
|
||||||
|
"description": "Forbidden",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.Error"
|
||||||
|
}
|
||||||
|
},
|
||||||
"404": {
|
"404": {
|
||||||
"description": "Not Found",
|
"description": "Not Found",
|
||||||
"schema": {
|
"schema": {
|
||||||
@@ -2101,6 +2322,12 @@
|
|||||||
"name": "id",
|
"name": "id",
|
||||||
"in": "path",
|
"in": "path",
|
||||||
"required": true
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Domain to act on",
|
||||||
|
"name": "domain",
|
||||||
|
"in": "query"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
@@ -2116,6 +2343,12 @@
|
|||||||
"$ref": "#/definitions/api.Error"
|
"$ref": "#/definitions/api.Error"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"403": {
|
||||||
|
"description": "Forbidden",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.Error"
|
||||||
|
}
|
||||||
|
},
|
||||||
"404": {
|
"404": {
|
||||||
"description": "Not Found",
|
"description": "Not Found",
|
||||||
"schema": {
|
"schema": {
|
||||||
@@ -2155,6 +2388,12 @@
|
|||||||
"name": "key",
|
"name": "key",
|
||||||
"in": "path",
|
"in": "path",
|
||||||
"required": true
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Domain to act on",
|
||||||
|
"name": "domain",
|
||||||
|
"in": "query"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
@@ -2168,6 +2407,12 @@
|
|||||||
"$ref": "#/definitions/api.Error"
|
"$ref": "#/definitions/api.Error"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"403": {
|
||||||
|
"description": "Forbidden",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.Error"
|
||||||
|
}
|
||||||
|
},
|
||||||
"404": {
|
"404": {
|
||||||
"description": "Not Found",
|
"description": "Not Found",
|
||||||
"schema": {
|
"schema": {
|
||||||
@@ -2206,6 +2451,12 @@
|
|||||||
"in": "path",
|
"in": "path",
|
||||||
"required": true
|
"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",
|
"description": "Arbitrary JSON data. The null value will remove the key and its contents",
|
||||||
"name": "data",
|
"name": "data",
|
||||||
@@ -2225,6 +2476,12 @@
|
|||||||
"$ref": "#/definitions/api.Error"
|
"$ref": "#/definitions/api.Error"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"403": {
|
||||||
|
"description": "Forbidden",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.Error"
|
||||||
|
}
|
||||||
|
},
|
||||||
"404": {
|
"404": {
|
||||||
"description": "Not Found",
|
"description": "Not Found",
|
||||||
"schema": {
|
"schema": {
|
||||||
@@ -2627,6 +2884,12 @@
|
|||||||
"name": "id",
|
"name": "id",
|
||||||
"in": "path",
|
"in": "path",
|
||||||
"required": true
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Domain to act on",
|
||||||
|
"name": "domain",
|
||||||
|
"in": "query"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
@@ -2635,6 +2898,12 @@
|
|||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/api.Probe"
|
"$ref": "#/definitions/api.Probe"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"403": {
|
||||||
|
"description": "Forbidden",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.Error"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2662,6 +2931,12 @@
|
|||||||
"name": "id",
|
"name": "id",
|
||||||
"in": "path",
|
"in": "path",
|
||||||
"required": true
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Domain to act on",
|
||||||
|
"name": "domain",
|
||||||
|
"in": "query"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
@@ -2677,6 +2952,12 @@
|
|||||||
"$ref": "#/definitions/api.Error"
|
"$ref": "#/definitions/api.Error"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"403": {
|
||||||
|
"description": "Forbidden",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.Error"
|
||||||
|
}
|
||||||
|
},
|
||||||
"404": {
|
"404": {
|
||||||
"description": "Not Found",
|
"description": "Not Found",
|
||||||
"schema": {
|
"schema": {
|
||||||
@@ -2709,6 +2990,12 @@
|
|||||||
"name": "id",
|
"name": "id",
|
||||||
"in": "path",
|
"in": "path",
|
||||||
"required": true
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Domain to act on",
|
||||||
|
"name": "domain",
|
||||||
|
"in": "query"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
@@ -2724,6 +3011,12 @@
|
|||||||
"$ref": "#/definitions/api.Error"
|
"$ref": "#/definitions/api.Error"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"403": {
|
||||||
|
"description": "Forbidden",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.Error"
|
||||||
|
}
|
||||||
|
},
|
||||||
"404": {
|
"404": {
|
||||||
"description": "Not Found",
|
"description": "Not Found",
|
||||||
"schema": {
|
"schema": {
|
||||||
@@ -3892,6 +4185,29 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"api.GetConfig": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"config": {
|
||||||
|
"$ref": "#/definitions/api.ConfigData"
|
||||||
|
},
|
||||||
|
"created_at": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"loaded_at": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"overrides": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"updated_at": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"api.GraphQuery": {
|
"api.GraphQuery": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
@@ -3937,6 +4253,9 @@
|
|||||||
"domain": {
|
"domain": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"resource": {
|
"resource": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
@@ -6014,29 +6333,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"github_com_datarhei_core_v16_http_api.Config": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"config": {
|
|
||||||
"$ref": "#/definitions/api.ConfigData"
|
|
||||||
},
|
|
||||||
"created_at": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"loaded_at": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"overrides": {
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"updated_at": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"value.Auth0Tenant": {
|
"value.Auth0Tenant": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
@@ -588,6 +588,21 @@ definitions:
|
|||||||
type:
|
type:
|
||||||
type: string
|
type: string
|
||||||
type: object
|
type: object
|
||||||
|
api.GetConfig:
|
||||||
|
properties:
|
||||||
|
config:
|
||||||
|
$ref: '#/definitions/api.ConfigData'
|
||||||
|
created_at:
|
||||||
|
type: string
|
||||||
|
loaded_at:
|
||||||
|
type: string
|
||||||
|
overrides:
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
updated_at:
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
api.GraphQuery:
|
api.GraphQuery:
|
||||||
properties:
|
properties:
|
||||||
query:
|
query:
|
||||||
@@ -618,6 +633,8 @@ definitions:
|
|||||||
type: array
|
type: array
|
||||||
domain:
|
domain:
|
||||||
type: string
|
type: string
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
resource:
|
resource:
|
||||||
type: string
|
type: string
|
||||||
type: object
|
type: object
|
||||||
@@ -2079,21 +2096,6 @@ definitions:
|
|||||||
uptime:
|
uptime:
|
||||||
type: integer
|
type: integer
|
||||||
type: object
|
type: object
|
||||||
github_com_datarhei_core_v16_http_api.Config:
|
|
||||||
properties:
|
|
||||||
config:
|
|
||||||
$ref: '#/definitions/api.ConfigData'
|
|
||||||
created_at:
|
|
||||||
type: string
|
|
||||||
loaded_at:
|
|
||||||
type: string
|
|
||||||
overrides:
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
type: array
|
|
||||||
updated_at:
|
|
||||||
type: string
|
|
||||||
type: object
|
|
||||||
value.Auth0Tenant:
|
value.Auth0Tenant:
|
||||||
properties:
|
properties:
|
||||||
audience:
|
audience:
|
||||||
@@ -2231,10 +2233,6 @@ paths:
|
|||||||
description: OK
|
description: OK
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/api.ClusterAbout'
|
$ref: '#/definitions/api.ClusterAbout'
|
||||||
"404":
|
|
||||||
description: Not Found
|
|
||||||
schema:
|
|
||||||
$ref: '#/definitions/api.Error'
|
|
||||||
security:
|
security:
|
||||||
- ApiKeyAuth: []
|
- ApiKeyAuth: []
|
||||||
summary: List of nodes in the cluster
|
summary: List of nodes in the cluster
|
||||||
@@ -2294,6 +2292,30 @@ paths:
|
|||||||
summary: List of identities in the cluster
|
summary: List of identities in the cluster
|
||||||
tags:
|
tags:
|
||||||
- v16.?.?
|
- v16.?.?
|
||||||
|
/api/v3/cluster/db/user/{name}:
|
||||||
|
get:
|
||||||
|
description: List of identities in the cluster
|
||||||
|
operationId: cluster-3-db-list-identity
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/api.IAMUser'
|
||||||
|
"403":
|
||||||
|
description: Forbidden
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/api.Error'
|
||||||
|
"404":
|
||||||
|
description: Not Found
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/api.Error'
|
||||||
|
security:
|
||||||
|
- ApiKeyAuth: []
|
||||||
|
summary: List of identities in the cluster
|
||||||
|
tags:
|
||||||
|
- v16.?.?
|
||||||
/api/v3/cluster/iam/policies:
|
/api/v3/cluster/iam/policies:
|
||||||
get:
|
get:
|
||||||
description: List of policies IAM
|
description: List of policies IAM
|
||||||
@@ -2312,10 +2334,10 @@ paths:
|
|||||||
summary: List of policies in IAM
|
summary: List of policies in IAM
|
||||||
tags:
|
tags:
|
||||||
- v16.?.?
|
- v16.?.?
|
||||||
/api/v3/cluster/iam/policies/reload:
|
/api/v3/cluster/iam/reload:
|
||||||
get:
|
get:
|
||||||
description: Reload policies
|
description: Reload identities and policies
|
||||||
operationId: cluster-3-iam-reload-policies
|
operationId: cluster-3-iam-reload
|
||||||
produces:
|
produces:
|
||||||
- application/json
|
- application/json
|
||||||
responses:
|
responses:
|
||||||
@@ -2329,7 +2351,7 @@ paths:
|
|||||||
$ref: '#/definitions/api.Error'
|
$ref: '#/definitions/api.Error'
|
||||||
security:
|
security:
|
||||||
- ApiKeyAuth: []
|
- ApiKeyAuth: []
|
||||||
summary: Reload policies
|
summary: Reload identities and policies
|
||||||
tags:
|
tags:
|
||||||
- v16.?.?
|
- v16.?.?
|
||||||
/api/v3/cluster/iam/user:
|
/api/v3/cluster/iam/user:
|
||||||
@@ -2373,6 +2395,10 @@ paths:
|
|||||||
description: Bad Request
|
description: Bad Request
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/api.Error'
|
$ref: '#/definitions/api.Error'
|
||||||
|
"403":
|
||||||
|
description: Forbidden
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/api.Error'
|
||||||
security:
|
security:
|
||||||
- ApiKeyAuth: []
|
- ApiKeyAuth: []
|
||||||
summary: Add a new identiy
|
summary: Add a new identiy
|
||||||
@@ -2395,6 +2421,10 @@ paths:
|
|||||||
description: OK
|
description: OK
|
||||||
schema:
|
schema:
|
||||||
type: string
|
type: string
|
||||||
|
"403":
|
||||||
|
description: Forbidden
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/api.Error'
|
||||||
"404":
|
"404":
|
||||||
description: Not Found
|
description: Not Found
|
||||||
schema:
|
schema:
|
||||||
@@ -2404,6 +2434,78 @@ paths:
|
|||||||
summary: Delete an identity by its name
|
summary: Delete an identity by its name
|
||||||
tags:
|
tags:
|
||||||
- v16.?.?
|
- v16.?.?
|
||||||
|
get:
|
||||||
|
description: Identity in IAM
|
||||||
|
operationId: cluster-3-iam-list-identity
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/api.IAMUser'
|
||||||
|
"403":
|
||||||
|
description: Forbidden
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/api.Error'
|
||||||
|
"404":
|
||||||
|
description: Not Found
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/api.Error'
|
||||||
|
security:
|
||||||
|
- ApiKeyAuth: []
|
||||||
|
summary: Identity in IAM
|
||||||
|
tags:
|
||||||
|
- v16.?.?
|
||||||
|
put:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: Replace an existing user.
|
||||||
|
operationId: cluster-3-update-identity
|
||||||
|
parameters:
|
||||||
|
- description: Username
|
||||||
|
in: path
|
||||||
|
name: name
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
- description: Domain of the acting user
|
||||||
|
in: query
|
||||||
|
name: domain
|
||||||
|
type: string
|
||||||
|
- description: User definition
|
||||||
|
in: body
|
||||||
|
name: user
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/api.IAMUser'
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/api.IAMUser'
|
||||||
|
"400":
|
||||||
|
description: Bad Request
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/api.Error'
|
||||||
|
"403":
|
||||||
|
description: Forbidden
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/api.Error'
|
||||||
|
"404":
|
||||||
|
description: Not Found
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/api.Error'
|
||||||
|
"500":
|
||||||
|
description: Internal Server Error
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/api.Error'
|
||||||
|
security:
|
||||||
|
- ApiKeyAuth: []
|
||||||
|
summary: Replace an existing user
|
||||||
|
tags:
|
||||||
|
- v16.?.?
|
||||||
/api/v3/cluster/iam/user/{name}/policy:
|
/api/v3/cluster/iam/user/{name}/policy:
|
||||||
put:
|
put:
|
||||||
consumes:
|
consumes:
|
||||||
@@ -2441,6 +2543,10 @@ paths:
|
|||||||
description: Bad Request
|
description: Bad Request
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/api.Error'
|
$ref: '#/definitions/api.Error'
|
||||||
|
"403":
|
||||||
|
description: Forbidden
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/api.Error'
|
||||||
"404":
|
"404":
|
||||||
description: Not Found
|
description: Not Found
|
||||||
schema:
|
schema:
|
||||||
@@ -2454,26 +2560,6 @@ paths:
|
|||||||
summary: Replace policies of an user
|
summary: Replace policies of an user
|
||||||
tags:
|
tags:
|
||||||
- v16.?.?
|
- v16.?.?
|
||||||
/api/v3/cluster/iam/user/reload:
|
|
||||||
get:
|
|
||||||
description: Reload identities
|
|
||||||
operationId: cluster-3-iam-reload-identities
|
|
||||||
produces:
|
|
||||||
- application/json
|
|
||||||
responses:
|
|
||||||
"200":
|
|
||||||
description: OK
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
"500":
|
|
||||||
description: Internal Server Error
|
|
||||||
schema:
|
|
||||||
$ref: '#/definitions/api.Error'
|
|
||||||
security:
|
|
||||||
- ApiKeyAuth: []
|
|
||||||
summary: Reload identities
|
|
||||||
tags:
|
|
||||||
- v16.?.?
|
|
||||||
/api/v3/cluster/node:
|
/api/v3/cluster/node:
|
||||||
get:
|
get:
|
||||||
description: List of proxy nodes in the cluster
|
description: List of proxy nodes in the cluster
|
||||||
@@ -2558,6 +2644,10 @@ paths:
|
|||||||
name: id
|
name: id
|
||||||
required: true
|
required: true
|
||||||
type: string
|
type: string
|
||||||
|
- description: Domain to act on
|
||||||
|
in: query
|
||||||
|
name: domain
|
||||||
|
type: string
|
||||||
produces:
|
produces:
|
||||||
- application/json
|
- application/json
|
||||||
responses:
|
responses:
|
||||||
@@ -2596,7 +2686,7 @@ paths:
|
|||||||
"200":
|
"200":
|
||||||
description: OK
|
description: OK
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/api.ClusterNode'
|
$ref: '#/definitions/api.Version'
|
||||||
"404":
|
"404":
|
||||||
description: Not Found
|
description: Not Found
|
||||||
schema:
|
schema:
|
||||||
@@ -2610,6 +2700,11 @@ paths:
|
|||||||
get:
|
get:
|
||||||
description: List of processes in the cluster
|
description: List of processes in the cluster
|
||||||
operationId: cluster-3-list-all-node-processes
|
operationId: cluster-3-list-all-node-processes
|
||||||
|
parameters:
|
||||||
|
- description: Domain to act on
|
||||||
|
in: query
|
||||||
|
name: domain
|
||||||
|
type: string
|
||||||
produces:
|
produces:
|
||||||
- application/json
|
- application/json
|
||||||
responses:
|
responses:
|
||||||
@@ -2647,6 +2742,10 @@ paths:
|
|||||||
description: Bad Request
|
description: Bad Request
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/api.Error'
|
$ref: '#/definitions/api.Error'
|
||||||
|
"403":
|
||||||
|
description: Forbidden
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/api.Error'
|
||||||
security:
|
security:
|
||||||
- ApiKeyAuth: []
|
- ApiKeyAuth: []
|
||||||
summary: Add a new process
|
summary: Add a new process
|
||||||
@@ -2669,8 +2768,12 @@ paths:
|
|||||||
description: OK
|
description: OK
|
||||||
schema:
|
schema:
|
||||||
type: string
|
type: string
|
||||||
"404":
|
"403":
|
||||||
description: Not Found
|
description: Forbidden
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/api.Error'
|
||||||
|
"500":
|
||||||
|
description: Internal Server Error
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/api.Error'
|
$ref: '#/definitions/api.Error'
|
||||||
security:
|
security:
|
||||||
@@ -2706,6 +2809,10 @@ paths:
|
|||||||
description: Bad Request
|
description: Bad Request
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/api.Error'
|
$ref: '#/definitions/api.Error'
|
||||||
|
"403":
|
||||||
|
description: Forbidden
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/api.Error'
|
||||||
"404":
|
"404":
|
||||||
description: Not Found
|
description: Not Found
|
||||||
schema:
|
schema:
|
||||||
@@ -2725,7 +2832,7 @@ paths:
|
|||||||
"200":
|
"200":
|
||||||
description: OK
|
description: OK
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/github_com_datarhei_core_v16_http_api.Config'
|
$ref: '#/definitions/api.GetConfig'
|
||||||
security:
|
security:
|
||||||
- ApiKeyAuth: []
|
- ApiKeyAuth: []
|
||||||
summary: Retrieve the currently active Restreamer configuration
|
summary: Retrieve the currently active Restreamer configuration
|
||||||
@@ -3278,6 +3385,10 @@ paths:
|
|||||||
listed processes.
|
listed processes.
|
||||||
operationId: process-3-get-all
|
operationId: process-3-get-all
|
||||||
parameters:
|
parameters:
|
||||||
|
- description: Domain to act on
|
||||||
|
in: query
|
||||||
|
name: domain
|
||||||
|
type: string
|
||||||
- description: Comma separated list of fields (config, state, report, metadata)
|
- description: Comma separated list of fields (config, state, report, metadata)
|
||||||
that will be part of the output. If empty, all fields will be part of the
|
that will be part of the output. If empty, all fields will be part of the
|
||||||
output.
|
output.
|
||||||
@@ -3351,6 +3462,10 @@ paths:
|
|||||||
description: Bad Request
|
description: Bad Request
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/api.Error'
|
$ref: '#/definitions/api.Error'
|
||||||
|
"403":
|
||||||
|
description: Forbidden
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/api.Error'
|
||||||
security:
|
security:
|
||||||
- ApiKeyAuth: []
|
- ApiKeyAuth: []
|
||||||
summary: Add a new process
|
summary: Add a new process
|
||||||
@@ -3366,6 +3481,10 @@ paths:
|
|||||||
name: id
|
name: id
|
||||||
required: true
|
required: true
|
||||||
type: string
|
type: string
|
||||||
|
- description: Domain to act on
|
||||||
|
in: query
|
||||||
|
name: domain
|
||||||
|
type: string
|
||||||
produces:
|
produces:
|
||||||
- application/json
|
- application/json
|
||||||
responses:
|
responses:
|
||||||
@@ -3373,6 +3492,10 @@ paths:
|
|||||||
description: OK
|
description: OK
|
||||||
schema:
|
schema:
|
||||||
type: string
|
type: string
|
||||||
|
"403":
|
||||||
|
description: Forbidden
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/api.Error'
|
||||||
"404":
|
"404":
|
||||||
description: Not Found
|
description: Not Found
|
||||||
schema:
|
schema:
|
||||||
@@ -3392,6 +3515,10 @@ paths:
|
|||||||
name: id
|
name: id
|
||||||
required: true
|
required: true
|
||||||
type: string
|
type: string
|
||||||
|
- description: Domain to act on
|
||||||
|
in: query
|
||||||
|
name: domain
|
||||||
|
type: string
|
||||||
- description: Comma separated list of fields (config, state, report, metadata)
|
- description: Comma separated list of fields (config, state, report, metadata)
|
||||||
to be part of the output. If empty, all fields will be part of the output
|
to be part of the output. If empty, all fields will be part of the output
|
||||||
in: query
|
in: query
|
||||||
@@ -3404,6 +3531,10 @@ paths:
|
|||||||
description: OK
|
description: OK
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/api.Process'
|
$ref: '#/definitions/api.Process'
|
||||||
|
"403":
|
||||||
|
description: Forbidden
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/api.Error'
|
||||||
"404":
|
"404":
|
||||||
description: Not Found
|
description: Not Found
|
||||||
schema:
|
schema:
|
||||||
@@ -3424,6 +3555,10 @@ paths:
|
|||||||
name: id
|
name: id
|
||||||
required: true
|
required: true
|
||||||
type: string
|
type: string
|
||||||
|
- description: Domain to act on
|
||||||
|
in: query
|
||||||
|
name: domain
|
||||||
|
type: string
|
||||||
- description: Process config
|
- description: Process config
|
||||||
in: body
|
in: body
|
||||||
name: config
|
name: config
|
||||||
@@ -3441,6 +3576,10 @@ paths:
|
|||||||
description: Bad Request
|
description: Bad Request
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/api.Error'
|
$ref: '#/definitions/api.Error'
|
||||||
|
"403":
|
||||||
|
description: Forbidden
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/api.Error'
|
||||||
"404":
|
"404":
|
||||||
description: Not Found
|
description: Not Found
|
||||||
schema:
|
schema:
|
||||||
@@ -3462,6 +3601,10 @@ paths:
|
|||||||
name: id
|
name: id
|
||||||
required: true
|
required: true
|
||||||
type: string
|
type: string
|
||||||
|
- description: Domain to act on
|
||||||
|
in: query
|
||||||
|
name: domain
|
||||||
|
type: string
|
||||||
- description: Process command
|
- description: Process command
|
||||||
in: body
|
in: body
|
||||||
name: command
|
name: command
|
||||||
@@ -3479,6 +3622,10 @@ paths:
|
|||||||
description: Bad Request
|
description: Bad Request
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/api.Error'
|
$ref: '#/definitions/api.Error'
|
||||||
|
"403":
|
||||||
|
description: Forbidden
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/api.Error'
|
||||||
"404":
|
"404":
|
||||||
description: Not Found
|
description: Not Found
|
||||||
schema:
|
schema:
|
||||||
@@ -3499,6 +3646,10 @@ paths:
|
|||||||
name: id
|
name: id
|
||||||
required: true
|
required: true
|
||||||
type: string
|
type: string
|
||||||
|
- description: Domain to act on
|
||||||
|
in: query
|
||||||
|
name: domain
|
||||||
|
type: string
|
||||||
produces:
|
produces:
|
||||||
- application/json
|
- application/json
|
||||||
responses:
|
responses:
|
||||||
@@ -3510,6 +3661,10 @@ paths:
|
|||||||
description: Bad Request
|
description: Bad Request
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/api.Error'
|
$ref: '#/definitions/api.Error'
|
||||||
|
"403":
|
||||||
|
description: Forbidden
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/api.Error'
|
||||||
"404":
|
"404":
|
||||||
description: Not Found
|
description: Not Found
|
||||||
schema:
|
schema:
|
||||||
@@ -3535,6 +3690,10 @@ paths:
|
|||||||
name: key
|
name: key
|
||||||
required: true
|
required: true
|
||||||
type: string
|
type: string
|
||||||
|
- description: Domain to act on
|
||||||
|
in: query
|
||||||
|
name: domain
|
||||||
|
type: string
|
||||||
produces:
|
produces:
|
||||||
- application/json
|
- application/json
|
||||||
responses:
|
responses:
|
||||||
@@ -3545,6 +3704,10 @@ paths:
|
|||||||
description: Bad Request
|
description: Bad Request
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/api.Error'
|
$ref: '#/definitions/api.Error'
|
||||||
|
"403":
|
||||||
|
description: Forbidden
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/api.Error'
|
||||||
"404":
|
"404":
|
||||||
description: Not Found
|
description: Not Found
|
||||||
schema:
|
schema:
|
||||||
@@ -3570,6 +3733,10 @@ paths:
|
|||||||
name: key
|
name: key
|
||||||
required: true
|
required: true
|
||||||
type: string
|
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
|
- description: Arbitrary JSON data. The null value will remove the key and its
|
||||||
contents
|
contents
|
||||||
in: body
|
in: body
|
||||||
@@ -3586,6 +3753,10 @@ paths:
|
|||||||
description: Bad Request
|
description: Bad Request
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/api.Error'
|
$ref: '#/definitions/api.Error'
|
||||||
|
"403":
|
||||||
|
description: Forbidden
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/api.Error'
|
||||||
"404":
|
"404":
|
||||||
description: Not Found
|
description: Not Found
|
||||||
schema:
|
schema:
|
||||||
@@ -3852,6 +4023,10 @@ paths:
|
|||||||
name: id
|
name: id
|
||||||
required: true
|
required: true
|
||||||
type: string
|
type: string
|
||||||
|
- description: Domain to act on
|
||||||
|
in: query
|
||||||
|
name: domain
|
||||||
|
type: string
|
||||||
produces:
|
produces:
|
||||||
- application/json
|
- application/json
|
||||||
responses:
|
responses:
|
||||||
@@ -3859,6 +4034,10 @@ paths:
|
|||||||
description: OK
|
description: OK
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/api.Probe'
|
$ref: '#/definitions/api.Probe'
|
||||||
|
"403":
|
||||||
|
description: Forbidden
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/api.Error'
|
||||||
security:
|
security:
|
||||||
- ApiKeyAuth: []
|
- ApiKeyAuth: []
|
||||||
summary: Probe a process
|
summary: Probe a process
|
||||||
@@ -3874,6 +4053,10 @@ paths:
|
|||||||
name: id
|
name: id
|
||||||
required: true
|
required: true
|
||||||
type: string
|
type: string
|
||||||
|
- description: Domain to act on
|
||||||
|
in: query
|
||||||
|
name: domain
|
||||||
|
type: string
|
||||||
produces:
|
produces:
|
||||||
- application/json
|
- application/json
|
||||||
responses:
|
responses:
|
||||||
@@ -3885,6 +4068,10 @@ paths:
|
|||||||
description: Bad Request
|
description: Bad Request
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/api.Error'
|
$ref: '#/definitions/api.Error'
|
||||||
|
"403":
|
||||||
|
description: Forbidden
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/api.Error'
|
||||||
"404":
|
"404":
|
||||||
description: Not Found
|
description: Not Found
|
||||||
schema:
|
schema:
|
||||||
@@ -3904,6 +4091,10 @@ paths:
|
|||||||
name: id
|
name: id
|
||||||
required: true
|
required: true
|
||||||
type: string
|
type: string
|
||||||
|
- description: Domain to act on
|
||||||
|
in: query
|
||||||
|
name: domain
|
||||||
|
type: string
|
||||||
produces:
|
produces:
|
||||||
- application/json
|
- application/json
|
||||||
responses:
|
responses:
|
||||||
@@ -3915,6 +4106,10 @@ paths:
|
|||||||
description: Bad Request
|
description: Bad Request
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/api.Error'
|
$ref: '#/definitions/api.Error'
|
||||||
|
"403":
|
||||||
|
description: Forbidden
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/api.Error'
|
||||||
"404":
|
"404":
|
||||||
description: Not Found
|
description: Not Found
|
||||||
schema:
|
schema:
|
||||||
|
@@ -19,8 +19,8 @@ type ConfigData struct {
|
|||||||
config.Data
|
config.Data
|
||||||
}
|
}
|
||||||
|
|
||||||
// Config is the config returned by the API
|
// GetConfig is the config returned by the API
|
||||||
type Config struct {
|
type GetConfig struct {
|
||||||
CreatedAt time.Time `json:"created_at"`
|
CreatedAt time.Time `json:"created_at"`
|
||||||
LoadedAt time.Time `json:"loaded_at"`
|
LoadedAt time.Time `json:"loaded_at"`
|
||||||
UpdatedAt time.Time `json:"updated_at"`
|
UpdatedAt time.Time `json:"updated_at"`
|
||||||
@@ -117,7 +117,7 @@ func (rscfg *SetConfig) MergeTo(cfg *config.Config) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Unmarshal converts a config.Config to a Config.
|
// Unmarshal converts a config.Config to a Config.
|
||||||
func (c *Config) Unmarshal(cfg *config.Config) {
|
func (c *GetConfig) Unmarshal(cfg *config.Config) {
|
||||||
if cfg == nil {
|
if cfg == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@@ -106,6 +106,7 @@ type IAMAuth0Tenant struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type IAMPolicy struct {
|
type IAMPolicy struct {
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
Domain string `json:"domain"`
|
Domain string `json:"domain"`
|
||||||
Resource string `json:"resource"`
|
Resource string `json:"resource"`
|
||||||
Actions []string `json:"actions"`
|
Actions []string `json:"actions"`
|
||||||
|
@@ -54,7 +54,6 @@ func NewCluster(cluster cluster.Cluster, iam iam.IAM) (*ClusterHandler, error) {
|
|||||||
// @ID cluster-3-get-cluster
|
// @ID cluster-3-get-cluster
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Success 200 {object} api.ClusterAbout
|
// @Success 200 {object} api.ClusterAbout
|
||||||
// @Failure 404 {object} api.Error
|
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Router /api/v3/cluster [get]
|
// @Router /api/v3/cluster [get]
|
||||||
func (h *ClusterHandler) About(c echo.Context) error {
|
func (h *ClusterHandler) About(c echo.Context) error {
|
||||||
@@ -91,15 +90,23 @@ func (h *ClusterHandler) About(c echo.Context) error {
|
|||||||
// @Tags v16.?.?
|
// @Tags v16.?.?
|
||||||
// @ID cluster-3-list-all-node-processes
|
// @ID cluster-3-list-all-node-processes
|
||||||
// @Produce json
|
// @Produce json
|
||||||
|
// @Param domain query string false "Domain to act on"
|
||||||
// @Success 200 {array} api.ClusterProcess
|
// @Success 200 {array} api.ClusterProcess
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Router /api/v3/cluster/process [get]
|
// @Router /api/v3/cluster/process [get]
|
||||||
func (h *ClusterHandler) ListAllNodeProcesses(c echo.Context) error {
|
func (h *ClusterHandler) ListAllNodeProcesses(c echo.Context) error {
|
||||||
|
ctxuser := util.DefaultContext(c, "user", "")
|
||||||
|
domain := util.DefaultQuery(c, "domain", "")
|
||||||
|
|
||||||
procs := h.proxy.ListProcesses()
|
procs := h.proxy.ListProcesses()
|
||||||
|
|
||||||
processes := []api.ClusterProcess{}
|
processes := []api.ClusterProcess{}
|
||||||
|
|
||||||
for _, p := range procs {
|
for _, p := range procs {
|
||||||
|
if !h.iam.Enforce(ctxuser, domain, "process:"+p.Config.ID, "read") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
processes = append(processes, api.ClusterProcess{
|
processes = append(processes, api.ClusterProcess{
|
||||||
ProcessID: p.Config.ID,
|
ProcessID: p.Config.ID,
|
||||||
NodeID: p.NodeID,
|
NodeID: p.NodeID,
|
||||||
@@ -193,7 +200,7 @@ func (h *ClusterHandler) GetNode(c echo.Context) error {
|
|||||||
// @ID cluster-3-get-node-version
|
// @ID cluster-3-get-node-version
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Param id path string true "Node ID"
|
// @Param id path string true "Node ID"
|
||||||
// @Success 200 {object} api.ClusterNode
|
// @Success 200 {object} api.Version
|
||||||
// @Failure 404 {object} api.Error
|
// @Failure 404 {object} api.Error
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Router /api/v3/cluster/node/{id}/version [get]
|
// @Router /api/v3/cluster/node/{id}/version [get]
|
||||||
@@ -205,7 +212,16 @@ func (h *ClusterHandler) GetNodeVersion(c echo.Context) error {
|
|||||||
return api.Err(http.StatusNotFound, "Node not found", "%s", err)
|
return api.Err(http.StatusNotFound, "Node not found", "%s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
version := peer.Version()
|
v := peer.Version()
|
||||||
|
|
||||||
|
version := api.Version{
|
||||||
|
Number: v.Number,
|
||||||
|
Commit: v.Commit,
|
||||||
|
Branch: v.Branch,
|
||||||
|
Build: v.Build.Format(time.RFC3339),
|
||||||
|
Arch: v.Arch,
|
||||||
|
Compiler: v.Compiler,
|
||||||
|
}
|
||||||
|
|
||||||
return c.JSON(http.StatusOK, version)
|
return c.JSON(http.StatusOK, version)
|
||||||
}
|
}
|
||||||
@@ -258,12 +274,15 @@ func (h *ClusterHandler) GetNodeFiles(c echo.Context) error {
|
|||||||
// @ID cluster-3-list-node-processes
|
// @ID cluster-3-list-node-processes
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Param id path string true "Node ID"
|
// @Param id path string true "Node ID"
|
||||||
|
// @Param domain query string false "Domain to act on"
|
||||||
// @Success 200 {array} api.ClusterProcess
|
// @Success 200 {array} api.ClusterProcess
|
||||||
// @Failure 404 {object} api.Error
|
// @Failure 404 {object} api.Error
|
||||||
// @Failure 500 {object} api.Error
|
// @Failure 500 {object} api.Error
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Router /api/v3/cluster/node/{id}/process [get]
|
// @Router /api/v3/cluster/node/{id}/process [get]
|
||||||
func (h *ClusterHandler) ListNodeProcesses(c echo.Context) error {
|
func (h *ClusterHandler) ListNodeProcesses(c echo.Context) error {
|
||||||
|
ctxuser := util.DefaultContext(c, "user", "")
|
||||||
|
domain := util.DefaultQuery(c, "domain", "")
|
||||||
id := util.PathParam(c, "id")
|
id := util.PathParam(c, "id")
|
||||||
|
|
||||||
peer, err := h.proxy.GetNode(id)
|
peer, err := h.proxy.GetNode(id)
|
||||||
@@ -279,6 +298,10 @@ func (h *ClusterHandler) ListNodeProcesses(c echo.Context) error {
|
|||||||
processes := []api.ClusterProcess{}
|
processes := []api.ClusterProcess{}
|
||||||
|
|
||||||
for _, p := range procs {
|
for _, p := range procs {
|
||||||
|
if !h.iam.Enforce(ctxuser, domain, "process:"+p.Config.ID, "read") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
processes = append(processes, api.ClusterProcess{
|
processes = append(processes, api.ClusterProcess{
|
||||||
ProcessID: p.Config.ID,
|
ProcessID: p.Config.ID,
|
||||||
NodeID: p.NodeID,
|
NodeID: p.NodeID,
|
||||||
@@ -304,11 +327,18 @@ func (h *ClusterHandler) ListNodeProcesses(c echo.Context) error {
|
|||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Router /api/v3/cluster/db/process [get]
|
// @Router /api/v3/cluster/db/process [get]
|
||||||
func (h *ClusterHandler) ListStoreProcesses(c echo.Context) error {
|
func (h *ClusterHandler) ListStoreProcesses(c echo.Context) error {
|
||||||
|
ctxuser := util.DefaultContext(c, "user", "")
|
||||||
|
domain := util.DefaultQuery(c, "domain", "")
|
||||||
|
|
||||||
procs := h.cluster.ListProcesses()
|
procs := h.cluster.ListProcesses()
|
||||||
|
|
||||||
processes := []api.Process{}
|
processes := []api.Process{}
|
||||||
|
|
||||||
for _, p := range procs {
|
for _, p := range procs {
|
||||||
|
if !h.iam.Enforce(ctxuser, domain, "process:"+p.Config.ID, "read") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
process := api.Process{
|
process := api.Process{
|
||||||
ID: p.Config.ID,
|
ID: p.Config.ID,
|
||||||
Type: "ffmpeg",
|
Type: "ffmpeg",
|
||||||
@@ -338,11 +368,16 @@ func (h *ClusterHandler) ListStoreProcesses(c echo.Context) error {
|
|||||||
// @Param config body api.ProcessConfig true "Process config"
|
// @Param config body api.ProcessConfig true "Process config"
|
||||||
// @Success 200 {object} api.ProcessConfig
|
// @Success 200 {object} api.ProcessConfig
|
||||||
// @Failure 400 {object} api.Error
|
// @Failure 400 {object} api.Error
|
||||||
|
// @Failure 403 {object} api.Error
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Router /api/v3/cluster/process [post]
|
// @Router /api/v3/cluster/process [post]
|
||||||
func (h *ClusterHandler) AddProcess(c echo.Context) error {
|
func (h *ClusterHandler) AddProcess(c echo.Context) error {
|
||||||
|
ctxuser := util.DefaultContext(c, "user", "")
|
||||||
|
superuser := util.DefaultContext(c, "superuser", false)
|
||||||
|
|
||||||
process := api.ProcessConfig{
|
process := api.ProcessConfig{
|
||||||
ID: shortuuid.New(),
|
ID: shortuuid.New(),
|
||||||
|
Owner: ctxuser,
|
||||||
Type: "ffmpeg",
|
Type: "ffmpeg",
|
||||||
Autostart: true,
|
Autostart: true,
|
||||||
}
|
}
|
||||||
@@ -351,6 +386,16 @@ func (h *ClusterHandler) AddProcess(c echo.Context) error {
|
|||||||
return api.Err(http.StatusBadRequest, "Invalid JSON", "%s", err)
|
return api.Err(http.StatusBadRequest, "Invalid JSON", "%s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !h.iam.Enforce(ctxuser, process.Domain, "process:"+process.ID, "write") {
|
||||||
|
return api.Err(http.StatusForbidden, "Forbidden")
|
||||||
|
}
|
||||||
|
|
||||||
|
if !superuser {
|
||||||
|
if !h.iam.Enforce(process.Owner, process.Domain, "process:"+process.ID, "write") {
|
||||||
|
return api.Err(http.StatusForbidden, "Forbidden")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if process.Type != "ffmpeg" {
|
if process.Type != "ffmpeg" {
|
||||||
return api.Err(http.StatusBadRequest, "Unsupported process type", "Supported process types are: ffmpeg")
|
return api.Err(http.StatusBadRequest, "Unsupported process type", "Supported process types are: ffmpeg")
|
||||||
}
|
}
|
||||||
@@ -379,18 +424,28 @@ func (h *ClusterHandler) AddProcess(c echo.Context) error {
|
|||||||
// @Param config body api.ProcessConfig true "Process config"
|
// @Param config body api.ProcessConfig true "Process config"
|
||||||
// @Success 200 {object} api.ProcessConfig
|
// @Success 200 {object} api.ProcessConfig
|
||||||
// @Failure 400 {object} api.Error
|
// @Failure 400 {object} api.Error
|
||||||
|
// @Failure 403 {object} api.Error
|
||||||
// @Failure 404 {object} api.Error
|
// @Failure 404 {object} api.Error
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Router /api/v3/cluster/process/{id} [put]
|
// @Router /api/v3/cluster/process/{id} [put]
|
||||||
func (h *ClusterHandler) UpdateProcess(c echo.Context) error {
|
func (h *ClusterHandler) UpdateProcess(c echo.Context) error {
|
||||||
|
ctxuser := util.DefaultContext(c, "user", "")
|
||||||
|
superuser := util.DefaultContext(c, "superuser", false)
|
||||||
|
domain := util.DefaultQuery(c, "domain", "$none")
|
||||||
id := util.PathParam(c, "id")
|
id := util.PathParam(c, "id")
|
||||||
|
|
||||||
process := api.ProcessConfig{
|
process := api.ProcessConfig{
|
||||||
ID: id,
|
ID: id,
|
||||||
|
Owner: ctxuser,
|
||||||
|
Domain: domain,
|
||||||
Type: "ffmpeg",
|
Type: "ffmpeg",
|
||||||
Autostart: true,
|
Autostart: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !h.iam.Enforce(ctxuser, domain, "process:"+id, "write") {
|
||||||
|
return api.Err(http.StatusForbidden, "Forbidden")
|
||||||
|
}
|
||||||
|
|
||||||
current, err := h.cluster.GetProcess(id)
|
current, err := h.cluster.GetProcess(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return api.Err(http.StatusNotFound, "Process not found", "%s", id)
|
return api.Err(http.StatusNotFound, "Process not found", "%s", id)
|
||||||
@@ -403,6 +458,16 @@ func (h *ClusterHandler) UpdateProcess(c echo.Context) error {
|
|||||||
return api.Err(http.StatusBadRequest, "Invalid JSON", "%s", err)
|
return api.Err(http.StatusBadRequest, "Invalid JSON", "%s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !h.iam.Enforce(ctxuser, process.Domain, "process:"+process.ID, "write") {
|
||||||
|
return api.Err(http.StatusForbidden, "Forbidden")
|
||||||
|
}
|
||||||
|
|
||||||
|
if !superuser {
|
||||||
|
if !h.iam.Enforce(process.Owner, process.Domain, "process:"+process.ID, "write") {
|
||||||
|
return api.Err(http.StatusForbidden, "Forbidden")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
config := process.Marshal()
|
config := process.Marshal()
|
||||||
|
|
||||||
if err := h.cluster.UpdateProcess("", id, config); err != nil {
|
if err := h.cluster.UpdateProcess("", id, config); err != nil {
|
||||||
@@ -424,12 +489,19 @@ func (h *ClusterHandler) UpdateProcess(c echo.Context) error {
|
|||||||
// @Produce json
|
// @Produce json
|
||||||
// @Param id path string true "Process ID"
|
// @Param id path string true "Process ID"
|
||||||
// @Success 200 {string} string
|
// @Success 200 {string} string
|
||||||
// @Failure 404 {object} api.Error
|
// @Failure 403 {object} api.Error
|
||||||
|
// @Failure 500 {object} api.Error
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Router /api/v3/cluster/process/{id} [delete]
|
// @Router /api/v3/cluster/process/{id} [delete]
|
||||||
func (h *ClusterHandler) DeleteProcess(c echo.Context) error {
|
func (h *ClusterHandler) DeleteProcess(c echo.Context) error {
|
||||||
|
ctxuser := util.DefaultContext(c, "user", "")
|
||||||
|
domain := util.DefaultQuery(c, "domain", "$none")
|
||||||
id := util.PathParam(c, "id")
|
id := util.PathParam(c, "id")
|
||||||
|
|
||||||
|
if !h.iam.Enforce(ctxuser, domain, "process:"+id, "write") {
|
||||||
|
return api.Err(http.StatusForbidden, "", "Not allowed to delete process")
|
||||||
|
}
|
||||||
|
|
||||||
if err := h.cluster.RemoveProcess("", id); err != nil {
|
if err := h.cluster.RemoveProcess("", id); err != nil {
|
||||||
return api.Err(http.StatusInternalServerError, "Process can't be deleted", "%s", err)
|
return api.Err(http.StatusInternalServerError, "Process can't be deleted", "%s", err)
|
||||||
}
|
}
|
||||||
@@ -447,28 +519,128 @@ func (h *ClusterHandler) DeleteProcess(c echo.Context) error {
|
|||||||
// @Param config body api.IAMUser true "Identity"
|
// @Param config body api.IAMUser true "Identity"
|
||||||
// @Success 200 {object} api.IAMUser
|
// @Success 200 {object} api.IAMUser
|
||||||
// @Failure 400 {object} api.Error
|
// @Failure 400 {object} api.Error
|
||||||
|
// @Failure 403 {object} api.Error
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Router /api/v3/cluster/iam/user [post]
|
// @Router /api/v3/cluster/iam/user [post]
|
||||||
func (h *ClusterHandler) AddIdentity(c echo.Context) error {
|
func (h *ClusterHandler) AddIdentity(c echo.Context) error {
|
||||||
|
ctxuser := util.DefaultContext(c, "user", "")
|
||||||
|
superuser := util.DefaultContext(c, "superuser", false)
|
||||||
|
domain := util.DefaultQuery(c, "domain", "$none")
|
||||||
|
|
||||||
user := api.IAMUser{}
|
user := api.IAMUser{}
|
||||||
|
|
||||||
if err := util.ShouldBindJSON(c, &user); err != nil {
|
if err := util.ShouldBindJSON(c, &user); err != nil {
|
||||||
return api.Err(http.StatusBadRequest, "Invalid JSON", "%s", err)
|
return api.Err(http.StatusBadRequest, "Invalid JSON", "%s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
identity, policies := user.Unmarshal()
|
iamuser, iampolicies := user.Unmarshal()
|
||||||
|
|
||||||
if err := h.cluster.AddIdentity("", identity); err != nil {
|
if !h.iam.Enforce(ctxuser, domain, "iam:"+iamuser.Name, "write") {
|
||||||
|
return api.Err(http.StatusForbidden, "Forbidden", "Not allowed to create user '%s'", iamuser.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, p := range iampolicies {
|
||||||
|
if !h.iam.Enforce(ctxuser, p.Domain, "iam:"+iamuser.Name, "write") {
|
||||||
|
return api.Err(http.StatusForbidden, "Forbidden", "Not allowed to write policy: %v", p)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !superuser && iamuser.Superuser {
|
||||||
|
return api.Err(http.StatusForbidden, "Forbidden", "Only superusers can add superusers")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := h.cluster.AddIdentity("", iamuser); err != nil {
|
||||||
return api.Err(http.StatusBadRequest, "Invalid identity", "%s", err.Error())
|
return api.Err(http.StatusBadRequest, "Invalid identity", "%s", err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := h.cluster.SetPolicies("", identity.Name, policies); err != nil {
|
if err := h.cluster.SetPolicies("", iamuser.Name, iampolicies); err != nil {
|
||||||
return api.Err(http.StatusBadRequest, "Invalid policies", "%s", err.Error())
|
return api.Err(http.StatusBadRequest, "Invalid policies", "%s", err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.JSON(http.StatusOK, user)
|
return c.JSON(http.StatusOK, user)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UpdateIdentity replaces an existing user
|
||||||
|
// @Summary Replace an existing user
|
||||||
|
// @Description Replace an existing user.
|
||||||
|
// @Tags v16.?.?
|
||||||
|
// @ID cluster-3-update-identity
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param name path string true "Username"
|
||||||
|
// @Param domain query string false "Domain of the acting user"
|
||||||
|
// @Param user body api.IAMUser true "User definition"
|
||||||
|
// @Success 200 {object} api.IAMUser
|
||||||
|
// @Failure 400 {object} api.Error
|
||||||
|
// @Failure 403 {object} api.Error
|
||||||
|
// @Failure 404 {object} api.Error
|
||||||
|
// @Failure 500 {object} api.Error
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Router /api/v3/cluster/iam/user/{name} [put]
|
||||||
|
func (h *ClusterHandler) UpdateIdentity(c echo.Context) error {
|
||||||
|
ctxuser := util.DefaultContext(c, "user", "")
|
||||||
|
superuser := util.DefaultContext(c, "superuser", false)
|
||||||
|
domain := util.DefaultQuery(c, "domain", "$none")
|
||||||
|
name := util.PathParam(c, "name")
|
||||||
|
|
||||||
|
if !h.iam.Enforce(ctxuser, domain, "iam:"+name, "write") {
|
||||||
|
return api.Err(http.StatusForbidden, "Forbidden", "Not allowed to modify this user")
|
||||||
|
}
|
||||||
|
|
||||||
|
var iamuser identity.User
|
||||||
|
var err error
|
||||||
|
|
||||||
|
if name != "$anon" {
|
||||||
|
iamuser, err = h.iam.GetIdentity(name)
|
||||||
|
if err != nil {
|
||||||
|
return api.Err(http.StatusNotFound, "Not found", "%s", err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
iamuser = identity.User{
|
||||||
|
Name: "$anon",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
iampolicies := h.iam.ListPolicies(name, "", "", nil)
|
||||||
|
|
||||||
|
user := api.IAMUser{}
|
||||||
|
user.Marshal(iamuser, iampolicies)
|
||||||
|
|
||||||
|
if err := util.ShouldBindJSON(c, &user); err != nil {
|
||||||
|
return api.Err(http.StatusBadRequest, "Invalid JSON", "%s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
iamuser, iampolicies = user.Unmarshal()
|
||||||
|
|
||||||
|
if !h.iam.Enforce(ctxuser, domain, "iam:"+iamuser.Name, "write") {
|
||||||
|
return api.Err(http.StatusForbidden, "Forbidden", "Not allowed to create user '%s'", iamuser.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, p := range iampolicies {
|
||||||
|
if !h.iam.Enforce(ctxuser, p.Domain, "iam:"+iamuser.Name, "write") {
|
||||||
|
return api.Err(http.StatusForbidden, "Forbidden", "Not allowed to write policy: %v", p)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !superuser && iamuser.Superuser {
|
||||||
|
return api.Err(http.StatusForbidden, "Forbidden", "Only superusers can modify superusers")
|
||||||
|
}
|
||||||
|
|
||||||
|
if name != "$anon" {
|
||||||
|
err = h.cluster.UpdateIdentity("", name, iamuser)
|
||||||
|
if err != nil {
|
||||||
|
return api.Err(http.StatusBadRequest, "Bad request", "%s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err = h.cluster.SetPolicies("", name, iampolicies)
|
||||||
|
if err != nil {
|
||||||
|
return api.Err(http.StatusInternalServerError, "", "set policies: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(http.StatusOK, user)
|
||||||
|
}
|
||||||
|
|
||||||
// UpdateIdentityPolicies replaces existing user policies
|
// UpdateIdentityPolicies replaces existing user policies
|
||||||
// @Summary Replace policies of an user
|
// @Summary Replace policies of an user
|
||||||
// @Description Replace policies of an user
|
// @Description Replace policies of an user
|
||||||
@@ -481,6 +653,7 @@ func (h *ClusterHandler) AddIdentity(c echo.Context) error {
|
|||||||
// @Param user body []api.IAMPolicy true "Policy definitions"
|
// @Param user body []api.IAMPolicy true "Policy definitions"
|
||||||
// @Success 200 {array} api.IAMPolicy
|
// @Success 200 {array} api.IAMPolicy
|
||||||
// @Failure 400 {object} api.Error
|
// @Failure 400 {object} api.Error
|
||||||
|
// @Failure 403 {object} api.Error
|
||||||
// @Failure 404 {object} api.Error
|
// @Failure 404 {object} api.Error
|
||||||
// @Failure 500 {object} api.Error
|
// @Failure 500 {object} api.Error
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
@@ -559,9 +732,111 @@ func (h *ClusterHandler) UpdateIdentityPolicies(c echo.Context) error {
|
|||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Router /api/v3/cluster/db/user [get]
|
// @Router /api/v3/cluster/db/user [get]
|
||||||
func (h *ClusterHandler) ListStoreIdentities(c echo.Context) error {
|
func (h *ClusterHandler) ListStoreIdentities(c echo.Context) error {
|
||||||
identities := h.cluster.ListIdentities()
|
ctxuser := util.DefaultContext(c, "user", "")
|
||||||
|
domain := util.DefaultQuery(c, "domain", "$none")
|
||||||
|
|
||||||
return c.JSON(http.StatusOK, identities)
|
updatedAt, identities := h.cluster.ListIdentities()
|
||||||
|
|
||||||
|
users := make([]api.IAMUser, len(identities))
|
||||||
|
|
||||||
|
for i, iamuser := range identities {
|
||||||
|
if !h.iam.Enforce(ctxuser, domain, "iam:"+iamuser.Name, "read") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if !h.iam.Enforce(ctxuser, domain, "iam:"+iamuser.Name, "write") {
|
||||||
|
iamuser = identity.User{
|
||||||
|
Name: iamuser.Name,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_, policies := h.cluster.ListUserPolicies(iamuser.Name)
|
||||||
|
users[i].Marshal(iamuser, policies)
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Response().Header().Set("Last-Modified", updatedAt.UTC().Format("Mon, 02 Jan 2006 15:04:05 GMT"))
|
||||||
|
|
||||||
|
return c.JSON(http.StatusOK, users)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListStoreIdentity returns the list of identities stored in the DB of the cluster
|
||||||
|
// @Summary List of identities in the cluster
|
||||||
|
// @Description List of identities in the cluster
|
||||||
|
// @Tags v16.?.?
|
||||||
|
// @ID cluster-3-db-list-identity
|
||||||
|
// @Produce json
|
||||||
|
// @Success 200 {object} api.IAMUser
|
||||||
|
// @Failure 403 {object} api.Error
|
||||||
|
// @Failure 404 {object} api.Error
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Router /api/v3/cluster/db/user/{name} [get]
|
||||||
|
func (h *ClusterHandler) ListStoreIdentity(c echo.Context) error {
|
||||||
|
ctxuser := util.DefaultContext(c, "user", "")
|
||||||
|
domain := util.DefaultQuery(c, "domain", "$none")
|
||||||
|
name := util.PathParam(c, "name")
|
||||||
|
|
||||||
|
if !h.iam.Enforce(ctxuser, domain, "iam:"+name, "read") {
|
||||||
|
return api.Err(http.StatusForbidden, "Forbidden", "Not allowed to access this user")
|
||||||
|
}
|
||||||
|
|
||||||
|
var updatedAt time.Time
|
||||||
|
var iamuser identity.User
|
||||||
|
var err error
|
||||||
|
|
||||||
|
if name != "$anon" {
|
||||||
|
updatedAt, iamuser, err = h.cluster.ListIdentity(name)
|
||||||
|
if err != nil {
|
||||||
|
return api.Err(http.StatusNotFound, "", "%s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if ctxuser != iamuser.Name {
|
||||||
|
if !h.iam.Enforce(ctxuser, domain, "iam:"+name, "write") {
|
||||||
|
iamuser = identity.User{
|
||||||
|
Name: iamuser.Name,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
iamuser = identity.User{
|
||||||
|
Name: "$anon",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
policiesUpdatedAt, policies := h.cluster.ListUserPolicies(name)
|
||||||
|
if updatedAt.IsZero() {
|
||||||
|
updatedAt = policiesUpdatedAt
|
||||||
|
}
|
||||||
|
|
||||||
|
user := api.IAMUser{}
|
||||||
|
user.Marshal(iamuser, policies)
|
||||||
|
|
||||||
|
c.Response().Header().Set("Last-Modified", updatedAt.UTC().Format("Mon, 02 Jan 2006 15:04:05 GMT"))
|
||||||
|
|
||||||
|
return c.JSON(http.StatusOK, user)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReloadIAM reloads the identities and policies from the cluster store to IAM
|
||||||
|
// @Summary Reload identities and policies
|
||||||
|
// @Description Reload identities and policies
|
||||||
|
// @Tags v16.?.?
|
||||||
|
// @ID cluster-3-iam-reload
|
||||||
|
// @Produce json
|
||||||
|
// @Success 200 {string} string
|
||||||
|
// @Success 500 {object} api.Error
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Router /api/v3/cluster/iam/reload [get]
|
||||||
|
func (h *ClusterHandler) ReloadIAM(c echo.Context) error {
|
||||||
|
err := h.iam.ReloadIndentities()
|
||||||
|
if err != nil {
|
||||||
|
return api.Err(http.StatusInternalServerError, "", "reload identities: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = h.iam.ReloadPolicies()
|
||||||
|
if err != nil {
|
||||||
|
return api.Err(http.StatusInternalServerError, "", "reload policies: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(http.StatusOK, "OK")
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListIdentities returns the list of identities stored in IAM
|
// ListIdentities returns the list of identities stored in IAM
|
||||||
@@ -574,28 +849,80 @@ func (h *ClusterHandler) ListStoreIdentities(c echo.Context) error {
|
|||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Router /api/v3/cluster/iam/user [get]
|
// @Router /api/v3/cluster/iam/user [get]
|
||||||
func (h *ClusterHandler) ListIdentities(c echo.Context) error {
|
func (h *ClusterHandler) ListIdentities(c echo.Context) error {
|
||||||
|
ctxuser := util.DefaultContext(c, "user", "")
|
||||||
|
domain := util.DefaultQuery(c, "domain", "$none")
|
||||||
|
|
||||||
identities := h.iam.ListIdentities()
|
identities := h.iam.ListIdentities()
|
||||||
|
|
||||||
return c.JSON(http.StatusOK, identities)
|
users := make([]api.IAMUser, len(identities))
|
||||||
}
|
|
||||||
|
|
||||||
// ReloadIdentities reloads the identities from the cluster store to IAM
|
for i, iamuser := range identities {
|
||||||
// @Summary Reload identities
|
if !h.iam.Enforce(ctxuser, domain, "iam:"+iamuser.Name, "read") {
|
||||||
// @Description Reload identities
|
continue
|
||||||
// @Tags v16.?.?
|
}
|
||||||
// @ID cluster-3-iam-reload-identities
|
|
||||||
// @Produce json
|
if !h.iam.Enforce(ctxuser, domain, "iam:"+iamuser.Name, "write") {
|
||||||
// @Success 200 {string} string
|
iamuser = identity.User{
|
||||||
// @Success 500 {object} api.Error
|
Name: iamuser.Name,
|
||||||
// @Security ApiKeyAuth
|
}
|
||||||
// @Router /api/v3/cluster/iam/user/reload [get]
|
}
|
||||||
func (h *ClusterHandler) ReloadIdentities(c echo.Context) error {
|
|
||||||
err := h.iam.ReloadIndentities()
|
policies := h.iam.ListPolicies(iamuser.Name, "", "", nil)
|
||||||
if err != nil {
|
|
||||||
return api.Err(http.StatusInternalServerError, "", "reload identities: %w", err)
|
users[i].Marshal(iamuser, policies)
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.JSON(http.StatusOK, "OK")
|
return c.JSON(http.StatusOK, users)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListIdentity returns the identity stored in IAM
|
||||||
|
// @Summary Identity in IAM
|
||||||
|
// @Description Identity in IAM
|
||||||
|
// @Tags v16.?.?
|
||||||
|
// @ID cluster-3-iam-list-identity
|
||||||
|
// @Produce json
|
||||||
|
// @Success 200 {object} api.IAMUser
|
||||||
|
// @Failure 403 {object} api.Error
|
||||||
|
// @Failure 404 {object} api.Error
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Router /api/v3/cluster/iam/user/{name} [get]
|
||||||
|
func (h *ClusterHandler) ListIdentity(c echo.Context) error {
|
||||||
|
ctxuser := util.DefaultContext(c, "user", "")
|
||||||
|
domain := util.DefaultQuery(c, "domain", "$none")
|
||||||
|
name := util.PathParam(c, "name")
|
||||||
|
|
||||||
|
if !h.iam.Enforce(ctxuser, domain, "iam:"+name, "read") {
|
||||||
|
return api.Err(http.StatusForbidden, "", "Not allowed to access this user")
|
||||||
|
}
|
||||||
|
|
||||||
|
var iamuser identity.User
|
||||||
|
var err error
|
||||||
|
|
||||||
|
if name != "$anon" {
|
||||||
|
iamuser, err = h.iam.GetIdentity(name)
|
||||||
|
if err != nil {
|
||||||
|
return api.Err(http.StatusNotFound, "", "%s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if ctxuser != iamuser.Name {
|
||||||
|
if !h.iam.Enforce(ctxuser, domain, "iam:"+name, "write") {
|
||||||
|
iamuser = identity.User{
|
||||||
|
Name: iamuser.Name,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
iamuser = identity.User{
|
||||||
|
Name: "$anon",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
iampolicies := h.iam.ListPolicies(name, "", "", nil)
|
||||||
|
|
||||||
|
user := api.IAMUser{}
|
||||||
|
user.Marshal(iamuser, iampolicies)
|
||||||
|
|
||||||
|
return c.JSON(http.StatusOK, user)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListStorePolicies returns the list of policies stored in the DB of the cluster
|
// ListStorePolicies returns the list of policies stored in the DB of the cluster
|
||||||
@@ -608,7 +935,20 @@ func (h *ClusterHandler) ReloadIdentities(c echo.Context) error {
|
|||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Router /api/v3/cluster/db/policies [get]
|
// @Router /api/v3/cluster/db/policies [get]
|
||||||
func (h *ClusterHandler) ListStorePolicies(c echo.Context) error {
|
func (h *ClusterHandler) ListStorePolicies(c echo.Context) error {
|
||||||
policies := h.cluster.ListPolicies()
|
updatedAt, clusterpolicies := h.cluster.ListPolicies()
|
||||||
|
|
||||||
|
policies := []api.IAMPolicy{}
|
||||||
|
|
||||||
|
for _, pol := range clusterpolicies {
|
||||||
|
policies = append(policies, api.IAMPolicy{
|
||||||
|
Name: pol.Name,
|
||||||
|
Domain: pol.Domain,
|
||||||
|
Resource: pol.Resource,
|
||||||
|
Actions: pol.Actions,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Response().Header().Set("Last-Modified", updatedAt.UTC().Format("Mon, 02 Jan 2006 15:04:05 GMT"))
|
||||||
|
|
||||||
return c.JSON(http.StatusOK, policies)
|
return c.JSON(http.StatusOK, policies)
|
||||||
}
|
}
|
||||||
@@ -623,28 +963,20 @@ func (h *ClusterHandler) ListStorePolicies(c echo.Context) error {
|
|||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Router /api/v3/cluster/iam/policies [get]
|
// @Router /api/v3/cluster/iam/policies [get]
|
||||||
func (h *ClusterHandler) ListPolicies(c echo.Context) error {
|
func (h *ClusterHandler) ListPolicies(c echo.Context) error {
|
||||||
policies := h.iam.ListPolicies("", "", "", nil)
|
iampolicies := h.iam.ListPolicies("", "", "", nil)
|
||||||
|
|
||||||
return c.JSON(http.StatusOK, policies)
|
policies := []api.IAMPolicy{}
|
||||||
}
|
|
||||||
|
|
||||||
// ReloadPolicies reloads the policies from the cluster store to IAM
|
for _, pol := range iampolicies {
|
||||||
// @Summary Reload policies
|
policies = append(policies, api.IAMPolicy{
|
||||||
// @Description Reload policies
|
Name: pol.Name,
|
||||||
// @Tags v16.?.?
|
Domain: pol.Domain,
|
||||||
// @ID cluster-3-iam-reload-policies
|
Resource: pol.Resource,
|
||||||
// @Produce json
|
Actions: pol.Actions,
|
||||||
// @Success 200 {string} string
|
})
|
||||||
// @Success 500 {object} api.Error
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Router /api/v3/cluster/iam/policies/reload [get]
|
|
||||||
func (h *ClusterHandler) ReloadPolicies(c echo.Context) error {
|
|
||||||
err := h.iam.ReloadPolicies()
|
|
||||||
if err != nil {
|
|
||||||
return api.Err(http.StatusInternalServerError, "", "reload policies: %w", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.JSON(http.StatusOK, "OK")
|
return c.JSON(http.StatusOK, policies)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete deletes the identity with the given name from the cluster
|
// Delete deletes the identity with the given name from the cluster
|
||||||
@@ -655,12 +987,29 @@ func (h *ClusterHandler) ReloadPolicies(c echo.Context) error {
|
|||||||
// @Produce json
|
// @Produce json
|
||||||
// @Param name path string true "Identity name"
|
// @Param name path string true "Identity name"
|
||||||
// @Success 200 {string} string
|
// @Success 200 {string} string
|
||||||
|
// @Failure 403 {object} api.Error
|
||||||
// @Failure 404 {object} api.Error
|
// @Failure 404 {object} api.Error
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Router /api/v3/cluster/iam/user/{name} [delete]
|
// @Router /api/v3/cluster/iam/user/{name} [delete]
|
||||||
func (h *ClusterHandler) RemoveIdentity(c echo.Context) error {
|
func (h *ClusterHandler) RemoveIdentity(c echo.Context) error {
|
||||||
|
ctxuser := util.DefaultContext(c, "user", "")
|
||||||
|
superuser := util.DefaultContext(c, "superuser", false)
|
||||||
|
domain := util.DefaultQuery(c, "domain", "$none")
|
||||||
name := util.PathParam(c, "name")
|
name := util.PathParam(c, "name")
|
||||||
|
|
||||||
|
if !h.iam.Enforce(ctxuser, domain, "iam:"+name, "write") {
|
||||||
|
return api.Err(http.StatusForbidden, "Forbidden", "Not allowed to delete this user")
|
||||||
|
}
|
||||||
|
|
||||||
|
iamuser, err := h.iam.GetIdentity(name)
|
||||||
|
if err != nil {
|
||||||
|
return api.Err(http.StatusNotFound, "Not found", "%s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !superuser && iamuser.Superuser {
|
||||||
|
return api.Err(http.StatusForbidden, "Forbidden", "Only superusers can remove superusers")
|
||||||
|
}
|
||||||
|
|
||||||
if err := h.cluster.RemoveIdentity("", name); err != nil {
|
if err := h.cluster.RemoveIdentity("", name); err != nil {
|
||||||
return api.Err(http.StatusBadRequest, "Invalid identity", "%s", err.Error())
|
return api.Err(http.StatusBadRequest, "Invalid identity", "%s", err.Error())
|
||||||
}
|
}
|
||||||
|
@@ -32,13 +32,13 @@ func NewConfig(store cfgstore.Store) *ConfigHandler {
|
|||||||
// @Tags v16.7.2
|
// @Tags v16.7.2
|
||||||
// @ID config-3-get
|
// @ID config-3-get
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Success 200 {object} api.Config
|
// @Success 200 {object} api.GetConfig
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Router /api/v3/config [get]
|
// @Router /api/v3/config [get]
|
||||||
func (p *ConfigHandler) Get(c echo.Context) error {
|
func (p *ConfigHandler) Get(c echo.Context) error {
|
||||||
cfg := p.store.GetActive()
|
cfg := p.store.GetActive()
|
||||||
|
|
||||||
apicfg := api.Config{}
|
apicfg := api.GetConfig{}
|
||||||
apicfg.Unmarshal(cfg)
|
apicfg.Unmarshal(cfg)
|
||||||
|
|
||||||
return c.JSON(http.StatusOK, apicfg)
|
return c.JSON(http.StatusOK, apicfg)
|
||||||
|
@@ -21,7 +21,7 @@ func NewIAM(iam iam.IAM) *IAMHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddUser adds a new user
|
// AddIdentity adds a new user
|
||||||
// @Summary Add a new user
|
// @Summary Add a new user
|
||||||
// @Description Add a new user
|
// @Description Add a new user
|
||||||
// @Tags v16.?.?
|
// @Tags v16.?.?
|
||||||
@@ -35,7 +35,7 @@ func NewIAM(iam iam.IAM) *IAMHandler {
|
|||||||
// @Failure 500 {object} api.Error
|
// @Failure 500 {object} api.Error
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Router /api/v3/iam/user [post]
|
// @Router /api/v3/iam/user [post]
|
||||||
func (h *IAMHandler) AddUser(c echo.Context) error {
|
func (h *IAMHandler) AddIdentity(c echo.Context) error {
|
||||||
ctxuser := util.DefaultContext(c, "user", "")
|
ctxuser := util.DefaultContext(c, "user", "")
|
||||||
superuser := util.DefaultContext(c, "superuser", false)
|
superuser := util.DefaultContext(c, "superuser", false)
|
||||||
domain := util.DefaultQuery(c, "domain", "$none")
|
domain := util.DefaultQuery(c, "domain", "$none")
|
||||||
@@ -74,7 +74,7 @@ func (h *IAMHandler) AddUser(c echo.Context) error {
|
|||||||
return c.JSON(http.StatusOK, user)
|
return c.JSON(http.StatusOK, user)
|
||||||
}
|
}
|
||||||
|
|
||||||
// RemoveUser deletes the user with the given name
|
// RemoveIdentity deletes the user with the given name
|
||||||
// @Summary Delete an user by its name
|
// @Summary Delete an user by its name
|
||||||
// @Description Delete an user by its name
|
// @Description Delete an user by its name
|
||||||
// @Tags v16.?.?
|
// @Tags v16.?.?
|
||||||
@@ -87,7 +87,7 @@ func (h *IAMHandler) AddUser(c echo.Context) error {
|
|||||||
// @Failure 500 {object} api.Error
|
// @Failure 500 {object} api.Error
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Router /api/v3/iam/user/{name} [delete]
|
// @Router /api/v3/iam/user/{name} [delete]
|
||||||
func (h *IAMHandler) RemoveUser(c echo.Context) error {
|
func (h *IAMHandler) RemoveIdentity(c echo.Context) error {
|
||||||
ctxuser := util.DefaultContext(c, "user", "")
|
ctxuser := util.DefaultContext(c, "user", "")
|
||||||
superuser := util.DefaultContext(c, "superuser", false)
|
superuser := util.DefaultContext(c, "superuser", false)
|
||||||
domain := util.DefaultQuery(c, "domain", "$none")
|
domain := util.DefaultQuery(c, "domain", "$none")
|
||||||
@@ -118,7 +118,7 @@ func (h *IAMHandler) RemoveUser(c echo.Context) error {
|
|||||||
return c.JSON(http.StatusOK, "OK")
|
return c.JSON(http.StatusOK, "OK")
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateUser replaces an existing user
|
// UpdateIdentity replaces an existing user
|
||||||
// @Summary Replace an existing user
|
// @Summary Replace an existing user
|
||||||
// @Description Replace an existing user.
|
// @Description Replace an existing user.
|
||||||
// @Tags v16.?.?
|
// @Tags v16.?.?
|
||||||
@@ -134,7 +134,7 @@ func (h *IAMHandler) RemoveUser(c echo.Context) error {
|
|||||||
// @Failure 500 {object} api.Error
|
// @Failure 500 {object} api.Error
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Router /api/v3/iam/user/{name} [put]
|
// @Router /api/v3/iam/user/{name} [put]
|
||||||
func (h *IAMHandler) UpdateUser(c echo.Context) error {
|
func (h *IAMHandler) UpdateIdentity(c echo.Context) error {
|
||||||
ctxuser := util.DefaultContext(c, "user", "")
|
ctxuser := util.DefaultContext(c, "user", "")
|
||||||
superuser := util.DefaultContext(c, "superuser", false)
|
superuser := util.DefaultContext(c, "superuser", false)
|
||||||
domain := util.DefaultQuery(c, "domain", "$none")
|
domain := util.DefaultQuery(c, "domain", "$none")
|
||||||
@@ -199,7 +199,7 @@ func (h *IAMHandler) UpdateUser(c echo.Context) error {
|
|||||||
return c.JSON(http.StatusOK, user)
|
return c.JSON(http.StatusOK, user)
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateUserPolicies replaces existing user policies
|
// UpdateIdentityPolicies replaces existing user policies
|
||||||
// @Summary Replace policies of an user
|
// @Summary Replace policies of an user
|
||||||
// @Description Replace policies of an user
|
// @Description Replace policies of an user
|
||||||
// @Tags v16.?.?
|
// @Tags v16.?.?
|
||||||
@@ -215,7 +215,7 @@ func (h *IAMHandler) UpdateUser(c echo.Context) error {
|
|||||||
// @Failure 500 {object} api.Error
|
// @Failure 500 {object} api.Error
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Router /api/v3/iam/user/{name}/policy [put]
|
// @Router /api/v3/iam/user/{name}/policy [put]
|
||||||
func (h *IAMHandler) UpdateUserPolicies(c echo.Context) error {
|
func (h *IAMHandler) UpdateIdentityPolicies(c echo.Context) error {
|
||||||
ctxuser := util.DefaultContext(c, "user", "")
|
ctxuser := util.DefaultContext(c, "user", "")
|
||||||
superuser := util.DefaultContext(c, "superuser", false)
|
superuser := util.DefaultContext(c, "superuser", false)
|
||||||
domain := util.DefaultQuery(c, "domain", "$none")
|
domain := util.DefaultQuery(c, "domain", "$none")
|
||||||
@@ -271,7 +271,7 @@ func (h *IAMHandler) UpdateUserPolicies(c echo.Context) error {
|
|||||||
return c.JSON(http.StatusOK, policies)
|
return c.JSON(http.StatusOK, policies)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetUser returns the user with the given name
|
// GetIdentity returns the user with the given name
|
||||||
// @Summary List an user by its name
|
// @Summary List an user by its name
|
||||||
// @Description List aa user by its name
|
// @Description List aa user by its name
|
||||||
// @Tags v16.?.?
|
// @Tags v16.?.?
|
||||||
@@ -283,9 +283,8 @@ func (h *IAMHandler) UpdateUserPolicies(c echo.Context) error {
|
|||||||
// @Failure 404 {object} api.Error
|
// @Failure 404 {object} api.Error
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Router /api/v3/iam/user/{name} [get]
|
// @Router /api/v3/iam/user/{name} [get]
|
||||||
func (h *IAMHandler) GetUser(c echo.Context) error {
|
func (h *IAMHandler) GetIdentity(c echo.Context) error {
|
||||||
ctxuser := util.DefaultContext(c, "user", "")
|
ctxuser := util.DefaultContext(c, "user", "")
|
||||||
superuser := util.DefaultContext(c, "superuser", false)
|
|
||||||
domain := util.DefaultQuery(c, "domain", "$none")
|
domain := util.DefaultQuery(c, "domain", "$none")
|
||||||
name := util.PathParam(c, "name")
|
name := util.PathParam(c, "name")
|
||||||
|
|
||||||
@@ -302,7 +301,7 @@ func (h *IAMHandler) GetUser(c echo.Context) error {
|
|||||||
return api.Err(http.StatusNotFound, "Not found", "%s", err)
|
return api.Err(http.StatusNotFound, "Not found", "%s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !superuser && name != iamuser.Name {
|
if ctxuser != iamuser.Name {
|
||||||
if !h.iam.Enforce(ctxuser, domain, "iam:"+name, "write") {
|
if !h.iam.Enforce(ctxuser, domain, "iam:"+name, "write") {
|
||||||
iamuser = identity.User{
|
iamuser = identity.User{
|
||||||
Name: iamuser.Name,
|
Name: iamuser.Name,
|
||||||
|
@@ -37,15 +37,16 @@ func NewRestream(restream restream.Restreamer, iam iam.IAM) *RestreamHandler {
|
|||||||
// @Param config body api.ProcessConfig true "Process config"
|
// @Param config body api.ProcessConfig true "Process config"
|
||||||
// @Success 200 {object} api.ProcessConfig
|
// @Success 200 {object} api.ProcessConfig
|
||||||
// @Failure 400 {object} api.Error
|
// @Failure 400 {object} api.Error
|
||||||
|
// @Failure 403 {object} api.Error
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Router /api/v3/process [post]
|
// @Router /api/v3/process [post]
|
||||||
func (h *RestreamHandler) Add(c echo.Context) error {
|
func (h *RestreamHandler) Add(c echo.Context) error {
|
||||||
user := util.DefaultContext(c, "user", "")
|
ctxuser := util.DefaultContext(c, "user", "")
|
||||||
superuser := util.DefaultContext(c, "superuser", false)
|
superuser := util.DefaultContext(c, "superuser", false)
|
||||||
|
|
||||||
process := api.ProcessConfig{
|
process := api.ProcessConfig{
|
||||||
ID: shortuuid.New(),
|
ID: shortuuid.New(),
|
||||||
Owner: user,
|
Owner: ctxuser,
|
||||||
Type: "ffmpeg",
|
Type: "ffmpeg",
|
||||||
Autostart: true,
|
Autostart: true,
|
||||||
}
|
}
|
||||||
@@ -54,6 +55,10 @@ func (h *RestreamHandler) Add(c echo.Context) error {
|
|||||||
return api.Err(http.StatusBadRequest, "Invalid JSON", "%s", err)
|
return api.Err(http.StatusBadRequest, "Invalid JSON", "%s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !h.iam.Enforce(ctxuser, process.Domain, "process:"+process.ID, "write") {
|
||||||
|
return api.Err(http.StatusForbidden, "Forbidden")
|
||||||
|
}
|
||||||
|
|
||||||
if !superuser {
|
if !superuser {
|
||||||
if !h.iam.Enforce(process.Owner, process.Domain, "process:"+process.ID, "write") {
|
if !h.iam.Enforce(process.Owner, process.Domain, "process:"+process.ID, "write") {
|
||||||
return api.Err(http.StatusForbidden, "Forbidden")
|
return api.Err(http.StatusForbidden, "Forbidden")
|
||||||
@@ -90,6 +95,7 @@ func (h *RestreamHandler) Add(c echo.Context) error {
|
|||||||
// @Tags v16.7.2
|
// @Tags v16.7.2
|
||||||
// @ID process-3-get-all
|
// @ID process-3-get-all
|
||||||
// @Produce json
|
// @Produce json
|
||||||
|
// @Param domain query string false "Domain to act on"
|
||||||
// @Param filter query string false "Comma separated list of fields (config, state, report, metadata) that will be part of the output. If empty, all fields will be part of the output."
|
// @Param filter query string false "Comma separated list of fields (config, state, report, metadata) that will be part of the output. If empty, all fields will be part of the output."
|
||||||
// @Param reference query string false "Return only these process that have this reference value. If empty, the reference will be ignored."
|
// @Param reference query string false "Return only these process that have this reference value. If empty, the reference will be ignored."
|
||||||
// @Param id query string false "Comma separated list of process ids to list. Overrides the reference. If empty all IDs will be returned."
|
// @Param id query string false "Comma separated list of process ids to list. Overrides the reference. If empty all IDs will be returned."
|
||||||
@@ -101,7 +107,7 @@ func (h *RestreamHandler) Add(c echo.Context) error {
|
|||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Router /api/v3/process [get]
|
// @Router /api/v3/process [get]
|
||||||
func (h *RestreamHandler) GetAll(c echo.Context) error {
|
func (h *RestreamHandler) GetAll(c echo.Context) error {
|
||||||
user := util.DefaultContext(c, "user", "")
|
ctxuser := util.DefaultContext(c, "user", "")
|
||||||
filter := util.DefaultQuery(c, "filter", "")
|
filter := util.DefaultQuery(c, "filter", "")
|
||||||
reference := util.DefaultQuery(c, "reference", "")
|
reference := util.DefaultQuery(c, "reference", "")
|
||||||
wantids := strings.FieldsFunc(util.DefaultQuery(c, "id", ""), func(r rune) bool {
|
wantids := strings.FieldsFunc(util.DefaultQuery(c, "id", ""), func(r rune) bool {
|
||||||
@@ -117,7 +123,7 @@ func (h *RestreamHandler) GetAll(c echo.Context) error {
|
|||||||
ids := []restream.TaskID{}
|
ids := []restream.TaskID{}
|
||||||
|
|
||||||
for _, id := range preids {
|
for _, id := range preids {
|
||||||
if !h.iam.Enforce(user, domain, "process:"+id.ID, "read") {
|
if !h.iam.Enforce(ctxuser, domain, "process:"+id.ID, "read") {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -157,18 +163,20 @@ func (h *RestreamHandler) GetAll(c echo.Context) error {
|
|||||||
// @ID process-3-get
|
// @ID process-3-get
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Param id path string true "Process ID"
|
// @Param id path string true "Process ID"
|
||||||
|
// @Param domain query string false "Domain to act on"
|
||||||
// @Param filter query string false "Comma separated list of fields (config, state, report, metadata) to be part of the output. If empty, all fields will be part of the output"
|
// @Param filter query string false "Comma separated list of fields (config, state, report, metadata) to be part of the output. If empty, all fields will be part of the output"
|
||||||
// @Success 200 {object} api.Process
|
// @Success 200 {object} api.Process
|
||||||
|
// @Failure 403 {object} api.Error
|
||||||
// @Failure 404 {object} api.Error
|
// @Failure 404 {object} api.Error
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Router /api/v3/process/{id} [get]
|
// @Router /api/v3/process/{id} [get]
|
||||||
func (h *RestreamHandler) Get(c echo.Context) error {
|
func (h *RestreamHandler) Get(c echo.Context) error {
|
||||||
user := util.DefaultContext(c, "user", "")
|
ctxuser := util.DefaultContext(c, "user", "")
|
||||||
id := util.PathParam(c, "id")
|
id := util.PathParam(c, "id")
|
||||||
filter := util.DefaultQuery(c, "filter", "")
|
filter := util.DefaultQuery(c, "filter", "")
|
||||||
domain := util.DefaultQuery(c, "domain", "")
|
domain := util.DefaultQuery(c, "domain", "")
|
||||||
|
|
||||||
if !h.iam.Enforce(user, domain, "process:"+id, "read") {
|
if !h.iam.Enforce(ctxuser, domain, "process:"+id, "read") {
|
||||||
return api.Err(http.StatusForbidden, "Forbidden")
|
return api.Err(http.StatusForbidden, "Forbidden")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,12 +200,14 @@ func (h *RestreamHandler) Get(c echo.Context) error {
|
|||||||
// @ID process-3-delete
|
// @ID process-3-delete
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Param id path string true "Process ID"
|
// @Param id path string true "Process ID"
|
||||||
|
// @Param domain query string false "Domain to act on"
|
||||||
// @Success 200 {string} string
|
// @Success 200 {string} string
|
||||||
|
// @Failure 403 {object} api.Error
|
||||||
// @Failure 404 {object} api.Error
|
// @Failure 404 {object} api.Error
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Router /api/v3/process/{id} [delete]
|
// @Router /api/v3/process/{id} [delete]
|
||||||
func (h *RestreamHandler) Delete(c echo.Context) error {
|
func (h *RestreamHandler) Delete(c echo.Context) error {
|
||||||
user := util.DefaultContext(c, "user", "")
|
ctxuser := util.DefaultContext(c, "user", "")
|
||||||
superuser := util.DefaultContext(c, "superuser", false)
|
superuser := util.DefaultContext(c, "superuser", false)
|
||||||
id := util.PathParam(c, "id")
|
id := util.PathParam(c, "id")
|
||||||
domain := util.DefaultQuery(c, "domain", "")
|
domain := util.DefaultQuery(c, "domain", "")
|
||||||
@@ -208,7 +218,7 @@ func (h *RestreamHandler) Delete(c echo.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !superuser {
|
if !superuser {
|
||||||
if !h.iam.Enforce(user, domain, "process:"+id, "write") {
|
if !h.iam.Enforce(ctxuser, domain, "process:"+id, "write") {
|
||||||
return api.Err(http.StatusForbidden, "Forbidden")
|
return api.Err(http.StatusForbidden, "Forbidden")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -232,24 +242,28 @@ func (h *RestreamHandler) Delete(c echo.Context) error {
|
|||||||
// @Accept json
|
// @Accept json
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Param id path string true "Process ID"
|
// @Param id path string true "Process ID"
|
||||||
|
// @Param domain query string false "Domain to act on"
|
||||||
// @Param config body api.ProcessConfig true "Process config"
|
// @Param config body api.ProcessConfig true "Process config"
|
||||||
// @Success 200 {object} api.ProcessConfig
|
// @Success 200 {object} api.ProcessConfig
|
||||||
// @Failure 400 {object} api.Error
|
// @Failure 400 {object} api.Error
|
||||||
|
// @Failure 403 {object} api.Error
|
||||||
// @Failure 404 {object} api.Error
|
// @Failure 404 {object} api.Error
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Router /api/v3/process/{id} [put]
|
// @Router /api/v3/process/{id} [put]
|
||||||
func (h *RestreamHandler) Update(c echo.Context) error {
|
func (h *RestreamHandler) Update(c echo.Context) error {
|
||||||
id := util.PathParam(c, "id")
|
ctxuser := util.DefaultContext(c, "user", "")
|
||||||
user := util.DefaultContext(c, "user", "")
|
superuser := util.DefaultContext(c, "superuser", false)
|
||||||
domain := util.DefaultQuery(c, "domain", "")
|
domain := util.DefaultQuery(c, "domain", "")
|
||||||
|
id := util.PathParam(c, "id")
|
||||||
|
|
||||||
process := api.ProcessConfig{
|
process := api.ProcessConfig{
|
||||||
ID: id,
|
ID: id,
|
||||||
|
Owner: ctxuser,
|
||||||
Type: "ffmpeg",
|
Type: "ffmpeg",
|
||||||
Autostart: true,
|
Autostart: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
if !h.iam.Enforce(user, domain, "process:"+id, "write") {
|
if !h.iam.Enforce(ctxuser, domain, "process:"+id, "write") {
|
||||||
return api.Err(http.StatusForbidden, "Forbidden")
|
return api.Err(http.StatusForbidden, "Forbidden")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -270,13 +284,18 @@ func (h *RestreamHandler) Update(c echo.Context) error {
|
|||||||
return api.Err(http.StatusBadRequest, "Invalid JSON", "%s", err)
|
return api.Err(http.StatusBadRequest, "Invalid JSON", "%s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
config := process.Marshal()
|
if !h.iam.Enforce(ctxuser, process.Domain, "process:"+process.ID, "write") {
|
||||||
config.Owner = user
|
|
||||||
|
|
||||||
if !h.iam.Enforce(user, config.Domain, "process:"+config.ID, "write") {
|
|
||||||
return api.Err(http.StatusForbidden, "Forbidden")
|
return api.Err(http.StatusForbidden, "Forbidden")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !superuser {
|
||||||
|
if !h.iam.Enforce(process.Owner, process.Domain, "process:"+process.ID, "write") {
|
||||||
|
return api.Err(http.StatusForbidden, "Forbidden")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
config := process.Marshal()
|
||||||
|
|
||||||
tid = restream.TaskID{
|
tid = restream.TaskID{
|
||||||
ID: id,
|
ID: id,
|
||||||
Domain: domain,
|
Domain: domain,
|
||||||
@@ -308,18 +327,20 @@ func (h *RestreamHandler) Update(c echo.Context) error {
|
|||||||
// @Accept json
|
// @Accept json
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Param id path string true "Process ID"
|
// @Param id path string true "Process ID"
|
||||||
|
// @Param domain query string false "Domain to act on"
|
||||||
// @Param command body api.Command true "Process command"
|
// @Param command body api.Command true "Process command"
|
||||||
// @Success 200 {string} string
|
// @Success 200 {string} string
|
||||||
// @Failure 400 {object} api.Error
|
// @Failure 400 {object} api.Error
|
||||||
|
// @Failure 403 {object} api.Error
|
||||||
// @Failure 404 {object} api.Error
|
// @Failure 404 {object} api.Error
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Router /api/v3/process/{id}/command [put]
|
// @Router /api/v3/process/{id}/command [put]
|
||||||
func (h *RestreamHandler) Command(c echo.Context) error {
|
func (h *RestreamHandler) Command(c echo.Context) error {
|
||||||
id := util.PathParam(c, "id")
|
id := util.PathParam(c, "id")
|
||||||
user := util.DefaultContext(c, "user", "")
|
ctxuser := util.DefaultContext(c, "user", "")
|
||||||
domain := util.DefaultQuery(c, "domain", "")
|
domain := util.DefaultQuery(c, "domain", "")
|
||||||
|
|
||||||
if !h.iam.Enforce(user, domain, "process:"+id, "write") {
|
if !h.iam.Enforce(ctxuser, domain, "process:"+id, "write") {
|
||||||
return api.Err(http.StatusForbidden, "Forbidden")
|
return api.Err(http.StatusForbidden, "Forbidden")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -361,17 +382,19 @@ func (h *RestreamHandler) Command(c echo.Context) error {
|
|||||||
// @ID process-3-get-config
|
// @ID process-3-get-config
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Param id path string true "Process ID"
|
// @Param id path string true "Process ID"
|
||||||
|
// @Param domain query string false "Domain to act on"
|
||||||
// @Success 200 {object} api.ProcessConfig
|
// @Success 200 {object} api.ProcessConfig
|
||||||
// @Failure 404 {object} api.Error
|
|
||||||
// @Failure 400 {object} api.Error
|
// @Failure 400 {object} api.Error
|
||||||
|
// @Failure 403 {object} api.Error
|
||||||
|
// @Failure 404 {object} api.Error
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Router /api/v3/process/{id}/config [get]
|
// @Router /api/v3/process/{id}/config [get]
|
||||||
func (h *RestreamHandler) GetConfig(c echo.Context) error {
|
func (h *RestreamHandler) GetConfig(c echo.Context) error {
|
||||||
id := util.PathParam(c, "id")
|
id := util.PathParam(c, "id")
|
||||||
user := util.DefaultContext(c, "user", "")
|
ctxuser := util.DefaultContext(c, "user", "")
|
||||||
domain := util.DefaultQuery(c, "domain", "")
|
domain := util.DefaultQuery(c, "domain", "")
|
||||||
|
|
||||||
if !h.iam.Enforce(user, domain, "process:"+id, "read") {
|
if !h.iam.Enforce(ctxuser, domain, "process:"+id, "read") {
|
||||||
return api.Err(http.StatusForbidden, "Forbidden")
|
return api.Err(http.StatusForbidden, "Forbidden")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -398,17 +421,19 @@ func (h *RestreamHandler) GetConfig(c echo.Context) error {
|
|||||||
// @ID process-3-get-state
|
// @ID process-3-get-state
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Param id path string true "Process ID"
|
// @Param id path string true "Process ID"
|
||||||
|
// @Param domain query string false "Domain to act on"
|
||||||
// @Success 200 {object} api.ProcessState
|
// @Success 200 {object} api.ProcessState
|
||||||
// @Failure 404 {object} api.Error
|
|
||||||
// @Failure 400 {object} api.Error
|
// @Failure 400 {object} api.Error
|
||||||
|
// @Failure 403 {object} api.Error
|
||||||
|
// @Failure 404 {object} api.Error
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Router /api/v3/process/{id}/state [get]
|
// @Router /api/v3/process/{id}/state [get]
|
||||||
func (h *RestreamHandler) GetState(c echo.Context) error {
|
func (h *RestreamHandler) GetState(c echo.Context) error {
|
||||||
id := util.PathParam(c, "id")
|
id := util.PathParam(c, "id")
|
||||||
user := util.DefaultContext(c, "user", "")
|
ctxuser := util.DefaultContext(c, "user", "")
|
||||||
domain := util.DefaultQuery(c, "domain", "")
|
domain := util.DefaultQuery(c, "domain", "")
|
||||||
|
|
||||||
if !h.iam.Enforce(user, domain, "process:"+id, "read") {
|
if !h.iam.Enforce(ctxuser, domain, "process:"+id, "read") {
|
||||||
return api.Err(http.StatusForbidden, "Forbidden")
|
return api.Err(http.StatusForbidden, "Forbidden")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -435,17 +460,19 @@ func (h *RestreamHandler) GetState(c echo.Context) error {
|
|||||||
// @ID process-3-get-report
|
// @ID process-3-get-report
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Param id path string true "Process ID"
|
// @Param id path string true "Process ID"
|
||||||
|
// @Param domain query string false "Domain to act on"
|
||||||
// @Success 200 {object} api.ProcessReport
|
// @Success 200 {object} api.ProcessReport
|
||||||
// @Failure 404 {object} api.Error
|
|
||||||
// @Failure 400 {object} api.Error
|
// @Failure 400 {object} api.Error
|
||||||
|
// @Failure 403 {object} api.Error
|
||||||
|
// @Failure 404 {object} api.Error
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Router /api/v3/process/{id}/report [get]
|
// @Router /api/v3/process/{id}/report [get]
|
||||||
func (h *RestreamHandler) GetReport(c echo.Context) error {
|
func (h *RestreamHandler) GetReport(c echo.Context) error {
|
||||||
id := util.PathParam(c, "id")
|
id := util.PathParam(c, "id")
|
||||||
user := util.DefaultContext(c, "user", "")
|
ctxuser := util.DefaultContext(c, "user", "")
|
||||||
domain := util.DefaultQuery(c, "domain", "")
|
domain := util.DefaultQuery(c, "domain", "")
|
||||||
|
|
||||||
if !h.iam.Enforce(user, domain, "process:"+id, "read") {
|
if !h.iam.Enforce(ctxuser, domain, "process:"+id, "read") {
|
||||||
return api.Err(http.StatusForbidden, "Forbidden")
|
return api.Err(http.StatusForbidden, "Forbidden")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -472,15 +499,17 @@ func (h *RestreamHandler) GetReport(c echo.Context) error {
|
|||||||
// @ID process-3-probe
|
// @ID process-3-probe
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Param id path string true "Process ID"
|
// @Param id path string true "Process ID"
|
||||||
|
// @Param domain query string false "Domain to act on"
|
||||||
// @Success 200 {object} api.Probe
|
// @Success 200 {object} api.Probe
|
||||||
|
// @Failure 403 {object} api.Error
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Router /api/v3/process/{id}/probe [get]
|
// @Router /api/v3/process/{id}/probe [get]
|
||||||
func (h *RestreamHandler) Probe(c echo.Context) error {
|
func (h *RestreamHandler) Probe(c echo.Context) error {
|
||||||
id := util.PathParam(c, "id")
|
id := util.PathParam(c, "id")
|
||||||
user := util.DefaultContext(c, "user", "")
|
ctxuser := util.DefaultContext(c, "user", "")
|
||||||
domain := util.DefaultQuery(c, "domain", "")
|
domain := util.DefaultQuery(c, "domain", "")
|
||||||
|
|
||||||
if !h.iam.Enforce(user, domain, "process:"+id, "write") {
|
if !h.iam.Enforce(ctxuser, domain, "process:"+id, "write") {
|
||||||
return api.Err(http.StatusForbidden, "Forbidden")
|
return api.Err(http.StatusForbidden, "Forbidden")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -542,18 +571,20 @@ func (h *RestreamHandler) ReloadSkills(c echo.Context) error {
|
|||||||
// @Produce json
|
// @Produce json
|
||||||
// @Param id path string true "Process ID"
|
// @Param id path string true "Process ID"
|
||||||
// @Param key path string true "Key for data store"
|
// @Param key path string true "Key for data store"
|
||||||
|
// @Param domain query string false "Domain to act on"
|
||||||
// @Success 200 {object} api.Metadata
|
// @Success 200 {object} api.Metadata
|
||||||
// @Failure 404 {object} api.Error
|
|
||||||
// @Failure 400 {object} api.Error
|
// @Failure 400 {object} api.Error
|
||||||
|
// @Failure 403 {object} api.Error
|
||||||
|
// @Failure 404 {object} api.Error
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Router /api/v3/process/{id}/metadata/{key} [get]
|
// @Router /api/v3/process/{id}/metadata/{key} [get]
|
||||||
func (h *RestreamHandler) GetProcessMetadata(c echo.Context) error {
|
func (h *RestreamHandler) GetProcessMetadata(c echo.Context) error {
|
||||||
id := util.PathParam(c, "id")
|
id := util.PathParam(c, "id")
|
||||||
key := util.PathParam(c, "key")
|
key := util.PathParam(c, "key")
|
||||||
user := util.DefaultContext(c, "user", "")
|
ctxuser := util.DefaultContext(c, "user", "")
|
||||||
domain := util.DefaultQuery(c, "domain", "")
|
domain := util.DefaultQuery(c, "domain", "")
|
||||||
|
|
||||||
if !h.iam.Enforce(user, domain, "process:"+id, "read") {
|
if !h.iam.Enforce(ctxuser, domain, "process:"+id, "read") {
|
||||||
return api.Err(http.StatusForbidden, "Forbidden")
|
return api.Err(http.StatusForbidden, "Forbidden")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -578,19 +609,21 @@ func (h *RestreamHandler) GetProcessMetadata(c echo.Context) error {
|
|||||||
// @Produce json
|
// @Produce json
|
||||||
// @Param id path string true "Process ID"
|
// @Param id path string true "Process ID"
|
||||||
// @Param key path string true "Key for data store"
|
// @Param key path string true "Key for data store"
|
||||||
|
// @Param domain query string false "Domain to act on"
|
||||||
// @Param data body api.Metadata true "Arbitrary JSON data. The null value will remove the key and its contents"
|
// @Param data body api.Metadata true "Arbitrary JSON data. The null value will remove the key and its contents"
|
||||||
// @Success 200 {object} api.Metadata
|
// @Success 200 {object} api.Metadata
|
||||||
// @Failure 404 {object} api.Error
|
|
||||||
// @Failure 400 {object} api.Error
|
// @Failure 400 {object} api.Error
|
||||||
|
// @Failure 403 {object} api.Error
|
||||||
|
// @Failure 404 {object} api.Error
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Router /api/v3/process/{id}/metadata/{key} [put]
|
// @Router /api/v3/process/{id}/metadata/{key} [put]
|
||||||
func (h *RestreamHandler) SetProcessMetadata(c echo.Context) error {
|
func (h *RestreamHandler) SetProcessMetadata(c echo.Context) error {
|
||||||
id := util.PathParam(c, "id")
|
id := util.PathParam(c, "id")
|
||||||
key := util.PathParam(c, "key")
|
key := util.PathParam(c, "key")
|
||||||
user := util.DefaultContext(c, "user", "")
|
ctxuser := util.DefaultContext(c, "user", "")
|
||||||
domain := util.DefaultQuery(c, "domain", "")
|
domain := util.DefaultQuery(c, "domain", "")
|
||||||
|
|
||||||
if !h.iam.Enforce(user, domain, "process:"+id, "write") {
|
if !h.iam.Enforce(ctxuser, domain, "process:"+id, "write") {
|
||||||
return api.Err(http.StatusForbidden, "Forbidden")
|
return api.Err(http.StatusForbidden, "Forbidden")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -20,7 +20,7 @@
|
|||||||
// an anonmyous user. If the Skipper function returns true for the request and the
|
// an anonmyous user. If the Skipper function returns true for the request and the
|
||||||
// API is accessed, the username will be the one of the IAM superuser.
|
// API is accessed, the username will be the one of the IAM superuser.
|
||||||
//
|
//
|
||||||
// The domain is provided as query parameter "group" for all API requests or the
|
// The domain is provided as query parameter "domain" for all API requests or the
|
||||||
// first path element after a mountpoint for filesystem requests.
|
// first path element after a mountpoint for filesystem requests.
|
||||||
//
|
//
|
||||||
// If the domain can't be detected, the domain "$none" will be used.
|
// If the domain can't be detected, the domain "$none" will be used.
|
||||||
@@ -179,7 +179,7 @@ func NewWithConfig(config Config) echo.MiddlewareFunc {
|
|||||||
username = config.IAM.GetDefaultVerifier().Name()
|
username = config.IAM.GetDefaultVerifier().Name()
|
||||||
}
|
}
|
||||||
|
|
||||||
domain = c.QueryParam("group")
|
domain = c.QueryParam("domain")
|
||||||
resource = "api:" + resource
|
resource = "api:" + resource
|
||||||
} else {
|
} else {
|
||||||
identity, err = mw.findIdentityFromBasicAuth(c)
|
identity, err = mw.findIdentityFromBasicAuth(c)
|
||||||
|
@@ -549,11 +549,11 @@ func (s *server) setRoutesV3(v3 *echo.Group) {
|
|||||||
|
|
||||||
// v3 IAM
|
// v3 IAM
|
||||||
if s.v3handler.iam != nil {
|
if s.v3handler.iam != nil {
|
||||||
v3.POST("/iam/user", s.v3handler.iam.AddUser)
|
v3.POST("/iam/user", s.v3handler.iam.AddIdentity)
|
||||||
v3.GET("/iam/user/:name", s.v3handler.iam.GetUser)
|
v3.GET("/iam/user/:name", s.v3handler.iam.GetIdentity)
|
||||||
v3.PUT("/iam/user/:name", s.v3handler.iam.UpdateUser)
|
v3.PUT("/iam/user/:name", s.v3handler.iam.UpdateIdentity)
|
||||||
v3.PUT("/iam/user/:name/policy", s.v3handler.iam.UpdateUserPolicies)
|
v3.PUT("/iam/user/:name/policy", s.v3handler.iam.UpdateIdentityPolicies)
|
||||||
v3.DELETE("/iam/user/:name", s.v3handler.iam.RemoveUser)
|
v3.DELETE("/iam/user/:name", s.v3handler.iam.RemoveIdentity)
|
||||||
}
|
}
|
||||||
|
|
||||||
// v3 Restreamer
|
// v3 Restreamer
|
||||||
@@ -658,10 +658,12 @@ func (s *server) setRoutesV3(v3 *echo.Group) {
|
|||||||
v3.GET("/cluster", s.v3handler.cluster.About)
|
v3.GET("/cluster", s.v3handler.cluster.About)
|
||||||
|
|
||||||
v3.GET("/cluster/db/process", s.v3handler.cluster.ListStoreProcesses)
|
v3.GET("/cluster/db/process", s.v3handler.cluster.ListStoreProcesses)
|
||||||
v3.GET("/cluster/db/policies", s.v3handler.cluster.ListStorePolicies)
|
|
||||||
v3.GET("/cluster/db/user", s.v3handler.cluster.ListStoreIdentities)
|
v3.GET("/cluster/db/user", s.v3handler.cluster.ListStoreIdentities)
|
||||||
|
v3.GET("/cluster/db/user/:name", s.v3handler.cluster.ListStoreIdentity)
|
||||||
|
v3.GET("/cluster/db/policies", s.v3handler.cluster.ListStorePolicies)
|
||||||
|
|
||||||
v3.GET("/cluster/iam/user", s.v3handler.cluster.ListIdentities)
|
v3.GET("/cluster/iam/user", s.v3handler.cluster.ListIdentities)
|
||||||
|
v3.GET("/cluster/iam/user/:name", s.v3handler.cluster.ListIdentity)
|
||||||
v3.GET("/cluster/iam/policies", s.v3handler.cluster.ListPolicies)
|
v3.GET("/cluster/iam/policies", s.v3handler.cluster.ListPolicies)
|
||||||
|
|
||||||
v3.GET("/cluster/process", s.v3handler.cluster.ListAllNodeProcesses)
|
v3.GET("/cluster/process", s.v3handler.cluster.ListAllNodeProcesses)
|
||||||
@@ -677,11 +679,11 @@ func (s *server) setRoutesV3(v3 *echo.Group) {
|
|||||||
v3.PUT("/cluster/process/:id", s.v3handler.cluster.UpdateProcess)
|
v3.PUT("/cluster/process/:id", s.v3handler.cluster.UpdateProcess)
|
||||||
v3.DELETE("/cluster/process/:id", s.v3handler.cluster.DeleteProcess)
|
v3.DELETE("/cluster/process/:id", s.v3handler.cluster.DeleteProcess)
|
||||||
|
|
||||||
v3.GET("/cluster/iam/user/reload", s.v3handler.cluster.ReloadIdentities)
|
v3.GET("/cluster/iam/reload", s.v3handler.cluster.ReloadIAM)
|
||||||
v3.POST("/cluster/iam/user", s.v3handler.cluster.AddIdentity)
|
v3.POST("/cluster/iam/user", s.v3handler.cluster.AddIdentity)
|
||||||
v3.PUT("/cluster/iam/user/:name/policies", s.v3handler.cluster.UpdateIdentityPolicies)
|
v3.PUT("/cluster/iam/user/:name", s.v3handler.cluster.UpdateIdentity)
|
||||||
|
v3.PUT("/cluster/iam/user/:name/policy", s.v3handler.cluster.UpdateIdentityPolicies)
|
||||||
v3.DELETE("/cluster/iam/user/:name", s.v3handler.cluster.RemoveIdentity)
|
v3.DELETE("/cluster/iam/user/:name", s.v3handler.cluster.RemoveIdentity)
|
||||||
v3.GET("/cluster/iam/policies/reload", s.v3handler.cluster.ReloadPolicies)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -157,7 +157,7 @@ func (i *iam) DeleteIdentity(name string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (i *iam) ListIdentities() []identity.User {
|
func (i *iam) ListIdentities() []identity.User {
|
||||||
return nil
|
return i.im.List()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *iam) ReloadIndentities() error {
|
func (i *iam) ReloadIndentities() error {
|
||||||
|
Reference in New Issue
Block a user