# -*- coding: utf-8 -*-
from setuptools import setup

packages = \
['yager', 'yager.controllers', 'yager.core', 'yager.ext', 'yager.templates']

package_data = \
{'': ['*']}

install_requires = \
['cement>=3.0.4,<4.0.0',
 'colorlog>=4.2.1,<5.0.0',
 'jinja2>=2.11.2,<3.0.0',
 'pyyaml>=5.3.1,<6.0.0',
 'tabulate>=0.8.7,<0.9.0',
 'typing>=3.7.4,<4.0.0']

extras_require = \
{'code-format': ['black>=19.10b0,<20.0', 'blacken-docs>=1.7,<2.0'],
 'code-lint': ['flake8>=3.8,<4.0',
               'flake8-import-order>=0.18,<0.19',
               'flake8-bandit>=2.1,<3.0',
               'flake8-blind-except>=0.1,<0.2',
               'flake8-bugbear>=20.1,<21.0',
               'flake8-builtins>=1.5,<2.0',
               'flake8-docstrings>=1.5,<2.0',
               'flake8-logging-format>=0.6,<0.7',
               'flake8-mypy>=17.8,<18.0',
               'pep8-naming>=0.8,<0.9',
               'pygments>=2.6,<3.0'],
 'docs': ['recommonmark>=0.6.0,<0.7.0',
          'sphinx>=3.1,<4.0',
          'sphinx-rtd-theme>=0.5,<0.6',
          'sphinx-autodoc-typehints>=1.11,<2.0'],
 'test': ['pytest>=6.0,<7.0',
          'pytest-benchmark[aspect]>=3.2,<4.0',
          'pytest-cov>=2.10,<3.0',
          'pytest-instafail>=0.4,<0.5',
          'pytest-lazy-fixture>=0.6,<0.7',
          'pytest-random-order>=1.0,<2.0']}

entry_points = \
{'console_scripts': ['yager = yager.main:main']}

setup_kwargs = {
    'name': 'yager',
    'version': '0.1.0',
    'description': 'Yet Another GEneric Reporter tool for parsing of XML data into an SQLite database and subsequent universal reporting based on SQL queries and Jinja2 templates.',
    'long_description': '# Yager = Yet Another GEneric Reporter\n\n[![Python 3.7+](https://img.shields.io/badge/Python-3.7+-blue.svg)][PythonRef] [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)][BlackRef] [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)][MITRef]\n\n[PythonRef]: https://docs.python.org/3.7/\n[BlackRef]: https://github.com/ambv/black\n[MITRef]: https://opensource.org/licenses/MIT\n\n`yager` is Yet Another GEneric Reporter tool for parsing of XML data into an SQLite database and subsequent universal reporting based on SQL queries and Jinja2 templates.\n\n## Getting Started\n\n### Installing\n\n`yager` is distributed through the [Python Package Index][PyPIRef] as [yager][PyPIProjRef]. Run the following command to:\n\n[PyPIRef]: https://pypi.org\n[PyPIProjRef]:https://pypi.org/project/yager/\n\n* install a specific version\n\n    ```sh\n    pip install "yager==0.1"\n    ```\n\n* install the latest version\n\n    ```sh\n    pip install "yager"\n    ```\n\n* upgrade to the latest version\n\n    ```sh\n    pip install --upgrade "yager"\n    ```\n\n* install optional DEV dependencies like `pytest` framework and plugins necessary for performance and functional testing\n\n    ```sh\n    pip install "yager[test]"\n    ```\n\n### Configuring\n\n`yager` looks for a `YAML` configuration file in the following locations:\n\n* `/etc/yager/yager.yaml`\n* `~/.config/yager/yager.yaml`\n* `~/.yager/config/yager.yaml`\n* `~/.yager.yaml`\n\nBelow is the [example configuration file][yagerConfigRef] that parses XML data from [Qualys Cloud Agent API][QualysCloudAgentAPIRef] about Azure VMs and generates reports for each Azure Subscription.\n\n[yagerConfigRef]: config/etc/yager_example.yaml\n[QualysCloudAgentAPIRef]: https://www.qualys.com/docs/qualys-ca-api-user-guide.pdf\n\n```yaml\n### Yager Configuration Settings\n---\nyager:\n  # Toggle application level debug (does not toggle Cement framework debugging)\n  # debug: true\n\n  # Data location and layout\n  data:\n    # URI to the SQLite3 database with Qualys data\n    db_uri: "file:./instance/data/results.db"\n\n    # Tables exclude from deletion during `refresh-db`\n    exclude_from_refresh: [\n      "QualysKB",\n    ]\n\n    # List of table definitions\n    layout:\n        # Table name\n      - name: AzureSubscriptions\n        # Table columns described as an SQL statement;\n        # Used in `CREATE TABLE IF NOT EXISTS {name} ({columns})`\n        columns: |\n          id TEXT PRIMARY KEY,\n          name TEXT,\n          contactName TEXT,\n          contactEmail TEXT\n        # Source of data for the table in a form of `{type}:{locator}`\n        #   {type} could be `csv` or `xml`\n        #   {locator} is a file path for `csv` type or XPath for `xml`\n        #   XML files are provided with `--file path/to/file.xml` option\n        data_source: csv:./instance/subscriptions.csv\n\n      - name: HostAssets\n        columns: |\n          id INTEGER PRIMARY KEY,\n          name TEXT,\n          fqdn TEXT,\n          os TEXT,\n          firstSeen DATETIME,\n          lastUpdated DATETIME,\n          lastVulnScan DATETIME,\n          azureVmId TEXT,\n          azureRgName TEXT,\n          azurePublicIp TEXT,\n          azurePrivateIp TEXT,\n          azureSubscriptionId TEXT,\n          FOREIGN KEY (azureSubscriptionId)\n              REFERENCES AzureSubscriptions (id)\n        data_source: xml:.//HostAsset\n        # Mapping between table columns and XPath to text values\n        # of sub-elements for each element returned by `data_source` XPath\n        input_map:\n          id: id\n          name: name\n          fqdn: fqdn\n          os: os\n          firstSeen: created\n          lastUpdated: modified\n          lastVulnScan: lastVulnScan\n          azureVmId: ./sourceInfo/list/AzureAssetSourceSimple/vmId\n          azureRgName: ./sourceInfo/list/AzureAssetSourceSimple/resourceGroupName\n          azurePublicIp: ./sourceInfo/list/AzureAssetSourceSimple/publicIpAddress\n          azurePrivateIp: ./sourceInfo/list/AzureAssetSourceSimple/privateIpAddress\n          azureSubscriptionId: ./sourceInfo/list/AzureAssetSourceSimple/subscriptionId\n\n      - name: Vulns\n        columns: |\n          id INTEGER PRIMARY KEY,\n          qid INTEGER,\n          firstFound DATETIME,\n          lastFound DATETIME,\n          hostAssetsId INTEGER,\n          FOREIGN KEY (hostAssetsId)\n              REFERENCES HostAssets (id)\n        data_source: xml:.//HostAssetVuln\n        input_map:\n          id: hostInstanceVulnId\n          qid: qid\n          firstFound: firstFound\n          lastFound: lastFound\n        # Similar to `input_map` but mapping is parametrized with any {table_column}\n        # already defined in the `input_map` section. Prior to running XPath match,\n        # each {table_column} is expanded with a value already acquired for `input_map`.\n        input_map_parametrized:\n          hostAssetsId: ".//HostAssetVuln/[hostInstanceVulnId=\'{id}\']/.../.../.../id"\n\n    # Path to directory with Jinja2 templates for reports\n    template_dir: "./config/templates/"\n\n  # Templated reports\n  reports:\n    - name: "single_sub_md"\n      description: |\n        Report provides detailed Qualys vulnerability data for an individual Azure subscription.\n        It expects the following parameters to be provided in CLI:\n          * `sub_id` - Subscription ID from `AzureSubscriptions` table\n      template_file: "report_single_sub_md.j2"\n      template_params:\n        - query: |\n            -- Subscription details\n            SELECT\n              id,\n              name,\n              contactName,\n              contactEmail\n            FROM\n              AzureSubscriptions\n            WHERE\n              id == \'{sub_id}\'\n          var_mapping:\n            subscription_id: id\n            subscription_name: name\n            subscription_poc_name: contactName\n            subscription_poc_email: contactEmail\n\n        - query: |\n            -- Vuln details for all hosts in subscription\n            SELECT\n                HostAssets.name as host_name,\n                HostAssets.azureVmId as host_vm_id,\n                Vulns.firstFound as vuln_seen_first,\n                Vulns.lastFound as vuln_seen_last,\n                Vulns.qid as vuln_qid,\n                QualysKB.severity_level as vuln_level\n            FROM\n                HostAssets\n                INNER JOIN Vulns ON Vulns.hostAssetsId = HostAssets.id\n                INNER JOIN QualysKB ON QualysKB.qid = Vulns.qid\n            WHERE\n                HostAssets.azureSubscriptionId == \'{sub_id}\'\n                AND QualysKB.vuln_type != "Information Gathered";\n          var_mapping:\n            all_vuln_details: "*"\n\n        - query: |\n            -- Additional host details\n            SELECT\n                HostAssets.name as host_name,\n                HostAssets.fqdn as host_fqdn,\n                HostAssets.os as host_os,\n                HostAssets.lastVulnScan as host_last_scan,\n                HostAssets.azureRgName as host_rg,\n                HostAssets.azureVmId as host_vm_id,\n                HostAssets.azurePrivateIp as host_priv_ip,\n                HostAssets.azurePublicIp as host_pub_ip\n            FROM\n                HostAssets\n            WHERE\n                HostAssets.azureSubscriptionId == \'{sub_id}\'\n          var_mapping:\n            all_host_details: "*"\n\n        - query: |\n            -- Reference information from Qualys Knowledge Base\n            SELECT\n                QualysKB.qid as vuln_qid,\n                QualysKB.severity_level as vuln_level,\n                QualysKB.title as vuln_title,\n                QualysKB.diagnosis as vuln_details,\n                QualysKB.consequence as vuln_risk,\n                QualysKB.solution as vuln_solution\n            FROM\n                QualysKB\n          var_mapping:\n            kb_details: "*"\n\n# Logging configuration\nlog.colorlog:\n  # Whether or not to colorize the log file.\n  # colorize_file_log: false\n\n  # Whether or not to colorize the console log.\n  # colorize_console_log: true\n\n  # Where the log file lives (no log file by default)\n  # file: null\n\n  # The level for which to log.  One of: info, warning, error, fatal, debug\n  # level: INFO\n\n  # Whether or not to log to console\n  # to_console: true\n\n  # Whether or not to rotate the log file when it reaches `max_bytes`\n  # rotate: false\n\n  # Max size in bytes that a log file can grow until it is rotated.\n  # max_bytes: 512000\n\n  # The maximum number of log files to maintain when rotating\n  # max_files: 4\n\n```\n\n## Usage\n\n### Generic\n\n```term\nusage: yager [-h] [-d] [-q] [-v] {query,refresh-db,report} ...\n\nYet Another GEneric Reporter tool for parsing of XML data into an SQLite database and subsequent universal reporting based on SQL queries and Jinja2 templates.\n\noptional arguments:\n  -h, --help            show this help message and exit\n  -d, --debug           full application debug mode\n  -q, --quiet           suppress all console output\n  -v, --version         show program\'s version number and exit\n\nsub-commands:\n  {query,refresh-db,report}\n    query               execute a query against database\n    refresh-db          generate database from configured data sources\n    report              execute a pre-configured report\n\nUsage: yager {sub-command} {options}\n```\n\n### Query\n\n```term\nusage: yager query [-h] [--output FORMAT] QUERY\n\npositional arguments:\n  QUERY                 query to be executed\n\noptional arguments:\n  -h, --help            show this help message and exit\n  --output FORMAT, -o FORMAT\n                        defines how to format the output (choose from \'csv\' or\n                        \'table\'; default: \'table\')\n```\n\n### Refresh-db\n\n```term\nusage: yager refresh-db [-h] [--file PATH]\n\noptional arguments:\n  -h, --help            show this help message and exit\n  --file PATH, -f PATH  path to XML file with data (could be repetated)\n```\n\n### Report\n\n```term\nusage: yager report [-h] [--param PARAM] NAME\n\npositional arguments:\n  NAME                  report to be executed\n\noptional arguments:\n  -h, --help            show this help message and exit\n  --param PARAM, -p PARAM\n                        NAME=VALUE pair defining a global query parameter to\n                        be used for each query in the template (could be\n                        repetated)\n```\n\n### Examples\n\nRefresh the database using the layout and data sources described in the YAML config.\n\n```sh\n$ yager refresh-db -f data.xml\n```\n\nGenerate report based on SQL queries and Jinja2 templates defined in the YAML config.\n\n```sh\n$ yager report TEMPLATE --param KEY1=VALUE1 --param KEY2=VALUE2\n```\n\n## Requirements\n\n* Python >= 3.7\n\n## Built using\n\n* [Cement Framework][CementRef] - CLI application framework\n\n[CementRef]: https://builtoncement.com/\n\n## Versioning\n\nWe use [Semantic Versioning Specification][SemVer] as a version numbering convention.\n\n[SemVer]: http://semver.org/\n\n## Release History\n\nFor the available versions, see the [tags on this repository][RepoTags]. Specific changes for each version are documented in [CHANGELOG.md][ChangelogRef].\n\nAlso, conventions for `git commit` messages are documented in [CONTRIBUTING.md][ContribRef].\n\n[RepoTags]: https://github.com/undp/yager/tags\n[ChangelogRef]: CHANGELOG.md\n[ContribRef]: CONTRIBUTING.md\n\n## Authors\n\n* **Oleksiy Kuzmenko** - [OK-UNDP@GitHub][OK-UNDP@GitHub] - *Initial design and implementation*\n\n[OK-UNDP@GitHub]: https://github.com/OK-UNDP\n\n## Acknowledgments\n\n* Hat tip to all individuals shaping design of this project by sharing their knowledge in articles, blogs and forums.\n\n## License\n\nUnless otherwise stated, all authors (see commit logs) release their work under the [MIT License][MITRef]. See [LICENSE.md][LicenseRef] for details.\n\n[LicenseRef]: LICENSE.md\n\n## Contributing\n\nThere are plenty of ways you could contribute to this project. Feel free to:\n\n* submit bug reports and feature requests\n* outline, fix and expand documentation\n* peer-review bug reports and pull requests\n* implement new features or fix bugs\n\nSee [CONTRIBUTING.md][ContribRef] for details on code formatting, linting and testing frameworks used by this project.\n',
    'author': 'Oleksiy Kuzmenko',
    'author_email': 'oleksiy.kuzmenko@undp.org',
    'maintainer': None,
    'maintainer_email': None,
    'url': 'https://github.com/undp/yager',
    'packages': packages,
    'package_data': package_data,
    'install_requires': install_requires,
    'extras_require': extras_require,
    'entry_points': entry_points,
    'python_requires': '>=3.6.1,<4.0.0',
}


setup(**setup_kwargs)
