Example #1
0
def follow_node_log(config, node, lines=10):
    """
    Return and follow node log lines from the API

    API endpoint: GET /node/{node}/log
    API arguments: lines={lines}
    API schema: {"name":"{nodename}","data":"{node_log}"}
    """
    # We always grab 200 to match the follow call, but only _show_ `lines` number
    params = {"lines": 200}
    response = call_api(config,
                        "get",
                        "/node/{node}/log".format(node=node),
                        params=params)

    if response.status_code != 200:
        return False, response.json().get("message", "")

    # Shrink the log buffer to length lines
    node_log = response.json()["data"]
    shrunk_log = node_log.split("\n")[-int(lines):]
    loglines = "\n".join(shrunk_log)

    # Print the initial data and begin following
    print(loglines, end="")
    print("\n", end="")

    while True:
        # Grab the next line set (200 is a reasonable number of lines per half-second; any more are skipped)
        try:
            params = {"lines": 200}
            response = call_api(config,
                                "get",
                                "/node/{node}/log".format(node=node),
                                params=params)
            new_node_log = response.json()["data"]
        except Exception:
            break
        # Split the new and old log strings into constitutent lines
        old_node_loglines = node_log.split("\n")
        new_node_loglines = new_node_log.split("\n")

        # Set the node log to the new log value for the next iteration
        node_log = new_node_log

        # Get the difference between the two sets of lines
        old_node_loglines_set = set(old_node_loglines)
        diff_node_loglines = [
            x for x in new_node_loglines if x not in old_node_loglines_set
        ]

        # If there's a difference, print it out
        if len(diff_node_loglines) > 0:
            print("\n".join(diff_node_loglines), end="")
            print("\n", end="")

        # Wait half a second
        time.sleep(0.5)

    return True, ""
Example #2
0
def node_list(config, limit, target_daemon_state, target_coordinator_state,
              target_domain_state):
    """
    Get list information about nodes (limited by {limit})

    API endpoint: GET /api/v1/node
    API arguments: limit={limit}
    API schema: [{json_data_object},{json_data_object},etc.]
    """
    params = dict()
    if limit:
        params["limit"] = limit
    if target_daemon_state:
        params["daemon_state"] = target_daemon_state
    if target_coordinator_state:
        params["coordinator_state"] = target_coordinator_state
    if target_domain_state:
        params["domain_state"] = target_domain_state

    response = call_api(config, "get", "/node", params=params)

    if response.status_code == 200:
        return True, response.json()
    else:
        return False, response.json().get("message", "")
Example #3
0
def net_acl_info(config, net, description):
    """
    Get information about network ACL

    API endpoint: GET /api/v1/network/{net}/acl/{description}
    API arguments:
    API schema: {json_data_object}
    """
    response = call_api(
        config,
        "get",
        "/network/{net}/acl/{description}".format(net=net,
                                                  description=description),
    )

    if response.status_code == 200:
        if isinstance(response.json(), list) and len(response.json()) != 1:
            # No exact match; return not found
            return False, "ACL not found."
        else:
            # Return a single instance if the response is a list
            if isinstance(response.json(), list):
                return True, response.json()[0]
            # This shouldn't happen, but is here just in case
            else:
                return True, response.json()
    else:
        return False, response.json().get("message", "")
Example #4
0
def net_dhcp_list(config, net, limit, only_static=False):
    """
    Get list information about leases (limited by {limit})

    API endpoint: GET /api/v1/network/{net}/lease
    API arguments: limit={limit}, static={only_static}
    API schema: [{json_data_object},{json_data_object},etc.]
    """
    params = dict()
    if limit:
        params["limit"] = limit

    if only_static:
        params["static"] = True
    else:
        params["static"] = False

    response = call_api(config,
                        "get",
                        "/network/{net}/lease".format(net=net),
                        params=params)

    if response.status_code == 200:
        return True, response.json()
    else:
        return False, response.json().get("message", "")
Example #5
0
def net_sriov_vf_set(
    config,
    node,
    vf,
    vlan_id,
    vlan_qos,
    tx_rate_min,
    tx_rate_max,
    link_state,
    spoof_check,
    trust,
    query_rss,
):
    """
    Mdoify configuration of a SR-IOV VF

    API endpoint: PUT /api/v1/sriov/vf/<node>/<vf>
    API arguments: vlan_id={vlan_id}, vlan_qos={vlan_qos}, tx_rate_min={tx_rate_min}, tx_rate_max={tx_rate_max},
                   link_state={link_state}, spoof_check={spoof_check}, trust={trust}, query_rss={query_rss}
    API schema: {"message": "{data}"}
    """
    params = dict()

    # Update any params that we've sent
    if vlan_id is not None:
        params["vlan_id"] = vlan_id

    if vlan_qos is not None:
        params["vlan_qos"] = vlan_qos

    if tx_rate_min is not None:
        params["tx_rate_min"] = tx_rate_min

    if tx_rate_max is not None:
        params["tx_rate_max"] = tx_rate_max

    if link_state is not None:
        params["link_state"] = link_state

    if spoof_check is not None:
        params["spoof_check"] = spoof_check

    if trust is not None:
        params["trust"] = trust

    if query_rss is not None:
        params["query_rss"] = query_rss

    # Write the new configuration to the API
    response = call_api(config,
                        "put",
                        "/sriov/vf/{node}/{vf}".format(node=node, vf=vf),
                        params=params)

    if response.status_code == 200:
        retstatus = True
    else:
        retstatus = False

    return retstatus, response.json().get("message", "")
Example #6
0
def net_acl_add(config, net, direction, description, rule, order):
    """
    Add new network acl

    API endpoint: POST /api/v1/network/{net}/acl
    API arguments: description=description, direction=direction, order=order, rule=rule
    API schema: {"message":"{data}"}
    """
    params = dict()
    params["description"] = description
    params["direction"] = direction
    params["rule"] = rule
    if order is not None:
        params["order"] = order

    response = call_api(config,
                        "post",
                        "/network/{net}/acl".format(net=net),
                        params=params)

    if response.status_code == 200:
        retstatus = True
    else:
        retstatus = False

    return retstatus, response.json().get("message", "")
Example #7
0
def net_modify(
    config,
    net,
    description,
    mtu,
    domain,
    name_servers,
    ip4_network,
    ip4_gateway,
    ip6_network,
    ip6_gateway,
    dhcp4_flag,
    dhcp4_start,
    dhcp4_end,
):
    """
    Modify a network

    API endpoint: POST /api/v1/network/{net}
    API arguments: lots
    API schema: {"message":"{data}"}
    """
    params = dict()
    if description is not None:
        params["description"] = description
    if mtu is not None:
        params["mtu"] = mtu
    if domain is not None:
        params["domain"] = domain
    if name_servers is not None:
        params["name_servers"] = name_servers
    if ip4_network is not None:
        params["ip4_network"] = ip4_network
    if ip4_gateway is not None:
        params["ip4_gateway"] = ip4_gateway
    if ip6_network is not None:
        params["ip6_network"] = ip6_network
    if ip6_gateway is not None:
        params["ip6_gateway"] = ip6_gateway
    if dhcp4_flag is not None:
        params["dhcp4"] = dhcp4_flag
    if dhcp4_start is not None:
        params["dhcp4_start"] = dhcp4_start
    if dhcp4_end is not None:
        params["dhcp4_end"] = dhcp4_end

    response = call_api(config,
                        "put",
                        "/network/{net}".format(net=net),
                        params=params)

    if response.status_code == 200:
        retstatus = True
    else:
        retstatus = False

    return retstatus, response.json().get("message", "")
Example #8
0
def get_info(config):
    """
    Get status of the PVC cluster

    API endpoint: GET /api/v1/status
    API arguments:
    API schema: {json_data_object}
    """
    response = call_api(config, "get", "/status")

    if response.status_code == 200:
        return True, response.json()
    else:
        return False, response.json().get("message", "")
Example #9
0
def backup(config):
    """
    Get a JSON backup of the cluster

    API endpoint: GET /api/v1/backup
    API arguments:
    API schema: {json_data_object}
    """
    response = call_api(config, "get", "/backup")

    if response.status_code == 200:
        return True, response.json()
    else:
        return False, response.json().get("message", "")
Example #10
0
def net_sriov_pf_list(config, node):
    """
    List all PFs on NODE

    API endpoint: GET /api/v1/sriov/pf/<node>
    API arguments: node={node}
    API schema: [{json_data_object},{json_data_object},etc.]
    """
    response = call_api(config, "get", "/sriov/pf/{}".format(node))

    if response.status_code == 200:
        return True, response.json()
    else:
        return False, response.json().get("message", "")
Example #11
0
def net_remove(config, net):
    """
    Remove a network

    API endpoint: DELETE /api/v1/network/{net}
    API arguments:
    API schema: {"message":"{data}"}
    """
    response = call_api(config, "delete", "/network/{net}".format(net=net))

    if response.status_code == 200:
        retstatus = True
    else:
        retstatus = False

    return retstatus, response.json().get("message", "")
Example #12
0
def net_add(
    config,
    vni,
    description,
    nettype,
    mtu,
    domain,
    name_servers,
    ip4_network,
    ip4_gateway,
    ip6_network,
    ip6_gateway,
    dhcp4_flag,
    dhcp4_start,
    dhcp4_end,
):
    """
    Add new network

    API endpoint: POST /api/v1/network
    API arguments: lots
    API schema: {"message":"{data}"}
    """
    params = {
        "vni": vni,
        "description": description,
        "nettype": nettype,
        "mtu": mtu,
        "domain": domain,
        "name_servers": name_servers,
        "ip4_network": ip4_network,
        "ip4_gateway": ip4_gateway,
        "ip6_network": ip6_network,
        "ip6_gateway": ip6_gateway,
        "dhcp4": dhcp4_flag,
        "dhcp4_start": dhcp4_start,
        "dhcp4_end": dhcp4_end,
    }
    response = call_api(config, "post", "/network", params=params)

    if response.status_code == 200:
        retstatus = True
    else:
        retstatus = False

    return retstatus, response.json().get("message", "")
Example #13
0
def maintenance_mode(config, state):
    """
    Enable or disable PVC cluster maintenance mode

    API endpoint: POST /api/v1/status
    API arguments: {state}={state}
    API schema: {json_data_object}
    """
    params = {"state": state}
    response = call_api(config, "post", "/status", params=params)

    if response.status_code == 200:
        retstatus = True
    else:
        retstatus = False

    return retstatus, response.json().get("message", "")
Example #14
0
def initialize(config, overwrite=False):
    """
    Initialize the PVC cluster

    API endpoint: GET /api/v1/initialize
    API arguments: overwrite, yes-i-really-mean-it
    API schema: {json_data_object}
    """
    params = {"yes-i-really-mean-it": "yes", "overwrite": overwrite}
    response = call_api(config, "post", "/initialize", params=params)

    if response.status_code == 200:
        retstatus = True
    else:
        retstatus = False

    return retstatus, response.json().get("message", "")
Example #15
0
def net_list(config, limit):
    """
    Get list information about networks (limited by {limit})

    API endpoint: GET /api/v1/network
    API arguments: limit={limit}
    API schema: [{json_data_object},{json_data_object},etc.]
    """
    params = dict()
    if limit:
        params["limit"] = limit

    response = call_api(config, "get", "/network", params=params)

    if response.status_code == 200:
        return True, response.json()
    else:
        return False, response.json().get("message", "")
Example #16
0
def restore(config, cluster_data):
    """
    Restore a JSON backup to the cluster

    API endpoint: POST /api/v1/restore
    API arguments: yes-i-really-mean-it
    API schema: {json_data_object}
    """
    cluster_data_json = json.dumps(cluster_data)

    params = {"yes-i-really-mean-it": "yes"}
    data = {"cluster_data": cluster_data_json}
    response = call_api(config, "post", "/restore", params=params, data=data)

    if response.status_code == 200:
        retstatus = True
    else:
        retstatus = False

    return retstatus, response.json().get("message", "")
Example #17
0
def net_sriov_vf_list(config, node, pf=None):
    """
    List all VFs on NODE, optionally limited by PF

    API endpoint: GET /api/v1/sriov/vf/<node>
    API arguments: node={node}, pf={pf}
    API schema: [{json_data_object},{json_data_object},etc.]
    """
    params = dict()
    params["pf"] = pf

    response = call_api(config,
                        "get",
                        "/sriov/vf/{}".format(node),
                        params=params)

    if response.status_code == 200:
        return True, response.json()
    else:
        return False, response.json().get("message", "")
Example #18
0
def net_dhcp_add(config, net, ipaddr, macaddr, hostname):
    """
    Add new network DHCP lease

    API endpoint: POST /api/v1/network/{net}/lease
    API arguments: macaddress=macaddr, ipaddress=ipaddr, hostname=hostname
    API schema: {"message":"{data}"}
    """
    params = {"macaddress": macaddr, "ipaddress": ipaddr, "hostname": hostname}
    response = call_api(config,
                        "post",
                        "/network/{net}/lease".format(net=net),
                        params=params)

    if response.status_code == 200:
        retstatus = True
    else:
        retstatus = False

    return retstatus, response.json().get("message", "")
Example #19
0
def node_domain_state(config, node, action, wait):
    """
    Set node domain state state (flush/ready)

    API endpoint: POST /api/v1/node/{node}/domain-state
    API arguments: action={action}, wait={wait}
    API schema: {"message": "{data}"}
    """
    params = {"state": action, "wait": str(wait).lower()}
    response = call_api(config,
                        "post",
                        "/node/{node}/domain-state".format(node=node),
                        params=params)

    if response.status_code == 200:
        retstatus = True
    else:
        retstatus = False

    return retstatus, response.json().get("message", "")
Example #20
0
def node_coordinator_state(config, node, action):
    """
    Set node coordinator state state (primary/secondary)

    API endpoint: POST /api/v1/node/{node}/coordinator-state
    API arguments: action={action}
    API schema: {"message": "{data}"}
    """
    params = {"state": action}
    response = call_api(
        config,
        "post",
        "/node/{node}/coordinator-state".format(node=node),
        params=params,
    )

    if response.status_code == 200:
        retstatus = True
    else:
        retstatus = False

    return retstatus, response.json().get("message", "")
Example #21
0
def net_sriov_vf_info(config, node, vf):
    """
    Get info about VF on NODE

    API endpoint: GET /api/v1/sriov/vf/<node>/<vf>
    API arguments:
    API schema: [{json_data_object}]
    """
    response = call_api(config, "get", "/sriov/vf/{}/{}".format(node, vf))

    if response.status_code == 200:
        if isinstance(response.json(), list) and len(response.json()) != 1:
            # No exact match; return not found
            return False, "VF not found."
        else:
            # Return a single instance if the response is a list
            if isinstance(response.json(), list):
                return True, response.json()[0]
            # This shouldn't happen, but is here just in case
            else:
                return True, response.json()
    else:
        return False, response.json().get("message", "")
Example #22
0
def node_info(config, node):
    """
    Get information about node

    API endpoint: GET /api/v1/node/{node}
    API arguments:
    API schema: {json_data_object}
    """
    response = call_api(config, "get", "/node/{node}".format(node=node))

    if response.status_code == 200:
        if isinstance(response.json(), list) and len(response.json()) != 1:
            # No exact match, return not found
            return False, "Node not found."
        else:
            # Return a single instance if the response is a list
            if isinstance(response.json(), list):
                return True, response.json()[0]
            # This shouldn't happen, but is here just in case
            else:
                return True, response.json()
    else:
        return False, response.json().get("message", "")
Example #23
0
def net_acl_list(config, net, limit, direction):
    """
    Get list information about ACLs (limited by {limit})

    API endpoint: GET /api/v1/network/{net}/acl
    API arguments: limit={limit}, direction={direction}
    API schema: [{json_data_object},{json_data_object},etc.]
    """
    params = dict()
    if limit:
        params["limit"] = limit
    if direction is not None:
        params["direction"] = direction

    response = call_api(config,
                        "get",
                        "/network/{net}/acl".format(net=net),
                        params=params)

    if response.status_code == 200:
        return True, response.json()
    else:
        return False, response.json().get("message", "")
Example #24
0
def view_node_log(config, node, lines=100):
    """
    Return node log lines from the API (and display them in a pager in the main CLI)

    API endpoint: GET /node/{node}/log
    API arguments: lines={lines}
    API schema: {"name":"{node}","data":"{node_log}"}
    """
    params = {"lines": lines}
    response = call_api(config,
                        "get",
                        "/node/{node}/log".format(node=node),
                        params=params)

    if response.status_code != 200:
        return False, response.json().get("message", "")

    node_log = response.json()["data"]

    # Shrink the log buffer to length lines
    shrunk_log = node_log.split("\n")[-lines:]
    loglines = "\n".join(shrunk_log)

    return True, loglines
Example #25
0
def format_info_sriov_vf(config, vf_information, node):
    if not vf_information:
        return "No VF found"

    # Get information on the using VM if applicable
    if vf_information["usage"]["used"] == "True" and vf_information["usage"][
            "domain"]:
        vm_information = call_api(
            config, "get",
            "/vm/{vm}".format(vm=vf_information["usage"]["domain"])).json()
        if isinstance(vm_information, list) and len(vm_information) > 0:
            vm_information = vm_information[0]
        else:
            vm_information = None

    # Format a nice output: do this line-by-line then concat the elements at the end
    ainformation = []
    ainformation.append("{}SR-IOV VF information:{}".format(
        ansiprint.bold(), ansiprint.end()))
    ainformation.append("")
    # Basic information
    ainformation.append("{}PHY:{}               {}".format(
        ansiprint.purple(), ansiprint.end(), vf_information["phy"]))
    ainformation.append("{}PF:{}                {} @ {}".format(
        ansiprint.purple(), ansiprint.end(), vf_information["pf"], node))
    ainformation.append("{}MTU:{}               {}".format(
        ansiprint.purple(), ansiprint.end(), vf_information["mtu"]))
    ainformation.append("{}MAC Address:{}       {}".format(
        ansiprint.purple(), ansiprint.end(), vf_information["mac"]))
    ainformation.append("")
    # Configuration information
    ainformation.append("{}vLAN ID:{}           {}".format(
        ansiprint.purple(), ansiprint.end(),
        vf_information["config"]["vlan_id"]))
    ainformation.append("{}vLAN QOS priority:{} {}".format(
        ansiprint.purple(), ansiprint.end(),
        vf_information["config"]["vlan_qos"]))
    ainformation.append("{}Minimum TX Rate:{}   {}".format(
        ansiprint.purple(), ansiprint.end(),
        vf_information["config"]["tx_rate_min"]))
    ainformation.append("{}Maximum TX Rate:{}   {}".format(
        ansiprint.purple(), ansiprint.end(),
        vf_information["config"]["tx_rate_max"]))
    ainformation.append("{}Link State:{}        {}".format(
        ansiprint.purple(), ansiprint.end(),
        vf_information["config"]["link_state"]))
    ainformation.append("{}Spoof Checking:{}    {}{}{}".format(
        ansiprint.purple(),
        ansiprint.end(),
        getColour(vf_information["config"]["spoof_check"]),
        vf_information["config"]["spoof_check"],
        ansiprint.end(),
    ))
    ainformation.append("{}VF User Trust:{}     {}{}{}".format(
        ansiprint.purple(),
        ansiprint.end(),
        getColour(vf_information["config"]["trust"]),
        vf_information["config"]["trust"],
        ansiprint.end(),
    ))
    ainformation.append("{}Query RSS Config:{}  {}{}{}".format(
        ansiprint.purple(),
        ansiprint.end(),
        getColour(vf_information["config"]["query_rss"]),
        vf_information["config"]["query_rss"],
        ansiprint.end(),
    ))
    ainformation.append("")
    # PCIe bus information
    ainformation.append("{}PCIe domain:{}       {}".format(
        ansiprint.purple(), ansiprint.end(), vf_information["pci"]["domain"]))
    ainformation.append("{}PCIe bus:{}          {}".format(
        ansiprint.purple(), ansiprint.end(), vf_information["pci"]["bus"]))
    ainformation.append("{}PCIe slot:{}         {}".format(
        ansiprint.purple(), ansiprint.end(), vf_information["pci"]["slot"]))
    ainformation.append("{}PCIe function:{}     {}".format(
        ansiprint.purple(), ansiprint.end(),
        vf_information["pci"]["function"]))
    ainformation.append("")
    # Usage information
    ainformation.append("{}VF Used:{}           {}{}{}".format(
        ansiprint.purple(),
        ansiprint.end(),
        getColour(vf_information["usage"]["used"]),
        vf_information["usage"]["used"],
        ansiprint.end(),
    ))
    if vf_information["usage"]["used"] == "True" and vm_information is not None:
        ainformation.append("{}Using Domain:{}      {} ({}) ({}{}{})".format(
            ansiprint.purple(),
            ansiprint.end(),
            vf_information["usage"]["domain"],
            vm_information["name"],
            getColour(vm_information["state"]),
            vm_information["state"],
            ansiprint.end(),
        ))
    else:
        ainformation.append("{}Using Domain:{}      N/A".format(
            ansiprint.purple(), ansiprint.end()))

    # Join it all together
    return "\n".join(ainformation)