tools: generate_listeners. (#46)
This tool will take a LDS response message with holes where opaque filter configs should go, and fill them with the Struct equivalent of the protos supplied for the filter configs. It emits both output text proto and JSON. To generate example output listeners.pb and listeners.json, run bazel build //examples/service_envoy:listeners_files.pull/53/head
parent
633a80eb8e
commit
bafed453b3
3 changed files with 80 additions and 2 deletions
@ -0,0 +1,9 @@ |
||||
py_binary( |
||||
name = "generate_listeners", |
||||
srcs = ["generate_listeners.py"], |
||||
deps = [ |
||||
"//api:lds_py", |
||||
"//api/filter:http_connection_manager_py", |
||||
], |
||||
visibility = ["//visibility:public"], |
||||
) |
@ -0,0 +1,69 @@ |
||||
# Map from listeners proto, with holes where filter config fragments should go, and |
||||
# a list of filter config fragment protos, to a final listeners.pb with the |
||||
# config fragments converted to the opaque Struct representation. |
||||
|
||||
import sys |
||||
|
||||
# Some evil hack to deal with the fact that Bazel puts both google/api and |
||||
# google/protobuf roots in the sys.path, and Python gets confused, e.g. it |
||||
# thinks that there is no api package if it encounters the google/protobuf root |
||||
# in sys.path first. |
||||
from pkgutil import extend_path |
||||
import google |
||||
google.__path__ = extend_path(google.__path__, google.__name__) |
||||
|
||||
from google.protobuf import json_format |
||||
from google.protobuf import struct_pb2 |
||||
from google.protobuf import text_format |
||||
|
||||
from api import lds_pb2 |
||||
from api.filter import http_connection_manager_pb2 |
||||
|
||||
|
||||
# Convert an arbitrary proto object to its Struct proto representation. |
||||
def ProtoToStruct(proto): |
||||
json_rep = json_format.MessageToJson(proto) |
||||
parsed_msg = struct_pb2.Struct() |
||||
json_format.Parse(json_rep, parsed_msg) |
||||
return parsed_msg |
||||
|
||||
|
||||
# Parse a proto from the filesystem. |
||||
def ParseProto(path, filter_name): |
||||
# We only know about some filter config protos ahead of time. |
||||
KNOWN_FILTERS = { |
||||
'http_connection_manager': |
||||
lambda: http_connection_manager_pb2.HttpConnectionManager() |
||||
} |
||||
filter_config = KNOWN_FILTERS[filter_name]() |
||||
with open(path, 'r') as f: |
||||
text_format.Merge(f.read(), filter_config) |
||||
return filter_config |
||||
|
||||
|
||||
if __name__ == '__main__': |
||||
if len(sys.argv) < 4: |
||||
print( |
||||
'Usage: %s <path to listeners.pb> <output listeners.pb> <output ' |
||||
'listeners.json> <filter config fragment paths>') % sys.argv[0] |
||||
sys.exit(1) |
||||
|
||||
listeners_path = sys.argv[1] |
||||
output_pb_path = sys.argv[2] |
||||
output_json_path = sys.argv[3] |
||||
fragments = iter(sys.argv[4:]) |
||||
|
||||
listener_discover_response = lds_pb2.ListenerDiscoverResponse() |
||||
with open(listeners_path, 'r') as f: |
||||
text_format.Merge(f.read(), listener_discover_response) |
||||
|
||||
for listener in listener_discover_response.listeners: |
||||
for filter_chain in listener.filter_chains: |
||||
for f in filter_chain.filter_chain: |
||||
f.config.CopyFrom(ProtoToStruct(ParseProto(fragments.next(), f.name))) |
||||
|
||||
with open(output_pb_path, 'w') as f: |
||||
f.write(str(listener)) |
||||
|
||||
with open(output_json_path, 'w') as f: |
||||
f.write(json_format.MessageToJson(listener)) |
Loading…
Reference in new issue