Hub client
The hub client is the part of every node that connects it to a hub server, the control plane that lets connected nodes find and manage each other. Use this service to sign the node hosting the API in to a hub server, disconnect it, follow its connection state, and read or change the details of nodes.
Get local node id
Get the ID of the node hosting the API, and whether it is authenticated with a hub server.
- REST
- gRPC
/v1/hub-client/local-node-id- TypeScript
- Python
- curl
import { NanopingClient } from "@nanoping/api";
const client = new NanopingClient({ baseUrl: "http://127.0.0.1:10565" });
const response = await client.hubClient.getLocalNodeId();
from nanoping_api import NanopingClient
client = NanopingClient("http://127.0.0.1:10565")
response = client.hub_client.get_local_node_id()
curl 'http://127.0.0.1:10565/v1/hub-client/local-node-id'
nodeIdstringId of the node hosting the API.
isAuthenticatedboolTrue if the node holds a sign-in to a hub server. It may still be disconnected from it at the moment.
rpc getLocalNodeId(GetLocalNodeIdRequest) returns (GetLocalNodeIdResponse)
Method /nanopinggrpc.hub.HubClientService/getLocalNodeId
No fields.
node_idstringId of the node hosting the API.
is_authenticatedboolTrue if the node holds a sign-in to a hub server. It may still be disconnected from it at the moment.
- Go
- Go (generated gRPC)
import (
client "github.com/nanoping-labs/nanoping-api-go/v11"
"github.com/nanoping-labs/nanoping-api-go/v11/hub_client"
)
c, err := client.Connect("127.0.0.1:10432")
defer c.Close()
response, err := c.HubClient.GetLocalNodeId(ctx, &hub_client.GetLocalNodeIdRequest{})
import (
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"github.com/nanoping-labs/nanoping-api-go/v11/hub_client"
)
conn, err := grpc.NewClient("127.0.0.1:10432", grpc.WithTransportCredentials(insecure.NewCredentials()))
defer conn.Close()
stub := hub_client.NewHubClientServiceClient(conn)
response, err := stub.GetLocalNodeId(ctx, &hub_client.GetLocalNodeIdRequest{})
Get node
Get the details of a node. Fails with Unavailable when the node cannot be reached.
- REST
- gRPC
/v1/nodes/{node_id}node_idstringId of the node to get information about, for example the id returned by getLocalNodeId.
- TypeScript
- Python
- curl
import { NanopingClient } from "@nanoping/api";
const client = new NanopingClient({ baseUrl: "http://127.0.0.1:10565" });
const response = await client.hubClient.getNode({
nodeId: "3f2b1c9e-8d4a-4f6b-9c2e-1a7d5e8b0c4f"
});
from nanoping_api import NanopingClient
client = NanopingClient("http://127.0.0.1:10565")
response = client.hub_client.get_node(node_id="3f2b1c9e-8d4a-4f6b-9c2e-1a7d5e8b0c4f")
curl 'http://127.0.0.1:10565/v1/nodes/<node_id>'
nodeNodeInformation about the node.
rpc getNode(GetNodeRequest) returns (GetNodeResponse)
Method /nanopinggrpc.hub.HubClientService/getNode
node_idstringId of the node to get information about, for example the id returned by getLocalNodeId.
nodeNodeInformation about the node.
- Go
- Go (generated gRPC)
import (
client "github.com/nanoping-labs/nanoping-api-go/v11"
"github.com/nanoping-labs/nanoping-api-go/v11/hub_client"
)
c, err := client.Connect("127.0.0.1:10432")
defer c.Close()
response, err := c.HubClient.GetNode(ctx, &hub_client.GetNodeRequest{
NodeId: "3f2b1c9e-8d4a-4f6b-9c2e-1a7d5e8b0c4f",
})
import (
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"github.com/nanoping-labs/nanoping-api-go/v11/hub_client"
)
conn, err := grpc.NewClient("127.0.0.1:10432", grpc.WithTransportCredentials(insecure.NewCredentials()))
defer conn.Close()
stub := hub_client.NewHubClientServiceClient(conn)
response, err := stub.GetNode(ctx, &hub_client.GetNodeRequest{
NodeId: "3f2b1c9e-8d4a-4f6b-9c2e-1a7d5e8b0c4f",
})
Set node
Change the details of a node, replacing the current values. Fails with PermissionDenied when the node's configuration comes from a config file.
- REST
- gRPC
/v1/nodes/{node_id}node_idstringId of the node to change.
namestringNew name of the node. Example:
edge-node-1metadataNodeMetadataNew metadata of the node. Replaces all existing metadata, so leaving it empty removes the metadata.
- TypeScript
- Python
- curl
import { NanopingClient } from "@nanoping/api";
const client = new NanopingClient({ baseUrl: "http://127.0.0.1:10565" });
const response = await client.hubClient.setNode({
nodeId: "3f2b1c9e-8d4a-4f6b-9c2e-1a7d5e8b0c4f",
name: "edge-node-1",
metadata: {
items: {
key: {
bytesValue: ""
}
}
}
});
from nanoping_api import NanopingClient, NodeMetadata, NodeMetadataItem
client = NanopingClient("http://127.0.0.1:10565")
response = client.hub_client.set_node(
node_id="3f2b1c9e-8d4a-4f6b-9c2e-1a7d5e8b0c4f",
name="edge-node-1",
metadata=NodeMetadata(items={"key": NodeMetadataItem(string_value="example")}),
)
curl -X PUT 'http://127.0.0.1:10565/v1/nodes/<node_id>' \
-H 'Content-Type: application/json' \
-d '{
"name": "edge-node-1",
"metadata": {
"items": {
"key": {
"bytesValue": ""
}
}
}
}'
nodeNodeThe node information after the change.
rpc setNode(SetNodeRequest) returns (SetNodeResponse)
Method /nanopinggrpc.hub.HubClientService/setNode
node_idstringId of the node to change.
namestringNew name of the node. Example:
edge-node-1metadataNodeMetadataNew metadata of the node. Replaces all existing metadata, so leaving it empty removes the metadata.
nodeNodeThe node information after the change.
- Go
- Go (generated gRPC)
import (
client "github.com/nanoping-labs/nanoping-api-go/v11"
"github.com/nanoping-labs/nanoping-api-go/v11/hub_client"
"github.com/nanoping-labs/nanoping-api-go/v11/hub_node"
)
c, err := client.Connect("127.0.0.1:10432")
defer c.Close()
response, err := c.HubClient.SetNode(ctx, &hub_client.SetNodeRequest{
NodeId: "3f2b1c9e-8d4a-4f6b-9c2e-1a7d5e8b0c4f",
Name: "edge-node-1",
Metadata: &hub_node.NodeMetadata{
Items: map[string]*hub_node.NodeMetadataItem{
"key": &hub_node.NodeMetadataItem{
Value: &hub_node.NodeMetadataItem_StringValue{StringValue: "example"},
},
},
},
})
import (
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"github.com/nanoping-labs/nanoping-api-go/v11/hub_client"
"github.com/nanoping-labs/nanoping-api-go/v11/hub_node"
)
conn, err := grpc.NewClient("127.0.0.1:10432", grpc.WithTransportCredentials(insecure.NewCredentials()))
defer conn.Close()
stub := hub_client.NewHubClientServiceClient(conn)
response, err := stub.SetNode(ctx, &hub_client.SetNodeRequest{
NodeId: "3f2b1c9e-8d4a-4f6b-9c2e-1a7d5e8b0c4f",
Name: "edge-node-1",
Metadata: &hub_node.NodeMetadata{
Items: map[string]*hub_node.NodeMetadataItem{
"key": &hub_node.NodeMetadataItem{
Value: &hub_node.NodeMetadataItem_StringValue{StringValue: "example"},
},
},
},
})
Authenticate by request
Ask a hub server to authenticate the node hosting the API, and wait for the hub server to accept or reject the request. On success the node stays authenticated, also after a restart. Fails with AlreadyExists if the node is already authenticated, Unauthenticated if the request was rejected, DeadlineExceeded if the hub server did not answer in time, Unavailable if the hub server could not be reached, and NotFound if the hub server does not accept authentication by request.
Joining a hub takes two sides. Call this on the node that should join. The call waits while the request is shown on the hub server, where it is approved or rejected: in the dashboard, with np authentication-requests, or with authentication by requests. When the call returns without an error, the node is part of the hub.
- REST
- gRPC
/v1/hub-client/authenticate-by-requesthubServerAddressstringHTTP or HTTPS address of the hub server. Example:
http://127.0.0.1:8769
- TypeScript
- Python
- curl
import { ApiError, Code, NanopingClient, joinHub } from "@nanoping/api";
const client = new NanopingClient({ baseUrl: "http://127.0.0.1:10565" });
try {
// Waits until the request is approved or rejected on the hub server.
await joinHub(client, "http://127.0.0.1:8769");
} catch (error) {
if (error instanceof ApiError && error.code === Code.Unauthenticated) {
throw new Error("The hub server rejected the node");
}
throw error;
}
// The node is part of the hub now, and stays so after a restart.
from nanoping_api import ApiError, Code, NanopingClient
client = NanopingClient("http://127.0.0.1:10565")
try:
# Waits until the request is approved or rejected on the hub server.
client.join_hub("http://127.0.0.1:8769")
except ApiError as error:
if error.code == Code.UNAUTHENTICATED:
raise RuntimeError("The hub server rejected the node") from error
raise
# The node is part of the hub now, and stays so after a restart.
# Waits until the request is approved or rejected on the hub server.
curl -X POST 'http://127.0.0.1:10565/v1/hub-client/authenticate-by-request' \
-H 'Content-Type: application/json' \
-d '{"hubServerAddress": "http://127.0.0.1:8769"}'
No fields.
rpc authenticateByRequest(AuthenticateByRequestRequest) returns (AuthenticateByRequestResponse)
Method /nanopinggrpc.hub.HubClientService/authenticateByRequest
hub_server_addressstringHTTP or HTTPS address of the hub server. Example:
http://127.0.0.1:8769
No fields.
- Go
- Go (generated gRPC)
import (
"errors"
client "github.com/nanoping-labs/nanoping-api-go/v11"
)
c, err := client.Connect("127.0.0.1:10432")
defer c.Close()
// Waits until the request is approved or rejected on the hub server.
err = c.JoinHub(ctx, "http://127.0.0.1:8769")
if errors.Is(err, client.ErrJoinRejected) {
return errors.New("the hub server rejected the node")
}
if err != nil {
return err
}
// The node is part of the hub now, and stays so after a restart.
import (
"github.com/nanoping-labs/nanoping-api-go/v11/hub_client"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/credentials/insecure"
"google.golang.org/grpc/status"
)
conn, err := grpc.NewClient("127.0.0.1:10432", grpc.WithTransportCredentials(insecure.NewCredentials()))
defer conn.Close()
stub := hub_client.NewHubClientServiceClient(conn)
// Waits until the request is approved or rejected on the hub server.
_, err = stub.AuthenticateByRequest(ctx, &hub_client.AuthenticateByRequestRequest{
HubServerAddress: "http://127.0.0.1:8769",
})
if status.Code(err) == codes.Unauthenticated {
return errors.New("the hub server rejected the node")
}
if err != nil {
return err
}
// The node is part of the hub now, and stays so after a restart.
Disconnect
Disconnect the node hosting the API from its hub server. The node always leaves, even if the hub server could not remove it from its list of nodes.
- REST
- gRPC
/v1/hub-client/disconnectNo fields.
- TypeScript
- Python
- curl
import { NanopingClient } from "@nanoping/api";
const client = new NanopingClient({ baseUrl: "http://127.0.0.1:10565" });
await client.hubClient.disconnect();
from nanoping_api import NanopingClient
client = NanopingClient("http://127.0.0.1:10565")
client.hub_client.disconnect()
curl -X POST 'http://127.0.0.1:10565/v1/hub-client/disconnect' \
-H 'Content-Type: application/json' \
-d '{}'
No fields.
rpc disconnect(DisconnectRequest) returns (DisconnectResponse)
Method /nanopinggrpc.hub.HubClientService/disconnect
No fields.
No fields.
- Go
- Go (generated gRPC)
import (
client "github.com/nanoping-labs/nanoping-api-go/v11"
"github.com/nanoping-labs/nanoping-api-go/v11/hub_client"
)
c, err := client.Connect("127.0.0.1:10432")
defer c.Close()
_, err = c.HubClient.Disconnect(ctx, &hub_client.DisconnectRequest{})
import (
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"github.com/nanoping-labs/nanoping-api-go/v11/hub_client"
)
conn, err := grpc.NewClient("127.0.0.1:10432", grpc.WithTransportCredentials(insecure.NewCredentials()))
defer conn.Close()
stub := hub_client.NewHubClientServiceClient(conn)
_, err = stub.Disconnect(ctx, &hub_client.DisconnectRequest{})
Stream connection state
Stream the connection state between the node hosting the API and its hub server. The current state is sent first, then a new message every time the state changes. The stream stays open until the caller closes it.
- REST
- gRPC
/v1/streams/hub-client/connection-stateServer-sent events. A : ready comment is sent when the stream is ready, then each message is a data: line holding the response below. A failure after that is an error event.
- TypeScript
- Python
- curl
import { NanopingClient } from "@nanoping/api";
const client = new NanopingClient({ baseUrl: "http://127.0.0.1:10565" });
for await (const response of client.hubClient.streamConnectionState()) {
}
from nanoping_api import NanopingClient
client = NanopingClient("http://127.0.0.1:10565")
for response in client.hub_client.stream_connection_state():
print(response)
curl -N 'http://127.0.0.1:10565/v1/streams/hub-client/connection-state'
stateConnectionStateThe current connection state.
rpc streamConnectionState(StreamConnectionStateRequest) returns (stream StreamConnectionStateResponse)
Method /nanopinggrpc.hub.HubClientService/streamConnectionState
No fields.
stateConnectionStateThe current connection state.
- Go
- Go (generated gRPC)
import (
client "github.com/nanoping-labs/nanoping-api-go/v11"
"github.com/nanoping-labs/nanoping-api-go/v11/hub_client"
)
c, err := client.Connect("127.0.0.1:10432")
defer c.Close()
stream, err := c.HubClient.StreamConnectionState(ctx, &hub_client.StreamConnectionStateRequest{})
for response, err := range client.Receive(stream) {
if err != nil {
return err
}
}
import (
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"github.com/nanoping-labs/nanoping-api-go/v11/hub_client"
)
conn, err := grpc.NewClient("127.0.0.1:10432", grpc.WithTransportCredentials(insecure.NewCredentials()))
defer conn.Close()
stub := hub_client.NewHubClientServiceClient(conn)
stream, err := stub.StreamConnectionState(ctx, &hub_client.StreamConnectionStateRequest{})
for {
response, err := stream.Recv()
if err != nil {
return err
}
}