kopia lustrzana https://github.com/bugout-dev/moonstream
cli to work with nodebalancer users access
rodzic
ae3dfa1449
commit
abd570b6a0
|
@ -11,10 +11,36 @@ go build -o nodebalancer
|
|||
|
||||
# Work with nodebalancer
|
||||
|
||||
## clients
|
||||
## add-access
|
||||
|
||||
Add new access for user:
|
||||
|
||||
```bash
|
||||
nodebalancer clients | jq .
|
||||
nodebalancer add-access \
|
||||
--user-id "<user_uuid>" \
|
||||
--access-id "<access_uuid>" \
|
||||
--name "Access name" \
|
||||
--description "Description of access" \
|
||||
--extended-methods false \
|
||||
--blockchain--access true
|
||||
```
|
||||
|
||||
## delete-access
|
||||
|
||||
Delete user access:
|
||||
|
||||
```bash
|
||||
nodebalancer delete-access \
|
||||
--user-id "<user_uuid>" \
|
||||
--access-id "<access_uuid>"
|
||||
```
|
||||
|
||||
If `access-id` not specified, all user accesses will be deleted.
|
||||
|
||||
## users
|
||||
|
||||
```bash
|
||||
nodebalancer users | jq .
|
||||
```
|
||||
|
||||
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`).
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
|
@ -59,10 +60,12 @@ func InitBugoutClient() {
|
|||
|
||||
// Get Bugout user
|
||||
func (bc *BugoutClient) GetUser(token string) (BugoutUserResponse, error) {
|
||||
var userResponse BugoutUserResponse
|
||||
|
||||
url := fmt.Sprintf("%s/user", configs.BUGOUT_AUTH_URL)
|
||||
req, err := http.NewRequest("GET", url, nil)
|
||||
if err != nil {
|
||||
return BugoutUserResponse{}, err
|
||||
return userResponse, err
|
||||
}
|
||||
|
||||
req.Header = http.Header{
|
||||
|
@ -70,27 +73,109 @@ func (bc *BugoutClient) GetUser(token string) (BugoutUserResponse, error) {
|
|||
}
|
||||
resp, err := bc.Client.Do(req)
|
||||
if err != nil {
|
||||
return BugoutUserResponse{}, err
|
||||
return userResponse, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
// Parse response
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return BugoutUserResponse{}, err
|
||||
return userResponse, err
|
||||
}
|
||||
var userResponse BugoutUserResponse
|
||||
err = json.Unmarshal(body, &userResponse)
|
||||
if err != nil {
|
||||
return BugoutUserResponse{}, err
|
||||
return userResponse, err
|
||||
}
|
||||
|
||||
return userResponse, nil
|
||||
}
|
||||
|
||||
// Get user accesses from Bugout resources
|
||||
func (bc *BugoutClient) GetUserAccesses(token, userID, accessID string) ([]UserAccess, error) {
|
||||
var userAccesses []UserAccess
|
||||
// Find Bugout user
|
||||
func (bc *BugoutClient) FindUser(token, userID string) (BugoutUserResponse, error) {
|
||||
var userResponse BugoutUserResponse
|
||||
|
||||
url := fmt.Sprintf("%s/user/find?user_id=%s", configs.BUGOUT_AUTH_URL, userID)
|
||||
req, err := http.NewRequest("GET", url, nil)
|
||||
if err != nil {
|
||||
return userResponse, err
|
||||
}
|
||||
|
||||
req.Header = http.Header{
|
||||
"Authorization": []string{fmt.Sprintf("Bearer %s", token)},
|
||||
}
|
||||
resp, err := bc.Client.Do(req)
|
||||
if err != nil {
|
||||
return userResponse, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
// Parse response
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return userResponse, err
|
||||
}
|
||||
err = json.Unmarshal(body, &userResponse)
|
||||
if err != nil {
|
||||
return userResponse, err
|
||||
}
|
||||
|
||||
return userResponse, nil
|
||||
}
|
||||
|
||||
func (bc *BugoutClient) AddUserAccess(token string, proposedUserAccess UserAccess) (UserAccess, error) {
|
||||
var userAccess UserAccess
|
||||
|
||||
// Check user exists
|
||||
user, err := bc.FindUser(token, proposedUserAccess.UserID)
|
||||
if err != nil {
|
||||
return userAccess, err
|
||||
}
|
||||
if user == (BugoutUserResponse{}) {
|
||||
return userAccess, fmt.Errorf("User with id %s not found", proposedUserAccess.UserID)
|
||||
}
|
||||
|
||||
resource := map[string]interface{}{
|
||||
"application_id": configs.NB_APPLICATION_ID,
|
||||
"resource_data": proposedUserAccess,
|
||||
}
|
||||
resourceJson, err := json.Marshal(resource)
|
||||
if err != nil {
|
||||
return userAccess, err
|
||||
}
|
||||
url := fmt.Sprintf("%s/resources", configs.BUGOUT_AUTH_URL)
|
||||
req, err := http.NewRequest("POST", url, bytes.NewBuffer(resourceJson))
|
||||
if err != nil {
|
||||
return userAccess, err
|
||||
}
|
||||
req.Header = http.Header{
|
||||
"Authorization": []string{fmt.Sprintf("Bearer %s", token)},
|
||||
"Content-Type": []string{"application/json"},
|
||||
}
|
||||
resp, err := bc.Client.Do(req)
|
||||
if err != nil {
|
||||
return userAccess, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
// Parse response
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return userAccess, err
|
||||
}
|
||||
var resourceResponse BugoutResourceResponse
|
||||
err = json.Unmarshal(body, &resourceResponse)
|
||||
if err != nil {
|
||||
return userAccess, err
|
||||
}
|
||||
|
||||
userAccess = resourceResponse.ResourceData
|
||||
|
||||
return userAccess, nil
|
||||
}
|
||||
|
||||
// Get Bugout resource
|
||||
func (bc *BugoutClient) GetResources(token, userID, accessID string) (BugoutResourcesResponse, error) {
|
||||
var resourcesResponse BugoutResourcesResponse
|
||||
|
||||
url := fmt.Sprintf("%s/resources?application_id=%s", configs.BUGOUT_AUTH_URL, configs.NB_APPLICATION_ID)
|
||||
if userID != "" {
|
||||
|
@ -101,31 +186,56 @@ func (bc *BugoutClient) GetUserAccesses(token, userID, accessID string) ([]UserA
|
|||
}
|
||||
req, err := http.NewRequest("GET", url, nil)
|
||||
if err != nil {
|
||||
return userAccesses, err
|
||||
return resourcesResponse, err
|
||||
}
|
||||
req.Header = http.Header{
|
||||
"Authorization": []string{fmt.Sprintf("Bearer %s", token)},
|
||||
}
|
||||
resp, err := bc.Client.Do(req)
|
||||
if err != nil {
|
||||
return userAccesses, err
|
||||
return resourcesResponse, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
// Parse response
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return userAccesses, err
|
||||
return resourcesResponse, err
|
||||
}
|
||||
var resourcesResponse BugoutResourcesResponse
|
||||
err = json.Unmarshal(body, &resourcesResponse)
|
||||
if err != nil {
|
||||
return userAccesses, err
|
||||
return resourcesResponse, err
|
||||
}
|
||||
|
||||
for _, resourceData := range resourcesResponse.Resources {
|
||||
userAccesses = append(userAccesses, resourceData.ResourceData)
|
||||
}
|
||||
|
||||
return userAccesses, nil
|
||||
return resourcesResponse, nil
|
||||
}
|
||||
|
||||
func (bc *BugoutClient) DeleteResource(token, resourceID string) (BugoutResourceResponse, error) {
|
||||
var resourceResponse BugoutResourceResponse
|
||||
|
||||
url := fmt.Sprintf("%s/resources/%s", configs.BUGOUT_AUTH_URL, resourceID)
|
||||
req, err := http.NewRequest("DELETE", url, nil)
|
||||
if err != nil {
|
||||
return resourceResponse, err
|
||||
}
|
||||
req.Header = http.Header{
|
||||
"Authorization": []string{fmt.Sprintf("Bearer %s", token)},
|
||||
}
|
||||
resp, err := bc.Client.Do(req)
|
||||
if err != nil {
|
||||
return resourceResponse, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
// Parse response
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return resourceResponse, err
|
||||
}
|
||||
err = json.Unmarshal(body, &resourceResponse)
|
||||
if err != nil {
|
||||
return resourceResponse, err
|
||||
}
|
||||
|
||||
return resourceResponse, nil
|
||||
}
|
||||
|
|
|
@ -7,6 +7,8 @@ import (
|
|||
"os"
|
||||
|
||||
"github.com/bugout-dev/moonstream/nodes/node_balancer/configs"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -15,13 +17,23 @@ var (
|
|||
|
||||
// Command Line Interface state
|
||||
type StateCLI struct {
|
||||
serverCmd *flag.FlagSet
|
||||
usersCmd *flag.FlagSet
|
||||
versionCmd *flag.FlagSet
|
||||
addAccessCmd *flag.FlagSet
|
||||
deleteAccessCmd *flag.FlagSet
|
||||
serverCmd *flag.FlagSet
|
||||
usersCmd *flag.FlagSet
|
||||
versionCmd *flag.FlagSet
|
||||
|
||||
// Common flags
|
||||
helpFlag bool
|
||||
|
||||
// Add user access flags
|
||||
userIDFlag string
|
||||
accessIDFlag string
|
||||
accessNameFlag string
|
||||
accessDescriptionFlag string
|
||||
blockchainAccessFlag bool
|
||||
extendedMethodsFlag bool
|
||||
|
||||
// Server flags
|
||||
listeningAddrFlag string
|
||||
listeningPortFlag string
|
||||
|
@ -30,50 +42,96 @@ type StateCLI struct {
|
|||
}
|
||||
|
||||
func (s *StateCLI) usage() {
|
||||
usage := fmt.Sprintf(`usage: nodebalancer [-h] {%[1]s,%[2]s,%[3]s} ...
|
||||
fmt.Printf(`usage: nodebalancer [-h] {%[1]s,%[2]s,%[3]s,%[4]s,%[5]s} ...
|
||||
|
||||
Moonstream node balancer CLI
|
||||
|
||||
optional arguments:
|
||||
-h, --help show this help message and exit
|
||||
-h, --help show this help message and exit
|
||||
|
||||
subcommands:
|
||||
{%[1]s,%[2]s,%[3]s}
|
||||
`, s.serverCmd.Name(), s.usersCmd.Name(), s.versionCmd.Name())
|
||||
|
||||
fmt.Println(usage)
|
||||
{%[1]s,%[2]s,%[3]s,%[4]s,%[5]s}
|
||||
`, s.addAccessCmd.Name(), s.deleteAccessCmd.Name(), s.serverCmd.Name(), s.usersCmd.Name(), s.versionCmd.Name())
|
||||
}
|
||||
|
||||
func (s *StateCLI) checkRequirements() {
|
||||
if s.helpFlag {
|
||||
switch {
|
||||
case s.addAccessCmd.Parsed():
|
||||
fmt.Println("add new user access token")
|
||||
s.addAccessCmd.PrintDefaults()
|
||||
os.Exit(0)
|
||||
case s.deleteAccessCmd.Parsed():
|
||||
fmt.Println("delete user access token")
|
||||
s.deleteAccessCmd.PrintDefaults()
|
||||
os.Exit(0)
|
||||
case s.serverCmd.Parsed():
|
||||
fmt.Println("start nodebalancer server")
|
||||
s.serverCmd.PrintDefaults()
|
||||
return
|
||||
os.Exit(0)
|
||||
case s.usersCmd.Parsed():
|
||||
fmt.Println("list user access tokens")
|
||||
s.usersCmd.PrintDefaults()
|
||||
return
|
||||
os.Exit(0)
|
||||
case s.versionCmd.Parsed():
|
||||
fmt.Println("show version")
|
||||
s.versionCmd.PrintDefaults()
|
||||
return
|
||||
os.Exit(0)
|
||||
default:
|
||||
s.usage()
|
||||
return
|
||||
os.Exit(0)
|
||||
}
|
||||
}
|
||||
|
||||
switch {
|
||||
case s.addAccessCmd.Parsed():
|
||||
if s.userIDFlag == "" {
|
||||
fmt.Println("User ID should be specified")
|
||||
s.addAccessCmd.PrintDefaults()
|
||||
os.Exit(1)
|
||||
}
|
||||
if s.accessIDFlag == "" {
|
||||
s.accessIDFlag = uuid.New().String()
|
||||
}
|
||||
if s.accessNameFlag == "" {
|
||||
fmt.Println("Access name should be specified")
|
||||
s.addAccessCmd.PrintDefaults()
|
||||
os.Exit(1)
|
||||
}
|
||||
case s.deleteAccessCmd.Parsed():
|
||||
if s.userIDFlag == "" && s.accessIDFlag == "" {
|
||||
fmt.Println("User or access ID flag should be specified")
|
||||
s.deleteAccessCmd.PrintDefaults()
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *StateCLI) populateCLI() {
|
||||
// Subcommands setup
|
||||
s.addAccessCmd = flag.NewFlagSet("add-access", 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.serverCmd, s.usersCmd, s.versionCmd} {
|
||||
for _, fs := range []*flag.FlagSet{s.addAccessCmd, s.deleteAccessCmd, s.serverCmd, s.usersCmd, s.versionCmd} {
|
||||
fs.BoolVar(&s.helpFlag, "help", false, "Show help message")
|
||||
}
|
||||
|
||||
// Add, delete and list user access subcommand flag pointers
|
||||
for _, fs := range []*flag.FlagSet{s.addAccessCmd, s.deleteAccessCmd, s.usersCmd} {
|
||||
fs.StringVar(&s.userIDFlag, "user-id", "", "Bugout user ID")
|
||||
fs.StringVar(&s.accessIDFlag, "access-id", "", "UUID for access identification")
|
||||
}
|
||||
|
||||
// Add user access subcommand flag pointers
|
||||
s.addAccessCmd.StringVar(&s.accessNameFlag, "name", "", "Name of access")
|
||||
s.addAccessCmd.StringVar(&s.accessDescriptionFlag, "description", "", "Description of access")
|
||||
s.addAccessCmd.BoolVar(&s.blockchainAccessFlag, "blockchain-access", false, "Provide if allow to access blockchain nodes")
|
||||
s.addAccessCmd.BoolVar(&s.extendedMethodsFlag, "extended-methods", false, "Provide to be able to execute not whitelisted methods")
|
||||
|
||||
// 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")
|
||||
|
@ -90,6 +148,57 @@ func CLI() {
|
|||
|
||||
// Parse subcommands and appropriate FlagSet
|
||||
switch os.Args[1] {
|
||||
case "add-access":
|
||||
stateCLI.addAccessCmd.Parse(os.Args[2:])
|
||||
stateCLI.checkRequirements()
|
||||
|
||||
proposedUserAccess := UserAccess{
|
||||
UserID: stateCLI.userIDFlag,
|
||||
AccessID: stateCLI.accessIDFlag,
|
||||
Name: stateCLI.accessNameFlag,
|
||||
Description: stateCLI.accessDescriptionFlag,
|
||||
BlockchainAccess: stateCLI.blockchainAccessFlag,
|
||||
ExtendedMethods: stateCLI.extendedMethodsFlag,
|
||||
}
|
||||
userAccess, err := bugoutClient.AddUserAccess(configs.NB_CONTROLLER_TOKEN, proposedUserAccess)
|
||||
if err != nil {
|
||||
fmt.Printf("Unable to create user access %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
userAccessJson, err := json.Marshal(userAccess)
|
||||
if err != nil {
|
||||
fmt.Printf("Unable to marshal user access struct %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Println(string(userAccessJson))
|
||||
|
||||
case "delete-access":
|
||||
stateCLI.deleteAccessCmd.Parse(os.Args[2:])
|
||||
stateCLI.checkRequirements()
|
||||
|
||||
resources, err := bugoutClient.GetResources(configs.NB_CONTROLLER_TOKEN, stateCLI.userIDFlag, stateCLI.accessIDFlag)
|
||||
if err != nil {
|
||||
fmt.Printf("Unable to get Bugout resources %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
var userAccesses []UserAccess
|
||||
for _, resource := range resources.Resources {
|
||||
deletedResource, err := bugoutClient.DeleteResource(configs.NB_CONTROLLER_TOKEN, resource.ID)
|
||||
if err != nil {
|
||||
fmt.Printf("Unable to delete resource with id %s %v\n", resource.ID, err)
|
||||
continue
|
||||
}
|
||||
userAccesses = append(userAccesses, deletedResource.ResourceData)
|
||||
}
|
||||
|
||||
userAccessesJson, err := json.Marshal(userAccesses)
|
||||
if err != nil {
|
||||
fmt.Printf("Unable to marshal user access struct %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Println(string(userAccessesJson))
|
||||
|
||||
case "server":
|
||||
stateCLI.serverCmd.Parse(os.Args[2:])
|
||||
stateCLI.checkRequirements()
|
||||
|
@ -100,15 +209,20 @@ func CLI() {
|
|||
stateCLI.usersCmd.Parse(os.Args[2:])
|
||||
stateCLI.checkRequirements()
|
||||
|
||||
userAccesses, err := bugoutClient.GetUserAccesses(configs.NB_CONTROLLER_TOKEN, "", "")
|
||||
resources, err := bugoutClient.GetResources(configs.NB_CONTROLLER_TOKEN, stateCLI.userIDFlag, stateCLI.accessIDFlag)
|
||||
if err != nil {
|
||||
fmt.Printf("Unable to get resources %v", err)
|
||||
return
|
||||
fmt.Printf("Unable to get Bugout resources %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
var userAccesses []UserAccess
|
||||
for _, resourceData := range resources.Resources {
|
||||
userAccesses = append(userAccesses, resourceData.ResourceData)
|
||||
}
|
||||
userAccessesJson, err := json.Marshal(userAccesses)
|
||||
if err != nil {
|
||||
fmt.Printf("Unable to marshal resources %v", err)
|
||||
return
|
||||
fmt.Printf("Unable to marshal user accesses struct %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Println(string(userAccessesJson))
|
||||
|
||||
|
|
|
@ -76,17 +76,16 @@ func accessMiddleware(next http.Handler) http.Handler {
|
|||
currentUserAccess = controllerUserAccess
|
||||
currentUserAccess.dataSource = dataSource
|
||||
} else {
|
||||
userAccesses, err := bugoutClient.GetUserAccesses(configs.NB_CONTROLLER_TOKEN, "", accessID)
|
||||
resources, err := bugoutClient.GetResources(configs.NB_CONTROLLER_TOKEN, "", accessID)
|
||||
if err != nil {
|
||||
http.Error(w, "Unable to get user with provided access identifier", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
if len(userAccesses) == 0 {
|
||||
if len(resources.Resources) == 0 {
|
||||
http.Error(w, "User with provided access identifier not found", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
userAccess := userAccesses[0]
|
||||
|
||||
userAccess := resources.Resources[0].ResourceData
|
||||
currentUserAccess = UserAccess{
|
||||
UserID: userAccess.UserID,
|
||||
AccessID: userAccess.AccessID,
|
||||
|
|
|
@ -111,11 +111,11 @@ func Server() {
|
|||
// Record system information
|
||||
reporter.Publish(humbug.SystemReport())
|
||||
|
||||
userAccesses, err := bugoutClient.GetUserAccesses(configs.NB_CONTROLLER_TOKEN, "", configs.NB_CONTROLLER_ACCESS_ID)
|
||||
resources, err := bugoutClient.GetResources(configs.NB_CONTROLLER_TOKEN, "", configs.NB_CONTROLLER_ACCESS_ID)
|
||||
if err != nil {
|
||||
fmt.Printf("Unable to access Bugout authentication server %v", err)
|
||||
}
|
||||
userAccess := userAccesses[0]
|
||||
userAccess := resources.Resources[0].ResourceData
|
||||
controllerUserAccess = UserAccess{
|
||||
UserID: userAccess.UserID,
|
||||
AccessID: userAccess.AccessID,
|
||||
|
|
Ładowanie…
Reference in New Issue