Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .env.sample
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
UURU_SITE_NAME = "DEVELOPMENT"

UURU_DATABASE_TYPE = "mysql"
UURU_DATABASE_SERVER = "127.0.0.1"
UURU_DATABASE_PORT = "3307"
UURU_DATABASE_USER = "uuuru"
UURU_DATABASE_PASSWORD = "uurupassword"
UURU_DATABASE_DB = "uuru"

# activate to drop state on every restart
# UURU_LIFESPAN_DROP_DB = 1
51 changes: 31 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,35 +1,46 @@
# Micro User Registration Utility

Minimal phone extension self registration utility. Build with shiny stuff like FastAPI and SQLModel.
Minimal phone extension self registration utility for asterisk.
Additional features:

## Get Started (Dev Server)
* `Innovaphone` provisioning

To run the devserver on your machine you need to install `uv`. Please
follow the steps [from these instructions](https://docs.astral.sh/uv/getting-started/installation/).
Build with shiny stuff like FastAPI and SQLModel.

Once you have `uv` installed, you can simply run the development server
using this command:
## Architecture

```bash
uv run fastapi dev
```
This project is based on two components:

* `uuru` (+ database)
* `asterisk` (+ database)

`uuru` configure `asterisk` via the database integration.

## Get Started

### Requirements

## Get Started (Docker)
To deploy `uuru` you need

* `docker compose` [Installation Instructions](https://docs.docker.com/compose/install/)
* `uv` [Installation Instructions](https://docs.astral_.sh/uv/getting-started/installation/) (if you want to develop)

### Production

**production environment**:
```
docker compose up
docker compose up --build
```

**development environment**:
### Development

```
docker compose up -f docker-compose.yml -f docker-compose.dev.yml
cp -av .env.sample .env
docker compose -f docker-compose-base.yml up --build -d
uv run fastapi dev
```

## Run tests

To run the test use this command
### ports

```bash
coverage run --source=app -m pytest
```
* app: `127.0.0.1:8000`
* mariadb app: `127.0.0.1:3307`
* mariadb asterisk: `127.0.0.1:3306`
39 changes: 20 additions & 19 deletions app/core/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,38 +47,39 @@ def all_cors_origins(self) -> list[str]:

## DATABASE

POSTGRES_SERVER: str
POSTGRES_PORT: int = 5432
POSTGRES_USER: str
POSTGRES_PASSWORD: str = ""
POSTGRES_DB: str = ""
POSTGRES_DB_TEST: str | None = None
DATABASE_TYPE: Literal["mysql"] | Literal["postgres"] = "postgres"
DATABASE_SERVER: str
DATABASE_PORT: int = 5432
DATABASE_USER: str
DATABASE_PASSWORD: str = ""
DATABASE_DB: str = ""
DATABASE_DB_TEST: str | None = None

@computed_field # type: ignore[prop-decorator]
@property
def SQLALCHEMY_TEST_DATABASE_URI(self) -> PostgresDsn:
if not self.POSTGRES_DB_TEST:
if not self.DATABASE_DB_TEST:
return self.SQLALCHEMY_DATABASE_URI

return MultiHostUrl.build(
scheme="postgresql+psycopg",
username=self.POSTGRES_USER,
password=self.POSTGRES_PASSWORD,
host=self.POSTGRES_SERVER,
port=self.POSTGRES_PORT,
path=self.POSTGRES_DB_TEST,
scheme="postgresql+psycopg" if self.DATABASE_TYPE == "postgres" else "mysql+pymysql",
username=self.DATABASE_USER,
password=self.DATABASE_PASSWORD,
host=self.DATABASE_SERVER,
port=self.DATABASE_PORT,
path=self.DATABASE_DB_TEST,
)

@computed_field # type: ignore[prop-decorator]
@property
def SQLALCHEMY_DATABASE_URI(self) -> PostgresDsn:
return MultiHostUrl.build(
scheme="postgresql+psycopg",
username=self.POSTGRES_USER,
password=self.POSTGRES_PASSWORD,
host=self.POSTGRES_SERVER,
port=self.POSTGRES_PORT,
path=self.POSTGRES_DB,
scheme="postgresql+psycopg" if self.DATABASE_TYPE == "postgres" else "mysql+pymysql",
username=self.DATABASE_USER,
password=self.DATABASE_PASSWORD,
host=self.DATABASE_SERVER,
port=self.DATABASE_PORT,
path=self.DATABASE_DB,
)

## BEHAVIOR
Expand Down
29 changes: 29 additions & 0 deletions asterisk/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
FROM ubuntu:24.04

ARG ASTERISK_SOURCE_VERSION=20.15.0

# download needed packages
RUN apt-get update && apt-get install -y --no-install-recommends \
wget \
alembic \
asterisk \
unixodbc \
unixodbc-dev \
odbc-mariadb \
gettext-base \
ca-certificates \
python3-mysqldb \
&& rm -rf /var/lib/apt/lists/*

# download asterisk source - extract alembic contrib - move into /etc/alembic
RUN wget https://downloads.asterisk.org/pub/telephony/asterisk/asterisk-${ASTERISK_SOURCE_VERSION}.tar.gz \
&& tar -xvzf asterisk-${ASTERISK_SOURCE_VERSION}.tar.gz asterisk-${ASTERISK_SOURCE_VERSION}/contrib/ast-db-manage \
&& mv asterisk-${ASTERISK_SOURCE_VERSION}/contrib/ast-db-manage alembic \
&& mv alembic /etc/alembic \
&& rm -rf asterisk-${ASTERISK_SOURCE_VERSION}* alembic/

COPY etc/ /etc/

COPY entrypoint.sh /

ENTRYPOINT /entrypoint.sh
14 changes: 14 additions & 0 deletions asterisk/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/bin/bash

set -e

# execute alembic database migrations
cd /etc/alembic
envsubst < config.ini.tmpl > config.ini
alembic -c config.ini upgrade head

# execute asterisk
cd /
envsubst < /etc/odbc.ini.tmpl > /etc/odbc.ini
envsubst < /etc/asterisk/res_odbc.conf.tmpl > /etc/asterisk/res_odbc.conf
exec asterisk -f
38 changes: 38 additions & 0 deletions asterisk/etc/alembic/config.ini.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
[alembic]
script_location = config
sqlalchemy.url = mysql://${MARIADB_USER}:${MARIADB_PASSWORD}@${MARIADB_HOST}/${MARIADB_DATABASE}

# Logging configuration
[loggers]
keys = root,sqlalchemy,alembic

[handlers]
keys = console

[formatters]
keys = generic

[logger_root]
level = WARN
handlers = console
qualname =

[logger_sqlalchemy]
level = WARN
handlers =
qualname = sqlalchemy.engine

[logger_alembic]
level = INFO
handlers =
qualname = alembic

[handler_console]
class = StreamHandler
args = (sys.stderr,)
level = NOTSET
formatter = generic

[formatter_generic]
format = %(levelname)-5.5s [%(name)s] %(message)s
datefmt = %H:%M:%S
7 changes: 7 additions & 0 deletions asterisk/etc/asterisk/extconfig.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[settings]
ps_endpoints => odbc,asterisk
ps_auths => odbc,asterisk
ps_aors => odbc,asterisk
ps_domain_aliases => odbc,asterisk
ps_endpoint_id_ips => odbc,asterisk
ps_contacts => odbc,asterisk
3 changes: 3 additions & 0 deletions asterisk/etc/asterisk/extensions.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[pjsip_internal]
exten => _1XXX,1,NoOp()
same => n,Dial(${PJSIP_DIAL_CONTACTS(${EXTEN})})
74 changes: 74 additions & 0 deletions asterisk/etc/asterisk/modules.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
;
; Asterisk configuration file
;
; Module Loader configuration file
;

[modules]
autoload=yes
;
; Any modules that need to be loaded before the Asterisk core has been
; initialized (just after the logger has been initialized) can be loaded
; using 'preload'. This will frequently be needed if you wish to map all
; module configuration files into Realtime storage, since the Realtime
; driver will need to be loaded before the modules using those configuration
; files are initialized.
;
; An example of loading ODBC support would be:
preload => res_odbc.so
preload => res_config_odbc.so
noload => chan_sip.so
;
; If you want, load the GTK console right away.
; Don't load the KDE console since
; it's not as sophisticated right now.
;
noload => pbx_gtkconsole.so
;load => pbx_gtkconsole.so
noload => pbx_kdeconsole.so
;
; Intercom application is obsoleted by
; chan_oss. Don't load it.
;
noload => app_intercom.so
;
; The 'modem' channel driver and its subdrivers are
; obsolete, don't load them.
;
noload => chan_modem.so
noload => chan_modem_aopen.so
noload => chan_modem_bestdata.so
noload => chan_modem_i4l.so
;
; Comment this out (after installing CAPI middleware and hardware
; drivers) if you have CAPI-able hardware and wish to use it in
; Asterisk.
;
noload => chan_capi.so
;
load => res_musiconhold.so
;
; Do not load load local channel drivers (using the system speaker) by default,
; they are not used in most installations and might block the sound hardware
;
noload => chan_alsa.so
noload => chan_console.so
noload => chan_oss.so
;
; Disable CDR logging to SQLite by default since it writes unconditionally to
; cdr.db without a way to rotate it.
;
noload => cdr_sqlite.so
;
; These conflict with app_directory.so and each other.
noload => app_directory_odbc.so
;
; Enable these if you want to configure Asterisk in a database
;
; noload => res_config_odbc.so
noload => res_config_pgsql.so
;
; Module names listed in "global" section will have symbols globally
; exported to modules loaded after them.
;
[global]
4 changes: 4 additions & 0 deletions asterisk/etc/asterisk/pjsip.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[transport-udp]
type=transport
protocol=udp
bind=0.0.0.0
6 changes: 6 additions & 0 deletions asterisk/etc/asterisk/res_odbc.conf.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[asterisk]
enabled => yes
dsn => asterisk
username => ${MARIADB_USER}
password => ${MARIADB_PASSWORD}
pre-connect => yes
9 changes: 9 additions & 0 deletions asterisk/etc/asterisk/sorcery.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[res_pjsip]
endpoint=realtime,ps_endpoints
auth=realtime,ps_auths
aor=realtime,ps_aors
domain_alias=realtime,ps_domain_aliases
contact=realtime,ps_contacts

[res_pjsip_endpoint_identifier_ip]
identify=realtime,ps_endpoint_id_ips
8 changes: 8 additions & 0 deletions asterisk/etc/odbc.ini.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[asterisk]
Driver = MariaDB Unicode
Description = MariaDB connection to ‘asterisk’ database
Server = ${MARIADB_HOST}
Port = 3306
Database = ${MARIADB_DATABASE}
UserName = ${MARIADB_USER}
Password = ${MARIADB_PASSWORD}
38 changes: 38 additions & 0 deletions docker-compose-base.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
services:
mariadb-app:
image: mariadb
healthcheck:
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
start_period: 300s
environment:
MARIADB_RANDOM_ROOT_PASSWORD: yes
MARIADB_USER: uuru
MARIADB_DATABASE: uuru
MARIADB_PASSWORD: uurupassword
ports:
- 127.0.0.1:3307:3306

mariadb-asterisk:
image: mariadb
healthcheck:
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
start_period: 300s
environment:
MARIADB_RANDOM_ROOT_PASSWORD: yes
MARIADB_USER: asterisk
MARIADB_DATABASE: asterisk
MARIADB_PASSWORD: asteriskpassword
ports:
- 127.0.0.1:3306:3306

asterisk:
build: asterisk/
depends_on:
mariadb-asterisk:
condition: service_healthy
environment:
MARIADB_DATABASE: asterisk
MARIADB_HOST: 127.0.0.1
MARIADB_USER: asterisk
MARIADB_PASSWORD: asteriskpassword
network_mode: host
5 changes: 0 additions & 5 deletions docker-compose.dev.yml

This file was deleted.

Loading