working commit

This commit is contained in:
2026-06-06 02:28:44 +02:00
parent 557aea269d
commit c96602e933
60 changed files with 2506 additions and 1273 deletions
@@ -6,7 +6,7 @@ import (
"mbase/pkg/mbctl"
)
func (util *Util) CreateAccount(ctx context.Context, operID int64) (*mbctl.CreateAccountResult, error) {
func (util *Util) CreateAccount(ctx context.Context, operID string) (*mbctl.CreateAccountResult, error) {
var err error
res := &mbctl.CreateAccountResult{}
@@ -21,7 +21,7 @@ func (util *Util) CreateAccount(ctx context.Context, operID int64) (*mbctl.Creat
return res, err
}
func (util *Util) DeleteAccount(ctx context.Context, operID int64) (*mbctl.DeleteAccountResult, error) {
func (util *Util) DeleteAccount(ctx context.Context, operID string) (*mbctl.DeleteAccountResult, error) {
var err error
res := &mbctl.DeleteAccountResult{}
params := &mbctl.DeleteAccountParams{
@@ -35,7 +35,7 @@ func (util *Util) DeleteAccount(ctx context.Context, operID int64) (*mbctl.Delet
return res, err
}
func (util *Util) ListAccounts(ctx context.Context, operID int64) (*mbctl.ListAccountsResult, error) {
func (util *Util) ListAccounts(ctx context.Context, operID string) (*mbctl.ListAccountsResult, error) {
var err error
res := &mbctl.ListAccountsResult{}
params := &mbctl.ListAccountsParams{}
@@ -46,7 +46,7 @@ func (util *Util) ListAccounts(ctx context.Context, operID int64) (*mbctl.ListAc
return res, err
}
func (util *Util) UpdateAccount(ctx context.Context, operID int64) (*mbctl.UpdateAccountResult, error) {
func (util *Util) UpdateAccount(ctx context.Context, operID string) (*mbctl.UpdateAccountResult, error) {
var err error
res := &mbctl.UpdateAccountResult{}
params := &mbctl.UpdateAccountParams{
@@ -6,7 +6,7 @@ import (
"mbase/pkg/mbctl"
)
func (util *Util) SetGrant(ctx context.Context, operID int64) (*mbctl.SetGrantResult, error) {
func (util *Util) SetGrant(ctx context.Context, operID string) (*mbctl.SetGrantResult, error) {
var err error
res := &mbctl.SetGrantResult{}
params := &mbctl.SetGrantParams{
@@ -24,7 +24,7 @@ func (util *Util) SetGrant(ctx context.Context, operID int64) (*mbctl.SetGrantRe
return res, err
}
func (util *Util) DeleteGrant(ctx context.Context, operID int64) (*mbctl.DeleteGrantResult, error) {
func (util *Util) DeleteGrant(ctx context.Context, operID string) (*mbctl.DeleteGrantResult, error) {
var err error
res := &mbctl.DeleteGrantResult{}
params := &mbctl.DeleteGrantParams{
+467
View File
@@ -0,0 +1,467 @@
/*
* 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
@@ -0,0 +1,23 @@
/*
* Copyright 2026 Oleg Borodin <onborodin@gmail.com>
*/
package account
import (
"github.com/spf13/cobra"
)
func (util *Util) CreateAccount(cmd *cobra.Command, args []string) {
//util.createAccountParams.Filename = args[0]
res, err := util.createAccount(util.createAccountParams)
printResponse(res, err)
}
type createAccountParams struct{}
type createAccountResult struct{}
func (util *Util) createAccount(params createAccountParams) (createAccountResult, error) {
var err error
res := createAccountResult{}
return res, err
}
+23
View File
@@ -0,0 +1,23 @@
/*
* Copyright 2026 Oleg Borodin <onborodin@gmail.com>
*/
package account
import (
"github.com/spf13/cobra"
)
func (util *Util) DeleteAccount(cmd *cobra.Command, args []string) {
//util.deleteAccountParams.Filename = args[0]
res, err := util.deleteAccount(util.deleteAccountParams)
printResponse(res, err)
}
type deleteAccountParams struct{}
type deleteAccountResult struct{}
func (util *Util) deleteAccount(params deleteAccountParams) (deleteAccountResult, error) {
var err error
res := deleteAccountResult{}
return res, err
}
+23
View File
@@ -0,0 +1,23 @@
/*
* Copyright 2026 Oleg Borodin <onborodin@gmail.com>
*/
package account
import (
"github.com/spf13/cobra"
)
func (util *Util) ListAccounts(cmd *cobra.Command, args []string) {
//util.listAccountsParams.Filename = args[0]
res, err := util.listAccounts(util.listAccountsParams)
printResponse(res, err)
}
type listAccountsParams struct{}
type listAccountsResult struct{}
func (util *Util) listAccounts(params listAccountsParams) (listAccountsResult, error) {
var err error
res := listAccountsResult{}
return res, err
}
+27
View File
@@ -0,0 +1,27 @@
/*
* Copyright 2026 Oleg Borodin <onborodin@gmail.com>
*/
package account
import (
"fmt"
"sigs.k8s.io/yaml"
)
func printResponse(res any, err error) {
type Response struct {
Error bool `json:"error" yaml:"error"`
Message string `json:"message,omitempty" yaml:"message,omitempty"`
Result any `json:"result,omitempty" yaml:"result,omitempty"`
}
resp := Response{}
if err != nil {
resp.Error = true
resp.Message = err.Error()
} else {
resp.Result = res
}
respBytes, _ := yaml.Marshal(resp)
fmt.Printf("---\n%s\n", string(respBytes))
}
+23
View File
@@ -0,0 +1,23 @@
/*
* Copyright 2026 Oleg Borodin <onborodin@gmail.com>
*/
package account
import (
"github.com/spf13/cobra"
)
func (util *Util) UpdateAccount(cmd *cobra.Command, args []string) {
//util.updateAccountParams.Filename = args[0]
res, err := util.updateAccount(util.updateAccountParams)
printResponse(res, err)
}
type updateAccountParams struct{}
type updateAccountResult struct{}
func (util *Util) updateAccount(params updateAccountParams) (updateAccountResult, error) {
var err error
res := updateAccountResult{}
return res, err
}
+68
View File
@@ -0,0 +1,68 @@
/*
* Copyright 2026 Oleg Borodin <onborodin@gmail.com>
*/
package account
import (
"github.com/spf13/cobra"
)
type Util struct {
rootCmd *cobra.Command
createAccountParams createAccountParams
listAccountsParams listAccountsParams
updateAccountParams updateAccountParams
deleteAccountParams deleteAccountParams
}
func NewUtil() *Util {
return &Util{}
}
func (util *Util) GetRooCmd() *cobra.Command {
return util.rootCmd
}
func (util *Util) BuildCmds() *cobra.Command {
rootCmd := &cobra.Command{
Use: "account",
Short: "\nAccount operations",
SilenceUsage: true,
}
rootCmd.CompletionOptions.DisableDefaultCmd = true
var createAccountCmd = &cobra.Command{
Use: "create name password ",
Short: "Create account",
Args: cobra.ExactArgs(2),
Run: util.CreateAccount,
}
rootCmd.AddCommand(createAccountCmd)
var listAccountsCmd = &cobra.Command{
Use: "list",
Short: "List accounts",
Run: util.ListAccounts,
}
rootCmd.AddCommand(listAccountsCmd)
var updateAccountsCmd = &cobra.Command{
Use: "update name|id",
Short: "Update account",
Args: cobra.ExactArgs(1),
Run: util.UpdateAccount,
}
rootCmd.AddCommand(updateAccountsCmd)
var deleteAccountCmd = &cobra.Command{
Use: "delete name|id",
Short: "Delete account",
Args: cobra.ExactArgs(1),
Run: util.DeleteAccount,
}
rootCmd.AddCommand(deleteAccountCmd)
util.rootCmd = rootCmd
return util.rootCmd
}
+63
View File
@@ -0,0 +1,63 @@
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
@@ -0,0 +1,40 @@
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
@@ -0,0 +1,467 @@
/*
* 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
@@ -0,0 +1,23 @@
/*
* Copyright 2026 Oleg Borodin <onborodin@gmail.com>
*/
package account
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
}
+23
View File
@@ -0,0 +1,23 @@
/*
* Copyright 2026 Oleg Borodin <onborodin@gmail.com>
*/
package account
import (
"github.com/spf13/cobra"
)
func (util *Util) DeleteGrant(cmd *cobra.Command, args []string) {
//util.deleteGrantParams.Filename = args[0]
res, err := util.deleteGrant(util.deleteGrantParams)
printResponse(res, err)
}
type deleteGrantParams struct{}
type deleteGrantResult struct{}
func (util *Util) deleteGrant(params deleteGrantParams) (deleteGrantResult, error) {
var err error
res := deleteGrantResult{}
return res, err
}
+27
View File
@@ -0,0 +1,27 @@
/*
* Copyright 2026 Oleg Borodin <onborodin@gmail.com>
*/
package account
import (
"fmt"
"sigs.k8s.io/yaml"
)
func printResponse(res any, err error) {
type Response struct {
Error bool `json:"error" yaml:"error"`
Message string `json:"message,omitempty" yaml:"message,omitempty"`
Result any `json:"result,omitempty" yaml:"result,omitempty"`
}
resp := Response{}
if err != nil {
resp.Error = true
resp.Message = err.Error()
} else {
resp.Result = res
}
respBytes, _ := yaml.Marshal(resp)
fmt.Printf("---\n%s\n", string(respBytes))
}
+51
View File
@@ -0,0 +1,51 @@
/*
* Copyright 2026 Oleg Borodin <onborodin@gmail.com>
*/
package grant
import (
"github.com/spf13/cobra"
)
type Util struct {
rootCmd *cobra.Command
createGrantParams createGrantParams
deleteGrantParams deleteGrantParams
}
func NewUtil() *Util {
return &Util{}
}
func (util *Util) GetRooCmd() *cobra.Command {
return util.rootCmd
}
func (util *Util) BuildCmds() *cobra.Command {
rootCmd := &cobra.Command{
Use: "grant",
Short: "\nGrant operations",
SilenceUsage: true,
}
rootCmd.CompletionOptions.DisableDefaultCmd = true
var createGrantCmd = &cobra.Command{
Use: "create name|id password",
Short: "Create grant",
Args: cobra.ExactArgs(2),
Run: util.CreateGrant,
}
rootCmd.AddCommand(createGrantCmd)
var deleteGrantCmd = &cobra.Command{
Use: "delete name|id grant",
Short: "Delete grant",
Args: cobra.ExactArgs(1),
Run: util.DeleteGrant,
}
rootCmd.AddCommand(deleteGrantCmd)
util.rootCmd = rootCmd
return util.rootCmd
}
+2 -448
View File
@@ -1,42 +1,10 @@
/*
* Copyright 2024 Oleg Borodin <borodin@unix7.org>
* Copyright 2026 Oleg Borodin <onborodin@gmail.com>
*/
package main
import (
"context"
"errors"
"flag"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"time"
"mbase/app/config"
"mbase/app/maindb"
"mbase/app/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() {
@@ -44,424 +12,10 @@ func main() {
util := NewUtil()
err = util.Build()
if err != nil {
fmt.Printf("Build error: %v\n", err)
os.Exit(1)
}
err = util.Exec()
err = util.Exec(os.Args[1:])
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
}
+49
View File
@@ -0,0 +1,49 @@
/*
* Copyright 2026 Oleg Borodin <onborodin@gmail.com>
*/
package main
import (
"os"
"path/filepath"
"mbase/cmd/mbaseadmin/account"
"github.com/spf13/cobra"
)
type Util struct {
rootCmd *cobra.Command
}
func NewUtil() *Util {
return &Util{}
}
func (util *Util) GetRooCmd() *cobra.Command {
return util.rootCmd
}
func (util *Util) Build() error {
var err error
execName := filepath.Base(os.Args[0])
rootCmd := &cobra.Command{
Use: execName,
Short: "\nAccount operations",
SilenceUsage: true,
}
rootCmd.CompletionOptions.DisableDefaultCmd = true
accountUtil := account.NewUtil()
rootCmd.AddCommand(accountUtil.BuildCmds())
util.rootCmd = rootCmd
return err
}
func (util *Util) Exec(args []string) error {
var err error
util.rootCmd.SetArgs(args)
err = util.rootCmd.Execute()
return err
}
+23
View File
@@ -0,0 +1,23 @@
/*
* Copyright 2026 Oleg Borodin <onborodin@gmail.com>
*/
package account
import (
"github.com/spf13/cobra"
)
func (util *Util) CreateAccount(cmd *cobra.Command, args []string) {
//util.createAccountParams.Filename = args[0]
res, err := util.createAccount(util.createAccountParams)
printResponse(res, err)
}
type createAccountParams struct{}
type createAccountResult struct{}
func (util *Util) createAccount(params createAccountParams) (createAccountResult, error) {
var err error
res := createAccountResult{}
return res, err
}
+23
View File
@@ -0,0 +1,23 @@
/*
* Copyright 2026 Oleg Borodin <onborodin@gmail.com>
*/
package account
import (
"github.com/spf13/cobra"
)
func (util *Util) DeleteAccount(cmd *cobra.Command, args []string) {
//util.deleteAccountParams.Filename = args[0]
res, err := util.deleteAccount(util.deleteAccountParams)
printResponse(res, err)
}
type deleteAccountParams struct{}
type deleteAccountResult struct{}
func (util *Util) deleteAccount(params deleteAccountParams) (deleteAccountResult, error) {
var err error
res := deleteAccountResult{}
return res, err
}
+23
View File
@@ -0,0 +1,23 @@
/*
* Copyright 2026 Oleg Borodin <onborodin@gmail.com>
*/
package account
import (
"github.com/spf13/cobra"
)
func (util *Util) ListAccounts(cmd *cobra.Command, args []string) {
//util.listAccountsParams.Filename = args[0]
res, err := util.listAccounts(util.listAccountsParams)
printResponse(res, err)
}
type listAccountsParams struct{}
type listAccountsResult struct{}
func (util *Util) listAccounts(params listAccountsParams) (listAccountsResult, error) {
var err error
res := listAccountsResult{}
return res, err
}
+27
View File
@@ -0,0 +1,27 @@
/*
* Copyright 2026 Oleg Borodin <onborodin@gmail.com>
*/
package account
import (
"fmt"
"sigs.k8s.io/yaml"
)
func printResponse(res any, err error) {
type Response struct {
Error bool `json:"error" yaml:"error"`
Message string `json:"message,omitempty" yaml:"message,omitempty"`
Result any `json:"result,omitempty" yaml:"result,omitempty"`
}
resp := Response{}
if err != nil {
resp.Error = true
resp.Message = err.Error()
} else {
resp.Result = res
}
respBytes, _ := yaml.Marshal(resp)
fmt.Printf("---\n%s\n", string(respBytes))
}
+23
View File
@@ -0,0 +1,23 @@
/*
* Copyright 2026 Oleg Borodin <onborodin@gmail.com>
*/
package account
import (
"github.com/spf13/cobra"
)
func (util *Util) UpdateAccount(cmd *cobra.Command, args []string) {
//util.updateAccountParams.Filename = args[0]
res, err := util.updateAccount(util.updateAccountParams)
printResponse(res, err)
}
type updateAccountParams struct{}
type updateAccountResult struct{}
func (util *Util) updateAccount(params updateAccountParams) (updateAccountResult, error) {
var err error
res := updateAccountResult{}
return res, err
}
+68
View File
@@ -0,0 +1,68 @@
/*
* Copyright 2026 Oleg Borodin <onborodin@gmail.com>
*/
package account
import (
"github.com/spf13/cobra"
)
type Util struct {
rootCmd *cobra.Command
createAccountParams createAccountParams
listAccountsParams listAccountsParams
updateAccountParams updateAccountParams
deleteAccountParams deleteAccountParams
}
func NewUtil() *Util {
return &Util{}
}
func (util *Util) GetRooCmd() *cobra.Command {
return util.rootCmd
}
func (util *Util) BuildCmds() *cobra.Command {
rootCmd := &cobra.Command{
Use: "account",
Short: "\nAccount operations",
SilenceUsage: true,
}
rootCmd.CompletionOptions.DisableDefaultCmd = true
var createAccountCmd = &cobra.Command{
Use: "create name password ",
Short: "Create account",
Args: cobra.ExactArgs(2),
Run: util.CreateAccount,
}
rootCmd.AddCommand(createAccountCmd)
var listAccountsCmd = &cobra.Command{
Use: "list",
Short: "List accounts",
Run: util.ListAccounts,
}
rootCmd.AddCommand(listAccountsCmd)
var updateAccountsCmd = &cobra.Command{
Use: "update name|id",
Short: "Update account",
Args: cobra.ExactArgs(1),
Run: util.UpdateAccount,
}
rootCmd.AddCommand(updateAccountsCmd)
var deleteAccountCmd = &cobra.Command{
Use: "delete name|id",
Short: "Delete account",
Args: cobra.ExactArgs(1),
Run: util.DeleteAccount,
}
rootCmd.AddCommand(deleteAccountCmd)
util.rootCmd = rootCmd
return util.rootCmd
}
+398
View File
@@ -0,0 +1,398 @@
/*
* Copyright 2024 Oleg Borodin <borodin@unix7.org>
*/
package main
import (
"context"
"errors"
"flag"
"fmt"
"os"
"os/user"
"path/filepath"
"time"
"mbase/pkg/client"
"mbase/pkg/mbctl"
"sigs.k8s.io/yaml"
)
const (
defaultHostname = "localhost"
rcFilename = ".certmanager.yaml"
defaultPort uint32 = client.DefaultPort
getHelloCmd = "getHello"
helpCmd = "help"
createAccountCmd = "createAccount"
updateAccountCmd = "updateAccount"
deleteAccountCmd = "deleteAccount"
listAccountsCmd = "listAccounts"
setGrantCmd = "setGrant"
deleteGrantCmd = "deleteGrant"
getDumpCmd = "getDump"
restoreDumpCmd = "restoreDump"
)
func main() {
var err error
util := NewUtil()
err = util.Exec()
if err != nil {
os.Exit(1)
}
os.Exit(0)
}
type Util struct {
subCmd string
cmdTimeout int64
access client.Access
cont *mbctl.ControlClient
caFilenamesList string
certFilename string
keyFilename string
issuerOrganizationName string
issuerOrganizationalUnitName string
issuerCommonName string
issuerID int64
issuerName string
signerID int64
signerName string
serviceOrganizationName string
serviceOrganizationalUnitName string
serviceCommonName string
hostnameList string
ipAdressesList string
serviceID int64
serviceName string
encodingKey string
accountID int64
username string
password string
disable bool
newUsername string
newPassword string
operation string
filename string
deleteAllRecords bool
}
func NewUtil() *Util {
var util Util
util.cmdTimeout = 120
util.access = client.Access{
Hostname: defaultHostname,
Port: defaultPort,
Username: "certmanager",
Password: "certmanager",
}
return &util
}
func (util *Util) GetOpt() error {
var err error
homeDir := os.Getenv("HOME")
if homeDir == "" {
currUsr, err := user.Current()
if err == nil {
homeDir = currUsr.HomeDir
}
}
if homeDir != "" {
confPath := filepath.Join(homeDir, rcFilename)
confData, err := os.ReadFile(confPath)
if err == nil && len(confData) > 0 {
yaml.Unmarshal(confData, &util.access)
}
}
exeName := filepath.Base(os.Args[0])
servicePort := int64(defaultPort)
flag.Int64Var(&util.cmdTimeout, "timeout", util.cmdTimeout, "command execution timeout")
flag.StringVar(&util.access.Hostname, "host", util.access.Hostname, "service hostname")
flag.Int64Var(&servicePort, "port", servicePort, "service port")
flag.StringVar(&util.access.Username, "user", util.access.Username, "access login")
flag.StringVar(&util.access.Password, "pass", util.access.Password, "access password")
util.access.Port = uint32(servicePort)
help := func() {
fmt.Println("")
fmt.Printf("Usage: %s [option] command [command option]\n", exeName)
fmt.Printf("\n")
fmt.Printf("Command list: help, %s\n", getHelloCmd)
fmt.Printf(" %s, %s, %s, %s,\n",
createAccountCmd,
deleteAccountCmd,
listAccountsCmd,
updateAccountCmd)
fmt.Printf(" %s, %s\n",
setGrantCmd,
deleteGrantCmd)
fmt.Printf(" %s, %s\n",
getDumpCmd,
restoreDumpCmd)
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:]
}
switch subCmd {
case helpCmd:
help()
return errors.New("Unknown command")
case getHelloCmd:
flagSet := flag.NewFlagSet(getHelloCmd, 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
flagSet.Parse(subArgs)
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 getDumpCmd:
flagSet := flag.NewFlagSet(getDumpCmd, flag.ExitOnError)
flagSet.StringVar(&util.filename, "file", util.filename, "dump file name")
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 restoreDumpCmd:
flagSet := flag.NewFlagSet(restoreDumpCmd, flag.ExitOnError)
flagSet.StringVar(&util.filename, "file", util.filename, "dump file name")
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
}
type Response struct {
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 getHelloCmd:
res, err = util.GetHello(ctx)
case createAccountCmd:
res, err = util.CreateAccount(ctx)
case updateAccountCmd:
res, err = util.UpdateAccount(ctx)
case listAccountsCmd:
res, err = util.ListAccounts(ctx)
case deleteAccountCmd:
res, err = util.DeleteAccount(ctx)
case setGrantCmd:
res, err = util.SetGrant(ctx)
case deleteGrantCmd:
res, err = util.DeleteGrant(ctx)
case getDumpCmd:
res, err = util.GetDump(ctx)
case restoreDumpCmd:
res, err = util.RestoreDump(ctx)
default:
err = errors.New("Unknown cli command")
}
var resp Response
if err != nil {
resp.Error = true
resp.Message = fmt.Sprintf("%v", err)
} else {
resp.Result = res
}
respBytes, _ := yaml.Marshal(resp)
fmt.Println(string(respBytes))
return err
}
func (util *Util) GetHello(ctx context.Context) (*mbctl.GetHelloResult, error) {
var err error
res := &mbctl.GetHelloResult{}
grpcConn, cont, err := client.NewClient(&util.access)
if err != nil {
return res, err
}
defer grpcConn.Close()
params := &mbctl.GetHelloParams{}
res, err = cont.GetHello(ctx, params)
if err != nil {
return res, err
}
return res, err
}
+23
View File
@@ -0,0 +1,23 @@
/*
* Copyright 2026 Oleg Borodin <onborodin@gmail.com>
*/
package account
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
}
+23
View File
@@ -0,0 +1,23 @@
/*
* Copyright 2026 Oleg Borodin <onborodin@gmail.com>
*/
package account
import (
"github.com/spf13/cobra"
)
func (util *Util) DeleteGrant(cmd *cobra.Command, args []string) {
//util.deleteGrantParams.Filename = args[0]
res, err := util.deleteGrant(util.deleteGrantParams)
printResponse(res, err)
}
type deleteGrantParams struct{}
type deleteGrantResult struct{}
func (util *Util) deleteGrant(params deleteGrantParams) (deleteGrantResult, error) {
var err error
res := deleteGrantResult{}
return res, err
}
+27
View File
@@ -0,0 +1,27 @@
/*
* Copyright 2026 Oleg Borodin <onborodin@gmail.com>
*/
package account
import (
"fmt"
"sigs.k8s.io/yaml"
)
func printResponse(res any, err error) {
type Response struct {
Error bool `json:"error" yaml:"error"`
Message string `json:"message,omitempty" yaml:"message,omitempty"`
Result any `json:"result,omitempty" yaml:"result,omitempty"`
}
resp := Response{}
if err != nil {
resp.Error = true
resp.Message = err.Error()
} else {
resp.Result = res
}
respBytes, _ := yaml.Marshal(resp)
fmt.Printf("---\n%s\n", string(respBytes))
}
+51
View File
@@ -0,0 +1,51 @@
/*
* Copyright 2026 Oleg Borodin <onborodin@gmail.com>
*/
package grant
import (
"github.com/spf13/cobra"
)
type Util struct {
rootCmd *cobra.Command
createGrantParams createGrantParams
deleteGrantParams deleteGrantParams
}
func NewUtil() *Util {
return &Util{}
}
func (util *Util) GetRooCmd() *cobra.Command {
return util.rootCmd
}
func (util *Util) BuildCmds() *cobra.Command {
rootCmd := &cobra.Command{
Use: "grant",
Short: "\nGrant operations",
SilenceUsage: true,
}
rootCmd.CompletionOptions.DisableDefaultCmd = true
var createGrantCmd = &cobra.Command{
Use: "create name|id password",
Short: "Create grant",
Args: cobra.ExactArgs(2),
Run: util.CreateGrant,
}
rootCmd.AddCommand(createGrantCmd)
var deleteGrantCmd = &cobra.Command{
Use: "delete name|id grant",
Short: "Delete grant",
Args: cobra.ExactArgs(1),
Run: util.DeleteGrant,
}
rootCmd.AddCommand(deleteGrantCmd)
util.rootCmd = rootCmd
return util.rootCmd
}
+4 -381
View File
@@ -1,398 +1,21 @@
/*
* Copyright 2024 Oleg Borodin <borodin@unix7.org>
* Copyright 2026 Oleg Borodin <onborodin@gmail.com>
*/
package main
import (
"context"
"errors"
"flag"
"fmt"
"os"
"os/user"
"path/filepath"
"time"
"mbase/pkg/client"
"mbase/pkg/mbctl"
"sigs.k8s.io/yaml"
)
const (
defaultHostname = "localhost"
rcFilename = ".certmanager.yaml"
defaultPort uint32 = client.DefaultPort
getHelloCmd = "getHello"
helpCmd = "help"
createAccountCmd = "createAccount"
updateAccountCmd = "updateAccount"
deleteAccountCmd = "deleteAccount"
listAccountsCmd = "listAccounts"
setGrantCmd = "setGrant"
deleteGrantCmd = "deleteGrant"
getDumpCmd = "getDump"
restoreDumpCmd = "restoreDump"
)
func main() {
var err error
util := NewUtil()
err = util.Exec()
err = util.Build()
if err != nil {
os.Exit(1)
}
os.Exit(0)
}
type Util struct {
subCmd string
cmdTimeout int64
access client.Access
cont *mbctl.ControlClient
caFilenamesList string
certFilename string
keyFilename string
issuerOrganizationName string
issuerOrganizationalUnitName string
issuerCommonName string
issuerID int64
issuerName string
signerID int64
signerName string
serviceOrganizationName string
serviceOrganizationalUnitName string
serviceCommonName string
hostnameList string
ipAdressesList string
serviceID int64
serviceName string
encodingKey string
accountID int64
username string
password string
disable bool
newUsername string
newPassword string
operation string
filename string
deleteAllRecords bool
}
func NewUtil() *Util {
var util Util
util.cmdTimeout = 120
util.access = client.Access{
Hostname: defaultHostname,
Port: defaultPort,
Username: "certmanager",
Password: "certmanager",
}
return &util
}
func (util *Util) GetOpt() error {
var err error
homeDir := os.Getenv("HOME")
if homeDir == "" {
currUsr, err := user.Current()
if err == nil {
homeDir = currUsr.HomeDir
}
}
if homeDir != "" {
confPath := filepath.Join(homeDir, rcFilename)
confData, err := os.ReadFile(confPath)
if err == nil && len(confData) > 0 {
yaml.Unmarshal(confData, &util.access)
}
}
exeName := filepath.Base(os.Args[0])
servicePort := int64(defaultPort)
flag.Int64Var(&util.cmdTimeout, "timeout", util.cmdTimeout, "command execution timeout")
flag.StringVar(&util.access.Hostname, "host", util.access.Hostname, "service hostname")
flag.Int64Var(&servicePort, "port", servicePort, "service port")
flag.StringVar(&util.access.Username, "user", util.access.Username, "access login")
flag.StringVar(&util.access.Password, "pass", util.access.Password, "access password")
util.access.Port = uint32(servicePort)
help := func() {
fmt.Println("")
fmt.Printf("Usage: %s [option] command [command option]\n", exeName)
fmt.Printf("\n")
fmt.Printf("Command list: help, %s\n", getHelloCmd)
fmt.Printf(" %s, %s, %s, %s,\n",
createAccountCmd,
deleteAccountCmd,
listAccountsCmd,
updateAccountCmd)
fmt.Printf(" %s, %s\n",
setGrantCmd,
deleteGrantCmd)
fmt.Printf(" %s, %s\n",
getDumpCmd,
restoreDumpCmd)
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:]
}
switch subCmd {
case helpCmd:
help()
return errors.New("Unknown command")
case getHelloCmd:
flagSet := flag.NewFlagSet(getHelloCmd, 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
flagSet.Parse(subArgs)
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 getDumpCmd:
flagSet := flag.NewFlagSet(getDumpCmd, flag.ExitOnError)
flagSet.StringVar(&util.filename, "file", util.filename, "dump file name")
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 restoreDumpCmd:
flagSet := flag.NewFlagSet(restoreDumpCmd, flag.ExitOnError)
flagSet.StringVar(&util.filename, "file", util.filename, "dump file name")
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
}
type Response struct {
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()
err = util.Exec(os.Args[1:])
if err != nil {
return err
os.Exit(1)
}
var timeout = time.Duration(util.cmdTimeout) * time.Second
ctx, close := context.WithTimeout(context.Background(), timeout)
defer close()
var res any
switch util.subCmd {
case getHelloCmd:
res, err = util.GetHello(ctx)
case createAccountCmd:
res, err = util.CreateAccount(ctx)
case updateAccountCmd:
res, err = util.UpdateAccount(ctx)
case listAccountsCmd:
res, err = util.ListAccounts(ctx)
case deleteAccountCmd:
res, err = util.DeleteAccount(ctx)
case setGrantCmd:
res, err = util.SetGrant(ctx)
case deleteGrantCmd:
res, err = util.DeleteGrant(ctx)
case getDumpCmd:
res, err = util.GetDump(ctx)
case restoreDumpCmd:
res, err = util.RestoreDump(ctx)
default:
err = errors.New("Unknown cli command")
}
var resp Response
if err != nil {
resp.Error = true
resp.Message = fmt.Sprintf("%v", err)
} else {
resp.Result = res
}
respBytes, _ := yaml.Marshal(resp)
fmt.Println(string(respBytes))
return err
}
func (util *Util) GetHello(ctx context.Context) (*mbctl.GetHelloResult, error) {
var err error
res := &mbctl.GetHelloResult{}
grpcConn, cont, err := client.NewClient(&util.access)
if err != nil {
return res, err
}
defer grpcConn.Close()
params := &mbctl.GetHelloParams{}
res, err = cont.GetHello(ctx, params)
if err != nil {
return res, err
}
return res, err
}
+49
View File
@@ -0,0 +1,49 @@
/*
* Copyright 2026 Oleg Borodin <onborodin@gmail.com>
*/
package main
import (
"os"
"path/filepath"
"mbase/cmd/mbaseadmin/account"
"github.com/spf13/cobra"
)
type Util struct {
rootCmd *cobra.Command
}
func NewUtil() *Util {
return &Util{}
}
func (util *Util) GetRooCmd() *cobra.Command {
return util.rootCmd
}
func (util *Util) Build() error {
var err error
execName := filepath.Base(os.Args[0])
rootCmd := &cobra.Command{
Use: execName,
Short: "\nAccount operations",
SilenceUsage: true,
}
rootCmd.CompletionOptions.DisableDefaultCmd = true
accountUtil := account.NewUtil()
rootCmd.AddCommand(accountUtil.BuildCmds())
util.rootCmd = rootCmd
return err
}
func (util *Util) Exec(args []string) error {
var err error
util.rootCmd.SetArgs(args)
err = util.rootCmd.Execute()
return err
}
+83
View File
@@ -0,0 +1,83 @@
/*
* Copyright 2026 Oleg Borodin <onborodin@gmail.com>
*/
package main
import (
"context"
"os"
"mbase/app/config"
"mbase/app/maindb"
"mbase/pkg/descr"
"mbase/pkg/auxtool"
"github.com/spf13/cobra"
"go.yaml.in/yaml/v4"
)
func (util *Util) DumpDatabase(cmd *cobra.Command, args []string) {
util.dumpDatabaseParams.Filename = args[0]
res, err := util.dumpDatabase(util.dumpDatabaseParams)
printResponse(res, err)
}
type dumpDatabaseParams struct {
Filename string
}
type dumpDatabaseResult struct{}
func (util *Util) dumpDatabase(params dumpDatabaseParams) (dumpDatabaseResult, error) {
var err error
res := dumpDatabaseResult{}
ctx := context.Background()
conf := config.NewConfig()
err = conf.ReadFile()
if err != nil {
return res, err
}
err = conf.ReadEnv()
if err != nil {
return res, err
}
db, err := maindb.NewDatabase(conf.DataDir)
if err != nil {
return res, err
}
err = db.OpenDatabase()
if err != nil {
return res, err
}
file := os.Stdout
if params.Filename != "-" {
file, err = os.OpenFile(params.Filename, os.O_CREATE|os.O_WRONLY, 0640)
if err != nil {
return res, err
}
defer file.Close()
}
listAccounts, err := db.CompletedListAccounts(ctx)
if err != nil {
return res, err
}
listGrants, err := db.ListGrants(ctx)
if err != nil {
return res, err
}
dump := descr.Dump{
Timestamp: auxtool.TimeNow(),
Accounts: listAccounts,
Grants: listGrants,
}
dumpBytes, err := yaml.Marshal(dump)
if err != nil {
return res, err
}
_, err = file.Write(dumpBytes)
if err != nil {
return res, err
}
return res, err
}
+96
View File
@@ -0,0 +1,96 @@
/*
* Copyright 2026 Oleg Borodin <onborodin@gmail.com>
*/
package main
import (
"bytes"
"context"
"io"
"os"
"mbase/app/config"
"mbase/app/maindb"
"mbase/pkg/descr"
"mbase/pkg/logger"
"github.com/spf13/cobra"
"go.yaml.in/yaml/v4"
)
func (util *Util) RestoreDatabase(cmd *cobra.Command, args []string) {
util.restoreDatabaseParams.Filename = args[0]
res, err := util.restoreDatabase(util.restoreDatabaseParams)
printResponse(res, err)
}
type restoreDatabaseParams struct {
Filename string
DeleteAllRecords bool
}
type restoreDatabaseResult struct{}
func (util *Util) restoreDatabase(params restoreDatabaseParams) (restoreDatabaseResult, error) {
var err error
res := restoreDatabaseResult{}
ctx := context.Background()
log := logger.NewLogger("restore")
conf := config.NewConfig()
err = conf.ReadFile()
if err != nil {
return res, err
}
err = conf.ReadEnv()
if err != nil {
return res, err
}
db, err := maindb.NewDatabase(conf.DataDir)
if err != nil {
return res, err
}
err = db.OpenDatabase()
if err != nil {
return res, err
}
file := os.Stdin
if params.Filename != "-" {
file, err = os.Open(params.Filename)
if err != nil {
return res, err
}
defer file.Close()
}
buffer := bytes.NewBuffer(nil)
_, err = io.Copy(buffer, file)
if err != nil {
return res, err
}
dump := descr.Dump{}
err = yaml.Unmarshal(buffer.Bytes(), &dump)
if err != nil {
return res, err
}
if params.DeleteAllRecords {
err = db.CleanDatabase(ctx)
if err != nil {
return res, err
}
}
for _, account := range dump.Accounts {
log.Infof("Insert account %s", account.Username)
err = db.InsertAccount(ctx, &account)
if err != nil {
log.Errorf("Insert account error: %v", err)
}
}
for _, grant := range dump.Grants {
log.Infof("Insert grant %s for account %d", grant.Operation, grant.AccountID)
err = db.InsertGrant(ctx, &grant)
if err != nil {
log.Errorf("Insert account error: %v", err)
}
}
return res, err
}
-151
View File
@@ -4,20 +4,10 @@
package main
import (
"bytes"
"context"
"io"
"os"
"path/filepath"
"mbase/app/config"
"mbase/app/maindb"
"mbase/app/descr"
"mbase/pkg/auxtool"
"mbase/pkg/logger"
"github.com/spf13/cobra"
"go.yaml.in/yaml/v4"
)
type Util struct {
@@ -72,144 +62,3 @@ func (util *Util) Exec(args []string) error {
return err
}
func (util *Util) DumpDatabase(cmd *cobra.Command, args []string) {
util.dumpDatabaseParams.Filename = args[0]
res, err := util.dumpDatabase(util.dumpDatabaseParams)
printResponse(res, err)
}
type dumpDatabaseParams struct {
Filename string
}
type dumpDatabaseResult struct{}
func (util *Util) dumpDatabase(params dumpDatabaseParams) (dumpDatabaseResult, error) {
var err error
res := dumpDatabaseResult{}
ctx := context.Background()
conf := config.NewConfig()
err = conf.ReadFile()
if err != nil {
return res, err
}
err = conf.ReadEnv()
if err != nil {
return res, err
}
db, err := maindb.NewDatabase(conf.DataDir)
if err != nil {
return res, err
}
err = db.OpenDatabase()
if err != nil {
return res, err
}
file := os.Stdout
if params.Filename != "-" {
file, err = os.OpenFile(params.Filename, os.O_CREATE|os.O_WRONLY, 0640)
if err != nil {
return res, err
}
defer file.Close()
}
listAccounts, err := db.CompletedListAccounts(ctx)
if err != nil {
return res, err
}
listGrants, err := db.ListGrants(ctx)
if err != nil {
return res, err
}
dump := descr.Dump{
Timestamp: auxtool.TimeNow(),
Accounts: listAccounts,
Grants: listGrants,
}
dumpBytes, err := yaml.Marshal(dump)
if err != nil {
return res, err
}
_, err = file.Write(dumpBytes)
if err != nil {
return res, err
}
return res, err
}
func (util *Util) RestoreDatabase(cmd *cobra.Command, args []string) {
util.restoreDatabaseParams.Filename = args[0]
res, err := util.restoreDatabase(util.restoreDatabaseParams)
printResponse(res, err)
}
type restoreDatabaseParams struct {
Filename string
DeleteAllRecords bool
}
type restoreDatabaseResult struct{}
func (util *Util) restoreDatabase(params restoreDatabaseParams) (restoreDatabaseResult, error) {
var err error
res := restoreDatabaseResult{}
ctx := context.Background()
log := logger.NewLogger("restore")
conf := config.NewConfig()
err = conf.ReadFile()
if err != nil {
return res, err
}
err = conf.ReadEnv()
if err != nil {
return res, err
}
db, err := maindb.NewDatabase(conf.DataDir)
if err != nil {
return res, err
}
err = db.OpenDatabase()
if err != nil {
return res, err
}
file := os.Stdin
if params.Filename != "-" {
file, err = os.Open(params.Filename)
if err != nil {
return res, err
}
defer file.Close()
}
buffer := bytes.NewBuffer(nil)
_, err = io.Copy(buffer, file)
if err != nil {
return res, err
}
dump := descr.Dump{}
err = yaml.Unmarshal(buffer.Bytes(), &dump)
if err != nil {
return res, err
}
if params.DeleteAllRecords {
err = db.CleanDatabase(ctx)
if err != nil {
return res, err
}
}
for _, account := range dump.Accounts {
log.Infof("Insert account %s", account.Username)
err = db.InsertAccount(ctx, &account)
if err != nil {
log.Errorf("Insert account error: %v", err)
}
}
for _, grant := range dump.Grants {
log.Infof("Insert grant %s for account %d", grant.Operation, grant.AccountID)
err = db.InsertGrant(ctx, &grant)
if err != nil {
log.Errorf("Insert account error: %v", err)
}
}
return res, err
}