opensipscli 0.4.0__tar.gz → 0.4.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- opensipscli-0.4.1/.github/workflows/docker-push-image.yml +38 -0
- {opensipscli-0.4.0 → opensipscli-0.4.1}/.github/workflows/docker-readme.yml +2 -2
- {opensipscli-0.4.0 → opensipscli-0.4.1}/.github/workflows/pypi.yml +5 -5
- {opensipscli-0.4.0 → opensipscli-0.4.1}/PKG-INFO +3 -3
- {opensipscli-0.4.0 → opensipscli-0.4.1}/docs/INSTALLATION.md +2 -2
- {opensipscli-0.4.0 → opensipscli-0.4.1}/docs/modules/database.md +15 -1
- {opensipscli-0.4.0 → opensipscli-0.4.1}/opensipscli/db.py +38 -40
- {opensipscli-0.4.0 → opensipscli-0.4.1}/opensipscli/modules/database.py +70 -1
- {opensipscli-0.4.0 → opensipscli-0.4.1}/opensipscli/version.py +1 -1
- {opensipscli-0.4.0 → opensipscli-0.4.1}/packaging/debian/changelog +6 -0
- {opensipscli-0.4.0 → opensipscli-0.4.1}/packaging/debian/control +1 -1
- {opensipscli-0.4.0 → opensipscli-0.4.1}/packaging/redhat_fedora/opensips-cli.spec +5 -3
- {opensipscli-0.4.0 → opensipscli-0.4.1}/pyproject.toml +1 -1
- {opensipscli-0.4.0 → opensipscli-0.4.1}/setup.py +1 -1
- opensipscli-0.4.0/.github/workflows/docker-push-image.yml +0 -26
- {opensipscli-0.4.0 → opensipscli-0.4.1}/.gitignore +0 -0
- {opensipscli-0.4.0 → opensipscli-0.4.1}/LICENSE +0 -0
- {opensipscli-0.4.0 → opensipscli-0.4.1}/README.md +0 -0
- {opensipscli-0.4.0 → opensipscli-0.4.1}/SECURITY.md +0 -0
- {opensipscli-0.4.0 → opensipscli-0.4.1}/bin/opensips-cli +0 -0
- {opensipscli-0.4.0 → opensipscli-0.4.1}/docker/Dockerfile +0 -0
- {opensipscli-0.4.0 → opensipscli-0.4.1}/docker/Makefile +0 -0
- {opensipscli-0.4.0 → opensipscli-0.4.1}/docker/docker.md +0 -0
- {opensipscli-0.4.0 → opensipscli-0.4.1}/docker/run.sh +0 -0
- {opensipscli-0.4.0 → opensipscli-0.4.1}/docs/modules/diagnose.md +0 -0
- {opensipscli-0.4.0 → opensipscli-0.4.1}/docs/modules/instance.md +0 -0
- {opensipscli-0.4.0 → opensipscli-0.4.1}/docs/modules/mi.md +0 -0
- {opensipscli-0.4.0 → opensipscli-0.4.1}/docs/modules/tls.md +0 -0
- {opensipscli-0.4.0 → opensipscli-0.4.1}/docs/modules/trace.md +0 -0
- {opensipscli-0.4.0 → opensipscli-0.4.1}/docs/modules/trap.md +0 -0
- {opensipscli-0.4.0 → opensipscli-0.4.1}/docs/modules/user.md +0 -0
- {opensipscli-0.4.0 → opensipscli-0.4.1}/etc/default.cfg +0 -0
- {opensipscli-0.4.0 → opensipscli-0.4.1}/opensipscli/__init__.py +0 -0
- {opensipscli-0.4.0 → opensipscli-0.4.1}/opensipscli/args.py +0 -0
- {opensipscli-0.4.0 → opensipscli-0.4.1}/opensipscli/cli.py +0 -0
- {opensipscli-0.4.0 → opensipscli-0.4.1}/opensipscli/comm.py +0 -0
- {opensipscli-0.4.0 → opensipscli-0.4.1}/opensipscli/config.py +0 -0
- {opensipscli-0.4.0 → opensipscli-0.4.1}/opensipscli/defaults.py +0 -0
- {opensipscli-0.4.0 → opensipscli-0.4.1}/opensipscli/libs/__init__.py +0 -0
- {opensipscli-0.4.0 → opensipscli-0.4.1}/opensipscli/libs/sqlalchemy_utils.py +0 -0
- {opensipscli-0.4.0 → opensipscli-0.4.1}/opensipscli/logger.py +0 -0
- {opensipscli-0.4.0 → opensipscli-0.4.1}/opensipscli/main.py +0 -0
- {opensipscli-0.4.0 → opensipscli-0.4.1}/opensipscli/module.py +0 -0
- {opensipscli-0.4.0 → opensipscli-0.4.1}/opensipscli/modules/__init__.py +0 -0
- {opensipscli-0.4.0 → opensipscli-0.4.1}/opensipscli/modules/diagnose.py +0 -0
- {opensipscli-0.4.0 → opensipscli-0.4.1}/opensipscli/modules/instance.py +0 -0
- {opensipscli-0.4.0 → opensipscli-0.4.1}/opensipscli/modules/mi.py +0 -0
- {opensipscli-0.4.0 → opensipscli-0.4.1}/opensipscli/modules/tls.py +0 -0
- {opensipscli-0.4.0 → opensipscli-0.4.1}/opensipscli/modules/trace.py +0 -0
- {opensipscli-0.4.0 → opensipscli-0.4.1}/opensipscli/modules/trap.py +0 -0
- {opensipscli-0.4.0 → opensipscli-0.4.1}/opensipscli/modules/user.py +0 -0
- {opensipscli-0.4.0 → opensipscli-0.4.1}/packaging/debian/.gitignore +0 -0
- {opensipscli-0.4.0 → opensipscli-0.4.1}/packaging/debian/compat +0 -0
- {opensipscli-0.4.0 → opensipscli-0.4.1}/packaging/debian/copyright +0 -0
- {opensipscli-0.4.0 → opensipscli-0.4.1}/packaging/debian/rules +0 -0
- {opensipscli-0.4.0 → opensipscli-0.4.1}/packaging/debian/source/format +0 -0
- {opensipscli-0.4.0 → opensipscli-0.4.1}/packaging/debian/watch +0 -0
- {opensipscli-0.4.0 → opensipscli-0.4.1}/setup.cfg +0 -0
- {opensipscli-0.4.0 → opensipscli-0.4.1}/test/alltests.py +0 -0
- {opensipscli-0.4.0 → opensipscli-0.4.1}/test/test-database.sh +0 -0
- {opensipscli-0.4.0 → opensipscli-0.4.1}/test/test.sh +0 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
name: Push OpenSIPS CLI Images in Docker Hub
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
repository_dispatch:
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
build:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v6
|
|
14
|
+
|
|
15
|
+
- name: Set up Docker Buildx
|
|
16
|
+
uses: docker/setup-buildx-action@v4
|
|
17
|
+
|
|
18
|
+
- name: Log in to Docker Hub
|
|
19
|
+
uses: docker/login-action@v4
|
|
20
|
+
with:
|
|
21
|
+
username: ${{ secrets.DOCKER_USERNAME }}
|
|
22
|
+
password: ${{ secrets.DOCKER_TOKEN }}
|
|
23
|
+
|
|
24
|
+
- name: Log in to GitHub Container Registry
|
|
25
|
+
uses: docker/login-action@v4
|
|
26
|
+
with:
|
|
27
|
+
registry: ghcr.io
|
|
28
|
+
username: ${{ github.repository_owner }}
|
|
29
|
+
password: ${{ secrets.GITHUB_TOKEN }}
|
|
30
|
+
|
|
31
|
+
- name: Build and push Docker image
|
|
32
|
+
uses: docker/build-push-action@v7
|
|
33
|
+
with:
|
|
34
|
+
context: ./docker/
|
|
35
|
+
push: true
|
|
36
|
+
tags: |
|
|
37
|
+
opensips/opensips-cli:latest
|
|
38
|
+
ghcr.io/opensips/opensips-cli:latest
|
|
@@ -12,11 +12,11 @@ jobs:
|
|
|
12
12
|
dockerHubDescription:
|
|
13
13
|
runs-on: ubuntu-latest
|
|
14
14
|
steps:
|
|
15
|
-
- uses: actions/checkout@
|
|
15
|
+
- uses: actions/checkout@v6
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
- name: Docker Hub Description
|
|
19
|
-
uses: peter-evans/dockerhub-description@
|
|
19
|
+
uses: peter-evans/dockerhub-description@v5
|
|
20
20
|
with:
|
|
21
21
|
username: ${{ secrets.DOCKER_USERNAME }}
|
|
22
22
|
password: ${{ secrets.DOCKER_TOKEN }}
|
|
@@ -9,9 +9,9 @@ jobs:
|
|
|
9
9
|
runs-on: ubuntu-latest
|
|
10
10
|
|
|
11
11
|
steps:
|
|
12
|
-
- uses: actions/checkout@
|
|
12
|
+
- uses: actions/checkout@v6
|
|
13
13
|
- name: Set up Python
|
|
14
|
-
uses: actions/setup-python@
|
|
14
|
+
uses: actions/setup-python@v6
|
|
15
15
|
with:
|
|
16
16
|
python-version: "3.x"
|
|
17
17
|
- name: Install pypa/build
|
|
@@ -23,7 +23,7 @@ jobs:
|
|
|
23
23
|
- name: Build a binary wheel and a source tarball
|
|
24
24
|
run: python3 -m build
|
|
25
25
|
- name: Store the distribution packages
|
|
26
|
-
uses: actions/upload-artifact@
|
|
26
|
+
uses: actions/upload-artifact@v7
|
|
27
27
|
with:
|
|
28
28
|
name: python-package-distributions
|
|
29
29
|
path: dist/
|
|
@@ -43,7 +43,7 @@ jobs:
|
|
|
43
43
|
|
|
44
44
|
steps:
|
|
45
45
|
- name: Download all the dists
|
|
46
|
-
uses: actions/download-artifact@
|
|
46
|
+
uses: actions/download-artifact@v8
|
|
47
47
|
with:
|
|
48
48
|
name: python-package-distributions
|
|
49
49
|
path: dist/
|
|
@@ -64,7 +64,7 @@ jobs:
|
|
|
64
64
|
|
|
65
65
|
steps:
|
|
66
66
|
- name: Download all the dists
|
|
67
|
-
uses: actions/download-artifact@
|
|
67
|
+
uses: actions/download-artifact@v8
|
|
68
68
|
with:
|
|
69
69
|
name: python-package-distributions
|
|
70
70
|
path: dist/
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
2
|
Name: opensipscli
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.1
|
|
4
4
|
Summary: OpenSIPS Command Line Interface
|
|
5
5
|
Project-URL: Homepage, https://github.com/OpenSIPS/opensips-cli
|
|
6
6
|
Project-URL: Source, https://github.com/OpenSIPS/opensips-cli
|
|
@@ -16,7 +16,7 @@ Classifier: Programming Language :: Python :: 3
|
|
|
16
16
|
Requires-Python: >=3.8
|
|
17
17
|
Requires-Dist: opensips
|
|
18
18
|
Requires-Dist: pymysql
|
|
19
|
-
Requires-Dist: sqlalchemy>=1.3.
|
|
19
|
+
Requires-Dist: sqlalchemy>=1.3.2
|
|
20
20
|
Description-Content-Type: text/markdown
|
|
21
21
|
|
|
22
22
|
# OpenSIPS CLI (Command Line Interface)
|
|
@@ -17,8 +17,8 @@ to your system using the instructions provided, then install the
|
|
|
17
17
|
|
|
18
18
|
Supported Operating Systems (at the time of writing):
|
|
19
19
|
|
|
20
|
-
* Debian
|
|
21
|
-
* Ubuntu
|
|
20
|
+
* Debian 10-12
|
|
21
|
+
* Ubuntu 18.04, 20.04, 22.04, 24.04
|
|
22
22
|
|
|
23
23
|
### RPM packages (.rpm)
|
|
24
24
|
|
|
@@ -14,7 +14,10 @@ which database to delete.
|
|
|
14
14
|
parameter the name of the module, as specified in the OpenSIPS scripts
|
|
15
15
|
hierarchy.
|
|
16
16
|
* `migrate` - copy and convert an OpenSIPS database into its next OpenSIPS
|
|
17
|
-
release equivalent
|
|
17
|
+
release equivalent
|
|
18
|
+
* `pi` - creates a `pi_http` framework from the framework shipped with
|
|
19
|
+
OpenSIPS, using the configured database URL and modules. An optional output
|
|
20
|
+
path may be provided.
|
|
18
21
|
|
|
19
22
|
## Configuration
|
|
20
23
|
|
|
@@ -90,6 +93,17 @@ opensips-cli -x database add rtpproxy
|
|
|
90
93
|
```
|
|
91
94
|
The command above will create the `rtpproxy_sockets` table.
|
|
92
95
|
|
|
96
|
+
To create a provisioning framework for the configured modules, run:
|
|
97
|
+
|
|
98
|
+
```
|
|
99
|
+
opensips-cli -x database pi /etc/opensips/pi_framework.xml
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
The command reuses the framework shipped in the OpenSIPS `pi_http` scripts,
|
|
103
|
+
including its module-specific columns, validations, and commands. When
|
|
104
|
+
`database_modules` is not `ALL`, entries for other modules are removed from
|
|
105
|
+
the generated file.
|
|
106
|
+
|
|
93
107
|
A drop command will prompt the user whether they really want to drop the
|
|
94
108
|
database or not:
|
|
95
109
|
|
|
@@ -210,7 +210,16 @@ class osdb(object):
|
|
|
210
210
|
|
|
211
211
|
# TODO: do this only for SQLAlchemy
|
|
212
212
|
try:
|
|
213
|
-
self.
|
|
213
|
+
if self.dialect == "sqlite":
|
|
214
|
+
# SQLite only got the AUTOCOMMIT isolation level in SA 1.3.16;
|
|
215
|
+
# older versions (EL8 ships 1.3.2) reject it with ArgumentError.
|
|
216
|
+
# Setting the pysqlite isolation_level to None gives the same
|
|
217
|
+
# autocommit behaviour on every supported SA version.
|
|
218
|
+
self.__engine = sqlalchemy.create_engine(
|
|
219
|
+
db_url, connect_args={'isolation_level': None})
|
|
220
|
+
else:
|
|
221
|
+
self.__engine = sqlalchemy.create_engine(
|
|
222
|
+
db_url, isolation_level='AUTOCOMMIT')
|
|
214
223
|
|
|
215
224
|
logger.debug("connecting to %s", db_url)
|
|
216
225
|
self.__conn = self.__engine.connect()
|
|
@@ -477,10 +486,10 @@ class osdb(object):
|
|
|
477
486
|
if not self.__conn:
|
|
478
487
|
raise osdbError("connection not available")
|
|
479
488
|
|
|
480
|
-
where_str = self.get_where(filter_keys)
|
|
489
|
+
where_str, params = self.get_where(filter_keys)
|
|
481
490
|
statement = "DELETE FROM {}{}".format(table, where_str)
|
|
482
491
|
try:
|
|
483
|
-
self.__conn.execute(text(statement))
|
|
492
|
+
self.__conn.execute(text(statement), params)
|
|
484
493
|
except sqlalchemy.exc.SQLAlchemyError as ex:
|
|
485
494
|
logger.error("cannot execute query: {}".format(statement))
|
|
486
495
|
logger.error(ex)
|
|
@@ -658,13 +667,13 @@ class osdb(object):
|
|
|
658
667
|
elif type(fields) != list:
|
|
659
668
|
fields = [ fields ]
|
|
660
669
|
|
|
661
|
-
where_str = self.get_where(filter_keys)
|
|
670
|
+
where_str, params = self.get_where(filter_keys)
|
|
662
671
|
statement = "SELECT {} FROM {}{}".format(
|
|
663
672
|
", ".join(fields),
|
|
664
673
|
table,
|
|
665
674
|
where_str)
|
|
666
675
|
try:
|
|
667
|
-
result = self.__conn.execute(text(statement))
|
|
676
|
+
result = self.__conn.execute(text(statement), params)
|
|
668
677
|
except sqlalchemy.exc.SQLAlchemyError as ex:
|
|
669
678
|
logger.error("cannot execute query: {}".format(statement))
|
|
670
679
|
logger.error(ex)
|
|
@@ -679,22 +688,18 @@ class osdb(object):
|
|
|
679
688
|
|
|
680
689
|
def get_where(self, filter_keys):
|
|
681
690
|
"""
|
|
682
|
-
construct a sql 'where clause' from given filter keys
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
where_str = " WHERE " + where_str[5:]
|
|
695
|
-
else:
|
|
696
|
-
where_str = ""
|
|
697
|
-
return where_str
|
|
691
|
+
construct a sql 'where clause' from given filter keys, along with
|
|
692
|
+
the parameters to bind to it
|
|
693
|
+
"""
|
|
694
|
+
if not filter_keys:
|
|
695
|
+
return "", {}
|
|
696
|
+
|
|
697
|
+
where_str = ""
|
|
698
|
+
params = {}
|
|
699
|
+
for i, (k, v) in enumerate(filter_keys.items()):
|
|
700
|
+
where_str += " AND {} = :w{}".format(k, i)
|
|
701
|
+
params["w{}".format(i)] = v
|
|
702
|
+
return " WHERE " + where_str[5:], params
|
|
698
703
|
|
|
699
704
|
def get_role(self, role_name="opensips"):
|
|
700
705
|
"""
|
|
@@ -781,18 +786,13 @@ class osdb(object):
|
|
|
781
786
|
if not self.__conn:
|
|
782
787
|
raise osdbError("connection not available")
|
|
783
788
|
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
values += ", "
|
|
787
|
-
if type(v) == int:
|
|
788
|
-
values += str(v)
|
|
789
|
-
else:
|
|
790
|
-
values += "'{}'".format(
|
|
791
|
-
v.translate(str.maketrans({'\'': '\\\''})))
|
|
789
|
+
cols = list(keys.keys())
|
|
790
|
+
params = {"v{}".format(i): keys[k] for i, k in enumerate(cols)}
|
|
792
791
|
statement = "INSERT INTO {} ({}) VALUES ({})".format(
|
|
793
|
-
table, ", ".join(
|
|
792
|
+
table, ", ".join(cols),
|
|
793
|
+
", ".join(":v{}".format(i) for i in range(len(cols))))
|
|
794
794
|
try:
|
|
795
|
-
result = self.__conn.execute(text(statement))
|
|
795
|
+
result = self.__conn.execute(text(statement), params)
|
|
796
796
|
except sqlalchemy.exc.SQLAlchemyError as ex:
|
|
797
797
|
logger.error("cannot execute query: {}".format(statement))
|
|
798
798
|
logger.error(ex)
|
|
@@ -874,18 +874,16 @@ class osdb(object):
|
|
|
874
874
|
raise osdbError("connection not available")
|
|
875
875
|
|
|
876
876
|
update_str = ""
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
v.translate(str.maketrans({'\'': '\\\''})))
|
|
884
|
-
where_str = self.get_where(filter_keys)
|
|
877
|
+
params = {}
|
|
878
|
+
for i, (k, v) in enumerate(update_keys.items()):
|
|
879
|
+
update_str += ", {} = :s{}".format(k, i)
|
|
880
|
+
params["s{}".format(i)] = v
|
|
881
|
+
where_str, where_params = self.get_where(filter_keys)
|
|
882
|
+
params.update(where_params)
|
|
885
883
|
statement = "UPDATE {} SET {}{}".format(table,
|
|
886
884
|
update_str[2:], where_str)
|
|
887
885
|
try:
|
|
888
|
-
result = self.__conn.execute(text(statement))
|
|
886
|
+
result = self.__conn.execute(text(statement), params)
|
|
889
887
|
except sqlalchemy.exc.SQLAlchemyError as ex:
|
|
890
888
|
logger.error("cannot execute query: {}".format(statement))
|
|
891
889
|
logger.error(ex)
|
|
@@ -28,6 +28,7 @@ from opensipscli.db import (
|
|
|
28
28
|
)
|
|
29
29
|
|
|
30
30
|
import os, re
|
|
31
|
+
import xml.etree.ElementTree as ET
|
|
31
32
|
from getpass import getpass, getuser
|
|
32
33
|
from collections import OrderedDict
|
|
33
34
|
|
|
@@ -590,7 +591,6 @@ class database(Module):
|
|
|
590
591
|
if not text:
|
|
591
592
|
return mig_flavours
|
|
592
593
|
ret = [t for t in mig_flavours if t.startswith(text)]
|
|
593
|
-
|
|
594
594
|
elif arg == 3 or (arg == 4 and line[-1] != ' '):
|
|
595
595
|
db_source = ['opensips ']
|
|
596
596
|
if not text:
|
|
@@ -602,6 +602,8 @@ class database(Module):
|
|
|
602
602
|
if not text:
|
|
603
603
|
return db_dest
|
|
604
604
|
ret = [t for t in db_dest if t.startswith(text)]
|
|
605
|
+
elif command == 'pi':
|
|
606
|
+
ret = ['pi_framework.xml ']
|
|
605
607
|
|
|
606
608
|
return ret or ['']
|
|
607
609
|
|
|
@@ -624,6 +626,7 @@ class database(Module):
|
|
|
624
626
|
'drop',
|
|
625
627
|
'add',
|
|
626
628
|
'migrate',
|
|
629
|
+
'pi',
|
|
627
630
|
]
|
|
628
631
|
|
|
629
632
|
def get_db_url(self, db_name=cfg.get('database_name')):
|
|
@@ -722,6 +725,72 @@ class database(Module):
|
|
|
722
725
|
db.destroy()
|
|
723
726
|
return ret
|
|
724
727
|
|
|
728
|
+
def do_pi(self, params=None, modifiers=None):
|
|
729
|
+
"""Generate a pi_http framework from the installed OpenSIPS template."""
|
|
730
|
+
output = params[0] if params else 'pi_framework.xml'
|
|
731
|
+
if os.path.isdir(output):
|
|
732
|
+
output = os.path.join(output, 'pi_framework.xml')
|
|
733
|
+
|
|
734
|
+
if not cfg.exists('database_url'):
|
|
735
|
+
logger.error("database_url must be configured to create a PI framework")
|
|
736
|
+
return -1
|
|
737
|
+
schema_path = self.get_schema_path(osdb.get_url_driver(cfg.get('database_url')))
|
|
738
|
+
if not schema_path:
|
|
739
|
+
return -1
|
|
740
|
+
|
|
741
|
+
template = None
|
|
742
|
+
for candidate in (
|
|
743
|
+
os.path.join(schema_path, 'pi_http', 'pi_framework.xml'),
|
|
744
|
+
os.path.join(schema_path, 'pi', 'pi_framework.xml'),
|
|
745
|
+
os.path.join(schema_path, 'pi_framework.xml'),
|
|
746
|
+
os.path.join(os.path.dirname(schema_path), 'pi_http',
|
|
747
|
+
'pi_framework.xml')):
|
|
748
|
+
if os.path.isfile(candidate):
|
|
749
|
+
template = candidate
|
|
750
|
+
break
|
|
751
|
+
if not template:
|
|
752
|
+
logger.error("cannot find the installed pi_http framework template")
|
|
753
|
+
return -1
|
|
754
|
+
|
|
755
|
+
try:
|
|
756
|
+
tree = ET.parse(template)
|
|
757
|
+
except ET.ParseError as ex:
|
|
758
|
+
logger.error("invalid PI framework template '{}': {}".format(template, ex))
|
|
759
|
+
return -1
|
|
760
|
+
root = tree.getroot()
|
|
761
|
+
db_url = self.get_db_url()
|
|
762
|
+
if not db_url:
|
|
763
|
+
logger.error("cannot determine the configured database URL")
|
|
764
|
+
return -1
|
|
765
|
+
for node in root.findall('db_url'):
|
|
766
|
+
node.text = db_url
|
|
767
|
+
|
|
768
|
+
configured = cfg.get('database_modules').strip().lower() \
|
|
769
|
+
if cfg.exists('database_modules') else ' '.join(STANDARD_DB_MODULES)
|
|
770
|
+
modules = None if configured == 'all' else set(configured.split())
|
|
771
|
+
if modules is not None:
|
|
772
|
+
retained = []
|
|
773
|
+
referenced_tables = set()
|
|
774
|
+
for mod in list(root.findall('mod')):
|
|
775
|
+
name = mod.findtext('mod_name', '').strip().lower()
|
|
776
|
+
if name in modules:
|
|
777
|
+
retained.append(mod)
|
|
778
|
+
referenced_tables.update(
|
|
779
|
+
c.text.strip() for c in mod.findall('.//db_table_id')
|
|
780
|
+
if c.text)
|
|
781
|
+
else:
|
|
782
|
+
root.remove(mod)
|
|
783
|
+
for table in list(root.findall('db_table')):
|
|
784
|
+
if (table.get('id') not in modules and
|
|
785
|
+
table.get('id') not in referenced_tables):
|
|
786
|
+
root.remove(table)
|
|
787
|
+
|
|
788
|
+
os.makedirs(os.path.dirname(os.path.abspath(output)), exist_ok=True)
|
|
789
|
+
ET.indent(root, space='\t')
|
|
790
|
+
tree.write(output, encoding='utf-8', xml_declaration=True)
|
|
791
|
+
logger.info("PI framework written to '{}' using '{}'".format(output, template))
|
|
792
|
+
return 0
|
|
793
|
+
|
|
725
794
|
|
|
726
795
|
def do_create(self, params=None, modifiers=None):
|
|
727
796
|
"""
|
|
@@ -9,7 +9,7 @@ Homepage: https://github.com/OpenSIPS/opensips-cli
|
|
|
9
9
|
Package: opensips-cli
|
|
10
10
|
Architecture: all
|
|
11
11
|
Multi-Arch: foreign
|
|
12
|
-
Depends: python3, ${misc:Depends}, ${python3:Depends}, python3-sqlalchemy (>= 1.3.
|
|
12
|
+
Depends: python3, ${misc:Depends}, ${python3:Depends}, python3-sqlalchemy (>= 1.3.2), python3-openssl, python3-pymysql, python3-opensips
|
|
13
13
|
Description: Interactive command-line tool for OpenSIPS 3.0+
|
|
14
14
|
This package contains the OpenSIPS CLI tool, an interactive command line tool
|
|
15
15
|
that can be used to control and monitor OpenSIPS 3.0+ servers.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Summary: Interactive command-line tool for OpenSIPS 3.0+
|
|
2
2
|
Name: opensips-cli
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.1
|
|
4
4
|
Release: 0%{?dist}
|
|
5
5
|
License: GPL-3+
|
|
6
6
|
Group: System Environment/Daemons
|
|
@@ -18,11 +18,11 @@ AutoReqProv: no
|
|
|
18
18
|
|
|
19
19
|
Requires: python3
|
|
20
20
|
%if 0%{?rhel} == 7
|
|
21
|
-
Requires: python36-sqlalchemy >= 1.3.
|
|
21
|
+
Requires: python36-sqlalchemy >= 1.3.2
|
|
22
22
|
Requires: python36-PyMySQL
|
|
23
23
|
Requires: python36-pyOpenSSL
|
|
24
24
|
%else
|
|
25
|
-
Requires: python3-sqlalchemy >= 1.3.
|
|
25
|
+
Requires: python3-sqlalchemy >= 1.3.2
|
|
26
26
|
Requires: python3-PyMySQL
|
|
27
27
|
Requires: python3-pyOpenSSL
|
|
28
28
|
%endif
|
|
@@ -68,6 +68,8 @@ rm -rf $RPM_BUILD_ROOT
|
|
|
68
68
|
%license LICENSE
|
|
69
69
|
|
|
70
70
|
%changelog
|
|
71
|
+
* Thu Sep 3 2026 Stefan Darius <darius.stefan@opensips.org> - 0.4.1-0
|
|
72
|
+
- Bump package version to 0.4.1.
|
|
71
73
|
* Fri May 8 2026 Razvan Crainea <razvan@opensips.org> - 0.4.0-0
|
|
72
74
|
- Bump package version to 0.4.0.
|
|
73
75
|
* Thu Aug 27 2020 Liviu Chircu <liviu@opensips.org> - 0.1-2
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
name: Push OpenSIPS CLI Images in Docker Hub
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
repository_dispatch:
|
|
6
|
-
workflow_dispatch:
|
|
7
|
-
|
|
8
|
-
jobs:
|
|
9
|
-
build:
|
|
10
|
-
runs-on: ubuntu-latest
|
|
11
|
-
|
|
12
|
-
steps:
|
|
13
|
-
- uses: actions/checkout@v3
|
|
14
|
-
|
|
15
|
-
- name: Log in to Docker Hub
|
|
16
|
-
uses: docker/login-action@v2.1.0
|
|
17
|
-
with:
|
|
18
|
-
username: ${{ secrets.DOCKER_USERNAME }}
|
|
19
|
-
password: ${{ secrets.DOCKER_TOKEN }}
|
|
20
|
-
|
|
21
|
-
- name: Build and push Docker image
|
|
22
|
-
uses: docker/build-push-action@v4
|
|
23
|
-
with:
|
|
24
|
-
context: ./docker/
|
|
25
|
-
push: true
|
|
26
|
-
tags: opensips/opensips-cli:latest
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|