Metadata-Version: 2.4
Name: asterisklint-jjs
Version: 0.5.0
Summary: Asterisk PBX configuration syntax checker
Home-page: https://github.com/jjsearle/asterisklint
Author: Walter Doekes, OSSO B.V.
Author-email: wjdoekes+asterisklint@osso.nl
License: GPLv3+
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Topic :: Communications :: Telephony
Classifier: Topic :: Software Development :: Pre-processors
Description-Content-Type: text/x-rst
License-File: LICENSE
Dynamic: author
Dynamic: author-email
Dynamic: classifier
Dynamic: description
Dynamic: description-content-type
Dynamic: home-page
Dynamic: license
Dynamic: license-file
Dynamic: summary

|AsteriskLint|
==============

*Asterisk PBX configuration syntax checker*

AsteriskLint is a suite of tools to check syntax of your Asterisk PBX
configuration files.

Alright, enough talking. Some examples please!

For an online example see `<https://asterisklint.osso.pub/>`_. For CLI
examples, keep reading:


Invocation
----------

.. code-block:: console

    $ asterisklint
    usage: asterisklint [-h] COMMAND
    asterisklint: error: the following arguments are required: COMMAND

    $ asterisklint ls
    builtin:
      ls                    List available commands.

    /usr/lib/python/dist-packages:
      dialplan-check        Do sanity checks on dialplan. Takes 'extensions.conf'
                            as argument. Suppress error classes using ALINT_IGNORE.
      dialplan-show         Show dialplan like Asterisk does with CLI command
                            "dialplan show". Takes 'extensions.conf' as argument.
      func_odbc-check       Do sanity checks on func_odbc.conf. Takes
                            'func_odbc.conf' as argument. Suppress error classes
                            using ALINT_IGNORE.
      ident-scan            Report similarly named contexts, labels and variables.
                            Takes 'extensions.conf' as argument. All parse errors
                            are suppressed.
      modules-show          Show which modules, apps and functions are used by the
                            dialplan. Takes 'extensions.conf' as argument.

    Place custom commands in ~/.asterisklint/asterisklint/commands.


Take this little dialplan snippet, that we'll call ``extensions.conf``::

    [default]
    exten => _8[2-9]x,1,NoOp
     same => n,GoSub(somewhere,s,1(argument1,argument2)
     same => n,Payback(audiofile)

Now run the ``dialplan-check`` command on it:

.. code-block:: console

    $ ALINT_IGNORE=H_DP_ asterisklint dialplan-check extensions.conf
    extensions.conf:2 H_PAT_NON_CANONICAL: pattern '_8[2-9]x' is not in the canonical form '_8NX'
    extensions.conf:3 W_APP_BAD_CASE: app 'GoSub' does not have the proper Case 'Gosub'
    extensions.conf:3 W_APP_BALANCE: app data '1(argument1,argument2' looks like unbalanced parentheses/quotes/curlies
    extensions.conf:4 E_APP_MISSING: app 'Payback' does not exist, dialplan will halt here!
    extensions.conf:3 E_DP_GOTO_NOCONTEXT: context not found for goto to somewhere, s, 1

It had a lot to complain about that little snippet. But it was right. We
even suppressed two hints about a missing ``[general]`` and ``[global]``
context using ``ALINT_IGNORE``.

Not everything it checks is documented, and it does not check everything
that we like yet. But it's a start. Bug reports are welcome. Feature requests
prefer to be accompanied by a patch :-)

Try out ``modules-show`` if you use ``autoload=no`` in your ``modules.conf``.

All commands show help if asked:

.. code-block:: console

    $ asterisklint modules-show --help
    usage: asterisklint modules-show [-h] [--func-odbc FUNC_ODBC_CONF]
                                     [EXTENSIONS_CONF]

    Show which modules, apps and functions are used by the dialplan. Useful when
    you use autoload=no in your modules.conf. Beware that you do need more modules
    than just these listed.

    positional arguments:
      EXTENSIONS_CONF       path to extensions.conf

    optional arguments:
      -h, --help            show this help message and exit
      --func-odbc FUNC_ODBC_CONF
                            path to func_odbc.conf, will be read automatically if
                            found in same the same dir as extensions.conf; set
                            empty to disable


Asterisk versions
-----------------

Apps and functions differ between Asterisk versions. Choose the version
to check against with ``--asterisk-version`` or the
``ALINT_ASTERISK_VERSION`` environment variable. Supported are 11, 13
(the default), 20 and 22:

.. code-block:: console

    $ asterisklint dialplan-check --asterisk-version 22 extensions.conf
    extensions.conf:6 E_APP_MISSING: app 'Macro' does not exist, dialplan will halt here!
    extensions.conf:7 E_APP_ARG_BADOPT: unrecognised options 'M' in arg 3 for app 'Dial'

The app and function lists for 20 and 22 follow the official
documentation at `<https://docs.asterisk.org/>`_. For those versions the
options of Dial, Queue, ResetCDR, Originate and VoiceMail are checked as
well.


Installation
------------

Installation is a matter of ``python3 setup.py install``. Or, for more
convenience, install a PyPI uploaded version through ``pip3(1)``:

.. code-block:: console

    $ sudo pip3 install asterisklint
    ...
    Successfully installed asterisklint


The ``dialplan-check`` comes in handy as a git commit hook, for example
``.git/hooks/pre-commit``:

.. code-block:: sh

    #!/bin/sh
    export ALINT_IGNORE=  # adjust as needed

    asterisklint dialplan-check PATH/TO/extensions.conf
    ret=$?
    if test $ret -ne 0; then
        echo >&2
        echo 'One or more dialplan syntax errors. Please fix before committing.' >&2
        exit $ret
    fi

    exit 0


TODO
----

* Expression parsing.
* Web: state is kept between requests:

  - on 500-error, the next user may get older errors (because of the
    messagedef singleton)
  - the BackGround/Background hack is stored between requests

* Log/store Set'd variables and compare against Read variables. Also log
  variables Set through the ARRAY() function. (And HASH?)
* Fix various includes issues:

  - Recursive #includes probably make asterisklint run out of stack.
  - Add checks for recursive dialplan-includes.
  - Scan for missing dialplan-includes.

* Trim CALLERID match (as used in FreePBX dialplan).
* Func_odbc parsing improvements:

  - check for missing synopsis/syntax (compare syntax to ARGn count)
  - check for correct usage of VAL (write only) and ARG and missing SQL_ESC
  - yield the odbc functions instead of contexts like it does now

  (See more in func_odbc.py.)
* Add ``app-check`` command to do dialplan checks of individual lines.
* Add ``expr-check`` command to do expression (``$[...]``) checks.
  E.g. add::

    exten => X!,1,Set(boolean=$["" <555> = 1234])
    ; Set(boolean=$[${CALLERID(all)} = 1234])
    ; incorrectly using 'all', should use 'num'
    ==> syntax error, unexpected '=', expecting '-' or '!' or '(' or '<token>'

* Allow multiline variables using += (key=val; key+=more-val).
* Investigate whether exten=>s,n(label)... exten=>s,label+10... is valid.
* For the Goto/Gosub-visiting:

  - Attempt to match contexts by regex if there are $VARs involved?
  - Allow a "noqa" style exceptions to be placed in a comment?

* Improve documentation as needed.
* Before 1.0, start adding versioning -- including semver -- so users can
  depend on a stable API from their custom scripts. Also version the scripts
  (commands) so they won't talk to older/newer libs if that poses a problem.


BUGS
----

* The library is very much in flux. Don't expect it to stabilize any time
  soon. Pay attention to versions!
* Multiline comments (``;-- ... --;``) are unsupported. Does anyone use those?
* Limits aren't checked (dialplan lines are limited at 255 or 8191 bytes
  for LOW_MEMORY and normal mode respectively).
* The library/suite is Python3 only. Right now the effort to make it Python2
  compatible is larger than the demand. In the future Python2 compatibility
  will become even less relevant.


Author
------

Walter Doekes, OSSO B.V. 2015-2020


.. |AsteriskLint| image:: assets/asterisklint_head.png
    :alt: AsteriskLint



0.5.0 (2026-10-05)
~~~~~~~~~~~~~~~~~~

Improvements:

* Added Asterisk 20 and 22 support, selected with ``--asterisk-version``
  or ``ALINT_ASTERISK_VERSION``. The default stays at 13. All apps and
  functions in the Asterisk 20/22 documentation are known; those removed
  in Asterisk 21 (app_macro, chan_sip, res_monitor, app_osplookup,
  NoCDR, ImportVar, SetAMAFlags) are reported as missing for 22.
* Check Dial, Queue, ResetCDR and Originate options for Asterisk 20/22,
  including options removed in 21 (Dial M, Queue w/W, ResetCDR e).
* Check FEATUREMAP() feature names for Asterisk 20/22.
* Added the m option to Milliwatt and the e, S and t options to VoiceMail
  (20/22).
* Added MSet, which checks its assignments like Set does.

Bug fixes:

* App options with arguments, like VoiceMail g(5), are no longer
  reported as unrecognised options.
* Fix test runner on Python 3.11+.

0.4.3 (2022-10-24)
~~~~~~~~~~~~~~~~~~

Bug fixes:

* Don't choke on slices with variable start/length.

Improvements:

* Added BridgeAdd, BridgeWait, DBdeltree, Bridge, ODBCFinish,
  PJSIP_DIAL_CONTACTS, PJSIP_DTMF_MODE, PJSIP_MEDIA_OFFER,
  PJSIP_MOH_PASSTHROUGH, PJSIP_PARSE_URI, PJSIP_SEND_SESSION_REFRESH,
  BASE64_ENCODE, BASE64_DECODE, DEVICE_STATE, HINT, DIALGROUP,
  DIALPLAN_EXISTS, VALID_EXTEN, ODBC_FETCH, SQL_ESC, TALK_DETECT.

0.4.2 (2020-02-19)
~~~~~~~~~~~~~~~~~~

Bug fixes:

* Don't choke on too many Gosub arguments.
* Fixes for various python 3 versions.

Improvements:

* Added PJSIP_HEADER, PJSIP_AOR, PJSIP_CONTACT, PJSIP_ENDPOINT.

0.4.1 (2018-10-10)
~~~~~~~~~~~~~~~~~~

Bug fixes:

* Cope with ${vars} in FUNC() arguments.
* Fix typo's in func_odbc-check.
* Speedup in dialplan goto-parsing.
* Unbreak custom command support.

Improvements:

* Add missing app_milliwatt, app_mysql, app_originate,
  func_audiohookinherit, func_volume_register.
* Add preliminary func_odbc-annotate command; not feature complete.
* Add the (now obsolete) vg.py contrib command which alters certain file
  reading functions so a slightly different syntax is accepted.
* Check applications called in ExecIf().

0.4.0 (2017-04-05)
~~~~~~~~~~~~~~~~~~

Bug fixes:

* When doing dialplan-file mutations, operate on the symlink target
  instead of replacing the symlink.
* Don't install README files into /usr, but in
  /usr/share/doc/asterisklint (or with a different prefix).
* Also search in included contexts for priority labels.

Improvements:

* Add various apps:
  - Authenticate, ControlPlayback, PickupChan
  - PickupOld1v4 (a workaround, see ASTERISK-26464)
  - VoiceMailPlayMsg, VMSayName,
  - ContinueWhile, EndWhile, ExitWhile, While,
  - AGI, DeadAGI, EAGI,
  - StopMusicOnHold
* Add various functions:
  - DB, DB_EXISTS, DB_KEYS, DB_DELETE,
  - MD5, TIMEOUT
  - LOCAL, LOCAL_PEEK, STACK_PEEK
* Add initial checks of function parameters: nothing more than the
  parentheses check we already used on undefined apps.
* Add application Set() support. Add function SET() support. This also
  enables checking calls to writable functions.
* Allow both the "BackGround" and "Background" spelling, as long as
  you choose one consistently.
* A bunch of refactoring to make BetterCodeHub happy. If you've made
  custom subcommands, look at the MainBase class.
* Add test with Asterisk 13 sample dialplan as input.
* Add web frontend into repository.

0.3.0 (2016-06-08)
~~~~~~~~~~~~~~~~~~

* Add preliminary Goto/Gosub scanning: the dialplan-check now tries to
  find non-existent goto destinations. New error classes:
  E_DP_GOTO_CONTEXT_NOLABEL, E_DP_GOTO_NOCONTEXT, E_DP_GOTO_NOLABEL,
  W_DP_GOTO_CONTEXT_NOEXTEN.
* Add preliminary app argument checking. New error classes:
  E_APP_ARG_IFCONST, E_APP_ARG_IFEMPTY, E_APP_ARG_SYNTAX.
* Add new command: ident-scan. It lists used contexts, labels and
  variables and does a poor attempt at finding typo's by comparing
  them against each other.
* Add Asterisk apps: NoCDR, Record.
* The commands taking a path to extensions.conf now default to scanning
  for it in the current directory.
* Python3.5 testcase compatibility fix.

0.2.1 (2016-01-29)
~~~~~~~~~~~~~~~~~~

* Don't look in __init__ for custom commands.

0.2.0 (2016-01-29)
~~~~~~~~~~~~~~~~~~

* Add partial func_odbc checking.
* Add new command: func_odbc-check
* Do func_odbc checks for modules-show and dialplan-show, so you don't
  get flooded with E_FUNC_MISSING errors if you use func_odbc.
* Fix a few variable/dialplan parsing bugs, improve some.

0.1.0 (2016-01-15)
~~~~~~~~~~~~~~~~~~

* Initial release.
* The following commands are available:
  dialplan-check, dialplan-show, modules-show
