Example #1
0
def test_connection_info():
    url = "postgres://*****:*****@dbhost.local:5555/abc?replication=true&sslmode=foobar&sslmode=require"
    cs = "host=dbhost.local user='******'   dbname='abc'\n" \
         "replication=true   password=secret sslmode=require port=5555"
    ci = {
        "host": "dbhost.local",
        "port": "5555",
        "user": "******",
        "password": "******",
        "dbname": "abc",
        "replication": "true",
        "sslmode": "require",
    }
    assert get_connection_info(ci) == get_connection_info(cs)
    assert get_connection_info(ci) == get_connection_info(url)

    basic_cstr = "host=localhost user=os"
    assert create_connection_string(get_connection_info(basic_cstr)) == "host='localhost' user='******'"

    assert get_connection_info("foo=bar bar='\\'x'") == {"foo": "bar", "bar": "'x"}

    with raises(ValueError):
        get_connection_info("foo=bar x")
    with raises(ValueError):
        get_connection_info("foo=bar bar='x")
Example #2
0
def test_connection_info():
    url = "postgres://*****:*****@dbhost.local:5555/abc?replication=true&sslmode=foobar&sslmode=require"
    cs = "host=dbhost.local user='******'   dbname='abc'\n" \
         "replication=true   password=secret sslmode=require port=5555"
    ci = {
        "host": "dbhost.local",
        "port": "5555",
        "user": "******",
        "password": "******",
        "dbname": "abc",
        "replication": "true",
        "sslmode": "require",
    }
    assert get_connection_info(ci) == get_connection_info(cs)
    assert get_connection_info(ci) == get_connection_info(url)

    basic_cstr = "host=localhost user=os"
    assert create_connection_string(
        get_connection_info(basic_cstr)) == "host='localhost' user='******'"

    assert get_connection_info("foo=bar bar='\\'x'") == {
        "foo": "bar",
        "bar": "'x"
    }

    with raises(ValueError):
        get_connection_info("foo=bar x")
    with raises(ValueError):
        get_connection_info("foo=bar bar='x")
Example #3
0
def create_pgpass_file(connection_string_or_info):
    """Look up password from the given object which can be a dict or a
    string and write a possible password in a pgpass file;
    returns a connection_string without a password in it"""
    info = pgutil.get_connection_info(connection_string_or_info)
    if "password" not in info:
        return pgutil.create_connection_string(info)
    linekey = "{host}:{port}:{dbname}:{user}:".format(
        host=info.get("host", "localhost"),
        port=info.get("port", 5432),
        user=info.get("user", ""),
        dbname=info.get("dbname", "*"))
    pwline = "{linekey}{password}".format(linekey=linekey,
                                          password=info.pop("password"))
    pgpass_path = os.path.join(os.environ.get("HOME"), ".pgpass")
    if os.path.exists(pgpass_path):
        with open(pgpass_path, "r") as fp:
            pgpass_lines = fp.read().splitlines()
    else:
        pgpass_lines = []
    if pwline in pgpass_lines:
        LOG.debug(
            "Not adding authentication data to: %s since it's already there",
            pgpass_path)
    else:
        # filter out any existing lines with our linekey and add the new line
        pgpass_lines = [
            line for line in pgpass_lines if not line.startswith(linekey)
        ] + [pwline]
        content = "\n".join(pgpass_lines) + "\n"
        with open(pgpass_path, "w") as fp:
            os.fchmod(fp.fileno(), 0o600)
            fp.write(content)
        LOG.debug("Wrote %r to %r", pwline, pgpass_path)
    return pgutil.create_connection_string(info)
Example #4
0
def create_pgpass_file(connection_string_or_info):
    """Look up password from the given object which can be a dict or a
    string and write a possible password in a pgpass file;
    returns a connection_string without a password in it"""
    info = pgutil.get_connection_info(connection_string_or_info)
    if "password" not in info:
        return pgutil.create_connection_string(info)
    linekey = "{host}:{port}:{dbname}:{user}:".format(
        host=info.get("host", "localhost"),
        port=info.get("port", 5432),
        user=info.get("user", ""),
        dbname=info.get("dbname", "*"))
    pwline = "{linekey}{password}".format(linekey=linekey, password=info.pop("password"))
    pgpass_path = os.path.join(os.environ.get("HOME"), ".pgpass")
    if os.path.exists(pgpass_path):
        with open(pgpass_path, "r") as fp:
            pgpass_lines = fp.read().splitlines()
    else:
        pgpass_lines = []
    if pwline in pgpass_lines:
        LOG.debug("Not adding authentication data to: %s since it's already there", pgpass_path)
    else:
        # filter out any existing lines with our linekey and add the new line
        pgpass_lines = [line for line in pgpass_lines if not line.startswith(linekey)] + [pwline]
        content = "\n".join(pgpass_lines) + "\n"
        with open(pgpass_path, "w") as fp:
            os.fchmod(fp.fileno(), 0o600)
            fp.write(content)
        LOG.debug("Wrote %r to %r", pwline, pgpass_path)
    return pgutil.create_connection_string(info)
Example #5
0
def connection_info_and_slot(target_node_info):
    """Process the input `target_node_info` entry which may be a libpq
    connection string or uri, or a dict containing key:value pairs of
    connection info entries or just the connection string with a replication
    slot name.  Return the connection info dict and a possible slot."""
    slot = None
    if isinstance(target_node_info, dict):
        target_node_info = target_node_info.copy()
        slot = target_node_info.pop("slot", None)
        if list(target_node_info) == ["connection_string"]:
            # if the dict only contains the `connection_string` key use it as-is
            target_node_info = target_node_info["connection_string"]
    connection_info = pgutil.get_connection_info(target_node_info)
    return connection_info, slot
Example #6
0
def connection_info_and_slot(target_node_info):
    """Process the input `target_node_info` entry which may be a libpq
    connection string or uri, or a dict containing key:value pairs of
    connection info entries or just the connection string with a replication
    slot name.  Return the connection info dict and a possible slot."""
    slot = None
    if isinstance(target_node_info, dict):
        target_node_info = target_node_info.copy()
        slot = target_node_info.pop("slot", None)
        if list(target_node_info) == ["connection_string"]:
            # if the dict only contains the `connection_string` key use it as-is
            target_node_info = target_node_info["connection_string"]
    connection_info = pgutil.get_connection_info(target_node_info)
    return connection_info, slot
Example #7
0
def test_mask_connection_info():
    url = "postgres://*****:*****@dbhost.local:5555/abc?replication=true&sslmode=foobar&sslmode=require"
    cs = "host=dbhost.local user='******'   dbname='abc'\n" \
         "replication=true   password=secret sslmode=require port=5555"
    ci = get_connection_info(cs)
    masked_url = mask_connection_info(url)
    masked_cs = mask_connection_info(url)
    masked_ci = mask_connection_info(url)
    assert masked_url == masked_cs
    assert masked_url == masked_ci
    assert "password" in ci  # make sure we didn't modify the original dict

    # the return format is a connection string without password, followed by
    # a semicolon and comment about password presence
    masked_str, password_info = masked_url.split("; ", 1)
    assert "password" not in masked_str
    assert password_info == "hidden password"

    # remasking the masked string should yield a no password comment
    masked_masked = mask_connection_info(masked_str)
    _, masked_password_info = masked_masked.split("; ", 1)
    assert masked_password_info == "no password"
Example #8
0
def test_mask_connection_info():
    url = "postgres://*****:*****@dbhost.local:5555/abc?replication=true&sslmode=foobar&sslmode=require"
    cs = "host=dbhost.local user='******'   dbname='abc'\n" \
         "replication=true   password=secret sslmode=require port=5555"
    ci = get_connection_info(cs)
    masked_url = mask_connection_info(url)
    masked_cs = mask_connection_info(url)
    masked_ci = mask_connection_info(url)
    assert masked_url == masked_cs
    assert masked_url == masked_ci
    assert "password" in ci  # make sure we didn't modify the original dict

    # the return format is a connection string without password, followed by
    # a semicolon and comment about password presence
    masked_str, password_info = masked_url.split("; ", 1)
    assert "password" not in masked_str
    assert password_info == "hidden password"

    # remasking the masked string should yield a no password comment
    masked_masked = mask_connection_info(masked_str)
    _, masked_password_info = masked_masked.split("; ", 1)
    assert masked_password_info == "no password"