diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 039a915..318c9ce 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -18,31 +18,22 @@ builds: - -X github.com/threefoldtech/tfgrid4-sdk-go/node-registrar/cmd.version={{.Tag}} - -X github.com/threefoldtech/tfgrid-sdk-go/node-registrar/cmd.commit={{.Commit}} - - dir: ./node-registrar/tools/account + - dir: ./node-registrar/tools/registrar-cli env: - CGO_ENABLED=0 goos: - linux - windows - darwin - binary: new-account - id: new-account + binary: reg-cli + id: reg-cli ignore: - goos: windows + ldflags: + - -X github.com/threefoldtech/tfgrid4-sdk-go/node-registrar/cmd.version={{.Tag}} + - -X github.com/threefoldtech/tfgrid-sdk-go/node-registrar/cmd.commit={{.Commit}} - - dir: ./node-registrar/tools/farm - env: - - CGO_ENABLED=0 - goos: - - linux - - windows - - darwin - binary: new-farm - id: new-farm - - ignore: - - goos: windows archives: diff --git a/go.work b/go.work index 179b9fc..36366c9 100644 --- a/go.work +++ b/go.work @@ -1,4 +1,6 @@ go 1.23.0 -use ./node-registrar -use ./rmb-sdk-go +use ( + ./node-registrar + ./registrar-cli +) diff --git a/go.work.sum b/go.work.sum index 59865b4..cdaf55e 100644 --- a/go.work.sum +++ b/go.work.sum @@ -106,19 +106,26 @@ golang.org/x/exp v0.0.0-20230206171751-46f607a40771/go.mod h1:CxIveKay+FTh1D0yPZ golang.org/x/image v0.25.0/go.mod h1:tCAmOEGthTtkalusGp1g3xa2gke8J6c2N565dTyl9Rs= golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= +golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= -golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= +golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= -golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= -golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= +golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= +golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM= +golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= +golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw= golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= golang.org/x/telemetry v0.0.0-20240521205824-bda55230c457/go.mod h1:pRgIJT+bRLFKnoM1ldnzKoxTIn14Yxz928LQRYYgIN0= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= @@ -126,15 +133,20 @@ golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M= golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= golang.org/x/time v0.0.0-20220922220347-f3bd1da661af/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= +golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA= +golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c= golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ= golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0= golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= diff --git a/node-registrar/tools/farm/README.md b/node-registrar/tools/farm/README.md index 55a1765..5cf7147 100644 --- a/node-registrar/tools/farm/README.md +++ b/node-registrar/tools/farm/README.md @@ -1,38 +1,49 @@ # New Farm Tool ## Overview + This tool allows users to create a farm account on a specified network. ## Installation + 1. Clone the repository: + ```sh git clone https://github.com/threefoldtech/tfgrid4-sdk-go ``` + 2. Navigate to the project directory: + ```sh cd tfgrid4-sdk-go/node-registrar/tools/farm ``` + 3. Build the application: + ```sh go build -o new-farm main.go ``` ## Usage + ```sh -./new-farm -seed -network -farm_name +./new-farm -seed -network -farm-name ``` ### Parameters + - `-seed` (required): A hexadecimal string used as a private key seed. - `-network` (required): Specifies the network (`dev`, `qa`, `test`, `main`). -- `-farm_name` (required): The name of the farm to create. +- `-farm-name` (required): The name of the farm to create. ### Example Usage + ```sh -./new-farm -seed aabbccddeeff00112233445566778899aabbccddeeff00112233445566778899 -network dev -farm_name MyFarm +./new-farm -seed aabbccddeeff00112233445566778899aabbccddeeff00112233445566778899 -network dev -farm-name MyFarm ``` + The `FarmID` (e.g., `11`) is returned upon successful farm creation. ## Next Step -Once this is done, you can create a V4 bootstrap image using the V4 Zero-OS Boot Generator: https://v4.bootstrap.grid.tf/. \ No newline at end of file +Once this is done, you can create a V4 bootstrap image using the V4 Zero-OS Boot Generator: . diff --git a/node-registrar/tools/farm/main.go b/node-registrar/tools/farm/main.go index 15a1eab..fedc747 100644 --- a/node-registrar/tools/farm/main.go +++ b/node-registrar/tools/farm/main.go @@ -29,7 +29,7 @@ func main() { flag.StringVar(&seed, "seed", "", "seed") flag.StringVar(&network, "network", "", "network (dev, qa, test, main)") - flag.StringVar(&name, "farm_name", "", "farm name") + flag.StringVar(&name, "farm-name", "", "farm name") flag.Parse() u, ok := urls[network] diff --git a/registrar-cli/LICENSE b/registrar-cli/LICENSE new file mode 100644 index 0000000..e69de29 diff --git a/registrar-cli/Makefile b/registrar-cli/Makefile new file mode 100644 index 0000000..a5bdaaf --- /dev/null +++ b/registrar-cli/Makefile @@ -0,0 +1,36 @@ +PWD := $(shell pwd) +GOPATH := $(shell go env GOPATH) + +all: verifiers test + +test: + @echo "Running Tests" + go test -v ./... + +coverage: clean + @echo "Installing gopherbadger" && go get -u github.com/jpoles1/gopherbadger && go install github.com/jpoles1/gopherbadger + mkdir coverage + go test -v -vet=off ./... -coverprofile=coverage/coverage.out + go tool cover -html=coverage/coverage.out -o coverage/coverage.html + @${GOPATH}/bin/gopherbadger -png=false -md="README.md" + rm coverage.out + go mod tidy + +clean: + rm ./coverage -rf + rm ./bin -rf + +getverifiers: + @echo "Installing golangci-lint" && go install github.com/golangci/golangci-lint/cmd/golangci-lint + go mod tidy + +lint: + @echo "Running $@" + golangci-lint run -c ../.golangci.yml + +build: + @echo "Running $@" + @go build -ldflags=\ + "-X 'github.com/threefoldtech/tfgrid4-sdk-go/node-registrar/tools/registrar-cli/cmd.commit=$(shell git rev-parse HEAD)'\ + -X 'github.com/threefoldtech/tfgrid4-sdk-go/node-registrar/tools/registrar-cli/cmd.version=$(shell git tag --sort=-version:refname | head -n 1)'"\ + -o bin/registrar-cli main.go diff --git a/registrar-cli/README.md b/registrar-cli/README.md new file mode 100644 index 0000000..b2c51bb --- /dev/null +++ b/registrar-cli/README.md @@ -0,0 +1,196 @@ +# New Farm Tool + +## Overview + +This tool allows users to create/get/update farm/account/node on a specified network. + +## Installation + +1. Clone the repository: + + ```sh + git clone https://github.com/threefoldtech/tfgrid4-sdk-go + ``` + +2. Navigate to the project directory: + + ```sh + cd tfgrid4-sdk-go/registrar-cli/ + ``` + +3. Build the application: + + ```sh + go build -o registrar-cli main.go + ``` + +## Usage + +## Account Command + +Account command represents events on account on Threefold grid4 + +### Create New Account + +**Flags**: + +- `--network` (required): Specifies the network (`dev`, `qa`, `test`, `main`). +- `--mnemonic` (optional): create an account of a mnemonic. +- `--relays` (optional): relays urls. +- `--rmb-enc-key` (optional): rmb encryption key. + +**Example Usage**: + +```sh +➜ ./registrar-cli account create --network local +1:07PM INF new account is created with mnemonic mnemonic="pyramid cattle mutual brush green east slam lava source stereo rigid able" +1:07PM INF account is created successfully twinID=4 +``` + +### Get Account + +**Flags**: + +- `--network` (required): Specifies the network (`dev`, `qa`, `test`, `main`). +- `--twin-id` (optional): twin id of the account needed to be loaded. +- `--public-key` (optional): public key of the account needed to be loaded. + +**Example Usage**: + +```sh +➜ ./registrar-cli account get --network dev --twin-id 33 +5:00PM INF account={"public_key":"w5TYTeB/rCskd1iNrOKaFlpGn+Cp28gFZobTNABUv50=","relays":[],"rmb_enc_key":"","twin_id":33} +➜ +➜ ./registrar-cli account get --network dev --public-key +5:01PM INF account={"public_key":"w5TYTeB/rCskd1iNrOKaFlpGn+Cp28gFZobTNABUv50=","relays":[],"rmb_enc_key":"","twin_id":33} +``` + +### Update Account + +**Flags**: + +- `--network` (required): Specifies the network (`dev`, `qa`, `test`, `main`). +- `--mnemonic` (required): Account mnemonic. +- `--relays` (optional): new relays urls. +- `--rmb-enc-key` (optional): new rmb encryption key. + +**Example Usage**: + +```sh +➜ ./registrar-cli account update --network dev --mnemonic --relays wss://relay.dev.grid.tf +5:02PM INF account is updated successfully +➜ +➜ ./registrar-cli account get --network dev --twin-id 33 +5:02PM INF account={"public_key":"w5TYTeB/rCskd1iNrOKaFlpGn+Cp28gFZobTNABUv50=","relays":["wss://relay.dev.grid.tf"],"rmb_enc_key":"","twin_id":33} +``` + +## Farm Command + +Farm command represents events on farms on Threefold grid4 + +### Create New Farm + +**Flags**: + +- `--farm-name` (required): The name of the farm to create. +- `--network` (required): Specifies the network (`dev`, `qa`, `test`, `main`). +- `--mnemonic` (required): Account mnemonic. +- `--dedicated` (optional default: false): is the farm dedicated. + +**Example Usage**: + +```sh +➜ ./registrar-cli farm create --farm-name testFarm1 --mnemonic --network dev +5:03PM INF farm is created successfully farmID=12 +``` + +### Get Farm + +**Flags**: + +- `--network` (required): Specifies the network (`dev`, `qa`, `test`, `main`). +- `--farm-id` (optional): id of the farm needed to be loaded. + +**Example Usage**: + +```sh +➜ ./registrar-cli farm get --farm-id 12 --network dev +5:03PM INF farm={"dedicated":false,"farm_id":12,"farm_name":"testFarm1","twin_id":33} +``` + +### Update Farm + +**Flags**: + +- `--network` (required): Specifies the network (`dev`, `qa`, `test`, `main`). +- `--mnemonic` (required): Account mnemonic. +- `--farm-id` (optional): id of the farm needed to be loaded. +- `--farm-name` (optional): The new name of the farm. +- `--dedicated` (optional): update the farm to dedicated. + +**Example Usage**: + +```sh +➜ ./registrar-cli farm update --farm-name notTestFarm1 --mnemonic --network dev --farm-id 12 +5:04PM INF farm is updated successfully +➜ +➜ ./registrar-cli farm get --farm-id 12 --network dev +5:04PM INF farm={"dedicated":false,"farm_id":12,"farm_name":"notTestFarm1","twin_id":33} +``` + +## Node Command + +Node command represents events on nodes on Threefold grid4 + +### Get Node + +**Flags**: + +- `--network` (required): Specifies the network (`dev`, `qa`, `test`, `main`). +- `--node-id` (optional): id of the node needed to be loaded. +- `--twin-id` (optional): twin id of the node needed to be loaded. + +**Example Usage**: + +```sh +➜ ./registrar-cli node get --network dev --node-id 1 +12:36PM INF node={"Approved":false,"farm_id":4,"interfaces":[{"ips":"192.168.123.22","mac":"54:fe:9a:b0:73:61","name":"zos"}],"location":{"city":"Cairo","country":"Egypt","latitude":"30.0588","longitude":"31.2268"},"node_id":1,"resources":{"cru":4,"hru":1073741824000,"mru":6230032384,"sru":1610612736000},"secure_boot":false,"serial_number":"Not Specified","twin_id":5,"uptime":null,"virtualized":true} +➜ +➜ ./registrar-cli node get --network dev --twin-id 5 +12:36PM INF node={"Approved":false,"farm_id":4,"interfaces":[{"ips":"192.168.123.22","mac":"54:fe:9a:b0:73:61","name":"zos"}],"location":{"city":"Cairo","country":"Egypt","latitude":"30.0588","longitude":"31.2268"},"node_id":1,"resources":{"cru":4,"hru":1073741824000,"mru":6230032384,"sru":1610612736000},"secure_boot":false,"serial_number":"Not Specified","twin_id":5,"uptime":null,"virtualized":true} +``` + +## Zos Version Command + +Zos Version command represents events on zos version on Threefold grid4 + +### Get Zos Version + +**Flags**: + +- `--network` (required): Specifies the network (`dev`, `qa`, `test`, `main`). + +**Example Usage**: + +```sh +➜ ./registrar-cli zos-version get --network dev +12:40PM INF zosVersion={"safe_to_upgrade":true,"version":"v0.1.8"} +``` + +### Update Zos Version + +**Flags**: + +- `--network` (required): Specifies the network (`dev`, `qa`, `test`, `main`). +- `--version` (required): new zos version to be set on specific network (`v0.1.x`) +- `--safe-to-upgrade` (required): if this version is safe to upgrade + +**Example Usage**: + +```sh +➜ ./registrar-cli zos-version update --network dev --version v0.1.8 --safe-to-upgrade --mnemonic +5:07PM INF zos version is updated successfully +➜ +➜ ./registrar-cli zos-version get --network dev +5:07PM INF zosVersion={"safe_to_upgrade":true,"version":"v0.1.8"} +``` diff --git a/registrar-cli/cmd/account.go b/registrar-cli/cmd/account.go new file mode 100644 index 0000000..f3034a7 --- /dev/null +++ b/registrar-cli/cmd/account.go @@ -0,0 +1,16 @@ +// Package cmd for parsing command line arguments +package cmd + +import ( + "github.com/spf13/cobra" +) + +// accountCmd represents the account command +var accountCmd = &cobra.Command{ + Use: "account", + Short: "account command represents events on account on Threefold grid4", +} + +func init() { + rootCmd.AddCommand(accountCmd) +} diff --git a/registrar-cli/cmd/account_create.go b/registrar-cli/cmd/account_create.go new file mode 100644 index 0000000..7ba7e68 --- /dev/null +++ b/registrar-cli/cmd/account_create.go @@ -0,0 +1,51 @@ +// Package cmd for parsing command line arguments +package cmd + +import ( + "github.com/pkg/errors" + "github.com/rs/zerolog/log" + "github.com/spf13/cobra" + "github.com/threefoldtech/tfgrid4-sdk-go/registrar-cli/internal/cmd" +) + +// accountCreateCmd represents the account create command +var accountCreateCmd = &cobra.Command{ + Use: "create", + Short: "create new account in node registrar", + RunE: func(cobraCmd *cobra.Command, args []string) error { + mnemonic, err := cobraCmd.Flags().GetString("mnemonic") + if err != nil { + return errors.Wrap(err, "failed to get mnemonic flag") + } + + network, err := cobraCmd.Flags().GetString("network") + if err != nil { + return errors.Wrap(err, "failed to get network flag") + } + + relays, err := cobraCmd.Flags().GetStringArray("relays") + if err != nil { + return err + } + + rmbEncKey, err := cobraCmd.Flags().GetString("rmb-enc-key") + if err != nil { + return err + } + + account, mnemonic, err := cmd.CreateAccount(network, relays, rmbEncKey, mnemonic) + if err != nil { + return errors.Wrap(err, "failed to create account") + } + log.Info().Str("mnemonic", mnemonic).Msg("new account is created with mnemonic") + log.Info().Uint64("twinID", account.TwinID).Msg("account is created successfully") + return nil + }, +} + +func init() { + accountCmd.AddCommand(accountCreateCmd) + accountCreateCmd.Flags().StringP("mnemonic", "m", "", "account mnemonic") + accountCreateCmd.Flags().StringArrayP("relays", "r", nil, "relays urls") + accountCreateCmd.Flags().StringP("rmb-enc-key", "k", "", "rmb encryption key") +} diff --git a/registrar-cli/cmd/account_get.go b/registrar-cli/cmd/account_get.go new file mode 100644 index 0000000..f004875 --- /dev/null +++ b/registrar-cli/cmd/account_get.go @@ -0,0 +1,46 @@ +// Package cmd for parsing command line arguments +package cmd + +import ( + "github.com/pkg/errors" + "github.com/rs/zerolog/log" + "github.com/spf13/cobra" + "github.com/threefoldtech/tfgrid4-sdk-go/registrar-cli/internal/cmd" +) + +// accountGetCmd represents the account get command +var accountGetCmd = &cobra.Command{ + Use: "get", + Short: "get account from node registrar", + RunE: func(cobraCmd *cobra.Command, args []string) error { + network, err := cobraCmd.Flags().GetString("network") + if err != nil { + return errors.Wrap(err, "failed to get network flag") + } + + twinID, err := cobraCmd.Flags().GetUint64("twin-id") + if err != nil { + return errors.Wrap(err, "failed to get twin-id flag") + } + + pk, err := cobraCmd.Flags().GetString("public-key") + if err != nil { + return errors.Wrap(err, "failed to get public-key flag") + } + + account, err := cmd.GetAccount(network, twinID, pk) + if err != nil { + return errors.Wrap(err, "failed to get account") + } + + log.Info().Any("account", account).Send() + return nil + }, +} + +func init() { + accountCmd.AddCommand(accountGetCmd) + accountGetCmd.Flags().Uint64P("twin-id", "i", 0, "twin id") + accountGetCmd.Flags().StringP("public-key", "k", "", "account public key") + accountGetCmd.MarkFlagsOneRequired("twin-id", "public-key") +} diff --git a/registrar-cli/cmd/account_update.go b/registrar-cli/cmd/account_update.go new file mode 100644 index 0000000..c82ad0a --- /dev/null +++ b/registrar-cli/cmd/account_update.go @@ -0,0 +1,55 @@ +// Package cmd for parsing command line arguments +package cmd + +import ( + "github.com/rs/zerolog/log" + "github.com/spf13/cobra" + "github.com/threefoldtech/tfgrid4-sdk-go/registrar-cli/internal/cmd" +) + +// accountUpdateCmd represents the account update command +var accountUpdateCmd = &cobra.Command{ + Use: "update", + Short: "update account in node registrar", + RunE: func(cobraCmd *cobra.Command, args []string) error { + mnemonic, err := cobraCmd.Flags().GetString("mnemonic") + if err != nil { + return err + } + + network, err := cobraCmd.Flags().GetString("network") + if err != nil { + return err + } + + relays, err := cobraCmd.Flags().GetStringArray("relays") + if err != nil { + return err + } + + rmbEncKey, err := cobraCmd.Flags().GetString("rmb-enc-key") + if err != nil { + return err + } + + err = cmd.UpdateAccount(mnemonic, network, relays, rmbEncKey) + if err != nil { + return err + } + + log.Info().Msg("account is updated successfully") + + return nil + }, +} + +func init() { + accountCmd.AddCommand(accountUpdateCmd) + accountUpdateCmd.Flags().StringP("mnemonic", "m", "", "account mnemonic") + if err := accountUpdateCmd.MarkFlagRequired("mnemonic"); err != nil { + log.Fatal().Err(err).Send() + } + accountUpdateCmd.Flags().StringArrayP("relays", "r", nil, "relays urls") + accountUpdateCmd.Flags().StringP("rmb-enc-key", "k", "", "rmb encryption key") + accountUpdateCmd.MarkFlagsOneRequired("relays", "rmb-enc-key") +} diff --git a/registrar-cli/cmd/farm.go b/registrar-cli/cmd/farm.go new file mode 100644 index 0000000..cf7e38c --- /dev/null +++ b/registrar-cli/cmd/farm.go @@ -0,0 +1,16 @@ +// Package cmd for parsing command line arguments +package cmd + +import ( + "github.com/spf13/cobra" +) + +// createCmd represents the farm command +var farmCmd = &cobra.Command{ + Use: "farm", + Short: "farm command represents events on farm on Threefold grid4", +} + +func init() { + rootCmd.AddCommand(farmCmd) +} diff --git a/registrar-cli/cmd/farm_create.go b/registrar-cli/cmd/farm_create.go new file mode 100644 index 0000000..98a9bd4 --- /dev/null +++ b/registrar-cli/cmd/farm_create.go @@ -0,0 +1,72 @@ +// Package cmd for parsing command line arguments +package cmd + +import ( + "github.com/pkg/errors" + "github.com/rs/zerolog/log" + "github.com/spf13/cobra" + "github.com/threefoldtech/tfgrid4-sdk-go/registrar-cli/internal/cmd" +) + +// farmCreateCmd represents the farm create command +var farmCreateCmd = &cobra.Command{ + Use: "create", + Short: "create new farm in node registrar", + RunE: func(cobraCmd *cobra.Command, args []string) error { + mnemonic, err := cobraCmd.Flags().GetString("mnemonic") + if err != nil { + return errors.Wrap(err, "failed to get mnemonic flag") + } + + network, err := cobraCmd.Flags().GetString("network") + if err != nil { + return errors.Wrap(err, "failed to get network flag") + } + + farmName, err := cobraCmd.Flags().GetString("farm-name") + if err != nil { + return errors.Wrap(err, "failed to get farm-name flag") + } + + stellarAddress, err := cobraCmd.Flags().GetString("stellar-address") + if err != nil { + return errors.Wrap(err, "failed to get stellar-address flag") + } + + dedicated, err := cobraCmd.Flags().GetBool("dedicated") + if err != nil { + return errors.Wrap(err, "failed to get dedicated flag") + } + + // Validate required inputs + if farmName == "" { + return errors.New("farm name is required (use --farm-name flag)") + } + + if network == "" { + return errors.New("network is required (use --network flag)") + } + + if mnemonic == "" { + return errors.New("mnemonic is required (use --mnemonic flag)") + } + + farmID, err := cmd.CreateFarm(mnemonic, network, farmName, stellarAddress, dedicated) + if err != nil { + return errors.Wrap(err, "failed to create farm") + } + + log.Info().Uint64("farmID", farmID).Msg("farm is created successfully") + return nil + }, +} + +func init() { + farmCmd.AddCommand(farmCreateCmd) + farmCreateCmd.Flags().StringP("mnemonic", "m", "", "account mnemonic") + farmCreateCmd.Flags().StringP("farm-name", "f", "", "farm name") + farmCreateCmd.Flags().StringP("stellar-address", "s", "", "stellar address") + farmCreateCmd.MarkFlagsRequiredTogether("mnemonic", "farm-name", "stellar-address") + + farmCreateCmd.Flags().BoolP("dedicated", "d", false, "is farm dedicated") +} diff --git a/registrar-cli/cmd/farm_get.go b/registrar-cli/cmd/farm_get.go new file mode 100644 index 0000000..6f111bc --- /dev/null +++ b/registrar-cli/cmd/farm_get.go @@ -0,0 +1,46 @@ +// Package cmd for parsing command line arguments +package cmd + +import ( + "github.com/pkg/errors" + "github.com/rs/zerolog/log" + "github.com/spf13/cobra" + "github.com/threefoldtech/tfgrid4-sdk-go/registrar-cli/internal/cmd" +) + +// farmGetCmd represents the farm get command +var farmGetCmd = &cobra.Command{ + Use: "get", + Short: "get farm from node registrar", + RunE: func(cobraCmd *cobra.Command, args []string) error { + network, err := cobraCmd.Flags().GetString("network") + if err != nil { + return errors.Wrap(err, "failed to get network flag") + } + + farmID, err := cobraCmd.Flags().GetUint64("farm-id") + if err != nil { + return errors.Wrap(err, "failed to get farm-id flag") + } + + if farmID == 0 { + return errors.New("farm id is required (use --farm-id flag with a non-zero value)") + } + + farm, err := cmd.GetFarm(network, farmID) + if err != nil { + return errors.Wrap(err, "failed to get farm") + } + + log.Info().Any("farm", farm).Send() + return nil + }, +} + +func init() { + farmCmd.AddCommand(farmGetCmd) + farmGetCmd.Flags().Uint64P("farm-id", "i", 0, "farm id") + if err := farmGetCmd.MarkFlagRequired("farm-id"); err != nil { + log.Fatal().Err(err).Send() + } +} diff --git a/registrar-cli/cmd/farm_update.go b/registrar-cli/cmd/farm_update.go new file mode 100644 index 0000000..a31887f --- /dev/null +++ b/registrar-cli/cmd/farm_update.go @@ -0,0 +1,66 @@ +// Package cmd for parsing command line arguments +package cmd + +import ( + "github.com/pkg/errors" + "github.com/rs/zerolog/log" + "github.com/spf13/cobra" + "github.com/threefoldtech/tfgrid4-sdk-go/registrar-cli/internal/cmd" +) + +// farmUpdateCmd represents the farm update command +var farmUpdateCmd = &cobra.Command{ + Use: "update", + Short: "update farm in node registrar", + RunE: func(cobraCmd *cobra.Command, args []string) error { + mnemonic, err := cobraCmd.Flags().GetString("mnemonic") + if err != nil { + return errors.Wrap(err, "failed to get mnemonic flag") + } + + network, err := cobraCmd.Flags().GetString("network") + if err != nil { + return errors.Wrap(err, "failed to get network flag") + } + + farmID, err := cobraCmd.Flags().GetUint64("farm-id") + if err != nil { + return errors.Wrap(err, "failed to get farm-id flag") + } + + farmName, err := cobraCmd.Flags().GetString("farm-name") + if err != nil { + return errors.Wrap(err, "failed to get farm-name flag") + } + + stellarAddress, err := cobraCmd.Flags().GetString("stellar-address") + if err != nil { + return errors.Wrap(err, "failed to get stellar-address flag") + } + + dedicated, err := cobraCmd.Flags().GetBool("dedicated") + if err != nil { + return errors.Wrap(err, "failed to get dedicated flag") + } + + err = cmd.UpdateFarm(farmID, mnemonic, network, farmName, stellarAddress, dedicated) + if err != nil { + return errors.Wrap(err, "failed to update farm") + } + + log.Info().Msg("farm is updated successfully") + return nil + }, +} + +func init() { + farmCmd.AddCommand(farmUpdateCmd) + farmUpdateCmd.Flags().StringP("mnemonic", "m", "", "account mnemonic") + farmUpdateCmd.Flags().Uint64P("farm-id", "i", 0, "farm id") + farmUpdateCmd.Flags().String("farm-name", "", "new farm name") + farmUpdateCmd.MarkFlagsRequiredTogether("mnemonic", "farm-id") + + farmUpdateCmd.Flags().StringP("stellar-address", "s", "", "stellar address") + farmUpdateCmd.Flags().BoolP("dedicated", "d", false, "farm is dedicated") + farmUpdateCmd.MarkFlagsOneRequired("stellar-address", "dedicated") +} diff --git a/registrar-cli/cmd/node.go b/registrar-cli/cmd/node.go new file mode 100644 index 0000000..f5fc465 --- /dev/null +++ b/registrar-cli/cmd/node.go @@ -0,0 +1,16 @@ +// Package cmd for parsing command line arguments +package cmd + +import ( + "github.com/spf13/cobra" +) + +// nodeCmd represents the node command +var nodeCmd = &cobra.Command{ + Use: "node", + Short: "node command represents events on node on Threefold grid4", +} + +func init() { + rootCmd.AddCommand(nodeCmd) +} diff --git a/registrar-cli/cmd/node_get.go b/registrar-cli/cmd/node_get.go new file mode 100644 index 0000000..cb5a058 --- /dev/null +++ b/registrar-cli/cmd/node_get.go @@ -0,0 +1,46 @@ +// Package cmd for parsing command line arguments +package cmd + +import ( + "github.com/pkg/errors" + "github.com/rs/zerolog/log" + "github.com/spf13/cobra" + "github.com/threefoldtech/tfgrid4-sdk-go/registrar-cli/internal/cmd" +) + +// nodeGetCmd represents the node get command +var nodeGetCmd = &cobra.Command{ + Use: "get", + Short: "get node from node registrar", + RunE: func(cobraCmd *cobra.Command, args []string) error { + network, err := cobraCmd.Flags().GetString("network") + if err != nil { + return errors.Wrap(err, "failed to get network flag") + } + + nodeID, err := cobraCmd.Flags().GetUint64("node-id") + if err != nil { + return errors.Wrap(err, "failed to get node-id flag") + } + + twinID, err := cobraCmd.Flags().GetUint64("twin-id") + if err != nil { + return errors.Wrap(err, "failed to get twin-id flag") + } + + node, err := cmd.GetNode(network, nodeID, twinID) + if err != nil { + return errors.Wrap(err, "failed to get node") + } + + log.Info().Any("node", node).Send() + return nil + }, +} + +func init() { + nodeCmd.AddCommand(nodeGetCmd) + nodeGetCmd.Flags().Uint64("node-id", 0, "node id") + nodeGetCmd.Flags().Uint64("twin-id", 0, "twin id") + nodeGetCmd.MarkFlagsOneRequired("node-id", "twin-id") +} diff --git a/registrar-cli/cmd/root.go b/registrar-cli/cmd/root.go new file mode 100644 index 0000000..0c1209b --- /dev/null +++ b/registrar-cli/cmd/root.go @@ -0,0 +1,33 @@ +/* +Copyright © 2025 NAME HERE +*/ +package cmd + +import ( + "os" + + "github.com/rs/zerolog" + "github.com/rs/zerolog/log" + "github.com/spf13/cobra" +) + +// rootCmd represents the base command when called without any subcommands +var rootCmd = &cobra.Command{ + Use: "registrar-cli", + Short: "cli tool to be used to interact with node registrar", +} + +// Execute adds all child commands to the root command and sets flags appropriately. +// This is called by main.main(). It only needs to happen once to the rootCmd. +func Execute() { + err := rootCmd.Execute() + if err != nil { + log.Fatal().Err(err).Send() + } +} + +func init() { + zerolog.SetGlobalLevel(zerolog.InfoLevel) + log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr}) + rootCmd.PersistentFlags().StringP("network", "n", "", "network (dev, qa, test, main)") +} diff --git a/registrar-cli/cmd/version.go b/registrar-cli/cmd/version.go new file mode 100644 index 0000000..0077662 --- /dev/null +++ b/registrar-cli/cmd/version.go @@ -0,0 +1,28 @@ +// Package cmd for parsing command line arguments +package cmd + +import ( + "fmt" + + "github.com/spf13/cobra" +) + +// set at build time +var ( + commit string + version string +) + +// versionCmd represents the version command +var versionCmd = &cobra.Command{ + Use: "version", + Short: "Get latest build tag", + Run: func(cmd *cobra.Command, args []string) { + fmt.Println(version) + fmt.Println(commit) + }, +} + +func init() { + rootCmd.AddCommand(versionCmd) +} diff --git a/registrar-cli/cmd/zos_version.go b/registrar-cli/cmd/zos_version.go new file mode 100644 index 0000000..d50412b --- /dev/null +++ b/registrar-cli/cmd/zos_version.go @@ -0,0 +1,16 @@ +// Package cmd for parsing command line arguments +package cmd + +import ( + "github.com/spf13/cobra" +) + +// zosVersionCmd represents the zos version command +var zosVersionCmd = &cobra.Command{ + Use: "zos-version", + Short: "zos-version command represents events on zos-version on Threefold grid4", +} + +func init() { + rootCmd.AddCommand(zosVersionCmd) +} diff --git a/registrar-cli/cmd/zos_version_get.go b/registrar-cli/cmd/zos_version_get.go new file mode 100644 index 0000000..5353145 --- /dev/null +++ b/registrar-cli/cmd/zos_version_get.go @@ -0,0 +1,33 @@ +// Package cmd for parsing command line arguments +package cmd + +import ( + "github.com/rs/zerolog/log" + "github.com/spf13/cobra" + "github.com/threefoldtech/tfgrid4-sdk-go/registrar-cli/internal/cmd" +) + +// zosVersionGetCmd represents the zos version get command +var zosVersionGetCmd = &cobra.Command{ + Use: "get", + Short: "get zos version from node registrar", + RunE: func(cobraCmd *cobra.Command, args []string) error { + network, err := cobraCmd.Flags().GetString("network") + if err != nil { + return err + } + + version, err := cmd.GetVersion(network) + if err != nil { + return err + } + + log.Info().Any("zosVersion", version).Send() + + return nil + }, +} + +func init() { + zosVersionCmd.AddCommand(zosVersionGetCmd) +} diff --git a/registrar-cli/cmd/zos_version_update.go b/registrar-cli/cmd/zos_version_update.go new file mode 100644 index 0000000..91e918b --- /dev/null +++ b/registrar-cli/cmd/zos_version_update.go @@ -0,0 +1,52 @@ +// Package cmd for parsing command line arguments +package cmd + +import ( + "github.com/rs/zerolog/log" + "github.com/spf13/cobra" + "github.com/threefoldtech/tfgrid4-sdk-go/registrar-cli/internal/cmd" +) + +// zosVersionUpdateCmd represents the zos version update command +var zosVersionUpdateCmd = &cobra.Command{ + Use: "update", + Short: "update zos version in node registrar", + RunE: func(cobraCmd *cobra.Command, args []string) error { + mnemonic, err := cobraCmd.Flags().GetString("mnemonic") + if err != nil { + return err + } + + network, err := cobraCmd.Flags().GetString("network") + if err != nil { + return err + } + + version, err := cobraCmd.Flags().GetString("version") + if err != nil { + return err + } + + safeToUpgrade, err := cobraCmd.Flags().GetBool("safe-to-upgrade") + if err != nil { + return err + } + + err = cmd.UpdateVersion(mnemonic, network, version, safeToUpgrade) + if err != nil { + return err + } + + log.Info().Msg("zos version is updated successfully") + + return nil + }, +} + +func init() { + zosVersionCmd.AddCommand(zosVersionUpdateCmd) + zosVersionUpdateCmd.Flags().StringP("mnemonic", "m", "", "account mnemonic") + zosVersionUpdateCmd.Flags().StringP("version", "v", "v0.0.0", "new zos version") + zosVersionUpdateCmd.Flags().BoolP("safe-to-upgrade", "u", false, "safe to upgrade") + zosVersionUpdateCmd.MarkFlagsRequiredTogether("mnemonic", "version") +} diff --git a/registrar-cli/go.mod b/registrar-cli/go.mod new file mode 100644 index 0000000..53a3572 --- /dev/null +++ b/registrar-cli/go.mod @@ -0,0 +1,18 @@ +module github.com/threefoldtech/tfgrid4-sdk-go/registrar-cli + +go 1.21.0 + +require ( + github.com/pkg/errors v0.9.1 + github.com/rs/zerolog v1.33.0 + github.com/spf13/cobra v1.9.1 + github.com/threefoldtech/tfgrid4-sdk-go/node-registrar v0.0.0-20250226194238-c27651fbdd6e +) + +require ( + github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/spf13/pflag v1.0.6 // indirect + golang.org/x/sys v0.28.0 // indirect +) diff --git a/registrar-cli/go.sum b/registrar-cli/go.sum new file mode 100644 index 0000000..0c87a5a --- /dev/null +++ b/registrar-cli/go.sum @@ -0,0 +1,37 @@ +github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8= +github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo= +github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0= +github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= +github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/threefoldtech/tfgrid4-sdk-go/node-registrar v0.0.0-20250226194238-c27651fbdd6e h1:n/hq2t7txZNuQ53EMR+ikwvu3bSvZIerm1d6JiXbmro= +github.com/threefoldtech/tfgrid4-sdk-go/node-registrar v0.0.0-20250226194238-c27651fbdd6e/go.mod h1:x6Sluj6YKfelWzcNwsD2oqGO8dpRlH7fbmeIqEsK8hI= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/registrar-cli/internal/cmd/account.go b/registrar-cli/internal/cmd/account.go new file mode 100644 index 0000000..5fa73a8 --- /dev/null +++ b/registrar-cli/internal/cmd/account.go @@ -0,0 +1,83 @@ +package cmd + +import ( + "encoding/hex" + "fmt" + + "github.com/threefoldtech/tfgrid4-sdk-go/node-registrar/client" +) + +var urls = map[string]string{ + "dev": "https://registrar.dev4.grid.tf/v1", + "qa": "https://registrar.qa4.grid.tf/v1", + "test": "https://registrar.test4.grid.tf/v1", + "main": "https://registrar.prod4.grid.tf/v1", +} + +func CreateAccount(network string, relays []string, rmbEncKey string, mnemonicOrSeed ...string) (account client.Account, mnemonic string, err error) { + u, ok := urls[network] + if !ok { + return account, "", fmt.Errorf("invalid network %s", network) + } + + var cli client.RegistrarClient + cli, err = client.NewRegistrarClient(u, mnemonicOrSeed...) + if err != nil { + return + } + + return cli.CreateAccount(relays, rmbEncKey) +} + +func GetAccount(network string, twinID uint64, pk string) (account client.Account, err error) { + u, ok := urls[network] + if !ok { + return account, fmt.Errorf("invalid network %s", network) + } + + cli, err := client.NewRegistrarClient(u) + if err != nil { + return + } + + if twinID != 0 { + return cli.GetAccount(twinID) + } else if len(pk) != 0 { + + publicKey, err := hex.DecodeString(pk) + if err != nil { + return account, err + } + + return cli.GetAccountByPK(publicKey) + } + + return account, fmt.Errorf("you need to provide either twin id or public key to load an account") +} + +func UpdateAccount(mnemonic string, network string, relays []string, rmbEncKey string) (err error) { + u, ok := urls[network] + if !ok { + return fmt.Errorf("invalid network %s", network) + } + + if len(mnemonic) == 0 { + return fmt.Errorf("can not initialize registrar client with no mnemonic") + } + + cli, err := client.NewRegistrarClient(u, mnemonic) + if err != nil { + return err + } + + var opts []client.UpdateAccountOpts + if len(relays) > 0 { + opts = append(opts, client.UpdateAccountWithRelays(relays)) + } + + if len(rmbEncKey) > 0 { + opts = append(opts, client.UpdateAccountWithRMBEncKey(rmbEncKey)) + } + + return cli.UpdateAccount(opts...) +} diff --git a/registrar-cli/internal/cmd/farm.go b/registrar-cli/internal/cmd/farm.go new file mode 100644 index 0000000..f1a6863 --- /dev/null +++ b/registrar-cli/internal/cmd/farm.go @@ -0,0 +1,76 @@ +package cmd + +import ( + "fmt" + + "github.com/pkg/errors" + "github.com/threefoldtech/tfgrid4-sdk-go/node-registrar/client" +) + +func CreateFarm(mnemonic, network, farmName, stellarAddress string, dedicated bool) (farmID uint64, err error) { + u, ok := urls[network] + if !ok { + return farmID, fmt.Errorf("invalid network %s (must be one of: dev, qa, test, main)", network) + } + + if len(mnemonic) == 0 { + return farmID, errors.New("empty mnemonic provided") + } + + cli, err := client.NewRegistrarClient(u, mnemonic) + if err != nil { + return farmID, errors.Wrap(err, "client initialization failed") + } + + farmID, err = cli.CreateFarm(farmName, stellarAddress, dedicated) + if err != nil { + return farmID, errors.Wrap(err, "farm creation failed") + } + + return farmID, nil +} + +func GetFarm(network string, farmID uint64) (farm client.Farm, err error) { + u, ok := urls[network] + if !ok { + return farm, fmt.Errorf("invalid network %s", network) + } + + cli, err := client.NewRegistrarClient(u) + if err != nil { + return + } + + return cli.GetFarm(farmID) +} + +func UpdateFarm(farmID uint64, mnemonic, network, farmName, stellarAddress string, dedicated bool) (err error) { + u, ok := urls[network] + if !ok { + return fmt.Errorf("invalid network %s", network) + } + + if len(mnemonic) == 0 { + return fmt.Errorf("can not initialize registrar client with no mnemonic") + } + + cli, err := client.NewRegistrarClient(u, mnemonic) + if err != nil { + return err + } + + var opts client.FarmUpdate + if len(farmName) > 0 { + opts.FarmName = &farmName + } + + if dedicated { + trueVal := true + opts.Dedicated = &trueVal + } + if len(stellarAddress) != 0 { + opts.StellarAddress = &stellarAddress + } + + return cli.UpdateFarm(farmID, opts) +} diff --git a/registrar-cli/internal/cmd/node.go b/registrar-cli/internal/cmd/node.go new file mode 100644 index 0000000..66d4a3f --- /dev/null +++ b/registrar-cli/internal/cmd/node.go @@ -0,0 +1,37 @@ +package cmd + +import ( + "fmt" + + "github.com/pkg/errors" + "github.com/threefoldtech/tfgrid4-sdk-go/node-registrar/client" +) + +func GetNode(network string, nodeID, twinID uint64) (node client.Node, err error) { + u, ok := urls[network] + if !ok { + return node, fmt.Errorf("invalid network %s (must be one of: dev, qa, test, main)", network) + } + + cli, err := client.NewRegistrarClient(u) + if err != nil { + return node, errors.Wrap(err, "client initialization failed") + } + + if nodeID != 0 { + node, err = cli.GetNode(nodeID) + if err != nil { + return + } + + } else if twinID != 0 { + node, err = cli.GetNodeByTwinID(twinID) + if err != nil { + return + } + } else { + return client.Node{}, fmt.Errorf("you need to provide either twin id or node id to load a node") + } + + return +} diff --git a/registrar-cli/internal/cmd/version.go b/registrar-cli/internal/cmd/version.go new file mode 100644 index 0000000..c409d42 --- /dev/null +++ b/registrar-cli/internal/cmd/version.go @@ -0,0 +1,39 @@ +package cmd + +import ( + "fmt" + + "github.com/threefoldtech/tfgrid4-sdk-go/node-registrar/client" +) + +func GetVersion(network string) (version client.ZosVersion, err error) { + u, ok := urls[network] + if !ok { + return version, fmt.Errorf("invalid network %s", network) + } + + cli, err := client.NewRegistrarClient(u) + if err != nil { + return + } + + return cli.GetZosVersion() +} + +func UpdateVersion(mnemonic string, network string, version string, safeToUpgrade bool) (err error) { + u, ok := urls[network] + if !ok { + return fmt.Errorf("invalid network %s", network) + } + + if len(mnemonic) == 0 { + return fmt.Errorf("can not initialize registrar client with no mnemonic") + } + + cli, err := client.NewRegistrarClient(u, mnemonic) + if err != nil { + return err + } + + return cli.SetZosVersion(version, safeToUpgrade) +} diff --git a/registrar-cli/main.go b/registrar-cli/main.go new file mode 100644 index 0000000..0fea299 --- /dev/null +++ b/registrar-cli/main.go @@ -0,0 +1,10 @@ +/* +Copyright © 2025 NAME HERE +*/ +package main + +import "github.com/threefoldtech/tfgrid4-sdk-go/registrar-cli/cmd" + +func main() { + cmd.Execute() +}