Skip to content
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
41 changes: 41 additions & 0 deletions PasarGuardNodeBridge/abstract_node.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,47 @@ async def sync_users_chunked(
) -> list[service.User]:
raise NotImplementedError

@abstractmethod
async def list_routing_rules(self, timeout: int | None = None) -> service.RoutingRulesResponse | None:
raise NotImplementedError

@abstractmethod
async def get_balancer_info(self, tag: str, timeout: int | None = None) -> service.BalancerInfoResponse | None:
raise NotImplementedError

@abstractmethod
async def test_route(
self,
inbound_tag: str = "",
network: str = "",
target_ip: str = "",
target_domain: str = "",
target_port: int = 0,
protocol: str = "",
user: str = "",
attributes: dict[str, str] | None = None,
field_selectors: list[str] | None = None,
publish_result: bool = False,
timeout: int | None = None,
) -> service.RouteResult | None:
raise NotImplementedError

@abstractmethod
async def add_routing_rule(
self, rule: str, should_reset: bool = False, timeout: int | None = None
) -> service.Empty | None:
raise NotImplementedError

@abstractmethod
async def remove_routing_rule(self, rule_tag: str, timeout: int | None = None) -> service.Empty | None:
raise NotImplementedError

@abstractmethod
async def override_balancer_target(
self, balancer_tag: str, target: str, timeout: int | None = None
) -> service.Empty | None:
raise NotImplementedError

@abstractmethod
async def _check_node_health(self):
raise NotImplementedError
Expand Down
53 changes: 53 additions & 0 deletions PasarGuardNodeBridge/common/service.proto
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,52 @@ message UsersChunk {
bool last = 3;
}

// Routing (mirrors xray app/router/command, node-friendly shapes)
message RoutingRule {
string outbound_tag = 1;
string rule_tag = 2;
}
message RoutingRulesResponse { repeated RoutingRule rules = 1; }

message BalancerInfoRequest { string tag = 1; }
message BalancerInfoResponse {
string override_target = 1;
repeated string principle_target = 2;
}

message TestRouteRequest {
string inbound_tag = 1;
string network = 2; // "tcp" | "udp"
string target_ip = 3;
string target_domain = 4;
uint32 target_port = 5;
string protocol = 6;
string user = 7;
map<string, string> attributes = 8;
repeated string field_selectors = 9;
bool publish_result = 10;
}
message RouteResult {
string outbound_tag = 1;
repeated string outbound_group_tags = 2;
string inbound_tag = 3;
string network = 4;
string target_domain = 5;
}

message AddRoutingRuleRequest {
string rule = 1; // JSON for one xray routing rule (same shape as routing.rules[])
// false (default) appends the rule, keeping existing rules; true resets the
// router (clears all rules + balancers) before adding. Default is the safe,
// non-destructive behavior.
bool should_reset = 2;
}
message RemoveRoutingRuleRequest { string rule_tag = 1; }
message OverrideBalancerTargetRequest {
string balancer_tag = 1;
string target = 2;
}

// Service for node management and connection
service NodeService {
rpc Start(Backend) returns (BaseInfoResponse) {}
Expand All @@ -182,4 +228,11 @@ service NodeService {
rpc SyncUser(stream User) returns (Empty) {}
rpc SyncUsers(Users) returns (Empty) {}
rpc SyncUsersChunked(stream UsersChunk) returns (Empty) {}

rpc ListRoutingRules(Empty) returns (RoutingRulesResponse) {}
rpc GetBalancerInfo(BalancerInfoRequest) returns (BalancerInfoResponse) {}
rpc TestRoute(TestRouteRequest) returns (RouteResult) {}
rpc AddRoutingRule(AddRoutingRuleRequest) returns (Empty) {}
rpc RemoveRoutingRule(RemoveRoutingRuleRequest) returns (Empty) {}
rpc OverrideBalancerTarget(OverrideBalancerTargetRequest) returns (Empty) {}
}
96 changes: 96 additions & 0 deletions PasarGuardNodeBridge/common/service_grpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,30 @@ async def SyncUsers(self, stream: 'grpclib.server.Stream[PasarGuardNodeBridge.co
async def SyncUsersChunked(self, stream: 'grpclib.server.Stream[PasarGuardNodeBridge.common.service_pb2.UsersChunk, PasarGuardNodeBridge.common.service_pb2.Empty]') -> None:
pass

@abc.abstractmethod
async def ListRoutingRules(self, stream: 'grpclib.server.Stream[PasarGuardNodeBridge.common.service_pb2.Empty, PasarGuardNodeBridge.common.service_pb2.RoutingRulesResponse]') -> None:
pass

@abc.abstractmethod
async def GetBalancerInfo(self, stream: 'grpclib.server.Stream[PasarGuardNodeBridge.common.service_pb2.BalancerInfoRequest, PasarGuardNodeBridge.common.service_pb2.BalancerInfoResponse]') -> None:
pass

@abc.abstractmethod
async def TestRoute(self, stream: 'grpclib.server.Stream[PasarGuardNodeBridge.common.service_pb2.TestRouteRequest, PasarGuardNodeBridge.common.service_pb2.RouteResult]') -> None:
pass

@abc.abstractmethod
async def AddRoutingRule(self, stream: 'grpclib.server.Stream[PasarGuardNodeBridge.common.service_pb2.AddRoutingRuleRequest, PasarGuardNodeBridge.common.service_pb2.Empty]') -> None:
pass

@abc.abstractmethod
async def RemoveRoutingRule(self, stream: 'grpclib.server.Stream[PasarGuardNodeBridge.common.service_pb2.RemoveRoutingRuleRequest, PasarGuardNodeBridge.common.service_pb2.Empty]') -> None:
pass

@abc.abstractmethod
async def OverrideBalancerTarget(self, stream: 'grpclib.server.Stream[PasarGuardNodeBridge.common.service_pb2.OverrideBalancerTargetRequest, PasarGuardNodeBridge.common.service_pb2.Empty]') -> None:
pass

def __mapping__(self) -> typing.Dict[str, grpclib.const.Handler]:
return {
'/service.NodeService/Start': grpclib.const.Handler(
Expand Down Expand Up @@ -146,6 +170,42 @@ def __mapping__(self) -> typing.Dict[str, grpclib.const.Handler]:
PasarGuardNodeBridge.common.service_pb2.UsersChunk,
PasarGuardNodeBridge.common.service_pb2.Empty,
),
'/service.NodeService/ListRoutingRules': grpclib.const.Handler(
self.ListRoutingRules,
grpclib.const.Cardinality.UNARY_UNARY,
PasarGuardNodeBridge.common.service_pb2.Empty,
PasarGuardNodeBridge.common.service_pb2.RoutingRulesResponse,
),
'/service.NodeService/GetBalancerInfo': grpclib.const.Handler(
self.GetBalancerInfo,
grpclib.const.Cardinality.UNARY_UNARY,
PasarGuardNodeBridge.common.service_pb2.BalancerInfoRequest,
PasarGuardNodeBridge.common.service_pb2.BalancerInfoResponse,
),
'/service.NodeService/TestRoute': grpclib.const.Handler(
self.TestRoute,
grpclib.const.Cardinality.UNARY_UNARY,
PasarGuardNodeBridge.common.service_pb2.TestRouteRequest,
PasarGuardNodeBridge.common.service_pb2.RouteResult,
),
'/service.NodeService/AddRoutingRule': grpclib.const.Handler(
self.AddRoutingRule,
grpclib.const.Cardinality.UNARY_UNARY,
PasarGuardNodeBridge.common.service_pb2.AddRoutingRuleRequest,
PasarGuardNodeBridge.common.service_pb2.Empty,
),
'/service.NodeService/RemoveRoutingRule': grpclib.const.Handler(
self.RemoveRoutingRule,
grpclib.const.Cardinality.UNARY_UNARY,
PasarGuardNodeBridge.common.service_pb2.RemoveRoutingRuleRequest,
PasarGuardNodeBridge.common.service_pb2.Empty,
),
'/service.NodeService/OverrideBalancerTarget': grpclib.const.Handler(
self.OverrideBalancerTarget,
grpclib.const.Cardinality.UNARY_UNARY,
PasarGuardNodeBridge.common.service_pb2.OverrideBalancerTargetRequest,
PasarGuardNodeBridge.common.service_pb2.Empty,
),
}


Expand Down Expand Up @@ -230,3 +290,39 @@ def __init__(self, channel: grpclib.client.Channel) -> None:
PasarGuardNodeBridge.common.service_pb2.UsersChunk,
PasarGuardNodeBridge.common.service_pb2.Empty,
)
self.ListRoutingRules = grpclib.client.UnaryUnaryMethod(
channel,
'/service.NodeService/ListRoutingRules',
PasarGuardNodeBridge.common.service_pb2.Empty,
PasarGuardNodeBridge.common.service_pb2.RoutingRulesResponse,
)
self.GetBalancerInfo = grpclib.client.UnaryUnaryMethod(
channel,
'/service.NodeService/GetBalancerInfo',
PasarGuardNodeBridge.common.service_pb2.BalancerInfoRequest,
PasarGuardNodeBridge.common.service_pb2.BalancerInfoResponse,
)
self.TestRoute = grpclib.client.UnaryUnaryMethod(
channel,
'/service.NodeService/TestRoute',
PasarGuardNodeBridge.common.service_pb2.TestRouteRequest,
PasarGuardNodeBridge.common.service_pb2.RouteResult,
)
self.AddRoutingRule = grpclib.client.UnaryUnaryMethod(
channel,
'/service.NodeService/AddRoutingRule',
PasarGuardNodeBridge.common.service_pb2.AddRoutingRuleRequest,
PasarGuardNodeBridge.common.service_pb2.Empty,
)
self.RemoveRoutingRule = grpclib.client.UnaryUnaryMethod(
channel,
'/service.NodeService/RemoveRoutingRule',
PasarGuardNodeBridge.common.service_pb2.RemoveRoutingRuleRequest,
PasarGuardNodeBridge.common.service_pb2.Empty,
)
self.OverrideBalancerTarget = grpclib.client.UnaryUnaryMethod(
channel,
'/service.NodeService/OverrideBalancerTarget',
PasarGuardNodeBridge.common.service_pb2.OverrideBalancerTargetRequest,
PasarGuardNodeBridge.common.service_pb2.Empty,
)
Loading