Fix reloading policies, add API endpoints for observing internal cluster state

This commit is contained in:
Ingo Oppermann
2023-05-31 11:23:54 +02:00
parent 2364aa9d41
commit 3a6bb02bfd
9 changed files with 989 additions and 121 deletions

View File

@@ -73,6 +73,7 @@ type Cluster interface {
IAM(superuser iamidentity.User, jwtRealm, jwtSecret string) (iam.IAM, error) IAM(superuser iamidentity.User, jwtRealm, jwtSecret string) (iam.IAM, error)
ListIdentities() store.Users ListIdentities() store.Users
ListPolicies() store.Policies
AddIdentity(origin string, identity iamidentity.User) error AddIdentity(origin 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
@@ -782,6 +783,10 @@ func (c *cluster) ListIdentities() store.Users {
return c.store.UserList() return c.store.UserList()
} }
func (c *cluster) ListPolicies() store.Policies {
return c.store.PolicyList()
}
func (c *cluster) AddIdentity(origin string, identity iamidentity.User) error { func (c *cluster) AddIdentity(origin string, identity iamidentity.User) error {
if !c.IsRaftLeader() { if !c.IsRaftLeader() {
return c.forwarder.AddIdentity(origin, identity) return c.forwarder.AddIdentity(origin, identity)

View File

@@ -2,6 +2,7 @@ package iam
import ( import (
"strings" "strings"
"sync"
"github.com/datarhei/core/v16/cluster/store" "github.com/datarhei/core/v16/cluster/store"
iamaccess "github.com/datarhei/core/v16/iam/access" iamaccess "github.com/datarhei/core/v16/iam/access"
@@ -12,11 +13,14 @@ import (
type policyAdapter struct { type policyAdapter struct {
store store.Store store store.Store
domains map[string]struct{}
lock sync.RWMutex
} }
func NewPolicyAdapter(store store.Store) (iamaccess.Adapter, error) { func NewPolicyAdapter(store store.Store) (iamaccess.Adapter, error) {
a := &policyAdapter{ a := &policyAdapter{
store: store, store: store,
domains: map[string]struct{}{},
} }
return a, nil return a, nil
@@ -26,6 +30,7 @@ func (a *policyAdapter) LoadPolicy(model model.Model) error {
policies := a.store.PolicyList() policies := a.store.PolicyList()
rules := [][]string{} rules := [][]string{}
domains := map[string]struct{}{}
for _, p := range policies.Policies { for _, p := range policies.Policies {
rule := []string{ rule := []string{
@@ -35,12 +40,17 @@ func (a *policyAdapter) LoadPolicy(model model.Model) error {
strings.Join(p.Actions, "|"), strings.Join(p.Actions, "|"),
} }
domains[p.Domain] = struct{}{}
rules = append(rules, rule) rules = append(rules, rule)
} }
model.ClearPolicy()
model.AddPolicies("p", "p", rules) model.AddPolicies("p", "p", rules)
a.lock.Lock()
a.domains = domains
a.lock.Unlock()
return nil return nil
} }
@@ -69,11 +79,27 @@ func (a *policyAdapter) RemoveFilteredPolicy(sec string, ptype string, fieldInde
} }
func (a *policyAdapter) AllDomains() []string { func (a *policyAdapter) AllDomains() []string {
return nil a.lock.RLock()
defer a.lock.RUnlock()
n := len(a.domains)
domains := make([]string, n)
for domain := range a.domains {
domains[n-1] = domain
n--
}
return domains
} }
func (a *policyAdapter) HasDomain(name string) bool { func (a *policyAdapter) HasDomain(name string) bool {
return false a.lock.RLock()
defer a.lock.RUnlock()
_, ok := a.domains[name]
return ok
} }
type identityAdapter struct { type identityAdapter struct {

View File

@@ -160,7 +160,182 @@ const docTemplate = `{
} }
} }
}, },
"/api/v3/cluster/db/policies": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "List of policies in the cluster",
"produces": [
"application/json"
],
"tags": [
"v16.?.?"
],
"summary": "List of policies in the cluster",
"operationId": "cluster-3-db-list-policies",
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/api.IAMPolicy"
}
}
}
}
}
},
"/api/v3/cluster/db/process": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "List of processes in the cluster",
"produces": [
"application/json"
],
"tags": [
"v16.?.?"
],
"summary": "List of processes in the cluster",
"operationId": "cluster-3-db-list-processes",
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/api.Process"
}
}
}
}
}
},
"/api/v3/cluster/db/user": {
"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-identities",
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/api.IAMUser"
}
}
}
}
}
},
"/api/v3/cluster/iam/policies": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "List of policies IAM",
"produces": [
"application/json"
],
"tags": [
"v16.?.?"
],
"summary": "List of policies in IAM",
"operationId": "cluster-3-iam-list-policies",
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/api.IAMPolicy"
}
}
}
}
}
},
"/api/v3/cluster/iam/policies/reload": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Reload policies",
"produces": [
"application/json"
],
"tags": [
"v16.?.?"
],
"summary": "Reload policies",
"operationId": "cluster-3-iam-reload-policies",
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "string"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/api.Error"
}
}
}
}
},
"/api/v3/cluster/iam/user": { "/api/v3/cluster/iam/user": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "List of identities in IAM",
"produces": [
"application/json"
],
"tags": [
"v16.?.?"
],
"summary": "List of identities in IAM",
"operationId": "cluster-3-iam-list-identities",
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/api.IAMUser"
}
}
}
}
},
"post": { "post": {
"security": [ "security": [
{ {
@@ -206,6 +381,38 @@ const docTemplate = `{
} }
} }
}, },
"/api/v3/cluster/iam/user/reload": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Reload identities",
"produces": [
"application/json"
],
"tags": [
"v16.?.?"
],
"summary": "Reload identities",
"operationId": "cluster-3-iam-reload-identities",
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "string"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/api.Error"
}
}
}
}
},
"/api/v3/cluster/iam/user/{name}": { "/api/v3/cluster/iam/user/{name}": {
"delete": { "delete": {
"security": [ "security": [
@@ -359,35 +566,6 @@ const docTemplate = `{
} }
} }
}, },
"/api/v3/cluster/node/process": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "List of processes in the cluster",
"produces": [
"application/json"
],
"tags": [
"v16.?.?"
],
"summary": "List of processes in the cluster",
"operationId": "cluster-3-list-node-processes",
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/api.ClusterProcess"
}
}
}
}
}
},
"/api/v3/cluster/node/{id}": { "/api/v3/cluster/node/{id}": {
"get": { "get": {
"security": [ "security": [
@@ -470,6 +648,97 @@ const docTemplate = `{
} }
} }
}, },
"/api/v3/cluster/node/{id}/process": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "List of processes in the cluster on a node",
"produces": [
"application/json"
],
"tags": [
"v16.?.?"
],
"summary": "List of processes in the cluster on a node",
"operationId": "cluster-3-list-node-processes",
"parameters": [
{
"type": "string",
"description": "Node ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/api.ClusterProcess"
}
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/api.Error"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/api.Error"
}
}
}
}
},
"/api/v3/cluster/node/{id}/version": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "List a proxy node by its ID",
"produces": [
"application/json"
],
"tags": [
"v16.?.?"
],
"summary": "List a proxy node by its ID",
"operationId": "cluster-3-get-node-version",
"parameters": [
{
"type": "string",
"description": "Node ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/api.ClusterNode"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/api.Error"
}
}
}
}
},
"/api/v3/cluster/process": { "/api/v3/cluster/process": {
"get": { "get": {
"security": [ "security": [
@@ -485,14 +754,14 @@ const docTemplate = `{
"v16.?.?" "v16.?.?"
], ],
"summary": "List of processes in the cluster", "summary": "List of processes in the cluster",
"operationId": "cluster-3-list-processes", "operationId": "cluster-3-list-all-node-processes",
"responses": { "responses": {
"200": { "200": {
"description": "OK", "description": "OK",
"schema": { "schema": {
"type": "array", "type": "array",
"items": { "items": {
"$ref": "#/definitions/api.Process" "$ref": "#/definitions/api.ClusterProcess"
} }
} }
} }

View File

@@ -152,7 +152,182 @@
} }
} }
}, },
"/api/v3/cluster/db/policies": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "List of policies in the cluster",
"produces": [
"application/json"
],
"tags": [
"v16.?.?"
],
"summary": "List of policies in the cluster",
"operationId": "cluster-3-db-list-policies",
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/api.IAMPolicy"
}
}
}
}
}
},
"/api/v3/cluster/db/process": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "List of processes in the cluster",
"produces": [
"application/json"
],
"tags": [
"v16.?.?"
],
"summary": "List of processes in the cluster",
"operationId": "cluster-3-db-list-processes",
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/api.Process"
}
}
}
}
}
},
"/api/v3/cluster/db/user": {
"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-identities",
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/api.IAMUser"
}
}
}
}
}
},
"/api/v3/cluster/iam/policies": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "List of policies IAM",
"produces": [
"application/json"
],
"tags": [
"v16.?.?"
],
"summary": "List of policies in IAM",
"operationId": "cluster-3-iam-list-policies",
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/api.IAMPolicy"
}
}
}
}
}
},
"/api/v3/cluster/iam/policies/reload": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Reload policies",
"produces": [
"application/json"
],
"tags": [
"v16.?.?"
],
"summary": "Reload policies",
"operationId": "cluster-3-iam-reload-policies",
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "string"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/api.Error"
}
}
}
}
},
"/api/v3/cluster/iam/user": { "/api/v3/cluster/iam/user": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "List of identities in IAM",
"produces": [
"application/json"
],
"tags": [
"v16.?.?"
],
"summary": "List of identities in IAM",
"operationId": "cluster-3-iam-list-identities",
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/api.IAMUser"
}
}
}
}
},
"post": { "post": {
"security": [ "security": [
{ {
@@ -198,6 +373,38 @@
} }
} }
}, },
"/api/v3/cluster/iam/user/reload": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Reload identities",
"produces": [
"application/json"
],
"tags": [
"v16.?.?"
],
"summary": "Reload identities",
"operationId": "cluster-3-iam-reload-identities",
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "string"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/api.Error"
}
}
}
}
},
"/api/v3/cluster/iam/user/{name}": { "/api/v3/cluster/iam/user/{name}": {
"delete": { "delete": {
"security": [ "security": [
@@ -351,35 +558,6 @@
} }
} }
}, },
"/api/v3/cluster/node/process": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "List of processes in the cluster",
"produces": [
"application/json"
],
"tags": [
"v16.?.?"
],
"summary": "List of processes in the cluster",
"operationId": "cluster-3-list-node-processes",
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/api.ClusterProcess"
}
}
}
}
}
},
"/api/v3/cluster/node/{id}": { "/api/v3/cluster/node/{id}": {
"get": { "get": {
"security": [ "security": [
@@ -462,6 +640,97 @@
} }
} }
}, },
"/api/v3/cluster/node/{id}/process": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "List of processes in the cluster on a node",
"produces": [
"application/json"
],
"tags": [
"v16.?.?"
],
"summary": "List of processes in the cluster on a node",
"operationId": "cluster-3-list-node-processes",
"parameters": [
{
"type": "string",
"description": "Node ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/api.ClusterProcess"
}
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/api.Error"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/api.Error"
}
}
}
}
},
"/api/v3/cluster/node/{id}/version": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "List a proxy node by its ID",
"produces": [
"application/json"
],
"tags": [
"v16.?.?"
],
"summary": "List a proxy node by its ID",
"operationId": "cluster-3-get-node-version",
"parameters": [
{
"type": "string",
"description": "Node ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/api.ClusterNode"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/api.Error"
}
}
}
}
},
"/api/v3/cluster/process": { "/api/v3/cluster/process": {
"get": { "get": {
"security": [ "security": [
@@ -477,14 +746,14 @@
"v16.?.?" "v16.?.?"
], ],
"summary": "List of processes in the cluster", "summary": "List of processes in the cluster",
"operationId": "cluster-3-list-processes", "operationId": "cluster-3-list-all-node-processes",
"responses": { "responses": {
"200": { "200": {
"description": "OK", "description": "OK",
"schema": { "schema": {
"type": "array", "type": "array",
"items": { "items": {
"$ref": "#/definitions/api.Process" "$ref": "#/definitions/api.ClusterProcess"
} }
} }
} }

View File

@@ -2240,7 +2240,116 @@ paths:
summary: List of nodes in the cluster summary: List of nodes in the cluster
tags: tags:
- v16.?.? - v16.?.?
/api/v3/cluster/db/policies:
get:
description: List of policies in the cluster
operationId: cluster-3-db-list-policies
produces:
- application/json
responses:
"200":
description: OK
schema:
items:
$ref: '#/definitions/api.IAMPolicy'
type: array
security:
- ApiKeyAuth: []
summary: List of policies in the cluster
tags:
- v16.?.?
/api/v3/cluster/db/process:
get:
description: List of processes in the cluster
operationId: cluster-3-db-list-processes
produces:
- application/json
responses:
"200":
description: OK
schema:
items:
$ref: '#/definitions/api.Process'
type: array
security:
- ApiKeyAuth: []
summary: List of processes in the cluster
tags:
- v16.?.?
/api/v3/cluster/db/user:
get:
description: List of identities in the cluster
operationId: cluster-3-db-list-identities
produces:
- application/json
responses:
"200":
description: OK
schema:
items:
$ref: '#/definitions/api.IAMUser'
type: array
security:
- ApiKeyAuth: []
summary: List of identities in the cluster
tags:
- v16.?.?
/api/v3/cluster/iam/policies:
get:
description: List of policies IAM
operationId: cluster-3-iam-list-policies
produces:
- application/json
responses:
"200":
description: OK
schema:
items:
$ref: '#/definitions/api.IAMPolicy'
type: array
security:
- ApiKeyAuth: []
summary: List of policies in IAM
tags:
- v16.?.?
/api/v3/cluster/iam/policies/reload:
get:
description: Reload policies
operationId: cluster-3-iam-reload-policies
produces:
- application/json
responses:
"200":
description: OK
schema:
type: string
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/api.Error'
security:
- ApiKeyAuth: []
summary: Reload policies
tags:
- v16.?.?
/api/v3/cluster/iam/user: /api/v3/cluster/iam/user:
get:
description: List of identities in IAM
operationId: cluster-3-iam-list-identities
produces:
- application/json
responses:
"200":
description: OK
schema:
items:
$ref: '#/definitions/api.IAMUser'
type: array
security:
- ApiKeyAuth: []
summary: List of identities in IAM
tags:
- v16.?.?
post: post:
consumes: consumes:
- application/json - application/json
@@ -2345,6 +2454,26 @@ 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
@@ -2419,10 +2548,16 @@ paths:
summary: List the files of a proxy node by its ID summary: List the files of a proxy node by its ID
tags: tags:
- v16.?.? - v16.?.?
/api/v3/cluster/node/process: /api/v3/cluster/node/{id}/process:
get: get:
description: List of processes in the cluster description: List of processes in the cluster on a node
operationId: cluster-3-list-node-processes operationId: cluster-3-list-node-processes
parameters:
- description: Node ID
in: path
name: id
required: true
type: string
produces: produces:
- application/json - application/json
responses: responses:
@@ -2432,15 +2567,49 @@ paths:
items: items:
$ref: '#/definitions/api.ClusterProcess' $ref: '#/definitions/api.ClusterProcess'
type: array type: array
"404":
description: Not Found
schema:
$ref: '#/definitions/api.Error'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/api.Error'
security: security:
- ApiKeyAuth: [] - ApiKeyAuth: []
summary: List of processes in the cluster summary: List of processes in the cluster on a node
tags:
- v16.?.?
/api/v3/cluster/node/{id}/version:
get:
description: List a proxy node by its ID
operationId: cluster-3-get-node-version
parameters:
- description: Node ID
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/api.ClusterNode'
"404":
description: Not Found
schema:
$ref: '#/definitions/api.Error'
security:
- ApiKeyAuth: []
summary: List a proxy node by its ID
tags: tags:
- v16.?.? - v16.?.?
/api/v3/cluster/process: /api/v3/cluster/process:
get: get:
description: List of processes in the cluster description: List of processes in the cluster
operationId: cluster-3-list-processes operationId: cluster-3-list-all-node-processes
produces: produces:
- application/json - application/json
responses: responses:
@@ -2448,7 +2617,7 @@ paths:
description: OK description: OK
schema: schema:
items: items:
$ref: '#/definitions/api.Process' $ref: '#/definitions/api.ClusterProcess'
type: array type: array
security: security:
- ApiKeyAuth: [] - ApiKeyAuth: []

View File

@@ -47,6 +47,74 @@ func NewCluster(cluster cluster.Cluster, iam iam.IAM) (*ClusterHandler, error) {
return h, nil return h, nil
} }
// GetCluster returns the list of nodes in the cluster
// @Summary List of nodes in the cluster
// @Description List of nodes in the cluster
// @Tags v16.?.?
// @ID cluster-3-get-cluster
// @Produce json
// @Success 200 {object} api.ClusterAbout
// @Failure 404 {object} api.Error
// @Security ApiKeyAuth
// @Router /api/v3/cluster [get]
func (h *ClusterHandler) About(c echo.Context) error {
state, _ := h.cluster.About()
about := api.ClusterAbout{
ID: state.ID,
Address: state.Address,
ClusterAPIAddress: state.ClusterAPIAddress,
CoreAPIAddress: state.CoreAPIAddress,
Server: []api.ClusterServer{},
Stats: api.ClusterStats{
State: state.Stats.State,
LastContact: state.Stats.LastContact.Seconds() * 1000,
NumPeers: state.Stats.NumPeers,
},
}
for _, n := range state.Nodes {
about.Server = append(about.Server, api.ClusterServer{
ID: n.ID,
Address: n.Address,
Voter: n.Voter,
Leader: n.Leader,
})
}
return c.JSON(http.StatusOK, about)
}
// ListAllNodeProcesses returns the list of processes running on all nodes of the cluster
// @Summary List of processes in the cluster
// @Description List of processes in the cluster
// @Tags v16.?.?
// @ID cluster-3-list-all-node-processes
// @Produce json
// @Success 200 {array} api.ClusterProcess
// @Security ApiKeyAuth
// @Router /api/v3/cluster/process [get]
func (h *ClusterHandler) ListAllNodeProcesses(c echo.Context) error {
procs := h.proxy.ListProcesses()
processes := []api.ClusterProcess{}
for _, p := range procs {
processes = append(processes, api.ClusterProcess{
ProcessID: p.Config.ID,
NodeID: p.NodeID,
Reference: p.Config.Reference,
Order: p.Order,
State: p.State,
CPU: json.ToNumber(p.CPU),
Memory: p.Mem,
Runtime: int64(p.Runtime.Seconds()),
})
}
return c.JSON(http.StatusOK, processes)
}
// GetNodes returns the list of proxy nodes in the cluster // GetNodes returns the list of proxy nodes in the cluster
// @Summary List of proxy nodes in the cluster // @Summary List of proxy nodes in the cluster
// @Description List of proxy nodes in the cluster // @Description List of proxy nodes in the cluster
@@ -122,13 +190,13 @@ func (h *ClusterHandler) GetNode(c echo.Context) error {
// @Summary List a proxy node by its ID // @Summary List a proxy node by its ID
// @Description List a proxy node by its ID // @Description List a proxy node by its ID
// @Tags v16.?.? // @Tags v16.?.?
// @ID cluster-3-get-node // @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.ClusterNode
// @Failure 404 {object} api.Error // @Failure 404 {object} api.Error
// @Security ApiKeyAuth // @Security ApiKeyAuth
// @Router /api/v3/cluster/node/{id} [get] // @Router /api/v3/cluster/node/{id}/version [get]
func (h *ClusterHandler) GetNodeVersion(c echo.Context) error { func (h *ClusterHandler) GetNodeVersion(c echo.Context) error {
id := util.PathParam(c, "id") id := util.PathParam(c, "id")
@@ -192,8 +260,9 @@ func (h *ClusterHandler) GetNodeFiles(c echo.Context) error {
// @Param id path string true "Node ID" // @Param id path string true "Node ID"
// @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
// @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 {
id := util.PathParam(c, "id") id := util.PathParam(c, "id")
@@ -225,53 +294,15 @@ func (h *ClusterHandler) ListNodeProcesses(c echo.Context) error {
return c.JSON(http.StatusOK, processes) return c.JSON(http.StatusOK, processes)
} }
// GetCluster returns the list of nodes in the cluster
// @Summary List of nodes in the cluster
// @Description List of nodes in the cluster
// @Tags v16.?.?
// @ID cluster-3-get-cluster
// @Produce json
// @Success 200 {object} api.ClusterAbout
// @Failure 404 {object} api.Error
// @Security ApiKeyAuth
// @Router /api/v3/cluster [get]
func (h *ClusterHandler) About(c echo.Context) error {
state, _ := h.cluster.About()
about := api.ClusterAbout{
ID: state.ID,
Address: state.Address,
ClusterAPIAddress: state.ClusterAPIAddress,
CoreAPIAddress: state.CoreAPIAddress,
Server: []api.ClusterServer{},
Stats: api.ClusterStats{
State: state.Stats.State,
LastContact: state.Stats.LastContact.Seconds() * 1000,
NumPeers: state.Stats.NumPeers,
},
}
for _, n := range state.Nodes {
about.Server = append(about.Server, api.ClusterServer{
ID: n.ID,
Address: n.Address,
Voter: n.Voter,
Leader: n.Leader,
})
}
return c.JSON(http.StatusOK, about)
}
// ListStoreProcesses returns the list of processes stored in the DB of the cluster // ListStoreProcesses returns the list of processes stored in the DB of the cluster
// @Summary List of processes in the cluster // @Summary List of processes in the cluster
// @Description List of processes in the cluster // @Description List of processes in the cluster
// @Tags v16.?.? // @Tags v16.?.?
// @ID cluster-3-list-processes // @ID cluster-3-db-list-processes
// @Produce json // @Produce json
// @Success 200 {array} api.Process // @Success 200 {array} api.Process
// @Security ApiKeyAuth // @Security ApiKeyAuth
// @Router /api/v3/cluster/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 {
procs := h.cluster.ListProcesses() procs := h.cluster.ListProcesses()
@@ -518,12 +549,104 @@ func (h *ClusterHandler) UpdateIdentityPolicies(c echo.Context) error {
return c.JSON(http.StatusOK, policies) return c.JSON(http.StatusOK, policies)
} }
func (h *ClusterHandler) ListIdentities(c echo.Context) error { // ListStoreIdentities 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-identities
// @Produce json
// @Success 200 {array} api.IAMUser
// @Security ApiKeyAuth
// @Router /api/v3/cluster/db/user [get]
func (h *ClusterHandler) ListStoreIdentities(c echo.Context) error {
identities := h.cluster.ListIdentities() identities := h.cluster.ListIdentities()
return c.JSON(http.StatusOK, identities) return c.JSON(http.StatusOK, identities)
} }
// ListIdentities returns the list of identities stored in IAM
// @Summary List of identities in IAM
// @Description List of identities in IAM
// @Tags v16.?.?
// @ID cluster-3-iam-list-identities
// @Produce json
// @Success 200 {array} api.IAMUser
// @Security ApiKeyAuth
// @Router /api/v3/cluster/iam/user [get]
func (h *ClusterHandler) ListIdentities(c echo.Context) error {
identities := h.iam.ListIdentities()
return c.JSON(http.StatusOK, identities)
}
// ReloadIdentities reloads the identities from the cluster store to IAM
// @Summary Reload identities
// @Description Reload identities
// @Tags v16.?.?
// @ID cluster-3-iam-reload-identities
// @Produce json
// @Success 200 {string} string
// @Success 500 {object} api.Error
// @Security ApiKeyAuth
// @Router /api/v3/cluster/iam/user/reload [get]
func (h *ClusterHandler) ReloadIdentities(c echo.Context) error {
err := h.iam.ReloadIndentities()
if err != nil {
return api.Err(http.StatusInternalServerError, "", "reload identities: %w", err)
}
return c.JSON(http.StatusOK, "OK")
}
// ListStorePolicies returns the list of policies stored in the DB of the cluster
// @Summary List of policies in the cluster
// @Description List of policies in the cluster
// @Tags v16.?.?
// @ID cluster-3-db-list-policies
// @Produce json
// @Success 200 {array} api.IAMPolicy
// @Security ApiKeyAuth
// @Router /api/v3/cluster/db/policies [get]
func (h *ClusterHandler) ListStorePolicies(c echo.Context) error {
policies := h.cluster.ListPolicies()
return c.JSON(http.StatusOK, policies)
}
// ListPolicies returns the list of policies stored in IAM
// @Summary List of policies in IAM
// @Description List of policies IAM
// @Tags v16.?.?
// @ID cluster-3-iam-list-policies
// @Produce json
// @Success 200 {array} api.IAMPolicy
// @Security ApiKeyAuth
// @Router /api/v3/cluster/iam/policies [get]
func (h *ClusterHandler) ListPolicies(c echo.Context) error {
policies := h.iam.ListPolicies("", "", "", nil)
return c.JSON(http.StatusOK, policies)
}
// ReloadPolicies reloads the policies from the cluster store to IAM
// @Summary Reload policies
// @Description Reload policies
// @Tags v16.?.?
// @ID cluster-3-iam-reload-policies
// @Produce json
// @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")
}
// Delete deletes the identity with the given name from the cluster // Delete deletes the identity with the given name from the cluster
// @Summary Delete an identity by its name // @Summary Delete an identity by its name
// @Description Delete an identity by its name // @Description Delete an identity by its name

View File

@@ -656,8 +656,15 @@ func (s *server) setRoutesV3(v3 *echo.Group) {
// v3 Cluster // v3 Cluster
if s.v3handler.cluster != nil { if s.v3handler.cluster != nil {
v3.GET("/cluster", s.v3handler.cluster.About) v3.GET("/cluster", s.v3handler.cluster.About)
v3.GET("/cluster/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/iam/user", s.v3handler.cluster.ListIdentities) v3.GET("/cluster/iam/user", s.v3handler.cluster.ListIdentities)
v3.GET("/cluster/iam/policies", s.v3handler.cluster.ListPolicies)
v3.GET("/cluster/process", s.v3handler.cluster.ListAllNodeProcesses)
v3.GET("/cluster/node", s.v3handler.cluster.GetNodes) v3.GET("/cluster/node", s.v3handler.cluster.GetNodes)
v3.GET("/cluster/node/:id", s.v3handler.cluster.GetNode) v3.GET("/cluster/node/:id", s.v3handler.cluster.GetNode)
@@ -670,9 +677,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.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/policies", 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)
} }
} }

View File

@@ -120,9 +120,9 @@ func (am *access) ListPolicies(name, domain, resource string, actions []string)
} }
func (am *access) ReloadPolicies() error { func (am *access) ReloadPolicies() error {
am.model.ClearPolicy() am.enforcer.ClearPolicy()
return am.adapter.LoadPolicy(am.model) return am.enforcer.LoadPolicy()
} }
func (am *access) HasDomain(name string) bool { func (am *access) HasDomain(name string) bool {

View File

@@ -80,8 +80,6 @@ func (a *adapter) loadPolicyFile(model model.Model) error {
return err return err
} }
model.ClearPolicy()
rule := [5]string{} rule := [5]string{}
for _, domain := range domains { for _, domain := range domains {
rule[0] = "p" rule[0] = "p"