Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v2-lib: add postgres get_url and make sure its url encoded #762

Merged
merged 12 commits into from
Oct 31, 2024
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
94 changes: 82 additions & 12 deletions library/2.0.5/deps.py → library/2.0.6/deps.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import os
import json
import urllib.parse
from typing import TYPE_CHECKING, TypedDict, NotRequired

if TYPE_CHECKING:
Expand Down Expand Up @@ -261,30 +262,80 @@ def perms(self, name: str):
return PermsContainer(self._render_instance, name)

def postgres(self, name: str, image: str, config: PostgresConfig, perms_instance: PermsContainer):
return PostgresContainer(self._render_instance, name, image, config, perms_instance)

def redis(self, name: str, image: str, config: RedisConfig, perms_instance: PermsContainer):
return RedisContainer(self._render_instance, name, image, config, perms_instance)

def mariadb(self, name: str, image: str, config: MariadbConfig, perms_instance: PermsContainer):
return MariadbContainer(self._render_instance, name, image, config, perms_instance)


class PostgresContainer:
def __init__(
self, render_instance: "Render", name: str, image: str, config: PostgresConfig, perms_instance: PermsContainer
):
self._render_instance = render_instance
self._name = name
self._config = config

for key in ("user", "password", "database", "volume"):
if key not in config:
raise RenderError(f"Expected [{key}] to be set for postgres")

port = valid_port_or_raise(config.get("port") or 5432)
port = valid_port_or_raise(self._get_port())

c = self._render_instance.add_container(name, image)
c.set_user(999, 999)
c.healthcheck.set_test("postgres")
c.deploy.resources.remove_devices()

c.add_storage("/var/lib/postgresql/data", config["volume"])
perms_instance.add_or_skip_action("postgres_data", config["volume"], {"uid": 999, "gid": 999, "mode": "check"})
perms_instance.add_or_skip_action(
f"${name}_postgres_data", config["volume"], {"uid": 999, "gid": 999, "mode": "check"}
)

c.environment.add_env("POSTGRES_USER", config["user"])
c.environment.add_env("POSTGRES_PASSWORD", config["password"])
c.environment.add_env("POSTGRES_DB", config["database"])
c.environment.add_env("POSTGRES_PORT", port)

# Return container for further configuration
# Store container for further configuration
# For example: c.depends.add_dependency("other_container", "service_started")
return c
self._container = c

@property
def container(self):
return self._container

def _get_port(self):
return self._config.get("port") or 5432

def get_url(self, variant: str):
user = urllib.parse.quote_plus(self._config["user"])
password = urllib.parse.quote_plus(self._config["password"])
creds = f"{user}:{password}"
addr = f"{self._name}:{self._get_port()}"
db = self._config["database"]

match variant:
case "postgres":
return f"postgres://{creds}@{addr}/{db}?sslmode=disable"
case "postgresql":
return f"postgresql://{creds}@{addr}/{db}?sslmode=disable"
case "host_port":
return addr
case _:
raise RenderError(f"Expected [variant] to be one of [postgres, postgresql], got [{variant}]")


class RedisContainer:
def __init__(
self, render_instance: "Render", name: str, image: str, config: RedisConfig, perms_instance: PermsContainer
):
self._render_instance = render_instance
self._name = name

def redis(self, name: str, image: str, config: RedisConfig, perms_instance: PermsContainer):
for key in ("password", "volume"):
if key not in config:
raise RenderError(f"Expected [{key}] to be set for redis")
Expand All @@ -297,17 +348,30 @@ def redis(self, name: str, image: str, config: RedisConfig, perms_instance: Perm
c.deploy.resources.remove_devices()

c.add_storage("/bitnami/redis/data", config["volume"])
perms_instance.add_or_skip_action("redis_data", config["volume"], {"uid": 1001, "gid": 0, "mode": "check"})
perms_instance.add_or_skip_action(
f"{self._name}_redis_data", config["volume"], {"uid": 1001, "gid": 0, "mode": "check"}
)

c.environment.add_env("ALLOW_EMPTY_PASSWORD", "no")
c.environment.add_env("REDIS_PASSWORD", config["password"])
c.environment.add_env("REDIS_PORT_NUMBER", port)

# Return container for further configuration
# Store container for further configuration
# For example: c.depends.add_dependency("other_container", "service_started")
return c
self._container = c

@property
def container(self):
return self._container


class MariadbContainer:
def __init__(
self, render_instance: "Render", name: str, image: str, config: MariadbConfig, perms_instance: PermsContainer
):
self._render_instance = render_instance
self._name = name

def mariadb(self, name: str, image: str, config: MariadbConfig, perms_instance: PermsContainer):
for key in ("user", "password", "database", "volume"):
if key not in config:
raise RenderError(f"Expected [{key}] to be set for mariadb")
Expand All @@ -322,7 +386,9 @@ def mariadb(self, name: str, image: str, config: MariadbConfig, perms_instance:
c.deploy.resources.remove_devices()

c.add_storage("/var/lib/mysql", config["volume"])
perms_instance.add_or_skip_action("mariadb_data", config["volume"], {"uid": 999, "gid": 999, "mode": "check"})
perms_instance.add_or_skip_action(
f"{self._name}_mariadb_data", config["volume"], {"uid": 999, "gid": 999, "mode": "check"}
)

c.environment.add_env("MARIADB_USER", config["user"])
c.environment.add_env("MARIADB_PASSWORD", config["password"])
Expand All @@ -331,6 +397,10 @@ def mariadb(self, name: str, image: str, config: MariadbConfig, perms_instance:
c.environment.add_env("MARIADB_AUTO_UPGRADE", str(auto_upgrade).lower())
c.set_command(["--port", str(port)])

# Return container for further configuration
# Store container for further configuration
# For example: c.depends.add_dependency("other_container", "service_started")
return c
self._container = c

@property
def container(self):
return self._container
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,19 @@ def test_add_postgres(mock_values):
"pg_image",
{
"user": "test_user",
"password": "test_password",
"password": "test_@password",
"database": "test_database",
"volume": {"type": "volume", "volume_config": {"volume_name": "test_volume"}, "auto_permissions": True},
},
perms_container,
)
if perms_container.has_actions():
perms_container.activate()
p.depends.add_dependency("perms_container", "service_completed_successfully")
p.container.depends.add_dependency("perms_container", "service_completed_successfully")
output = render.render()
assert (
p.get_url("postgres") == "postgres://test_user:test_%40password@pg_container:5432/test_database?sslmode=disable"
)
assert "devices" not in output["services"]["pg_container"]
assert "reservations" not in output["services"]["pg_container"]["deploy"]["resources"]
assert output["services"]["pg_container"]["image"] == "postgres:latest"
Expand All @@ -75,7 +78,7 @@ def test_add_postgres(mock_values):
"TZ": "Etc/UTC",
"NVIDIA_VISIBLE_DEVICES": "void",
"POSTGRES_USER": "test_user",
"POSTGRES_PASSWORD": "test_password",
"POSTGRES_PASSWORD": "test_@password",
"POSTGRES_DB": "test_database",
"POSTGRES_PORT": "5432",
}
Expand Down Expand Up @@ -114,7 +117,7 @@ def test_add_redis(mock_values):
)
if perms_container.has_actions():
perms_container.activate()
r.depends.add_dependency("perms_container", "service_completed_successfully")
r.container.depends.add_dependency("perms_container", "service_completed_successfully")
output = render.render()
assert "devices" not in output["services"]["redis_container"]
assert "reservations" not in output["services"]["redis_container"]["deploy"]["resources"]
Expand Down Expand Up @@ -181,7 +184,7 @@ def test_add_mariadb(mock_values):
)
if perms_container.has_actions():
perms_container.activate()
m.depends.add_dependency("perms_container", "service_completed_successfully")
m.container.depends.add_dependency("perms_container", "service_completed_successfully")
output = render.render()
assert "devices" not in output["services"]["mariadb_container"]
assert "reservations" not in output["services"]["mariadb_container"]["deploy"]["resources"]
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion library/hashes.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
0.0.1: f074617a82a86d2a6cc78a4c8a4296fc9d168e456f12713e50c696557b302133
1.1.5: 51332f2b032a0c473693458cd93daa96d56604241878e538c07cb85b8be66727
2.0.5: 0a65beb80aa50e867204d9c6720f8c841047d9e2a0e03d2c949534688c2832e1
2.0.6: 39d6ab5b62befe6d2e1d80fe590291662ccd2b678f162ea13d305008fb695b66
Loading