working commit

This commit is contained in:
2026-06-07 18:19:15 +02:00
parent d3556d397c
commit 0506b35cd1
26 changed files with 199 additions and 1299 deletions
+5 -5
View File
@@ -23,7 +23,7 @@ func (hand *Handler) Authentificate(ctx context.Context) (string, error) {
} }
username := meta["username"][0] username := meta["username"][0]
password := meta["password"][0] password := meta["password"][0]
validated, accountID, err := hand.lg.ValidateAccount(ctx, username, password) validated, accountID, err := hand.oper.ValidateAccount(ctx, username, password)
if !validated { if !validated {
err := status.Errorf(codes.PermissionDenied, "Wrong auth data") err := status.Errorf(codes.PermissionDenied, "Wrong auth data")
return accountID, err return accountID, err
@@ -39,7 +39,7 @@ func (hand *Handler) CreateAccount(ctx context.Context, params *mbctl.CreateAcco
if err != nil { if err != nil {
return res, err return res, err
} }
res, err = hand.lg.CreateAccount(ctx, accountID, params) res, err = hand.oper.CreateAccount(ctx, accountID, params)
return res, err return res, err
} }
@@ -51,7 +51,7 @@ func (hand *Handler) DeleteAccount(ctx context.Context, params *mbctl.DeleteAcco
if err != nil { if err != nil {
return res, err return res, err
} }
res, err = hand.lg.DeleteAccount(ctx, accountID, params) res, err = hand.oper.DeleteAccount(ctx, accountID, params)
return res, err return res, err
} }
@@ -63,7 +63,7 @@ func (hand *Handler) ListAccounts(ctx context.Context, params *mbctl.ListAccount
if err != nil { if err != nil {
return res, err return res, err
} }
res, err = hand.lg.ListAccounts(ctx, accountID, params) res, err = hand.oper.ListAccounts(ctx, accountID, params)
return res, err return res, err
} }
@@ -75,6 +75,6 @@ func (hand *Handler) UpdateAccount(ctx context.Context, params *mbctl.UpdateAcco
if err != nil { if err != nil {
return res, err return res, err
} }
res, err = hand.lg.UpdateAccount(ctx, accountID, params) res, err = hand.oper.UpdateAccount(ctx, accountID, params)
return res, err return res, err
} }
+2 -2
View File
@@ -14,7 +14,7 @@ func (hand *Handler) GetDump(ctx context.Context, params *mbctl.GetDumpParams) (
if err != nil { if err != nil {
return res, err return res, err
} }
res, err = hand.lg.GetDump(ctx, accountID, params) res, err = hand.oper.GetDump(ctx, accountID, params)
return res, err return res, err
} }
@@ -26,6 +26,6 @@ func (hand *Handler) RestoreDump(ctx context.Context, params *mbctl.RestoreDumpP
if err != nil { if err != nil {
return res, err return res, err
} }
res, err = hand.lg.RestoreDump(ctx, accountID, params) res, err = hand.oper.RestoreDump(ctx, accountID, params)
return res, err return res, err
} }
+2 -2
View File
@@ -14,7 +14,7 @@ func (hand *Handler) SetGrant(ctx context.Context, params *mbctl.SetGrantParams)
if err != nil { if err != nil {
return res, err return res, err
} }
res, err = hand.lg.SetGrant(ctx, accountID, params) res, err = hand.oper.SetGrant(ctx, accountID, params)
return res, err return res, err
} }
@@ -26,6 +26,6 @@ func (hand *Handler) DeleteGrant(ctx context.Context, params *mbctl.DeleteGrantP
if err != nil { if err != nil {
return res, err return res, err
} }
res, err = hand.lg.DeleteGrant(ctx, accountID, params) res, err = hand.oper.DeleteGrant(ctx, accountID, params)
return res, err return res, err
} }
+4 -4
View File
@@ -9,18 +9,18 @@ import (
) )
type HandlerConfig struct { type HandlerConfig struct {
Logic *operator.Logic Operator *operator.Operator
} }
type Handler struct { type Handler struct {
mbctl.UnimplementedControlServer mbctl.UnimplementedControlServer
lg *operator.Logic oper *operator.Operator
log *logger.Logger log *logger.Logger
} }
func NewHandler(conf *HandlerConfig) *Handler { func NewHandler(conf *HandlerConfig) *Handler {
hand := Handler{ hand := Handler{
lg: conf.Logic, oper: conf.Operator,
} }
hand.log = logger.NewLogger("ghandler") hand.log = logger.NewLogger("ghandler")
return &hand return &hand
+1 -1
View File
@@ -9,6 +9,6 @@ import (
func (hand *Handler) GetHello(ctx context.Context, params *mbctl.GetHelloParams) (*mbctl.GetHelloResult, error) { func (hand *Handler) GetHello(ctx context.Context, params *mbctl.GetHelloParams) (*mbctl.GetHelloResult, error) {
var err error var err error
hand.log.Debugf("Handle getHello call") hand.log.Debugf("Handle getHello call")
res, err := hand.lg.GetHello(ctx, params) res, err := hand.oper.GetHello(ctx, params)
return res, err return res, err
} }
+29 -29
View File
@@ -11,14 +11,14 @@ import (
"mbase/pkg/mbctl" "mbase/pkg/mbctl"
) )
func (lg *Logic) ValidateAccount(ctx context.Context, username, password string) (bool, string, error) { func (oper *Operator) ValidateAccount(ctx context.Context, username, password string) (bool, string, error) {
var err error var err error
var accountID string var accountID string
var valid bool var valid bool
lg.WaitRestoring() oper.WaitRestoring()
accountExists, accountDescr, err := lg.db.GetAccountByUsername(ctx, username) accountExists, accountDescr, err := oper.db.GetAccountByUsername(ctx, username)
if !accountExists { if !accountExists {
err := fmt.Errorf("Account not exists") err := fmt.Errorf("Account not exists")
return valid, accountID, err return valid, accountID, err
@@ -32,14 +32,14 @@ func (lg *Logic) ValidateAccount(ctx context.Context, username, password string)
return valid, accountID, err return valid, accountID, err
} }
func (lg *Logic) CreateAccount(ctx context.Context, accountID string, params *mbctl.CreateAccountParams) (*mbctl.CreateAccountResult, error) { func (oper *Operator) CreateAccount(ctx context.Context, accountID string, params *mbctl.CreateAccountParams) (*mbctl.CreateAccountResult, error) {
var err error var err error
res := &mbctl.CreateAccountResult{} res := &mbctl.CreateAccountResult{}
lg.WaitDumping() oper.WaitDumping()
lg.WaitRestoring() oper.WaitRestoring()
grantExists, _, err := lg.db.GetGrant(ctx, accountID, descr.GrantModifyUsers) grantExists, _, err := oper.db.GetGrant(ctx, accountID, descr.GrantModifyUsers)
if err != nil { if err != nil {
return res, err return res, err
} }
@@ -57,7 +57,7 @@ func (lg *Logic) CreateAccount(ctx context.Context, accountID string, params *mb
return res, err return res, err
} }
accountExists, _, err := lg.db.GetAccountByUsername(ctx, params.Username) accountExists, _, err := oper.db.GetAccountByUsername(ctx, params.Username)
if err != nil { if err != nil {
return res, err return res, err
} }
@@ -75,7 +75,7 @@ func (lg *Logic) CreateAccount(ctx context.Context, accountID string, params *mb
CreatedAt: now, CreatedAt: now,
UpdatedAt: now, UpdatedAt: now,
} }
err = lg.db.InsertAccount(ctx, accountDescr) err = oper.db.InsertAccount(ctx, accountDescr)
if err != nil { if err != nil {
return res, err return res, err
} }
@@ -83,14 +83,14 @@ func (lg *Logic) CreateAccount(ctx context.Context, accountID string, params *mb
return res, err return res, err
} }
func (lg *Logic) UpdateAccount(ctx context.Context, accountID string, params *mbctl.UpdateAccountParams) (*mbctl.UpdateAccountResult, error) { func (oper *Operator) UpdateAccount(ctx context.Context, accountID string, params *mbctl.UpdateAccountParams) (*mbctl.UpdateAccountResult, error) {
var err error var err error
res := &mbctl.UpdateAccountResult{} res := &mbctl.UpdateAccountResult{}
lg.WaitRestoring() oper.WaitRestoring()
lg.WaitDumping() oper.WaitDumping()
grantExists, _, err := lg.db.GetGrant(ctx, accountID, descr.GrantModifyUsers) grantExists, _, err := oper.db.GetGrant(ctx, accountID, descr.GrantModifyUsers)
if err != nil { if err != nil {
return res, err return res, err
} }
@@ -103,12 +103,12 @@ func (lg *Logic) UpdateAccount(ctx context.Context, accountID string, params *mb
var accountExists bool var accountExists bool
switch { switch {
case params.AccountID != "": case params.AccountID != "":
accountExists, accountDescr, err = lg.db.GetAccountByID(ctx, params.AccountID) accountExists, accountDescr, err = oper.db.GetAccountByID(ctx, params.AccountID)
if err != nil { if err != nil {
return res, err return res, err
} }
case params.Username != "": case params.Username != "":
accountExists, accountDescr, err = lg.db.GetAccountByUsername(ctx, params.Username) accountExists, accountDescr, err = oper.db.GetAccountByUsername(ctx, params.Username)
if err != nil { if err != nil {
return res, err return res, err
} }
@@ -133,21 +133,21 @@ func (lg *Logic) UpdateAccount(ctx context.Context, accountID string, params *mb
accountDescr.Disabled = params.Disabled accountDescr.Disabled = params.Disabled
} }
err = lg.db.UpdateAccountByID(ctx, accountDescr.ID, accountDescr) err = oper.db.UpdateAccountByID(ctx, accountDescr.ID, accountDescr)
if err != nil { if err != nil {
return res, err return res, err
} }
return res, err return res, err
} }
func (lg *Logic) DeleteAccount(ctx context.Context, accountID string, params *mbctl.DeleteAccountParams) (*mbctl.DeleteAccountResult, error) { func (oper *Operator) DeleteAccount(ctx context.Context, accountID string, params *mbctl.DeleteAccountParams) (*mbctl.DeleteAccountResult, error) {
var err error var err error
res := &mbctl.DeleteAccountResult{} res := &mbctl.DeleteAccountResult{}
lg.WaitDumping() oper.WaitDumping()
lg.WaitRestoring() oper.WaitRestoring()
grantExists, _, err := lg.db.GetGrant(ctx, accountID, descr.GrantModifyUsers) grantExists, _, err := oper.db.GetGrant(ctx, accountID, descr.GrantModifyUsers)
if err != nil { if err != nil {
return res, err return res, err
} }
@@ -160,12 +160,12 @@ func (lg *Logic) DeleteAccount(ctx context.Context, accountID string, params *mb
var accountExists bool var accountExists bool
switch { switch {
case params.AccountID != "": case params.AccountID != "":
accountExists, accountDescr, err = lg.db.GetAccountByID(ctx, params.AccountID) accountExists, accountDescr, err = oper.db.GetAccountByID(ctx, params.AccountID)
if err != nil { if err != nil {
return res, err return res, err
} }
case params.Username != "": case params.Username != "":
accountExists, accountDescr, err = lg.db.GetAccountByUsername(ctx, params.Username) accountExists, accountDescr, err = oper.db.GetAccountByUsername(ctx, params.Username)
if err != nil { if err != nil {
return res, err return res, err
} }
@@ -175,26 +175,26 @@ func (lg *Logic) DeleteAccount(ctx context.Context, accountID string, params *mb
return res, err return res, err
} }
err = lg.db.DeleteAllGrantsForAccountID(ctx, accountDescr.ID) err = oper.db.DeleteAllGrantsForAccountID(ctx, accountDescr.ID)
if err != nil { if err != nil {
return res, err return res, err
} }
err = lg.db.DeleteAccountByID(ctx, accountDescr.ID) err = oper.db.DeleteAccountByID(ctx, accountDescr.ID)
if err != nil { if err != nil {
return res, err return res, err
} }
return res, err return res, err
} }
func (lg *Logic) ListAccounts(ctx context.Context, accountID string, params *mbctl.ListAccountsParams) (*mbctl.ListAccountsResult, error) { func (oper *Operator) ListAccounts(ctx context.Context, accountID string, params *mbctl.ListAccountsParams) (*mbctl.ListAccountsResult, error) {
var err error var err error
res := &mbctl.ListAccountsResult{ res := &mbctl.ListAccountsResult{
Accounts: make([]*mbctl.AccountShortDescr, 0), Accounts: make([]*mbctl.AccountShortDescr, 0),
} }
lg.WaitRestoring() oper.WaitRestoring()
grantExists, _, err := lg.db.GetGrant(ctx, accountID, descr.GrantModifyUsers) grantExists, _, err := oper.db.GetGrant(ctx, accountID, descr.GrantModifyUsers)
if err != nil { if err != nil {
return res, err return res, err
} }
@@ -203,7 +203,7 @@ func (lg *Logic) ListAccounts(ctx context.Context, accountID string, params *mbc
return res, err return res, err
} }
accountDescrs, err := lg.db.ReducedListAccounts(ctx) accountDescrs, err := oper.db.ReducedListAccounts(ctx)
if err != nil { if err != nil {
return res, err return res, err
} }
@@ -215,7 +215,7 @@ func (lg *Logic) ListAccounts(ctx context.Context, accountID string, params *mbc
UpdatedAt: accountDescr.UpdatedAt, UpdatedAt: accountDescr.UpdatedAt,
Grants: make([]*mbctl.GrantShortDescr, 0), Grants: make([]*mbctl.GrantShortDescr, 0),
} }
grantDescrs, err := lg.db.ListGrantsByAccountID(ctx, accountDescr.ID) grantDescrs, err := oper.db.ListGrantsByAccountID(ctx, accountDescr.ID)
if err != nil { if err != nil {
return res, err return res, err
} }
+7 -7
View File
@@ -14,23 +14,23 @@ const (
defaultSeedPassword = "mbase" defaultSeedPassword = "mbase"
) )
func (lg *Logic) CleanDatabase(ctx context.Context) error { func (oper *Operator) CleanDatabase(ctx context.Context) error {
var err error var err error
err = lg.db.CleanDatabase(ctx) err = oper.db.CleanDatabase(ctx)
if err != nil { if err != nil {
return err return err
} }
return err return err
} }
func (lg *Logic) SeedAccount(ctx context.Context) (string, error) { func (oper *Operator) SeedAccount(ctx context.Context) (string, error) {
var err error var err error
var accountID string var accountID string
accountDescrs, err := lg.db.ReducedListAccounts(ctx) accountDescrs, err := oper.db.ReducedListAccounts(ctx)
if err != nil { if err != nil {
return accountID, err return accountID, err
} }
lg.log.Debugf("Seed account") oper.log.Debugf("Seed account")
if len(accountDescrs) == 0 { if len(accountDescrs) == 0 {
now := time.Now().Format(time.RFC3339) now := time.Now().Format(time.RFC3339)
passhash := auxpwd.MakeSHA256Hash([]byte(defaultSeedPassword)) passhash := auxpwd.MakeSHA256Hash([]byte(defaultSeedPassword))
@@ -42,7 +42,7 @@ func (lg *Logic) SeedAccount(ctx context.Context) (string, error) {
CreatedAt: now, CreatedAt: now,
UpdatedAt: now, UpdatedAt: now,
} }
err = lg.db.InsertAccount(ctx, accountDescr) err = oper.db.InsertAccount(ctx, accountDescr)
if err != nil { if err != nil {
return accountID, err return accountID, err
} }
@@ -57,7 +57,7 @@ func (lg *Logic) SeedAccount(ctx context.Context) (string, error) {
Operation: grantType, Operation: grantType,
CreatedAt: now, CreatedAt: now,
} }
err = lg.db.InsertGrant(ctx, grantDescr) err = oper.db.InsertGrant(ctx, grantDescr)
if err != nil { if err != nil {
return accountID, err return accountID, err
} }
+22 -22
View File
@@ -11,11 +11,11 @@ import (
"go.yaml.in/yaml/v4" "go.yaml.in/yaml/v4"
) )
func (lg *Logic) GetDump(ctx context.Context, accountID string, params *mbctl.GetDumpParams) (*mbctl.GetDumpResult, error) { func (oper *Operator) GetDump(ctx context.Context, accountID string, params *mbctl.GetDumpParams) (*mbctl.GetDumpResult, error) {
var err error var err error
res := &mbctl.GetDumpResult{} res := &mbctl.GetDumpResult{}
grantExists, _, err := lg.db.GetGrant(ctx, accountID, descr.GrantModifyDatabase) grantExists, _, err := oper.db.GetGrant(ctx, accountID, descr.GrantModifyDatabase)
if err != nil { if err != nil {
return res, err return res, err
} }
@@ -24,21 +24,21 @@ func (lg *Logic) GetDump(ctx context.Context, accountID string, params *mbctl.Ge
return res, err return res, err
} }
lg.WaitRestoring() oper.WaitRestoring()
lg.WaitDumping() oper.WaitDumping()
lg.DumpingSemUp() oper.DumpingSemUp()
defer lg.DumpingSemDown() defer oper.DumpingSemDown()
listAccounts, err := lg.db.CompletedListAccounts(ctx) listAccounts, err := oper.db.CompletedListAccounts(ctx)
if err != nil { if err != nil {
return res, err return res, err
} }
listGrants, err := lg.db.ListGrants(ctx) listGrants, err := oper.db.ListGrants(ctx)
if err != nil { if err != nil {
return res, err return res, err
} }
lg.DumpingSemDown() oper.DumpingSemDown()
dump := descr.Dump{ dump := descr.Dump{
Timestamp: time.Now().Format(time.RFC3339), Timestamp: time.Now().Format(time.RFC3339),
@@ -55,11 +55,11 @@ func (lg *Logic) GetDump(ctx context.Context, accountID string, params *mbctl.Ge
return res, err return res, err
} }
func (lg *Logic) RestoreDump(ctx context.Context, accountID string, params *mbctl.RestoreDumpParams) (*mbctl.RestoreDumpResult, error) { func (oper *Operator) RestoreDump(ctx context.Context, accountID string, params *mbctl.RestoreDumpParams) (*mbctl.RestoreDumpResult, error) {
var err error var err error
res := &mbctl.RestoreDumpResult{} res := &mbctl.RestoreDumpResult{}
grantExists, _, err := lg.db.GetGrant(ctx, accountID, descr.GrantModifyDatabase) grantExists, _, err := oper.db.GetGrant(ctx, accountID, descr.GrantModifyDatabase)
if err != nil { if err != nil {
return res, err return res, err
} }
@@ -68,8 +68,8 @@ func (lg *Logic) RestoreDump(ctx context.Context, accountID string, params *mbct
return res, err return res, err
} }
lg.WaitDumping() oper.WaitDumping()
lg.WaitRestoring() oper.WaitRestoring()
var dump descr.Dump var dump descr.Dump
@@ -78,28 +78,28 @@ func (lg *Logic) RestoreDump(ctx context.Context, accountID string, params *mbct
return res, err return res, err
} }
lg.RestoringSemUp() oper.RestoringSemUp()
defer lg.RestoringSemDown() defer oper.RestoringSemDown()
if params.DeleteAllRecords { if params.DeleteAllRecords {
err = lg.db.CleanDatabase(ctx) err = oper.db.CleanDatabase(ctx)
if err != nil { if err != nil {
return res, err return res, err
} }
} }
for _, account := range dump.Accounts { for _, account := range dump.Accounts {
lg.log.Infof("Insert account %s", account.Username) oper.log.Infof("Insert account %s", account.Username)
err = lg.db.InsertAccount(ctx, &account) err = oper.db.InsertAccount(ctx, &account)
if err != nil { if err != nil {
lg.log.Errorf("Insert account error: %v", err) oper.log.Errorf("Insert account error: %v", err)
} }
} }
for _, grant := range dump.Grants { for _, grant := range dump.Grants {
lg.log.Infof("Insert grant %s for account %d", grant.Operation, grant.AccountID) oper.log.Infof("Insert grant %s for account %d", grant.Operation, grant.AccountID)
err = lg.db.InsertGrant(ctx, &grant) err = oper.db.InsertGrant(ctx, &grant)
if err != nil { if err != nil {
lg.log.Errorf("Insert account error: %v", err) oper.log.Errorf("Insert account error: %v", err)
} }
} }
+14 -14
View File
@@ -10,13 +10,13 @@ import (
"mbase/pkg/mbctl" "mbase/pkg/mbctl"
) )
func (lg *Logic) SetGrant(ctx context.Context, accountID string, params *mbctl.SetGrantParams) (*mbctl.SetGrantResult, error) { func (oper *Operator) SetGrant(ctx context.Context, accountID string, params *mbctl.SetGrantParams) (*mbctl.SetGrantResult, error) {
var err error var err error
res := &mbctl.SetGrantResult{} res := &mbctl.SetGrantResult{}
lg.WaitDumping() oper.WaitDumping()
grantExists, _, err := lg.db.GetGrant(ctx, accountID, descr.GrantModifyUsers) grantExists, _, err := oper.db.GetGrant(ctx, accountID, descr.GrantModifyUsers)
if err != nil { if err != nil {
return res, err return res, err
} }
@@ -45,12 +45,12 @@ func (lg *Logic) SetGrant(ctx context.Context, accountID string, params *mbctl.S
var accountExists bool var accountExists bool
switch { switch {
case params.AccountID != "": case params.AccountID != "":
accountExists, accountDescr, err = lg.db.GetAccountByID(ctx, params.AccountID) accountExists, accountDescr, err = oper.db.GetAccountByID(ctx, params.AccountID)
if err != nil { if err != nil {
return res, err return res, err
} }
case params.Username != "": case params.Username != "":
accountExists, accountDescr, err = lg.db.GetAccountByUsername(ctx, params.Username) accountExists, accountDescr, err = oper.db.GetAccountByUsername(ctx, params.Username)
if err != nil { if err != nil {
return res, err return res, err
} }
@@ -60,7 +60,7 @@ func (lg *Logic) SetGrant(ctx context.Context, accountID string, params *mbctl.S
return res, err return res, err
} }
grantExists, _, err = lg.db.GetGrant(ctx, accountDescr.ID, params.Operation) grantExists, _, err = oper.db.GetGrant(ctx, accountDescr.ID, params.Operation)
if err != nil { if err != nil {
return res, err return res, err
} }
@@ -75,20 +75,20 @@ func (lg *Logic) SetGrant(ctx context.Context, accountID string, params *mbctl.S
CreatedAt: now, CreatedAt: now,
Operation: params.Operation, Operation: params.Operation,
} }
err = lg.db.InsertGrant(ctx, grantDescr) err = oper.db.InsertGrant(ctx, grantDescr)
if err != nil { if err != nil {
return res, err return res, err
} }
return res, err return res, err
} }
func (lg *Logic) DeleteGrant(ctx context.Context, accountID string, params *mbctl.DeleteGrantParams) (*mbctl.DeleteGrantResult, error) { func (oper *Operator) DeleteGrant(ctx context.Context, accountID string, params *mbctl.DeleteGrantParams) (*mbctl.DeleteGrantResult, error) {
var err error var err error
res := &mbctl.DeleteGrantResult{} res := &mbctl.DeleteGrantResult{}
lg.WaitDumping() oper.WaitDumping()
grantExists, _, err := lg.db.GetGrant(ctx, accountID, descr.GrantModifyUsers) grantExists, _, err := oper.db.GetGrant(ctx, accountID, descr.GrantModifyUsers)
if err != nil { if err != nil {
return res, err return res, err
} }
@@ -117,12 +117,12 @@ func (lg *Logic) DeleteGrant(ctx context.Context, accountID string, params *mbct
var accountExists bool var accountExists bool
switch { switch {
case params.AccountID != "": case params.AccountID != "":
accountExists, accountDescr, err = lg.db.GetAccountByID(ctx, params.AccountID) accountExists, accountDescr, err = oper.db.GetAccountByID(ctx, params.AccountID)
if err != nil { if err != nil {
return res, err return res, err
} }
case params.Username != "": case params.Username != "":
accountExists, accountDescr, err = lg.db.GetAccountByUsername(ctx, params.Username) accountExists, accountDescr, err = oper.db.GetAccountByUsername(ctx, params.Username)
if err != nil { if err != nil {
return res, err return res, err
} }
@@ -132,7 +132,7 @@ func (lg *Logic) DeleteGrant(ctx context.Context, accountID string, params *mbct
return res, err return res, err
} }
grantExists, _, err = lg.db.GetGrant(ctx, accountDescr.ID, params.Operation) grantExists, _, err = oper.db.GetGrant(ctx, accountDescr.ID, params.Operation)
if err != nil { if err != nil {
return res, err return res, err
} }
@@ -140,7 +140,7 @@ func (lg *Logic) DeleteGrant(ctx context.Context, accountID string, params *mbct
err := fmt.Errorf("Requested grant for the user not found") err := fmt.Errorf("Requested grant for the user not found")
return res, err return res, err
} }
err = lg.db.DeleteGrantByAccountID(ctx, accountDescr.ID, params.Operation) err = oper.db.DeleteGrantByAccountID(ctx, accountDescr.ID, params.Operation)
if err != nil { if err != nil {
return res, err return res, err
} }
+1 -1
View File
@@ -6,7 +6,7 @@ import (
"mbase/pkg/mbctl" "mbase/pkg/mbctl"
) )
func (lg *Logic) GetHello(ctx context.Context, params *mbctl.GetHelloParams) (*mbctl.GetHelloResult, error) { func (oper *Operator) GetHello(ctx context.Context, params *mbctl.GetHelloParams) (*mbctl.GetHelloResult, error) {
var err error var err error
res := &mbctl.GetHelloResult{ res := &mbctl.GetHelloResult{
Message: "hello", Message: "hello",
+18 -18
View File
@@ -8,54 +8,54 @@ import (
"mbase/pkg/logger" "mbase/pkg/logger"
) )
type LogicConfig struct { type OperatorConfig struct {
Database *maindb.Database Database *maindb.Database
} }
type Logic struct { type Operator struct {
log *logger.Logger log *logger.Logger
db *maindb.Database db *maindb.Database
dumpingSem atomic.Bool dumpingSem atomic.Bool
restoringSem atomic.Bool restoringSem atomic.Bool
} }
func NewLogic(conf *LogicConfig) (*Logic, error) { func NewOperator(conf *OperatorConfig) (*Operator, error) {
var err error var err error
lg := &Logic{ oper := &Operator{
db: conf.Database, db: conf.Database,
} }
lg.log = logger.NewLogger("logic") oper.log = logger.NewLogger("Operator")
return lg, err return oper, err
} }
func (lg *Logic) DumpingSemUp() { func (oper *Operator) DumpingSemUp() {
lg.dumpingSem.Store(true) oper.dumpingSem.Store(true)
} }
func (lg *Logic) DumpingSemDown() { func (oper *Operator) DumpingSemDown() {
lg.dumpingSem.Store(false) oper.dumpingSem.Store(false)
} }
func (lg *Logic) WaitDumping() { func (oper *Operator) WaitDumping() {
for { for {
if !lg.dumpingSem.Load() { if !oper.dumpingSem.Load() {
return return
} }
time.Sleep(1 * time.Millisecond) time.Sleep(1 * time.Millisecond)
} }
} }
func (lg *Logic) RestoringSemUp() { func (oper *Operator) RestoringSemUp() {
lg.restoringSem.Store(true) oper.restoringSem.Store(true)
} }
func (lg *Logic) RestoringSemDown() { func (oper *Operator) RestoringSemDown() {
lg.restoringSem.Store(false) oper.restoringSem.Store(false)
} }
func (lg *Logic) WaitRestoring() { func (oper *Operator) WaitRestoring() {
for { for {
if !lg.restoringSem.Load() { if !oper.restoringSem.Load() {
return return
} }
time.Sleep(1 * time.Millisecond) time.Sleep(1 * time.Millisecond)
+6 -6
View File
@@ -26,7 +26,7 @@ import (
type Server struct { type Server struct {
conf *config.Config conf *config.Config
lg *operator.Logic oper *operator.Operator
svc *service.Service svc *service.Service
hand *handler.Handler hand *handler.Handler
log *logger.Logger log *logger.Logger
@@ -175,11 +175,11 @@ func (srv *Server) Build() error {
if err != nil { if err != nil {
return err return err
} }
// Create logic // Create operator
logicConfig := &operator.LogicConfig{ operConfig := &operator.OperatorConfig{
Database: srv.db, Database: srv.db,
} }
srv.lg, err = operator.NewLogic(logicConfig) srv.oper, err = operator.NewOperator(operConfig)
if err != nil { if err != nil {
return err return err
} }
@@ -198,7 +198,7 @@ func (srv *Server) Build() error {
} }
// Create handler // Create handler
handlerConfig := &handler.HandlerConfig{ handlerConfig := &handler.HandlerConfig{
Logic: srv.lg, Operator: srv.oper,
} }
srv.hand = handler.NewHandler(handlerConfig) srv.hand = handler.NewHandler(handlerConfig)
if err != nil { if err != nil {
@@ -212,7 +212,7 @@ func (srv *Server) Build() error {
Hostname: srv.conf.Hostname, Hostname: srv.conf.Hostname,
Handler: srv.hand, Handler: srv.hand,
Logic: srv.lg, Operator: srv.oper,
X509Cert: srv.x509cert, X509Cert: srv.x509cert,
X509Key: srv.x509key, X509Key: srv.x509key,
NetACL: srv.nacl, NetACL: srv.nacl,
+3 -3
View File
@@ -20,7 +20,7 @@ import (
type ServiceConfig struct { type ServiceConfig struct {
Handler *handler.Handler Handler *handler.Handler
Logic *operator.Logic Operator *operator.Operator
NetACL *netacl.NetACL NetACL *netacl.NetACL
Portnum uint32 Portnum uint32
Address string Address string
@@ -33,7 +33,7 @@ type ServiceConfig struct {
type Service struct { type Service struct {
gsrv *grpc.Server gsrv *grpc.Server
hand *handler.Handler hand *handler.Handler
lg *operator.Logic oper *operator.Operator
log *logger.Logger log *logger.Logger
nacl *netacl.NetACL nacl *netacl.NetACL
portnum uint32 portnum uint32
@@ -49,7 +49,7 @@ type Service struct {
func NewService(conf *ServiceConfig) *Service { func NewService(conf *ServiceConfig) *Service {
svc := Service{ svc := Service{
hand: conf.Handler, hand: conf.Handler,
lg: conf.Logic, oper: conf.Operator,
nacl: conf.NetACL, nacl: conf.NetACL,
portnum: conf.Portnum, portnum: conf.Portnum,
address: conf.Address, address: conf.Address,
+3 -3
View File
@@ -18,7 +18,7 @@ const (
) )
type Util struct { type Util struct {
oper *operator.Logic oper *operator.Operator
subCmd *cobra.Command subCmd *cobra.Command
createAccountParams CreateAccountParams createAccountParams CreateAccountParams
listAccountsParams ListAccountsParams listAccountsParams ListAccountsParams
@@ -28,7 +28,7 @@ type Util struct {
operID string operID string
} }
func NewUtil(oper *operator.Logic) *Util { func NewUtil(oper *operator.Operator) *Util {
return &Util{ return &Util{
oper: oper, oper: oper,
} }
@@ -86,7 +86,7 @@ func (util *Util) BuildCmds() *cobra.Command {
} }
updateAccountsCmd.Flags().StringVarP(&util.updateAccountParams.Password, "newpass", "N", util.updateAccountParams.Password, "New password") updateAccountsCmd.Flags().StringVarP(&util.updateAccountParams.Password, "newpass", "N", util.updateAccountParams.Password, "New password")
updateAccountsCmd.Flags().StringVarP(&util.updateAccountParams.Username, "newname", "M", util.updateAccountParams.Username, "New username") updateAccountsCmd.Flags().StringVarP(&util.updateAccountParams.Username, "newname", "M", util.updateAccountParams.Username, "New username")
updateAccountsCmd.MarkFlagsOneRequired("newpass", "newname") updateAccountsCmd.MarkFlagsOneRequired("newpass", "newname")
subCmd.AddCommand(updateAccountsCmd) subCmd.AddCommand(updateAccountsCmd)
var deleteAccountCmd = &cobra.Command{ var deleteAccountCmd = &cobra.Command{
-63
View File
@@ -1,63 +0,0 @@
package main
import (
"context"
"mbase/pkg/mbctl"
)
func (util *Util) CreateAccount(ctx context.Context, operID string) (*mbctl.CreateAccountResult, error) {
var err error
res := &mbctl.CreateAccountResult{}
params := &mbctl.CreateAccountParams{
Username: util.username,
Password: util.password,
}
res, err = util.lg.CreateAccount(ctx, operID, params)
if err != nil {
return res, err
}
return res, err
}
func (util *Util) DeleteAccount(ctx context.Context, operID string) (*mbctl.DeleteAccountResult, error) {
var err error
res := &mbctl.DeleteAccountResult{}
params := &mbctl.DeleteAccountParams{
Username: util.username,
AccountID: util.accountID,
}
res, err = util.lg.DeleteAccount(ctx, operID, params)
if err != nil {
return res, err
}
return res, err
}
func (util *Util) ListAccounts(ctx context.Context, operID string) (*mbctl.ListAccountsResult, error) {
var err error
res := &mbctl.ListAccountsResult{}
params := &mbctl.ListAccountsParams{}
res, err = util.lg.ListAccounts(ctx, operID, params)
if err != nil {
return res, err
}
return res, err
}
func (util *Util) UpdateAccount(ctx context.Context, operID string) (*mbctl.UpdateAccountResult, error) {
var err error
res := &mbctl.UpdateAccountResult{}
params := &mbctl.UpdateAccountParams{
Username: util.username,
AccountID: util.accountID,
NewUsername: util.newUsername,
NewPassword: util.newPassword,
}
res, err = util.lg.UpdateAccount(ctx, operID, params)
if err != nil {
return res, err
}
return res, err
}
-40
View File
@@ -1,40 +0,0 @@
package main
import (
"context"
"mbase/pkg/mbctl"
)
func (util *Util) SetGrant(ctx context.Context, operID string) (*mbctl.SetGrantResult, error) {
var err error
res := &mbctl.SetGrantResult{}
params := &mbctl.SetGrantParams{
Username: util.username,
AccountID: util.accountID,
Operation: util.operation,
}
res, err = util.lg.SetGrant(ctx, operID, params)
if err != nil {
return res, err
}
if err != nil {
return res, err
}
return res, err
}
func (util *Util) DeleteGrant(ctx context.Context, operID string) (*mbctl.DeleteGrantResult, error) {
var err error
res := &mbctl.DeleteGrantResult{}
params := &mbctl.DeleteGrantParams{
Username: util.username,
AccountID: util.accountID,
Operation: util.operation,
}
res, err = util.lg.DeleteGrant(ctx, operID, params)
if err != nil {
return res, err
}
return res, err
}
-467
View File
@@ -1,467 +0,0 @@
/*
* Copyright 2024 Oleg Borodin <borodin@unix7.org>
*/
package main
import (
"context"
"errors"
"flag"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"time"
"mbase/app/config"
"mbase/app/maindb"
"mbase/pkg/descr"
"mbase/app/logic"
"sigs.k8s.io/yaml"
)
const (
rcFilename = ".certmanager.yaml"
helpCmd = "help"
createAccountCmd = "createAccount"
updateAccountCmd = "updateAccount"
deleteAccountCmd = "deleteAccount"
listAccountsCmd = "listAccounts"
setGrantCmd = "setGrant"
deleteGrantCmd = "deleteGrant"
initDatabaseCmd = "initDatabase"
seedAccountCmd = "seedAccount"
)
func main() {
var err error
util := NewUtil()
err = util.Build()
if err != nil {
fmt.Printf("Build error: %v\n", err)
os.Exit(1)
}
err = util.Exec()
if err != nil {
fmt.Printf("Exec error: %v\n", err)
os.Exit(1)
}
os.Exit(0)
}
type Util struct {
subCmd string
cmdTimeout int64
conf *config.Config
lg *logic.Logic
db *maindb.Database
state descr.Server
sfile string
accessUsername string
accessPassword string
accountID int64
username string
password string
disable bool
newUsername string
newPassword string
operation string
quiet bool
}
func NewUtil() *Util {
var util Util
util.cmdTimeout = 120
return &util
}
func (util *Util) GetOpt() error {
var err error
exeName := filepath.Base(os.Args[0])
flag.Int64Var(&util.cmdTimeout, "timeout", util.cmdTimeout, "command execution timeout")
flag.StringVar(&util.accessUsername, "user", util.accessUsername, "access login")
flag.StringVar(&util.accessPassword, "pass", util.accessPassword, "access password")
flag.BoolVar(&util.quiet, "quiet", util.quiet, "don't print result")
help := func() {
fmt.Println("")
fmt.Printf("Usage: %s [option] command [command option]\n", exeName)
fmt.Printf("\n")
fmt.Printf(" %s, %s, %s, %s,\n",
createAccountCmd,
deleteAccountCmd,
listAccountsCmd,
updateAccountCmd)
fmt.Printf(" %s, %s\n",
setGrantCmd,
deleteGrantCmd)
fmt.Printf(" %s, %s\n",
initDatabaseCmd,
seedAccountCmd)
fmt.Printf("\n")
fmt.Printf("Global options:\n")
flag.PrintDefaults()
fmt.Printf("\n")
}
flag.Usage = help
flag.Parse()
args := flag.Args()
var subCmd string
var subArgs []string
if len(args) > 0 {
subCmd = args[0]
subArgs = args[1:]
}
util.subCmd = subCmd
switch subCmd {
case helpCmd:
help()
return errors.New("Unknown command")
case createAccountCmd:
flagSet := flag.NewFlagSet(createAccountCmd, flag.ExitOnError)
flagSet.StringVar(&util.username, "username", util.username, "user name")
flagSet.StringVar(&util.password, "password", util.password, "user password")
flagSet.Usage = func() {
fmt.Printf("\n")
fmt.Printf("Usage: %s [global options] %s [command options]\n", exeName, subCmd)
fmt.Printf("\n")
fmt.Printf("The command options: none\n")
flagSet.PrintDefaults()
fmt.Printf("\n")
}
flagSet.Parse(subArgs)
util.subCmd = subCmd
case deleteAccountCmd:
flagSet := flag.NewFlagSet(deleteAccountCmd, flag.ExitOnError)
flagSet.StringVar(&util.username, "username", util.username, "user name")
flagSet.Int64Var(&util.accountID, "accountId", util.accountID, "account ID")
flagSet.Usage = func() {
fmt.Printf("\n")
fmt.Printf("Usage: %s [global options] %s [command options]\n", exeName, subCmd)
fmt.Printf("\n")
fmt.Printf("The command options: none\n")
flagSet.PrintDefaults()
fmt.Printf("\n")
}
flagSet.Parse(subArgs)
util.subCmd = subCmd
case listAccountsCmd:
flagSet := flag.NewFlagSet(listAccountsCmd, flag.ExitOnError)
flagSet.Usage = func() {
fmt.Printf("\n")
fmt.Printf("Usage: %s [global options] %s [command options]\n", exeName, subCmd)
fmt.Printf("\n")
fmt.Printf("The command options: none\n")
flagSet.PrintDefaults()
fmt.Printf("\n")
}
flagSet.Parse(subArgs)
util.subCmd = subCmd
case updateAccountCmd:
flagSet := flag.NewFlagSet(updateAccountCmd, flag.ExitOnError)
flagSet.StringVar(&util.username, "username", util.username, "user name")
flagSet.Int64Var(&util.accountID, "accountId", util.accountID, "account ID")
flagSet.StringVar(&util.newUsername, "newUsername", util.newUsername, "new user name")
flagSet.StringVar(&util.newPassword, "newPassword", util.newPassword, "new user password")
flagSet.BoolVar(&util.disable, "disable", util.disable, "disable account")
flagSet.Usage = func() {
fmt.Printf("\n")
fmt.Printf("Usage: %s [global options] %s [command options]\n", exeName, subCmd)
fmt.Printf("\n")
fmt.Printf("The command options: none\n")
flagSet.PrintDefaults()
fmt.Printf("\n")
}
flagSet.Parse(subArgs)
util.subCmd = subCmd
case setGrantCmd:
flagSet := flag.NewFlagSet(setGrantCmd, flag.ExitOnError)
flagSet.StringVar(&util.username, "username", util.username, "user name")
flagSet.Int64Var(&util.accountID, "accountId", util.accountID, "account ID")
flagSet.StringVar(&util.operation, "operation", util.operation, "grant type")
flagSet.Usage = func() {
fmt.Printf("\n")
fmt.Printf("Usage: %s [global options] %s [command options]\n", exeName, subCmd)
fmt.Printf("\n")
fmt.Printf("The command options: none\n")
flagSet.PrintDefaults()
fmt.Printf("\n")
}
flagSet.Parse(subArgs)
util.subCmd = subCmd
case deleteGrantCmd:
flagSet := flag.NewFlagSet(deleteGrantCmd, flag.ExitOnError)
flagSet.StringVar(&util.username, "username", util.username, "user name")
flagSet.Int64Var(&util.accountID, "accountId", util.accountID, "account ID")
flagSet.StringVar(&util.operation, "operation", util.operation, "grant type")
flagSet.Usage = func() {
fmt.Printf("\n")
fmt.Printf("Usage: %s [global options] %s [command options]\n", exeName, subCmd)
fmt.Printf("\n")
fmt.Printf("The command options: none\n")
flagSet.PrintDefaults()
fmt.Printf("\n")
}
flagSet.Parse(subArgs)
util.subCmd = subCmd
case initDatabaseCmd:
flagSet := flag.NewFlagSet(initDatabaseCmd, flag.ExitOnError)
flagSet.Usage = func() {
fmt.Printf("\n")
fmt.Printf("Usage: %s [global options] %s [command options]\n", exeName, subCmd)
fmt.Printf("\n")
fmt.Printf("The command options: none\n")
flagSet.PrintDefaults()
fmt.Printf("\n")
}
flagSet.Parse(subArgs)
util.subCmd = subCmd
case seedAccountCmd:
flagSet := flag.NewFlagSet(seedAccountCmd, flag.ExitOnError)
flagSet.Usage = func() {
fmt.Printf("\n")
fmt.Printf("Usage: %s [global options] %s [command options]\n", exeName, subCmd)
fmt.Printf("\n")
fmt.Printf("The command options: none\n")
flagSet.PrintDefaults()
fmt.Printf("\n")
}
flagSet.Parse(subArgs)
util.subCmd = subCmd
default:
help()
return errors.New("Unknown command")
}
return err
}
func (util *Util) Build() error {
var err error
util.conf = config.NewConfig()
err = util.conf.ReadFile()
if err != nil {
return err
}
err = util.conf.ReadEnv()
if err != nil {
return err
}
util.sfile = filepath.Join(util.conf.DataDir, "certmanager.yaml")
db, err := maindb.NewDatabase(util.conf.DataDir)
if err != nil {
return err
}
err = db.OpenDatabase()
if err != nil {
return err
}
util.db = db
logicConfig := &logic.LogicConfig{
Database: util.db,
}
util.lg, err = logic.NewLogic(logicConfig)
if err != nil {
return err
}
return err
}
type Response struct {
Command string `json:"command" yaml:"command"`
Args []string `json:"args" yaml:"args"`
Error bool `json:"error" yaml:"error"`
Message string `json:"message,omitempty" yaml:"message,omitempty"`
Result any `json:"result,omitempty" yaml:"result,omitempty"`
}
func (util *Util) Exec() error {
var err error
err = util.GetOpt()
if err != nil {
return err
}
var timeout = time.Duration(util.cmdTimeout) * time.Second
ctx, close := context.WithTimeout(context.Background(), timeout)
defer close()
var res any
switch util.subCmd {
case initDatabaseCmd:
res, err = util.InitDatabase(ctx)
case seedAccountCmd:
res, err = util.SeedAccount(ctx)
default:
authOk, operID, localErr := util.lg.ValidateAcount(ctx, util.accessUsername, util.accessPassword)
if err != nil {
err = localErr
goto exit
}
if !authOk {
err = fmt.Errorf("Incorrect username or password")
goto exit
}
switch util.subCmd {
case createAccountCmd:
res, err = util.CreateAccount(ctx, operID)
case updateAccountCmd:
res, err = util.UpdateAccount(ctx, operID)
case listAccountsCmd:
res, err = util.ListAccounts(ctx, operID)
case deleteAccountCmd:
res, err = util.DeleteAccount(ctx, operID)
case setGrantCmd:
res, err = util.SetGrant(ctx, operID)
case deleteGrantCmd:
res, err = util.DeleteGrant(ctx, operID)
default:
err = errors.New("Unknown cli command")
}
}
exit:
var resp Response
resp.Command = util.subCmd
resp.Args = os.Args
if err != nil {
resp.Error = true
resp.Message = fmt.Sprintf("%v", err)
} else {
resp.Result = res
}
if !resp.Error && !util.quiet {
respBytes, _ := yaml.Marshal(resp)
fmt.Println(string(respBytes))
}
return err
}
type InitDatabaseRes struct{}
func (util *Util) InitDatabase(ctx context.Context) (InitDatabaseRes, error) {
res := InitDatabaseRes{}
// Initialize database
// Load state
err := util.LoadState()
if err != nil {
return res, err
}
if !util.state.DatabaseInitialized {
if util.db == nil {
err = fmt.Errorf("Nil db object")
return res, err
}
err := util.db.InitDatabase()
if err != nil {
return res, err
}
util.state.DatabaseInitialized = true
err = util.SaveState()
if err != nil {
return res, err
}
}
return res, err
}
type SeedAccountRes struct{}
func (util *Util) SeedAccount(ctx context.Context) (SeedAccountRes, error) {
// Seed accounts
res := SeedAccountRes{}
_, err := util.lg.SeedAccount(ctx)
if err != nil {
return res, err
}
return res, err
}
func (util *Util) LoadState() error {
var err error
_, err = os.Stat(util.sfile)
if os.IsNotExist(err) {
err = nil
return err
}
file, err := os.Open(util.sfile)
if err != nil {
return err
}
defer file.Close()
stateBytes, err := ioutil.ReadAll(file)
if err != nil {
return err
}
err = yaml.Unmarshal(stateBytes, &util.state)
if err != nil {
return err
}
return err
}
func (util *Util) SaveState() error {
var err error
file, err := os.OpenFile(util.sfile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0640)
if err != nil {
return err
}
defer file.Close()
util.state.UpdatedAt = time.Now().Format(time.RFC3339)
if util.state.CreatedAt == "" {
util.state.CreatedAt = util.state.UpdatedAt
}
stateBytes, err := yaml.Marshal(util.state)
if err != nil {
return err
}
_, err = file.Write(stateBytes)
if err != nil {
return err
}
return err
}
-63
View File
@@ -1,63 +0,0 @@
package main
import (
"context"
"mbase/pkg/mbctl"
)
func (util *Util) CreateAccount(ctx context.Context, operID string) (*mbctl.CreateAccountResult, error) {
var err error
res := &mbctl.CreateAccountResult{}
params := &mbctl.CreateAccountParams{
Username: util.username,
Password: util.password,
}
res, err = util.lg.CreateAccount(ctx, operID, params)
if err != nil {
return res, err
}
return res, err
}
func (util *Util) DeleteAccount(ctx context.Context, operID string) (*mbctl.DeleteAccountResult, error) {
var err error
res := &mbctl.DeleteAccountResult{}
params := &mbctl.DeleteAccountParams{
Username: util.username,
AccountID: util.accountID,
}
res, err = util.lg.DeleteAccount(ctx, operID, params)
if err != nil {
return res, err
}
return res, err
}
func (util *Util) ListAccounts(ctx context.Context, operID string) (*mbctl.ListAccountsResult, error) {
var err error
res := &mbctl.ListAccountsResult{}
params := &mbctl.ListAccountsParams{}
res, err = util.lg.ListAccounts(ctx, operID, params)
if err != nil {
return res, err
}
return res, err
}
func (util *Util) UpdateAccount(ctx context.Context, operID string) (*mbctl.UpdateAccountResult, error) {
var err error
res := &mbctl.UpdateAccountResult{}
params := &mbctl.UpdateAccountParams{
Username: util.username,
AccountID: util.accountID,
NewUsername: util.newUsername,
NewPassword: util.newPassword,
}
res, err = util.lg.UpdateAccount(ctx, operID, params)
if err != nil {
return res, err
}
return res, err
}
-40
View File
@@ -1,40 +0,0 @@
package main
import (
"context"
"mbase/pkg/mbctl"
)
func (util *Util) SetGrant(ctx context.Context, operID string) (*mbctl.SetGrantResult, error) {
var err error
res := &mbctl.SetGrantResult{}
params := &mbctl.SetGrantParams{
Username: util.username,
AccountID: util.accountID,
Operation: util.operation,
}
res, err = util.lg.SetGrant(ctx, operID, params)
if err != nil {
return res, err
}
if err != nil {
return res, err
}
return res, err
}
func (util *Util) DeleteGrant(ctx context.Context, operID string) (*mbctl.DeleteGrantResult, error) {
var err error
res := &mbctl.DeleteGrantResult{}
params := &mbctl.DeleteGrantParams{
Username: util.username,
AccountID: util.accountID,
Operation: util.operation,
}
res, err = util.lg.DeleteGrant(ctx, operID, params)
if err != nil {
return res, err
}
return res, err
}
-467
View File
@@ -1,467 +0,0 @@
/*
* Copyright 2024 Oleg Borodin <borodin@unix7.org>
*/
package main
import (
"context"
"errors"
"flag"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"time"
"mbase/app/config"
"mbase/app/maindb"
"mbase/pkg/descr"
"mbase/app/logic"
"sigs.k8s.io/yaml"
)
const (
rcFilename = ".certmanager.yaml"
helpCmd = "help"
createAccountCmd = "createAccount"
updateAccountCmd = "updateAccount"
deleteAccountCmd = "deleteAccount"
listAccountsCmd = "listAccounts"
setGrantCmd = "setGrant"
deleteGrantCmd = "deleteGrant"
initDatabaseCmd = "initDatabase"
seedAccountCmd = "seedAccount"
)
func main() {
var err error
util := NewUtil()
err = util.Build()
if err != nil {
fmt.Printf("Build error: %v\n", err)
os.Exit(1)
}
err = util.Exec()
if err != nil {
fmt.Printf("Exec error: %v\n", err)
os.Exit(1)
}
os.Exit(0)
}
type Util struct {
subCmd string
cmdTimeout int64
conf *config.Config
lg *logic.Logic
db *maindb.Database
state descr.Server
sfile string
accessUsername string
accessPassword string
accountID int64
username string
password string
disable bool
newUsername string
newPassword string
operation string
quiet bool
}
func NewUtil() *Util {
var util Util
util.cmdTimeout = 120
return &util
}
func (util *Util) GetOpt() error {
var err error
exeName := filepath.Base(os.Args[0])
flag.Int64Var(&util.cmdTimeout, "timeout", util.cmdTimeout, "command execution timeout")
flag.StringVar(&util.accessUsername, "user", util.accessUsername, "access login")
flag.StringVar(&util.accessPassword, "pass", util.accessPassword, "access password")
flag.BoolVar(&util.quiet, "quiet", util.quiet, "don't print result")
help := func() {
fmt.Println("")
fmt.Printf("Usage: %s [option] command [command option]\n", exeName)
fmt.Printf("\n")
fmt.Printf(" %s, %s, %s, %s,\n",
createAccountCmd,
deleteAccountCmd,
listAccountsCmd,
updateAccountCmd)
fmt.Printf(" %s, %s\n",
setGrantCmd,
deleteGrantCmd)
fmt.Printf(" %s, %s\n",
initDatabaseCmd,
seedAccountCmd)
fmt.Printf("\n")
fmt.Printf("Global options:\n")
flag.PrintDefaults()
fmt.Printf("\n")
}
flag.Usage = help
flag.Parse()
args := flag.Args()
var subCmd string
var subArgs []string
if len(args) > 0 {
subCmd = args[0]
subArgs = args[1:]
}
util.subCmd = subCmd
switch subCmd {
case helpCmd:
help()
return errors.New("Unknown command")
case createAccountCmd:
flagSet := flag.NewFlagSet(createAccountCmd, flag.ExitOnError)
flagSet.StringVar(&util.username, "username", util.username, "user name")
flagSet.StringVar(&util.password, "password", util.password, "user password")
flagSet.Usage = func() {
fmt.Printf("\n")
fmt.Printf("Usage: %s [global options] %s [command options]\n", exeName, subCmd)
fmt.Printf("\n")
fmt.Printf("The command options: none\n")
flagSet.PrintDefaults()
fmt.Printf("\n")
}
flagSet.Parse(subArgs)
util.subCmd = subCmd
case deleteAccountCmd:
flagSet := flag.NewFlagSet(deleteAccountCmd, flag.ExitOnError)
flagSet.StringVar(&util.username, "username", util.username, "user name")
flagSet.Int64Var(&util.accountID, "accountId", util.accountID, "account ID")
flagSet.Usage = func() {
fmt.Printf("\n")
fmt.Printf("Usage: %s [global options] %s [command options]\n", exeName, subCmd)
fmt.Printf("\n")
fmt.Printf("The command options: none\n")
flagSet.PrintDefaults()
fmt.Printf("\n")
}
flagSet.Parse(subArgs)
util.subCmd = subCmd
case listAccountsCmd:
flagSet := flag.NewFlagSet(listAccountsCmd, flag.ExitOnError)
flagSet.Usage = func() {
fmt.Printf("\n")
fmt.Printf("Usage: %s [global options] %s [command options]\n", exeName, subCmd)
fmt.Printf("\n")
fmt.Printf("The command options: none\n")
flagSet.PrintDefaults()
fmt.Printf("\n")
}
flagSet.Parse(subArgs)
util.subCmd = subCmd
case updateAccountCmd:
flagSet := flag.NewFlagSet(updateAccountCmd, flag.ExitOnError)
flagSet.StringVar(&util.username, "username", util.username, "user name")
flagSet.Int64Var(&util.accountID, "accountId", util.accountID, "account ID")
flagSet.StringVar(&util.newUsername, "newUsername", util.newUsername, "new user name")
flagSet.StringVar(&util.newPassword, "newPassword", util.newPassword, "new user password")
flagSet.BoolVar(&util.disable, "disable", util.disable, "disable account")
flagSet.Usage = func() {
fmt.Printf("\n")
fmt.Printf("Usage: %s [global options] %s [command options]\n", exeName, subCmd)
fmt.Printf("\n")
fmt.Printf("The command options: none\n")
flagSet.PrintDefaults()
fmt.Printf("\n")
}
flagSet.Parse(subArgs)
util.subCmd = subCmd
case setGrantCmd:
flagSet := flag.NewFlagSet(setGrantCmd, flag.ExitOnError)
flagSet.StringVar(&util.username, "username", util.username, "user name")
flagSet.Int64Var(&util.accountID, "accountId", util.accountID, "account ID")
flagSet.StringVar(&util.operation, "operation", util.operation, "grant type")
flagSet.Usage = func() {
fmt.Printf("\n")
fmt.Printf("Usage: %s [global options] %s [command options]\n", exeName, subCmd)
fmt.Printf("\n")
fmt.Printf("The command options: none\n")
flagSet.PrintDefaults()
fmt.Printf("\n")
}
flagSet.Parse(subArgs)
util.subCmd = subCmd
case deleteGrantCmd:
flagSet := flag.NewFlagSet(deleteGrantCmd, flag.ExitOnError)
flagSet.StringVar(&util.username, "username", util.username, "user name")
flagSet.Int64Var(&util.accountID, "accountId", util.accountID, "account ID")
flagSet.StringVar(&util.operation, "operation", util.operation, "grant type")
flagSet.Usage = func() {
fmt.Printf("\n")
fmt.Printf("Usage: %s [global options] %s [command options]\n", exeName, subCmd)
fmt.Printf("\n")
fmt.Printf("The command options: none\n")
flagSet.PrintDefaults()
fmt.Printf("\n")
}
flagSet.Parse(subArgs)
util.subCmd = subCmd
case initDatabaseCmd:
flagSet := flag.NewFlagSet(initDatabaseCmd, flag.ExitOnError)
flagSet.Usage = func() {
fmt.Printf("\n")
fmt.Printf("Usage: %s [global options] %s [command options]\n", exeName, subCmd)
fmt.Printf("\n")
fmt.Printf("The command options: none\n")
flagSet.PrintDefaults()
fmt.Printf("\n")
}
flagSet.Parse(subArgs)
util.subCmd = subCmd
case seedAccountCmd:
flagSet := flag.NewFlagSet(seedAccountCmd, flag.ExitOnError)
flagSet.Usage = func() {
fmt.Printf("\n")
fmt.Printf("Usage: %s [global options] %s [command options]\n", exeName, subCmd)
fmt.Printf("\n")
fmt.Printf("The command options: none\n")
flagSet.PrintDefaults()
fmt.Printf("\n")
}
flagSet.Parse(subArgs)
util.subCmd = subCmd
default:
help()
return errors.New("Unknown command")
}
return err
}
func (util *Util) Build() error {
var err error
util.conf = config.NewConfig()
err = util.conf.ReadFile()
if err != nil {
return err
}
err = util.conf.ReadEnv()
if err != nil {
return err
}
util.sfile = filepath.Join(util.conf.DataDir, "certmanager.yaml")
db, err := maindb.NewDatabase(util.conf.DataDir)
if err != nil {
return err
}
err = db.OpenDatabase()
if err != nil {
return err
}
util.db = db
logicConfig := &logic.LogicConfig{
Database: util.db,
}
util.lg, err = logic.NewLogic(logicConfig)
if err != nil {
return err
}
return err
}
type Response struct {
Command string `json:"command" yaml:"command"`
Args []string `json:"args" yaml:"args"`
Error bool `json:"error" yaml:"error"`
Message string `json:"message,omitempty" yaml:"message,omitempty"`
Result any `json:"result,omitempty" yaml:"result,omitempty"`
}
func (util *Util) Exec() error {
var err error
err = util.GetOpt()
if err != nil {
return err
}
var timeout = time.Duration(util.cmdTimeout) * time.Second
ctx, close := context.WithTimeout(context.Background(), timeout)
defer close()
var res any
switch util.subCmd {
case initDatabaseCmd:
res, err = util.InitDatabase(ctx)
case seedAccountCmd:
res, err = util.SeedAccount(ctx)
default:
authOk, operID, localErr := util.lg.ValidateAcount(ctx, util.accessUsername, util.accessPassword)
if err != nil {
err = localErr
goto exit
}
if !authOk {
err = fmt.Errorf("Incorrect username or password")
goto exit
}
switch util.subCmd {
case createAccountCmd:
res, err = util.CreateAccount(ctx, operID)
case updateAccountCmd:
res, err = util.UpdateAccount(ctx, operID)
case listAccountsCmd:
res, err = util.ListAccounts(ctx, operID)
case deleteAccountCmd:
res, err = util.DeleteAccount(ctx, operID)
case setGrantCmd:
res, err = util.SetGrant(ctx, operID)
case deleteGrantCmd:
res, err = util.DeleteGrant(ctx, operID)
default:
err = errors.New("Unknown cli command")
}
}
exit:
var resp Response
resp.Command = util.subCmd
resp.Args = os.Args
if err != nil {
resp.Error = true
resp.Message = fmt.Sprintf("%v", err)
} else {
resp.Result = res
}
if !resp.Error && !util.quiet {
respBytes, _ := yaml.Marshal(resp)
fmt.Println(string(respBytes))
}
return err
}
type InitDatabaseRes struct{}
func (util *Util) InitDatabase(ctx context.Context) (InitDatabaseRes, error) {
res := InitDatabaseRes{}
// Initialize database
// Load state
err := util.LoadState()
if err != nil {
return res, err
}
if !util.state.DatabaseInitialized {
if util.db == nil {
err = fmt.Errorf("Nil db object")
return res, err
}
err := util.db.InitDatabase()
if err != nil {
return res, err
}
util.state.DatabaseInitialized = true
err = util.SaveState()
if err != nil {
return res, err
}
}
return res, err
}
type SeedAccountRes struct{}
func (util *Util) SeedAccount(ctx context.Context) (SeedAccountRes, error) {
// Seed accounts
res := SeedAccountRes{}
_, err := util.lg.SeedAccount(ctx)
if err != nil {
return res, err
}
return res, err
}
func (util *Util) LoadState() error {
var err error
_, err = os.Stat(util.sfile)
if os.IsNotExist(err) {
err = nil
return err
}
file, err := os.Open(util.sfile)
if err != nil {
return err
}
defer file.Close()
stateBytes, err := ioutil.ReadAll(file)
if err != nil {
return err
}
err = yaml.Unmarshal(stateBytes, &util.state)
if err != nil {
return err
}
return err
}
func (util *Util) SaveState() error {
var err error
file, err := os.OpenFile(util.sfile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0640)
if err != nil {
return err
}
defer file.Close()
util.state.UpdatedAt = time.Now().Format(time.RFC3339)
if util.state.CreatedAt == "" {
util.state.CreatedAt = util.state.UpdatedAt
}
stateBytes, err := yaml.Marshal(util.state)
if err != nil {
return err
}
_, err = file.Write(stateBytes)
if err != nil {
return err
}
return err
}
-23
View File
@@ -1,23 +0,0 @@
/*
* Copyright 2026 Oleg Borodin <onborodin@gmail.com>
*/
package grant
import (
"github.com/spf13/cobra"
)
func (util *Util) CreateGrant(cmd *cobra.Command, args []string) {
//util.createGrantParams.Filename = args[0]
res, err := util.createGrant(util.createGrantParams)
printResponse(res, err)
}
type createGrantParams struct{}
type createGrantResult struct{}
func (util *Util) createGrant(params createGrantParams) (createGrantResult, error) {
var err error
res := createGrantResult{}
return res, err
}
+26 -6
View File
@@ -4,20 +4,40 @@
package grant package grant
import ( import (
"context"
"mbase/pkg/mbctl"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
func (util *Util) DeleteGrant(cmd *cobra.Command, args []string) { func (util *Util) DeleteGrant(cmd *cobra.Command, args []string) {
//util.deleteGrantParams.Filename = args[0] util.deleteGrantParams.Username = args[0]
res, err := util.deleteGrant(util.deleteGrantParams) util.deleteGrantParams.Operation = args[1]
res, err := util.deleteGrant(&util.deleteGrantParams)
printResponse(res, err) printResponse(res, err)
} }
type deleteGrantParams struct{} type DeleteGrantParams struct {
type deleteGrantResult struct{} Username string
Operation string
}
type DeleteGrantResult struct {
GrantID string `json:"grantId"`
}
func (util *Util) deleteGrant(params deleteGrantParams) (deleteGrantResult, error) { func (util *Util) deleteGrant(params *DeleteGrantParams) (*DeleteGrantResult, error) {
var err error var err error
res := deleteGrantResult{} res := &DeleteGrantResult{}
ctx := context.Background()
operParams := &mbctl.SetGrantParams{
Username: params.Username,
Operation: params.Operation,
}
operRes, err := util.oper.SetGrant(ctx, util.operID, operParams)
if err != nil {
return res, err
}
res.GrantID = operRes.GrantID
return res, err return res, err
} }
+10 -10
View File
@@ -13,15 +13,15 @@ import (
) )
type Util struct { type Util struct {
oper *operator.Logic oper *operator.Operator
operID string operID string
subCmd *cobra.Command subCmd *cobra.Command
createGrantParams createGrantParams setGrantParams SetGrantParams
deleteGrantParams deleteGrantParams deleteGrantParams DeleteGrantParams
commonParams CommonParams commonParams CommonParams
} }
func NewUtil(oper *operator.Logic) *Util { func NewUtil(oper *operator.Operator) *Util {
return &Util{ return &Util{
oper: oper, oper: oper,
} }
@@ -56,17 +56,17 @@ func (util *Util) BuildCmds() *cobra.Command {
util.commonParams.Username = vi.GetString("user") util.commonParams.Username = vi.GetString("user")
util.commonParams.Password = vi.GetString("pass") util.commonParams.Password = vi.GetString("pass")
var createGrantCmd = &cobra.Command{ var setGrantCmd = &cobra.Command{
Use: "create name|id password", Use: "set name|id password",
Short: "Create grant", Short: "Set grant for account",
Args: cobra.ExactArgs(2), Args: cobra.ExactArgs(2),
Run: util.CreateGrant, Run: util.SetGrant,
} }
subCmd.AddCommand(createGrantCmd) subCmd.AddCommand(setGrantCmd)
var deleteGrantCmd = &cobra.Command{ var deleteGrantCmd = &cobra.Command{
Use: "delete name|id grant", Use: "delete name|id grant",
Short: "Delete grant", Short: "Delete grant for account",
Args: cobra.ExactArgs(1), Args: cobra.ExactArgs(1),
Run: util.DeleteGrant, Run: util.DeleteGrant,
} }
+43
View File
@@ -0,0 +1,43 @@
/*
* Copyright 2026 Oleg Borodin <onborodin@gmail.com>
*/
package grant
import (
"context"
"mbase/pkg/mbctl"
"github.com/spf13/cobra"
)
func (util *Util) SetGrant(cmd *cobra.Command, args []string) {
util.setGrantParams.Username = args[0]
util.setGrantParams.Operation = args[1]
res, err := util.setGrant(&util.setGrantParams)
printResponse(res, err)
}
type SetGrantParams struct {
Username string
Operation string
}
type SetGrantResult struct {
GrantID string `json:"grantId"`
}
func (util *Util) setGrant(params *SetGrantParams) (*SetGrantResult, error) {
var err error
res := &SetGrantResult{}
ctx := context.Background()
operParams := &mbctl.SetGrantParams{
Username: params.Username,
Operation: params.Operation,
}
operRes, err := util.oper.SetGrant(ctx, util.operID, operParams)
if err != nil {
return res, err
}
res.GrantID = operRes.GrantID
return res, err
}
+3 -3
View File
@@ -24,7 +24,7 @@ import (
type Util struct { type Util struct {
log *logger.Logger log *logger.Logger
oper *operator.Logic oper *operator.Operator
db *maindb.Database db *maindb.Database
state descr.Server state descr.Server
sfile string sfile string
@@ -84,10 +84,10 @@ func (util *Util) Build() error {
return err return err
} }
util.db = db util.db = db
logicConfig := &operator.LogicConfig{ operConfig := &operator.OperatorConfig{
Database: util.db, Database: util.db,
} }
util.oper, err = operator.NewLogic(logicConfig) util.oper, err = operator.NewOperator(operConfig)
if err != nil { if err != nil {
return err return err
} }