Skip to content

Commit

Permalink
v2-lib: add postgres get_url and make sure its url encoded (#762)
Browse files Browse the repository at this point in the history
* auto add labels from a top level structure

* improve message

* fix escaping

* fix escaping

* move dep containers to their own class

* implement the get_url for postgres

* make sure action id is unique

* add variant

* rm
  • Loading branch information
stavros-k committed Oct 31, 2024
1 parent 3765242 commit 5b26113
Show file tree
Hide file tree
Showing 50 changed files with 91 additions and 18 deletions.
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.
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.
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

0 comments on commit 5b26113

Please sign in to comment.