Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
750092c
draft
Gwynbleidd0241 Apr 16, 2026
cb79dd6
fix
Gwynbleidd0241 Apr 16, 2026
2575bce
bib
Gwynbleidd0241 Apr 17, 2026
46021af
fix
Gwynbleidd0241 Apr 17, 2026
987850e
fix
Gwynbleidd0241 Apr 17, 2026
61920a7
fix
Gwynbleidd0241 Apr 17, 2026
7777890
fix
Gwynbleidd0241 Apr 17, 2026
c9f2ab6
add index, update admin.proto
Gwynbleidd0241 Apr 24, 2026
2a3dcb5
Merge branch 'main' into 39-admin
Gwynbleidd0241 Apr 28, 2026
7a37309
add implementation service and repository layer
Gwynbleidd0241 Apr 30, 2026
7d1e469
grpc admin
Gwynbleidd0241 May 4, 2026
7aee423
http admin
Gwynbleidd0241 May 4, 2026
77be96f
fix generate
Gwynbleidd0241 May 4, 2026
8687c45
add mw, setUserKey, new repo, service logic
Gwynbleidd0241 May 5, 2026
602103b
fix generate
Gwynbleidd0241 May 5, 2026
143d235
fix role existence
Gwynbleidd0241 May 5, 2026
6abafd3
Merge branch 'main' into 39-admin
Gwynbleidd0241 May 12, 2026
5131750
fix
Gwynbleidd0241 May 15, 2026
dab6e7d
fix
Gwynbleidd0241 May 15, 2026
fc9179f
fix
Gwynbleidd0241 May 15, 2026
6c99a98
fix
Gwynbleidd0241 May 15, 2026
9a51bcd
fix
Gwynbleidd0241 May 15, 2026
ee0c1f2
Merge branch 'main' into 39-admin
Gwynbleidd0241 May 19, 2026
971363f
huge fix
Gwynbleidd0241 May 27, 2026
3591ff0
fix
Gwynbleidd0241 May 27, 2026
e9f197e
fix
Gwynbleidd0241 May 28, 2026
a2167c7
refactor documentation
Gwynbleidd0241 May 28, 2026
456fb21
add tests and little refactor
Gwynbleidd0241 Jun 3, 2026
46229e1
fix
Gwynbleidd0241 Jun 3, 2026
efc3654
add grpc roles test
Gwynbleidd0241 Jun 4, 2026
307878e
some refactor
Gwynbleidd0241 Jun 8, 2026
8fa9143
merge main
Gwynbleidd0241 Jun 11, 2026
5a8b1fb
add http tests
Gwynbleidd0241 Jun 13, 2026
97047b0
fix
Gwynbleidd0241 Jun 13, 2026
ec85f91
refactor admin-api
Gwynbleidd0241 Jun 23, 2026
95e079c
update logic with permissions and cache
Gwynbleidd0241 Jul 1, 2026
2ad4e50
merge main
Gwynbleidd0241 Jul 1, 2026
90e26ae
update
Gwynbleidd0241 Jul 1, 2026
928258c
add roleID in userprofile response
Gwynbleidd0241 Jul 6, 2026
043a270
update getUserPermissions
Gwynbleidd0241 Jul 6, 2026
b7ca52c
update DeleteRole and UpdateRole
Gwynbleidd0241 Jul 6, 2026
c5c94b4
fix
Gwynbleidd0241 Jul 6, 2026
d0221a8
merge main
Gwynbleidd0241 Jul 15, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,10 @@ mock:
-destination=internal/pkg/service/massexport/mock/service.go \
github.com/ozontech/seq-ui/internal/pkg/service/massexport \
Service
PATH="$(LOCAL_BIN):$(PATH)" mockgen \
-destination=internal/pkg/service/admin/mock/service.go \
github.com/ozontech/seq-ui/internal/pkg/service/admin \
Service

.PHONY: protoc
protoc:
Expand Down
85 changes: 85 additions & 0 deletions api/admin/v1/admin.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
syntax = "proto3";

package admin.v1;

option go_package = "github.com/ozontech/seq-ui/pkg/admin/v1;admin";

service AdminService {
rpc CreateRole(CreateRoleRequest) returns (CreateRoleResponse);

rpc AddUsersToRole(AddUsersToRoleRequest) returns (AddUsersToRoleResponse);

rpc GetRoles(GetRolesRequest) returns (GetRolesResponse);

rpc GetRole(GetRoleRequest) returns (GetRoleResponse);

rpc UpdateRole(UpdateRoleRequest) returns (UpdateRoleResponse);

rpc DeleteRole(DeleteRoleRequest) returns (DeleteRoleResponse);

rpc DeleteUsersFromRole(DeleteUsersFromRoleRequest) returns (DeleteUsersFromRoleResponse);
}

message PermissionGroup {
string group = 1;
repeated string permissions = 2;
}

message Role {
int32 id = 1;
string name = 2;
repeated PermissionGroup permissions = 3;
}

message CreateRoleRequest {
string name = 1;
repeated PermissionGroup permissions = 2;
}

message CreateRoleResponse {
int32 role_id = 1;
}

message AddUsersToRoleRequest {
int32 role_id = 1;
repeated string usernames = 2;
}

message AddUsersToRoleResponse {}

message GetRolesRequest {}

message GetRolesResponse {
repeated Role roles = 1;
repeated PermissionGroup available_permissions = 2;
}

message GetRoleRequest {
int32 id = 1;
}

message GetRoleResponse {
repeated string usernames = 1;
}

message UpdateRoleRequest {
int32 id = 1;
optional string name = 2;
repeated PermissionGroup permissions = 3;
}

message UpdateRoleResponse {}

message DeleteRoleRequest {
int32 id = 1;
optional int32 replacement_role_id = 2;
}

message DeleteRoleResponse {}

message DeleteUsersFromRoleRequest {
int32 role_id = 1;
repeated string usernames = 2;
}

message DeleteUsersFromRoleResponse {}
1 change: 1 addition & 0 deletions api/userprofile/v1/userprofile.proto
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ message GetUserProfileResponse {
string timezone = 1;
string onboarding_version = 2;
LogColumns log_columns = 3;
optional int32 role_id = 4;
}

message UpdateUserProfileRequest {
Expand Down
14 changes: 10 additions & 4 deletions cmd/seq-ui/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"go.uber.org/zap"

"github.com/ozontech/seq-ui/internal/api"
admin_v1 "github.com/ozontech/seq-ui/internal/api/admin/v1"
dashboards_v1 "github.com/ozontech/seq-ui/internal/api/dashboards/v1"
errorgroups_v1 "github.com/ozontech/seq-ui/internal/api/errorgroups/v1"
massexport_v1 "github.com/ozontech/seq-ui/internal/api/massexport/v1"
Expand All @@ -29,6 +30,7 @@ import (
"github.com/ozontech/seq-ui/internal/pkg/client/seqdb"
"github.com/ozontech/seq-ui/internal/pkg/repository"
repositorych "github.com/ozontech/seq-ui/internal/pkg/repository_ch"
"github.com/ozontech/seq-ui/internal/pkg/service/admin"
asyncsearches "github.com/ozontech/seq-ui/internal/pkg/service/async_searches"
"github.com/ozontech/seq-ui/internal/pkg/service/dashboards"
"github.com/ozontech/seq-ui/internal/pkg/service/errorgroups"
Expand Down Expand Up @@ -152,6 +154,7 @@ func initApp(ctx context.Context, cfg config.Config) *api.Registrar {
}

var (
adminV1 *admin_v1.Admin
asyncSearchesService asyncsearches.Service
userProfileV1 *userprofile_v1.UserProfile
dashboardsV1 *dashboards_v1.Dashboards
Expand All @@ -166,6 +169,11 @@ func initApp(ctx context.Context, cfg config.Config) *api.Registrar {
dashboardsV1 = dashboards_v1.New(dashboardsSvc)

asyncSearchesService = asyncsearches.New(ctx, repo, defaultClient, cfg.Handlers.AsyncSearch)

if cfg.Handlers.Admin != nil {
adminSvc := admin.New(repo, redisCache, cfg.Handlers.Admin)
adminV1 = admin_v1.New(adminSvc)
}
}

seqApiV1 := seqapi_v1.New(cfg.Handlers.SeqAPI, seqDBClients, inmemWithRedisCache, redisCache, asyncSearchesService)
Expand All @@ -184,7 +192,7 @@ func initApp(ctx context.Context, cfg config.Config) *api.Registrar {
errorGroupsV1 = errorgroups_v1.New(svc)
}

return api.NewRegistrar(seqApiV1, userProfileV1, dashboardsV1, massExportV1, errorGroupsV1)
return api.NewRegistrar(adminV1, seqApiV1, userProfileV1, dashboardsV1, massExportV1, errorGroupsV1)
}

func initSeqDBClients(ctx context.Context, cfg config.Config) (map[string]seqdb.Client, error) {
Expand All @@ -202,9 +210,7 @@ func initSeqDBClients(ctx context.Context, cfg config.Config) (map[string]seqdb.

func createSeqBDClient(ctx context.Context, cfg config.SeqDBClient, seqAPI config.SeqAPI) (seqdb.Client, error) {
clientMaxRecvMsgSize := cfg.AvgDocSize * 1024 * int(seqAPI.MaxSearchLimit)
if clientMaxRecvMsgSize < defaultClientMaxRecvMsgSize {
clientMaxRecvMsgSize = defaultClientMaxRecvMsgSize
}
clientMaxRecvMsgSize = max(clientMaxRecvMsgSize, defaultClientMaxRecvMsgSize)

clientParams := seqdb.ClientParams{
Addrs: cfg.Addrs,
Expand Down
17 changes: 17 additions & 0 deletions docs/en/02-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,7 @@ handlers:
error_groups:
mass_export:
async_search:
admin:
```

### SeqAPI
Expand Down Expand Up @@ -831,6 +832,22 @@ Configuration for async search request.

Maximum length of `request.query` in async searches list responses. Requests exceeding the limit will be truncated to it

### Admin

**`admin`** *`Admin`* *`optional`*

Configuration for `/admin` API.

`Admin` fields:

+ **`super_users`** *`[]string`* *`required`*

List of users with full access to admin features.

+ **`cache_ttl`** *`string`* *`default="5m"`*

Cache TTL for roles and user permissions. If not set or set to zero, then it will be reset to `default`.

## Tracing

The tracing configuration is set through environment variables.
Expand Down
19 changes: 18 additions & 1 deletion docs/ru/02-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,7 @@ handlers:
error_groups:
mass_export:
async_search:
admin:
```

### SeqAPI
Expand All @@ -513,7 +514,7 @@ handlers:

Конфигурация `/seqapi` API.

`SeqAPI` fields:
Поля `SeqAPI`:

+ **`max_search_limit`** *`int`* *`default=0`*

Expand Down Expand Up @@ -831,6 +832,22 @@ handlers:

Максимальная длина `request.query` в ответе списка отложенных запросов. Запросы, превышающие лимит, будут обрезаны до этого значения.

### Admin

**`admin`** *`Admin`* *`optional`*

Конфигурация `/admin` API.

Поля `Admin`:

+ **`super_users`** *`[]string`* *`required`*

Список пользователей с полным доступом к административным функциям.

+ **`cache_ttl`** *`string`* *`default="5m"`*

TTL кэширования ролей и прав пользователей. Если установлено нулевое или отрицательное значение, то оно будет сброшено на `default`.

## Tracing

Конфигурация трейсинга задается переменными окружения.
Expand Down
29 changes: 29 additions & 0 deletions internal/api/admin/v1/admin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package admin_v1

import (
"github.com/go-chi/chi/v5"

grpc_api "github.com/ozontech/seq-ui/internal/api/admin/v1/grpc"
http_api "github.com/ozontech/seq-ui/internal/api/admin/v1/http"
"github.com/ozontech/seq-ui/internal/pkg/service/admin"
)

type Admin struct {
grpcAPI *grpc_api.API
httpAPI *http_api.API
}

func New(svc admin.Service) *Admin {
return &Admin{
grpcAPI: grpc_api.New(svc),
httpAPI: http_api.New(svc),
}
}

func (a *Admin) GRPCServer() *grpc_api.API {
return a.grpcAPI
}

func (a *Admin) HTTPRouter() chi.Router {
return a.httpAPI.Router()
}
32 changes: 32 additions & 0 deletions internal/api/admin/v1/grpc/api.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package grpc

import (
"github.com/ozontech/seq-ui/internal/app/types"
admin "github.com/ozontech/seq-ui/internal/pkg/service/admin"
api "github.com/ozontech/seq-ui/pkg/admin/v1"
)

type API struct {
api.UnimplementedAdminServiceServer

service admin.Service
availablePermissions []*api.PermissionGroup
}

func New(svc admin.Service) *API {
return &API{
service: svc,
availablePermissions: availablePermissionsToProto(svc.GetAvailablePermissions()),
}
}

func availablePermissionsToProto(source []types.PermissionGroup) []*api.PermissionGroup {
availablePermissions := make([]*api.PermissionGroup, 0, len(source))
for _, s := range source {
availablePermissions = append(availablePermissions, &api.PermissionGroup{
Group: s.Group,
Permissions: s.Permissions,
})
}
return availablePermissions
}
Loading
Loading