kopia lustrzana https://github.com/bugout-dev/moonstream
Fix nodebalancer CLI and removed autogen accesses
rodzic
2afc38f730
commit
8bf1915b68
|
@ -2,519 +2,275 @@ package main
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
bugout "github.com/bugout-dev/bugout-go/pkg"
|
||||
"github.com/google/uuid"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var (
|
||||
// Storing CLI definitions at server startup
|
||||
stateCLI StateCLI
|
||||
var CommonCommands = []*cli.Command{
|
||||
{
|
||||
Name: "access",
|
||||
Usage: "Operations with access IDs as Brood resource",
|
||||
Flags: []cli.Flag{},
|
||||
Subcommands: []*cli.Command{
|
||||
{
|
||||
Name: "add",
|
||||
Usage: "Add new user's access ID",
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "access-token",
|
||||
Aliases: []string{"t"},
|
||||
Usage: "Authorized user access token with granted privileges to create resources in Moonstream Bugout application and sharing read permissions to nodebalancer application user",
|
||||
Required: true,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "access-id",
|
||||
Aliases: []string{"a"},
|
||||
Usage: "UUID for access identification",
|
||||
Required: true,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "user-id",
|
||||
Aliases: []string{"u"},
|
||||
Usage: "Bugout user ID",
|
||||
Required: true,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "name",
|
||||
Aliases: []string{"n"},
|
||||
Usage: "Name of the user or application to work with nodebalancer",
|
||||
Required: true,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "description",
|
||||
Aliases: []string{"d"},
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "blockchain-access",
|
||||
Aliases: []string{"b"},
|
||||
Usage: "Specify this flag to grant direct access to blockchain nodes",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "extended-methods",
|
||||
Aliases: []string{"e"},
|
||||
Usage: "Specify this flag to grant execution availability to not whitelisted methods",
|
||||
},
|
||||
&cli.UintFlag{
|
||||
Name: "period-duration",
|
||||
Aliases: []string{"p"},
|
||||
Usage: "Access period duration in seconds",
|
||||
Value: 2592000,
|
||||
},
|
||||
&cli.UintFlag{
|
||||
Name: "max-calls-per-period",
|
||||
Aliases: []string{"m"},
|
||||
Usage: "Max available calls to node during the period",
|
||||
Value: 10000,
|
||||
},
|
||||
},
|
||||
Before: func(c *cli.Context) error {
|
||||
periodDurationFlag := c.Uint("period-duration")
|
||||
|
||||
bugoutClient bugout.BugoutClient
|
||||
if periodDurationFlag < 3600 {
|
||||
return fmt.Errorf("time for --period-duration should be greater then 1 hour")
|
||||
}
|
||||
|
||||
DEFAULT_ACCESS_NAME = ""
|
||||
DEFAULT_ACCESS_DESCRIPTION = ""
|
||||
DEFAULT_BLOCKCHAIN_ACCESS = true
|
||||
DEFAULT_EXTENDED_METHODS = true
|
||||
DEFAULT_PERIOD_DURATION = int64(86400) // 1 day
|
||||
DEFAULT_MAX_CALLS_PER_PERIOD = int64(10000)
|
||||
)
|
||||
return nil
|
||||
},
|
||||
Action: func(c *cli.Context) error {
|
||||
var clientErr error
|
||||
bugoutClient, clientErr = CreateBugoutClient()
|
||||
if clientErr != nil {
|
||||
return fmt.Errorf("an error occurred during Bugout client creation, err: %v", clientErr)
|
||||
}
|
||||
|
||||
// Command Line Interface state
|
||||
type StateCLI struct {
|
||||
addAccessCmd *flag.FlagSet
|
||||
updateAccessCmd *flag.FlagSet
|
||||
generateConfigCmd *flag.FlagSet
|
||||
deleteAccessCmd *flag.FlagSet
|
||||
serverCmd *flag.FlagSet
|
||||
usersCmd *flag.FlagSet
|
||||
versionCmd *flag.FlagSet
|
||||
newAccess, newErr := AddNewAccess(c.String("access-id"), c.String("user-id"), c.String("name"), c.String("description"), c.Bool("blockchain-access"), c.Bool("extended-methods"), c.Uint("period-duration"), c.Uint("max-calls-per-period"), c.String("access-token"))
|
||||
if newErr != nil {
|
||||
return fmt.Errorf("failed to add new access, err: %v", newErr)
|
||||
}
|
||||
|
||||
// Common flags
|
||||
configPathFlag string
|
||||
helpFlag bool
|
||||
_, shareErr := ShareAccess(newAccess.ResourceID, NB_CONTROLLER_USER_ID, "user", DEFAULT_AUTOGENERATED_USER_PERMISSIONS, c.String("access-token"))
|
||||
if shareErr != nil {
|
||||
return fmt.Errorf("failed to share access to resource ID %s with nodebalancer application user, err: %v", newAccess.ResourceID, shareErr)
|
||||
}
|
||||
|
||||
// Add/update user access flags
|
||||
userIDFlag string
|
||||
accessIDFlag string
|
||||
accessNameFlag string
|
||||
accessDescriptionFlag string
|
||||
newAccessJson, err := json.Marshal(newAccess)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to encode resource %s data interface to json, err: %v", newAccess.ResourceID, err)
|
||||
}
|
||||
fmt.Println(string(newAccessJson))
|
||||
|
||||
blockchainAccessFlag bool
|
||||
extendedMethodsFlag bool
|
||||
|
||||
PeriodDurationFlag int64
|
||||
MaxCallsPerPeriodFlag int64
|
||||
|
||||
// Update user access flags
|
||||
PeriodStartTsFlag int64
|
||||
CallsPerPeriodFlag int64
|
||||
|
||||
// Server flags
|
||||
listeningAddrFlag string
|
||||
listeningPortFlag string
|
||||
enableHealthCheckFlag bool
|
||||
enableDebugFlag bool
|
||||
|
||||
// Users list flags
|
||||
limitFlag int
|
||||
offsetFlag int
|
||||
}
|
||||
|
||||
func (s *StateCLI) usage() {
|
||||
fmt.Printf(`usage: nodebalancer [-h] {%[1]s,%[2]s,%[3]s,%[4]s,%[5]s,%[6]s} ...
|
||||
|
||||
Moonstream node balancer CLI
|
||||
optional arguments:
|
||||
-h, --help show this help message and exit
|
||||
|
||||
subcommands:
|
||||
{%[1]s,%[2]s,%[3]s,%[4]s,%[5]s,%[6]s,%[7]s}
|
||||
`, s.addAccessCmd.Name(), s.updateAccessCmd.Name(), s.generateConfigCmd.Name(), s.deleteAccessCmd.Name(), s.serverCmd.Name(), s.usersCmd.Name(), s.versionCmd.Name())
|
||||
}
|
||||
|
||||
// Check if required flags are set
|
||||
func (s *StateCLI) checkRequirements() {
|
||||
if s.helpFlag {
|
||||
switch {
|
||||
case s.addAccessCmd.Parsed():
|
||||
fmt.Printf("Add new user access resource\n\n")
|
||||
s.addAccessCmd.PrintDefaults()
|
||||
os.Exit(0)
|
||||
case s.updateAccessCmd.Parsed():
|
||||
fmt.Printf("Update user access resource\n\n")
|
||||
s.updateAccessCmd.PrintDefaults()
|
||||
os.Exit(0)
|
||||
case s.generateConfigCmd.Parsed():
|
||||
fmt.Printf("Generate new configuration\n\n")
|
||||
s.generateConfigCmd.PrintDefaults()
|
||||
os.Exit(0)
|
||||
case s.deleteAccessCmd.Parsed():
|
||||
fmt.Printf("Delete user access resource\n\n")
|
||||
s.deleteAccessCmd.PrintDefaults()
|
||||
os.Exit(0)
|
||||
case s.serverCmd.Parsed():
|
||||
fmt.Printf("Start nodebalancer server\n\n")
|
||||
s.serverCmd.PrintDefaults()
|
||||
os.Exit(0)
|
||||
case s.usersCmd.Parsed():
|
||||
fmt.Printf("List user access tokens\n\n")
|
||||
s.usersCmd.PrintDefaults()
|
||||
os.Exit(0)
|
||||
case s.versionCmd.Parsed():
|
||||
fmt.Printf("Show version\n\n")
|
||||
s.versionCmd.PrintDefaults()
|
||||
os.Exit(0)
|
||||
default:
|
||||
s.usage()
|
||||
os.Exit(0)
|
||||
}
|
||||
}
|
||||
|
||||
switch {
|
||||
case s.addAccessCmd.Parsed():
|
||||
if s.userIDFlag == "" {
|
||||
fmt.Printf("User ID should be specified\n\n")
|
||||
s.addAccessCmd.PrintDefaults()
|
||||
os.Exit(1)
|
||||
}
|
||||
if s.accessIDFlag == "" {
|
||||
s.accessIDFlag = uuid.New().String()
|
||||
}
|
||||
if s.accessNameFlag == "" {
|
||||
fmt.Printf("Access name should be specified\n\n")
|
||||
s.addAccessCmd.PrintDefaults()
|
||||
os.Exit(1)
|
||||
}
|
||||
case s.updateAccessCmd.Parsed():
|
||||
if s.userIDFlag == "" && s.accessIDFlag == "" {
|
||||
fmt.Printf("User ID or access ID should be specified\n\n")
|
||||
s.updateAccessCmd.PrintDefaults()
|
||||
os.Exit(1)
|
||||
}
|
||||
case s.deleteAccessCmd.Parsed():
|
||||
if s.userIDFlag == "" && s.accessIDFlag == "" {
|
||||
fmt.Printf("User or access ID flag should be specified\n\n")
|
||||
s.deleteAccessCmd.PrintDefaults()
|
||||
os.Exit(1)
|
||||
}
|
||||
case s.usersCmd.Parsed():
|
||||
if s.offsetFlag < 0 || s.limitFlag < 0 {
|
||||
fmt.Printf("Offset and limit flags should be greater then zero\n\n")
|
||||
s.usersCmd.PrintDefaults()
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
// Load configuration
|
||||
config, err := GetConfigPath(s.configPathFlag)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if !config.ConfigExists {
|
||||
if err := GenerateDefaultConfig(config); err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
} else {
|
||||
log.Printf("Loaded configuration from %s", config.ConfigPath)
|
||||
}
|
||||
s.configPathFlag = config.ConfigPath
|
||||
}
|
||||
|
||||
func (s *StateCLI) populateCLI() {
|
||||
// Subcommands setup
|
||||
s.addAccessCmd = flag.NewFlagSet("add-access", flag.ExitOnError)
|
||||
s.updateAccessCmd = flag.NewFlagSet("update-access", flag.ExitOnError)
|
||||
s.generateConfigCmd = flag.NewFlagSet("generate-config", flag.ExitOnError)
|
||||
s.deleteAccessCmd = flag.NewFlagSet("delete-access", flag.ExitOnError)
|
||||
s.serverCmd = flag.NewFlagSet("server", flag.ExitOnError)
|
||||
s.usersCmd = flag.NewFlagSet("users", flag.ExitOnError)
|
||||
s.versionCmd = flag.NewFlagSet("version", flag.ExitOnError)
|
||||
|
||||
// Common flag pointers
|
||||
for _, fs := range []*flag.FlagSet{s.addAccessCmd, s.updateAccessCmd, s.generateConfigCmd, s.deleteAccessCmd, s.serverCmd, s.usersCmd, s.versionCmd} {
|
||||
fs.BoolVar(&s.helpFlag, "help", false, "Show help message")
|
||||
fs.StringVar(&s.configPathFlag, "config", "", "Path to configuration file (default: ~/.nodebalancer/config.json)")
|
||||
}
|
||||
|
||||
// Add, delete and list user access subcommand flag pointers
|
||||
for _, fs := range []*flag.FlagSet{s.addAccessCmd, s.updateAccessCmd, s.deleteAccessCmd, s.usersCmd} {
|
||||
fs.StringVar(&s.userIDFlag, "user-id", "", "Bugout user ID")
|
||||
fs.StringVar(&s.accessIDFlag, "access-id", "", "UUID for access identification")
|
||||
}
|
||||
|
||||
// Add/update user access subcommand flag pointers
|
||||
for _, fs := range []*flag.FlagSet{s.addAccessCmd, s.updateAccessCmd} {
|
||||
fs.StringVar(&s.accessNameFlag, "name", DEFAULT_ACCESS_NAME, fmt.Sprintf("Name of access (default: %s)", DEFAULT_ACCESS_NAME))
|
||||
fs.StringVar(&s.accessDescriptionFlag, "description", DEFAULT_ACCESS_DESCRIPTION, fmt.Sprintf("Description of access (default: %s)", DEFAULT_ACCESS_DESCRIPTION))
|
||||
fs.BoolVar(&s.blockchainAccessFlag, "blockchain-access", DEFAULT_BLOCKCHAIN_ACCESS, fmt.Sprintf("Specify this flag to grant direct access to blockchain nodes (default: %t)", DEFAULT_BLOCKCHAIN_ACCESS))
|
||||
fs.BoolVar(&s.extendedMethodsFlag, "extended-methods", DEFAULT_EXTENDED_METHODS, fmt.Sprintf("Specify this flag to grant execution availability to not whitelisted methods (default: %t)", DEFAULT_EXTENDED_METHODS))
|
||||
fs.Int64Var(&s.PeriodDurationFlag, "period-duration", DEFAULT_PERIOD_DURATION, fmt.Sprintf("Access period duration in seconds (default: %d)", DEFAULT_PERIOD_DURATION))
|
||||
fs.Int64Var(&s.MaxCallsPerPeriodFlag, "max-calls-per-period", DEFAULT_MAX_CALLS_PER_PERIOD, fmt.Sprintf("Max available calls to node during the period (default: %d)", DEFAULT_MAX_CALLS_PER_PERIOD))
|
||||
}
|
||||
|
||||
s.updateAccessCmd.Int64Var(&s.PeriodStartTsFlag, "period-start-ts", 0, "When period starts in unix timestamp format (default: now)")
|
||||
s.updateAccessCmd.Int64Var(&s.CallsPerPeriodFlag, "calls-per-period", 0, "Current number of calls to node during the period (default: 0)")
|
||||
|
||||
// Server subcommand flag pointers
|
||||
s.serverCmd.StringVar(&s.listeningAddrFlag, "host", "127.0.0.1", "Server listening address")
|
||||
s.serverCmd.StringVar(&s.listeningPortFlag, "port", "8544", "Server listening port")
|
||||
s.serverCmd.BoolVar(&s.enableHealthCheckFlag, "healthcheck", false, "To enable healthcheck set healthcheck flag")
|
||||
s.serverCmd.BoolVar(&s.enableDebugFlag, "debug", false, "To enable debug mode with extended log set debug flag")
|
||||
|
||||
// Users list subcommand flag pointers
|
||||
s.usersCmd.IntVar(&s.limitFlag, "limit", 10, "Output result limit")
|
||||
s.usersCmd.IntVar(&s.offsetFlag, "offset", 0, "Result output offset")
|
||||
}
|
||||
|
||||
func cli() {
|
||||
stateCLI.populateCLI()
|
||||
if len(os.Args) < 2 {
|
||||
stateCLI.usage()
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Init bugout client
|
||||
bc, err := CreateBugoutClient()
|
||||
if err != nil {
|
||||
log.Printf("An error occurred during Bugout client creation: %v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
bugoutClient = bc
|
||||
|
||||
// Parse subcommands and appropriate FlagSet
|
||||
switch os.Args[1] {
|
||||
case "generate-config":
|
||||
stateCLI.generateConfigCmd.Parse(os.Args[2:])
|
||||
stateCLI.checkRequirements()
|
||||
|
||||
case "add-access":
|
||||
stateCLI.addAccessCmd.Parse(os.Args[2:])
|
||||
stateCLI.checkRequirements()
|
||||
|
||||
proposedClientResourceData := ClientResourceData{
|
||||
UserID: stateCLI.userIDFlag,
|
||||
AccessID: stateCLI.accessIDFlag,
|
||||
Name: stateCLI.accessNameFlag,
|
||||
Description: stateCLI.accessDescriptionFlag,
|
||||
BlockchainAccess: stateCLI.blockchainAccessFlag,
|
||||
ExtendedMethods: stateCLI.extendedMethodsFlag,
|
||||
|
||||
PeriodDuration: stateCLI.PeriodDurationFlag,
|
||||
PeriodStartTs: time.Now().Unix(),
|
||||
MaxCallsPerPeriod: stateCLI.MaxCallsPerPeriodFlag,
|
||||
CallsPerPeriod: 0,
|
||||
|
||||
Type: BUGOUT_RESOURCE_TYPE_NODEBALANCER_ACCESS,
|
||||
}
|
||||
_, err := bugoutClient.Brood.FindUser(
|
||||
NB_CONTROLLER_TOKEN,
|
||||
map[string]string{
|
||||
"user_id": proposedClientResourceData.UserID,
|
||||
"application_id": MOONSTREAM_APPLICATION_ID,
|
||||
return nil
|
||||
},
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Printf("User does not exists, err: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
resource, err := bugoutClient.Brood.CreateResource(NB_CONTROLLER_TOKEN, MOONSTREAM_APPLICATION_ID, proposedClientResourceData)
|
||||
if err != nil {
|
||||
fmt.Printf("Unable to create user access, err: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
resourceData, err := json.Marshal(resource.ResourceData)
|
||||
if err != nil {
|
||||
fmt.Printf("Unable to encode resource %s data interface to json, err: %v\n", resource.Id, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
var newUserAccess ClientAccess
|
||||
err = json.Unmarshal(resourceData, &newUserAccess)
|
||||
if err != nil {
|
||||
fmt.Printf("Unable to decode resource %s data json to structure, err: %v\n", resource.Id, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
newUserAccess.ResourceID = resource.Id
|
||||
userAccessJson, err := json.Marshal(newUserAccess)
|
||||
if err != nil {
|
||||
fmt.Printf("Unable to encode resource %s data interface to json, err: %v", resource.Id, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Println(string(userAccessJson))
|
||||
{
|
||||
Name: "update",
|
||||
Usage: "Update user's access ID",
|
||||
Flags: []cli.Flag{},
|
||||
Before: func(c *cli.Context) error { return nil },
|
||||
Action: func(c *cli.Context) error { return nil },
|
||||
},
|
||||
{
|
||||
Name: "delete",
|
||||
Usage: "Delete user's access ID",
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "access-token",
|
||||
Aliases: []string{"t"},
|
||||
Usage: "Authorized user access token with granted privileges to delete resources in Moonstream Bugout application",
|
||||
Required: true,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "access-id",
|
||||
Aliases: []string{"a"},
|
||||
Usage: "UUID for access identification",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "user-id",
|
||||
Aliases: []string{"u"},
|
||||
Usage: "Filter by user_id",
|
||||
},
|
||||
},
|
||||
Before: func(c *cli.Context) error {
|
||||
accessIdFlag := c.String("access-id")
|
||||
userIdFlag := c.String("user-id")
|
||||
|
||||
case "update-access":
|
||||
stateCLI.updateAccessCmd.Parse(os.Args[2:])
|
||||
stateCLI.checkRequirements()
|
||||
if accessIdFlag == "" && userIdFlag == "" {
|
||||
return fmt.Errorf("at least one of --access-id or --user-id should be set")
|
||||
}
|
||||
|
||||
queryParameters := make(map[string]string)
|
||||
if stateCLI.userIDFlag != "" {
|
||||
queryParameters["user_id"] = stateCLI.userIDFlag
|
||||
}
|
||||
if stateCLI.accessIDFlag != "" {
|
||||
queryParameters["access_id"] = stateCLI.accessIDFlag
|
||||
}
|
||||
resources, err := bugoutClient.Brood.GetResources(
|
||||
NB_CONTROLLER_TOKEN,
|
||||
MOONSTREAM_APPLICATION_ID,
|
||||
queryParameters,
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Printf("Unable to get Bugout resources, err: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
return nil
|
||||
},
|
||||
Action: func(c *cli.Context) error {
|
||||
var clientErr error
|
||||
bugoutClient, clientErr = CreateBugoutClient()
|
||||
if clientErr != nil {
|
||||
return fmt.Errorf("an error occurred during Bugout client creation: %v", clientErr)
|
||||
}
|
||||
|
||||
resourcesLen := len(resources.Resources)
|
||||
if resourcesLen == 0 {
|
||||
fmt.Printf("There are no access resource with provided user-id %s or access-id %s\n", stateCLI.userIDFlag, stateCLI.accessIDFlag)
|
||||
os.Exit(1)
|
||||
}
|
||||
if resourcesLen > 1 {
|
||||
fmt.Printf("There are several %d access resources with provided user-id %s or access-id %s\n", resourcesLen, stateCLI.userIDFlag, stateCLI.accessIDFlag)
|
||||
os.Exit(1)
|
||||
}
|
||||
resources, getResErr := GetAccesses(c.String("access-id"), c.String("user-id"), c.String("access-token"))
|
||||
if getResErr != nil {
|
||||
return fmt.Errorf("unable to get Bugout resources, err: %v", getResErr)
|
||||
}
|
||||
|
||||
resource := resources.Resources[0]
|
||||
resourceData, err := json.Marshal(resource.ResourceData)
|
||||
if err != nil {
|
||||
fmt.Printf("Unable to encode resource %s data interface to json, err: %v\n", resource.Id, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
if len(resources.Resources) == 0 {
|
||||
fmt.Println("[]")
|
||||
return nil
|
||||
}
|
||||
|
||||
var currentClientAccess ClientAccess
|
||||
currentClientAccess.ResourceID = resource.Id
|
||||
err = json.Unmarshal(resourceData, ¤tClientAccess.ClientResourceData)
|
||||
if err != nil {
|
||||
fmt.Printf("Unable to decode resource %s data json to structure, err: %v\n", resource.Id, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
var clientAccesses []ClientAccess
|
||||
for _, resource := range resources.Resources {
|
||||
clientAccess, parseErr := ParseResourceDataToClientAccess(resource)
|
||||
if parseErr != nil {
|
||||
fmt.Printf("Unable to parse resource data, err: %v", parseErr)
|
||||
continue
|
||||
}
|
||||
|
||||
// TODO(kompotkot): Since we are using bool flags I moved with ugly solution.
|
||||
// Let's find better one when have free time or will re-write flag Set.
|
||||
update := make(map[string]interface{})
|
||||
if stateCLI.accessNameFlag != currentClientAccess.ClientResourceData.Name && stateCLI.accessNameFlag != DEFAULT_ACCESS_NAME {
|
||||
update["name"] = stateCLI.accessNameFlag
|
||||
}
|
||||
if stateCLI.accessDescriptionFlag != currentClientAccess.ClientResourceData.Description && stateCLI.accessDescriptionFlag != DEFAULT_ACCESS_DESCRIPTION {
|
||||
update["description"] = stateCLI.accessDescriptionFlag
|
||||
}
|
||||
if stateCLI.blockchainAccessFlag != currentClientAccess.ClientResourceData.BlockchainAccess && stateCLI.blockchainAccessFlag != DEFAULT_BLOCKCHAIN_ACCESS {
|
||||
update["blockchain_access"] = stateCLI.blockchainAccessFlag
|
||||
}
|
||||
if stateCLI.extendedMethodsFlag != currentClientAccess.ClientResourceData.ExtendedMethods && stateCLI.extendedMethodsFlag != DEFAULT_EXTENDED_METHODS {
|
||||
update["extended_methods"] = stateCLI.extendedMethodsFlag
|
||||
}
|
||||
if stateCLI.PeriodDurationFlag != currentClientAccess.ClientResourceData.PeriodDuration && stateCLI.PeriodDurationFlag != DEFAULT_PERIOD_DURATION {
|
||||
update["period_duration"] = stateCLI.PeriodDurationFlag
|
||||
}
|
||||
if stateCLI.MaxCallsPerPeriodFlag != currentClientAccess.ClientResourceData.MaxCallsPerPeriod && stateCLI.MaxCallsPerPeriodFlag != DEFAULT_MAX_CALLS_PER_PERIOD {
|
||||
update["max_calls_per_period"] = stateCLI.MaxCallsPerPeriodFlag
|
||||
}
|
||||
if stateCLI.PeriodStartTsFlag != currentClientAccess.ClientResourceData.PeriodStartTs && stateCLI.PeriodStartTsFlag != 0 {
|
||||
update["period_start_ts"] = stateCLI.PeriodStartTsFlag
|
||||
}
|
||||
if stateCLI.CallsPerPeriodFlag != currentClientAccess.ClientResourceData.CallsPerPeriod && stateCLI.CallsPerPeriodFlag != 0 {
|
||||
update["calls_per_period"] = stateCLI.CallsPerPeriodFlag
|
||||
}
|
||||
clientAccesses = append(clientAccesses, *clientAccess)
|
||||
}
|
||||
|
||||
updatedResource, err := bugoutClient.Brood.UpdateResource(
|
||||
NB_CONTROLLER_TOKEN,
|
||||
resource.Id,
|
||||
update,
|
||||
[]string{},
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Printf("Unable to update Bugout resource, err: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
for _, access := range clientAccesses {
|
||||
fmt.Printf("Deleting resource ID %s with name %s in 3 seconds..\n", access.ResourceID, access.ClientResourceData.Name)
|
||||
time.Sleep(3 * time.Second)
|
||||
|
||||
updatedResourceData, err := json.Marshal(updatedResource.ResourceData)
|
||||
if err != nil {
|
||||
fmt.Printf("Unable to encode resource %s data interface to json, err: %v\n", resource.Id, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
var updatedUserAccess ClientAccess
|
||||
err = json.Unmarshal(updatedResourceData, &updatedUserAccess)
|
||||
if err != nil {
|
||||
fmt.Printf("Unable to decode resource %s data json to structure, err: %v\n", resource.Id, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
updatedUserAccess.ResourceID = updatedResource.Id
|
||||
userAccessJson, err := json.Marshal(updatedUserAccess)
|
||||
if err != nil {
|
||||
fmt.Printf("Unable to marshal user access struct, err: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Println(string(userAccessJson))
|
||||
_, delErr := DeleteAccess(access.ResourceID, c.String("access-token"))
|
||||
if delErr != nil {
|
||||
fmt.Printf("Failed to delete resource with ID %s err: %v\n", access.ResourceID, delErr)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
case "delete-access":
|
||||
stateCLI.deleteAccessCmd.Parse(os.Args[2:])
|
||||
stateCLI.checkRequirements()
|
||||
return nil
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "list",
|
||||
Usage: "List all user access IDs",
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "access-token",
|
||||
Aliases: []string{"t"},
|
||||
Usage: "Authorized user access token with granted privileges to get resources in Moonstream Bugout application",
|
||||
Required: true,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "access-id",
|
||||
Aliases: []string{"a"},
|
||||
Usage: "Filter by access_id",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "user-id",
|
||||
Aliases: []string{"u"},
|
||||
Usage: "Filter by user_id",
|
||||
},
|
||||
},
|
||||
Action: func(c *cli.Context) error {
|
||||
var clientErr error
|
||||
bugoutClient, clientErr = CreateBugoutClient()
|
||||
if clientErr != nil {
|
||||
return fmt.Errorf("an error occurred during Bugout client creation: %v", clientErr)
|
||||
}
|
||||
|
||||
queryParameters := make(map[string]string)
|
||||
if stateCLI.userIDFlag != "" {
|
||||
queryParameters["user_id"] = stateCLI.userIDFlag
|
||||
}
|
||||
if stateCLI.accessIDFlag != "" {
|
||||
queryParameters["access_id"] = stateCLI.accessIDFlag
|
||||
}
|
||||
resources, err := bugoutClient.Brood.GetResources(
|
||||
NB_CONTROLLER_TOKEN,
|
||||
MOONSTREAM_APPLICATION_ID,
|
||||
queryParameters,
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Printf("Unable to get Bugout resources, err: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
resources, getResErr := GetAccesses(c.String("access-id"), c.String("user-id"), c.String("access-token"))
|
||||
if getResErr != nil {
|
||||
return fmt.Errorf("unable to get Bugout resources, err: %v", getResErr)
|
||||
}
|
||||
|
||||
var userAccesses []ClientAccess
|
||||
for _, resource := range resources.Resources {
|
||||
deletedResource, err := bugoutClient.Brood.DeleteResource(NB_CONTROLLER_TOKEN, resource.Id)
|
||||
if err != nil {
|
||||
fmt.Printf("Unable to delete resource %s, err: %v\n", resource.Id, err)
|
||||
continue
|
||||
}
|
||||
deletedResourceData, err := json.Marshal(deletedResource.ResourceData)
|
||||
if err != nil {
|
||||
fmt.Printf("Unable to encode resource %s data interface to json, err: %v\n", resource.Id, err)
|
||||
continue
|
||||
}
|
||||
var deletedUserAccess ClientAccess
|
||||
err = json.Unmarshal(deletedResourceData, &deletedUserAccess)
|
||||
if err != nil {
|
||||
fmt.Printf("Unable to decode resource %s data json to structure, err: %v\n", resource.Id, err)
|
||||
continue
|
||||
}
|
||||
deletedUserAccess.ResourceID = deletedResource.Id
|
||||
userAccesses = append(userAccesses, deletedUserAccess)
|
||||
}
|
||||
var clientAccesses []ClientAccess
|
||||
for _, resource := range resources.Resources {
|
||||
clientAccess, parseErr := ParseResourceDataToClientAccess(resource)
|
||||
if parseErr != nil {
|
||||
fmt.Printf("Unable to parse resource data, err: %v", parseErr)
|
||||
continue
|
||||
}
|
||||
|
||||
userAccessesJson, err := json.Marshal(userAccesses)
|
||||
if err != nil {
|
||||
fmt.Printf("Unable to marshal user access struct, err: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Println(string(userAccessesJson))
|
||||
clientAccesses = append(clientAccesses, *clientAccess)
|
||||
}
|
||||
|
||||
case "server":
|
||||
stateCLI.serverCmd.Parse(os.Args[2:])
|
||||
stateCLI.checkRequirements()
|
||||
userAccessesJson, marErr := json.Marshal(clientAccesses)
|
||||
if marErr != nil {
|
||||
return fmt.Errorf("unable to marshal user accesses struct, err: %v", marErr)
|
||||
}
|
||||
fmt.Println(string(userAccessesJson))
|
||||
|
||||
CheckEnvVarSet()
|
||||
return nil
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "configure",
|
||||
Usage: "Generate nodebalancer configuration",
|
||||
Action: func(cCtx *cli.Context) error {
|
||||
|
||||
Server()
|
||||
return nil
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "server",
|
||||
Usage: "Start nodebalancer server",
|
||||
Action: func(cCtx *cli.Context) error {
|
||||
|
||||
case "users":
|
||||
stateCLI.usersCmd.Parse(os.Args[2:])
|
||||
stateCLI.checkRequirements()
|
||||
return nil
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "version",
|
||||
Usage: "Shows nodebalancer package version",
|
||||
Action: func(cCtx *cli.Context) error {
|
||||
fmt.Println(NB_VERSION)
|
||||
return nil
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
queryParameters := make(map[string]string)
|
||||
if stateCLI.userIDFlag != "" {
|
||||
queryParameters["user_id"] = stateCLI.userIDFlag
|
||||
}
|
||||
if stateCLI.accessIDFlag != "" {
|
||||
queryParameters["access_id"] = stateCLI.accessIDFlag
|
||||
}
|
||||
resources, err := bugoutClient.Brood.GetResources(
|
||||
NB_CONTROLLER_TOKEN,
|
||||
MOONSTREAM_APPLICATION_ID,
|
||||
queryParameters,
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Printf("Unable to get Bugout resources, err: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
var clientAccesses []ClientAccess
|
||||
|
||||
offset := stateCLI.offsetFlag
|
||||
if stateCLI.offsetFlag > len(resources.Resources) {
|
||||
offset = len(resources.Resources)
|
||||
}
|
||||
limit := stateCLI.offsetFlag + stateCLI.limitFlag
|
||||
if limit > len(resources.Resources) {
|
||||
limit = len(resources.Resources[offset:]) + offset
|
||||
}
|
||||
|
||||
for _, resource := range resources.Resources[offset:limit] {
|
||||
resourceData, err := json.Marshal(resource.ResourceData)
|
||||
if err != nil {
|
||||
fmt.Printf("Unable to encode resource %s data interface to json, err: %v\n", resource.Id, err)
|
||||
continue
|
||||
}
|
||||
var clientAccess ClientAccess
|
||||
clientAccess.ResourceID = resource.Id
|
||||
err = json.Unmarshal(resourceData, &clientAccess.ClientResourceData)
|
||||
if err != nil {
|
||||
fmt.Printf("Unable to decode resource %s data json to structure, err: %v\n", resource.Id, err)
|
||||
continue
|
||||
}
|
||||
clientAccesses = append(clientAccesses, clientAccess)
|
||||
}
|
||||
userAccessesJson, err := json.Marshal(clientAccesses)
|
||||
if err != nil {
|
||||
fmt.Printf("Unable to marshal user accesses struct, err: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Println(string(userAccessesJson))
|
||||
|
||||
case "version":
|
||||
stateCLI.versionCmd.Parse(os.Args[2:])
|
||||
stateCLI.checkRequirements()
|
||||
|
||||
fmt.Printf("v%s\n", NB_VERSION)
|
||||
|
||||
default:
|
||||
stateCLI.usage()
|
||||
os.Exit(1)
|
||||
func NodebalancerAppCli() *cli.App {
|
||||
return &cli.App{
|
||||
Name: "nodebalancer",
|
||||
Version: fmt.Sprintf("v%s", NB_VERSION),
|
||||
Usage: "Web3 node balancer",
|
||||
EnableBashCompletion: true,
|
||||
Commands: CommonCommands,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,517 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
var (
|
||||
// Storing CLI definitions at server startup
|
||||
stateCLI StateCLI
|
||||
|
||||
DEFAULT_ACCESS_NAME = ""
|
||||
DEFAULT_ACCESS_DESCRIPTION = ""
|
||||
DEFAULT_BLOCKCHAIN_ACCESS = true
|
||||
DEFAULT_EXTENDED_METHODS = true
|
||||
DEFAULT_PERIOD_DURATION = int64(86400) // 1 day
|
||||
DEFAULT_MAX_CALLS_PER_PERIOD = int64(10000)
|
||||
)
|
||||
|
||||
// Command Line Interface state
|
||||
type StateCLI struct {
|
||||
addAccessCmd *flag.FlagSet
|
||||
updateAccessCmd *flag.FlagSet
|
||||
generateConfigCmd *flag.FlagSet
|
||||
deleteAccessCmd *flag.FlagSet
|
||||
serverCmd *flag.FlagSet
|
||||
usersCmd *flag.FlagSet
|
||||
versionCmd *flag.FlagSet
|
||||
|
||||
// Common flags
|
||||
configPathFlag string
|
||||
helpFlag bool
|
||||
|
||||
// Add/update user access flags
|
||||
userIDFlag string
|
||||
accessIDFlag string
|
||||
accessNameFlag string
|
||||
accessDescriptionFlag string
|
||||
|
||||
blockchainAccessFlag bool
|
||||
extendedMethodsFlag bool
|
||||
|
||||
PeriodDurationFlag int64
|
||||
MaxCallsPerPeriodFlag int64
|
||||
|
||||
// Update user access flags
|
||||
PeriodStartTsFlag int64
|
||||
CallsPerPeriodFlag int64
|
||||
|
||||
// Server flags
|
||||
listeningAddrFlag string
|
||||
listeningPortFlag string
|
||||
enableHealthCheckFlag bool
|
||||
enableDebugFlag bool
|
||||
|
||||
// Users list flags
|
||||
limitFlag int
|
||||
offsetFlag int
|
||||
}
|
||||
|
||||
func (s *StateCLI) usage() {
|
||||
fmt.Printf(`usage: nodebalancer [-h] {%[1]s,%[2]s,%[3]s,%[4]s,%[5]s,%[6]s} ...
|
||||
|
||||
Moonstream node balancer CLI
|
||||
optional arguments:
|
||||
-h, --help show this help message and exit
|
||||
|
||||
subcommands:
|
||||
{%[1]s,%[2]s,%[3]s,%[4]s,%[5]s,%[6]s,%[7]s}
|
||||
`, s.addAccessCmd.Name(), s.updateAccessCmd.Name(), s.generateConfigCmd.Name(), s.deleteAccessCmd.Name(), s.serverCmd.Name(), s.usersCmd.Name(), s.versionCmd.Name())
|
||||
}
|
||||
|
||||
// Check if required flags are set
|
||||
func (s *StateCLI) checkRequirements() {
|
||||
if s.helpFlag {
|
||||
switch {
|
||||
case s.addAccessCmd.Parsed():
|
||||
fmt.Printf("Add new user access resource\n\n")
|
||||
s.addAccessCmd.PrintDefaults()
|
||||
os.Exit(0)
|
||||
case s.updateAccessCmd.Parsed():
|
||||
fmt.Printf("Update user access resource\n\n")
|
||||
s.updateAccessCmd.PrintDefaults()
|
||||
os.Exit(0)
|
||||
case s.generateConfigCmd.Parsed():
|
||||
fmt.Printf("Generate new configuration\n\n")
|
||||
s.generateConfigCmd.PrintDefaults()
|
||||
os.Exit(0)
|
||||
case s.deleteAccessCmd.Parsed():
|
||||
fmt.Printf("Delete user access resource\n\n")
|
||||
s.deleteAccessCmd.PrintDefaults()
|
||||
os.Exit(0)
|
||||
case s.serverCmd.Parsed():
|
||||
fmt.Printf("Start nodebalancer server\n\n")
|
||||
s.serverCmd.PrintDefaults()
|
||||
os.Exit(0)
|
||||
case s.usersCmd.Parsed():
|
||||
fmt.Printf("List user access tokens\n\n")
|
||||
s.usersCmd.PrintDefaults()
|
||||
os.Exit(0)
|
||||
case s.versionCmd.Parsed():
|
||||
fmt.Printf("Show version\n\n")
|
||||
s.versionCmd.PrintDefaults()
|
||||
os.Exit(0)
|
||||
default:
|
||||
s.usage()
|
||||
os.Exit(0)
|
||||
}
|
||||
}
|
||||
|
||||
switch {
|
||||
case s.addAccessCmd.Parsed():
|
||||
if s.userIDFlag == "" {
|
||||
fmt.Printf("User ID should be specified\n\n")
|
||||
s.addAccessCmd.PrintDefaults()
|
||||
os.Exit(1)
|
||||
}
|
||||
if s.accessIDFlag == "" {
|
||||
s.accessIDFlag = uuid.New().String()
|
||||
}
|
||||
if s.accessNameFlag == "" {
|
||||
fmt.Printf("Access name should be specified\n\n")
|
||||
s.addAccessCmd.PrintDefaults()
|
||||
os.Exit(1)
|
||||
}
|
||||
case s.updateAccessCmd.Parsed():
|
||||
if s.userIDFlag == "" && s.accessIDFlag == "" {
|
||||
fmt.Printf("User ID or access ID should be specified\n\n")
|
||||
s.updateAccessCmd.PrintDefaults()
|
||||
os.Exit(1)
|
||||
}
|
||||
case s.deleteAccessCmd.Parsed():
|
||||
if s.userIDFlag == "" && s.accessIDFlag == "" {
|
||||
fmt.Printf("User or access ID flag should be specified\n\n")
|
||||
s.deleteAccessCmd.PrintDefaults()
|
||||
os.Exit(1)
|
||||
}
|
||||
case s.usersCmd.Parsed():
|
||||
if s.offsetFlag < 0 || s.limitFlag < 0 {
|
||||
fmt.Printf("Offset and limit flags should be greater then zero\n\n")
|
||||
s.usersCmd.PrintDefaults()
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
// Load configuration
|
||||
config, err := GetConfigPath(s.configPathFlag)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if !config.ConfigExists {
|
||||
if err := GenerateDefaultConfig(config); err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
} else {
|
||||
log.Printf("Loaded configuration from %s", config.ConfigPath)
|
||||
}
|
||||
s.configPathFlag = config.ConfigPath
|
||||
}
|
||||
|
||||
func (s *StateCLI) populateCLI() {
|
||||
// Subcommands setup
|
||||
s.addAccessCmd = flag.NewFlagSet("add-access", flag.ExitOnError)
|
||||
s.updateAccessCmd = flag.NewFlagSet("update-access", flag.ExitOnError)
|
||||
s.generateConfigCmd = flag.NewFlagSet("generate-config", flag.ExitOnError)
|
||||
s.deleteAccessCmd = flag.NewFlagSet("delete-access", flag.ExitOnError)
|
||||
s.serverCmd = flag.NewFlagSet("server", flag.ExitOnError)
|
||||
s.usersCmd = flag.NewFlagSet("users", flag.ExitOnError)
|
||||
s.versionCmd = flag.NewFlagSet("version", flag.ExitOnError)
|
||||
|
||||
// Common flag pointers
|
||||
for _, fs := range []*flag.FlagSet{s.addAccessCmd, s.updateAccessCmd, s.generateConfigCmd, s.deleteAccessCmd, s.serverCmd, s.usersCmd, s.versionCmd} {
|
||||
fs.BoolVar(&s.helpFlag, "help", false, "Show help message")
|
||||
fs.StringVar(&s.configPathFlag, "config", "", "Path to configuration file (default: ~/.nodebalancer/config.json)")
|
||||
}
|
||||
|
||||
// Add, delete and list user access subcommand flag pointers
|
||||
for _, fs := range []*flag.FlagSet{s.addAccessCmd, s.updateAccessCmd, s.deleteAccessCmd, s.usersCmd} {
|
||||
fs.StringVar(&s.userIDFlag, "user-id", "", "Bugout user ID")
|
||||
fs.StringVar(&s.accessIDFlag, "access-id", "", "UUID for access identification")
|
||||
}
|
||||
|
||||
// Add/update user access subcommand flag pointers
|
||||
for _, fs := range []*flag.FlagSet{s.addAccessCmd, s.updateAccessCmd} {
|
||||
fs.StringVar(&s.accessNameFlag, "name", DEFAULT_ACCESS_NAME, fmt.Sprintf("Name of access (default: %s)", DEFAULT_ACCESS_NAME))
|
||||
fs.StringVar(&s.accessDescriptionFlag, "description", DEFAULT_ACCESS_DESCRIPTION, fmt.Sprintf("Description of access (default: %s)", DEFAULT_ACCESS_DESCRIPTION))
|
||||
fs.BoolVar(&s.blockchainAccessFlag, "blockchain-access", DEFAULT_BLOCKCHAIN_ACCESS, fmt.Sprintf("Specify this flag to grant direct access to blockchain nodes (default: %t)", DEFAULT_BLOCKCHAIN_ACCESS))
|
||||
fs.BoolVar(&s.extendedMethodsFlag, "extended-methods", DEFAULT_EXTENDED_METHODS, fmt.Sprintf("Specify this flag to grant execution availability to not whitelisted methods (default: %t)", DEFAULT_EXTENDED_METHODS))
|
||||
fs.Int64Var(&s.PeriodDurationFlag, "period-duration", DEFAULT_PERIOD_DURATION, fmt.Sprintf("Access period duration in seconds (default: %d)", DEFAULT_PERIOD_DURATION))
|
||||
fs.Int64Var(&s.MaxCallsPerPeriodFlag, "max-calls-per-period", DEFAULT_MAX_CALLS_PER_PERIOD, fmt.Sprintf("Max available calls to node during the period (default: %d)", DEFAULT_MAX_CALLS_PER_PERIOD))
|
||||
}
|
||||
|
||||
s.updateAccessCmd.Int64Var(&s.PeriodStartTsFlag, "period-start-ts", 0, "When period starts in unix timestamp format (default: now)")
|
||||
s.updateAccessCmd.Int64Var(&s.CallsPerPeriodFlag, "calls-per-period", 0, "Current number of calls to node during the period (default: 0)")
|
||||
|
||||
// Server subcommand flag pointers
|
||||
s.serverCmd.StringVar(&s.listeningAddrFlag, "host", "127.0.0.1", "Server listening address")
|
||||
s.serverCmd.StringVar(&s.listeningPortFlag, "port", "8544", "Server listening port")
|
||||
s.serverCmd.BoolVar(&s.enableHealthCheckFlag, "healthcheck", false, "To enable healthcheck set healthcheck flag")
|
||||
s.serverCmd.BoolVar(&s.enableDebugFlag, "debug", false, "To enable debug mode with extended log set debug flag")
|
||||
|
||||
// Users list subcommand flag pointers
|
||||
s.usersCmd.IntVar(&s.limitFlag, "limit", 10, "Output result limit")
|
||||
s.usersCmd.IntVar(&s.offsetFlag, "offset", 0, "Result output offset")
|
||||
}
|
||||
|
||||
func NodebalancerAppCli_OLD() {
|
||||
stateCLI.populateCLI()
|
||||
if len(os.Args) < 2 {
|
||||
stateCLI.usage()
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Init bugout client
|
||||
bc, err := CreateBugoutClient()
|
||||
if err != nil {
|
||||
log.Printf("An error occurred during Bugout client creation: %v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
bugoutClient = bc
|
||||
|
||||
// Parse subcommands and appropriate FlagSet
|
||||
switch os.Args[1] {
|
||||
case "generate-config":
|
||||
stateCLI.generateConfigCmd.Parse(os.Args[2:])
|
||||
stateCLI.checkRequirements()
|
||||
|
||||
case "add-access":
|
||||
stateCLI.addAccessCmd.Parse(os.Args[2:])
|
||||
stateCLI.checkRequirements()
|
||||
|
||||
proposedClientResourceData := ClientResourceData{
|
||||
UserID: stateCLI.userIDFlag,
|
||||
AccessID: stateCLI.accessIDFlag,
|
||||
Name: stateCLI.accessNameFlag,
|
||||
Description: stateCLI.accessDescriptionFlag,
|
||||
BlockchainAccess: stateCLI.blockchainAccessFlag,
|
||||
ExtendedMethods: stateCLI.extendedMethodsFlag,
|
||||
|
||||
PeriodDuration: stateCLI.PeriodDurationFlag,
|
||||
PeriodStartTs: time.Now().Unix(),
|
||||
MaxCallsPerPeriod: stateCLI.MaxCallsPerPeriodFlag,
|
||||
CallsPerPeriod: 0,
|
||||
|
||||
Type: BUGOUT_RESOURCE_TYPE_NODEBALANCER_ACCESS,
|
||||
}
|
||||
_, err := bugoutClient.Brood.FindUser(
|
||||
NB_CONTROLLER_TOKEN,
|
||||
map[string]string{
|
||||
"user_id": proposedClientResourceData.UserID,
|
||||
"application_id": MOONSTREAM_APPLICATION_ID,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Printf("User does not exists, err: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
resource, err := bugoutClient.Brood.CreateResource(NB_CONTROLLER_TOKEN, MOONSTREAM_APPLICATION_ID, proposedClientResourceData)
|
||||
if err != nil {
|
||||
fmt.Printf("Unable to create user access, err: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
resourceData, err := json.Marshal(resource.ResourceData)
|
||||
if err != nil {
|
||||
fmt.Printf("Unable to encode resource %s data interface to json, err: %v\n", resource.Id, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
var newUserAccess ClientAccess
|
||||
err = json.Unmarshal(resourceData, &newUserAccess)
|
||||
if err != nil {
|
||||
fmt.Printf("Unable to decode resource %s data json to structure, err: %v\n", resource.Id, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
newUserAccess.ResourceID = resource.Id
|
||||
userAccessJson, err := json.Marshal(newUserAccess)
|
||||
if err != nil {
|
||||
fmt.Printf("Unable to encode resource %s data interface to json, err: %v", resource.Id, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Println(string(userAccessJson))
|
||||
|
||||
case "update-access":
|
||||
stateCLI.updateAccessCmd.Parse(os.Args[2:])
|
||||
stateCLI.checkRequirements()
|
||||
|
||||
queryParameters := make(map[string]string)
|
||||
if stateCLI.userIDFlag != "" {
|
||||
queryParameters["user_id"] = stateCLI.userIDFlag
|
||||
}
|
||||
if stateCLI.accessIDFlag != "" {
|
||||
queryParameters["access_id"] = stateCLI.accessIDFlag
|
||||
}
|
||||
resources, err := bugoutClient.Brood.GetResources(
|
||||
NB_CONTROLLER_TOKEN,
|
||||
MOONSTREAM_APPLICATION_ID,
|
||||
queryParameters,
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Printf("Unable to get Bugout resources, err: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
resourcesLen := len(resources.Resources)
|
||||
if resourcesLen == 0 {
|
||||
fmt.Printf("There are no access resource with provided user-id %s or access-id %s\n", stateCLI.userIDFlag, stateCLI.accessIDFlag)
|
||||
os.Exit(1)
|
||||
}
|
||||
if resourcesLen > 1 {
|
||||
fmt.Printf("There are several %d access resources with provided user-id %s or access-id %s\n", resourcesLen, stateCLI.userIDFlag, stateCLI.accessIDFlag)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
resource := resources.Resources[0]
|
||||
resourceData, err := json.Marshal(resource.ResourceData)
|
||||
if err != nil {
|
||||
fmt.Printf("Unable to encode resource %s data interface to json, err: %v\n", resource.Id, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
var currentClientAccess ClientAccess
|
||||
currentClientAccess.ResourceID = resource.Id
|
||||
err = json.Unmarshal(resourceData, ¤tClientAccess.ClientResourceData)
|
||||
if err != nil {
|
||||
fmt.Printf("Unable to decode resource %s data json to structure, err: %v\n", resource.Id, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// TODO(kompotkot): Since we are using bool flags I moved with ugly solution.
|
||||
// Let's find better one when have free time or will re-write flag Set.
|
||||
update := make(map[string]interface{})
|
||||
if stateCLI.accessNameFlag != currentClientAccess.ClientResourceData.Name && stateCLI.accessNameFlag != DEFAULT_ACCESS_NAME {
|
||||
update["name"] = stateCLI.accessNameFlag
|
||||
}
|
||||
if stateCLI.accessDescriptionFlag != currentClientAccess.ClientResourceData.Description && stateCLI.accessDescriptionFlag != DEFAULT_ACCESS_DESCRIPTION {
|
||||
update["description"] = stateCLI.accessDescriptionFlag
|
||||
}
|
||||
if stateCLI.blockchainAccessFlag != currentClientAccess.ClientResourceData.BlockchainAccess && stateCLI.blockchainAccessFlag != DEFAULT_BLOCKCHAIN_ACCESS {
|
||||
update["blockchain_access"] = stateCLI.blockchainAccessFlag
|
||||
}
|
||||
if stateCLI.extendedMethodsFlag != currentClientAccess.ClientResourceData.ExtendedMethods && stateCLI.extendedMethodsFlag != DEFAULT_EXTENDED_METHODS {
|
||||
update["extended_methods"] = stateCLI.extendedMethodsFlag
|
||||
}
|
||||
if stateCLI.PeriodDurationFlag != currentClientAccess.ClientResourceData.PeriodDuration && stateCLI.PeriodDurationFlag != DEFAULT_PERIOD_DURATION {
|
||||
update["period_duration"] = stateCLI.PeriodDurationFlag
|
||||
}
|
||||
if stateCLI.MaxCallsPerPeriodFlag != currentClientAccess.ClientResourceData.MaxCallsPerPeriod && stateCLI.MaxCallsPerPeriodFlag != DEFAULT_MAX_CALLS_PER_PERIOD {
|
||||
update["max_calls_per_period"] = stateCLI.MaxCallsPerPeriodFlag
|
||||
}
|
||||
if stateCLI.PeriodStartTsFlag != currentClientAccess.ClientResourceData.PeriodStartTs && stateCLI.PeriodStartTsFlag != 0 {
|
||||
update["period_start_ts"] = stateCLI.PeriodStartTsFlag
|
||||
}
|
||||
if stateCLI.CallsPerPeriodFlag != currentClientAccess.ClientResourceData.CallsPerPeriod && stateCLI.CallsPerPeriodFlag != 0 {
|
||||
update["calls_per_period"] = stateCLI.CallsPerPeriodFlag
|
||||
}
|
||||
|
||||
updatedResource, err := bugoutClient.Brood.UpdateResource(
|
||||
NB_CONTROLLER_TOKEN,
|
||||
resource.Id,
|
||||
update,
|
||||
[]string{},
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Printf("Unable to update Bugout resource, err: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
updatedResourceData, err := json.Marshal(updatedResource.ResourceData)
|
||||
if err != nil {
|
||||
fmt.Printf("Unable to encode resource %s data interface to json, err: %v\n", resource.Id, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
var updatedUserAccess ClientAccess
|
||||
err = json.Unmarshal(updatedResourceData, &updatedUserAccess)
|
||||
if err != nil {
|
||||
fmt.Printf("Unable to decode resource %s data json to structure, err: %v\n", resource.Id, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
updatedUserAccess.ResourceID = updatedResource.Id
|
||||
userAccessJson, err := json.Marshal(updatedUserAccess)
|
||||
if err != nil {
|
||||
fmt.Printf("Unable to marshal user access struct, err: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Println(string(userAccessJson))
|
||||
|
||||
case "delete-access":
|
||||
stateCLI.deleteAccessCmd.Parse(os.Args[2:])
|
||||
stateCLI.checkRequirements()
|
||||
|
||||
queryParameters := make(map[string]string)
|
||||
if stateCLI.userIDFlag != "" {
|
||||
queryParameters["user_id"] = stateCLI.userIDFlag
|
||||
}
|
||||
if stateCLI.accessIDFlag != "" {
|
||||
queryParameters["access_id"] = stateCLI.accessIDFlag
|
||||
}
|
||||
resources, err := bugoutClient.Brood.GetResources(
|
||||
NB_CONTROLLER_TOKEN,
|
||||
MOONSTREAM_APPLICATION_ID,
|
||||
queryParameters,
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Printf("Unable to get Bugout resources, err: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
var userAccesses []ClientAccess
|
||||
for _, resource := range resources.Resources {
|
||||
deletedResource, err := bugoutClient.Brood.DeleteResource(NB_CONTROLLER_TOKEN, resource.Id)
|
||||
if err != nil {
|
||||
fmt.Printf("Unable to delete resource %s, err: %v\n", resource.Id, err)
|
||||
continue
|
||||
}
|
||||
deletedResourceData, err := json.Marshal(deletedResource.ResourceData)
|
||||
if err != nil {
|
||||
fmt.Printf("Unable to encode resource %s data interface to json, err: %v\n", resource.Id, err)
|
||||
continue
|
||||
}
|
||||
var deletedUserAccess ClientAccess
|
||||
err = json.Unmarshal(deletedResourceData, &deletedUserAccess)
|
||||
if err != nil {
|
||||
fmt.Printf("Unable to decode resource %s data json to structure, err: %v\n", resource.Id, err)
|
||||
continue
|
||||
}
|
||||
deletedUserAccess.ResourceID = deletedResource.Id
|
||||
userAccesses = append(userAccesses, deletedUserAccess)
|
||||
}
|
||||
|
||||
userAccessesJson, err := json.Marshal(userAccesses)
|
||||
if err != nil {
|
||||
fmt.Printf("Unable to marshal user access struct, err: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Println(string(userAccessesJson))
|
||||
|
||||
case "server":
|
||||
stateCLI.serverCmd.Parse(os.Args[2:])
|
||||
stateCLI.checkRequirements()
|
||||
|
||||
CheckEnvVarSet()
|
||||
|
||||
Server()
|
||||
|
||||
case "users":
|
||||
stateCLI.usersCmd.Parse(os.Args[2:])
|
||||
stateCLI.checkRequirements()
|
||||
|
||||
queryParameters := make(map[string]string)
|
||||
if stateCLI.userIDFlag != "" {
|
||||
queryParameters["user_id"] = stateCLI.userIDFlag
|
||||
}
|
||||
if stateCLI.accessIDFlag != "" {
|
||||
queryParameters["access_id"] = stateCLI.accessIDFlag
|
||||
}
|
||||
resources, err := bugoutClient.Brood.GetResources(
|
||||
NB_CONTROLLER_TOKEN,
|
||||
MOONSTREAM_APPLICATION_ID,
|
||||
queryParameters,
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Printf("Unable to get Bugout resources, err: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
var clientAccesses []ClientAccess
|
||||
|
||||
offset := stateCLI.offsetFlag
|
||||
if stateCLI.offsetFlag > len(resources.Resources) {
|
||||
offset = len(resources.Resources)
|
||||
}
|
||||
limit := stateCLI.offsetFlag + stateCLI.limitFlag
|
||||
if limit > len(resources.Resources) {
|
||||
limit = len(resources.Resources[offset:]) + offset
|
||||
}
|
||||
|
||||
for _, resource := range resources.Resources[offset:limit] {
|
||||
resourceData, err := json.Marshal(resource.ResourceData)
|
||||
if err != nil {
|
||||
fmt.Printf("Unable to encode resource %s data interface to json, err: %v\n", resource.Id, err)
|
||||
continue
|
||||
}
|
||||
var clientAccess ClientAccess
|
||||
clientAccess.ResourceID = resource.Id
|
||||
err = json.Unmarshal(resourceData, &clientAccess.ClientResourceData)
|
||||
if err != nil {
|
||||
fmt.Printf("Unable to decode resource %s data json to structure, err: %v\n", resource.Id, err)
|
||||
continue
|
||||
}
|
||||
clientAccesses = append(clientAccesses, clientAccess)
|
||||
}
|
||||
userAccessesJson, err := json.Marshal(clientAccesses)
|
||||
if err != nil {
|
||||
fmt.Printf("Unable to marshal user accesses struct, err: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Println(string(userAccessesJson))
|
||||
|
||||
case "version":
|
||||
stateCLI.versionCmd.Parse(os.Args[2:])
|
||||
stateCLI.checkRequirements()
|
||||
|
||||
fmt.Printf("v%s\n", NB_VERSION)
|
||||
|
||||
default:
|
||||
stateCLI.usage()
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
|
@ -1,10 +1,14 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"reflect"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/bugout-dev/bugout-go/pkg/brood"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -188,3 +192,109 @@ func (cpool *ClientPool) CleanInactiveClientNodes() int {
|
|||
|
||||
return cnt
|
||||
}
|
||||
|
||||
// Creates new Bugout resource according to nodebalancer type to grant user or application access to call JSON RPC nodes
|
||||
func AddNewAccess(accessId, userId, name, description string, blockchainAccess, extendedMethods bool, periodDuration, maxCallsPerPeriod uint, accessToken string) (*ClientAccess, error) {
|
||||
_, findErr := bugoutClient.Brood.FindUser(
|
||||
accessToken,
|
||||
map[string]string{
|
||||
"user_id": userId,
|
||||
"application_id": MOONSTREAM_APPLICATION_ID,
|
||||
},
|
||||
)
|
||||
if findErr != nil {
|
||||
return nil, fmt.Errorf("user does not exists, err: %v", findErr)
|
||||
}
|
||||
|
||||
proposedClientResourceData := ClientResourceData{
|
||||
AccessID: accessId,
|
||||
UserID: userId,
|
||||
Name: name,
|
||||
Description: description,
|
||||
BlockchainAccess: blockchainAccess,
|
||||
ExtendedMethods: extendedMethods,
|
||||
|
||||
PeriodDuration: int64(periodDuration),
|
||||
PeriodStartTs: int64(time.Now().Unix()),
|
||||
MaxCallsPerPeriod: int64(maxCallsPerPeriod),
|
||||
CallsPerPeriod: 0,
|
||||
|
||||
Type: BUGOUT_RESOURCE_TYPE_NODEBALANCER_ACCESS,
|
||||
}
|
||||
|
||||
resource, err := bugoutClient.Brood.CreateResource(accessToken, MOONSTREAM_APPLICATION_ID, proposedClientResourceData)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to create user access, err: %v", err)
|
||||
}
|
||||
resourceData, err := json.Marshal(resource.ResourceData)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to encode resource %s data interface to json, err: %v", resource.Id, err)
|
||||
}
|
||||
var newUserAccess ClientAccess
|
||||
err = json.Unmarshal(resourceData, &newUserAccess)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to decode resource %s data json to structure, err: %v", resource.Id, err)
|
||||
}
|
||||
newUserAccess.ResourceID = resource.Id
|
||||
|
||||
return &newUserAccess, nil
|
||||
}
|
||||
|
||||
func ShareAccess(resourceId, userId, holderType string, permissions []string, accessToken string) (*brood.ResourceHolders, error) {
|
||||
resourceHolderPermissions, holdErr := bugoutClient.Brood.AddResourceHolderPermissions(
|
||||
accessToken, resourceId, brood.ResourceHolder{
|
||||
Id: userId,
|
||||
HolderType: holderType,
|
||||
Permissions: permissions,
|
||||
},
|
||||
)
|
||||
if holdErr != nil {
|
||||
return nil, fmt.Errorf("unable to grant permissions to user with ID %s at resource with ID %s, err: %v", resourceId, userId, holdErr)
|
||||
}
|
||||
|
||||
return &resourceHolderPermissions, nil
|
||||
}
|
||||
|
||||
func GetAccesses(accessId, userId, accessToken string) (*brood.Resources, error) {
|
||||
queryParameters := map[string]string{
|
||||
"type": BUGOUT_RESOURCE_TYPE_NODEBALANCER_ACCESS,
|
||||
}
|
||||
if userId != "" {
|
||||
queryParameters["user_id"] = userId
|
||||
}
|
||||
if accessId != "" {
|
||||
queryParameters["access_id"] = accessId
|
||||
}
|
||||
|
||||
resources, getResErr := bugoutClient.Brood.GetResources(accessToken, MOONSTREAM_APPLICATION_ID, queryParameters)
|
||||
if getResErr != nil {
|
||||
return nil, fmt.Errorf("unable to get Bugout resources, err: %v", getResErr)
|
||||
}
|
||||
|
||||
return &resources, nil
|
||||
}
|
||||
|
||||
func ParseResourceDataToClientAccess(resource brood.Resource) (*ClientAccess, error) {
|
||||
resourceData, marErr := json.Marshal(resource.ResourceData)
|
||||
if marErr != nil {
|
||||
return nil, fmt.Errorf("unable to encode resource %s data interface to json, err: %v", resource.Id, marErr)
|
||||
}
|
||||
|
||||
var clientAccess ClientAccess
|
||||
clientAccess.ResourceID = resource.Id
|
||||
unmarErr := json.Unmarshal(resourceData, &clientAccess.ClientResourceData)
|
||||
if unmarErr != nil {
|
||||
return nil, fmt.Errorf("unable to decode resource %s data json to structure, err: %v", resource.Id, unmarErr)
|
||||
}
|
||||
|
||||
return &clientAccess, nil
|
||||
}
|
||||
|
||||
func DeleteAccess(resourceId, accessToken string) (*brood.Resource, error) {
|
||||
del, delErr := bugoutClient.Brood.DeleteResource(accessToken, resourceId)
|
||||
if delErr != nil {
|
||||
return nil, fmt.Errorf("unable to delete resource, err: %v", delErr)
|
||||
}
|
||||
|
||||
return &del, nil
|
||||
}
|
||||
|
|
|
@ -23,15 +23,18 @@ var (
|
|||
|
||||
supportedBlockchains map[string]bool
|
||||
|
||||
bugoutClient *bugout.BugoutClient
|
||||
|
||||
// Bugout client
|
||||
// TODO(kompotkot): Find out why it cuts out the port
|
||||
BUGOUT_BROOD_URL = "https://auth.bugout.dev"
|
||||
// BUGOUT_BROOD_URL = os.Getenv("BUGOUT_BROOD_URL")
|
||||
// BUGOUT_BROOD_URL = "https://auth.bugout.dev"
|
||||
BUGOUT_BROOD_URL = os.Getenv("BUGOUT_BROOD_URL")
|
||||
NB_BUGOUT_TIMEOUT_SECONDS_RAW = os.Getenv("NB_BUGOUT_TIMEOUT_SECONDS")
|
||||
|
||||
// Bugout and application configuration
|
||||
BUGOUT_AUTH_CALL_TIMEOUT = time.Second * 5
|
||||
MOONSTREAM_APPLICATION_ID = os.Getenv("MOONSTREAM_APPLICATION_ID")
|
||||
NB_CONTROLLER_USER_ID = os.Getenv("NB_CONTROLLER_USER_ID")
|
||||
NB_CONTROLLER_TOKEN = os.Getenv("NB_CONTROLLER_TOKEN")
|
||||
NB_CONTROLLER_ACCESS_ID = os.Getenv("NB_CONTROLLER_ACCESS_ID")
|
||||
MOONSTREAM_CORS_ALLOWED_ORIGINS = os.Getenv("MOONSTREAM_CORS_ALLOWED_ORIGINS")
|
||||
|
@ -64,15 +67,15 @@ var (
|
|||
DEFAULT_AUTOGENERATED_MAX_CALLS_PER_PERIOD = int64(1000)
|
||||
)
|
||||
|
||||
func CreateBugoutClient() (bugout.BugoutClient, error) {
|
||||
func CreateBugoutClient() (*bugout.BugoutClient, error) {
|
||||
bugoutTimeoutSeconds, err := strconv.Atoi(NB_BUGOUT_TIMEOUT_SECONDS_RAW)
|
||||
if err != nil {
|
||||
return bugout.BugoutClient{}, fmt.Errorf("unable to parse environment variable as integer: %v", err)
|
||||
return nil, fmt.Errorf("unable to parse environment variable as integer: %v", err)
|
||||
}
|
||||
NB_BUGOUT_TIMEOUT_SECONDS := time.Duration(bugoutTimeoutSeconds) * time.Second
|
||||
|
||||
broodClient := bugout.ClientBrood(BUGOUT_BROOD_URL, NB_BUGOUT_TIMEOUT_SECONDS)
|
||||
return broodClient, nil
|
||||
bugoutClient := bugout.ClientBrood(BUGOUT_BROOD_URL, NB_BUGOUT_TIMEOUT_SECONDS)
|
||||
return &bugoutClient, nil
|
||||
}
|
||||
|
||||
func CheckEnvVarSet() {
|
||||
|
|
|
@ -1,5 +1,13 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
)
|
||||
|
||||
func main() {
|
||||
cli()
|
||||
app := NodebalancerAppCli()
|
||||
if err := app.Run(os.Args); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -234,52 +234,9 @@ func fetchClientAccessFromResources(accessID, authorizationToken string, tsNow i
|
|||
}
|
||||
|
||||
if len(resources.Resources) == 0 {
|
||||
if authorizationToken != "" {
|
||||
// Generate new autogenerated access resource with default parameters and grant user permissions to work with it
|
||||
user, err := bugoutClient.Brood.GetUser(authorizationToken)
|
||||
if err != nil {
|
||||
log.Printf("Unable to get user, err: %v", err)
|
||||
return nil, fmt.Errorf("unable to find user with provided authorization token")
|
||||
}
|
||||
newResource, err := bugoutClient.Brood.CreateResource(
|
||||
NB_CONTROLLER_TOKEN, MOONSTREAM_APPLICATION_ID, ClientResourceData{
|
||||
UserID: user.Id,
|
||||
AccessID: uuid.New().String(),
|
||||
Name: user.Username,
|
||||
Description: "Autogenerated access ID",
|
||||
BlockchainAccess: true,
|
||||
ExtendedMethods: false,
|
||||
|
||||
PeriodDuration: DEFAULT_AUTOGENERATED_PERIOD_DURATION,
|
||||
PeriodStartTs: tsNow,
|
||||
MaxCallsPerPeriod: DEFAULT_AUTOGENERATED_MAX_CALLS_PER_PERIOD,
|
||||
CallsPerPeriod: 0,
|
||||
|
||||
Type: BUGOUT_RESOURCE_TYPE_NODEBALANCER_ACCESS,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
log.Printf("Unable to create resource with autogenerated access for user with ID %s, err: %v", user.Id, err)
|
||||
return nil, fmt.Errorf("unable to create resource with autogenerated access for user")
|
||||
}
|
||||
|
||||
resourceHolderPermissions, err := bugoutClient.Brood.AddResourceHolderPermissions(
|
||||
NB_CONTROLLER_TOKEN, newResource.Id, brood.ResourceHolder{
|
||||
Id: user.Id,
|
||||
HolderType: "user",
|
||||
Permissions: DEFAULT_AUTOGENERATED_USER_PERMISSIONS,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
log.Printf("Unable to grant permissions to user with ID %s at resource with ID %s, err: %v", newResource.Id, user.Id, err)
|
||||
return nil, fmt.Errorf("unable to create resource with autogenerated access for user")
|
||||
}
|
||||
|
||||
log.Printf("Created new resource with ID %s with autogenerated access for user with ID %s", resourceHolderPermissions.ResourceId, user.Id)
|
||||
resources.Resources = append(resources.Resources, newResource)
|
||||
} else {
|
||||
return nil, fmt.Errorf("there are no provided access identifier")
|
||||
}
|
||||
// Generate new autogenerated access resource with default parameters and grant user permissions to work with it
|
||||
// TODO(kompotkot): Not working because of permissions models change at Brood layer
|
||||
return nil, fmt.Errorf("there are no provided access identifier")
|
||||
} else if len(resources.Resources) > 1 {
|
||||
// TODO(kompotkot): Write support of multiple resources, be careful, because NB_CONTROLLER has several resources
|
||||
return nil, fmt.Errorf("there are no provided access identifier")
|
||||
|
|
|
@ -6,4 +6,11 @@ require (
|
|||
github.com/bugout-dev/bugout-go v0.4.3
|
||||
github.com/bugout-dev/humbug/go v0.0.0-20211206230955-57607cd2d205
|
||||
github.com/google/uuid v1.3.0
|
||||
github.com/urfave/cli/v2 v2.27.5
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect
|
||||
)
|
||||
|
|
|
@ -12,6 +12,7 @@ cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2k
|
|||
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
|
@ -35,6 +36,8 @@ github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3Ee
|
|||
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
|
@ -142,6 +145,8 @@ github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40T
|
|||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
|
@ -163,7 +168,11 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf
|
|||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/urfave/cli/v2 v2.27.5 h1:WoHEJLdsXr6dDWoJgMq/CboDmyY/8HMMH1fTECbih+w=
|
||||
github.com/urfave/cli/v2 v2.27.5/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5hrMvTQ=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4=
|
||||
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM=
|
||||
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
|
@ -282,6 +291,7 @@ gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bl
|
|||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
|
|
|
@ -3,8 +3,9 @@ export BUGOUT_BROOD_URL="https://auth.bugout.dev"
|
|||
export NB_BUGOUT_TIMEOUT_SECONDS=15
|
||||
export MOONSTREAM_APPLICATION_ID="<application_id_to_controll_access>"
|
||||
export MOONSTREAM_CORS_ALLOWED_ORIGINS="http://localhost:3000,https://moonstream.to,https://portal.moonstream.to"
|
||||
export NB_CONTROLLER_TOKEN="<token_of_controller_user>"
|
||||
export NB_CONTROLLER_ACCESS_ID="<controller_access_id_for_internal_usage>"
|
||||
export NB_CONTROLLER_USER_ID="<bugout_id_of_nodebalancer_user>"
|
||||
export NB_CONTROLLER_TOKEN="<token_of_nodebalancer_user>"
|
||||
export NB_CONTROLLER_ACCESS_ID="<nodebalancer_access_id_for_internal_usage>"
|
||||
|
||||
# Error humbug reporter
|
||||
export HUMBUG_REPORTER_NODE_BALANCER_TOKEN="<bugout_humbug_token_for_crash_reports>"
|
||||
|
|
Ładowanie…
Reference in New Issue