From d0a5226b0c739d8ec1fbfae8ef838a9aae9cd02b Mon Sep 17 00:00:00 2001 From: Sergei Sumarokov <7047457+kompotkot@users.noreply.github.com> Date: Fri, 13 Dec 2024 12:55:37 +0300 Subject: [PATCH] Revert "Fix nodebalancer CLI and removed autogen accesses" --- nodebalancer/README.md | 29 +- nodebalancer/cmd/nodebalancer/cli.go | 1055 +++++++++---------- nodebalancer/cmd/nodebalancer/clients.go | 115 +- nodebalancer/cmd/nodebalancer/configs.go | 17 +- nodebalancer/cmd/nodebalancer/main.go | 10 +- nodebalancer/cmd/nodebalancer/middleware.go | 56 +- nodebalancer/cmd/nodebalancer/server.go | 71 +- nodebalancer/cmd/nodebalancer/version.go | 2 +- nodebalancer/deploy/nodebalancer.service | 8 +- nodebalancer/go.mod | 13 +- nodebalancer/go.sum | 22 +- nodebalancer/sample.env | 5 +- 12 files changed, 629 insertions(+), 774 deletions(-) diff --git a/nodebalancer/README.md b/nodebalancer/README.md index c96950d6..f7f42c23 100644 --- a/nodebalancer/README.md +++ b/nodebalancer/README.md @@ -3,36 +3,37 @@ ## Installation - Prepare environment variables, according to `sample.env`. -- Build an application +- Build application ```bash go build -o nodebalancer . ``` -## CLI +## Work with nodebalancer **IMPORTANT** Do not use flag `-debug` in production. -Node balancer access manipulation requires an administration token to create and modify resources within the Bugout moonstream application. - -### add new access +### add-access Add new access for user: ```bash -./nodebalancer access add \ - --access-token "" +nodebalancer add-access \ + --user-id "" \ + --access-id "" \ --name "Access name" \ - --description "Description of access" + --description "Description of access" \ + --extended-methods false \ + --blockchain--access true ``` -### delete access +### delete-access Delete user access: ```bash -./nodebalancer access delete \ - --access-token "" +nodebalancer delete-access \ + --user-id "" \ --access-id "" ``` @@ -41,10 +42,10 @@ If `access-id` not specified, all user accesses will be deleted. ### users ```bash -./nodebalancer access list --access-token "" | jq . +nodebalancer users | jq . ``` -This command will return a list of bugout resources of registered users to access node balancer. +This command will return a list of bugout resources of registered users to access node balancer with their `crawlers/app/project` (in our project we will call it `crawlers`). ```json [ @@ -71,7 +72,7 @@ This command will return a list of bugout resources of registered users to acces ### server ```bash -./nodebalancer server --host 0.0.0.0 --port 8544 --healthcheck +nodebalancer server -host 0.0.0.0 -port 8544 -healthcheck ``` Flag `--healthcheck` will execute background process to ping-pong available nodes to keep their status and current block number. diff --git a/nodebalancer/cmd/nodebalancer/cli.go b/nodebalancer/cmd/nodebalancer/cli.go index 264a89dc..f33699e5 100644 --- a/nodebalancer/cmd/nodebalancer/cli.go +++ b/nodebalancer/cmd/nodebalancer/cli.go @@ -2,584 +2,519 @@ package main import ( "encoding/json" + "flag" "fmt" - "strings" - "sync" + "log" + "os" "time" bugout "github.com/bugout-dev/bugout-go/pkg" - "github.com/bugout-dev/bugout-go/pkg/brood" "github.com/google/uuid" - "github.com/urfave/cli/v2" ) -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", - }, - &cli.StringFlag{ - Name: "user-id", - Aliases: []string{"u"}, - Usage: "Bugout user ID", - }, - &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", - Value: true, - }, - &cli.BoolFlag{ - Name: "extended-methods", - Aliases: []string{"e"}, - Usage: "Specify this flag to grant execution availability to not whitelisted methods", - Value: true, - }, - &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 { - accessIdFlag := c.String("access-id") - if accessIdFlag != "" { - _, uuidErr := uuid.Parse(accessIdFlag) - if uuidErr != nil { - return fmt.Errorf("provided --access-id should be valid UUID string") - } - } +var ( + // Storing CLI definitions at server startup + stateCLI StateCLI - 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 { - accessToken := c.String("access-token") +// 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 - var clientErr error - bugoutClient, clientErr = CreateBugoutClient() - if clientErr != nil { - return clientErr - } + // Common flags + configPathFlag string + helpFlag bool - newAccess, newErr := AddNewAccess(accessToken, 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")) - if newErr != nil { - return newErr - } + // Add/update user access flags + userIDFlag string + accessIDFlag string + accessNameFlag string + accessDescriptionFlag string - _, shareErr := ShareAccess(accessToken, newAccess.ResourceID, NB_CONTROLLER_USER_ID, "user", DEFAULT_AUTOGENERATED_USER_PERMISSIONS) - if shareErr != nil { - return shareErr - } + blockchainAccessFlag bool + extendedMethodsFlag bool - 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)) + PeriodDurationFlag int64 + MaxCallsPerPeriodFlag int64 - return nil - }, - }, - { - Name: "update", - Usage: "Update user's access", - Flags: []cli.Flag{ - &cli.StringFlag{ - Name: "access-token", - Aliases: []string{"t"}, - Usage: "Authorized user access token with granted privileges to updated resources in Moonstream Bugout application", - Required: true, - }, - &cli.StringFlag{ - Name: "access-id", - Aliases: []string{"a"}, - Usage: "UUID for access identification", - }, - &cli.StringFlag{ - Name: "resource-id", - Aliases: []string{"r"}, - Usage: "UUID of Bugout resource for access identification", - }, - &cli.BoolFlag{ - Name: "reset-period-start-ts", - Aliases: []string{"s"}, - Usage: "Resets access unix period start timestamp to time now", - }, - &cli.UintFlag{ - Name: "period-duration", - Aliases: []string{"p"}, - Usage: "Access period duration in seconds", - }, - &cli.UintFlag{ - Name: "max-calls-per-period", - Aliases: []string{"m"}, - Usage: "Max available calls to node during the period", - }, - }, - Before: func(c *cli.Context) error { - accessIdFlag := c.String("access-id") - if accessIdFlag != "" { - _, uuidErr := uuid.Parse(accessIdFlag) - if uuidErr != nil { - return fmt.Errorf("provided --access-id should be valid UUID string") - } - } + // Update user access flags + PeriodStartTsFlag int64 + CallsPerPeriodFlag int64 - if accessIdFlag == "" && c.String("resource-id") == "" { - return fmt.Errorf("at least one of --access-id or --resource-id should be set") - } + // Server flags + listeningAddrFlag string + listeningPortFlag string + enableHealthCheckFlag bool + enableDebugFlag bool - if !c.Bool("reset-period-start-ts") && c.Uint("period-duration") == 0 && c.Uint("max-calls-per-period") == 0 { - return fmt.Errorf("no updated parameters provided, at least one of --reset-period-start-ts or --max-calls-per-period or --period-duration should be set") - } - - return nil - }, - Action: func(c *cli.Context) error { - accessToken := c.String("access-token") - - var clientErr error - bugoutClient, clientErr = CreateBugoutClient() - if clientErr != nil { - return clientErr - } - - resourceIdFlag := c.String("resource-id") - - var resources *brood.Resources - var getResErr error - if resourceIdFlag == "" { - resources, getResErr = GetResources(accessToken, c.String("access-id"), "") - if getResErr != nil { - return getResErr - } - } else { - var resource brood.Resource - resource, getResErr = bugoutClient.Brood.GetResource(accessToken, resourceIdFlag) - if getResErr != nil { - return fmt.Errorf("unable to get Bugout resource, err: %v", getResErr) - } - resources = &brood.Resources{Resources: []brood.Resource{resource}} - } - - if len(resources.Resources) > 1 { - return fmt.Errorf("too many resources to update") - } else if len(resources.Resources) == 0 { - return fmt.Errorf("there are no resources with such parameters") - } - - clientAccess, parseErr := ParseResourceDataToClientAccess(resources.Resources[0]) - if parseErr != nil { - return parseErr - } - - resourceId := clientAccess.ResourceID - updatedClientAccessResourceData := clientAccess.ClientResourceData - if c.Bool("reset-period-start-ts") { - updatedClientAccessResourceData.PeriodStartTs = int64(time.Now().Unix()) - } - if c.Uint("period-duration") != 0 { - updatedClientAccessResourceData.PeriodDuration = int64(c.Uint("period-duration")) - } - if c.Uint("max-calls-per-period") != 0 { - updatedClientAccessResourceData.MaxCallsPerPeriod = int64(c.Uint("max-calls-per-period")) - } - - updatedResource, updErr := bugoutClient.Brood.UpdateResource(accessToken, resourceId, updatedClientAccessResourceData, []string{}) - if updErr != nil { - return fmt.Errorf("unable to update Bugout resource, err: %v", updErr) - } - - fmt.Printf("Updated resource %s\n", updatedResource.Id) - - return nil - }, - }, - { - Name: "delete", - Usage: "Delete user's access", - 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", - }, - &cli.StringFlag{ - Name: "resource-id", - Aliases: []string{"r"}, - Usage: "UUID of Bugout resource for access identification", - }, - }, - Before: func(c *cli.Context) error { - accessIdFlag := c.String("access-id") - if accessIdFlag != "" { - _, uuidErr := uuid.Parse(accessIdFlag) - if uuidErr != nil { - return fmt.Errorf("provided --access-id should be valid UUID string") - } - } - - userIdFlag := c.String("user-id") - resourceIdFlag := c.String("resource-id") - - if accessIdFlag == "" && userIdFlag == "" && resourceIdFlag == "" { - return fmt.Errorf("at least one of --access-id or --user-id or --resource-id should be set") - } - - return nil - }, - Action: func(c *cli.Context) error { - accessToken := c.String("access-token") - - var clientErr error - bugoutClient, clientErr = CreateBugoutClient() - if clientErr != nil { - return clientErr - } - - var resources *brood.Resources - var getResErr error - - resourceIdFlag := c.String("resource-id") - if resourceIdFlag == "" { - resources, getResErr = GetResources(accessToken, c.String("access-id"), c.String("user-id")) - if getResErr != nil { - return getResErr - } - } else { - var resource brood.Resource - resource, getResErr = bugoutClient.Brood.GetResource(accessToken, resourceIdFlag) - if getResErr != nil { - return fmt.Errorf("unable to get Bugout resource, err: %v", getResErr) - } - resources = &brood.Resources{Resources: []brood.Resource{resource}} - - } - - fmt.Printf("Found %d resources to delete\n", len(resources.Resources)) - if len(resources.Resources) == 0 { - return nil - } - - var clientAccesses []ClientAccess - for _, resource := range resources.Resources { - clientAccess, parseErr := ParseResourceDataToClientAccess(resource) - if parseErr != nil { - fmt.Println(parseErr) - continue - } - - clientAccesses = append(clientAccesses, *clientAccess) - } - - 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) - - _, delErr := bugoutClient.Brood.DeleteResource(accessToken, access.ResourceID) - if delErr != nil { - fmt.Printf("Failed to delete resource with ID %s err: %v\n", access.ResourceID, delErr) - continue - } - } - - return nil - }, - }, - { - Name: "list", - Usage: "List user accesses", - 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 { - accessToken := c.String("access-token") - - var clientErr error - bugoutClient, clientErr = CreateBugoutClient() - if clientErr != nil { - return clientErr - } - - resources, getResErr := GetResources(accessToken, c.String("access-id"), c.String("user-id")) - if getResErr != nil { - return getResErr - } - - var clientAccesses []ClientAccess - for _, resource := range resources.Resources { - clientAccess, parseErr := ParseResourceDataToClientAccess(resource) - if parseErr != nil { - fmt.Println(parseErr) - continue - } - - clientAccesses = append(clientAccesses, *clientAccess) - } - - userAccessesJson, marErr := json.Marshal(clientAccesses) - if marErr != nil { - return fmt.Errorf("unable to marshal user accesses struct, err: %v", marErr) - } - fmt.Println(string(userAccessesJson)) - - return nil - }, - }, - { - Name: "verify", - Usage: "Verify accesses in correct state", - 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, - }, - }, - Action: func(c *cli.Context) error { - accessToken := c.String("access-token") - - var clientErr error - bugoutClient, clientErr = CreateBugoutClient() - if clientErr != nil { - return clientErr - } - - resources, getResErr := GetResources(accessToken, "", "") - if getResErr != nil { - return getResErr - } - - if len(resources.Resources) == 0 { - fmt.Println("[]") - return nil - } - - var wg sync.WaitGroup - sem := make(chan struct{}, 3) - errChan := make(chan error, len(resources.Resources)) - - var modifiedClientAccesses []ClientAccess - var deleteClientAccesses []ClientAccess - shareResourceIds := make(map[string]bool) - for _, resource := range resources.Resources { - wg.Add(1) - go func(resourceId string) { - defer wg.Done() - sem <- struct{}{} - - var isShared bool - - holders, holdErr := bugoutClient.Brood.GetResourceHolders(accessToken, resourceId) - if holdErr != nil { - errChan <- fmt.Errorf("failed get holders for resource ID %s with error %v", resourceId, holdErr) - } - - for _, h := range holders.Holders { - if h.Id == NB_CONTROLLER_USER_ID { - isShared = true - } - } - - if !isShared { - shareResourceIds[resourceId] = true - } - - <-sem - }(resource.Id) - - var isModified bool - clientAccess, parseErr := ParseResourceDataToClientAccess(resource) - if parseErr != nil { - fmt.Println(parseErr) - continue - } - - if clientAccess.ClientResourceData.Name == "" || clientAccess.ClientResourceData.AccessID == "" { - deleteClientAccesses = append(deleteClientAccesses, *clientAccess) - continue - } - - if clientAccess.ClientResourceData.PeriodStartTs == 0 { - clientAccess.ClientResourceData.PeriodStartTs = int64(time.Now().Unix()) - isModified = true - } - - if clientAccess.ClientResourceData.PeriodDuration < 3600 { - clientAccess.ClientResourceData.PeriodDuration = 3600 - isModified = true - } - - if isModified { - modifiedClientAccesses = append(modifiedClientAccesses, *clientAccess) - continue - } - } - - fmt.Printf("There are %d accesses to modify\n", len(modifiedClientAccesses)) - for _, a := range modifiedClientAccesses { - fmt.Printf(" - resource ID %s with access ID %s\n", a.ResourceID, a.ClientResourceData.AccessID) - } - fmt.Printf("There are %d accesses to delete\n", len(deleteClientAccesses)) - for _, a := range deleteClientAccesses { - fmt.Printf(" - resource ID %s with access ID %s\n", a.ResourceID, a.ClientResourceData.AccessID) - } - - wg.Wait() - close(sem) - close(errChan) - - var errorMessages []string - for err := range errChan { - errorMessages = append(errorMessages, err.Error()) - } - - if len(errorMessages) > 0 { - fmt.Printf("errors occurred during verification:\n%s", strings.Join(errorMessages, "\n")) - } - - fmt.Printf("There are %d accesses not shared with nodebalancer application user\n", len(shareResourceIds)) - for a := range shareResourceIds { - fmt.Printf(" - resource ID %s\n", a) - } - - return nil - }, - }, - }, - }, - { - Name: "server", - Usage: "Start nodebalancer server", - Flags: []cli.Flag{ - &cli.StringFlag{ - Name: "config", - Aliases: []string{"c"}, - Usage: "Path to configuration file", - Required: true, - }, - &cli.StringFlag{ - Name: "host", - Usage: "Server listening address", - Value: "127.0.0.1", - }, - &cli.StringFlag{ - Name: "port", - Aliases: []string{"p"}, - Usage: "Server listening port", - Value: "8544", - }, - &cli.BoolFlag{ - Name: "healthcheck", - Usage: "Repeatedly send ping requests to the node to verify its availability", - }, - &cli.BoolFlag{ - Name: "debug", - Usage: "Show extended logs", - }, - }, - Action: func(c *cli.Context) error { - NB_ENABLE_DEBUG = c.Bool("debug") - - var clientErr error - bugoutClient, clientErr = CreateBugoutClient() - if clientErr != nil { - return clientErr - } - - CheckEnvVarSet() - - servErr := Server(c.String("config"), c.String("host"), c.String("port"), c.Bool("healthcheck")) - if servErr != nil { - return servErr - } - - return nil - }, - }, - { - Name: "version", - Usage: "Shows nodebalancer package version", - Action: func(cCtx *cli.Context) error { - fmt.Printf("Node Balancer version: %s\n", NB_VERSION) - fmt.Printf("Bugout version: %s\n", bugout.Version) - return nil - }, - }, + // Users list flags + limitFlag int + offsetFlag int } -func NodebalancerAppCli() *cli.App { - return &cli.App{ - Name: "nodebalancer", - Version: fmt.Sprintf("v%s", NB_VERSION), - Usage: "Web3 node balancer", - EnableBashCompletion: true, - Commands: CommonCommands, +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, + }, + ) + 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) } } diff --git a/nodebalancer/cmd/nodebalancer/clients.go b/nodebalancer/cmd/nodebalancer/clients.go index adcfd89c..56cb1e17 100644 --- a/nodebalancer/cmd/nodebalancer/clients.go +++ b/nodebalancer/cmd/nodebalancer/clients.go @@ -1,15 +1,10 @@ package main import ( - "encoding/json" - "fmt" "log" "reflect" "sync" "time" - - "github.com/bugout-dev/bugout-go/pkg/brood" - "github.com/google/uuid" ) var ( @@ -60,7 +55,7 @@ func (ca *ClientAccess) CheckClientCallPeriodLimits(tsNow int64) bool { } } else { // Client period should be refreshed - if NB_ENABLE_DEBUG { + if stateCLI.enableDebugFlag { log.Printf("Refresh client's period_start_ts with time.now() and reset calls_per_period") } ca.ClientResourceData.CallsPerPeriod = 0 @@ -193,111 +188,3 @@ 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(accessToken, accessId, userId, name, description string, blockchainAccess, extendedMethods bool, periodDuration, maxCallsPerPeriod uint) (*ClientAccess, error) { - if userId == "" { - userId = NB_CONTROLLER_USER_ID - } else { - _, 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) - } - } - - if accessId == "" { - accessId = uuid.NewString() - } - - 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 -} - -// Share access represented as Brood resource with new holder. Mostly used to share with nodebalancer application user -func ShareAccess(accessToken, resourceId, userId, holderType string, permissions []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", userId, resourceId, holdErr) - } - - return &resourceHolderPermissions, nil -} - -// Get resource with nodebalancer access type -func GetResources(accessToken, accessId, userId 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 -} - -// Parse Brood resource to nodebalancer client access representation -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 -} diff --git a/nodebalancer/cmd/nodebalancer/configs.go b/nodebalancer/cmd/nodebalancer/configs.go index c6beac3f..d3991328 100644 --- a/nodebalancer/cmd/nodebalancer/configs.go +++ b/nodebalancer/cmd/nodebalancer/configs.go @@ -23,25 +23,20 @@ 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") CORS_WHITELIST_MAP = make(map[string]bool) - NB_ENABLE_DEBUG = false - NB_CONNECTION_RETRIES = 2 NB_CONNECTION_RETRIES_INTERVAL = time.Millisecond * 10 NB_HEALTH_CHECK_INTERVAL = os.Getenv("NB_HEALTH_CHECK_INTERVAL") @@ -69,15 +64,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 nil, fmt.Errorf("unable to parse environment variable as integer: %v", err) + return bugout.BugoutClient{}, fmt.Errorf("unable to parse environment variable as integer: %v", err) } NB_BUGOUT_TIMEOUT_SECONDS := time.Duration(bugoutTimeoutSeconds) * time.Second - bugoutClient := bugout.ClientBrood(BUGOUT_BROOD_URL, NB_BUGOUT_TIMEOUT_SECONDS) - return &bugoutClient, nil + broodClient := bugout.ClientBrood(BUGOUT_BROOD_URL, NB_BUGOUT_TIMEOUT_SECONDS) + return broodClient, nil } func CheckEnvVarSet() { diff --git a/nodebalancer/cmd/nodebalancer/main.go b/nodebalancer/cmd/nodebalancer/main.go index c6dad82c..cee85c6c 100644 --- a/nodebalancer/cmd/nodebalancer/main.go +++ b/nodebalancer/cmd/nodebalancer/main.go @@ -1,13 +1,5 @@ package main -import ( - "log" - "os" -) - func main() { - app := NodebalancerAppCli() - if err := app.Run(os.Args); err != nil { - log.Fatal(err) - } + cli() } diff --git a/nodebalancer/cmd/nodebalancer/middleware.go b/nodebalancer/cmd/nodebalancer/middleware.go index 1df8cdec..14881312 100644 --- a/nodebalancer/cmd/nodebalancer/middleware.go +++ b/nodebalancer/cmd/nodebalancer/middleware.go @@ -236,12 +236,50 @@ 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 - // TODO(kompotkot): Not working because of permissions models changed at Brood layer - return nil, fmt.Errorf("unsupported authentication method") + 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") } - } 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") @@ -441,7 +479,7 @@ func logMiddleware(next http.Handler) http.Handler { } } - if NB_ENABLE_DEBUG { + if stateCLI.enableDebugFlag { if r.URL.RawQuery != "" { logStr += fmt.Sprintf(" %s", r.URL.RawQuery) } @@ -488,14 +526,14 @@ func accessMiddleware(next http.Handler) http.Handler { // If access id does not belong to internal crawlers, then check cache or find it in Bugout resources if accessID != "" && accessID == NB_CONTROLLER_ACCESS_ID { - if NB_ENABLE_DEBUG { + if stateCLI.enableDebugFlag { log.Printf("Access ID belongs to internal usage for user with ID %s", currentClientAccess.ClientResourceData.UserID) } currentClientAccess = internalUsageAccess currentClientAccess.LastAccessTs = tsNow currentClientAccess.requestedDataSource = requestedDataSource } else if accessID != "" && accessCache.isAccessIdInCache(accessID) { - if NB_ENABLE_DEBUG { + if stateCLI.enableDebugFlag { log.Printf("Access ID found in cache for user with ID %s", currentClientAccess.ClientResourceData.UserID) } currentClientAccess = *accessCache.accessIds[accessID] @@ -507,7 +545,7 @@ func accessMiddleware(next http.Handler) http.Handler { currentClientAccess.requestedDataSource = requestedDataSource accessCache.UpdateAccessAtCache(accessID, authorizationToken, requestedDataSource, tsNow) } else if accessID == "" && accessCache.isAuthorizationTokenInCache(authorizationToken) { - if NB_ENABLE_DEBUG { + if stateCLI.enableDebugFlag { log.Printf("Client connected with Authorization token") } currentClientAccess = *accessCache.authorizationTokens[authorizationToken] @@ -519,7 +557,7 @@ func accessMiddleware(next http.Handler) http.Handler { currentClientAccess.requestedDataSource = requestedDataSource accessCache.UpdateAccessAtCache(accessID, authorizationToken, requestedDataSource, tsNow) } else { - if NB_ENABLE_DEBUG { + if stateCLI.enableDebugFlag { log.Printf("No access identity found in cache, looking at Brood resources") } @@ -543,7 +581,7 @@ func accessMiddleware(next http.Handler) http.Handler { if authorizationToken != "" && accessCache.isAccessIdInCache(currentClientAccess.ClientResourceData.AccessID) { accessCache.authorizationTokens[authorizationToken] = accessCache.accessIds[currentClientAccess.ClientResourceData.AccessID] } else { - if NB_ENABLE_DEBUG { + if stateCLI.enableDebugFlag { log.Printf("Adding new access identifier in cache") } err := accessCache.AddAccessToCache(currentClientAccess, tsNow) diff --git a/nodebalancer/cmd/nodebalancer/server.go b/nodebalancer/cmd/nodebalancer/server.go index 106f85bd..7dee1aeb 100644 --- a/nodebalancer/cmd/nodebalancer/server.go +++ b/nodebalancer/cmd/nodebalancer/server.go @@ -5,11 +5,13 @@ package main import ( "context" + "encoding/json" "fmt" "log" "net/http" "net/http/httputil" "net/url" + "os" "strconv" "strings" "time" @@ -105,7 +107,7 @@ func proxyErrorHandler(proxy *httputil.ReverseProxy, url *url.URL) { } } -func Server(configPath, listeningHostAddr, listeningPort string, enableHealthCheck bool) error { +func Server() { // Create Access ID cache CreateAccessCache() @@ -115,26 +117,47 @@ func Server(configPath, listeningHostAddr, listeningPort string, enableHealthChe consent := humbug.CreateHumbugConsent(humbug.True) reporter, err = humbug.CreateHumbugReporter(consent, "moonstream-node-balancer", sessionID, HUMBUG_REPORTER_NB_TOKEN) if err != nil { - return fmt.Errorf("invalid Humbug Crash configuration, err: %v", err) + fmt.Printf("Invalid Humbug Crash configuration, err: %v\n", err) + os.Exit(1) } // Record system information reporter.Publish(humbug.SystemReport()) // Fetch access id for internal usage (crawlers, infrastructure, etc) - resources, getErr := GetResources(NB_CONTROLLER_TOKEN, NB_CONTROLLER_ACCESS_ID, "") - if getErr != nil { - return fmt.Errorf("unable to get user with provided access identifier, err: %v", getErr) + resources, err := bugoutClient.Brood.GetResources( + NB_CONTROLLER_TOKEN, + MOONSTREAM_APPLICATION_ID, + map[string]string{"access_id": NB_CONTROLLER_ACCESS_ID}, + ) + if err != nil { + fmt.Printf("Unable to get user with provided access identifier, err: %v\n", err) + os.Exit(1) } if len(resources.Resources) == 1 { - clientAccess, parseErr := ParseResourceDataToClientAccess(resources.Resources[0]) - if parseErr != nil { - return parseErr + resourceData, err := json.Marshal(resources.Resources[0].ResourceData) + if err != nil { + fmt.Printf("Unable to encode resource data interface to json, err: %v\n", err) + os.Exit(1) + } + var clientResourceData ClientResourceData + err = json.Unmarshal(resourceData, &clientResourceData) + if err != nil { + fmt.Printf("Unable to decode resource data json to structure, err: %v\n", err) + os.Exit(1) + } + internalUsageAccess = ClientAccess{ + ClientResourceData: ClientResourceData{ + UserID: clientResourceData.UserID, + AccessID: clientResourceData.AccessID, + Name: clientResourceData.Name, + Description: clientResourceData.Description, + BlockchainAccess: clientResourceData.BlockchainAccess, + ExtendedMethods: clientResourceData.ExtendedMethods, + }, } - internalUsageAccess = *clientAccess - log.Printf( "Internal crawlers access set, resource id: %s, blockchain access: %t, extended methods: %t", - resources.Resources[0].Id, internalUsageAccess.ClientResourceData.BlockchainAccess, internalUsageAccess.ClientResourceData.ExtendedMethods, + resources.Resources[0].Id, clientResourceData.BlockchainAccess, clientResourceData.ExtendedMethods, ) } else if len(resources.Resources) == 0 { @@ -150,13 +173,15 @@ func Server(configPath, listeningHostAddr, listeningPort string, enableHealthChe } fmt.Printf("There are no provided NB_CONTROLLER_ACCESS_ID records in Brood resources. Using provided with environment variable or randomly generated\n") } else { - return fmt.Errorf("user with provided access identifier has wrong number of resources: %d\n", len(resources.Resources)) + fmt.Printf("User with provided access identifier has wrong number of resources: %d\n", len(resources.Resources)) + os.Exit(1) } // Fill NodeConfigList with initial nodes from environment variables - err = LoadConfig(configPath) + err = LoadConfig(stateCLI.configPathFlag) if err != nil { - return err + fmt.Println(err) + os.Exit(1) } supportedBlockchains = make(map[string]bool) @@ -164,7 +189,8 @@ func Server(configPath, listeningHostAddr, listeningPort string, enableHealthChe for i, nodeConfig := range nodeConfigs { endpoint, err := url.Parse(nodeConfig.Endpoint) if err != nil { - return err + fmt.Println(err) + os.Exit(1) } // Append to supported blockchain set @@ -225,7 +251,7 @@ func Server(configPath, listeningHostAddr, listeningPort string, enableHealthChe commonHandler = panicMiddleware(commonHandler) server := http.Server{ - Addr: fmt.Sprintf("%s:%s", listeningHostAddr, listeningPort), + Addr: fmt.Sprintf("%s:%s", stateCLI.listeningAddrFlag, stateCLI.listeningPortFlag), Handler: commonHandler, ReadTimeout: 40 * time.Second, WriteTimeout: 40 * time.Second, @@ -233,18 +259,17 @@ func Server(configPath, listeningHostAddr, listeningPort string, enableHealthChe // Start node health checking and current block fetching blockchainPool.HealthCheck() - if enableHealthCheck { - go initHealthCheck(NB_ENABLE_DEBUG) + if stateCLI.enableHealthCheckFlag { + go initHealthCheck(stateCLI.enableDebugFlag) } // Start access id cache cleaning - go initCacheCleaning(NB_ENABLE_DEBUG) + go initCacheCleaning(stateCLI.enableDebugFlag) - log.Printf("Starting node load balancer HTTP server at %s:%s", listeningHostAddr, listeningPort) + log.Printf("Starting node load balancer HTTP server at %s:%s", stateCLI.listeningAddrFlag, stateCLI.listeningPortFlag) err = server.ListenAndServe() if err != nil { - return fmt.Errorf("failed to start server listener, err: %v", err) + fmt.Printf("Failed to start server listener, err: %v\n", err) + os.Exit(1) } - - return nil } diff --git a/nodebalancer/cmd/nodebalancer/version.go b/nodebalancer/cmd/nodebalancer/version.go index 41799620..5b04a011 100644 --- a/nodebalancer/cmd/nodebalancer/version.go +++ b/nodebalancer/cmd/nodebalancer/version.go @@ -1,3 +1,3 @@ package main -var NB_VERSION = "0.2.8" +var NB_VERSION = "0.2.7" diff --git a/nodebalancer/deploy/nodebalancer.service b/nodebalancer/deploy/nodebalancer.service index 3a3c691b..e353ec58 100644 --- a/nodebalancer/deploy/nodebalancer.service +++ b/nodebalancer/deploy/nodebalancer.service @@ -10,10 +10,10 @@ EnvironmentFile=/home/ubuntu/nodebalancer-secrets/app.env Restart=on-failure RestartSec=15s ExecStart=/home/ubuntu/api/nodebalancer/nodebalancer server \ - --host "${AWS_LOCAL_IPV4}" \ - --port 8544 \ - --healthcheck \ - --config /home/ubuntu/.nodebalancer/config.json + -host "${AWS_LOCAL_IPV4}" \ + -port 8544 \ + -healthcheck \ + -config /home/ubuntu/.nodebalancer/config.json SyslogIdentifier=nodebalancer [Install] diff --git a/nodebalancer/go.mod b/nodebalancer/go.mod index f1046536..5726eb78 100644 --- a/nodebalancer/go.mod +++ b/nodebalancer/go.mod @@ -3,14 +3,7 @@ module github.com/bugout-dev/moonstream/nodes/node_balancer go 1.17 require ( - github.com/bugout-dev/bugout-go v0.4.6 - github.com/bugout-dev/humbug/go v0.0.0-20230713220619-2cd74a2b36d7 - github.com/google/uuid v1.6.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 + 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 ) diff --git a/nodebalancer/go.sum b/nodebalancer/go.sum index 22ab4ee7..b8d5c645 100644 --- a/nodebalancer/go.sum +++ b/nodebalancer/go.sum @@ -12,7 +12,6 @@ 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= @@ -24,10 +23,10 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24 github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= -github.com/bugout-dev/bugout-go v0.4.6 h1:HaXoVNVZYqd6BaPwlQGhWKBYdGc2lhF3BRxIgyL+1SY= -github.com/bugout-dev/bugout-go v0.4.6/go.mod h1:P4+788iHtt/32u2wIaRTaiXTWpvSVBYxZ01qQ8N7eB8= -github.com/bugout-dev/humbug/go v0.0.0-20230713220619-2cd74a2b36d7 h1:Mn6t3HO056/++m5UESl/06FdSxz84S1p7pfQA+NZwVo= -github.com/bugout-dev/humbug/go v0.0.0-20230713220619-2cd74a2b36d7/go.mod h1:U/NXHfc3tzGeQz+xVfpifXdPZi7p6VV8xdP/4ZKeWJU= +github.com/bugout-dev/bugout-go v0.4.3 h1:sTwMgNDZR8mK0BkPVfXIsFWZAkL8ePKr5Xmj35A2O3o= +github.com/bugout-dev/bugout-go v0.4.3/go.mod h1:P4+788iHtt/32u2wIaRTaiXTWpvSVBYxZ01qQ8N7eB8= +github.com/bugout-dev/humbug/go v0.0.0-20211206230955-57607cd2d205 h1:UQ7XGjvoOVKGRIuTFXgqGtU/UgMOk8+ikpoHWrWefjQ= +github.com/bugout-dev/humbug/go v0.0.0-20211206230955-57607cd2d205/go.mod h1:U/NXHfc3tzGeQz+xVfpifXdPZi7p6VV8xdP/4ZKeWJU= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= @@ -36,8 +35,6 @@ 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= @@ -68,8 +65,8 @@ github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXi github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= -github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= @@ -145,8 +142,6 @@ 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= @@ -168,11 +163,7 @@ 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= @@ -291,7 +282,6 @@ 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= diff --git a/nodebalancer/sample.env b/nodebalancer/sample.env index efea6003..d6458c49 100644 --- a/nodebalancer/sample.env +++ b/nodebalancer/sample.env @@ -3,9 +3,8 @@ export BUGOUT_BROOD_URL="https://auth.bugout.dev" export NB_BUGOUT_TIMEOUT_SECONDS=15 export MOONSTREAM_APPLICATION_ID="" export MOONSTREAM_CORS_ALLOWED_ORIGINS="http://localhost:3000,https://moonstream.to,https://portal.moonstream.to" -export NB_CONTROLLER_USER_ID="" -export NB_CONTROLLER_TOKEN="" -export NB_CONTROLLER_ACCESS_ID="" +export NB_CONTROLLER_TOKEN="" +export NB_CONTROLLER_ACCESS_ID="" # Error humbug reporter export HUMBUG_REPORTER_NODE_BALANCER_TOKEN=""