Beispiel #1
0
def check_container_status_docker():
    """
    Checks and prints the calico/node container status when running in Docker.
    """
    try:
        calico_node_info = filter(lambda container: "/calico-node" in
                                  container["Names"],
                                  docker_client.containers())
        if len(calico_node_info) == 0:
            print "calico-node container not running"
            sys.exit(1)
        else:
            print "calico-node container is running. Status: %s" % \
                  calico_node_info[0]["Status"]

            libraries_cmd = docker_client.exec_create("calico-node",
                                                      ["sh", "-c",
                                                       "cat libraries.txt"])
            libraries_out = docker_client.exec_start(libraries_cmd)
            result = re.search(r"^calico\s*\((.*)\)\s*$", libraries_out,
                               re.MULTILINE)

            if result is not None:
                print "Running felix version %s" % result.group(1)
    except ConnectionError:
        print "Docker is not running"
        sys.exit(1)
Beispiel #2
0
def status(arguments):
    """
    Main dispatcher for status commands. Calls the corresponding helper
    function.

    :param arguments: A dictionary of arguments already processed through
    this file's docstring with docopt
    :return: None
    """
    calico_node_info = filter(lambda container: "/calico-node" in
                              container["Names"],
                              docker_client.containers())
    if len(calico_node_info) == 0:
        print "calico-node container not running"
    else:
        print "calico-node container is running. Status: %s" % \
              calico_node_info[0]["Status"]

        libraries_cmd = docker_client.exec_create("calico-node",
                                                  ["sh", "-c",
                                                   "cat libraries.txt"])
        libraries_out = docker_client.exec_start(libraries_cmd)
        result = re.search(r"^calico\s*\((.*)\)\s*$", libraries_out,
                           re.MULTILINE)

        if result is not None:
            print "Running felix version %s" % result.group(1)

        print "\nIPv4 BGP status"
        pprint_bird_protocols(4)
        print "IPv6 BGP status"
        pprint_bird_protocols(6)
Beispiel #3
0
def check_container_status_docker():
    """
    Checks and prints the calico/node container status when running in Docker. 
    """
    try:
        calico_node_info = filter(lambda container: "/calico-node" in
                                  container["Names"],
                                  docker_client.containers())
        if len(calico_node_info) == 0:
            print "calico-node container not running"
            sys.exit(1)
        else:
            print "calico-node container is running. Status: %s" % \
                  calico_node_info[0]["Status"]

            libraries_cmd = docker_client.exec_create("calico-node",
                                                      ["sh", "-c",
                                                       "cat libraries.txt"])
            libraries_out = docker_client.exec_start(libraries_cmd)
            result = re.search(r"^calico\s*\((.*)\)\s*$", libraries_out,
                               re.MULTILINE)

            if result is not None:
                print "Running felix version %s" % result.group(1)
    except ConnectionError:
        print "Docker is not running"
        sys.exit(1)
Beispiel #4
0
def status(arguments):
    """
    Main dispatcher for status commands. Calls the corresponding helper
    function.

    :param arguments: A dictionary of arguments already processed through
    this file's docstring with docopt
    :return: None
    """
    calico_node_info = filter(lambda container: "/calico-node" in
                              container["Names"],
                              docker_client.containers())
    if len(calico_node_info) == 0:
        print "calico-node container not running"
    else:
        print "calico-node container is running. Status: %s" % \
              calico_node_info[0]["Status"]

        apt_cmd = docker_client.exec_create("calico-node",
                                           ["/bin/bash", "-c",
                                            "apt-cache policy calico-felix"])
        result = re.search(r"Installed: (.*?)\s",
                           docker_client.exec_start(apt_cmd))
        if result is not None:
            print "Running felix version %s" % result.group(1)

        print "\nIPv4 BGP status"
        pprint_bird_protocols(4)
        print "IPv6 BGP status"
        pprint_bird_protocols(6)
Beispiel #5
0
def status(arguments):
    """
    Main dispatcher for status commands. Calls the corresponding helper
    function.

    :param arguments: A dictionary of arguments already processed through
    this file's docstring with docopt
    :return: None
    """
    calico_node_info = filter(
        lambda container: "/calico-node" in container["Names"],
        docker_client.containers())
    if len(calico_node_info) == 0:
        print "calico-node container not running"
    else:
        print "calico-node container is running. Status: %s" % \
              calico_node_info[0]["Status"]

        apt_cmd = docker_client.exec_create(
            "calico-node", ["sh", "-c", "apt-cache policy calico-felix"])
        result = re.search(r"Installed: (.*?)\s",
                           docker_client.exec_start(apt_cmd))
        if result is not None:
            print "Running felix version %s" % result.group(1)

        print "\nIPv4 BGP status"
        pprint_bird_protocols(4)
        print "IPv6 BGP status"
        pprint_bird_protocols(6)
Beispiel #6
0
def status(arguments):
    """
    Main dispatcher for status commands. Calls the corresponding helper
    function.

    :param arguments: A dictionary of arguments already processed through
    this file's docstring with docopt
    :return: None
    """
    try:
        calico_node_info = filter(lambda container: "/calico-node" in
                                  container["Names"],
                                  docker_client.containers())
        if len(calico_node_info) == 0:
            print "calico-node container not running"
        else:
            print "calico-node container is running. Status: %s" % \
                  calico_node_info[0]["Status"]

            libraries_cmd = docker_client.exec_create("calico-node",
                                                      ["sh", "-c",
                                                       "cat libraries.txt"])
            libraries_out = docker_client.exec_start(libraries_cmd)
            result = re.search(r"^calico\s*\((.*)\)\s*$", libraries_out,
                               re.MULTILINE)

            if result is not None:
                print "Running felix version %s" % result.group(1)

            print "\nIPv4 BGP status"
            pprint_bird_protocols(4)
            print "IPv6 BGP status"
            pprint_bird_protocols(6)
    except ConnectionError:
        print "Docker is not running"
        # TODO: Perform status checks in platform-independent way.
        return
Beispiel #7
0
def pprint_bird_protocols(version):
    """
    Pretty print the output from the BIRD "show protocols".  This parses the
    existing output and lays it out in pretty printed table.

    :param version:
    :return: None.
    """
    # Based on the IP version, run the appropriate BIRD command, and select
    # the appropriate separator char for an IP address.
    if version == 4:
        bird_cmd = docker_client.exec_create("calico-node",
                                    ["/bin/bash", "-c",
                                     "echo show protocols | "
                                     "birdc -s /etc/service/bird/bird.ctl"])
        results = docker_client.exec_start(bird_cmd)
        ip_sep = "."
    else:
        bird6_cmd = docker_client.exec_create("calico-node",
                                    ["/bin/bash", "-c",
                                     "echo show protocols | "
                                     "birdc6 -s "
                                     "/etc/service/bird6/bird6.ctl"])
        results = docker_client.exec_start(bird6_cmd)
        ip_sep = ":"

    # Parse the output from BIRD to extract the values in the protocol status
    # table.  We'll further parse the name since that includes details about
    # the type of peer and the peer IP address.
    x = PrettyTable(["Peer address", "Peer type", "State",
                     "Since", "Info"])
    lines = results.split("\n")
    found_table = False
    for line in lines:
        # When BIRD displays its protocol table, it prints the bird> prompt and
        # then shifts the cursor to print back over the prompt.  However, this
        # means that we get rogue prompts when parsing the output.  For this
        # processing just remove the prompt if it is present.
        if line.startswith("bird>"):
            line = line[5:]

        # Skip blank lines.
        line = line.strip()
        if not line:
            continue

        # Split the line into columns based on whitespace separators.  We split
        # a maximum of 5 times because the 6th "info" column may contain a
        # string that itself includes whitespace that should be maintained.
        columns = re.split("\s+", line.strip(), 5)

        # Loop until we find the table heading.
        if columns == ["name", "proto", "table", "state", "since", "info"]:
            found_table = True
            continue
        elif not found_table:
            continue

        # We expect either 5 or 6 columns depending on whether there was a
        # value in the info column.  Anything else is not handled, so revert
        # to displaying the raw BIRD output.
        if not (5 <= len(columns) <= 6):
            found_table = False
            break

        # Parse the name, we name our BGP peers as "Mesh", "Node" or "Global"
        # followed by the IP address.  Extract the info so we can pretty
        # print it.
        combined = columns[0]
        if combined.startswith("Mesh_"):
            name = combined[5:].replace("_", ip_sep)
            ptype = "node-to-node mesh"
        elif combined.startswith("Node_"):
            name = combined[5:].replace("_", ip_sep)
            ptype = "node specific"
        elif combined.startswith("Global_"):
            name = combined[7:].replace("_", ip_sep)
            ptype = "global"
        else:
            # This is not a BGP Peer, so do not include in the output.
            continue

        x.add_row([name, ptype, columns[3], columns[4],
                   columns[5] if len(columns) == 6 else ""])

    # If we parsed the table then pretty print the table, otherwise just output
    # the BIRD output directly.  The first line of the BIRD output provides an
    # overall BIRD status.
    if found_table:
        print str(x) + "\n"
    else:
        print results + "\n"
Beispiel #8
0
def pprint_bird_protocols(version):
    """
    Pretty print the output from the BIRD "show protocols".  This parses the
    existing output and lays it out in pretty printed table.

    :param version:  The IP version (4 or 6).
    :return: None.
    """
    # Based on the IP version, run the appropriate BIRD command, and select
    # the appropriate separator char for an IP address.
    if version == 4:
        bird_cmd = docker_client.exec_create("calico-node", [
            "sh", "-c", "echo show protocols | "
            "birdcl -s /etc/service/bird/bird.ctl"
        ])
        results = docker_client.exec_start(bird_cmd)
        ip_sep = "."
    else:
        bird6_cmd = docker_client.exec_create("calico-node", [
            "sh", "-c", "echo show protocols | "
            "birdcl -s "
            "/etc/service/bird6/bird6.ctl"
        ])
        results = docker_client.exec_start(bird6_cmd)
        ip_sep = ":"

    # Parse the output from BIRD to extract the values in the protocol status
    # table.  We'll further parse the name since that includes details about
    # the type of peer and the peer IP address.
    x = PrettyTable(["Peer address", "Peer type", "State", "Since", "Info"])
    lines = results.split("\n")
    found_table = False
    for line in lines:
        # When BIRD displays its protocol table, it prints the bird> prompt and
        # then shifts the cursor to print back over the prompt.  However, this
        # means that we get rogue prompts when parsing the output.  For this
        # processing just remove the prompt if it is present.
        if line.startswith("bird>"):
            line = line[5:]

        # Skip blank lines.
        line = line.strip()
        if not line:
            continue

        # Split the line into columns based on whitespace separators.  We split
        # a maximum of 5 times because the 6th "info" column may contain a
        # string that itself includes whitespace that should be maintained.
        columns = re.split("\s+", line.strip(), 5)

        # Loop until we find the table heading.
        if columns == ["name", "proto", "table", "state", "since", "info"]:
            found_table = True
            continue
        elif not found_table:
            continue

        # We expect either 5 or 6 columns depending on whether there was a
        # value in the info column.  Anything else is not handled, so revert
        # to displaying the raw BIRD output.
        if not (5 <= len(columns) <= 6):
            found_table = False
            break

        # Parse the name, we name our BGP peers as "Mesh", "Node" or "Global"
        # followed by the IP address.  Extract the info so we can pretty
        # print it.
        combined = columns[0]
        if combined.startswith("Mesh_"):
            name = combined[5:].replace("_", ip_sep)
            ptype = "node-to-node mesh"
        elif combined.startswith("Node_"):
            name = combined[5:].replace("_", ip_sep)
            ptype = "node specific"
        elif combined.startswith("Global_"):
            name = combined[7:].replace("_", ip_sep)
            ptype = "global"
        else:
            # This is not a BGP Peer, so do not include in the output.
            continue

        x.add_row([
            name, ptype, columns[3], columns[4],
            columns[5] if len(columns) == 6 else ""
        ])

    # If we parsed the table then pretty print the table, otherwise just output
    # the BIRD output directly.  The first line of the BIRD output provides an
    # overall BIRD status.
    if found_table:
        print str(x) + "\n"
    else:
        print results + "\n"
Beispiel #9
0
def status(arguments):
    """
    Main dispatcher for status commands. Calls the corresponding helper
    function.

    :param arguments: A dictionary of arguments already processed through
    this file's docstring with docopt
    :return: None
    """
    # Start by locating the calico-node container and querying the package
    # summary file.
    try:
        calico_node_info = filter(
            lambda container: "/calico-node" in container["Names"],
            docker_client.containers())
        if len(calico_node_info) == 0:
            print "calico-node container not running"
            sys.exit(1)
        else:
            print "calico-node container is running. Status: %s" % \
                  calico_node_info[0]["Status"]

            libraries_cmd = docker_client.exec_create(
                "calico-node", ["sh", "-c", "cat libraries.txt"])
            libraries_out = docker_client.exec_start(libraries_cmd)
            result = re.search(r"^calico\s*\((.*)\)\s*$", libraries_out,
                               re.MULTILINE)

            if result is not None:
                print "Running felix version %s" % result.group(1)
    except ConnectionError:
        print "Docker is not running"
        # TODO: Perform status checks in platform-independent way.
        sys.exit(1)

    # Now query the host BGP details.  If the AS number is not specified on the
    # host then it must be inheriting the default.
    try:
        bgp_ipv4, bgp_ipv6 = client.get_host_bgp_ips(hostname)
        bgp_as = client.get_host_as(hostname)
        if bgp_as is None:
            bgp_as = client.get_default_node_as()
            bgp_as += " (inherited)"
    except DataStoreError:
        print "Error connecting to etcd."
        bgp_ipv4 = bgp_ipv6 = "unknown"
        bgp_as = "unknown"

    # TODO: Add additional information to the BIRD section:
    # TODO: - Include AS numbers of peers
    # TODO: - Include host name of peers when the peer is a calico-node
    # TODO: - Include details of peers configured multiple times

    print "\nIPv4 BGP status"
    if bgp_ipv4:
        print "IP: %s    AS Number: %s" % (bgp_ipv4, bgp_as)
        pprint_bird_protocols(4)
    else:
        print "No IPv4 address configured.\n"

    print "IPv6 BGP status"
    if bgp_ipv6:
        print "IP: %s    AS Number: %s" % (bgp_ipv6, bgp_as)
        pprint_bird_protocols(6)
    else:
        print "No IPv6 address configured.\n"
Beispiel #10
0
def status(arguments):
    """
    Main dispatcher for status commands. Calls the corresponding helper
    function.

    :param arguments: A dictionary of arguments already processed through
    this file's docstring with docopt
    :return: None
    """
    # Start by locating the calico-node container and querying the package
    # summary file.
    try:
        calico_node_info = filter(lambda container: "/calico-node" in
                                  container["Names"],
                                  docker_client.containers())
        if len(calico_node_info) == 0:
            print "calico-node container not running"
            sys.exit(1)
        else:
            print "calico-node container is running. Status: %s" % \
                  calico_node_info[0]["Status"]

            libraries_cmd = docker_client.exec_create("calico-node",
                                                      ["sh", "-c",
                                                       "cat libraries.txt"])
            libraries_out = docker_client.exec_start(libraries_cmd)
            result = re.search(r"^calico\s*\((.*)\)\s*$", libraries_out,
                               re.MULTILINE)

            if result is not None:
                print "Running felix version %s" % result.group(1)
    except ConnectionError:
        print "Docker is not running"
        # TODO: Perform status checks in platform-independent way.
        sys.exit(1)

    # Now query the host BGP details.  If the AS number is not specified on the
    # host then it must be inheriting the default.
    try:
        bgp_ipv4, bgp_ipv6 = client.get_host_bgp_ips(hostname)
        bgp_as = client.get_host_as(hostname)
        if bgp_as is None:
            bgp_as = client.get_default_node_as()
            bgp_as += " (inherited)"
    except DataStoreError:
        print "Error connecting to etcd."
        bgp_ipv4 = bgp_ipv6 = "unknown"
        bgp_as = "unknown"

    # TODO: Add additional information to the BIRD section:
    # TODO: - Include AS numbers of peers
    # TODO: - Include host name of peers when the peer is a calico-node
    # TODO: - Include details of peers configured multiple times

    print "\nIPv4 BGP status"
    if bgp_ipv4:
        print "IP: %s    AS Number: %s" % (bgp_ipv4, bgp_as)
        pprint_bird_protocols(4)
    else:
        print "No IPv4 address configured.\n"

    print "IPv6 BGP status"
    if bgp_ipv6:
        print "IP: %s    AS Number: %s" % (bgp_ipv6, bgp_as)
        pprint_bird_protocols(6)
    else:
        print "No IPv6 address configured.\n"