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
htuch 8 years ago committed by GitHub
parent 633a80eb8e
commit bafed453b3
  1. 4
      examples/service_envoy/listeners.pb
  2. 9
      tools/BUILD
  3. 69
      tools/generate_listeners.py

@ -1,6 +1,6 @@
listeners {
resolved_address {
socket_address {
address {
named_address {
protocol: TCP
port {
value: 80

@ -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…
Cancel
Save