Docs using Sphinx

This commit is contained in:
Zaid Abdulla committed 2019-07-27 22:38:32 -07:00
1 parent 39901150a7
commit 1ee6c9e89e
14 files changed
+1348

No files matched your search

+529
View File
@@ -0,0 +1,529 @@
API Reference
=============
GenieACS expoeses a rich RESTful API through its NBI component. This document
serves as a reference for the available APIs.
This API makes use of MongoDB's query language in some of its endpoints. Refer
to MongoDB's documentation for details.
.. note::
The examples below use ``curl`` command for simplicity and ease of testing.
Query parameters are URL-encoded, but the original pre-encoding values are
shown for reference. These examples assume genieacs-nbi is running locally
and listening on the default NBI port (7557).
.. warning::
A common pitfll is not properly percent-encoding special characters in the
device ID or query in the URL.
Endpoints
---------
GET /\<collection\>/?query=\<query\>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Search for records in the database (e.g. devices, tasks, presets, files).
Returns a JSON representation of all items in the given collection that match
the search criteria.
*collection*: The data collection to search. Could be one of: tasks, devices,
presets, objects.
*query*: Search query. Refer to MongoDB queries for reference.
Examples
^^^^^^^^
- Find a device by its ID:
.. code:: javascript
query = {"_id": "202BC1-BM632w-0000000"}
.. code:: bash
curl -i 'http://localhost:7557/devices/?query=%7B%22_id%22%3A%22202BC1-BM632w-0000000%22%7D'
- Find a device by its MAC address:
.. code:: javascript
query = {
"InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANIPConnection.1.MACAddress": "20:2B:C1:E0:06:65"
}
.. code:: bash
curl -i 'http://localhost:7557/devices/?query=%7B%22InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANIPConnection.1.MACAddress%22%3A%2220:2B:C1:E0:06:65%22%7D'
- Search for devices that have not initiated an inform in the last 7 days.
.. code:: javascript
query = {
"_lastInform": {
"$lt" : "2017-12-11 13:16:23 +0000"
}
}
.. code:: bash
curl -i 'http://localhost:7557/devices/?query=%7B%22_lastInform%22%3A%7B%22%24lt%22%3A%222017-12-11%2013%3A16%3A23%20%2B0000%22%7D%7D'
- Show pending tasks for a given device:
.. code:: javascript
query = {"device": "202BC1-BM632w-0000000"}
.. code:: bash
curl -i 'http://localhost:7557/tasks/?query=%7B%22device%22%3A%22202BC1-BM632w-0000000%22%7D'
- Return specific parameters for a given device:
.. code:: javascript
query = {"_id": "202BC1-BM632w-0000000"}
.. code:: bash
curl -i 'http://localhost:7557/devices?query=%7B%22_id%22%3A%22202BC1-BM632w-0000000%22%7D&projection=InternetGatewayDevice.DeviceInfo.ModelName,InternetGatewayDevice.DeviceInfo.Manufacturer'
The ``projection`` URL param is a comma-separated list of the parameters to receive.
POST /devices/\<device_id\>/tasks?[connection_request]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Enqueue task(s) and optionally trigger a connection request to the device.
Refer to :ref:`tasks` section for information about the task object format.
Returns status code 200 if the tasks have been successfully executed, and 202
if the tasks have been queued to be executed at the next inform.
*device_id*: The ID of the device.
*connection_request*: Indicates that a connection request will be triggered to
execute the tasks immediatly. Otherwise, the tasks will be queued and be
processed at the next inform.
The response body is the task object as it is inserted in the database. The
object will include ``_id`` property which you can use to look up the task
later.
Examples
^^^^^^^^
- Refresh all device parameters now:
.. code:: bash
curl -i 'http://localhost:7557/devices/202BC1-BM632w-0000000/tasks?connection_request' \
-X POST \
--data '{"name": "refreshObject", "objectName": ""}'
- Change WiFi SSID and password:
.. code:: javascript
{
"name": "setParameterValues",
"parameterValues": [
["InternetGatewayDevice.LANDevice.1.WLANConfiguration.1.SSID", "GenieACS", "xsd:string"],
["InternetGatewayDevice.LANDevice.1.WLANConfiguration.1.PreSharedKey.1.PreSharedKey", "hello world", "xsd:string"]
]
}
.. code:: bash
curl -i 'http://localhost:7557/devices/202BC1-BM632w-0000000/tasks?connection_request' \
-X POST \
--data '{"name":"setParameterValues", "parameterValues": [["InternetGatewayDevice.LANDevice.1.WLANConfiguration.1.SSID", "GenieACS", "xsd:string"],["InternetGatewayDevice.LANDevice.1.WLANConfiguration.1.PreSharedKey.1.PreSharedKey", "hello world", "xsd:string"]]}'
POST /tasks/\<task_id\>/retry
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Retry a faulty task at the next inform.
*task_id*: The ID of the task as returned by 'GET /tasks' request.
Example
^^^^^^^
.. code:: bash
curl -i 'http://localhost:7557/tasks/5403908ef28ea3a25c138adc/retry' -X POST
DELETE /tasks/\<task_id\>
~~~~~~~~~~~~~~~~~~~~~~~~~
Delete the given task.
*task_id*: The ID of the task as returned by 'GET /tasks' request.
Example
^^^^^^^
.. code:: bash
curl -i 'http://localhost:7557/tasks/5403908ef28ea3a25c138adc' -X DELETE
DELETE /faults/\<fault_id\>
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Delete the given fault.
*fault_id*: The ID of the fault as returned by 'GET /faults' request. The ID
format is "\<device_id\>:\<channel\>".
Example
^^^^^^^
.. code:: bash
curl -i 'http://localhost:7557/faults/202BC1-BM632w-0000000:default' -X DELETE
DELETE /devices/\<device_id\>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Delete the given device from the database.
Example
^^^^^^^
.. code:: bash
curl -X DELETE -i 'http://localhost:7557/devices/202BC1-BM632w-000001'
.. note::
Note that the device will be registered again when/if it contacts the ACS
again (e.g. on the next periodic inform).
POST /devices/\<device_id\>/tags/\<tag\>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Assign a tag to a device. Has no effect if such tag already exists.
*device_id*: The ID of the device.
*tag*: The tag to be assigned.
Example
^^^^^^^
Assign the tag "testing" to a device:
.. code:: bash
curl -i 'http://localhost:7557/devices/202BC1-BM632w-0000000/tags/testing' -X POST
DELETE /devices/\<device_id\>/tags/\<tag\>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Remove a tag from a device.
*device_id*: The ID of the device.
*tag*: The tag to be removed.
Example
^^^^^^^
Remove the tag "testing" from a device:
.. code:: bash
curl -i 'http://localhost:7557/devices/202BC1-BM632w-0000000/tags/testing' -X DELETE
PUT /presets/\<preset_name\>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Create or update a preset. Returns status code 200 if the preset has been
added/updated successfully. The body of the request is a JSON representation of
the preset. Refer to :ref:`presets` section below for details about its format.
*preset_name*: The name of the preset.
Example
^^^^^^^
Create a preset to set 5 minutes inform interval for all devices tagged with
"test":
.. code:: javascript
query = {
"weight": 0,
"precondition": "{\"_tags\": \"test\"}"
"configurations": [
{
"type": "value",
"name": "InternetGatewayDevice.ManagementServer.PeriodicInformEnable",
"value": "true"
},
{
"type": "value",
"name": "InternetGatewayDevice.ManagementServer.PeriodicInformInterval",
"value": "300"
}
]
}
.. code:: bash
curl -i 'http://localhost:7557/presets/inform' \
-X PUT \
--data '{"weight": 0, "precondition": "{\"_tags\": \"test\"}", "configurations": [{"type": "value", "name": "InternetGatewayDevice.ManagementServer.PeriodicInformEnable", "value": "true"}, {"type": "value", "name": "InternetGatewayDevice.ManagementServer.PeriodicInformInterval", "value": "300"}]}'
DELETE /presets/\<preset_name\>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. code:: bash
curl -i 'http://localhost:7557/presets/inform' -X DELETE
PUT /files/\<file_name\>
~~~~~~~~~~~~~~~~~~~~~~~~
Upload a new file or overwrite an existing one. Returns status code 200 if the
file has been added/updated successfully. The file content should be sent as
the request body.
*file_name*: The name of the uploaded file.
The following file metadata may be sent as request headers:
- ``fileType``: For firmware images it should be "1 Firmware Upgrade Image".
Other common types are "2 Web Content" and "3 Vendor Configuration File".
- ``oui``: The OUI of the device model that this file belogs to.
- ``productClass``: The product class of the device.
- ``version``: In case of firmware images, this refer to the firmware version.
Example
^^^^^^^
Upload a firmware image file:
.. code:: bash
curl -i 'http://localhost:7557/files/new_firmware_v1.0.bin' \
-X PUT \
--data-binary @"./new_firmware_v1.0.bin" \
--header "fileType: 1 Firmware Upgrade Image" \
--header "oui: 123456" \
--header "productClass: ABC" \
--header "version: 1.0"
DELETE /files/\<file_name\>
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Delete a previously uploaded file:
.. code:: bash
curl -i 'http://localhost:7557/files/new_firmware_v1.0.bin' -X DELETE
GET /files/
~~~~~~~~~~~
Gets all previously uploaded files.
GET /files/?query={"filename":"\<filename\>"}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Find files using a query.
.. _tasks:
Tasks
-----
Find the different availabe tasks and their object structure.
``getParameterValues``
~~~~~~~~~~~~~~~~~~~~~~
.. code:: javascript
query = {
"name": "getParameterValues",
"parameterNames": [
"InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANIPConnectionNumberOfEntries",
"InternetGatewayDevice.Time.NTPServer1", "InternetGatewayDevice.Time.Status"
]
}
.. code:: bash
curl -i 'http://localhost:7557/devices/00236a-96318REF-SR360NA0A4%252D0003196/tasks?timeout=3000&connection_request' \
-X POST \
--data '{"name": "getParameterValues", "parameterNames": ["InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANIPConnectionNumberOfEntries", "InternetGatewayDevice.Time.NTPServer1", "InternetGatewayDevice.Time.Status"] }'
You may request a single or multiple parameters at once.
After the task has been executed successfully you can then fetch the CPE object
and read the parameters from the JSON object.
.. code:: javascript
query = {"_id": "00236a-96318REF-SR360NA0A4%2D0003196"}
.. code:: bash
curl -i 'http://localhost:7557/devices/?query=%7B%22_id%22%3A%2200236a-96318REF-SR360NA0A4%252D0003196%22%7D'
``refreshObject``
~~~~~~~~~~~~~~~~~
.. code:: bash
curl -i 'http://localhost:7557/devices/00236a-SR552n-SR552NA084%252D0003269/tasks?timeout=3000&connection_request' \
-X POST \
--data '{"name": "refreshObject", "objectName": "InternetGatewayDevice.WANDevice.1.WANConnectionDevice"}'
``setParameterValues``
~~~~~~~~~~~~~~~~~~~~~~
.. code:: bash
curl -i 'http://localhost:7557/devices/00236a-SR552n-SR552NA084%252D0003269/tasks?timeout=3000&connection_request' \
-X POST \
--data '{"name": "setParameterValues", "parameterValues": [["InternetGatewayDevice.ManagementServer.UpgradesManaged",false]]}'
Multiple values can be set at once by adding multiple arrays to the
parameterValues key. For example:
.. code:: javascript
{
name: "setParameterValues",
parameterValues: [["InternetGatewayDevice.ManagementServer.UpgradesManaged", false], ["InternetGatewayDevice.Time.Enable", true], ["InternetGatewayDevice.Time.NTPServer1", "pool.ntp.org"]]
}
``addObject``
~~~~~~~~~~~~~
.. code:: bash
curl -i 'http://localhost:7557/devices/00236a-SR552n-SR552NA084%252D0003269/tasks?timeout=3000&connection_request' \
-X POST \
--data '{"name":"addObject","objectName":"InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANPPPConnection"}'
``reboot``
~~~~~~~~~~
.. code:: bash
curl -i 'http://localhost:7557/devices/00236a-SR552n-SR552NA084%252D0003269/tasks?timeout=3000&connection_request' \
-X POST \
--data '{"name": "reboot"}'
``factoryReset``
~~~~~~~~~~~~~~~~
.. code:: bash
curl -i 'http://localhost:7557/devices/00236a-SR552n-SR552NA084%252D0003269/tasks?timeout=3000&connection_request' \
-X POST \
--data '{"name": "factoryReset"}'
``download``
~~~~~~~~~~~~
.. code:: bash
curl -i 'http://localhost:7557/devices/00236a-SR552n-SR552NA084%252D0003269/tasks?timeout=3000&connection_request' \
-X POST \
--data '{"name": "download", "file": "mipsbe-6-42-lite.xml"}'
.. _presets:
Presets
-------
Presets assign a set of configuration or a Provision script to devices based on
a precondition (search filter), schedule (cron expression), and events.
Precondition
~~~~~~~~~~~~
The ``precondition`` property is a JSON string representation of the search
filter to test if the preset applies to a given device. Examples preconditions
are:
- ``{"param": "value"}``
- ``{"param": value", "param2": {"$ne": "value2"}}``
Other operators that can be used are ``$gt``, ``$lt``, ``$gte`` and ``$lte``.
Configuration
~~~~~~~~~~~~~
The configuration property is an array containing the different configurations
to be applied to a device, as shown below:
.. code:: javascript
[
{
"type": "value",
"name": "InternetGatewayDevice.ManagementServer.PeriodicInformEnable",
"value": "true"
},
{
"type": "value",
"name": "InternetGatewayDevice.ManagementServer.PeriodicInformInterval",
"value": "300"
},
{
"type": "delete_object",
"name": "object_parent",
"object": "object_name"
},
{
"type": "add_object",
"name": "object_parent",
"object": "object_name"
},
{
"type": "provision",
"name": "YourProvisionName"
},
]
The configuration type ``provision`` triggers a Provision script. In the
example above, the provision named "YourProvisionName" will be executed.
Provisions
----------
Create a provision
~~~~~~~~~~~~~~~~~~
The Provision's JavaScript code is the body of the HTTP PUT request.
.. code:: bash
curl -X PUT -i 'http://localhost:7557/provisions/mynewprovision' --data 'log("Provision started at " + now);'
Delete a provision
~~~~~~~~~~~~~~~~~~
.. code:: bash
curl -X DELETE -i 'http://localhost:7557/provisions/mynewprovision'
Get provisions
~~~~~~~~~~~~~~
Get all provisions:
.. code:: bash
curl -X GET -i 'http://localhost:7557/provisions/'
+65
View File
@@ -0,0 +1,65 @@
# Configuration file for the Sphinx documentation builder.
#
# This file only contains a selection of the most common options. For a full
# list see the documentation:
# http://www.sphinx-doc.org/en/master/config
# -- Path setup --------------------------------------------------------------
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
# import os
# import sys
# sys.path.insert(0, os.path.abspath('.'))
import json
# -- Project information -----------------------------------------------------
project = 'GenieACS Documentation'
copyright = '2019, GenieACS Inc.'
author = 'GenieACS Inc.'
# The full version, including alpha/beta/rc tags
release = json.load(open("../package.json"))["version"]
# -- General configuration ---------------------------------------------------
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
# -- Options for HTML output -------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
# html_theme = 'alabaster'
html_theme = 'sphinx_rtd_theme'
html_logo = "logo.svg"
html_theme_options = {
"logo_only": True
}
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
master_doc = 'index'
highlight_language = 'javascript'
+6
View File
@@ -0,0 +1,6 @@
.. _cpe-authentication:
CPE Authentication
==================
TODO
+6
View File
@@ -0,0 +1,6 @@
.. _environment-variables:
Environment Variables
=====================
TODO
+34
View File
@@ -0,0 +1,34 @@
// This is an exmaple GenieACS extension to get the current latitude/longitude
// of the International Space Station. Why, you ask? Because why not.
// To install, copy this file to config/ext/iss.js.
"use strict";
const http = require("http");
let cache = null;
let cacheExpire = 0;
function latlong(args, callback) {
if (Date.now() < cacheExpire)
return callback(null, cache);
http.get("http://api.open-notify.org/iss-now.json", (res) => {
if (res.statusCode !== 200)
return callback(new Error(`Request failed (status code: ${res.statusCode})`));
let rawData = "";
res.on("data", (chunk) => rawData += chunk);
res.on("end", () => {
let pos = JSON.parse(rawData)["iss_position"];
cache = [+pos["latitude"], +pos["longitude"]];
cacheExpire = Date.now() + 10000;
callback(null, cache);
});
}).on("error", (err) => {
callback(err);
});
}
exports.latlong = latlong;
+33
View File
@@ -0,0 +1,33 @@
.. _extensions:
Extensions
==========
Given that :ref:`provisions` and :ref:`virtual-parameters` are executed in a
sandbox environment, it is not possible to interact with external sources or
execute any action that requires OS, file system, or network access. Extensions
exist to bridge that gap.
Extensions are fully-privileged Node.js modules and as such have access to
standard Node libraries and 3rd party packages. Functions exposed by the
extension can be called from Provision scripts using the ``ext()`` function. A
typical use case for extensions is fetching credentials from a database to have
that pushed to the device during provisioning.
By default, the extension JS code must be placed under ``config/ext``
directory. You may need to create that directory if it doesn't already exist.
The example extension below fetches data from an external REST API and returns
that to the caller:
.. literalinclude:: ext-sample.js
:language: javascript
To call this extension from a Provision or a Virtual Parameter script:
.. code:: javascript
// The arguments "arg1" and "arg2" are passed to the latlong. Though they are
// unused in this particular example.
const res = ext("ext-sample", "latlong", "arg1", "arg2");
log(JSON.stringify(res));
+6
View File
@@ -0,0 +1,6 @@
.. _https:
HTTPS
=====
TODO
+55
View File
@@ -0,0 +1,55 @@
.. GenieACS documentation master file, created by
sphinx-quickstart on Wed Jun 5 13:47:06 2019.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Welcome to GenieACS's documentation!
====================================
.. toctree::
:caption: Table of Contents
.. raw:: latex
\part{Installation}
.. toctree::
:maxdepth: 1
:caption: Installation
installation-guide
environment-variables
.. raw:: latex
\part{Administration}
.. toctree::
:maxdepth: 1
:caption: Administration
provisions
virtual-parameters
.. raw:: latex
\part{Integration}
.. toctree::
:maxdepth: 1
:caption: Integration
extensions
api-reference
.. raw:: latex
\part{Security}
.. toctree::
:maxdepth: 1
:caption: Security
https
cpe-authentication
roles-and-permissions
+230
View File
@@ -0,0 +1,230 @@
Installation Guide
==================
This guide is for installing GenieACS on a single server on any Linux distro
that uses *systemd* as its init system.
The various GenieACS services are independant of each other and may be
installed on different servers. You may also run multiple instances of each in
a load-balancing/failover setup.
.. attention::
For production deployments make sure to configure TLS and change
``UI_JWT_SECRET`` to a unique and secure string. Refer to :ref:`https`
section for how to enable TLS to encrypt traffic.
Prerequisites
-------------
.. topic:: Node.js
GenieACS requires Node.js 10.x and up. Refer to https://nodejs.org/ for
instructions.
.. topic:: MongoDB
GenieACS requires MongoDB 3.6 and up. Refer to https://www.mongodb.com/ for
instructions.
Install GenieACS
-------------------
.. topic:: Installing from NPM:
.. parsed-literal::
sudo npm install -g genieacs@\ |release|
.. topic:: Installing from source
If you prefer installing from source, such as when running a GenieACS copy
with custom patches, refer to README.md file in the source package. Adjust
the next steps below accordingly.
Configure systemd
-----------------
.. topic:: Create a system user to run GenieACS daemons
.. code:: bash
sudo useradd --system --no-create-home --user-group genieacs
.. topic:: Create directory to save extensions and environment file
We'll use :file:`/opt/genieacs/ext/` directory to store extension scripts (if any).
.. code:: bash
mkdir /opt/genieacs
mkdir /opt/genieacs/ext
chown genieacs:genieacs /opt/genieacs/ext
Create the file :file:`/opt/genieacs/genieacs.env` to hold our configuration
options which we pass to GenieACS as environment variables. See
:ref:`environment-variables` section for a list of all available
configuration options.
.. code:: bash
GENIEACS_CWMP_ACCESS_LOG_FILE=/var/log/genieacs/genieacs-cmwp-access.log
GENIEACS_NBI_ACCESS_LOG_FILE=/var/log/genieacs/genieacs-nbi-access.log
GENIEACS_FS_ACCESS_LOG_FILE=/var/log/genieacs/genieacs-fs-access.log
GENIEACS_UI_ACCESS_LOG_FILE=/var/log/genieacs/genieacs-ui-access.log
GENIEACS_DEBUG_FILE=/var/log/genieacs/genieacs-debug.yaml
GENIEACS_UI_JWT_SECRET=secret
Set file ownership and permissions:
.. code:: bash
sudo chown genieacs:genieacs /opt/genieacs/genieacs.env
sudo chmod 600 /opt/genieacs/genieacs.env
.. topic:: Create logs directory
.. code:: bash
mkdir /var/log/genieacs
chown genieacs:genieacs /var/log/genieacs
.. topic:: Create systemd unit files
Create a systemd unit file for each of the four GenieACS services. Note that
we're using EnvironmentFile directive to read the environment variables from
the file we created earlier.
Each service has two streams of logs: access log and process log. Access logs
are configured here to be dumped in a log file under
:file:`/var/log/genieacs/` while process logs go to *journald*. Use
``journalctl`` command to view process logs.
1. Run the following command to create ``genieacs-cwmp`` service:
.. code:: bash
sudo systemctl edit --force genieacs-cwmp
Then paste the following in the editor and save:
.. code:: cfg
[Unit]
Description=GenieACS CWMP
After=network.target
[Service]
User=genieacs
EnvironmentFile=/opt/genieacs/genieacs.env
ExecStart=genieacs-cwmp
KillMode=process
[Install]
WantedBy=default.target
2. Run the following command to create ``genieacs-nbi`` service:
.. code:: bash
sudo systemctl edit --force genieacs-nbi
Then paste the following in the editor and save:
.. code:: cfg
[Unit]
Description=GenieACS NBI
After=network.target
[Service]
User=genieacs
EnvironmentFile=/opt/genieacs/genieacs.env
ExecStart=genieacs-nbi
KillMode=process
[Install]
WantedBy=default.target
3. Run the following command to create ``genieacs-fs`` service:
.. code:: bash
sudo systemctl edit --force genieacs-fs
Then paste the following in the editor and save:
.. code:: cfg
[Unit]
Description=GenieACS FS
After=network.target
[Service]
User=genieacs
EnvironmentFile=/opt/genieacs/genieacs.env
ExecStart=genieacs-fs
KillMode=process
[Install]
WantedBy=default.target
4. Run the following command to create ``genieacs-ui`` service:
.. code:: bash
sudo systemctl edit --force genieacs-ui
Then paste the following in the editor and save:
.. code:: cfg
[Unit]
Description=GenieACS UI
After=network.target
[Service]
User=genieacs
EnvironmentFile=/opt/genieacs/genieacs.env
ExecStart=genieacs-ui
KillMode=process
[Install]
WantedBy=default.target
.. topic:: Configure log file rotation using logrotate
Save the following under :file:`/etc/logrotate.d/genieacs`
.. code::
/var/log/genieacs/*.{log,yaml} {
daily
rotate 30
compress
delaycompress
dateext
}
.. topic:: Enable and start services
.. code:: bash
sudo systemctl enable genieacs-cwmp
sudo systemctl start genieacs-cwmp
sudo systemctl status genieacs-cwmp
sudo systemctl enable genieacs-nbi
sudo systemctl start genieacs-nbi
sudo systemctl status genieacs-nbi
sudo systemctl enable genieacs-fs
sudo systemctl start genieacs-fs
sudo systemctl status genieacs-fs
sudo systemctl enable genieacs-ui
sudo systemctl start genieacs-ui
sudo systemctl status genieacs-ui
Review the status message for each to verify that the services are running
successfully.
+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="310" height="64" viewBox="0 0 82.021 16.933"><path d="M7.341 9.892l.687 1.307c-.305.53-.718.99-1.238 1.378-.851.503-1.543.421-2.076-.244 1.03-.466 1.907-1.28 2.627-2.44M4.676 5.97a2.144 2.144 0 0 1 .237 1.228 8.358 8.358 0 0 1-.518 2.21 7.386 7.386 0 0 0-.424 1.708 2.38 2.38 0 0 0 .168 1.205c.163.393.457.73.883 1.01-.458.138-.859.175-1.202.112-.6-.114-.992-.476-1.175-1.084a3.571 3.571 0 0 1-.093-1.787 11.742 11.742 0 0 1 .435-1.644 11.606 11.606 0 0 0 .432-1.708c.037-.22.041-.45.01-.687a1.66 1.66 0 0 0-.273-.706 1.582 1.582 0 0 0-.6-.506c.245-.046.487-.083.728-.113a1.45 1.45 0 0 1 .728.123c.295.13.517.343.665.639m7.901-1.802l.222.218-1.847 1.678.555.555 1.678-1.846.218.22-1.843 1.679.521.521L13.76 5.35l.222.218-1.847 1.678.556.556 1.764-1.765.375.368-1.584 1.584h.004l-2.065 2.061-1.253.515-1.795-1.348-.007-.008-.008.008.004.007 1.194 1.592-.398.161-1.75-1.75.444-1.08 1.636 1.228.004.003.011-.007-.003-.004-1.39-1.85.225-.553 1.694-1.689h-.004l1.956-1.952.372.368-1.769 1.768.552.552 1.678-1.843m1.456 9.91c1.55-1.549 2.324-3.42 2.324-5.612 0-2.187-.774-4.058-2.323-5.612C12.48 1.304 10.61.53 8.423.53 6.23.53 4.36 1.305 2.81 2.854c-.95.953-1.609 2.025-1.974 3.213l.158-.086c.788-.415 1.486-.203 2.094.638-.55.113-.992.232-1.325.357a1.923 1.923 0 0 0-.503.289c-.337.268-.55.608-.638 1.02a3.98 3.98 0 0 0 .011 1.761c.285 1.527 1.011 2.87 2.178 4.032 1.549 1.552 3.42 2.328 5.612 2.328 2.19 0 4.06-.776 5.612-2.328" fill="white"/><path d="M47.104 1.767c-.456 0-.816.388-.816.849 0 .46.355.816.816.816a.82.82 0 0 0 .833-.816.85.85 0 0 0-.833-.849zM25.602 3.171c-.205 0-.382.046-.5.13-.118.085-.187.201-.187.4v.981l-.151-.031a9.89 9.89 0 0 0-1.872-.173c-1.288 0-2.148.066-2.657.374a1.264 1.264 0 0 0-.548.676c-.119.313-.177.73-.177 1.28v6.123c0 .982.25 1.508.787 1.824.539.315 1.407.41 2.628.41 1.308 0 2.178-.13 2.701-.484.524-.354.745-.932.745-1.942 0-.821-.147-1.37-.543-1.722-.395-.352-1.075-.528-2.186-.528h-2.787V9.255l.148.03c.478.092 1.094.11 1.89.11 1.292 0 2.148-.112 2.658-.453.51-.34.724-.915.724-1.958V3.7c0-.198-.07-.314-.186-.399a.843.843 0 0 0-.487-.13zm6.112 1.29c-1.226 0-2.038.137-2.526.495-.488.357-.697.945-.697 1.947v2.84c0 .935.23 1.54.743 1.932.512.39 1.337.571 2.544.571 1.392 0 2.17-.058 2.567-.196.199-.069.298-.15.355-.246.058-.097.078-.227.078-.405 0-.208-.04-.378-.117-.485-.076-.108-.186-.171-.396-.171-.794 0-1.057.19-2.408.19-.593 0-1.06-.078-1.395-.255-.335-.177-.53-.473-.53-.84v-.89h4.301a.717.717 0 0 0 .539-.213c.13-.138.213-.342.213-.62V6.903c0-1.037-.179-1.623-.654-1.97-.476-.348-1.3-.472-2.617-.472zm8.83 0c-1.303 0-2.117.086-2.59.49-.472.403-.665 1.168-.665 2.623v4.002c0 .215.074.338.197.426.123.088.31.134.524.134.223 0 .412-.046.537-.134.125-.088.198-.211.198-.426v-3.81c0-.424.006-.754.04-1.019.036-.265.102-.47.236-.623.135-.152.328-.236.574-.28.246-.044.552-.053.949-.053.4 0 .712.01.963.053.25.044.447.126.587.278.139.151.211.358.25.623.038.265.046.597.046 1.02v3.81c0 .217.07.34.19.427.122.088.308.134.53.134.215 0 .401-.046.525-.134.123-.088.196-.211.196-.426V7.574c0-1.455-.201-2.219-.682-2.623-.48-.404-1.303-.49-2.605-.49zm12.996 0c-1.227 0-2.038.137-2.527.495-.488.357-.696.945-.696 1.947v2.84c0 .935.23 1.54.742 1.932.513.39 1.338.571 2.545.571 1.392 0 2.17-.058 2.567-.196.2-.069.298-.15.355-.246.058-.097.079-.227.079-.405 0-.208-.04-.378-.117-.485-.077-.108-.188-.171-.398-.171-.793 0-1.056.19-2.406.19-.594 0-1.062-.078-1.396-.255-.335-.177-.53-.473-.53-.84v-.89h4.301a.716.716 0 0 0 .539-.213c.13-.138.213-.342.213-.62V6.903c0-1.037-.18-1.623-.655-1.97-.475-.348-1.3-.472-2.616-.472zm-6.436.13c-.212 0-.398.047-.522.14-.124.09-.198.22-.198.435v6.41c0 .215.073.338.196.426.123.088.31.134.524.134.223 0 .414-.046.54-.134.124-.088.198-.211.198-.426v-6.41c0-.215-.075-.342-.201-.434-.126-.092-.316-.142-.537-.142zM22.892 5.726c.662 0 1.4.065 1.918.146l.105.016v.92c0 .246-.01.453-.058.632a.757.757 0 0 1-.292.441c-.305.216-.798.263-1.673.263h-.123v-.013c-.761 0-1.26-.002-1.55-.16a.637.637 0 0 1-.307-.395c-.049-.17-.057-.37-.057-.625v-.062c0-.227.03-.418.108-.58a.811.811 0 0 1 .373-.373c.337-.171.826-.21 1.556-.21zm8.839.049c.677 0 1.116.054 1.412.237a.775.775 0 0 1 .316.373c.063.154.085.33.085.535v.811h-3.611V6.92c0-.437.135-.755.439-.928.304-.174.739-.217 1.359-.217zm21.825 0c.677 0 1.117.054 1.413.237a.779.779 0 0 1 .318.373c.062.154.084.33.084.535v.811h-3.613V6.92c0-.437.136-.755.44-.928.304-.174.738-.217 1.358-.217zm-32.701 5.867h2.388c.613 0 1.05.045 1.355.226.306.18.443.505.443.95 0 .429-.179.743-.533.907-.354.164-.861.206-1.568.206-.652 0-1.151-.045-1.51-.186a.952.952 0 0 1-.425-.3.789.789 0 0 1-.15-.483v-1.195z" fill="white"/><path d="M62.339 4.462c-1.399 0-2.18.078-2.58.225-.2.073-.3.157-.357.254-.058.097-.079.22-.079.386 0 .199.043.362.122.469.079.107.19.172.392.172.38 0 .616-.048.947-.096a9.457 9.457 0 0 1 1.475-.098c.58 0 .966.043 1.233.192a.685.685 0 0 1 .292.312c.06.13.082.281.082.452v.857h-2.484c-1.134 0-1.763.19-2.11.559-.346.367-.443.95-.443 1.802 0Line truncated

After

Width:  |  Height:  |  Size: 6.8 KiB

+271
View File
@@ -0,0 +1,271 @@
.. _provisions:
Provisions
==========
A Provision is a piece of JavaScript code that is executed on the server on a
per-device basis. It enables implementing complex provisioning scenarios and
other operations such as automated firmware upgrade rollout. Apart from a few
special functions, the script is essentially a standard ES6 code executed in
strict mode.
Provisions are mapped to devices using presets. Note that the added performance
overhead when using Provisions as opposed to simple preset configuration
entries is relatively small. Anything that can be done via preset
configurations can be done using a Provision script. In fact, the now
deprecated configuration format is still supported primarily for backward
compatibility and it is recommended to use Provision scripts for all
configuration.
When assigning a Provision script to a preset, you may pass arguments to the
script. The arguments can be accessed from the script through the global
``args`` variable.
.. note::
Provision scripts may get executed multiple times in a given session.
Although all data model-mutating operations are idempotent, a script as a
whole may not be. It is, therefore, necessary to repeatedly run the script
until there are no more side effects and a stable state is reached.
Built-in functions
------------------
``declare(path, timestamps, values)``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This function is for declaring parameter values to be set, as well as specify
constraints on how recent you'd like the parameter value (or other attributes)
to have been refreshed from the device. If the given timestamp is lower than
the timestamp of the last refresh from the device, then this function will
return the last known value. Otherwise, the value will be fetched from the
device before being returned to the caller.
The timestamp argument is an object where the key is the attribute name (e.g.
``value``, ``object``, ``writable``, ``path``) and the value is an integer
representing a Unix timestamp.
The values argument is an object similar to the timestamp argument but its
property values being the parameter values to be set.
The possible attributes in 'timestamps' and 'values' arguments are:
- ``value``: a [<value>, <type>] pair
This attribute is not available for objects or object instances. If the value
is not a [<value>, <type>] array then it'll assumed to be a value without a
type and therefore the type will be inferred from the parameter's type.
- ``writable``: boolean
The meaning of this attribute can vary depending on the type of the parameter.
In the case of regular parameters, it indicates if its value is writable. In
the case of objects, it's whether or not it's possible to add new object
instances. In the case of object instances, it indicates whether or not this
instance can be deleted.
- ``object``: boolean
True if this is an object or object instance, false otherwise.
- ``path``: string
This attribute is special in that it's not a parameter attribute per se, but it
refers to the presence of parameters matching the given path. For example,
given the following wildcard path:
``InternetGatewayDevice.LANDevice.1.Hosts.Host.*.MACAddress``
Using a recent timestamp for path in ``declare()`` will result in a sync with
the device to rediscover all Host instances (``Host.*``). The path attribute
can also be used to create or delete object instances as described in
:ref:`path-format` section.
The return value of ``declare()`` is an iterator to access parameters that
match the given path. Each item in the iterator has the attribute 'path' in
addition to any other attribute given in the ``declare()`` call. The iterator
object itself has convenience attribute accessors which come in handy when
you're expecting a single parameter (e.g. when path does not contain wildcards
or aliases).
.. code:: javascript
// Example: Setting the SSID as the last 6 characters of the serial number
let serial = declare("Device.DeviceInfo.SerialNumber", {value: 1});
declare("Device.LANDevice.1.WLANConfiguration.1.SSID", null, {value: serial.value[0]});
``clear(path, timestamp)``
~~~~~~~~~~~~~~~~~~~~~~~~~~
This function invalidates the database copy of parameters (and their child
parameters) that match the given path and have a last refresh timestamp that is
less than the given timestamp. The most obvious use for this function is to
invalidate the database copy of the entire data model after the device has been
factory reset:
.. code:: javascript
// Example: Clear cached device data model Note
// Make sure to apply only on "0 BOOTSTRAP" event
clear("Device", Date.now());
clear("InternetGatewayDevice", Date.now());
``commit()``
~~~~~~~~~~~~
This function commits the pending declarations and performs any necessary sync
with the device. It's usually not required to call this function as it called
implicitly at the end of the script and when accessing any property of the
promise-like object returned by the ``declare()`` function. Calling this
explicitly is only necessary if you want to control the order in which
parameters are configured.
``ext(file, function, arg1, arg2, ...)``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Execute an extension script and return the result. The first argument is the
script filename while second argument is the function name within that script.
Any remaining arguments will be passed to that function. See :ref:`extensions`
for more details.
.. _path-format:
Path format
-----------
A parameter path may contain a wildcard (``*``) or an alias filter
(``[name:value]``). A wildcard segment in a parameter path will apply the
declared configuration to zero or more parameters that match the given path
where the wildcard segment can be anything.
An alias filter is like a wildcard, but additionally performs filtering on the
child parameters based on the key-value pairs provided. For example, the
following path:
``Device.WANDevice.1.WANConnectionDevice.1.WANIPConnection.[AddressingType:DHCP].ExternalIPAddress``
will return a list of ExternalIPAddress parameters (0 or more) where the
sibling parameter AddressingType is assigned the value "DHCP".
This can be useful when the exact instance numbers may be different from one
device to another. It is possible to use more than one key-value pair in the
alias filter. It's also possible to use multiple filters or use a combination
of filters and wildcards.
Creating/deleting object instances
----------------------------------
Given the declarative nature of provisions, we cannot explicitly tell the
device to create or delete an instance under a given object. Instead, we
specify the number of instances we want there to be, and based on that GenieACS
will determine whether or not it needs to create or delete instances. For
example, the following declaration will ensure we have one and only one
WANIPConnection object:
.. code:: javascript
// Example: Ensure we have one and only one WANIPConnection object
declare("InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANIPConnection.*", null, {path: 1});
Note the wildcard at the end of the parameter path.
It is also possible to use alias filters as the last path segment which will
ensure that the declared number of instances is satisfied given the alias
filter:
.. code:: javascript
// Ensure that *all* other instances are deleted
declare("InternetGatewayDevice.X_BROADCOM_COM_IPAddrAccCtrl.X_BROADCOM_COM_IPAddrAccCtrlListCfg.[]", null, {path: 0});
// Add the two entries we care about
declare("InternetGatewayDevice.X_BROADCOM_COM_IPAddrAccCtrl.X_BROADCOM_COM_IPAddrAccCtrlListCfg.[SourceIPAddress:192.168.1.0,SourceNetMask:255.255.255.0]", {path: now}, {path: 1});
declare("InternetGatewayDevice.X_BROADCOM_COM_IPAddrAccCtrl.X_BROADCOM_COM_IPAddrAccCtrlListCfg.[SourceIPAddress:172.16.12.0,SourceNetMask:255.255.0.0]", {path: now}, {path: 1});
Special GenieACS parameters
---------------------------
In addition to the parameters exposed in the device's data model through
TR-069, GenieACS has its own set of special parameters:
``DeviceID``
~~~~~~~~~~~~
This parameter sub-tree includes the following read-only parameters:
- ``DeviceID.ID``
- ``DeviceID.SerialNumber``
- ``DeviceID.ProductClass``
- ``DeviceID.OUI``
- ``DeviceID.Manufacturer``
``Tags``
~~~~~~~~
The ``Tags`` root parameter is used to expose device tags in the data model.
Tags appear as child parameters that are writable and have boolean value.
Setting a tag to ``false`` will delete that tag, and setting the value of a
non-existing tag parameter to ``true`` will create it.
.. code:: javascript
// Example: Remove "tag1", add "tag2", and read "tag3"
declare("Tags.tag1", null, {value: false});
declare("Tags.tag2", null, {value: true});
let tag3 = declare("Tags.tag3", {value: 1});
``Reboot``
~~~~~~~~~~
The ``Reboot`` root parameter hold the timestamp of the last reboot command.
The parameter value is writable and declaring a timestamp value that is larger
than the current value will trigger a reboot.
.. code:: javascript
// Example: Reboot the device only if it hasn't been rebooted in the past 300 seconds
declare("Reboot", null, {value: Date.now() - (300 * 1000)});
``FactoryReset``
~~~~~~~~~~~~~~~~
Works like ``Reboot`` parameter but for factory reset.
.. code:: javascript
// Example: Default the device to factory settings
declare("FactoryReset", null, {value: Date.now()});
``Downloads``
~~~~~~~~~~~~~
The ``Downloads`` sub-tree holds information about the last download
command(s). A download command is represented as an instance (e.g.
``Downloads.1``) containing parameters such as ``Download`` (timestamp),
``LastFileType``, ``LastFileName``. The parameters ``FileType``, ``FileName``,
``TargetFileName`` and ``Download`` are writable and can be used to trigger a
new download.
.. code:: javascript
declare("Downloads.[FileType:1 Firmware Upgrade Image]", {path: 1}, {path: 1});
declare("Downloads.[FileType:1 Firmware Upgrade Image].FileName", {value: 1}, {value: "firmware-2017.01.tar"});
declare("Downloads.[FileType:1 Firmware Upgrade Image].Download", {value: 1}, {value: Date.now()});
Common file types are:
- ``1 Firmware Upgrade Image``
- ``2 Web Content``
- ``3 Vendor Configuration File``
- ``4 Tone File``
- ``5 Ringer File``
.. warning::
Pushing a file to the device is often a service-interrupting operation. It's
recommended to only trigger it on certain events such as ``1 BOOT`` or during
a predetermined maintenance window).
After the CPE had finished downloading and applying the config file, it will
send a ``7 TRANSFER COMPLETE`` event. You may use that to trigger a reboot
after the firmware image or configuration file had been applied.
+6
View File
@@ -0,0 +1,6 @@
.. _roles-and-permissions:
Roles and Permissions
=====================
TODO
+105
View File
@@ -0,0 +1,105 @@
.. _virtual-parameters:
Virtual Parameters
==================
Virtual parameters are user-defined parameters whose values are generated using
a custom Javascript code. Virtual parameters behave just like regular
parameters and appear in the data model under ``VirtualParameters.`` path.
Virtual parameter names cannot contain a period (``.``).
The execution environment for virtual parameters is almost identical to that of
provisions. See :ref:`provisions` for more details and examples. The only
differences between the scripts of provisions and virtual parameters are:
- You can't pass custom arguments to virtual parameter scripts. Instead, the
variable ``args`` will hold the current vparam timestamps and values as well
as the declared timestamps and values. Like this:
.. code:: javascript
// [<current attr timestamps>, <current attr values>, <declared attr timestamps, declared attr values>]
[{path: 1559840000000, value: 1559840000000}, {value: ["cur val", "xsd:string"]}, {path: 1559849387191, value: 1559849387191}, {value: ["new val", "xsd:string"]}]
- Virtual parameter scripts must return an object containing the attributes of
this parameter.
.. note::
Just like a regular parameter, creating a virtual parameter does not
automatically add it to the parameter list for a device. It needs to fetched
(manually or via a preset) before you can see it in the data model.
Examples
--------
Unified MAC parameter across different device models
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. code:: javascript
// Example: Unified MAC parameter across different device models
let m = "00:00:00:00:00:00";
let d = declare("Device.WANDevice.*.WANConnectionDevice.*.WANIPConnection.*.MACAddress", {value: Date.now()});
let igd = declare("InternetGatewayDevice.WANDevice.*.WANConnectionDevice.*.WANPPPConnection.*.MACAddress", {value: Date.now()});
if (d.size) {
for (let p of d) {
if (p.value[0]) {
m = p.value[0];
break;
}
}
}
else if (igd.size) {
for (let p of igd) {
if (p.value[0]) {
m = p.value[0];
break;
}
}
}
return {writable: false, value: [m, "xsd:string"]};
Expose an external value as a virtual parameter
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. code:: javascript
// Example: Expose an external value as a virtual parameter
let serial = declare("DeviceID.SerialNumber", {value: 1});
if (values.value) {
ext("example-ext", "set", serial.value[0], values.value[0]);
return {writable: true, value: [values.value[0], "xsd:string"]};
}
else {
let v = ext("example-ext", "get", serial.value[0]);
return {writable: true, value: [v, "xsd:string"]};
}
Create an editable virtual parameter for WPA passphrase
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. code:: javascript
// Example: Create an editable virtual parameter for WPA passphrase
let m = "";
if (VALUES && VALUES.value) {
m = VALUES.value[0];
declare("Device.WiFi.AccessPoint.1.Security.KeyPassphrase", null, {value: m});
declare("InternetGatewayDevice.LANDevice.1.WLANConfiguration.1.KeyPassphrase", null, {value: m});
}
else {
let d = declare("Device.WiFi.AccessPoint.1.Security.KeyPassphrase", {value: Date.now()});
let igd = declare("InternetGatewayDevice.LANDevice.1.WLANConfiguration.1.KeyPassphrase", {value: Date.now()});
if (d.size) {
m = d.value[0];
}
else if (igd.size) {
m = igd.value[0];
}
}
return {writable: true, value: [m, "xsd:string"]};