mirror of
https://github.com/Telecominfraproject/wlan-cloud-ucentralfms.git
synced 2025-10-30 18:27:54 +00:00
Compare commits
80 Commits
v2.6.0-RC1
...
release/v2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7fc16581c7 | ||
|
|
2244e20be2 | ||
|
|
129458f7b6 | ||
|
|
c187710ddf | ||
|
|
c04a0c47ba | ||
|
|
8e16986e2d | ||
|
|
7492e68a73 | ||
|
|
3df36a2e9d | ||
|
|
c74507948d | ||
|
|
912903cc49 | ||
|
|
2a1cc8dc2a | ||
|
|
4e344eac03 | ||
|
|
838b6d016c | ||
|
|
9be24a146d | ||
|
|
2b9e934ac1 | ||
|
|
db5dffe2b8 | ||
|
|
e527983fa6 | ||
|
|
e0ef8d1dbf | ||
|
|
bc1a2b2ab8 | ||
|
|
06da583a6d | ||
|
|
39e8fbc863 | ||
|
|
88adcf6e78 | ||
|
|
dc6455813a | ||
|
|
fed5739afc | ||
|
|
f2fd761558 | ||
|
|
139c3ba217 | ||
|
|
ec8d304ae7 | ||
|
|
578580ad95 | ||
|
|
5e719c9b90 | ||
|
|
96b59c700a | ||
|
|
bbaa5da556 | ||
|
|
5df2701c21 | ||
|
|
ebd890dc79 | ||
|
|
23729bdde0 | ||
|
|
f02d932059 | ||
|
|
c450328e05 | ||
|
|
cf461eadb0 | ||
|
|
73ee40acde | ||
|
|
acd5800206 | ||
|
|
c5b613ecff | ||
|
|
892a756aae | ||
|
|
ccf1834c0b | ||
|
|
f5c4b3b37b | ||
|
|
33f8d5afb2 | ||
|
|
8b37fe2c8c | ||
|
|
66433efb61 | ||
|
|
085aa109c3 | ||
|
|
63043acce8 | ||
|
|
2612a74567 | ||
|
|
38e86e4de6 | ||
|
|
d0ba0eac22 | ||
|
|
0a59afa1fa | ||
|
|
7df6151da8 | ||
|
|
6351082acf | ||
|
|
de6abed9ae | ||
|
|
ba97fd59df | ||
|
|
8ef97f6300 | ||
|
|
f24fb790eb | ||
|
|
1c786ec360 | ||
|
|
c001eb77d8 | ||
|
|
7e7ddd953f | ||
|
|
477f59ca9b | ||
|
|
e0548a2696 | ||
|
|
a900b7e28e | ||
|
|
ef63dcd5b9 | ||
|
|
946c4bc1df | ||
|
|
7fb5be32be | ||
|
|
7cc719fcd6 | ||
|
|
9ea29b6088 | ||
|
|
24e25daa11 | ||
|
|
9a5063b6cf | ||
|
|
f0188afdc1 | ||
|
|
f5c1f808d8 | ||
|
|
eb2e039d48 | ||
|
|
adafc84cb8 | ||
|
|
2eff4174c3 | ||
|
|
dcc39392cf | ||
|
|
f19276e63e | ||
|
|
9ba9b82c31 | ||
|
|
602ca394ed |
8
.github/workflows/cleanup.yml
vendored
8
.github/workflows/cleanup.yml
vendored
@@ -17,4 +17,10 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- run: |
|
- run: |
|
||||||
export PR_BRANCH_TAG=$(echo ${GITHUB_HEAD_REF#refs/heads/} | tr '/' '-')
|
export PR_BRANCH_TAG=$(echo ${GITHUB_HEAD_REF#refs/heads/} | tr '/' '-')
|
||||||
curl -uucentral:${{ secrets.DOCKER_REGISTRY_PASSWORD }} -X DELETE "https://tip.jfrog.io/artifactory/tip-wlan-cloud-ucentral/owfms/$PR_BRANCH_TAG"
|
|
||||||
|
if [[ ! $PR_BRANCH_TAG =~ (main|master|release-*) ]]; then
|
||||||
|
echo "PR branch is $PR_BRANCH_TAG, deleting Docker image"
|
||||||
|
curl -s -uucentral:${{ secrets.DOCKER_REGISTRY_PASSWORD }} -X DELETE "https://tip.jfrog.io/artifactory/tip-wlan-cloud-ucentral/owfms/$PR_BRANCH_TAG"
|
||||||
|
else
|
||||||
|
echo "PR branch is $PR_BRANCH_TAG, not deleting Docker image"
|
||||||
|
fi
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
cmake_minimum_required(VERSION 3.13)
|
cmake_minimum_required(VERSION 3.13)
|
||||||
project(owfms VERSION 2.6.0)
|
project(owfms VERSION 2.7.0)
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 17)
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
|
|
||||||
@@ -59,6 +59,8 @@ include_directories(/usr/local/include /usr/local/opt/openssl/include src inclu
|
|||||||
configure_file(src/ow_version.h.in ${PROJECT_SOURCE_DIR}/src/ow_version.h @ONLY)
|
configure_file(src/ow_version.h.in ${PROJECT_SOURCE_DIR}/src/ow_version.h @ONLY)
|
||||||
|
|
||||||
add_compile_options(-Wall -Wextra)
|
add_compile_options(-Wall -Wextra)
|
||||||
|
add_definitions(-DPOCO_LOG_DEBUG="1")
|
||||||
|
|
||||||
if(ASAN)
|
if(ASAN)
|
||||||
add_compile_options(-fsanitize=address)
|
add_compile_options(-fsanitize=address)
|
||||||
add_link_options(-fsanitize=address)
|
add_link_options(-fsanitize=address)
|
||||||
@@ -74,7 +76,9 @@ add_executable( owfms
|
|||||||
src/framework/orm.h
|
src/framework/orm.h
|
||||||
src/framework/StorageClass.h
|
src/framework/StorageClass.h
|
||||||
src/framework/ow_constants.h
|
src/framework/ow_constants.h
|
||||||
|
src/framework/MicroServiceErrorHandler.h
|
||||||
src/framework/WebSocketClientNotifications.h
|
src/framework/WebSocketClientNotifications.h
|
||||||
|
src/framework/MicroServiceErrorHandler.h
|
||||||
src/RESTObjects/RESTAPI_SecurityObjects.h src/RESTObjects/RESTAPI_SecurityObjects.cpp
|
src/RESTObjects/RESTAPI_SecurityObjects.h src/RESTObjects/RESTAPI_SecurityObjects.cpp
|
||||||
src/RESTObjects/RESTAPI_ProvObjects.cpp src/RESTObjects/RESTAPI_ProvObjects.h
|
src/RESTObjects/RESTAPI_ProvObjects.cpp src/RESTObjects/RESTAPI_ProvObjects.h
|
||||||
src/RESTObjects/RESTAPI_GWobjects.h src/RESTObjects/RESTAPI_GWobjects.cpp
|
src/RESTObjects/RESTAPI_GWobjects.h src/RESTObjects/RESTAPI_GWobjects.cpp
|
||||||
|
|||||||
69
Dockerfile
69
Dockerfile
@@ -1,16 +1,24 @@
|
|||||||
FROM alpine:3.15 AS build-base
|
ARG DEBIAN_VERSION=11.4-slim
|
||||||
|
ARG POCO_VERSION=poco-tip-v1
|
||||||
|
ARG FMTLIB_VERSION=9.0.0
|
||||||
|
ARG CPPKAFKA_VERSION=tip-v1
|
||||||
|
ARG JSON_VALIDATOR_VERSION=2.1.0
|
||||||
|
ARG AWS_SDK_VERSION=1.9.315
|
||||||
|
|
||||||
RUN apk add --update --no-cache \
|
FROM debian:$DEBIAN_VERSION AS build-base
|
||||||
|
|
||||||
|
RUN apt-get update && apt-get install --no-install-recommends -y \
|
||||||
make cmake g++ git \
|
make cmake g++ git \
|
||||||
unixodbc-dev postgresql-dev mariadb-dev \
|
libpq-dev libmariadb-dev libmariadbclient-dev-compat \
|
||||||
librdkafka-dev boost-dev openssl-dev \
|
librdkafka-dev libboost-all-dev libssl-dev \
|
||||||
zlib-dev nlohmann-json \
|
zlib1g-dev nlohmann-json3-dev ca-certificates libcurl4-openssl-dev
|
||||||
curl-dev
|
|
||||||
|
|
||||||
FROM build-base AS poco-build
|
FROM build-base AS poco-build
|
||||||
|
|
||||||
ADD https://api.github.com/repos/stephb9959/poco/git/refs/heads/master version.json
|
ARG POCO_VERSION
|
||||||
RUN git clone https://github.com/stephb9959/poco /poco
|
|
||||||
|
ADD https://api.github.com/repos/AriliaWireless/poco/git/refs/tags/${POCO_VERSION} version.json
|
||||||
|
RUN git clone https://github.com/AriliaWireless/poco --branch ${POCO_VERSION} /poco
|
||||||
|
|
||||||
WORKDIR /poco
|
WORKDIR /poco
|
||||||
RUN mkdir cmake-build
|
RUN mkdir cmake-build
|
||||||
@@ -21,8 +29,10 @@ RUN cmake --build . --target install
|
|||||||
|
|
||||||
FROM build-base AS fmtlib-build
|
FROM build-base AS fmtlib-build
|
||||||
|
|
||||||
ADD https://api.github.com/repos/fmtlib/fmt/git/refs/heads/master version.json
|
ARG FMTLIB_VERSION
|
||||||
RUN git clone https://github.com/fmtlib/fmt /fmtlib
|
|
||||||
|
ADD https://api.github.com/repos/fmtlib/fmt/git/refs/tags/${FMTLIB_VERSION} version.json
|
||||||
|
RUN git clone https://github.com/fmtlib/fmt --branch ${FMTLIB_VERSION} /fmtlib
|
||||||
|
|
||||||
WORKDIR /fmtlib
|
WORKDIR /fmtlib
|
||||||
RUN mkdir cmake-build
|
RUN mkdir cmake-build
|
||||||
@@ -33,8 +43,10 @@ RUN make install
|
|||||||
|
|
||||||
FROM build-base AS cppkafka-build
|
FROM build-base AS cppkafka-build
|
||||||
|
|
||||||
ADD https://api.github.com/repos/stephb9959/cppkafka/git/refs/heads/master version.json
|
ARG CPPKAFKA_VERSION
|
||||||
RUN git clone https://github.com/stephb9959/cppkafka /cppkafka
|
|
||||||
|
ADD https://api.github.com/repos/AriliaWireless/cppkafka/git/refs/tags/${CPPKAFKA_VERSION} version.json
|
||||||
|
RUN git clone https://github.com/AriliaWireless/cppkafka --branch ${CPPKAFKA_VERSION} /cppkafka
|
||||||
|
|
||||||
WORKDIR /cppkafka
|
WORKDIR /cppkafka
|
||||||
RUN mkdir cmake-build
|
RUN mkdir cmake-build
|
||||||
@@ -45,8 +57,10 @@ RUN cmake --build . --target install
|
|||||||
|
|
||||||
FROM build-base AS json-schema-validator-build
|
FROM build-base AS json-schema-validator-build
|
||||||
|
|
||||||
ADD https://api.github.com/repos/pboettch/json-schema-validator/git/refs/heads/master version.json
|
ARG JSON_VALIDATOR_VERSION
|
||||||
RUN git clone https://github.com/pboettch/json-schema-validator /json-schema-validator
|
|
||||||
|
ADD https://api.github.com/repos/pboettch/json-schema-validator/git/refs/tags/${JSON_VALIDATOR_VERSION} version.json
|
||||||
|
RUN git clone https://github.com/pboettch/json-schema-validator --branch ${JSON_VALIDATOR_VERSION} /json-schema-validator
|
||||||
|
|
||||||
WORKDIR /json-schema-validator
|
WORKDIR /json-schema-validator
|
||||||
RUN mkdir cmake-build
|
RUN mkdir cmake-build
|
||||||
@@ -57,14 +71,19 @@ RUN make install
|
|||||||
|
|
||||||
FROM build-base AS aws-sdk-cpp-build
|
FROM build-base AS aws-sdk-cpp-build
|
||||||
|
|
||||||
ADD https://api.github.com/repos/aws/aws-sdk-cpp/git/refs/heads/main version.json
|
ARG AWS_SDK_VERSION
|
||||||
RUN git clone --recurse-submodules https://github.com/aws/aws-sdk-cpp /aws-sdk-cpp
|
|
||||||
|
ADD https://api.github.com/repos/aws/aws-sdk-cpp/git/refs/tags/${AWS_SDK_VERSION} version.json
|
||||||
|
RUN git clone --recurse-submodules https://github.com/aws/aws-sdk-cpp --branch ${AWS_SDK_VERSION} /aws-sdk-cpp
|
||||||
|
|
||||||
WORKDIR /aws-sdk-cpp
|
WORKDIR /aws-sdk-cpp
|
||||||
RUN mkdir cmake-build
|
RUN mkdir cmake-build
|
||||||
WORKDIR cmake-build
|
WORKDIR cmake-build
|
||||||
RUN cmake .. -DBUILD_ONLY="sns;s3" \
|
RUN cmake .. -DBUILD_ONLY="sns;s3" \
|
||||||
-DCMAKE_BUILD_TYPE=Release \
|
-DCMAKE_BUILD_TYPE=Release \
|
||||||
|
-DUSE_OPENSSL=ON \
|
||||||
|
-DCPP_STANDARD=17 \
|
||||||
|
-DBUILD_SHARED_LIBS=ON \
|
||||||
-DCMAKE_CXX_FLAGS="-Wno-error=stringop-overflow -Wno-error=uninitialized" \
|
-DCMAKE_CXX_FLAGS="-Wno-error=stringop-overflow -Wno-error=uninitialized" \
|
||||||
-DAUTORUN_UNIT_TESTS=OFF
|
-DAUTORUN_UNIT_TESTS=OFF
|
||||||
RUN cmake --build . --config Release -j8
|
RUN cmake --build . --config Release -j8
|
||||||
@@ -91,26 +110,24 @@ COPY --from=fmtlib-build /usr/local/lib /usr/local/lib
|
|||||||
WORKDIR /owfms
|
WORKDIR /owfms
|
||||||
RUN mkdir cmake-build
|
RUN mkdir cmake-build
|
||||||
WORKDIR /owfms/cmake-build
|
WORKDIR /owfms/cmake-build
|
||||||
RUN cmake .. \
|
RUN cmake ..
|
||||||
-Dcrypto_LIBRARY=/usr/lib/libcrypto.so \
|
|
||||||
-DBUILD_SHARED_LIBS=ON
|
|
||||||
RUN cmake --build . --config Release -j8
|
RUN cmake --build . --config Release -j8
|
||||||
|
|
||||||
FROM alpine:3.15
|
FROM debian:$DEBIAN_VERSION
|
||||||
|
|
||||||
ENV OWFMS_USER=owfms \
|
ENV OWFMS_USER=owfms \
|
||||||
OWFMS_ROOT=/owfms-data \
|
OWFMS_ROOT=/owfms-data \
|
||||||
OWFMS_CONFIG=/owfms-data
|
OWFMS_CONFIG=/owfms-data
|
||||||
|
|
||||||
RUN addgroup -S "$OWFMS_USER" && \
|
RUN useradd "$OWFMS_USER"
|
||||||
adduser -S -G "$OWFMS_USER" "$OWFMS_USER"
|
|
||||||
|
|
||||||
RUN mkdir /openwifi
|
RUN mkdir /openwifi
|
||||||
RUN mkdir -p "$OWFMS_ROOT" "$OWFMS_CONFIG" && \
|
RUN mkdir -p "$OWFMS_ROOT" "$OWFMS_CONFIG" && \
|
||||||
chown "$OWFMS_USER": "$OWFMS_ROOT" "$OWFMS_CONFIG"
|
chown "$OWFMS_USER": "$OWFMS_ROOT" "$OWFMS_CONFIG"
|
||||||
|
|
||||||
RUN apk add --update --no-cache librdkafka su-exec gettext ca-certificates bash jq curl \
|
RUN apt-get update && apt-get install --no-install-recommends -y \
|
||||||
mariadb-connector-c libpq unixodbc postgresql-client
|
librdkafka++1 gosu gettext ca-certificates bash jq curl wget \
|
||||||
|
libmariadb-dev-compat libpq5 unixodbc postgresql-client
|
||||||
|
|
||||||
COPY readiness_check /readiness_check
|
COPY readiness_check /readiness_check
|
||||||
COPY test_scripts/curl/cli /cli
|
COPY test_scripts/curl/cli /cli
|
||||||
@@ -119,7 +136,7 @@ COPY owfms.properties.tmpl /
|
|||||||
COPY docker-entrypoint.sh /
|
COPY docker-entrypoint.sh /
|
||||||
COPY wait-for-postgres.sh /
|
COPY wait-for-postgres.sh /
|
||||||
RUN wget https://raw.githubusercontent.com/Telecominfraproject/wlan-cloud-ucentral-deploy/main/docker-compose/certs/restapi-ca.pem \
|
RUN wget https://raw.githubusercontent.com/Telecominfraproject/wlan-cloud-ucentral-deploy/main/docker-compose/certs/restapi-ca.pem \
|
||||||
-O /usr/local/share/ca-certificates/restapi-ca-selfsigned.pem
|
-O /usr/local/share/ca-certificates/restapi-ca-selfsigned.crt
|
||||||
|
|
||||||
COPY --from=owfms-build /owfms/cmake-build/owfms /openwifi/owfms
|
COPY --from=owfms-build /owfms/cmake-build/owfms /openwifi/owfms
|
||||||
COPY --from=cppkafka-build /cppkafka/cmake-build/src/lib/* /usr/local/lib
|
COPY --from=cppkafka-build /cppkafka/cmake-build/src/lib/* /usr/local/lib
|
||||||
@@ -128,6 +145,8 @@ COPY --from=aws-sdk-cpp-build /aws-sdk-cpp/cmake-build/aws-cpp-sdk-core/libaws-c
|
|||||||
COPY --from=aws-sdk-cpp-build /aws-sdk-cpp/cmake-build/aws-cpp-sdk-s3/libaws-cpp-sdk-s3.so /usr/local/lib
|
COPY --from=aws-sdk-cpp-build /aws-sdk-cpp/cmake-build/aws-cpp-sdk-s3/libaws-cpp-sdk-s3.so /usr/local/lib
|
||||||
COPY --from=aws-sdk-cpp-build /aws-sdk-cpp/cmake-build/aws-cpp-sdk-sns/libaws-cpp-sdk-sns.so /usr/local/lib
|
COPY --from=aws-sdk-cpp-build /aws-sdk-cpp/cmake-build/aws-cpp-sdk-sns/libaws-cpp-sdk-sns.so /usr/local/lib
|
||||||
|
|
||||||
|
RUN ldconfig
|
||||||
|
|
||||||
EXPOSE 16004 17004 16104
|
EXPOSE 16004 17004 16104
|
||||||
|
|
||||||
ENTRYPOINT ["/docker-entrypoint.sh"]
|
ENTRYPOINT ["/docker-entrypoint.sh"]
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
#!/bin/sh
|
#!/bin/bash
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
if [ "$SELFSIGNED_CERTS" = 'true' ]; then
|
if [ "$SELFSIGNED_CERTS" = 'true' ]; then
|
||||||
update-ca-certificates
|
update-ca-certificates
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ "$TEMPLATE_CONFIG" = 'true' && ! -f "$OWFMS_CONFIG"/owfms.properties ]]; then
|
if [[ "$TEMPLATE_CONFIG" = 'true' ]]; then
|
||||||
RESTAPI_HOST_ROOTCA=${RESTAPI_HOST_ROOTCA:-"\$OWFMS_ROOT/certs/restapi-ca.pem"} \
|
RESTAPI_HOST_ROOTCA=${RESTAPI_HOST_ROOTCA:-"\$OWFMS_ROOT/certs/restapi-ca.pem"} \
|
||||||
RESTAPI_HOST_PORT=${RESTAPI_HOST_PORT:-"16004"} \
|
RESTAPI_HOST_PORT=${RESTAPI_HOST_PORT:-"16004"} \
|
||||||
RESTAPI_HOST_CERT=${RESTAPI_HOST_CERT:-"\$OWFMS_ROOT/certs/restapi-cert.pem"} \
|
RESTAPI_HOST_CERT=${RESTAPI_HOST_CERT:-"\$OWFMS_ROOT/certs/restapi-cert.pem"} \
|
||||||
@@ -22,6 +22,7 @@ if [[ "$TEMPLATE_CONFIG" = 'true' && ! -f "$OWFMS_CONFIG"/owfms.properties ]]; t
|
|||||||
SYSTEM_URI_PRIVATE=${SYSTEM_URI_PRIVATE:-"https://localhost:17004"} \
|
SYSTEM_URI_PRIVATE=${SYSTEM_URI_PRIVATE:-"https://localhost:17004"} \
|
||||||
SYSTEM_URI_PUBLIC=${SYSTEM_URI_PUBLIC:-"https://localhost:16004"} \
|
SYSTEM_URI_PUBLIC=${SYSTEM_URI_PUBLIC:-"https://localhost:16004"} \
|
||||||
SYSTEM_URI_UI=${SYSTEM_URI_UI:-"http://localhost"} \
|
SYSTEM_URI_UI=${SYSTEM_URI_UI:-"http://localhost"} \
|
||||||
|
SECURITY_RESTAPI_DISABLE=${SECURITY_RESTAPI_DISABLE:-"false"} \
|
||||||
S3_BUCKETNAME=${S3_BUCKETNAME:-"ucentral-ap-firmware"} \
|
S3_BUCKETNAME=${S3_BUCKETNAME:-"ucentral-ap-firmware"} \
|
||||||
S3_REGION=${S3_REGION:-"us-east-1"} \
|
S3_REGION=${S3_REGION:-"us-east-1"} \
|
||||||
S3_SECRET=${S3_SECRET:-"*******************************************"} \
|
S3_SECRET=${S3_SECRET:-"*******************************************"} \
|
||||||
@@ -51,7 +52,7 @@ if [ "$1" = '/openwifi/owfms' -a "$(id -u)" = '0' ]; then
|
|||||||
if [ "$RUN_CHOWN" = 'true' ]; then
|
if [ "$RUN_CHOWN" = 'true' ]; then
|
||||||
chown -R "$OWFMS_USER": "$OWFMS_ROOT" "$OWFMS_CONFIG"
|
chown -R "$OWFMS_USER": "$OWFMS_ROOT" "$OWFMS_CONFIG"
|
||||||
fi
|
fi
|
||||||
exec su-exec "$OWFMS_USER" "$@"
|
exec gosu "$OWFMS_USER" "$@"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
exec "$@"
|
exec "$@"
|
||||||
|
|||||||
2
helm/.gitignore
vendored
2
helm/.gitignore
vendored
@@ -1 +1,3 @@
|
|||||||
*.swp
|
*.swp
|
||||||
|
Chart.lock
|
||||||
|
charts/
|
||||||
|
|||||||
@@ -5,14 +5,14 @@ name: owfms
|
|||||||
version: 0.1.0
|
version: 0.1.0
|
||||||
dependencies:
|
dependencies:
|
||||||
- name: postgresql
|
- name: postgresql
|
||||||
repository: https://charts.bitnami.com/bitnami
|
repository: https://tip.jfrog.io/artifactory/tip-wlan-cloud-ucentral-helm/
|
||||||
version: 10.9.2
|
version: 10.9.2
|
||||||
condition: postgresql.enabled
|
condition: postgresql.enabled
|
||||||
- name: mysql
|
- name: mysql
|
||||||
repository: https://charts.bitnami.com/bitnami
|
repository: https://tip.jfrog.io/artifactory/tip-wlan-cloud-ucentral-helm/
|
||||||
version: 8.8.3
|
version: 8.8.3
|
||||||
condition: mysql.enabled
|
condition: mysql.enabled
|
||||||
- name: mariadb
|
- name: mariadb
|
||||||
repository: https://charts.bitnami.com/bitnami
|
repository: https://tip.jfrog.io/artifactory/tip-wlan-cloud-ucentral-helm/
|
||||||
version: 9.4.2
|
version: 9.4.2
|
||||||
condition: mariadb.enabled
|
condition: mariadb.enabled
|
||||||
|
|||||||
@@ -70,7 +70,8 @@ The following table lists the configurable parameters of the chart and their def
|
|||||||
| persistence.size | string | Defines PV size | `'10Gi'` |
|
| persistence.size | string | Defines PV size | `'10Gi'` |
|
||||||
| public_env_variables | hash | Defines list of environment variables to be passed to the Firmware | |
|
| public_env_variables | hash | Defines list of environment variables to be passed to the Firmware | |
|
||||||
| configProperties | hash | Configuration properties that should be passed to the application in `owfms.properties`. May be passed by key in set (i.e. `configProperties."rtty\.token"`) | |
|
| configProperties | hash | Configuration properties that should be passed to the application in `owfms.properties`. May be passed by key in set (i.e. `configProperties."rtty\.token"`) | |
|
||||||
| certs | hash | Defines files (keys and certificates) that should be passed to the Firmware (PEM format is adviced to be used) (see `volumes.owfms` on where it is mounted) | |
|
| existingCertsSecret | string | Existing Kubernetes secret containing all required certificates and private keys for microservice operation. If set, certificates from `certs` key are ignored | `""` |
|
||||||
|
| certs | hash | Defines files (keys and certificates) that should be passed to the Gateway (PEM format is adviced to be used) (see `volumes.owfms` on where it is mounted). If `existingCertsSecret` is set, certificates passed this way will not be used. | |
|
||||||
|
|
||||||
|
|
||||||
Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example,
|
Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example,
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
{{- $root := . -}}
|
{{- $root := . -}}
|
||||||
|
{{- $storageType := index .Values.configProperties "storage.type" -}}
|
||||||
---
|
---
|
||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
@@ -46,6 +47,39 @@ spec:
|
|||||||
- -timeout
|
- -timeout
|
||||||
- 600s
|
- 600s
|
||||||
|
|
||||||
|
{{- if eq $storageType "postgresql" }}
|
||||||
|
- name: wait-postgres
|
||||||
|
image: "{{ .Values.images.owfms.repository }}:{{ .Values.images.owfms.tag }}"
|
||||||
|
imagePullPolicy: {{ .Values.images.owfms.pullPolicy }}
|
||||||
|
command:
|
||||||
|
- /wait-for-postgres.sh
|
||||||
|
- {{ index .Values.configProperties "storage.type.postgresql.host" }}
|
||||||
|
- echo
|
||||||
|
- "PostgreSQL is ready"
|
||||||
|
env:
|
||||||
|
- name: KUBERNETES_DEPLOYED
|
||||||
|
value: "{{ now }}"
|
||||||
|
{{- range $key, $value := .Values.public_env_variables }}
|
||||||
|
- name: {{ $key }}
|
||||||
|
value: {{ $value | quote }}
|
||||||
|
{{- end }}
|
||||||
|
{{- range $key, $value := .Values.secret_env_variables }}
|
||||||
|
- name: {{ $key }}
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: {{ include "owfms.fullname" $root }}-env
|
||||||
|
key: {{ $key }}
|
||||||
|
{{- end }}
|
||||||
|
volumeMounts:
|
||||||
|
{{- range .Values.volumes.owfms }}
|
||||||
|
- name: {{ .name }}
|
||||||
|
mountPath: {{ .mountPath }}
|
||||||
|
{{- if .subPath }}
|
||||||
|
subPath: {{ .subPath }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
containers:
|
containers:
|
||||||
|
|
||||||
- name: owfms
|
- name: owfms
|
||||||
@@ -97,8 +131,10 @@ spec:
|
|||||||
{{- toYaml . | nindent 12 }}
|
{{- toYaml . | nindent 12 }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
|
||||||
|
{{- with .Values.securityContext }}
|
||||||
securityContext:
|
securityContext:
|
||||||
fsGroup: 101
|
{{- toYaml . | nindent 8 }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
imagePullSecrets:
|
imagePullSecrets:
|
||||||
{{- range $image, $imageValue := .Values.images }}
|
{{- range $image, $imageValue := .Values.images }}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ fullnameOverride: ""
|
|||||||
images:
|
images:
|
||||||
owfms:
|
owfms:
|
||||||
repository: tip-tip-wlan-cloud-ucentral.jfrog.io/owfms
|
repository: tip-tip-wlan-cloud-ucentral.jfrog.io/owfms
|
||||||
tag: main
|
tag: v2.7.0
|
||||||
pullPolicy: Always
|
pullPolicy: Always
|
||||||
# regcred:
|
# regcred:
|
||||||
# registry: tip-tip-wlan-cloud-ucentral.jfrog.io
|
# registry: tip-tip-wlan-cloud-ucentral.jfrog.io
|
||||||
@@ -71,7 +71,7 @@ volumes:
|
|||||||
mountPath: /owfms-data/certs
|
mountPath: /owfms-data/certs
|
||||||
volumeDefinition: |
|
volumeDefinition: |
|
||||||
secret:
|
secret:
|
||||||
secretName: {{ include "owfms.fullname" . }}-certs
|
secretName: {{ if .Values.existingCertsSecret }}{{ .Values.existingCertsSecret }}{{ else }}{{ include "owfms.fullname" . }}-certs{{ end }}
|
||||||
# Change this if you want to use another volume type
|
# Change this if you want to use another volume type
|
||||||
- name: persist
|
- name: persist
|
||||||
mountPath: /owfms-data/persist
|
mountPath: /owfms-data/persist
|
||||||
@@ -91,6 +91,9 @@ resources: {}
|
|||||||
# cpu: 100m
|
# cpu: 100m
|
||||||
# memory: 128Mi
|
# memory: 128Mi
|
||||||
|
|
||||||
|
securityContext:
|
||||||
|
fsGroup: 1000
|
||||||
|
|
||||||
nodeSelector: {}
|
nodeSelector: {}
|
||||||
|
|
||||||
tolerations: []
|
tolerations: []
|
||||||
@@ -207,6 +210,9 @@ configProperties:
|
|||||||
storage.type.mysql.username: stephb
|
storage.type.mysql.username: stephb
|
||||||
storage.type.mysql.password: snoopy99
|
storage.type.mysql.password: snoopy99
|
||||||
|
|
||||||
|
# NOTE: List of required certificates may be found in "certs" key. Alternative way to pass required certificates is to create external secret with all required certificates and set secret name in "existingCertsSecret" key. Details may be found in https://github.com/Telecominfraproject/wlan-cloud-ucentral-deploy/tree/main/chart#tldr
|
||||||
|
existingCertsSecret: ""
|
||||||
|
|
||||||
certs:
|
certs:
|
||||||
# restapi-ca.pem: ""
|
# restapi-ca.pem: ""
|
||||||
# restapi-cert.pem: ""
|
# restapi-cert.pem: ""
|
||||||
|
|||||||
@@ -30,58 +30,13 @@ components:
|
|||||||
|
|
||||||
responses:
|
responses:
|
||||||
NotFound:
|
NotFound:
|
||||||
description: The specified resource was not found.
|
$ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/NotFound'
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
properties:
|
|
||||||
ErrorCode:
|
|
||||||
type: integer
|
|
||||||
ErrorDetails:
|
|
||||||
type: string
|
|
||||||
ErrorDescription:
|
|
||||||
type: string
|
|
||||||
|
|
||||||
Unauthorized:
|
Unauthorized:
|
||||||
description: The requested does not have sufficient rights to perform the operation.
|
$ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/Unauthorized'
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
properties:
|
|
||||||
ErrorCode:
|
|
||||||
type: integer
|
|
||||||
enum:
|
|
||||||
- 0 # Success
|
|
||||||
- 1 # PASSWORD_CHANGE_REQUIRED,
|
|
||||||
- 2 # INVALID_CREDENTIALS,
|
|
||||||
- 3 # PASSWORD_ALREADY_USED,
|
|
||||||
- 4 # USERNAME_PENDING_VERIFICATION,
|
|
||||||
- 5 # PASSWORD_INVALID,
|
|
||||||
- 6 # INTERNAL_ERROR,
|
|
||||||
- 7 # ACCESS_DENIED,
|
|
||||||
- 8 # INVALID_TOKEN
|
|
||||||
- 9 # EXPIRED_TOKEN
|
|
||||||
- 10 # RATE_LIMIT_EXCEEDED
|
|
||||||
- 11 # BAD_MFA_TRANSACTION
|
|
||||||
- 12 # MFA_FAILURE
|
|
||||||
- 13 # SECURITY_SERVICE_UNREACHABLE
|
|
||||||
ErrorDetails:
|
|
||||||
type: string
|
|
||||||
ErrorDescription:
|
|
||||||
type: string
|
|
||||||
|
|
||||||
Success:
|
Success:
|
||||||
description: The requested operation was performed.
|
$ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/Success'
|
||||||
content:
|
BadRequest:
|
||||||
application/json:
|
$ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/BadRequest'
|
||||||
schema:
|
|
||||||
properties:
|
|
||||||
Operation:
|
|
||||||
type: string
|
|
||||||
Details:
|
|
||||||
type: string
|
|
||||||
Code:
|
|
||||||
type: integer
|
|
||||||
|
|
||||||
schemas:
|
schemas:
|
||||||
FirmwareDetails:
|
FirmwareDetails:
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ openwifi.system.uri.private = https://localhost:17004
|
|||||||
openwifi.system.uri.public = https://ucentral.dpaas.arilia.com:16004
|
openwifi.system.uri.public = https://ucentral.dpaas.arilia.com:16004
|
||||||
openwifi.system.commandchannel = /tmp/app.owfms
|
openwifi.system.commandchannel = /tmp/app.owfms
|
||||||
openwifi.system.uri.ui = ucentral-ui.arilia.com
|
openwifi.system.uri.ui = ucentral-ui.arilia.com
|
||||||
|
openwifi.security.restapi.disable = false
|
||||||
|
|
||||||
firmwaredb.refresh = 1800
|
firmwaredb.refresh = 1800
|
||||||
firmwaredb.maxage = 90
|
firmwaredb.maxage = 90
|
||||||
|
|||||||
@@ -36,6 +36,8 @@ openwifi.system.uri.private = ${SYSTEM_URI_PRIVATE}
|
|||||||
openwifi.system.uri.public = ${SYSTEM_URI_PUBLIC}
|
openwifi.system.uri.public = ${SYSTEM_URI_PUBLIC}
|
||||||
openwifi.system.commandchannel = /tmp/app.ucentralfms
|
openwifi.system.commandchannel = /tmp/app.ucentralfms
|
||||||
openwifi.system.uri.ui = ${SYSTEM_URI_UI}
|
openwifi.system.uri.ui = ${SYSTEM_URI_UI}
|
||||||
|
openwifi.security.restapi.disable = ${SECURITY_RESTAPI_DISABLE}
|
||||||
|
|
||||||
firmwaredb.refresh = 1800
|
firmwaredb.refresh = 1800
|
||||||
firmwaredb.maxage = 90
|
firmwaredb.maxage = 90
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
|
|
||||||
int AutoUpdater::Start() {
|
int AutoUpdater::Start() {
|
||||||
|
poco_information(Logger(),"Starting...");
|
||||||
AutoUpdaterEnabled_ = MicroService::instance().ConfigGetBool("autoupdater.enabled", false);
|
AutoUpdaterEnabled_ = MicroService::instance().ConfigGetBool("autoupdater.enabled", false);
|
||||||
if(AutoUpdaterEnabled_) {
|
if(AutoUpdaterEnabled_) {
|
||||||
Running_ = false;
|
Running_ = false;
|
||||||
@@ -24,10 +25,12 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void AutoUpdater::Stop() {
|
void AutoUpdater::Stop() {
|
||||||
|
poco_information(Logger(),"Stopping...");
|
||||||
Running_ = false;
|
Running_ = false;
|
||||||
if(AutoUpdaterEnabled_) {
|
if(AutoUpdaterEnabled_) {
|
||||||
Timer_.stop();
|
Timer_.stop();
|
||||||
}
|
}
|
||||||
|
poco_information(Logger(),"Stopped...");
|
||||||
}
|
}
|
||||||
|
|
||||||
void AutoUpdater::ToBeUpgraded(std::string serialNumber, std::string DeviceType) {
|
void AutoUpdater::ToBeUpgraded(std::string serialNumber, std::string DeviceType) {
|
||||||
@@ -38,13 +41,14 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void AutoUpdater::onTimer([[maybe_unused]] Poco::Timer & timer) {
|
void AutoUpdater::onTimer([[maybe_unused]] Poco::Timer & timer) {
|
||||||
|
Utils::SetThreadName("auto-updater");
|
||||||
Running_ = true;
|
Running_ = true;
|
||||||
std::unique_lock L(Mutex_);
|
std::unique_lock L(Mutex_);
|
||||||
while(!Queue_.empty() && Running_) {
|
while(!Queue_.empty() && Running_) {
|
||||||
auto Entry = Queue_.front();
|
auto Entry = Queue_.front();
|
||||||
Queue_.pop_front();
|
Queue_.pop_front();
|
||||||
try {
|
try {
|
||||||
Logger().debug(fmt::format("Preparing to upgrade {}",Entry.first));
|
poco_debug(Logger(),fmt::format("Preparing to upgrade {}",Entry.first));
|
||||||
auto CacheEntry = Cache_.find(Entry.first);
|
auto CacheEntry = Cache_.find(Entry.first);
|
||||||
uint64_t now = OpenWifi::Now();
|
uint64_t now = OpenWifi::Now();
|
||||||
std::string firmwareUpgrade;
|
std::string firmwareUpgrade;
|
||||||
@@ -54,11 +58,11 @@ namespace OpenWifi {
|
|||||||
C.LastCheck = now;
|
C.LastCheck = now;
|
||||||
bool firmwareRCOnly;
|
bool firmwareRCOnly;
|
||||||
if(OpenWifi::SDK::Prov::GetFirmwareOptions(Entry.first, firmwareUpgrade, firmwareRCOnly)) {
|
if(OpenWifi::SDK::Prov::GetFirmwareOptions(Entry.first, firmwareUpgrade, firmwareRCOnly)) {
|
||||||
Logger().debug(fmt::format("Found firmware options for {}",Entry.first));
|
poco_debug(Logger(),fmt::format("Found firmware options for {}",Entry.first));
|
||||||
C.firmwareRCOnly = firmwareRCOnly;
|
C.firmwareRCOnly = firmwareRCOnly;
|
||||||
C.firmwareUpgrade = firmwareUpgrade;
|
C.firmwareUpgrade = firmwareUpgrade;
|
||||||
} else {
|
} else {
|
||||||
Logger().debug(fmt::format("Found no firmware options for {}",Entry.first));
|
poco_debug(Logger(),fmt::format("Found no firmware options for {}",Entry.first));
|
||||||
C.firmwareRCOnly = firmwareRCOnly;
|
C.firmwareRCOnly = firmwareRCOnly;
|
||||||
C.firmwareUpgrade = firmwareUpgrade;
|
C.firmwareUpgrade = firmwareUpgrade;
|
||||||
}
|
}
|
||||||
@@ -68,7 +72,7 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(firmwareUpgrade=="no") {
|
if(firmwareUpgrade=="no") {
|
||||||
Logger().information(fmt::format("Device {} not upgradable. Provisioning service settings.",Entry.first));
|
poco_information(Logger(),fmt::format("Device {} not upgradable. Provisioning service settings.",Entry.first));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,26 +82,26 @@ namespace OpenWifi {
|
|||||||
if(LF) {
|
if(LF) {
|
||||||
if(StorageService()->FirmwaresDB().GetFirmware(fwEntry.Id,fwDetails)) {
|
if(StorageService()->FirmwaresDB().GetFirmware(fwEntry.Id,fwDetails)) {
|
||||||
// send the command to upgrade this device...
|
// send the command to upgrade this device...
|
||||||
Logger().information(fmt::format("Upgrading {} to version {}", Entry.first, fwEntry.Revision));
|
poco_information(Logger(),fmt::format("Upgrading {} to version {}", Entry.first, fwEntry.Revision));
|
||||||
if(OpenWifi::SDK::GW::SendFirmwareUpgradeCommand(Entry.first,fwDetails.uri)) {
|
if(OpenWifi::SDK::GW::SendFirmwareUpgradeCommand(Entry.first,fwDetails.uri)) {
|
||||||
Logger().information(fmt::format("Upgrade command sent for {}",Entry.first));
|
poco_information(Logger(),fmt::format("Upgrade command sent for {}",Entry.first));
|
||||||
} else {
|
} else {
|
||||||
Logger().information(fmt::format("Upgrade command not sent for {}",Entry.first));
|
poco_information(Logger(),fmt::format("Upgrade command not sent for {}",Entry.first));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Logger().information(fmt::format("Firmware for device {} ({}) cannot be found.", Entry.first, Entry.second ));
|
poco_information(Logger(),fmt::format("Firmware for device {} ({}) cannot be found.", Entry.first, Entry.second ));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Logger().information(fmt::format("Firmware for device {} ({}) cannot be found.", Entry.first, Entry.second ));
|
poco_information(Logger(),fmt::format("Firmware for device {} ({}) cannot be found.", Entry.first, Entry.second ));
|
||||||
}
|
}
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
Logger().information(fmt::format("Exception during auto update for device {}.", Entry.first ));
|
poco_information(Logger(),fmt::format("Exception during auto update for device {}.", Entry.first ));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AutoUpdater::reinitialize([[maybe_unused]] Poco::Util::Application &self) {
|
void AutoUpdater::reinitialize([[maybe_unused]] Poco::Util::Application &self) {
|
||||||
Logger().information("Reinitializing.");
|
poco_information(Logger(),"Reinitializing.");
|
||||||
Reset();
|
Reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7,10 +7,13 @@
|
|||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
|
|
||||||
int DeviceCache::Start() {
|
int DeviceCache::Start() {
|
||||||
|
poco_information(Logger(),"Starting...");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceCache::Stop() {
|
void DeviceCache::Stop() {
|
||||||
|
poco_information(Logger(),"Stopping...");
|
||||||
|
poco_information(Logger(),"Stopped...");
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceCache::AddToCache(
|
void DeviceCache::AddToCache(
|
||||||
|
|||||||
@@ -7,11 +7,13 @@
|
|||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
|
|
||||||
int FirmwareCache::Start() {
|
int FirmwareCache::Start() {
|
||||||
|
poco_information(Logger(),"Starting...");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FirmwareCache::Stop() {
|
void FirmwareCache::Stop() {
|
||||||
|
poco_information(Logger(),"Stopping...");
|
||||||
|
poco_information(Logger(),"Stopped...");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<FMSObjects::Firmware> GetFirmware([[maybe_unused]] const std::string & DeviceType, [[maybe_unused]] const std::string & Revision) {
|
std::shared_ptr<FMSObjects::Firmware> GetFirmware([[maybe_unused]] const std::string & DeviceType, [[maybe_unused]] const std::string & Revision) {
|
||||||
|
|||||||
@@ -8,11 +8,14 @@
|
|||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
|
|
||||||
int LatestFirmwareCache::Start() {
|
int LatestFirmwareCache::Start() {
|
||||||
|
poco_information(Logger(),"Starting...");
|
||||||
StorageService()->FirmwaresDB().PopulateLatestFirmwareCache();
|
StorageService()->FirmwaresDB().PopulateLatestFirmwareCache();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LatestFirmwareCache::Stop() {
|
void LatestFirmwareCache::Stop() {
|
||||||
|
poco_information(Logger(),"Stopping...");
|
||||||
|
poco_information(Logger(),"Stopped...");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LatestFirmwareCache::AddToCache(const std::string & DeviceType, const std::string &Revision, const std::string &Id, uint64_t TimeStamp) {
|
bool LatestFirmwareCache::AddToCache(const std::string & DeviceType, const std::string &Revision, const std::string &Id, uint64_t TimeStamp) {
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ namespace OpenWifi {
|
|||||||
Types::StringSet RevisionSet_;
|
Types::StringSet RevisionSet_;
|
||||||
Types::StringSet DeviceSet_;
|
Types::StringSet DeviceSet_;
|
||||||
explicit LatestFirmwareCache() noexcept:
|
explicit LatestFirmwareCache() noexcept:
|
||||||
SubSystemServer("FirmwareCache", "FIRMWARE-CACHE", "FirmwareCache")
|
SubSystemServer("LatestFirmwareCache", "LATEST-FIRMWARE-CACHE", "LatestFirmwareCache")
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -17,11 +17,12 @@
|
|||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
|
|
||||||
void ManifestCreator::onTimer([[maybe_unused]] Poco::Timer &timer) {
|
void ManifestCreator::onTimer([[maybe_unused]] Poco::Timer &timer) {
|
||||||
Logger().information("Performing DB refresh");
|
Utils::SetThreadName("manifest");
|
||||||
|
poco_information(Logger(),"Performing DB refresh");
|
||||||
S3BucketContent BucketList;
|
S3BucketContent BucketList;
|
||||||
StorageService()->FirmwaresDB().RemoveOldFirmware();
|
StorageService()->FirmwaresDB().RemoveOldFirmware();
|
||||||
ReadBucket(BucketList);
|
ReadBucket(BucketList);
|
||||||
Logger().information(fmt::format("Found {} firmware entries in S3 repository.", BucketList.size()));
|
poco_information(Logger(),fmt::format("Found {} firmware entries in S3 repository.", BucketList.size()));
|
||||||
ComputeManifest(BucketList);
|
ComputeManifest(BucketList);
|
||||||
AddManifestToDB(BucketList);
|
AddManifestToDB(BucketList);
|
||||||
}
|
}
|
||||||
@@ -48,7 +49,7 @@ namespace OpenWifi {
|
|||||||
Entry.Image = ParsedContent->get("image").toString();
|
Entry.Image = ParsedContent->get("image").toString();
|
||||||
auto FullNme = Name + "-upgrade.bin";
|
auto FullNme = Name + "-upgrade.bin";
|
||||||
if(FullNme!=Entry.Image) {
|
if(FullNme!=Entry.Image) {
|
||||||
Logger().error(fmt::format("MANIFEST({}): Image name does not match manifest name ({}).",Name,Entry.Image));
|
poco_error(Logger(),fmt::format("MANIFEST({}): Image name does not match manifest name ({}).",Name,Entry.Image));
|
||||||
Entry.Valid = false;
|
Entry.Valid = false;
|
||||||
BadFormat++;
|
BadFormat++;
|
||||||
continue;
|
continue;
|
||||||
@@ -60,7 +61,7 @@ namespace OpenWifi {
|
|||||||
Entry.Valid = false;
|
Entry.Valid = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Logger().error(fmt::format("MANIFEST({}): Entry does not have a valid JSON manifest.",Name));
|
poco_error(Logger(),fmt::format("MANIFEST({}): Entry does not have a valid JSON manifest.",Name));
|
||||||
MissingJson++;
|
MissingJson++;
|
||||||
Entry.Valid = false;
|
Entry.Valid = false;
|
||||||
}
|
}
|
||||||
@@ -69,10 +70,10 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger().information(fmt::format("Accepted {} firmwares.", Accepted));
|
poco_information(Logger(),fmt::format("Accepted {} firmwares.", Accepted));
|
||||||
Logger().information(fmt::format("Rejected {} too old firmwares.", Rejected));
|
poco_information(Logger(),fmt::format("Rejected {} too old firmwares.", Rejected));
|
||||||
Logger().information(fmt::format("Rejected {} bad JSON.", BadFormat));
|
poco_information(Logger(),fmt::format("Rejected {} bad JSON.", BadFormat));
|
||||||
Logger().information(fmt::format("Rejected {} missing JSON.", MissingJson));
|
poco_information(Logger(),fmt::format("Rejected {} missing JSON.", MissingJson));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -98,7 +99,7 @@ namespace OpenWifi {
|
|||||||
F.revision = BucketEntry.Revision;
|
F.revision = BucketEntry.Revision;
|
||||||
F.deviceType = BucketEntry.Compatible;
|
F.deviceType = BucketEntry.Compatible;
|
||||||
if(StorageService()->FirmwaresDB().AddFirmware(F)) {
|
if(StorageService()->FirmwaresDB().AddFirmware(F)) {
|
||||||
Logger().information(fmt::format("Adding firmware '{}', size={}",Release,F.size));
|
poco_information(Logger(),fmt::format("Adding firmware '{}', size={}",Release,F.size));
|
||||||
} else {
|
} else {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -184,7 +185,7 @@ namespace OpenWifi {
|
|||||||
while(!isDone) {
|
while(!isDone) {
|
||||||
Outcome = S3Client.ListObjectsV2(Request);
|
Outcome = S3Client.ListObjectsV2(Request);
|
||||||
if(!Outcome.IsSuccess()) {
|
if(!Outcome.IsSuccess()) {
|
||||||
Logger().error(fmt::format("Error while doing ListObjectsV2: {}, {}",
|
poco_error(Logger(),fmt::format("Error while doing ListObjectsV2: {}, {}",
|
||||||
std::string{Outcome.GetError().GetExceptionName()},
|
std::string{Outcome.GetError().GetExceptionName()},
|
||||||
std::string{Outcome.GetError().GetMessage()}));
|
std::string{Outcome.GetError().GetMessage()}));
|
||||||
return false;
|
return false;
|
||||||
@@ -280,7 +281,7 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
// std::cout << "Count:" << Count << " Runs:" << Runs << std::endl;
|
// std::cout << "Count:" << Count << " Runs:" << Runs << std::endl;
|
||||||
if(!Outcome.IsSuccess()) {
|
if(!Outcome.IsSuccess()) {
|
||||||
Logger().error(fmt::format("Error while doing ListObjectsV2: {}, {}",
|
poco_error(Logger(),fmt::format("Error while doing ListObjectsV2: {}, {}",
|
||||||
std::string{Outcome.GetError().GetExceptionName()},
|
std::string{Outcome.GetError().GetExceptionName()},
|
||||||
std::string{Outcome.GetError().GetMessage()}));
|
std::string{Outcome.GetError().GetMessage()}));
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
void NewCommandHandler::run() {
|
void NewCommandHandler::run() {
|
||||||
Running_ = true ;
|
Running_ = true ;
|
||||||
|
Utils::SetThreadName("cmd-handler");
|
||||||
while(Running_) {
|
while(Running_) {
|
||||||
Poco::Thread::trySleep(2000);
|
Poco::Thread::trySleep(2000);
|
||||||
|
|
||||||
@@ -45,9 +46,9 @@ namespace OpenWifi {
|
|||||||
if(Command=="delete_device") {
|
if(Command=="delete_device") {
|
||||||
auto pSerialNumber = PayloadSection["payload"]["serialNumber"];
|
auto pSerialNumber = PayloadSection["payload"]["serialNumber"];
|
||||||
if(pSerialNumber==SerialNumber) {
|
if(pSerialNumber==SerialNumber) {
|
||||||
Logger().debug(fmt::format("Removing device '{}' from upgrade history.",SerialNumber));
|
poco_debug(Logger(),fmt::format("Removing device '{}' from upgrade history.",SerialNumber));
|
||||||
StorageService()->HistoryDB().DeleteHistory(SerialNumber);
|
StorageService()->HistoryDB().DeleteHistory(SerialNumber);
|
||||||
Logger().debug(fmt::format("Removing device '{}' from device table.",SerialNumber));
|
poco_debug(Logger(),fmt::format("Removing device '{}' from device table.",SerialNumber));
|
||||||
StorageService()->DevicesDB().DeleteDevice(SerialNumber);
|
StorageService()->DevicesDB().DeleteDevice(SerialNumber);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
|
|
||||||
void NewConnectionHandler::run() {
|
void NewConnectionHandler::run() {
|
||||||
|
Utils::SetThreadName("conn-handler");
|
||||||
Running_ = true ;
|
Running_ = true ;
|
||||||
while(Running_) {
|
while(Running_) {
|
||||||
Poco::Thread::trySleep(2000);
|
Poco::Thread::trySleep(2000);
|
||||||
@@ -67,12 +68,12 @@ namespace OpenWifi {
|
|||||||
if(StorageService()->FirmwaresDB().ComputeFirmwareAge(DeviceType, Revision, FA)) {
|
if(StorageService()->FirmwaresDB().ComputeFirmwareAge(DeviceType, Revision, FA)) {
|
||||||
StorageService()->DevicesDB().SetDeviceRevision(SerialNumber, Revision, DeviceType, EndPoint);
|
StorageService()->DevicesDB().SetDeviceRevision(SerialNumber, Revision, DeviceType, EndPoint);
|
||||||
if(FA.age)
|
if(FA.age)
|
||||||
Logger().information(fmt::format("Device {} connection. Firmware is {} older than latest.",SerialNumber, Utils::SecondsToNiceText(FA.age)));
|
poco_information(Logger(),fmt::format("Device {} connection. Firmware is {} older than latest.",SerialNumber, Utils::SecondsToNiceText(FA.age)));
|
||||||
else
|
else
|
||||||
Logger().information(fmt::format("Device {} connection. Device firmware is up to date.",SerialNumber));
|
poco_information(Logger(),fmt::format("Device {} connection. Device firmware is up to date.",SerialNumber));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Logger().information(fmt::format("Device {} connection. Firmware age cannot be determined.",SerialNumber));
|
poco_information(Logger(),fmt::format("Device {} connection. Firmware age cannot be determined.",SerialNumber));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!LatestFirmwareCache()->IsLatest(DeviceType, Revision)) {
|
if(!LatestFirmwareCache()->IsLatest(DeviceType, Revision)) {
|
||||||
@@ -115,6 +116,7 @@ namespace OpenWifi {
|
|||||||
};
|
};
|
||||||
|
|
||||||
int NewConnectionHandler::Start() {
|
int NewConnectionHandler::Start() {
|
||||||
|
poco_information(Logger(),"Starting...");
|
||||||
Types::TopicNotifyFunction F = [this](std::string s1,std::string s2) { this->ConnectionReceived(s1,s2); };
|
Types::TopicNotifyFunction F = [this](std::string s1,std::string s2) { this->ConnectionReceived(s1,s2); };
|
||||||
ConnectionWatcherId_ = KafkaManager()->RegisterTopicWatcher(KafkaTopics::CONNECTION, F);
|
ConnectionWatcherId_ = KafkaManager()->RegisterTopicWatcher(KafkaTopics::CONNECTION, F);
|
||||||
Worker_.start(*this);
|
Worker_.start(*this);
|
||||||
@@ -122,10 +124,12 @@ namespace OpenWifi {
|
|||||||
};
|
};
|
||||||
|
|
||||||
void NewConnectionHandler::Stop() {
|
void NewConnectionHandler::Stop() {
|
||||||
|
poco_information(Logger(),"Stopping...");
|
||||||
KafkaManager()->UnregisterTopicWatcher(KafkaTopics::CONNECTION, ConnectionWatcherId_);
|
KafkaManager()->UnregisterTopicWatcher(KafkaTopics::CONNECTION, ConnectionWatcherId_);
|
||||||
Running_ = false;
|
Running_ = false;
|
||||||
Worker_.wakeUp();
|
Worker_.wakeUp();
|
||||||
Worker_.join();
|
Worker_.join();
|
||||||
|
poco_information(Logger(),"Stopped...");
|
||||||
};
|
};
|
||||||
|
|
||||||
bool NewConnectionHandler::Update() {
|
bool NewConnectionHandler::Update() {
|
||||||
|
|||||||
@@ -538,8 +538,8 @@ namespace OpenWifi::AnalyticsObjects {
|
|||||||
|
|
||||||
void WifiClientHistory::to_json(Poco::JSON::Object &Obj) const {
|
void WifiClientHistory::to_json(Poco::JSON::Object &Obj) const {
|
||||||
field_to_json(Obj,"timestamp",timestamp);
|
field_to_json(Obj,"timestamp",timestamp);
|
||||||
field_to_json(Obj,"stationId",stationId);
|
field_to_json(Obj,"station_id",station_id);
|
||||||
field_to_json(Obj,"bssId",bssId);
|
field_to_json(Obj,"bssid",bssid);
|
||||||
field_to_json(Obj,"ssid",ssid);
|
field_to_json(Obj,"ssid",ssid);
|
||||||
field_to_json(Obj,"rssi",rssi);
|
field_to_json(Obj,"rssi",rssi);
|
||||||
field_to_json(Obj,"rx_bitrate",rx_bitrate);
|
field_to_json(Obj,"rx_bitrate",rx_bitrate);
|
||||||
@@ -573,13 +573,14 @@ namespace OpenWifi::AnalyticsObjects {
|
|||||||
field_to_json(Obj,"connected",connected);
|
field_to_json(Obj,"connected",connected);
|
||||||
field_to_json(Obj,"inactive",inactive);
|
field_to_json(Obj,"inactive",inactive);
|
||||||
field_to_json(Obj,"tx_retries",tx_retries);
|
field_to_json(Obj,"tx_retries",tx_retries);
|
||||||
|
field_to_json(Obj,"venue_id",venue_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WifiClientHistory::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
bool WifiClientHistory::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
try {
|
try {
|
||||||
field_from_json(Obj,"timestamp",timestamp);
|
field_from_json(Obj,"timestamp",timestamp);
|
||||||
field_from_json(Obj,"stationId",stationId);
|
field_from_json(Obj,"station_id",station_id);
|
||||||
field_from_json(Obj,"bssId",bssId);
|
field_from_json(Obj,"bssid",bssid);
|
||||||
field_from_json(Obj,"ssid",ssid);
|
field_from_json(Obj,"ssid",ssid);
|
||||||
field_from_json(Obj,"rssi",rssi);
|
field_from_json(Obj,"rssi",rssi);
|
||||||
field_from_json(Obj,"rx_bitrate",rx_bitrate);
|
field_from_json(Obj,"rx_bitrate",rx_bitrate);
|
||||||
@@ -613,6 +614,7 @@ namespace OpenWifi::AnalyticsObjects {
|
|||||||
field_from_json(Obj,"connected",connected);
|
field_from_json(Obj,"connected",connected);
|
||||||
field_from_json(Obj,"inactive",inactive);
|
field_from_json(Obj,"inactive",inactive);
|
||||||
field_from_json(Obj,"tx_retries",tx_retries);
|
field_from_json(Obj,"tx_retries",tx_retries);
|
||||||
|
field_from_json(Obj,"venue_id",venue_id);
|
||||||
return true;
|
return true;
|
||||||
} catch(...) {
|
} catch(...) {
|
||||||
|
|
||||||
|
|||||||
@@ -376,8 +376,8 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
struct WifiClientHistory {
|
struct WifiClientHistory {
|
||||||
uint64_t timestamp=OpenWifi::Now();
|
uint64_t timestamp=OpenWifi::Now();
|
||||||
std::string stationId;
|
std::string station_id;
|
||||||
std::string bssId;
|
std::string bssid;
|
||||||
std::string ssid;
|
std::string ssid;
|
||||||
int64_t rssi=0;
|
int64_t rssi=0;
|
||||||
uint32_t rx_bitrate=0;
|
uint32_t rx_bitrate=0;
|
||||||
@@ -411,6 +411,7 @@ namespace OpenWifi {
|
|||||||
uint64_t connected=0;
|
uint64_t connected=0;
|
||||||
uint64_t inactive=0;
|
uint64_t inactive=0;
|
||||||
uint64_t tx_retries=0;
|
uint64_t tx_retries=0;
|
||||||
|
std::string venue_id;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
|
|||||||
@@ -3,176 +3,206 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#include "RESTAPI_CertObjects.h"
|
#include "RESTAPI_CertObjects.h"
|
||||||
|
#include "framework/MicroService.h"
|
||||||
|
|
||||||
using OpenWifi::RESTAPI_utils::field_to_json;
|
using OpenWifi::RESTAPI_utils::field_to_json;
|
||||||
using OpenWifi::RESTAPI_utils::field_from_json;
|
using OpenWifi::RESTAPI_utils::field_from_json;
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi::CertObjects {
|
||||||
namespace CertObjects {
|
void CertificateEntry::to_json(Poco::JSON::Object &Obj) const {
|
||||||
void CertificateEntry::to_json(Poco::JSON::Object &Obj) const {
|
field_to_json(Obj,"id", id);
|
||||||
field_to_json(Obj,"id", id);
|
field_to_json(Obj,"entity", entity);
|
||||||
field_to_json(Obj,"entity", entity);
|
field_to_json(Obj,"creator", creator);
|
||||||
field_to_json(Obj,"creator", creator);
|
field_to_json(Obj,"type", type);
|
||||||
field_to_json(Obj,"type", type);
|
field_to_json(Obj,"status", status);
|
||||||
field_to_json(Obj,"status", status);
|
field_to_json(Obj,"certificate", certificate);
|
||||||
field_to_json(Obj,"certificate", certificate);
|
field_to_json(Obj,"key", key);
|
||||||
field_to_json(Obj,"key", key);
|
field_to_json(Obj,"devid", devid);
|
||||||
field_to_json(Obj,"devid", devid);
|
field_to_json(Obj,"cas", cas);
|
||||||
field_to_json(Obj,"cas", cas);
|
field_to_json(Obj,"manufacturer", manufacturer);
|
||||||
field_to_json(Obj,"manufacturer", manufacturer);
|
field_to_json(Obj,"model", model);
|
||||||
field_to_json(Obj,"model", model);
|
field_to_json(Obj,"redirector", redirector);
|
||||||
field_to_json(Obj,"redirector", redirector);
|
field_to_json(Obj,"commonName", commonName);
|
||||||
field_to_json(Obj,"commonName", commonName);
|
field_to_json(Obj,"certificateId", certificateId);
|
||||||
field_to_json(Obj,"certificateId", certificateId);
|
field_to_json(Obj,"batch", batch);
|
||||||
field_to_json(Obj,"batch", batch);
|
field_to_json(Obj,"created", created);
|
||||||
field_to_json(Obj,"created", created);
|
field_to_json(Obj,"modified", modified);
|
||||||
field_to_json(Obj,"modified", modified);
|
field_to_json(Obj,"revoked", revoked);
|
||||||
field_to_json(Obj,"revoked", revoked);
|
field_to_json(Obj,"revokeCount", revokeCount);
|
||||||
field_to_json(Obj,"revokeCount", revokeCount);
|
field_to_json(Obj,"synched", synched);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CertificateEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
bool CertificateEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
try {
|
try {
|
||||||
field_from_json(Obj,"id", id);
|
field_from_json(Obj,"id", id);
|
||||||
field_from_json(Obj,"entity", entity);
|
field_from_json(Obj,"entity", entity);
|
||||||
field_from_json(Obj,"creator", creator);
|
field_from_json(Obj,"creator", creator);
|
||||||
field_from_json(Obj,"type", type);
|
field_from_json(Obj,"type", type);
|
||||||
field_from_json(Obj,"status", status);
|
field_from_json(Obj,"status", status);
|
||||||
field_from_json(Obj,"certificate", certificate);
|
field_from_json(Obj,"certificate", certificate);
|
||||||
field_from_json(Obj,"key", key);
|
field_from_json(Obj,"key", key);
|
||||||
field_from_json(Obj,"devid", devid);
|
field_from_json(Obj,"devid", devid);
|
||||||
field_from_json(Obj,"cas", cas);
|
field_from_json(Obj,"cas", cas);
|
||||||
field_from_json(Obj,"manufacturer", manufacturer);
|
field_from_json(Obj,"manufacturer", manufacturer);
|
||||||
field_from_json(Obj,"model", model);
|
field_from_json(Obj,"model", model);
|
||||||
field_from_json(Obj,"redirector", redirector);
|
field_from_json(Obj,"redirector", redirector);
|
||||||
field_from_json(Obj,"commonName", commonName);
|
field_from_json(Obj,"commonName", commonName);
|
||||||
field_from_json(Obj,"certificateId", certificateId);
|
field_from_json(Obj,"certificateId", certificateId);
|
||||||
field_from_json(Obj,"batch", batch);
|
field_from_json(Obj,"batch", batch);
|
||||||
field_from_json(Obj,"created", created);
|
field_from_json(Obj,"created", created);
|
||||||
field_from_json(Obj,"modified", modified);
|
field_from_json(Obj,"modified", modified);
|
||||||
field_from_json(Obj,"revoked", revoked);
|
field_from_json(Obj,"revoked", revoked);
|
||||||
field_from_json(Obj,"revokeCount", revokeCount);
|
field_from_json(Obj,"revokeCount", revokeCount);
|
||||||
return true;
|
field_from_json(Obj,"synched", synched);
|
||||||
} catch (...) {
|
return true;
|
||||||
}
|
} catch (...) {
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void EntityEntry::to_json(Poco::JSON::Object &Obj) const {
|
void EntityEntry::to_json(Poco::JSON::Object &Obj) const {
|
||||||
field_to_json(Obj,"id", id);
|
field_to_json(Obj,"id", id);
|
||||||
field_to_json(Obj,"creator", creator);
|
field_to_json(Obj,"creator", creator);
|
||||||
field_to_json(Obj,"name", name);
|
field_to_json(Obj,"name", name);
|
||||||
field_to_json(Obj,"description", description);
|
field_to_json(Obj,"description", description);
|
||||||
field_to_json(Obj,"defaultRedirector", defaultRedirector);
|
field_to_json(Obj,"defaultRedirector", defaultRedirector);
|
||||||
field_to_json(Obj,"apiKey", apiKey);
|
field_to_json(Obj,"apiKey", apiKey);
|
||||||
field_to_json(Obj,"serverEnrollmentProfile", serverEnrollmentProfile);
|
field_to_json(Obj,"serverEnrollmentProfile", serverEnrollmentProfile);
|
||||||
field_to_json(Obj,"clientEnrollmentProfile", clientEnrollmentProfile);
|
field_to_json(Obj,"clientEnrollmentProfile", clientEnrollmentProfile);
|
||||||
field_to_json(Obj,"organization", organization);
|
field_to_json(Obj,"organization", organization);
|
||||||
field_to_json(Obj,"created", created);
|
field_to_json(Obj,"created", created);
|
||||||
field_to_json(Obj,"modified", modified);
|
field_to_json(Obj,"modified", modified);
|
||||||
field_to_json(Obj,"suspended", suspended);
|
field_to_json(Obj,"suspended", suspended);
|
||||||
field_to_json(Obj,"deleted", deleted);
|
field_to_json(Obj,"deleted", deleted);
|
||||||
field_to_json(Obj,"notes", notes);
|
field_to_json(Obj,"notes", notes);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EntityEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
bool EntityEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
try {
|
try {
|
||||||
field_from_json(Obj,"id", id);
|
field_from_json(Obj,"id", id);
|
||||||
field_from_json(Obj,"creator", creator);
|
field_from_json(Obj,"creator", creator);
|
||||||
field_from_json(Obj,"name", name);
|
field_from_json(Obj,"name", name);
|
||||||
field_from_json(Obj,"description", description);
|
field_from_json(Obj,"description", description);
|
||||||
field_from_json(Obj,"defaultRedirector", defaultRedirector);
|
field_from_json(Obj,"defaultRedirector", defaultRedirector);
|
||||||
field_from_json(Obj,"apiKey", apiKey);
|
field_from_json(Obj,"apiKey", apiKey);
|
||||||
field_from_json(Obj,"serverEnrollmentProfile", serverEnrollmentProfile);
|
field_from_json(Obj,"serverEnrollmentProfile", serverEnrollmentProfile);
|
||||||
field_from_json(Obj,"clientEnrollmentProfile", clientEnrollmentProfile);
|
field_from_json(Obj,"clientEnrollmentProfile", clientEnrollmentProfile);
|
||||||
field_from_json(Obj,"organization", organization);
|
field_from_json(Obj,"organization", organization);
|
||||||
field_from_json(Obj,"created", created);
|
field_from_json(Obj,"created", created);
|
||||||
field_from_json(Obj,"modified", modified);
|
field_from_json(Obj,"modified", modified);
|
||||||
field_from_json(Obj,"suspended", suspended);
|
field_from_json(Obj,"suspended", suspended);
|
||||||
field_from_json(Obj,"deleted", deleted);
|
field_from_json(Obj,"deleted", deleted);
|
||||||
field_from_json(Obj,"notes", notes);
|
field_from_json(Obj,"notes", notes);
|
||||||
return true;
|
return true;
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void BatchEntry::to_json(Poco::JSON::Object &Obj) const {
|
void BatchEntry::to_json(Poco::JSON::Object &Obj) const {
|
||||||
field_to_json(Obj,"id", id);
|
field_to_json(Obj,"id", id);
|
||||||
field_to_json(Obj,"entity", entity);
|
field_to_json(Obj,"entity", entity);
|
||||||
field_to_json(Obj,"creator", creator);
|
field_to_json(Obj,"creator", creator);
|
||||||
field_to_json(Obj,"name", name);
|
field_to_json(Obj,"name", name);
|
||||||
field_to_json(Obj,"description", description);
|
field_to_json(Obj,"description", description);
|
||||||
field_to_json(Obj,"manufacturer", manufacturer);
|
field_to_json(Obj,"manufacturer", manufacturer);
|
||||||
field_to_json(Obj,"model", model);
|
field_to_json(Obj,"model", model);
|
||||||
field_to_json(Obj,"redirector", redirector);
|
field_to_json(Obj,"redirector", redirector);
|
||||||
field_to_json(Obj,"commonNames", commonNames);
|
field_to_json(Obj,"commonNames", commonNames);
|
||||||
field_to_json(Obj,"jobHistory", jobHistory);
|
field_to_json(Obj,"jobHistory", jobHistory);
|
||||||
field_to_json(Obj,"notes", notes);
|
field_to_json(Obj,"notes", notes);
|
||||||
field_to_json(Obj,"submitted", submitted);
|
field_to_json(Obj,"submitted", submitted);
|
||||||
field_to_json(Obj,"started", started);
|
field_to_json(Obj,"started", started);
|
||||||
field_to_json(Obj,"completed", completed);
|
field_to_json(Obj,"completed", completed);
|
||||||
field_to_json(Obj,"modified", modified);
|
field_to_json(Obj,"modified", modified);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BatchEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
bool BatchEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
try {
|
try {
|
||||||
field_from_json(Obj,"id", id);
|
field_from_json(Obj,"id", id);
|
||||||
field_from_json(Obj,"entity", entity);
|
field_from_json(Obj,"entity", entity);
|
||||||
field_from_json(Obj,"creator", creator);
|
field_from_json(Obj,"creator", creator);
|
||||||
field_from_json(Obj,"name", name);
|
field_from_json(Obj,"name", name);
|
||||||
field_from_json(Obj,"description", description);
|
field_from_json(Obj,"description", description);
|
||||||
field_from_json(Obj,"manufacturer", manufacturer);
|
field_from_json(Obj,"manufacturer", manufacturer);
|
||||||
field_from_json(Obj,"model", model);
|
field_from_json(Obj,"model", model);
|
||||||
field_from_json(Obj,"redirector", redirector);
|
field_from_json(Obj,"redirector", redirector);
|
||||||
field_from_json(Obj,"commonNames", commonNames);
|
field_from_json(Obj,"commonNames", commonNames);
|
||||||
field_from_json(Obj,"jobHistory", jobHistory);
|
field_from_json(Obj,"jobHistory", jobHistory);
|
||||||
field_from_json(Obj,"notes", notes);
|
field_from_json(Obj,"notes", notes);
|
||||||
field_from_json(Obj,"submitted", submitted);
|
field_from_json(Obj,"submitted", submitted);
|
||||||
field_from_json(Obj,"started", started);
|
field_from_json(Obj,"started", started);
|
||||||
field_from_json(Obj,"completed", completed);
|
field_from_json(Obj,"completed", completed);
|
||||||
field_from_json(Obj,"modified", modified);
|
field_from_json(Obj,"modified", modified);
|
||||||
return true;
|
return true;
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void JobEntry::to_json(Poco::JSON::Object &Obj) const {
|
void JobEntry::to_json(Poco::JSON::Object &Obj) const {
|
||||||
field_to_json(Obj,"id", id);
|
field_to_json(Obj,"id", id);
|
||||||
field_to_json(Obj,"entity", entity);
|
field_to_json(Obj,"entity", entity);
|
||||||
field_to_json(Obj,"creator", creator);
|
field_to_json(Obj,"creator", creator);
|
||||||
field_to_json(Obj,"batch", batch);
|
field_to_json(Obj,"batch", batch);
|
||||||
field_to_json(Obj,"commonNames", commonNames);
|
field_to_json(Obj,"commonNames", commonNames);
|
||||||
field_to_json(Obj,"completedNames", completedNames);
|
field_to_json(Obj,"completedNames", completedNames);
|
||||||
field_to_json(Obj,"errorNames", errorNames);
|
field_to_json(Obj,"errorNames", errorNames);
|
||||||
field_to_json(Obj,"status", status);
|
field_to_json(Obj,"status", status);
|
||||||
field_to_json(Obj,"command", command);
|
field_to_json(Obj,"command", command);
|
||||||
field_to_json(Obj,"parameters", parameters);
|
field_to_json(Obj,"parameters", parameters);
|
||||||
field_to_json(Obj,"submitted", submitted);
|
field_to_json(Obj,"submitted", submitted);
|
||||||
field_to_json(Obj,"started", started);
|
field_to_json(Obj,"started", started);
|
||||||
field_to_json(Obj,"completed", completed);
|
field_to_json(Obj,"completed", completed);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool JobEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
bool JobEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
try {
|
try {
|
||||||
field_from_json(Obj,"id", id);
|
field_from_json(Obj,"id", id);
|
||||||
field_from_json(Obj,"entity", entity);
|
field_from_json(Obj,"entity", entity);
|
||||||
field_from_json(Obj,"creator", creator);
|
field_from_json(Obj,"creator", creator);
|
||||||
field_from_json(Obj,"batch", batch);
|
field_from_json(Obj,"batch", batch);
|
||||||
field_from_json(Obj,"commonNames", commonNames);
|
field_from_json(Obj,"commonNames", commonNames);
|
||||||
field_from_json(Obj,"completedNames", completedNames);
|
field_from_json(Obj,"completedNames", completedNames);
|
||||||
field_from_json(Obj,"errorNames", errorNames);
|
field_from_json(Obj,"errorNames", errorNames);
|
||||||
field_from_json(Obj,"status", status);
|
field_from_json(Obj,"status", status);
|
||||||
field_from_json(Obj,"command", command);
|
field_from_json(Obj,"command", command);
|
||||||
field_from_json(Obj,"parameters", parameters);
|
field_from_json(Obj,"parameters", parameters);
|
||||||
field_from_json(Obj,"submitted", submitted);
|
field_from_json(Obj,"submitted", submitted);
|
||||||
field_from_json(Obj,"started", started);
|
field_from_json(Obj,"started", started);
|
||||||
field_from_json(Obj,"completed", completed);
|
field_from_json(Obj,"completed", completed);
|
||||||
return true;
|
return true;
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DashBoardYearlyStats::to_json(Poco::JSON::Object &Obj) const {
|
||||||
|
field_to_json(Obj, "year", year);
|
||||||
|
field_to_json(Obj, "activeCerts", activeCerts);
|
||||||
|
field_to_json(Obj, "revokedCerts", revokedCerts);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Dashboard::to_json(Poco::JSON::Object &Obj) const {
|
||||||
|
field_to_json(Obj,"snapshot", snapshot);
|
||||||
|
field_to_json(Obj,"numberOfIssuedCerts", numberOfIssuedCerts);
|
||||||
|
field_to_json(Obj,"numberOfRevokedCerts", numberOfRevokedCerts);
|
||||||
|
field_to_json(Obj,"activeCertsPerOrganization", activeCertsPerOrganization);
|
||||||
|
field_to_json(Obj,"revokedCertsPerOrganization", revokedCertsPerOrganization);
|
||||||
|
field_to_json(Obj,"numberOfRedirectors", numberOfRedirectors);
|
||||||
|
field_to_json(Obj,"deviceTypes", deviceTypes);
|
||||||
|
field_to_json(Obj,"monthlyNumberOfCerts", monthlyNumberOfCerts);
|
||||||
|
field_to_json(Obj,"monthlyNumberOfCertsPerOrgPerYear", monthlyNumberOfCertsPerOrgPerYear);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Dashboard::reset() {
|
||||||
|
snapshot=0;
|
||||||
|
numberOfRevokedCerts = numberOfIssuedCerts = 0;
|
||||||
|
activeCertsPerOrganization.clear();
|
||||||
|
revokedCertsPerOrganization.clear();
|
||||||
|
numberOfRedirectors.clear();
|
||||||
|
deviceTypes.clear();
|
||||||
|
monthlyNumberOfCerts.clear();
|
||||||
|
monthlyNumberOfCertsPerOrgPerYear.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,97 +5,118 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "framework/MicroService.h"
|
|
||||||
#include "framework/OpenWifiTypes.h"
|
#include "framework/OpenWifiTypes.h"
|
||||||
#include "RESTObjects/RESTAPI_SecurityObjects.h"
|
#include "RESTObjects/RESTAPI_SecurityObjects.h"
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi::CertObjects {
|
||||||
|
|
||||||
namespace CertObjects {
|
struct CertificateEntry {
|
||||||
|
OpenWifi::Types::UUID_t id;
|
||||||
|
OpenWifi::Types::UUID_t entity;
|
||||||
|
OpenWifi::Types::UUID_t creator;
|
||||||
|
std::string type;
|
||||||
|
std::string status;
|
||||||
|
std::string certificate;
|
||||||
|
std::string key;
|
||||||
|
std::string devid;
|
||||||
|
std::string cas;
|
||||||
|
std::string manufacturer;
|
||||||
|
std::string model;
|
||||||
|
std::string redirector;
|
||||||
|
std::string commonName;
|
||||||
|
std::string certificateId;
|
||||||
|
OpenWifi::Types::UUID_t batch;
|
||||||
|
uint64_t created = 0;
|
||||||
|
uint64_t modified = 0;
|
||||||
|
uint64_t revoked = 0;
|
||||||
|
uint64_t revokeCount = 0;
|
||||||
|
uint64_t synched = 0;
|
||||||
|
|
||||||
struct CertificateEntry {
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
OpenWifi::Types::UUID_t id;
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
OpenWifi::Types::UUID_t entity;
|
};
|
||||||
OpenWifi::Types::UUID_t creator;
|
|
||||||
std::string type;
|
|
||||||
std::string status;
|
|
||||||
std::string certificate;
|
|
||||||
std::string key;
|
|
||||||
std::string devid;
|
|
||||||
std::string cas;
|
|
||||||
std::string manufacturer;
|
|
||||||
std::string model;
|
|
||||||
std::string redirector;
|
|
||||||
std::string commonName;
|
|
||||||
std::string certificateId;
|
|
||||||
OpenWifi::Types::UUID_t batch;
|
|
||||||
uint64_t created = 0;
|
|
||||||
uint64_t modified = 0;
|
|
||||||
uint64_t revoked = 0;
|
|
||||||
uint64_t revokeCount = 0;
|
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
struct EntityEntry {
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
OpenWifi::Types::UUID_t id;
|
||||||
};
|
OpenWifi::Types::UUID_t creator;
|
||||||
|
std::string name;
|
||||||
|
std::string description;
|
||||||
|
std::string defaultRedirector;
|
||||||
|
std::string apiKey;
|
||||||
|
std::string serverEnrollmentProfile;
|
||||||
|
std::string clientEnrollmentProfile;
|
||||||
|
std::string organization;
|
||||||
|
SecurityObjects::NoteInfoVec notes;
|
||||||
|
bool suspended=false;
|
||||||
|
bool deleted=false;
|
||||||
|
uint64_t created = 0 ;
|
||||||
|
uint64_t modified = 0 ;
|
||||||
|
|
||||||
struct EntityEntry {
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
OpenWifi::Types::UUID_t id;
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
OpenWifi::Types::UUID_t creator;
|
};
|
||||||
std::string name;
|
|
||||||
std::string description;
|
|
||||||
std::string defaultRedirector;
|
|
||||||
std::string apiKey;
|
|
||||||
std::string serverEnrollmentProfile;
|
|
||||||
std::string clientEnrollmentProfile;
|
|
||||||
std::string organization;
|
|
||||||
SecurityObjects::NoteInfoVec notes;
|
|
||||||
bool suspended=false;
|
|
||||||
bool deleted=false;
|
|
||||||
uint64_t created = 0 ;
|
|
||||||
uint64_t modified = 0 ;
|
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
struct BatchEntry {
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
OpenWifi::Types::UUID_t id;
|
||||||
};
|
OpenWifi::Types::UUID_t entity;
|
||||||
|
OpenWifi::Types::UUID_t creator;
|
||||||
|
std::string name;
|
||||||
|
std::string description;
|
||||||
|
std::string manufacturer;
|
||||||
|
std::string model;
|
||||||
|
std::string redirector;
|
||||||
|
std::vector<std::string> commonNames;
|
||||||
|
std::vector<std::string> jobHistory;
|
||||||
|
SecurityObjects::NoteInfoVec notes;
|
||||||
|
uint64_t submitted = 0 ;
|
||||||
|
uint64_t started = 0 ;
|
||||||
|
uint64_t completed = 0 ;
|
||||||
|
uint64_t modified = 0 ;
|
||||||
|
|
||||||
struct BatchEntry {
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
OpenWifi::Types::UUID_t id;
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
OpenWifi::Types::UUID_t entity;
|
};
|
||||||
OpenWifi::Types::UUID_t creator;
|
|
||||||
std::string name;
|
|
||||||
std::string description;
|
|
||||||
std::string manufacturer;
|
|
||||||
std::string model;
|
|
||||||
std::string redirector;
|
|
||||||
std::vector<std::string> commonNames;
|
|
||||||
std::vector<std::string> jobHistory;
|
|
||||||
SecurityObjects::NoteInfoVec notes;
|
|
||||||
uint64_t submitted = 0 ;
|
|
||||||
uint64_t started = 0 ;
|
|
||||||
uint64_t completed = 0 ;
|
|
||||||
uint64_t modified = 0 ;
|
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
struct JobEntry {
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
OpenWifi::Types::UUID_t id;
|
||||||
};
|
OpenWifi::Types::UUID_t entity;
|
||||||
|
OpenWifi::Types::UUID_t creator;
|
||||||
|
OpenWifi::Types::UUID_t batch;
|
||||||
|
std::string command;
|
||||||
|
OpenWifi::Types::StringVec commonNames;
|
||||||
|
OpenWifi::Types::StringVec completedNames;
|
||||||
|
OpenWifi::Types::StringVec errorNames;
|
||||||
|
Types::StringPairVec parameters;
|
||||||
|
std::string status;
|
||||||
|
uint64_t submitted=0;
|
||||||
|
uint64_t started=0;
|
||||||
|
uint64_t completed=0;
|
||||||
|
|
||||||
struct JobEntry {
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
OpenWifi::Types::UUID_t id;
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
OpenWifi::Types::UUID_t entity;
|
};
|
||||||
OpenWifi::Types::UUID_t creator;
|
|
||||||
OpenWifi::Types::UUID_t batch;
|
struct DashBoardYearlyStats {
|
||||||
std::string command;
|
uint64_t year=0;
|
||||||
OpenWifi::Types::StringVec commonNames;
|
OpenWifi::Types::Counted3DMapSII activeCerts;
|
||||||
OpenWifi::Types::StringVec completedNames;
|
OpenWifi::Types::Counted3DMapSII revokedCerts;
|
||||||
OpenWifi::Types::StringVec errorNames;
|
|
||||||
Types::StringPairVec parameters;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
std::string status;
|
};
|
||||||
uint64_t submitted=0;
|
|
||||||
uint64_t started=0;
|
struct Dashboard {
|
||||||
uint64_t completed=0;
|
uint64_t snapshot=0;
|
||||||
|
uint64_t numberOfIssuedCerts=0;
|
||||||
|
uint64_t numberOfRevokedCerts=0;
|
||||||
|
OpenWifi::Types::CountedMap activeCertsPerOrganization;
|
||||||
|
OpenWifi::Types::CountedMap revokedCertsPerOrganization;
|
||||||
|
OpenWifi::Types::CountedMap numberOfRedirectors;
|
||||||
|
OpenWifi::Types::CountedMap deviceTypes;
|
||||||
|
OpenWifi::Types::CountedMap monthlyNumberOfCerts;
|
||||||
|
std::vector<DashBoardYearlyStats> monthlyNumberOfCertsPerOrgPerYear;
|
||||||
|
|
||||||
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
void reset();
|
||||||
|
};
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -203,6 +203,10 @@ namespace OpenWifi::GWObjects {
|
|||||||
field_to_json(Obj,"kafkaClients", kafkaClients);
|
field_to_json(Obj,"kafkaClients", kafkaClients);
|
||||||
field_to_json(Obj,"kafkaPackets", kafkaPackets);
|
field_to_json(Obj,"kafkaPackets", kafkaPackets);
|
||||||
field_to_json(Obj,"locale", locale);
|
field_to_json(Obj,"locale", locale);
|
||||||
|
field_to_json(Obj,"started", started);
|
||||||
|
field_to_json(Obj,"sessionId", sessionId);
|
||||||
|
field_to_json(Obj,"connectionCompletionTime", connectionCompletionTime);
|
||||||
|
field_to_json(Obj,"totalConnectionTime", OpenWifi::Now() - started);
|
||||||
|
|
||||||
switch(VerifiedCertificate) {
|
switch(VerifiedCertificate) {
|
||||||
case NO_CERTIFICATE:
|
case NO_CERTIFICATE:
|
||||||
@@ -218,6 +222,21 @@ namespace OpenWifi::GWObjects {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DeviceConnectionStatistics::to_json(Poco::JSON::Object &Obj) const {
|
||||||
|
field_to_json(Obj,"averageConnectionTime", averageConnectionTime);
|
||||||
|
field_to_json(Obj,"connectedDevices", connectedDevices );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DeviceConnectionStatistics::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
|
try {
|
||||||
|
field_from_json(Obj,"averageConnectionTime", averageConnectionTime);
|
||||||
|
field_from_json(Obj,"connectedDevices", connectedDevices );
|
||||||
|
return true;
|
||||||
|
} catch (const Poco::Exception &E) {
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void RttySessionDetails::to_json(Poco::JSON::Object &Obj) const {
|
void RttySessionDetails::to_json(Poco::JSON::Object &Obj) const {
|
||||||
field_to_json(Obj,"serialNumber", SerialNumber);
|
field_to_json(Obj,"serialNumber", SerialNumber);
|
||||||
field_to_json(Obj,"server", Server);
|
field_to_json(Obj,"server", Server);
|
||||||
@@ -293,7 +312,6 @@ namespace OpenWifi::GWObjects {
|
|||||||
} catch (const Poco::Exception &E) {
|
} catch (const Poco::Exception &E) {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RadiusProxyPoolList::to_json(Poco::JSON::Object &Obj) const {
|
void RadiusProxyPoolList::to_json(Poco::JSON::Object &Obj) const {
|
||||||
@@ -314,6 +332,8 @@ namespace OpenWifi::GWObjects {
|
|||||||
field_to_json(Obj,"description",description);
|
field_to_json(Obj,"description",description);
|
||||||
field_to_json(Obj,"authConfig",authConfig);
|
field_to_json(Obj,"authConfig",authConfig);
|
||||||
field_to_json(Obj,"acctConfig",acctConfig);
|
field_to_json(Obj,"acctConfig",acctConfig);
|
||||||
|
field_to_json(Obj,"coaConfig",coaConfig);
|
||||||
|
field_to_json(Obj,"useByDefault",useByDefault);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RadiusProxyPool::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
bool RadiusProxyPool::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
@@ -322,6 +342,8 @@ namespace OpenWifi::GWObjects {
|
|||||||
field_from_json(Obj,"description",description);
|
field_from_json(Obj,"description",description);
|
||||||
field_from_json(Obj,"authConfig",authConfig);
|
field_from_json(Obj,"authConfig",authConfig);
|
||||||
field_from_json(Obj,"acctConfig",acctConfig);
|
field_from_json(Obj,"acctConfig",acctConfig);
|
||||||
|
field_from_json(Obj,"coaConfig",coaConfig);
|
||||||
|
field_from_json(Obj,"useByDefault",useByDefault);
|
||||||
return true;
|
return true;
|
||||||
} catch (const Poco::Exception &E) {
|
} catch (const Poco::Exception &E) {
|
||||||
}
|
}
|
||||||
@@ -329,7 +351,7 @@ namespace OpenWifi::GWObjects {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void RadiusProxyServerConfig::to_json(Poco::JSON::Object &Obj) const {
|
void RadiusProxyServerConfig::to_json(Poco::JSON::Object &Obj) const {
|
||||||
field_to_json(Obj,"policy",strategy);
|
field_to_json(Obj,"strategy",strategy);
|
||||||
field_to_json(Obj,"monitor",monitor);
|
field_to_json(Obj,"monitor",monitor);
|
||||||
field_to_json(Obj,"monitorMethod",monitorMethod);
|
field_to_json(Obj,"monitorMethod",monitorMethod);
|
||||||
field_to_json(Obj,"methodParameters",methodParameters);
|
field_to_json(Obj,"methodParameters",methodParameters);
|
||||||
@@ -338,7 +360,7 @@ namespace OpenWifi::GWObjects {
|
|||||||
|
|
||||||
bool RadiusProxyServerConfig::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
bool RadiusProxyServerConfig::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
try {
|
try {
|
||||||
field_from_json(Obj,"policy",strategy);
|
field_from_json(Obj,"strategy",strategy);
|
||||||
field_from_json(Obj,"monitor",monitor);
|
field_from_json(Obj,"monitor",monitor);
|
||||||
field_from_json(Obj,"monitorMethod",monitorMethod);
|
field_from_json(Obj,"monitorMethod",monitorMethod);
|
||||||
field_from_json(Obj,"methodParameters",methodParameters);
|
field_from_json(Obj,"methodParameters",methodParameters);
|
||||||
@@ -354,6 +376,16 @@ namespace OpenWifi::GWObjects {
|
|||||||
field_to_json(Obj,"ip",ip);
|
field_to_json(Obj,"ip",ip);
|
||||||
field_to_json(Obj,"port",port);
|
field_to_json(Obj,"port",port);
|
||||||
field_to_json(Obj,"weight",weight);
|
field_to_json(Obj,"weight",weight);
|
||||||
|
field_to_json(Obj,"secret",secret);
|
||||||
|
field_to_json(Obj,"certificate",certificate);
|
||||||
|
field_to_json(Obj,"radsec",radsec);
|
||||||
|
field_to_json(Obj,"radsecPort",radsecPort);
|
||||||
|
field_to_json(Obj,"radsecSecret",radsecSecret);
|
||||||
|
field_to_json(Obj,"radsecCacerts",radsecCacerts);
|
||||||
|
field_to_json(Obj,"radsecCert",radsecCert);
|
||||||
|
field_to_json(Obj,"radsecKey",radsecKey);
|
||||||
|
field_to_json(Obj,"radsecRealms",radsecRealms);
|
||||||
|
field_to_json(Obj,"ignore",ignore);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RadiusProxyServerEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
bool RadiusProxyServerEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
@@ -362,6 +394,16 @@ namespace OpenWifi::GWObjects {
|
|||||||
field_from_json(Obj,"ip",ip);
|
field_from_json(Obj,"ip",ip);
|
||||||
field_from_json(Obj,"port",port);
|
field_from_json(Obj,"port",port);
|
||||||
field_from_json(Obj,"weight",weight);
|
field_from_json(Obj,"weight",weight);
|
||||||
|
field_from_json(Obj,"secret",secret);
|
||||||
|
field_from_json(Obj,"certificate",certificate);
|
||||||
|
field_from_json(Obj,"radsec",radsec);
|
||||||
|
field_from_json(Obj,"radsecSecret",radsecSecret);
|
||||||
|
field_from_json(Obj,"radsecPort",radsecPort);
|
||||||
|
field_from_json(Obj,"radsecCacerts",radsecCacerts);
|
||||||
|
field_from_json(Obj,"radsecCert",radsecCert);
|
||||||
|
field_from_json(Obj,"radsecKey",radsecKey);
|
||||||
|
field_from_json(Obj,"radsecRealms",radsecRealms);
|
||||||
|
field_from_json(Obj,"ignore",ignore);
|
||||||
return true;
|
return true;
|
||||||
} catch (const Poco::Exception &E) {
|
} catch (const Poco::Exception &E) {
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,6 +38,10 @@ namespace OpenWifi::GWObjects {
|
|||||||
uint64_t kafkaPackets=0;
|
uint64_t kafkaPackets=0;
|
||||||
uint64_t websocketPackets=0;
|
uint64_t websocketPackets=0;
|
||||||
std::string locale;
|
std::string locale;
|
||||||
|
uint64_t started=0;
|
||||||
|
uint64_t sessionId=0;
|
||||||
|
double connectionCompletionTime=0.0;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -71,6 +75,13 @@ namespace OpenWifi::GWObjects {
|
|||||||
void Print() const;
|
void Print() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct DeviceConnectionStatistics {
|
||||||
|
std::uint64_t connectedDevices = 0;
|
||||||
|
std::uint64_t averageConnectionTime = 0;
|
||||||
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
|
};
|
||||||
|
|
||||||
struct Statistics {
|
struct Statistics {
|
||||||
std::string SerialNumber;
|
std::string SerialNumber;
|
||||||
uint64_t UUID = 0 ;
|
uint64_t UUID = 0 ;
|
||||||
@@ -216,6 +227,16 @@ namespace OpenWifi::GWObjects {
|
|||||||
std::string ip;
|
std::string ip;
|
||||||
uint16_t port=0;
|
uint16_t port=0;
|
||||||
uint64_t weight=0;
|
uint64_t weight=0;
|
||||||
|
std::string secret;
|
||||||
|
std::string certificate;
|
||||||
|
bool radsec=false;
|
||||||
|
uint16_t radsecPort=2083;
|
||||||
|
std::string radsecSecret;
|
||||||
|
std::string radsecKey;
|
||||||
|
std::string radsecCert;
|
||||||
|
std::vector<std::string> radsecCacerts;
|
||||||
|
std::vector<std::string> radsecRealms;
|
||||||
|
bool ignore=false;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
@@ -237,6 +258,8 @@ namespace OpenWifi::GWObjects {
|
|||||||
std::string description;
|
std::string description;
|
||||||
RadiusProxyServerConfig authConfig;
|
RadiusProxyServerConfig authConfig;
|
||||||
RadiusProxyServerConfig acctConfig;
|
RadiusProxyServerConfig acctConfig;
|
||||||
|
RadiusProxyServerConfig coaConfig;
|
||||||
|
bool useByDefault=false;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <type_traits>
|
||||||
#include "framework/OpenWifiTypes.h"
|
#include "framework/OpenWifiTypes.h"
|
||||||
#include "Poco/JSON/Object.h"
|
#include "Poco/JSON/Object.h"
|
||||||
#include "Poco/Data/LOB.h"
|
#include "Poco/Data/LOB.h"
|
||||||
@@ -27,8 +28,13 @@ namespace OpenWifi {
|
|||||||
bool Delete_ = true;
|
bool Delete_ = true;
|
||||||
bool PortalLogin_ = true;
|
bool PortalLogin_ = true;
|
||||||
|
|
||||||
|
AclTemplate() noexcept = default;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj); };
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
|
};
|
||||||
|
|
||||||
|
static_assert( std::is_nothrow_move_constructible_v<AclTemplate> );
|
||||||
|
|
||||||
struct WebToken {
|
struct WebToken {
|
||||||
std::string access_token_;
|
std::string access_token_;
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
|
|
||||||
int Storage::Start() {
|
int Storage::Start() {
|
||||||
|
poco_information(Logger(),"Starting...");
|
||||||
std::lock_guard Guard(Mutex_);
|
std::lock_guard Guard(Mutex_);
|
||||||
|
|
||||||
StorageClass::Start();
|
StorageClass::Start();
|
||||||
@@ -27,9 +28,10 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Storage::Stop() {
|
void Storage::Stop() {
|
||||||
|
poco_information(Logger(),"Stopping...");
|
||||||
std::lock_guard Guard(Mutex_);
|
std::lock_guard Guard(Mutex_);
|
||||||
Logger().notice("Stopping.");
|
|
||||||
StorageClass::Stop();
|
StorageClass::Stop();
|
||||||
|
poco_information(Logger(),"Stopped...");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Storage::TrimRevision(const std::string &R) {
|
std::string Storage::TrimRevision(const std::string &R) {
|
||||||
|
|||||||
@@ -13,9 +13,10 @@
|
|||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
|
|
||||||
static const std::string GitUCentralJSONSchemaFile{"https://raw.githubusercontent.com/blogic/ucentral-schema/main/ucentral.schema.json"};
|
static const std::string GitUCentralJSONSchemaFile{
|
||||||
|
"https://raw.githubusercontent.com/blogic/ucentral-schema/main/ucentral.schema.json"};
|
||||||
|
|
||||||
static json DefaultUCentralSchema = R"(
|
static json DefaultUCentralSchema = R"(
|
||||||
|
|
||||||
{
|
{
|
||||||
"$id": "https://openwrt.org/ucentral.schema.json",
|
"$id": "https://openwrt.org/ucentral.schema.json",
|
||||||
@@ -43,7 +44,7 @@ namespace OpenWifi {
|
|||||||
"switch": {
|
"switch": {
|
||||||
"$ref": "#/$defs/switch"
|
"$ref": "#/$defs/switch"
|
||||||
},
|
},
|
||||||
"radios": {
|
"radiosgrep": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"$ref": "#/$defs/radio"
|
"$ref": "#/$defs/radio"
|
||||||
@@ -518,7 +519,7 @@ namespace OpenWifi {
|
|||||||
"maximum": 4050
|
"maximum": 4050
|
||||||
},
|
},
|
||||||
"proto": {
|
"proto": {
|
||||||
"decription": "The L2 vlan tag that shall be added (1q,1ad) ",
|
"decription": "The L2 vlan tag that shall be added (1q,1ad ) ",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"enum": [
|
||||||
"802.1ad",
|
"802.1ad",
|
||||||
@@ -669,6 +670,47 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"interface.ipv4.port-forward": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"protocol": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"tcp",
|
||||||
|
"udp",
|
||||||
|
"any"
|
||||||
|
],
|
||||||
|
"default": "any"
|
||||||
|
},
|
||||||
|
"external-port": {
|
||||||
|
"type": [
|
||||||
|
"integer",
|
||||||
|
"string"
|
||||||
|
],
|
||||||
|
"minimum": 0,
|
||||||
|
"maximum": 65535,
|
||||||
|
"format": "uc-portrange"
|
||||||
|
},
|
||||||
|
"internal-address": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "ipv4",
|
||||||
|
"example": "0.0.0.120"
|
||||||
|
},
|
||||||
|
"internal-port": {
|
||||||
|
"type": [
|
||||||
|
"integer",
|
||||||
|
"string"
|
||||||
|
],
|
||||||
|
"minimum": 0,
|
||||||
|
"maximum": 65535,
|
||||||
|
"format": "uc-portrange"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"external-port",
|
||||||
|
"internal-address"
|
||||||
|
]
|
||||||
|
},
|
||||||
"interface.ipv4": {
|
"interface.ipv4": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
@@ -722,6 +764,12 @@ namespace OpenWifi {
|
|||||||
"items": {
|
"items": {
|
||||||
"$ref": "#/$defs/interface.ipv4.dhcp-lease"
|
"$ref": "#/$defs/interface.ipv4.dhcp-lease"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"port-forward": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/$defs/interface.ipv4.port-forward"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -751,6 +799,96 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"interface.ipv6.port-forward": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"protocol": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"tcp",
|
||||||
|
"udp",
|
||||||
|
"any"
|
||||||
|
],
|
||||||
|
"default": "any"
|
||||||
|
},
|
||||||
|
"external-port": {
|
||||||
|
"type": [
|
||||||
|
"integer",
|
||||||
|
"string"
|
||||||
|
],
|
||||||
|
"minimum": 0,
|
||||||
|
"maximum": 65535,
|
||||||
|
"format": "uc-portrange"
|
||||||
|
},
|
||||||
|
"internal-address": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "ipv6",
|
||||||
|
"example": "::1234:abcd"
|
||||||
|
},
|
||||||
|
"internal-port": {
|
||||||
|
"type": [
|
||||||
|
"integer",
|
||||||
|
"string"
|
||||||
|
],
|
||||||
|
"minimum": 0,
|
||||||
|
"maximum": 65535,
|
||||||
|
"format": "uc-portrange"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"external-port",
|
||||||
|
"internal-address"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"interface.ipv6.traffic-allow": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"protocol": {
|
||||||
|
"type": "string",
|
||||||
|
"default": "any"
|
||||||
|
},
|
||||||
|
"source-address": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "uc-cidr6",
|
||||||
|
"example": "2001:db8:1234:abcd::/64",
|
||||||
|
"default": "::/0"
|
||||||
|
},
|
||||||
|
"source-ports": {
|
||||||
|
"type": "array",
|
||||||
|
"minItems": 1,
|
||||||
|
"items": {
|
||||||
|
"type": [
|
||||||
|
"integer",
|
||||||
|
"string"
|
||||||
|
],
|
||||||
|
"minimum": 0,
|
||||||
|
"maximum": 65535,
|
||||||
|
"format": "uc-portrange"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"destination-address": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "ipv6",
|
||||||
|
"example": "::1000"
|
||||||
|
},
|
||||||
|
"destination-ports": {
|
||||||
|
"type": "array",
|
||||||
|
"minItems": 1,
|
||||||
|
"items": {
|
||||||
|
"type": [
|
||||||
|
"integer",
|
||||||
|
"string"
|
||||||
|
],
|
||||||
|
"minimum": 0,
|
||||||
|
"maximum": 65535,
|
||||||
|
"format": "uc-portrange"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"destination-address"
|
||||||
|
]
|
||||||
|
},
|
||||||
"interface.ipv6": {
|
"interface.ipv6": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
@@ -782,6 +920,18 @@ namespace OpenWifi {
|
|||||||
},
|
},
|
||||||
"dhcpv6": {
|
"dhcpv6": {
|
||||||
"$ref": "#/$defs/interface.ipv6.dhcpv6"
|
"$ref": "#/$defs/interface.ipv6.dhcpv6"
|
||||||
|
},
|
||||||
|
"port-forward": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/$defs/interface.ipv6.port-forward"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"traffic-allow": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/$defs/interface.ipv6.traffic-allow"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -866,7 +1016,7 @@ namespace OpenWifi {
|
|||||||
},
|
},
|
||||||
"gateway-fqdn": {
|
"gateway-fqdn": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"format": "fqdn",
|
"format": "uc-fqdn",
|
||||||
"default": "ucentral.splash"
|
"default": "ucentral.splash"
|
||||||
},
|
},
|
||||||
"max-clients": {
|
"max-clients": {
|
||||||
@@ -901,6 +1051,7 @@ namespace OpenWifi {
|
|||||||
"psk",
|
"psk",
|
||||||
"psk2",
|
"psk2",
|
||||||
"psk-mixed",
|
"psk-mixed",
|
||||||
|
"psk2-radius",
|
||||||
"wpa",
|
"wpa",
|
||||||
"wpa2",
|
"wpa2",
|
||||||
"wpa-mixed",
|
"wpa-mixed",
|
||||||
@@ -961,6 +1112,10 @@ namespace OpenWifi {
|
|||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"default": false
|
"default": false
|
||||||
},
|
},
|
||||||
|
"reduced-neighbor-reporting": {
|
||||||
|
"type": "boolean",
|
||||||
|
"default": false
|
||||||
|
},
|
||||||
"lci": {
|
"lci": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
@@ -1527,6 +1682,11 @@ namespace OpenWifi {
|
|||||||
"decription": "This option allows embedding custom vendor specific IEs inside the beacons of a BSS in AP mode.",
|
"decription": "This option allows embedding custom vendor specific IEs inside the beacons of a BSS in AP mode.",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"fils-discovery-interval": {
|
||||||
|
"type": "integer",
|
||||||
|
"default": 20,
|
||||||
|
"maximum": 10000
|
||||||
|
},
|
||||||
"encryption": {
|
"encryption": {
|
||||||
"$ref": "#/$defs/interface.ssid.encryption"
|
"$ref": "#/$defs/interface.ssid.encryption"
|
||||||
},
|
},
|
||||||
@@ -2087,6 +2247,10 @@ namespace OpenWifi {
|
|||||||
"auto-channel": {
|
"auto-channel": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"default": false
|
"default": false
|
||||||
|
},
|
||||||
|
"ipv6": {
|
||||||
|
"type": "boolean",
|
||||||
|
"default": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -2193,7 +2357,7 @@ namespace OpenWifi {
|
|||||||
"properties": {
|
"properties": {
|
||||||
"fqdn": {
|
"fqdn": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"format": "fqdn"
|
"format": "uc-fqdn"
|
||||||
},
|
},
|
||||||
"suffix-matching": {
|
"suffix-matching": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
@@ -2444,8 +2608,7 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
)"_json;
|
||||||
)"_json;
|
|
||||||
|
|
||||||
class custom_error_handler : public nlohmann::json_schema::basic_error_handler
|
class custom_error_handler : public nlohmann::json_schema::basic_error_handler
|
||||||
{
|
{
|
||||||
@@ -2460,9 +2623,18 @@ namespace OpenWifi {
|
|||||||
void ConfigurationValidator::Init() {
|
void ConfigurationValidator::Init() {
|
||||||
if(Initialized_)
|
if(Initialized_)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
std::string GitSchema;
|
std::string GitSchema;
|
||||||
|
if(MicroService::instance().ConfigGetBool("ucentral.datamodel.internal",true)) {
|
||||||
|
RootSchema_ = DefaultUCentralSchema;
|
||||||
|
Logger().information("Using uCentral validation from built-in default.");
|
||||||
|
Initialized_ = Working_ = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if(Utils::wgets(GitUCentralJSONSchemaFile, GitSchema)) {
|
auto GitURI = MicroService::instance().ConfigGetString("ucentral.datamodel.uri",GitUCentralJSONSchemaFile);
|
||||||
|
if(Utils::wgets(GitURI, GitSchema)) {
|
||||||
RootSchema_ = json::parse(GitSchema);
|
RootSchema_ = json::parse(GitSchema);
|
||||||
Logger().information("Using uCentral validation schema from GIT.");
|
Logger().information("Using uCentral validation schema from GIT.");
|
||||||
} else {
|
} else {
|
||||||
@@ -2528,6 +2700,17 @@ namespace OpenWifi {
|
|||||||
return IsCIDRv4(value) || IsCIDRv6(value);
|
return IsCIDRv4(value) || IsCIDRv6(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool IsPortRangeIsValid(const std::string &r) {
|
||||||
|
const auto ports = Poco::StringTokenizer("-",r,Poco::StringTokenizer::TOK_TRIM);
|
||||||
|
|
||||||
|
for(const auto &port:ports) {
|
||||||
|
uint32_t port_num = std::stoul(port);
|
||||||
|
if(port_num==0 || port_num>65535)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void ConfigurationValidator::my_format_checker(const std::string &format, const std::string &value)
|
void ConfigurationValidator::my_format_checker(const std::string &format, const std::string &value)
|
||||||
{
|
{
|
||||||
static const std::regex host_regex{"^(?=.{1,254}$)((?=[a-z0-9-]{1,63}\\.)(xn--+)?[a-z0-9]+(-[a-z0-9]+)*\\.)+[a-z]{2,63}$"};
|
static const std::regex host_regex{"^(?=.{1,254}$)((?=[a-z0-9-]{1,63}\\.)(xn--+)?[a-z0-9]+(-[a-z0-9]+)*\\.)+[a-z]{2,63}$"};
|
||||||
@@ -2578,6 +2761,14 @@ namespace OpenWifi {
|
|||||||
} catch (...) {
|
} catch (...) {
|
||||||
}
|
}
|
||||||
throw std::invalid_argument(value + " is not a valid URI: should be something like https://hello.world.com.");
|
throw std::invalid_argument(value + " is not a valid URI: should be something like https://hello.world.com.");
|
||||||
|
} else if(format == "uc-portrange") {
|
||||||
|
try {
|
||||||
|
if(IsPortRangeIsValid(value))
|
||||||
|
return;
|
||||||
|
throw std::invalid_argument(value + " is not a valid port range: should an integer between 1-65535 or a port range like post-port.");
|
||||||
|
} catch (...) {
|
||||||
|
}
|
||||||
|
throw std::invalid_argument(value + " is not a valid port range: should an integer between 1-65535 or a port range like post-port.");
|
||||||
} else if(format == "ip") {
|
} else if(format == "ip") {
|
||||||
if (IsIP(value))
|
if (IsIP(value))
|
||||||
return;
|
return;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
169
src/framework/MicroServiceErrorHandler.h
Normal file
169
src/framework/MicroServiceErrorHandler.h
Normal file
@@ -0,0 +1,169 @@
|
|||||||
|
//
|
||||||
|
// Created by stephane bourque on 2022-09-29.
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "fmt/format.h"
|
||||||
|
#include "Poco/Util/Application.h"
|
||||||
|
#include "Poco/ErrorHandler.h"
|
||||||
|
#include "Poco/Net/NetException.h"
|
||||||
|
#include "Poco/Net/SSLException.h"
|
||||||
|
#include "Poco/JSON/Template.h"
|
||||||
|
#include "Poco/Thread.h"
|
||||||
|
|
||||||
|
namespace OpenWifi {
|
||||||
|
|
||||||
|
class MicroServiceErrorHandler : public Poco::ErrorHandler {
|
||||||
|
public:
|
||||||
|
explicit MicroServiceErrorHandler(Poco::Util::Application &App) : App_(App) {
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void exception(const Poco::Exception & Base) override {
|
||||||
|
try {
|
||||||
|
if(Poco::Thread::current()!= nullptr) {
|
||||||
|
t_name = Poco::Thread::current()->getName();
|
||||||
|
t_id = Poco::Thread::current()->id();
|
||||||
|
} else {
|
||||||
|
t_name = "startup_code";
|
||||||
|
t_id = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
App_.logger().log(Base);
|
||||||
|
Base.rethrow();
|
||||||
|
|
||||||
|
} catch (const Poco::Net::InvalidCertificateException &E) {
|
||||||
|
poco_error(App_.logger(), fmt::format("Poco::Net::InvalidCertificateException thr_name={} thr_id={} code={} text={} msg={} what={}",
|
||||||
|
t_name, t_id, E.code(),
|
||||||
|
E.displayText(),
|
||||||
|
E.message(),
|
||||||
|
E.what()));
|
||||||
|
} catch (const Poco::Net::InvalidSocketException &E) {
|
||||||
|
poco_error(App_.logger(), fmt::format("Poco::Net::InvalidSocketException thr_name={} thr_id={} code={} text={} msg={} what={}",
|
||||||
|
t_name, t_id, E.code(),
|
||||||
|
E.displayText(),
|
||||||
|
E.message(),
|
||||||
|
E.what()));
|
||||||
|
} catch (const Poco::Net::WebSocketException &E) {
|
||||||
|
poco_error(App_.logger(), fmt::format("Poco::Net::WebSocketException thr_name={} thr_id={} code={} text={} msg={} what={}",
|
||||||
|
t_name, t_id, E.code(),
|
||||||
|
E.displayText(),
|
||||||
|
E.message(),
|
||||||
|
E.what()));
|
||||||
|
} catch (const Poco::Net::ConnectionResetException &E) {
|
||||||
|
poco_error(App_.logger(), fmt::format("Poco::Net::ConnectionResetException thr_name={} thr_id={} code={} text={} msg={} what={}",
|
||||||
|
t_name, t_id, E.code(),
|
||||||
|
E.displayText(),
|
||||||
|
E.message(),
|
||||||
|
E.what()));
|
||||||
|
} catch (const Poco::Net::CertificateValidationException &E) {
|
||||||
|
poco_error(App_.logger(), fmt::format("Poco::Net::CertificateValidationException thr_name={} thr_id={} code={} text={} msg={} what={}",
|
||||||
|
t_name, t_id, E.code(),
|
||||||
|
E.displayText(),
|
||||||
|
E.message(),
|
||||||
|
E.what()));
|
||||||
|
} catch (const Poco::Net::SSLConnectionUnexpectedlyClosedException &E) {
|
||||||
|
poco_error(App_.logger(), fmt::format("Poco::Net::SSLConnectionUnexpectedlyClosedException thr_name={} thr_id={} code={} text={} msg={} what={}",
|
||||||
|
t_name, t_id, E.code(),
|
||||||
|
E.displayText(),
|
||||||
|
E.message(),
|
||||||
|
E.what()));
|
||||||
|
} catch (const Poco::Net::SSLContextException &E) {
|
||||||
|
poco_error(App_.logger(), fmt::format("Poco::Net::SSLContextException thr_name={} thr_id={} code={} text={} msg={} what={}",
|
||||||
|
t_name, t_id, E.code(),
|
||||||
|
E.displayText(),
|
||||||
|
E.message(),
|
||||||
|
E.what()));
|
||||||
|
} catch (const Poco::Net::SSLException &E) {
|
||||||
|
poco_error(App_.logger(), fmt::format("Poco::Net::SSLException thr_name={} thr_id={} code={} text={} msg={} what={}",
|
||||||
|
t_name, t_id, E.code(),
|
||||||
|
E.displayText(),
|
||||||
|
E.message(),
|
||||||
|
E.what()));
|
||||||
|
|
||||||
|
} catch (const Poco::Net::InvalidAddressException &E) {
|
||||||
|
poco_error(App_.logger(), fmt::format("Poco::Net::InvalidAddressException thr_name={} thr_id={} code={} text={} msg={} what={}",
|
||||||
|
t_name, t_id, E.code(),
|
||||||
|
E.displayText(),
|
||||||
|
E.message(),
|
||||||
|
E.what()));
|
||||||
|
|
||||||
|
} catch (const Poco::Net::NetException &E) {
|
||||||
|
poco_error(App_.logger(), fmt::format("Poco::Net::NetException thr_name={} thr_id={} code={} text={} msg={} what={}",
|
||||||
|
t_name, t_id, E.code(),
|
||||||
|
E.displayText(),
|
||||||
|
E.message(),
|
||||||
|
E.what()));
|
||||||
|
|
||||||
|
} catch (const Poco::IOException &E) {
|
||||||
|
poco_error(App_.logger(), fmt::format("Poco::IOException thr_name={} thr_id={} code={} text={} msg={} what={}",
|
||||||
|
t_name, t_id, E.code(),
|
||||||
|
E.displayText(),
|
||||||
|
E.message(),
|
||||||
|
E.what()));
|
||||||
|
} catch (const Poco::RuntimeException &E) {
|
||||||
|
poco_error(App_.logger(), fmt::format("Poco::RuntimeException thr_name={} thr_id={} code={} text={} msg={} what={}",
|
||||||
|
t_name, t_id, E.code(),
|
||||||
|
E.displayText(),
|
||||||
|
E.message(),
|
||||||
|
E.what()));
|
||||||
|
} catch (const Poco::JSON::JSONTemplateException &E) {
|
||||||
|
poco_error(App_.logger(), fmt::format("Poco::JSON::JSONTemplateException thr_name={} thr_id={} code={} text={} msg={} what={}",
|
||||||
|
t_name, t_id, E.code(),
|
||||||
|
E.displayText(),
|
||||||
|
E.message(),
|
||||||
|
E.what()));
|
||||||
|
} catch (const Poco::JSON::JSONException &E) {
|
||||||
|
poco_error(App_.logger(), fmt::format("Poco::JSON::JSONException thr_name={} thr_id={} code={} text={} msg={} what={}",
|
||||||
|
t_name, t_id, E.code(),
|
||||||
|
E.displayText(),
|
||||||
|
E.message(),
|
||||||
|
E.what()));
|
||||||
|
} catch (const Poco::ApplicationException &E) {
|
||||||
|
poco_error(App_.logger(), fmt::format("Poco::ApplicationException thr_name={} thr_id={} code={} text={} msg={} what={}",
|
||||||
|
t_name, t_id, E.code(),
|
||||||
|
E.displayText(),
|
||||||
|
E.message(),
|
||||||
|
E.what()));
|
||||||
|
} catch (const Poco::Exception &E) {
|
||||||
|
poco_error(App_.logger(), fmt::format("Poco::Exception thr_name={} thr_id={} code={} text={} msg={} what={}",
|
||||||
|
t_name, t_id, E.code(),
|
||||||
|
E.displayText(),
|
||||||
|
E.message(),
|
||||||
|
E.what()));
|
||||||
|
} catch (...) {
|
||||||
|
poco_error(App_.logger(), fmt::format("Poco:Generic thr_name={}",t_name, t_id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void exception(const std::exception & E) override {
|
||||||
|
if(Poco::Thread::current()!= nullptr) {
|
||||||
|
t_name = Poco::Thread::current()->getName();
|
||||||
|
t_id = Poco::Thread::current()->id();
|
||||||
|
} else {
|
||||||
|
t_name = "startup_code";
|
||||||
|
t_id = 0;
|
||||||
|
}
|
||||||
|
poco_warning(App_.logger(), fmt::format("std::exception in {}: {} thr_id={}",
|
||||||
|
t_name,E.what(),
|
||||||
|
t_id));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void exception() override {
|
||||||
|
if(Poco::Thread::current()!= nullptr) {
|
||||||
|
t_name = Poco::Thread::current()->getName();
|
||||||
|
t_id = Poco::Thread::current()->id();
|
||||||
|
} else {
|
||||||
|
t_name = "startup_code";
|
||||||
|
t_id = 0;
|
||||||
|
}
|
||||||
|
poco_warning(App_.logger(), fmt::format("generic exception in {} thr_id={}",
|
||||||
|
t_name, t_id));
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
Poco::Util::Application &App_;
|
||||||
|
std::string t_name;
|
||||||
|
int t_id=0;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
@@ -33,7 +33,6 @@ namespace OpenWifi {
|
|||||||
int Start() override {
|
int Start() override {
|
||||||
std::lock_guard Guard(Mutex_);
|
std::lock_guard Guard(Mutex_);
|
||||||
|
|
||||||
Logger().setLevel(Poco::Message::PRIO_INFORMATION);
|
|
||||||
Logger().notice("Starting.");
|
Logger().notice("Starting.");
|
||||||
std::string DBType = MicroService::instance().ConfigGetString("storage.type");
|
std::string DBType = MicroService::instance().ConfigGetString("storage.type");
|
||||||
|
|
||||||
|
|||||||
@@ -146,6 +146,10 @@ namespace OpenWifi {
|
|||||||
WebSocketClientServer()->SendUserNotification(User,N);
|
WebSocketClientServer()->SendUserNotification(User,N);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/////
|
||||||
|
/////
|
||||||
|
/////
|
||||||
|
|
||||||
struct WebSocketNotificationRebootList {
|
struct WebSocketNotificationRebootList {
|
||||||
std::string title,
|
std::string title,
|
||||||
details,
|
details,
|
||||||
@@ -189,5 +193,58 @@ namespace OpenWifi {
|
|||||||
WebSocketClientServer()->SendUserNotification(User,N);
|
WebSocketClientServer()->SendUserNotification(User,N);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/////
|
||||||
|
/////
|
||||||
|
/////
|
||||||
|
|
||||||
|
struct WebSocketNotificationUpgradeList {
|
||||||
|
std::string title,
|
||||||
|
details,
|
||||||
|
jobId;
|
||||||
|
std::vector<std::string> success,
|
||||||
|
skipped,
|
||||||
|
no_firmware,
|
||||||
|
not_connected;
|
||||||
|
uint64_t timeStamp=OpenWifi::Now();
|
||||||
|
|
||||||
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef WebSocketNotification<WebSocketNotificationUpgradeList> WebSocketClientNotificationVenueUpgradeList_t;
|
||||||
|
|
||||||
|
inline void WebSocketNotificationUpgradeList::to_json(Poco::JSON::Object &Obj) const {
|
||||||
|
RESTAPI_utils::field_to_json(Obj,"title",title);
|
||||||
|
RESTAPI_utils::field_to_json(Obj,"jobId",jobId);
|
||||||
|
RESTAPI_utils::field_to_json(Obj,"success",success);
|
||||||
|
RESTAPI_utils::field_to_json(Obj,"notConnected",not_connected);
|
||||||
|
RESTAPI_utils::field_to_json(Obj,"noFirmware",no_firmware);
|
||||||
|
RESTAPI_utils::field_to_json(Obj,"skipped",skipped);
|
||||||
|
RESTAPI_utils::field_to_json(Obj,"timeStamp",timeStamp);
|
||||||
|
RESTAPI_utils::field_to_json(Obj,"details",details);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool WebSocketNotificationUpgradeList::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
|
try {
|
||||||
|
RESTAPI_utils::field_from_json(Obj,"title",title);
|
||||||
|
RESTAPI_utils::field_from_json(Obj,"jobId",jobId);
|
||||||
|
RESTAPI_utils::field_from_json(Obj,"success",success);
|
||||||
|
RESTAPI_utils::field_from_json(Obj,"notConnected",not_connected);
|
||||||
|
RESTAPI_utils::field_from_json(Obj,"noFirmware",no_firmware);
|
||||||
|
RESTAPI_utils::field_from_json(Obj,"skipped",skipped);
|
||||||
|
RESTAPI_utils::field_from_json(Obj,"timeStamp",timeStamp);
|
||||||
|
RESTAPI_utils::field_from_json(Obj,"details",details);
|
||||||
|
return true;
|
||||||
|
} catch(...) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void WebSocketClientNotificationVenueUpgradeCompletionToUser( const std::string & User, WebSocketClientNotificationVenueUpgradeList_t &N) {
|
||||||
|
N.type = "venue_upgrader";
|
||||||
|
WebSocketClientServer()->SendUserNotification(User,N);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace OpenWifi
|
} // namespace OpenWifi
|
||||||
|
|
||||||
|
|||||||
@@ -133,6 +133,37 @@ namespace ORM {
|
|||||||
return R;
|
return R;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline std::string WHERE_AND_(std::string Result) {
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename... Args> std::string WHERE_AND_(std::string Result, const char *fieldName, const T &Value, Args... args) {
|
||||||
|
if constexpr(std::is_same_v<T,std::string>)
|
||||||
|
{
|
||||||
|
if(!Value.empty()) {
|
||||||
|
if(!Result.empty())
|
||||||
|
Result += " and ";
|
||||||
|
Result += fieldName;
|
||||||
|
Result += '=';
|
||||||
|
Result += "'";
|
||||||
|
Result += Escape(Value);
|
||||||
|
Result += "'";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(!Result.empty())
|
||||||
|
Result += " and ";
|
||||||
|
Result += fieldName ;
|
||||||
|
Result += '=';
|
||||||
|
Result += std::to_string(Value);
|
||||||
|
}
|
||||||
|
return WHERE_AND_(Result,args...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename... Args> std::string WHERE_AND(Args... args) {
|
||||||
|
std::string Result;
|
||||||
|
return WHERE_AND_(Result, args...);
|
||||||
|
}
|
||||||
|
|
||||||
enum SqlComparison { EQ = 0, NEQ, LT, LTE, GT, GTE };
|
enum SqlComparison { EQ = 0, NEQ, LT, LTE, GT, GTE };
|
||||||
enum SqlBinaryOp { AND = 0 , OR };
|
enum SqlBinaryOp { AND = 0 , OR };
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <cstring>
|
||||||
#include "Poco/String.h"
|
#include "Poco/String.h"
|
||||||
|
|
||||||
#if defined(__GNUC__)
|
#if defined(__GNUC__)
|
||||||
@@ -195,6 +196,8 @@ namespace OpenWifi::RESTAPI::Errors {
|
|||||||
static const struct msg InvalidRadiusServerEntry{1142,"RADIUS Server IP address invalid or port missing."};
|
static const struct msg InvalidRadiusServerEntry{1142,"RADIUS Server IP address invalid or port missing."};
|
||||||
static const struct msg InvalidRadiusServerWeigth{1143,"RADIUS Server IP weight cannot be 0."};
|
static const struct msg InvalidRadiusServerWeigth{1143,"RADIUS Server IP weight cannot be 0."};
|
||||||
|
|
||||||
|
static const struct msg MaximumRTTYSessionsReached{1144,"Too many RTTY sessions currently active"};
|
||||||
|
static const struct msg DeviceIsAlreadyBusy{1145,"Device is already executing a command. Please try later."};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -427,7 +430,9 @@ namespace OpenWifi::uCentralProtocol {
|
|||||||
static const char *RADIUSDATA = "data";
|
static const char *RADIUSDATA = "data";
|
||||||
static const char *RADIUSACCT = "acct";
|
static const char *RADIUSACCT = "acct";
|
||||||
static const char *RADIUSAUTH = "auth";
|
static const char *RADIUSAUTH = "auth";
|
||||||
|
static const char *RADIUSCOA = "coa";
|
||||||
static const char *RADIUSDST = "dst";
|
static const char *RADIUSDST = "dst";
|
||||||
|
static const char *IES = "ies";
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace OpenWifi::uCentralProtocol::Events {
|
namespace OpenWifi::uCentralProtocol::Events {
|
||||||
@@ -442,6 +447,7 @@ namespace OpenWifi::uCentralProtocol::Events {
|
|||||||
static const char *RECOVERY = "recovery";
|
static const char *RECOVERY = "recovery";
|
||||||
static const char *TELEMETRY = "telemetry";
|
static const char *TELEMETRY = "telemetry";
|
||||||
static const char *DEVICEUPDATE = "deviceupdate";
|
static const char *DEVICEUPDATE = "deviceupdate";
|
||||||
|
static const char *VENUE_BROADCAST = "venue_broadcast";
|
||||||
|
|
||||||
enum EVENT_MSG {
|
enum EVENT_MSG {
|
||||||
ET_UNKNOWN,
|
ET_UNKNOWN,
|
||||||
@@ -454,28 +460,34 @@ namespace OpenWifi::uCentralProtocol::Events {
|
|||||||
ET_CFGPENDING,
|
ET_CFGPENDING,
|
||||||
ET_RECOVERY,
|
ET_RECOVERY,
|
||||||
ET_DEVICEUPDATE,
|
ET_DEVICEUPDATE,
|
||||||
ET_TELEMETRY
|
ET_TELEMETRY,
|
||||||
|
ET_VENUEBROADCAST
|
||||||
};
|
};
|
||||||
|
|
||||||
inline static EVENT_MSG EventFromString(const std::string & Method) {
|
inline EVENT_MSG EventFromString(const std::string & Method) {
|
||||||
static std::vector<std::pair<const char *,EVENT_MSG>> Values{
|
if(strcmp(STATE,Method.c_str())==0)
|
||||||
{ CFGPENDING , ET_CFGPENDING },
|
return ET_STATE;
|
||||||
{ CONNECT, ET_CONNECT },
|
else if(strcmp(HEALTHCHECK,Method.c_str())==0)
|
||||||
{ CRASHLOG, ET_CRASHLOG },
|
return ET_HEALTHCHECK;
|
||||||
{ DEVICEUPDATE, ET_DEVICEUPDATE },
|
else if(strcmp(CONNECT,Method.c_str())==0)
|
||||||
{ HEALTHCHECK, ET_HEALTHCHECK },
|
return ET_CONNECT;
|
||||||
{ LOG, ET_LOG },
|
else if(strcmp(CFGPENDING,Method.c_str())==0)
|
||||||
{ PING, ET_PING },
|
return ET_CFGPENDING;
|
||||||
{ RECOVERY, ET_RECOVERY },
|
else if(strcmp(CRASHLOG,Method.c_str())==0)
|
||||||
{ STATE, ET_STATE },
|
return ET_CRASHLOG;
|
||||||
{ TELEMETRY, ET_TELEMETRY }
|
else if(strcmp(DEVICEUPDATE,Method.c_str())==0)
|
||||||
};
|
return ET_DEVICEUPDATE;
|
||||||
|
else if(strcmp(LOG,Method.c_str())==0)
|
||||||
std::string L = Poco::toLower(Method);
|
return ET_LOG;
|
||||||
auto hint = std::find_if(cbegin(Values),cend(Values),[&](const std::pair<const char *,EVENT_MSG> &v) ->bool { return strcmp(v.first,L.c_str())==0; });
|
else if(strcmp(PING,Method.c_str())==0)
|
||||||
if(hint == cend(Values))
|
return ET_PING;
|
||||||
return ET_UNKNOWN;
|
else if(strcmp(RECOVERY,Method.c_str())==0)
|
||||||
return hint->second;
|
return ET_RECOVERY;
|
||||||
|
else if(strcmp(TELEMETRY,Method.c_str())==0)
|
||||||
|
return ET_TELEMETRY;
|
||||||
|
else if(strcmp(VENUE_BROADCAST,Method.c_str())==0)
|
||||||
|
return ET_VENUEBROADCAST;
|
||||||
|
return ET_UNKNOWN;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#!/bin/sh
|
#!/bin/bash
|
||||||
# wait-for-postgres.sh
|
# wait-for-postgres.sh
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
@@ -20,7 +20,7 @@ if [ "$1" = '/openwifi/owfms' -a "$(id -u)" = '0' ]; then
|
|||||||
if [ "$RUN_CHOWN" = 'true' ]; then
|
if [ "$RUN_CHOWN" = 'true' ]; then
|
||||||
chown -R "$OWFMS_USER": "$OWFMS_ROOT" "$OWFMS_CONFIG"
|
chown -R "$OWFMS_USER": "$OWFMS_ROOT" "$OWFMS_CONFIG"
|
||||||
fi
|
fi
|
||||||
exec su-exec "$OWFMS_USER" "$@"
|
exec gosu "$OWFMS_USER" "$@"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
exec "$@"
|
exec "$@"
|
||||||
|
|||||||
Reference in New Issue
Block a user