Repository: threefoldtech/zos
Pull request #373 (2019-11-07 14:10:58)

change the farm id to be of type uint64


Patch:
diff --git a/cmds/capacityd/main.go b/cmds/capacityd/main.go
index f5901f36..7899f6b7 100644
--- a/cmds/capacityd/main.go
+++ b/cmds/capacityd/main.go
@@ -108,7 +108,10 @@ func main() {
 
 // instantiate the proper client based on the running mode
 func bcdbClient() (capacity.Store, error) {
-	env := environment.Get()
+	env, err := environment.Get()
+	if err != nil {
+		return nil, errors.Wrap(err, "failed to parse node environment")
+	}
 
 	// use the bcdb mock for dev and test
 	if env.RunningMode == environment.RunningDev {
diff --git a/cmds/identityd/main.go b/cmds/identityd/main.go
index dcdc195f..13b5423b 100644
--- a/cmds/identityd/main.go
+++ b/cmds/identityd/main.go
@@ -249,7 +249,10 @@ func identityMgr(root string) (pkg.IdentityManager, error) {
 		return nil, err
 	}
 
-	env := environment.Get()
+	env, err := environment.Get()
+	if err != nil {
+		return nil, errors.Wrap(err, "failed to parse node environment")
+	}
 
 	nodeID := manager.NodeID()
 	log.Info().
@@ -258,7 +261,7 @@ func identityMgr(root string) (pkg.IdentityManager, error) {
 
 	log.Info().
 		Bool("orphan", env.Orphan).
-		Str("farmer_id", env.FarmerID).
+		Uint64("farmer_id", uint64(env.FarmerID)).
 		Msg("farmer identified")
 
 	return manager, nil
@@ -266,7 +269,10 @@ func identityMgr(root string) (pkg.IdentityManager, error) {
 
 // instantiate the proper client based on the running mode
 func bcdbClient() (identity.IDStore, error) {
-	env := environment.Get()
+	env, err := environment.Get()
+	if err != nil {
+		return nil, errors.Wrap(err, "failed to parse node environment")
+	}
 
 	// use the bcdb mock for dev and test
 	if env.RunningMode == environment.RunningDev {
@@ -281,7 +287,7 @@ func bcdbClient() (identity.IDStore, error) {
 	return store, nil
 }
 
-func registerNode(nodeID, farmID pkg.Identifier, version string, store identity.IDStore, loc geoip.Location) error {
+func registerNode(nodeID pkg.Identifier, farmID pkg.FarmID, version string, store identity.IDStore, loc geoip.Location) error {
 	log.Info().Str("version", version).Msg("start registration of the node")
 
 	_, err := store.RegisterNode(nodeID, farmID, version, loc)
diff --git a/cmds/networkd/main.go b/cmds/networkd/main.go
index 2fae1416..3bb673a0 100644
--- a/cmds/networkd/main.go
+++ b/cmds/networkd/main.go
@@ -203,7 +203,10 @@ func startServer(ctx context.Context, broker string, networker pkg.Networker) er
 
 // instantiate the proper client based on the running mode
 func bcdbClient() (network.TNoDB, error) {
-	env := environment.Get()
+	env, err := environment.Get()
+	if err != nil {
+		return nil, errors.Wrap(err, "failed to parse node environment")
+	}
 
 	// use the bcdb mock for dev and test
 	if env.RunningMode == environment.RunningDev {
diff --git a/cmds/provisiond/main.go b/cmds/provisiond/main.go
index 69749c0f..8888596f 100644
--- a/cmds/provisiond/main.go
+++ b/cmds/provisiond/main.go
@@ -51,7 +51,10 @@ func main() {
 		log.Fatal().Err(err).Msg("failed to create cache directory")
 	}
 
-	env := environment.Get()
+	env, err := environment.Get()
+	if err != nil {
+		log.Fatal().Err(err).Msg("failed to parse node environment")
+	}
 
 	if env.Orphan {
 		// disable providiond on this node
@@ -117,7 +120,10 @@ type store interface {
 
 // instantiate the proper client based on the running mode
 func bcdbClient() (store, error) {
-	env := environment.Get()
+	env, err := environment.Get()
+	if err != nil {
+		return nil, errors.Wrap(err, "failed to parse node environment")
+	}
 
 	// use the bcdb mock for dev and test
 	if env.RunningMode == environment.RunningDev {
diff --git a/pkg/environment/environment.go b/pkg/environment/environment.go
index dc90f27b..0313e212 100644
--- a/pkg/environment/environment.go
+++ b/pkg/environment/environment.go
@@ -2,6 +2,9 @@ package environment
 
 import (
 	"os"
+	"strconv"
+
+	"github.com/threefoldtech/zos/pkg"
 
 	"github.com/threefoldtech/zos/pkg/kernel"
 )
@@ -15,7 +18,7 @@ type Environment struct {
 	BcdbNamespace string
 	BcdbPassword  string
 
-	FarmerID string
+	FarmerID pkg.FarmID
 	Orphan   bool
 
 	// ProvisionTimeout  int64
@@ -33,9 +36,9 @@ const (
 
 	// Orphanage is the default farmid where nodes are registered
 	// if no farmid were specified on the kernel command line
-	OrphanageDev  string = "orphan"
-	OrphanageTest string = "orphan"
-	OrphanageMain string = "orphan"
+	OrphanageDev  pkg.FarmID = 0
+	OrphanageTest pkg.FarmID = 0
+	OrphanageMain pkg.FarmID = 0
 )
 
 var (
@@ -64,12 +67,12 @@ var (
 )
 
 // Get return the running environment of the node
-func Get() Environment {
+func Get() (Environment, error) {
 	params := kernel.GetParams()
 	return getEnvironmentFromParams(params)
 }
 
-func getEnvironmentFromParams(params kernel.Params) Environment {
+func getEnvironmentFromParams(params kernel.Params) (Environment, error) {
 	var runmode []string
 	var env Environment
 
@@ -114,7 +117,11 @@ func getEnvironmentFromParams(params kernel.Params) Environment {
 
 	} else {
 		env.Orphan = false
-		env.FarmerID = farmerID[0]
+		id, err := strconv.ParseUint(farmerID[0], 10, 64)
+		if err != nil {
+			return env, err
+		}
+		env.FarmerID = pkg.FarmID(id)
 	}
 
 	// Checking if there environment variable
@@ -144,5 +151,5 @@ func getEnvironmentFromParams(params kernel.Params) Environment {
 	// 	}
 	// }
 
-	return env
+	return env, nil
 }
diff --git a/pkg/gedis/commands_identity.go b/pkg/gedis/commands_identity.go
index 73707f66..4d1043a3 100644
--- a/pkg/gedis/commands_identity.go
+++ b/pkg/gedis/commands_identity.go
@@ -22,14 +22,14 @@ import (
 //
 
 //RegisterNode implements pkg.IdentityManager interface
-func (g *Gedis) RegisterNode(nodeID, farmID pkg.Identifier, version string, location geoip.Location) (string, error) {
+func (g *Gedis) RegisterNode(nodeID pkg.Identifier, farmID pkg.FarmID, version string, location geoip.Location) (string, error) {
 
 	pk := base58.Decode(nodeID.Identity())
 
 	resp, err := Bytes(g.Send("nodes", "add", Args{
 		"node": directory.TfgridNode2{
 			NodeID:       nodeID.Identity(),
-			FarmID:       farmID.Identity(),
+			FarmID:       uint64(farmID),
 			OsVersion:    version,
 			PublicKeyHex: hex.EncodeToString(pk),
 			Location: directory.TfgridLocation1{
@@ -57,9 +57,9 @@ func (g *Gedis) RegisterNode(nodeID, farmID pkg.Identifier, version string, loca
 }
 
 // ListNode implements pkg.IdentityManager interface
-func (g *Gedis) ListNode(farmID pkg.Identifier, country string, city string) ([]types.Node, error) {
+func (g *Gedis) ListNode(farmID pkg.FarmID, country string, city string) ([]types.Node, error) {
 	resp, err := Bytes(g.Send("nodes", "list", Args{
-		"farm_id": farmID.Identity(),
+		"farm_id": farmID,
 		"country": country,
 		"city":    city,
 	}))
@@ -85,10 +85,10 @@ func (g *Gedis) ListNode(farmID pkg.Identifier, country string, city string) ([]
 }
 
 //RegisterFarm implements pkg.IdentityManager interface
-func (g *Gedis) RegisterFarm(farm pkg.Identifier, name string, email string, wallet []string) (string, error) {
+func (g *Gedis) RegisterFarm(tid uint64, name string, email string, wallet []string) (pkg.FarmID, error) {
 	resp, err := Bytes(g.Send("farms", "register", Args{
 		"farm": directory.TfgridFarm1{
-			ThreebotID:      farm.Identity(),
+			ThreebotID:      tid,
 			Name:            name,
 			Email:           email,
 			WalletAddresses: wallet,
@@ -96,7 +96,7 @@ func (g *Gedis) RegisterFarm(farm pkg.Identifier, name string, email string, wal
 	}))
 
 	if err != nil {
-		return "", err
+		return 0, err
 	}
 
 	var out struct {
@@ -104,10 +104,15 @@ func (g *Gedis) RegisterFarm(farm pkg.Identifier, name string, email string, wal
 	}
 
 	if err := json.Unmarshal(resp, &out); err != nil {
-		return "", err
+		return 0, err
+	}
+
+	id, err := out.FarmID.Int64()
+	if err != nil {
+		return 0, err
 	}
 
-	return out.FarmID.String(), nil
+	return pkg.FarmID(id), nil
 }
 
 //GetNode implements pkg.IdentityManager interface
diff --git a/pkg/gedis/types/directory/tfgrid_farm_1.go b/pkg/gedis/types/directory/tfgrid_farm_1.go
index 63c97926..e878eec4 100644
--- a/pkg/gedis/types/directory/tfgrid_farm_1.go
+++ b/pkg/gedis/types/directory/tfgrid_farm_1.go
@@ -2,8 +2,8 @@ package directory
 
 //TfgridFarm1 jsx schema
 type TfgridFarm1 struct {
-	ID              string                     `json:"id"`
-	ThreebotID      string                     `json:"threebot_id"`
+	ID              uint64                     `json:"id"`
+	ThreebotID      uint64                     `json:"threebot_id"`
 	IyoOrganization string                     `json:"iyo_organization"`
 	Name            string                     `json:"name"`
 	WalletAddresses []string                   `json:"wallet_addresses"`
diff --git a/pkg/gedis/types/directory/tfgrid_node_2.go b/pkg/gedis/types/directory/tfgrid_node_2.go
index 3079664a..e4b11108 100644
--- a/pkg/gedis/types/directory/tfgrid_node_2.go
+++ b/pkg/gedis/types/directory/tfgrid_node_2.go
@@ -9,7 +9,7 @@ import (
 //TfgridNode2 jsx schema
 type TfgridNode2 struct {
 	NodeID            string                    `json:"node_id"`
-	FarmID            string                    `json:"farm_id"`
+	FarmID            uint64                    `json:"farm_id"`
 	OsVersion         string                    `json:"os_version"`
 	Created           schema.Date               `json:"created"`
 	Updated           schema.Date               `json:"updated"`
diff --git a/pkg/identity.go b/pkg/identity.go
index 4804bc58..525f66b0 100644
--- a/pkg/identity.go
+++ b/pkg/identity.go
@@ -25,7 +25,7 @@ type IdentityManager interface {
 
 	// FarmID return the farm id this node is part of. this is usually a configuration
 	// that the node is booted with. An error is returned if the farmer id is not configured
-	FarmID() (StrIdentifier, error)
+	FarmID() (FarmID, error)
 
 	// Sign signs the message with privateKey and returns a signature.
 	Sign(message []byte) ([]byte, error)
@@ -39,3 +39,6 @@ type IdentityManager interface {
 	// Decrypt decrypts message with the private of the node
 	Decrypt(message []byte) ([]byte, error)
 }
+
+// FarmID is the identification of a farm
+type FarmID uint64
diff --git a/pkg/identity/identityd.go b/pkg/identity/identityd.go
index db93042f..85b2d9e1 100644
--- a/pkg/identity/identityd.go
+++ b/pkg/identity/identityd.go
@@ -46,9 +46,12 @@ func (d *identityManager) NodeID() pkg.StrIdentifier {
 }
 
 // FarmID returns the farm ID of the node or an error if no farm ID is configured
-func (d *identityManager) FarmID() (pkg.StrIdentifier, error) {
-	env := environment.Get()
-	return pkg.StrIdentifier(env.FarmerID), nil
+func (d *identityManager) FarmID() (pkg.FarmID, error) {
+	env, err := environment.Get()
+	if err != nil {
+		return 0, errors.Wrap(err, "failed to parse node environment")
+	}
+	return env.FarmerID, nil
 }
 
 // Sign signs the message with privateKey and returns a signature.
diff --git a/pkg/identity/store.go b/pkg/identity/store.go
index cacf094b..bb972a10 100644
--- a/pkg/identity/store.go
+++ b/pkg/identity/store.go
@@ -16,8 +16,8 @@ import (
 // IDStore is the interface defining the
 // client side of an identity store
 type IDStore interface {
-	RegisterNode(node pkg.Identifier, farm pkg.Identifier, version string, loc geoip.Location) (string, error)
-	RegisterFarm(farm pkg.Identifier, name string, email string, wallet []string) (string, error)
+	RegisterNode(node pkg.Identifier, farm pkg.FarmID, version string, loc geoip.Location) (string, error)
+	RegisterFarm(tid uint64, name string, email string, wallet []string) (pkg.FarmID, error)
 }
 
 type httpIDStore struct {
@@ -30,11 +30,11 @@ func NewHTTPIDStore(url string) IDStore {
 }
 
 // RegisterNode implements the IDStore interface
-func (s *httpIDStore) RegisterNode(node pkg.Identifier, farm pkg.Identifier, version string, loc geoip.Location) (string, error) {
+func (s *httpIDStore) RegisterNode(node pkg.Identifier, farm pkg.FarmID, version string, loc geoip.Location) (string, error) {
 	buf := bytes.Buffer{}
 	err := json.NewEncoder(&buf).Encode(directory.TfgridNode2{
 		NodeID:    node.Identity(),
-		FarmID:    farm.Identity(),
+		FarmID:    uint64(farm),
 		OsVersion: version,
 		Location: directory.TfgridLocation1{
 			City:      loc.City,
@@ -65,23 +65,33 @@ type farmRegisterReq struct {
 }
 
 // RegisterFarm implements the IDStore interface
-func (s *httpIDStore) RegisterFarm(farm pkg.Identifier, name string, email string, wallet []string) (string, error) {
+func (s *httpIDStore) RegisterFarm(tid uint64, name string, email string, wallet []string) (pkg.FarmID, error) {
 	buf := bytes.Buffer{}
-	err := json.NewEncoder(&buf).Encode(farmRegisterReq{
-		ID:   farm.Identity(),
-		Name: name,
+	err := json.NewEncoder(&buf).Encode(directory.TfgridFarm1{
+		ThreebotID:      tid,
+		Name:            name,
+		Email:           email,
+		WalletAddresses: wallet,
 	})
 	if err != nil {
-		return "", err
+		return 0, err
 	}
 
 	resp, err := http.Post(s.baseURL+"/farms", "application/json", &buf)
 	if err != nil {
-		return "", err
+		return 0, err
 	}
 	if resp.StatusCode != http.StatusCreated {
-		return "", fmt.Errorf("wrong response status code received: %v", resp.Status)
+		return 0, fmt.Errorf("wrong response status code received: %v", resp.Status)
+	}
+
+	defer resp.Body.Close()
+	id := struct {
+		ID pkg.FarmID `json:"id"`
+	}{}
+	if err := json.NewDecoder(resp.Body).Decode(&id); err != nil {
+		return 0, err
 	}
 
-	return name, nil
+	return id.ID, nil
 }
diff --git a/pkg/network/types/types.go b/pkg/network/types/types.go
index b7b0d0d2..8c7dd45b 100644
--- a/pkg/network/types/types.go
+++ b/pkg/network/types/types.go
@@ -69,7 +69,7 @@ type PubIface struct {
 // Node is the public information about a node
 type Node struct {
 	NodeID string `json:"node_id"`
-	FarmID string `json:"farm_id"`
+	FarmID uint64 `json:"farm_id"`
 
 	Ifaces []*IfaceInfo `json:"ifaces"`
 
diff --git a/pkg/stubs/identity_stub.go b/pkg/stubs/identity_stub.go
index bb2e2bc1..9ba8208c 100644
--- a/pkg/stubs/identity_stub.go
+++ b/pkg/stubs/identity_stub.go
@@ -54,7 +54,7 @@ func (s *IdentityManagerStub) Encrypt(arg0 []uint8) (ret0 []uint8, ret1 error) {
 	return
 }
 
-func (s *IdentityManagerStub) FarmID() (ret0 pkg.StrIdentifier, ret1 error) {
+func (s *IdentityManagerStub) FarmID() (ret0 pkg.FarmID, ret1 error) {
 	args := []interface{}{}
 	result, err := s.client.Request(s.module, s.object, "FarmID", args...)
 	if err != nil {
diff --git a/tools/bcdb_mock/error.go b/tools/bcdb_mock/error.go
index fb7311f9..f7fb237f 100644
--- a/tools/bcdb_mock/error.go
+++ b/tools/bcdb_mock/error.go
@@ -10,8 +10,8 @@ func httpError(w http.ResponseWriter, err error, code int) {
 	w.Header().Set("X-Content-Type-Options", "nosniff")
 	w.WriteHeader(code)
 	json.NewEncoder(w).Encode(struct {
-		Error error
+		Error string
 	}{
-		Error: err,
+		Error: err.Error(),
 	})
 }
diff --git a/tools/bcdb_mock/farms_handlers.go b/tools/bcdb_mock/farms_handlers.go
index 55645a53..f0fff8cc 100644
--- a/tools/bcdb_mock/farms_handlers.go
+++ b/tools/bcdb_mock/farms_handlers.go
@@ -4,6 +4,11 @@ import (
 	"encoding/json"
 	"log"
 	"net/http"
+	"strconv"
+
+	"github.com/threefoldtech/zos/pkg"
+
+	"github.com/pkg/errors"
 
 	"github.com/threefoldtech/zos/pkg/gedis/types/directory"
 
@@ -21,11 +26,17 @@ func (s *farmStore) registerFarm(w http.ResponseWriter, r *http.Request) {
 		return
 	}
 
-	if err := s.Add(info); err != nil {
+	id, err := s.Add(info)
+	if err != nil {
 		httpError(w, err, http.StatusInternalServerError)
 		return
 	}
 	w.WriteHeader(http.StatusCreated)
+	json.NewEncoder(w).Encode(struct {
+		ID pkg.FarmID `json:"id"`
+	}{
+		id,
+	})
 }
 
 func (s *farmStore) listFarm(w http.ResponseWriter, r *http.Request) {
@@ -45,8 +56,15 @@ func (s *farmStore) cockpitListFarm(w http.ResponseWriter, r *http.Request) {
 }
 
 func (s *farmStore) getFarm(w http.ResponseWriter, r *http.Request) {
-	name := mux.Vars(r)["farm_id"]
-	farm, err := s.Get(name)
+	sid := mux.Vars(r)["farm_id"]
+
+	id, err := strconv.Atoi(sid)
+	if err != nil {
+		httpError(w, errors.Wrap(err, "id should be an integer"), http.StatusBadRequest)
+		return
+	}
+
+	farm, err := s.GetByID(id)
 	if err != nil {
 		httpError(w, err, http.StatusNotFound)
 		return
diff --git a/tools/bcdb_mock/farms_store.go b/tools/bcdb_mock/farms_store.go
index dadec468..bac6beb0 100644
--- a/tools/bcdb_mock/farms_store.go
+++ b/tools/bcdb_mock/farms_store.go
@@ -6,6 +6,7 @@ import (
 	"os"
 	"sync"
 
+	"github.com/threefoldtech/zos/pkg"
 	"github.com/threefoldtech/zos/pkg/gedis/types/directory"
 )
 
@@ -56,7 +57,7 @@ func (s *farmStore) List() []*directory.TfgridFarm1 {
 	return out
 }
 
-func (s *farmStore) Get(name string) (*directory.TfgridFarm1, error) {
+func (s *farmStore) GetByName(name string) (*directory.TfgridFarm1, error) {
 	s.m.RLock()
 	defer s.m.RUnlock()
 
@@ -68,7 +69,17 @@ func (s *farmStore) Get(name string) (*directory.TfgridFarm1, error) {
 	return nil, fmt.Errorf("farm %s not found", name)
 }
 
-func (s *farmStore) Add(farm directory.TfgridFarm1) error {
+func (s *farmStore) GetByID(id int) (*directory.TfgridFarm1, error) {
+	s.m.RLock()
+	defer s.m.RUnlock()
+
+	if id <= 0 || id > len(s.Farms) {
+		return nil, fmt.Errorf("farm with id %d not found", id)
+	}
+	return s.Farms[id-1], nil
+}
+
+func (s *farmStore) Add(farm directory.TfgridFarm1) (pkg.FarmID, error) {
 	s.m.Lock()
 	defer s.m.Unlock()
 
@@ -78,10 +89,11 @@ func (s *farmStore) Add(farm directory.TfgridFarm1) error {
 			f.Location = farm.Location
 			f.Email = farm.Email
 			f.ResourcePrices = farm.ResourcePrices
-			return nil
+			return pkg.FarmID(f.ID), nil
 		}
 	}
 
+	farm.ID = uint64(len(s.Farms) + 1) // ids starts at 1
 	s.Farms = append(s.Farms, &farm)
-	return nil
+	return pkg.FarmID(farm.ID), nil
 }
diff --git a/tools/bcdb_mock/node_handlers.go b/tools/bcdb_mock/node_handlers.go
index debaed02..a7236f2a 100644
--- a/tools/bcdb_mock/node_handlers.go
+++ b/tools/bcdb_mock/node_handlers.go
@@ -5,6 +5,7 @@ import (
 	"fmt"
 	"log"
 	"net/http"
+	"strconv"
 
 	"github.com/threefoldtech/zos/pkg/capacity"
 
@@ -52,7 +53,20 @@ func (s *nodeStore) nodeDetail(w http.ResponseWriter, r *http.Request) {
 
 func (s *nodeStore) listNodes(w http.ResponseWriter, r *http.Request) {
 	nodes := s.List()
-	farm := r.URL.Query().Get("farm")
+	sFarm := r.URL.Query().Get("farm")
+
+	var (
+		farm uint64
+		err  error
+	)
+
+	if sFarm != "" {
+		farm, err = strconv.ParseUint(sFarm, 10, 64)
+		if err != nil {
+			httpError(w, err, http.StatusBadRequest)
+			return
+		}
+	}
 
 	for i, node := range nodes {
 		if node == nil {
@@ -60,7 +74,7 @@ func (s *nodeStore) listNodes(w http.ResponseWriter, r *http.Request) {
 			continue
 		}
 
-		if farm != "" && node.FarmID != farm {
+		if farm != 0 && uint64(node.FarmID) != farm {
 			nodes = append(nodes[:i], nodes[i+1:]...)
 			continue
 		}
@@ -73,7 +87,20 @@ func (s *nodeStore) listNodes(w http.ResponseWriter, r *http.Request) {
 
 func (s *nodeStore) cockpitListNodes(w http.ResponseWriter, r *http.Request) {
 	nodes := s.List()
-	farm := r.URL.Query().Get("farm")
+	sFarm := r.URL.Query().Get("farm")
+
+	var (
+		farm uint64
+		err  error
+	)
+
+	if sFarm != "" {
+		farm, err = strconv.ParseUint(sFarm, 10, 64)
+		if err != nil {
+			httpError(w, err, http.StatusBadRequest)
+			return
+		}
+	}
 
 	for i, node := range nodes {
 		if node == nil {
@@ -81,12 +108,16 @@ func (s *nodeStore) cockpitListNodes(w http.ResponseWriter, r *http.Request) {
 			continue
 		}
 
-		if farm != "" && node.FarmID != farm {
+		if farm != 0 && uint64(node.FarmID) != farm {
 			nodes = append(nodes[:i], nodes[i+1:]...)
 			continue
 		}
 	}
 
+	w.Header().Set("Content-Type", "application/json")
+	w.WriteHeader(http.StatusOK)
+	_ = json.NewEncoder(w).Encode(nodes)
+
 	x := struct {
 		Node []*directory.TfgridNode2 `json:"nodes"`
 	}{nodes}
diff --git a/tools/tffarmer/farm.go b/tools/tffarmer/farm.go
index ac628f16..59bfec24 100644
--- a/tools/tffarmer/farm.go
+++ b/tools/tffarmer/farm.go
@@ -3,7 +3,6 @@ package main
 import (
 	"fmt"
 
-	"github.com/threefoldtech/zos/pkg"
 	"github.com/urfave/cli"
 )
 
@@ -14,27 +13,15 @@ func registerFarm(c *cli.Context) error {
 		return fmt.Errorf("A farm name needs to be specified")
 	}
 
-	var farmID pkg.Identifier
-	var err error
-	seedPath := c.String("seed")
-	if seedPath != "" {
-		farmID, err = loadFarmID(seedPath)
-		if err != nil {
-			return err
-		}
-	}
-	if farmID == nil {
-		farmID, err = generateKeyPair(seedPath)
-		if err != nil {
-			return err
-		}
-	}
+	tid := c.Uint64("tid")
 
-	if _, err := idStore.RegisterFarm(farmID, name, "", []string{}); err != nil {
+	farmID, err := idStore.RegisterFarm(tid, name, "", []string{})
+	if err != nil {
 		return err
 	}
+
 	fmt.Println("Farm registered successfully")
 	fmt.Printf("Name: %s\n", name)
-	fmt.Printf("Identity: %s\n", farmID.Identity())
+	fmt.Printf("Farm ID: %d\n", farmID)
 	return nil
 }
diff --git a/tools/tffarmer/main.go b/tools/tffarmer/main.go
index 73cef299..0d6091b2 100644
--- a/tools/tffarmer/main.go
+++ b/tools/tffarmer/main.go
@@ -63,9 +63,9 @@ func main() {
 					Category:  "identity",
 					ArgsUsage: "farm_name",
 					Flags: []cli.Flag{
-						cli.StringFlag{
-							Name:  "seed",
-							Usage: "path to the farmer seed. Specify this if you already have a seed generated for your farm",
+						cli.Uint64Flag{
+							Name:  "tid",
+							Usage: "threebot id",
 						},
 					},
 					Action: registerFarm,


Test patch:
diff --git a/pkg/environment/environment_test.go b/pkg/environment/environment_test.go
index 3c7ab837..ade317f7 100644
--- a/pkg/environment/environment_test.go
+++ b/pkg/environment/environment_test.go
@@ -4,6 +4,8 @@ import (
 	"os"
 	"testing"
 
+	"github.com/stretchr/testify/require"
+
 	"github.com/stretchr/testify/assert"
 	"github.com/threefoldtech/zos/pkg/kernel"
 )
@@ -14,31 +16,36 @@ import (
 func TestManager(t *testing.T) {
 	// Development mode
 	params := kernel.Params{"runmode": {"dev"}}
-	value := getEnvironmentFromParams(params)
+	value, err := getEnvironmentFromParams(params)
+	require.NoError(t, err)
 
 	assert.Equal(t, RunningDev, value.RunningMode)
 
 	// Testing mode
 	params = kernel.Params{"runmode": {"test"}}
-	value = getEnvironmentFromParams(params)
+	value, err = getEnvironmentFromParams(params)
+	require.NoError(t, err)
 
 	assert.Equal(t, RunningTest, value.RunningMode)
 
 	// Main mode
 	params = kernel.Params{"runmode": {"prod"}}
-	value = getEnvironmentFromParams(params)
+	value, err = getEnvironmentFromParams(params)
+	require.NoError(t, err)
 
 	assert.Equal(t, RunningMain, value.RunningMode)
 
 	// Fallback
 	params = kernel.Params{"nope": {"lulz"}}
-	value = getEnvironmentFromParams(params)
+	value, err = getEnvironmentFromParams(params)
+	require.NoError(t, err)
 
 	assert.Equal(t, RunningMain, value.RunningMode)
 
 	// Fallback on undefined
 	params = kernel.Params{"runmode": {"dunno"}}
-	value = getEnvironmentFromParams(params)
+	value, err = getEnvironmentFromParams(params)
+	require.NoError(t, err)
 
 	assert.Equal(t, value.RunningMode, RunningMain)
 }
@@ -47,7 +54,8 @@ func TestEnvironmentOverride(t *testing.T) {
 	os.Setenv("ZOS_BCDB_URL", "localhost:1234")
 
 	params := kernel.Params{"runmode": {"dev"}}
-	value := getEnvironmentFromParams(params)
+	value, err := getEnvironmentFromParams(params)
+	require.NoError(t, err)
 
 	assert.Equal(t, value.BcdbURL, "localhost:1234")
 }
diff --git a/pkg/gedis/commands_identity_test.go b/pkg/gedis/commands_identity_test.go
index 211bb43f..05088d4a 100644
--- a/pkg/gedis/commands_identity_test.go
+++ b/pkg/gedis/commands_identity_test.go
@@ -22,7 +22,7 @@ func TestRegisterFarm(t *testing.T) {
 
 	args := Args{
 		"farm": directory.TfgridFarm1{
-			ThreebotID:      "farm-id",
+			ThreebotID:      10,
 			Name:            "my-node",
 			Email:           "azmy@test.com",
 			WalletAddresses: []string{"addr1", "addr2"},
@@ -33,14 +33,14 @@ func TestRegisterFarm(t *testing.T) {
 		Return(mustMarshal(t, Args{"farm_id": 123}), nil)
 
 	id, err := gedis.RegisterFarm(
-		pkg.StrIdentifier("farm-id"),
+		10,
 		"my-node",
 		"azmy@test.com",
 		[]string{"addr1", "addr2"},
 	)
 
 	require.NoError(err)
-	require.Equal(id, "123")
+	require.Equal(id, pkg.FarmID(123))
 	conn.AssertCalled(t, "Close")
 }
 
@@ -58,7 +58,7 @@ func TestRegisterNode(t *testing.T) {
 	args := Args{
 		"node": directory.TfgridNode2{
 			NodeID:       "node-1",
-			FarmID:       "farm-1",
+			FarmID:       1,
 			OsVersion:    "v1.1.0",
 			PublicKeyHex: hex.EncodeToString(base58.Decode("node-1")),
 			Location: directory.TfgridLocation1{
@@ -76,7 +76,7 @@ func TestRegisterNode(t *testing.T) {
 
 	id, err := gedis.RegisterNode(
 		pkg.StrIdentifier("node-1"),
-		pkg.StrIdentifier("farm-1"),
+		pkg.FarmID(1),
 		"v1.1.0",
 		l,
 	)
@@ -95,7 +95,7 @@ func TestListNode(t *testing.T) {
 	}
 
 	args := Args{
-		"farm_id": "farm-1",
+		"farm_id": 1,
 		"country": "eg",
 		"city":    "cairo",
 	}
@@ -107,7 +107,7 @@ func TestListNode(t *testing.T) {
 		}}), nil)
 
 	nodes, err := gedis.ListNode(
-		pkg.StrIdentifier("farm-1"), "eg", "cairo",
+		pkg.FarmID(1), "eg", "cairo",
 	)
 
 	require.NoError(err)
@@ -156,7 +156,7 @@ func TestGetFarm(t *testing.T) {
 
 	conn.On("Do", "default.farms.get", mustMarshal(t, args)).
 		Return(mustMarshal(t, directory.TfgridFarm1{
-			ID:   "100",
+			ID:   100,
 			Name: "farm-1",
 		}), nil)
 
@@ -185,8 +185,8 @@ func TestListFarm(t *testing.T) {
 
 	conn.On("Do", "default.farms.list", mustMarshal(t, args)).
 		Return(mustMarshal(t, Args{"farms": []directory.TfgridFarm1{
-			{ID: "1", Name: "farm-1"},
-			{ID: "2", Name: "farm-2"},
+			{ID: 1, Name: "farm-1"},
+			{ID: 2, Name: "farm-2"},
 		}}), nil)
 
 	nodes, err := gedis.ListFarm("eg", "cairo")
diff --git a/pkg/network/nr/net_resource_test.go b/pkg/network/nr/net_resource_test.go
index c6dca47f..8e148a86 100644
--- a/pkg/network/nr/net_resource_test.go
+++ b/pkg/network/nr/net_resource_test.go
@@ -14,7 +14,7 @@ import (
 
 type testIdentityManager struct {
 	id   string
-	farm string
+	farm uint64
 }
 
 var _ pkg.IdentityManager = (*testIdentityManager)(nil)
@@ -26,8 +26,8 @@ func (t *testIdentityManager) NodeID() pkg.StrIdentifier {
 
 // FarmID return the farm id this node is part of. this is usually a configuration
 // that the node is booted with. An error is returned if the farmer id is not configured
-func (t *testIdentityManager) FarmID() (pkg.StrIdentifier, error) {
-	return pkg.StrIdentifier(t.farm), nil
+func (t *testIdentityManager) FarmID() (pkg.FarmID, error) {
+	return pkg.FarmID(t.farm), nil
 }
 
 // Sign signs the message with privateKey and returns a signature.