mirror of
https://github.com/Drop-OSS/libtailscale-drop.git
synced 2026-02-04 06:51:18 +01:00
ruby: add initial support for making local API requests
This commit is contained in:
@@ -39,6 +39,7 @@ class Tailscale
|
||||
attach_function :TsnetListenerClose, [:int], :int
|
||||
attach_function :TsnetAccept, [:int, :pointer], :int, blocking: true
|
||||
attach_function :TsnetErrmsg, [:int, :pointer, :size_t], :int
|
||||
attach_function :TsnetLoopbackAPI, [:int, :pointer, :size_t, :pointer], :int
|
||||
end
|
||||
|
||||
class ClosedError < StandardError
|
||||
@@ -93,6 +94,72 @@ class Tailscale
|
||||
end
|
||||
end
|
||||
|
||||
# LocalAPIClient provides a Net::HTTP-alike API that can be used to make
|
||||
# authenticated requests to the local tailscale API. For higher level use,
|
||||
# +LocalAPI+ may be more convenient.
|
||||
class LocalAPIClient
|
||||
# address is the host:port address of the nodes LocalAPI server.
|
||||
attr_reader :address
|
||||
# credential is the basic-auth password used to authenticate requests.
|
||||
attr_reader :credential
|
||||
|
||||
def initialize(addr, cred)
|
||||
@address = addr
|
||||
@credential = cred
|
||||
@basic = Base64.strict_encode64(":#{cred}")
|
||||
host, _, port = addr.rpartition(":")
|
||||
@http = Net::HTTP.new(host, port)
|
||||
end
|
||||
|
||||
def head(path, initheader = nil, &block)
|
||||
request Net::HTTP::Head.new(path, initheader), &block
|
||||
end
|
||||
|
||||
def get(path, initheader = nil, &block)
|
||||
request Net::HTTP::Get.new(path, initheader), &block
|
||||
end
|
||||
|
||||
def post(path, body = nil, initheader = nil, &block)
|
||||
request Net::HTTP::Post.new(path, initheader), body, &block
|
||||
end
|
||||
|
||||
def put(path, body = nil, initheader = nil, &block)
|
||||
request Net::HTTP::Put.new(path, initheader), body, &block
|
||||
end
|
||||
|
||||
def patch(path, body = nil, initheader = nil, &block)
|
||||
request Net::HTTP::Patch.new(path, initheader), body, &block
|
||||
end
|
||||
|
||||
def delete(path, initheader = nil, &block)
|
||||
request Net::HTTP::Delete.new(path, initheader), &block
|
||||
end
|
||||
|
||||
def request(req, body = nil, &block)
|
||||
req["Host"] = @address
|
||||
req["Authorization"] = "Basic #{@basic}"
|
||||
req["Sec-Tailscale"] = "localapi"
|
||||
@http.request(req, body, &block)
|
||||
end
|
||||
end
|
||||
|
||||
# LocalAPI provides a convenient interface for interacting with a LocalAPI given a
|
||||
# LocalAPIClient to make requests with.
|
||||
class LocalAPI
|
||||
|
||||
def initialize(client)
|
||||
@client = client
|
||||
end
|
||||
|
||||
# status returns the status of the local tailscale node.
|
||||
def status
|
||||
@client.get("/localapi/v0/status") do |r|
|
||||
return JSON.parse(r.body)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# Create a new tailscale server.
|
||||
#
|
||||
# The server is not started, and no network traffic will occur until start
|
||||
@@ -176,6 +243,27 @@ class Tailscale
|
||||
Listener.new self, listener.read_int
|
||||
end
|
||||
|
||||
# Start a LocalAPI listener on a loopback address, and returns the address
|
||||
# and password credential string for the instance.
|
||||
def loopback_api
|
||||
assert_open
|
||||
addrbuf = FFI::MemoryPointer.new(:char, 1024)
|
||||
credbuf = FFI::MemoryPointer.new(:char, 33)
|
||||
Error.check self, Libtailscale::TsnetLoopbackAPI(@t, addrbuf, addrbuf.size, credbuf)
|
||||
[addrbuf.read_string, credbuf.read_string]
|
||||
end
|
||||
|
||||
# Start the local API and return a LocalAPIClient for interacting with it.
|
||||
def local_api_client
|
||||
addr, cred = loopback_api
|
||||
LocalAPIClient.new(addr, cred)
|
||||
end
|
||||
|
||||
# Start the local API and return a LocalAPI for interacting with it.
|
||||
def local_api
|
||||
LocalAPI.new(local_api_client)
|
||||
end
|
||||
|
||||
# Get the last detailed error message from the tailscale server. This method
|
||||
# is typically not needed by user code, as the library will raise an
|
||||
# +Error+ with the error message.
|
||||
|
||||
Reference in New Issue
Block a user