Skip to content
Snippets Groups Projects
generatePackage.py 9.65 KiB
Newer Older
#!/usr/bin/env python3
from __future__ import annotations

import os
import string
import random
import argparse
import re
from collections.abc import Sequence
# Generates a random string
def random_string(stringLength=4):
    letters = string.ascii_lowercase
    return ''.join(random.choice(letters) for i in range(stringLength))


# Generate a list of all ports servers and gateways occupy. Doing this as a
# separate step because their configs need every one listed, and generating them
# once is lighter on CPU cycles. Takes an offset to ensure no port collisions
# occur with existing packages
def create_ports_list(offset, manualOffset=0):
    # Array of integers for ports of each server and gateway in the network
    gateway_ports = []
    node_ports = []
    node_regCodes = []

    for i in range(nodes):
        gateway_ports.append(1000 + 10 * offset + manualOffset + i)
        node_ports.append(10000 + 10 * offset + i)

        regCode = random_string()
        # If this regCode is already in the list, we loop until we get one that
        # isn't
        while regCode in node_regCodes:
            regCode = random_string()
        node_regCodes.append(regCode)
    permissioningPort = 20000 + 10 * offset
    udbPort = 30000 + 10 * offset
    return gateway_ports, node_ports, permissioningPort, udbPort, node_regCodes

# Generate server and gateway configs
def generate_server_side_config(offset: int, newPackage: string):

    # Open gateway template
    gateway_template = ""
    with open("gen/gateway.yaml") as f:
        gateway_template = f.read()

    # Open network config
    network_config = ""
    with open("gen/network.config") as f:
        network_config = f.read()

    # Open no errors template
    no_errors = ""
    with open("gen/noerrors.txt") as f:
        no_errors = f.read()

Josh Brooks's avatar
Josh Brooks committed
    # Open whitelist template
    whitelist = ""
    with open("gen/whitelist.txt") as f:
        whitelist = f.read()

    # Open release template
    release_template = ""
    with open("gen/release.txt") as f:
        release_template = f.read()

    # Open mainnet template
    mainnet_template = ""
    with open("gen/mainnet.txt") as f:
        mainnet_template = f.read()

    # Open devnet template
    devnet_template = ""
    with open("gen/devnet.txt") as f:
        devnet_template = f.read()

    #Open betanet template
    betanet_template = ""
    with open("gen/betanet.txt") as f:
        betanet_template = f.read()

    # Open permissioning template
    reg_template = ""
    with open("gen/permissioning.yaml") as f:
        reg_template = f.read()

    # Open client-registrar
    client_reg_template = ""
    with open("gen/client-registrar.yaml") as f:
        client_reg_template = f.read()

    # Open server template
    server_template = ""
    with open("gen/server.yaml") as f:
        server_template = f.read()


    # Open run script template
    run_template=""
    with open("gen/run.sh") as f:
        run_template = f.read()

    # Open udb config
    udb_config = ""
    with open("gen/udb.yaml") as f:
        udb_config = f.read()
    # Open udb contact
    udb_contact = ""
    with open("gen/udbContact.bin") as f:
        udb_contact = f.read()
    reg_json = ""
    with open("gen/registration.json") as f:
        reg_json = f.read()
    # Open udb proto file
    udb_proto = ""
    with open("gen/udbProto.json") as f:
        udb_proto = f.read()

    # Create package
    if not os.path.exists(newPackage):
        os.makedirs(newPackage)
    # Create gold sub-directory
    if not os.path.exists("{}/clients.goldoutput/".format(newPackage)):
        os.makedirs("{}/clients.goldoutput/".format(newPackage))
    gateway_ports, node_ports, perm_port, udbPort, node_regCodes = create_ports_list(offset)

    for i in range(nodes):
        with open("{}/server-{}.yaml".format(newPackage, i+1), 'w') as f:
            # Array of strings defining node and gateway IPs and ports
            node_addrs = []
            node_addrs.append("\"{}\"".format(node_ports[i]))

            # Create a new config based on template
            s_config = server_template.replace("server-1", "server-" + str(i+1)) \
                .replace("gateway-1", "gateway-" + str(i)) \
                .replace("{NODE_ADDR}", "\r\n".join(node_addrs)) \
                .replace("{DB_ADDR}", "".join(["\"\""])) \
                .replace("AAAA", node_regCodes[i]) \
                .replace("nodeID-1.json", "nodeID-"+str(i)+".json") \
                .replace("errServer-0.txt", "errServer-"+str(i)+".txt") \
                .replace("{permissioning_port}", str(perm_port))
        with open("{}/gateway-{}.yaml".format(newPackage, i+1), 'w') as f:
            # Array of strings defining node and gateway IPs and ports
            node_addrs = []
            node_addrs.append(" \"0.0.0.0:{}\"".format(node_ports[i]))

            # Create a new config based on template
            g_config = gateway_template.replace("server-1", "server-" + str(i+1)) \
                .replace("gateway-1", "gateway-" + str(i+1)) \
                .replace("{GW_ADDR}", str(gateway_ports[i])) \
                .replace("{NODE_ADDR}", "\r\n".join(node_addrs)) \
                .replace("gatewayIDF-0", "gatewayIDF-" + str(i))

            f.write(g_config)



    # Generate regCodes file
    with open("{}/regCodes.json".format(newPackage), "w") as f:
        f.write("[")

        for i in range(nodes):
            f.write("{\"RegCode\": \"" + node_regCodes[i] + "\", \"Order\": \"" + \
                "CR" + "\"}")
            # If not the last element, write a comma
            if i is not (nodes - 1):
                f.write(",")

        f.write("]")


    # Generate network config
    with open("{}/network.config".format(newPackage), "w") as f:
        network_config = network_config.replace("{entry_point}", str(gateway_ports[0]))
        f.write(network_config)

    # Generate permissioning config
    with open("{}/permissioning.yaml".format(newPackage), "w") as f:
        reg_template = reg_template.replace("{permissioning_port}", str(perm_port))  \
            .replace("{udb_port}", str(udbPort))\
            .replace("{registration_port}", str(perm_port+1))
        f.write(reg_template)
   # Generate registration configs
    with open("{}/registration.json".format(newPackage), "w") as f:
        f.write(reg_json)

    with open("{}/client-registrar.yaml".format(newPackage), "w") as f:
        client_reg_template = client_reg_template.replace("{registration_port}", str(perm_port+1))
        f.write(client_reg_template)
    with open("{}/noerrors.txt".format(newPackage), "w") as f:
        f.write(no_errors)

    if not os.path.exists("{}/run.sh".format(newPackage)):
        with open("{}/run.sh".format(newPackage), "w") as f:
            run_template = run_template.replace("{entry_point}", str(gateway_ports[0]))
            f.write(run_template)
    else:
        with open("{}/run.sh".format(newPackage), "r") as f:
            filedata = f.read()
        newdata = re.sub(r"(localhost:)(\d+)", f"localhost:{str(gateway_ports[0])}", filedata)
        with open("{}/run.sh".format(newPackage), "w") as f:
            f.write(newdata)


    # Set the executable permissions on the bash script file
    os.chmod("{}/run.sh".format(newPackage), 0o755)

    
Josh Brooks's avatar
Josh Brooks committed
    # Write whitelist to package
    with open("{}/whitelist.txt".format(newPackage), "w") as f:
        f.write(whitelist)

    # Write release to package
    with open("{}/release.txt".format(newPackage), "w") as f:
        f.write(release_template)

    # Write mainnet to package
    with open("{}/mainnet.txt".format(newPackage), "w") as f:
        f.write(mainnet_template)

    # Write devnet to package
    with open("{}/devnet.txt".format(newPackage), "w") as f:
        f.write(devnet_template)

   # Write betanet to package
    with open("{}/betanet.txt".format(newPackage), "w") as f:
        f.write(betanet_template)


    # Write udb config
    with open("{}/udb.yaml".format(newPackage), "w") as f:
        udb_config = udb_config.replace("{permissioning_port}", str(perm_port))  \
            .replace("{udb_port}", str(udbPort))
        f.write(udb_config)

    with open("{}/udbContact.bin".format(newPackage), "w") as f:
        f.write(udb_contact)

    with open("{}/udbProto.json".format(newPackage), "w") as f:
        f.write(udb_proto)





# Count the number of packages previously created by counting
# run.sh files creates
def count_networks():
    current_dir = os.getcwd()
    count = 0
    for root, dirs, files in os.walk(current_dir):
        for file in files:
            if file == "permissioning.yaml":
                count += 1
    return count


def main(argv: Sequence[str] | None = None) -> int:
    network_count = count_networks()
    parser = argparse.ArgumentParser(description='Generate or count packages')
    subparsers = parser.add_subparsers(title='subcommands', dest='command')
    # "generate" subcommand
    generate_parser = subparsers.add_parser('generate', help='Generate packages')
    generate_parser.add_argument('--package', required=True, help='Name of the package')
    generate_parser.add_argument('--offset', type=int, default=0, help='Offset value')
    # "count" subcommand
    count_parser = subparsers.add_parser('count', help='Count packages')
    # parse the arguments
    args = parser.parse_args()

    if args.command == "count":
        print(f"Number of occurrences of run.sh in all subdirectories: {network_count}")
        return
    elif args.command == "generate":
        generate_server_side_config(network_count + args.offset, args.package)
    else:
        raise NotImplementedError(
            f"Command {args.command} does not exist.",
        )



if __name__ == "__main__":
    raise SystemExit(main())