Skip to content

mycelium messaging integration #26

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ require (
github.com/stretchr/testify v1.10.0
github.com/threefoldtech/0-fs v1.3.1-0.20240424140157-b488dfedcc56
github.com/threefoldtech/tfchain/clients/tfchain-client-go v0.0.0-20241127100051-77e684bcb1b2
github.com/threefoldtech/tfgrid-sdk-go/messenger v0.0.0-00010101000000-000000000000
github.com/threefoldtech/tfgrid-sdk-go/rmb-sdk-go v0.16.1-0.20241229121208-76ac3fea5e67
github.com/threefoldtech/zbus v1.0.1
github.com/tyler-smith/go-bip39 v1.1.0
Expand Down
2 changes: 0 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -562,8 +562,6 @@ github.com/stripe/safesql v0.2.0/go.mod h1:q7b2n0JmzM1mVGfcYpanfVb2j23cXZeWFxcIL
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
github.com/threefoldtech/0-fs v1.3.1-0.20240424140157-b488dfedcc56 h1:uWd8JfE8N3IM6Zw/LMr0+sRJl+G0YgqQmNDP8xXR0vw=
github.com/threefoldtech/0-fs v1.3.1-0.20240424140157-b488dfedcc56/go.mod h1:lZjR32SiNo3dP70inVFxaLMyZjmKX1ucS+5O31dbPNM=
github.com/threefoldtech/tfchain/clients/tfchain-client-go v0.0.0-20241127100051-77e684bcb1b2 h1:VW2J36F8g/kJn4IkY0JiRFmb1gFcdjiOyltfJLJ0mYU=
github.com/threefoldtech/tfchain/clients/tfchain-client-go v0.0.0-20241127100051-77e684bcb1b2/go.mod h1:cOL5YgHUmDG5SAXrsZxFjUECRQQuAqOoqvXhZG5sEUw=
github.com/threefoldtech/tfgrid-sdk-go/rmb-sdk-go v0.16.1-0.20241229121208-76ac3fea5e67 h1:Ii9TmXPBC1GYxRirReSygRZvEGXfAsQRaIipMEzGik0=
github.com/threefoldtech/tfgrid-sdk-go/rmb-sdk-go v0.16.1-0.20241229121208-76ac3fea5e67/go.mod h1:93SROfr+QjgaJ5/jIWtIpLkhaD8Pv8WbdfwvwMNG2p4=
github.com/threefoldtech/zbus v1.0.1 h1:3KaEpyOiDYAw+lrAyoQUGIvY9BcjVRXlQ1beBRqhRNk=
Expand Down
53 changes: 53 additions & 0 deletions nodeclient/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# NodeClient

NodeClient provides a simple interface to interact with ThreeFold nodes through JSON-RPC calls. It supports various operations including system information, network configuration, deployment management, and performance monitoring.

## Usage

```go
package main

import (
"context"
"fmt"
"log"

"github.com/threefoldtech/tfgrid-sdk-go/messenger"
"github.com/threefoldtech/zosbase/nodeclient"
)

func main() {
// Create messenger instance
msgr := messenger.NewMessenger(/* messenger config */)

// Create node client
client := nodeclient.NewNodeClient(msgr, "node-destination-id")

ctx := context.Background()

// Get node version
version, err := client.GetNodeVersion(ctx)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Node version: %+v\n", version)

// Get system diagnostics
diag, err := client.GetSystemDiagnostics(ctx)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Diagnostics: %+v\n", diag)

// List deployments
deployments, err := client.DeploymentList(ctx)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Found %d deployments\n", len(deployments))
}
```

## Generate client

a node client can be generated in any language with proper tool or LLMs from the [openrpc.json](../openrpc.json) file
251 changes: 251 additions & 0 deletions nodeclient/nodeclient.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,251 @@
package nodeclient

import (
"context"

"github.com/threefoldtech/tfgrid-sdk-go/messenger"
"github.com/threefoldtech/zosbase/pkg"
"github.com/threefoldtech/zosbase/pkg/api"
"github.com/threefoldtech/zosbase/pkg/capacity/dmi"
"github.com/threefoldtech/zosbase/pkg/diagnostics"
"github.com/threefoldtech/zosbase/pkg/geoip"
"github.com/threefoldtech/zosbase/pkg/gridtypes"
)

type NodeClient struct {
rpcClient *messenger.JSONRPCClient
destination string
}

func NewNodeClient(msgr *messenger.Messenger, destination string) *NodeClient {
return &NodeClient{
rpcClient: messenger.NewJSONRPCClient(msgr),
destination: destination,
}
}

// System Methods

func (c *NodeClient) GetNodeVersion(ctx context.Context) (api.Version, error) {
var version api.Version
if err := c.rpcClient.Call(ctx, c.destination, "system.version", nil, &version); err != nil {
return api.Version{}, err
}
return version, nil
}

func (c *NodeClient) GetSystemDMI(ctx context.Context) (dmi.DMI, error) {
var dmiInfo dmi.DMI
if err := c.rpcClient.Call(ctx, c.destination, "system.dmi", nil, &dmiInfo); err != nil {
return dmi.DMI{}, err
}
return dmiInfo, nil
}

func (c *NodeClient) GetSystemHypervisor(ctx context.Context) (string, error) {
var hypervisor string
if err := c.rpcClient.Call(ctx, c.destination, "system.hypervisor", nil, &hypervisor); err != nil {
return "", err
}
return hypervisor, nil
}

func (c *NodeClient) GetSystemDiagnostics(ctx context.Context) (diagnostics.Diagnostics, error) {
var diag diagnostics.Diagnostics
if err := c.rpcClient.Call(ctx, c.destination, "system.diagnostics", nil, &diag); err != nil {
return diagnostics.Diagnostics{}, err
}
return diag, nil
}

func (c *NodeClient) GetSystemFeatures(ctx context.Context) ([]pkg.NodeFeature, error) {
var features []pkg.NodeFeature
if err := c.rpcClient.Call(ctx, c.destination, "system.features", nil, &features); err != nil {
return nil, err
}
return features, nil
}

// Monitor/Performance Methods

func (c *NodeClient) GetMonitorSpeed(ctx context.Context) (pkg.IperfTaskResult, error) {
var result pkg.IperfTaskResult
if err := c.rpcClient.Call(ctx, c.destination, "monitor.speed", nil, &result); err != nil {
return pkg.IperfTaskResult{}, err
}
return result, nil
}

func (c *NodeClient) GetMonitorHealth(ctx context.Context) (pkg.HealthTaskResult, error) {
var result pkg.HealthTaskResult
if err := c.rpcClient.Call(ctx, c.destination, "monitor.health", nil, &result); err != nil {
return pkg.HealthTaskResult{}, err
}
return result, nil
}

func (c *NodeClient) GetMonitorPublicIp(ctx context.Context) (pkg.PublicIpTaskResult, error) {
var result pkg.PublicIpTaskResult
if err := c.rpcClient.Call(ctx, c.destination, "monitor.publicip", nil, &result); err != nil {
return pkg.PublicIpTaskResult{}, err
}
return result, nil
}

func (c *NodeClient) GetMonitorBenchmark(ctx context.Context) (pkg.CpuBenchTaskResult, error) {
var result pkg.CpuBenchTaskResult
if err := c.rpcClient.Call(ctx, c.destination, "monitor.benchmark", nil, &result); err != nil {
return pkg.CpuBenchTaskResult{}, err
}
return result, nil
}

func (c *NodeClient) GetMonitorAll(ctx context.Context) (pkg.AllTaskResult, error) {
var result pkg.AllTaskResult
if err := c.rpcClient.Call(ctx, c.destination, "monitor.all", nil, &result); err != nil {
return pkg.AllTaskResult{}, err
}
return result, nil
}

// Network Methods

func (c *NodeClient) GetNetworkWGPorts(ctx context.Context) ([]uint, error) {
var ports []uint
if err := c.rpcClient.Call(ctx, c.destination, "network.wg_ports", nil, &ports); err != nil {
return nil, err
}
return ports, nil
}

func (c *NodeClient) GetNetworkPublicConfig(ctx context.Context) (pkg.PublicConfig, error) {
var config pkg.PublicConfig
if err := c.rpcClient.Call(ctx, c.destination, "network.public_config", nil, &config); err != nil {
return pkg.PublicConfig{}, err
}
return config, nil
}

func (c *NodeClient) GetNetworkHasIPv6(ctx context.Context) (bool, error) {
var hasIPv6 bool
if err := c.rpcClient.Call(ctx, c.destination, "network.has_ipv6", nil, &hasIPv6); err != nil {
return false, err
}
return hasIPv6, nil
}

func (c *NodeClient) GetNetworkPublicIPs(ctx context.Context) ([]string, error) {
var ips []string
if err := c.rpcClient.Call(ctx, c.destination, "network.public_ips", nil, &ips); err != nil {
return nil, err
}
return ips, nil
}

func (c *NodeClient) GetNetworkPrivateIPs(ctx context.Context, networkName string) ([]string, error) {
params := map[string]any{
"network_name": networkName,
}
var ips []string
if err := c.rpcClient.Call(ctx, c.destination, "network.private_ips", params, &ips); err != nil {
return nil, err
}
return ips, nil
}

func (c *NodeClient) GetNetworkInterfaces(ctx context.Context) ([]pkg.Interface, error) {
var interfaces []pkg.Interface
if err := c.rpcClient.Call(ctx, c.destination, "network.interfaces", nil, &interfaces); err != nil {
return nil, err
}
return interfaces, nil
}

func (c *NodeClient) SetNetworkPublicNIC(ctx context.Context, device string) error {
params := map[string]any{
"device": device,
}
return c.rpcClient.Call(ctx, c.destination, "network.set_public_nic", params, nil)
}

func (c *NodeClient) GetNetworkPublicNIC(ctx context.Context) (pkg.ExitDevice, error) {
var device pkg.ExitDevice
if err := c.rpcClient.Call(ctx, c.destination, "network.get_public_nic", nil, &device); err != nil {
return pkg.ExitDevice{}, err
}
return device, nil
}

// Deployment Methods

func (c *NodeClient) DeploymentDeploy(ctx context.Context, deployment gridtypes.Deployment) error {
return c.rpcClient.Call(ctx, c.destination, "deployment.deploy", deployment, nil)
}

func (c *NodeClient) DeploymentUpdate(ctx context.Context, deployment gridtypes.Deployment) error {
return c.rpcClient.Call(ctx, c.destination, "deployment.update", deployment, nil)
}

func (c *NodeClient) DeploymentGet(ctx context.Context, contractID uint64) (gridtypes.Deployment, error) {
params := map[string]any{
"contract_id": contractID,
}
var deployment gridtypes.Deployment
if err := c.rpcClient.Call(ctx, c.destination, "deployment.get", params, &deployment); err != nil {
return gridtypes.Deployment{}, err
}
return deployment, nil
}

func (c *NodeClient) DeploymentList(ctx context.Context) ([]gridtypes.Deployment, error) {
var deployments []gridtypes.Deployment
if err := c.rpcClient.Call(ctx, c.destination, "deployment.list", nil, &deployments); err != nil {
return nil, err
}
return deployments, nil
}

func (c *NodeClient) DeploymentChanges(ctx context.Context, contractID uint64) ([]gridtypes.Workload, error) {
params := map[string]any{
"contract_id": contractID,
}
var changes []gridtypes.Workload
if err := c.rpcClient.Call(ctx, c.destination, "deployment.changes", params, &changes); err != nil {
return nil, err
}
return changes, nil
}

// Other Methods

func (c *NodeClient) GetGpuList(ctx context.Context) ([]pkg.GPUInfo, error) {
var gpus []pkg.GPUInfo
if err := c.rpcClient.Call(ctx, c.destination, "gpu.list", nil, &gpus); err != nil {
return nil, err
}
return gpus, nil
}

func (c *NodeClient) GetStoragePools(ctx context.Context) ([]pkg.PoolMetrics, error) {
var pools []pkg.PoolMetrics
if err := c.rpcClient.Call(ctx, c.destination, "storage.pools", nil, &pools); err != nil {
return nil, err
}
return pools, nil
}

func (c *NodeClient) GetStatistics(ctx context.Context) (pkg.Counters, error) {
var stats pkg.Counters
if err := c.rpcClient.Call(ctx, c.destination, "statistics", nil, &stats); err != nil {
return pkg.Counters{}, err
}
return stats, nil
}

func (c *NodeClient) GetLocation(ctx context.Context) (geoip.Location, error) {
var location geoip.Location
if err := c.rpcClient.Call(ctx, c.destination, "location.get", nil, &location); err != nil {
return geoip.Location{}, err
}
return location, nil
}
Loading